X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a9269c187774dea6e939066a79901f23ae79641f..14af5f7fc4d7557ee712d3b6a8b46d9034c2ff39:/src/dbusbind.c diff --git a/src/dbusbind.c b/src/dbusbind.c index 4828f4e968..c89867fbae 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -1,5 +1,5 @@ /* Elisp bindings for D-Bus. - Copyright (C) 2007-2011 Free Software Foundation, Inc. + Copyright (C) 2007-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -184,7 +184,7 @@ static int xd_in_read_queued_messages = 0; #endif /* This was a macro. On Solaris 2.11 it was said to compile for - hours, when optimzation is enabled. So we have transferred it into + hours, when optimization is enabled. So we have transferred it into a function. */ /* Determine the DBusType of a given Lisp symbol. OBJECT must be one of the predefined D-Bus type symbols. */ @@ -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: @@ -950,7 +968,7 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, connection = xd_initialize (bus, TRUE); /* Add the watch functions. We pass also the bus as data, in order - to distinguish between the busses in xd_remove_watch. */ + to distinguish between the buses in xd_remove_watch. */ if (!dbus_connection_set_watch_functions (connection, xd_add_watch, xd_remove_watch, @@ -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. */ @@ -2053,13 +2071,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG && (SBYTES (service) > 0) && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0) && (strncmp (SSDATA (service), ":", 1) != 0)) - { - uname = call2 (intern ("dbus-get-name-owner"), bus, service); - /* When there is no unique name, we mark it with an empty - string. */ - if (NILP (uname)) - uname = empty_unibyte_string; - } + uname = call2 (intern ("dbus-get-name-owner"), bus, service); else uname = service; @@ -2071,32 +2083,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 +2139,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 +2171,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 +2313,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