]> code.delx.au - gnu-emacs/blobdiff - src/dbusbind.c
Merge from trunk.
[gnu-emacs] / src / dbusbind.c
index 4828f4e968dcda6e3a42960394c30ac55f56527a..0b6d6929a4d497755215fe4502aa2cd286d6bc0c 100644 (file)
@@ -259,6 +259,18 @@ xd_symbol_to_dbus_type (Lisp_Object object)
     }                                                                  \
   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
@@ -271,6 +283,8 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
 {
   unsigned int subtype;
   Lisp_Object elt;
+  char const *subsig;
+  int subsiglen;
   char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
 
   elt = object;
@@ -328,12 +342,13 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       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
@@ -342,7 +357,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       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))
        {
@@ -351,7 +366,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
          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:
@@ -383,10 +401,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
        {
          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:
@@ -407,7 +425,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       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)));
@@ -416,14 +434,14 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       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:
@@ -467,7 +485,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
        }
 
       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);
@@ -477,7 +495,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
        }
 
       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);
@@ -487,7 +505,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
        }
 
       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);
@@ -500,7 +518,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
 #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);
@@ -520,7 +538,7 @@ xd_append_arg (unsigned int dtype, Lisp_Object object, DBusMessageIter *iter)
        }
 
       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));
@@ -1127,7 +1145,7 @@ usage: (dbus-call-method BUS SERVICE PATH INTERFACE METHOD &optional :timeout TI
   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;
     }
 
@@ -1310,7 +1328,7 @@ usage: (dbus-call-method-asynchronously BUS SERVICE PATH INTERFACE METHOD HANDLE
   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;
     }
 
@@ -1862,7 +1880,7 @@ xd_read_queued_messages (int fd, void *data, int for_read)
        busp = CDR_SAFE (busp);
       }
 
-  if (NILP(bus))
+  if (NILP (bus))
     return;
 
   /* We ignore all Lisp errors during the call.  */
@@ -2026,7 +2044,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
   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.  */
@@ -2071,32 +2089,43 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
       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.  */
@@ -2116,7 +2145,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
 
   /* 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)))
@@ -2148,7 +2177,7 @@ When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not
 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,
@@ -2290,6 +2319,9 @@ be called when a D-Bus message, which matches the key criteria,
 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