} \
while (0)
+/* Append to SIGNATURE a copy of X, making sure SIGNATURE does
+ not become too long. */
+static void
+xd_signature_cat (char *signature, char const *x)
+{
+ ptrdiff_t siglen = strlen (signature);
+ ptrdiff_t xlen = strlen (x);
+ if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen)
+ string_overflow ();
+ strcat (signature, x);
+}
+
/* Compute SIGNATURE of OBJECT. It must have a form that it can be
used in dbus_message_iter_open_container. DTYPE is the DBusType
the object is related to. It is passed as argument, because it
{
unsigned int subtype;
Lisp_Object elt;
+ char const *subsig;
+ int subsiglen;
char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
elt = object;
if (NILP (elt))
{
subtype = DBUS_TYPE_STRING;
- strcpy (x, DBUS_TYPE_STRING_AS_STRING);
+ subsig = DBUS_TYPE_STRING_AS_STRING;
}
else
{
subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
+ subsig = x;
}
/* If the element type is DBUS_TYPE_SIGNATURE, and this is the
if ((subtype == DBUS_TYPE_SIGNATURE)
&& STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt)))
&& NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
- strcpy (x, SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt))));
+ subsig = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)));
while (!NILP (elt))
{
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
}
- sprintf (signature, "%c%s", dtype, x);
+ subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
+ "%c%s", dtype, subsig);
+ if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
+ string_overflow ();
break;
case DBUS_TYPE_VARIANT:
{
subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
- strcat (signature, x);
+ xd_signature_cat (signature, x);
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
}
- strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
+ xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
break;
case DBUS_TYPE_DICT_ENTRY:
elt = XD_NEXT_VALUE (elt);
subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
- strcat (signature, x);
+ xd_signature_cat (signature, x);
if (!XD_BASIC_DBUS_TYPE (subtype))
wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
elt = CDR_SAFE (XD_NEXT_VALUE (elt));
subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
- strcat (signature, x);
+ xd_signature_cat (signature, x);
if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
wrong_type_argument (intern ("D-Bus"),
CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
/* Closing signature. */
- strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
+ xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
break;
default:
}
case DBUS_TYPE_INT16:
- CHECK_NUMBER (object);
+ CHECK_TYPE_RANGED_INTEGER (dbus_int16_t, object);
{
dbus_int16_t val = XINT (object);
XD_DEBUG_MESSAGE ("%c %d", dtype, (int) val);
}
case DBUS_TYPE_UINT16:
- CHECK_NATNUM (object);
+ CHECK_TYPE_RANGED_INTEGER (dbus_uint16_t, object);
{
dbus_uint16_t val = XFASTINT (object);
XD_DEBUG_MESSAGE ("%c %u", dtype, (unsigned int) val);
}
case DBUS_TYPE_INT32:
- CHECK_NUMBER (object);
+ CHECK_TYPE_RANGED_INTEGER (dbus_int32_t, object);
{
dbus_int32_t val = XINT (object);
XD_DEBUG_MESSAGE ("%c %d", dtype, val);
#ifdef DBUS_TYPE_UNIX_FD
case DBUS_TYPE_UNIX_FD:
#endif
- CHECK_NATNUM (object);
+ CHECK_TYPE_RANGED_INTEGER (dbus_uint32_t, object);
{
dbus_uint32_t val = XFASTINT (object);
XD_DEBUG_MESSAGE ("%c %u", dtype, val);
}
case DBUS_TYPE_UINT64:
- CHECK_NATNUM (object);
+ CHECK_TYPE_RANGED_INTEGER (dbus_uint64_t, object);
{
dbus_uint64_t val = XFASTINT (object);
XD_DEBUG_MESSAGE ("%c %"pI"d", dtype, XFASTINT (object));
if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
{
CHECK_NATNUM (args[i+1]);
- timeout = XFASTINT (args[i+1]);
+ timeout = min (XFASTINT (args[i+1]), INT_MAX);
i = i+2;
}
if ((i+2 <= nargs) && (EQ ((args[i]), QCdbus_timeout)))
{
CHECK_NATNUM (args[i+1]);
- timeout = XFASTINT (args[i+1]);
+ timeout = min (XFASTINT (args[i+1]), INT_MAX);
i = i+2;
}
busp = CDR_SAFE (busp);
}
- if (NILP(bus))
+ if (NILP (bus))
return;
/* We ignore all Lisp errors during the call. */
DBusConnection *connection;
ptrdiff_t i;
char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
- char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH];
+ int rulelen;
DBusError derror;
/* Check parameters. */
connection = xd_initialize (bus, TRUE);
/* Create a rule to receive related signals. */
- sprintf (rule,
- "type='signal',interface='%s',member='%s'",
- SDATA (interface),
- SDATA (signal));
+ rulelen = snprintf (rule, sizeof rule,
+ "type='signal',interface='%s',member='%s'",
+ SDATA (interface),
+ SDATA (signal));
+ if (! (0 <= rulelen && rulelen < sizeof rule))
+ string_overflow ();
/* Add unique name and path to the rule if they are non-nil. */
if (!NILP (uname))
{
- sprintf (x, ",sender='%s'", SDATA (uname));
- strcat (rule, x);
+ int len = snprintf (rule + rulelen, sizeof rule - rulelen,
+ ",sender='%s'", SDATA (uname));
+ if (! (0 <= len && len < sizeof rule - rulelen))
+ string_overflow ();
+ rulelen += len;
}
if (!NILP (path))
{
- sprintf (x, ",path='%s'", SDATA (path));
- strcat (rule, x);
+ int len = snprintf (rule + rulelen, sizeof rule - rulelen,
+ ",path='%s'", SDATA (path));
+ if (! (0 <= len && len < sizeof rule - rulelen))
+ string_overflow ();
+ rulelen += len;
}
/* Add arguments to the rule if they are non-nil. */
for (i = 6; i < nargs; ++i)
if (!NILP (args[i]))
{
+ int len;
CHECK_STRING (args[i]);
- sprintf (x, ",arg%"pD"d='%s'", i - 6,
- SDATA (args[i]));
- strcat (rule, x);
+ len = snprintf (rule + rulelen, sizeof rule - rulelen,
+ ",arg%"pD"d='%s'", i - 6, SDATA (args[i]));
+ if (! (0 <= len && len < sizeof rule - rulelen))
+ string_overflow ();
+ rulelen += len;
}
/* Add the rule to the bus. */
/* Create a hash table entry. */
key = list3 (bus, interface, signal);
- key1 = list4 (uname, service, path, handler);
+ key1 = list5 (uname, service, path, handler, build_string (rule));
value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
if (NILP (Fmember (key1, value)))
registered. This means that other D-Bus clients have no way of
noticing the newly registered method. When interfaces are constructed
incrementally by adding single methods or properties at a time,
-DONT-REGISTER-SERVICE can be use to prevent other clients from
+DONT-REGISTER-SERVICE can be used to prevent other clients from
discovering the still incomplete interface.*/)
(Lisp_Object bus, Lisp_Object service, Lisp_Object path,
Lisp_Object interface, Lisp_Object method, Lisp_Object handler,
arrives (methods and signals), or a cons cell containing the value of
the property.
+For signals, there is also a fifth element RULE, which keeps the match
+string the signal is registered with.
+
In the second case, the key in the hash table is the list (BUS
SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a
string denoting the bus address. SERIAL is the serial number of the