busctl introspect: accept direction="out" for signals
authorMantas Mikulėnas <grawity@gmail.com>
Tue, 8 Nov 2016 12:20:00 +0000 (14:20 +0200)
committerMantas Mikulėnas <grawity@gmail.com>
Wed, 9 Nov 2016 14:38:49 +0000 (16:38 +0200)
According to the D-Bus spec (v0.29),

| The direction element on <arg> may be omitted, in which case it
| defaults to "in" for method calls and "out" for signals. Signals only
| allow "out" so while direction may be specified, it's pointless.

Therefore we still should accept a 'direction' attribute, even if it's
useless in reality.

Closes: #4616

src/libsystemd/sd-bus/busctl-introspect.c

index 09cbd9a..9e0525e 100644 (file)
@@ -194,6 +194,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
                 STATE_SIGNAL_ARG,
                 STATE_SIGNAL_ARG_NAME,
                 STATE_SIGNAL_ARG_TYPE,
+                STATE_SIGNAL_ARG_DIRECTION,
                 STATE_PROPERTY,
                 STATE_PROPERTY_NAME,
                 STATE_PROPERTY_TYPE,
@@ -432,7 +433,7 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
                                 else if (streq_ptr(name, "type"))
                                         state = STATE_METHOD_ARG_TYPE;
                                 else if (streq_ptr(name, "direction"))
-                                         state = STATE_METHOD_ARG_DIRECTION;
+                                        state = STATE_METHOD_ARG_DIRECTION;
                                 else {
                                         log_error("Unexpected method <arg> attribute %s.", name);
                                         return -EBADMSG;
@@ -458,7 +459,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
                                                 } else if (streq(argument_direction, "out")) {
                                                         if (!strextend(&context->member_result, argument_type, NULL))
                                                                 return log_oom();
-                                                }
+                                                } else
+                                                        log_error("Unexpected method <arg> direction value '%s'.", argument_direction);
                                         }
 
                                         argument_type = mfree(argument_type);
@@ -582,6 +584,8 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
                                         state = STATE_SIGNAL_ARG_NAME;
                                 else if (streq_ptr(name, "type"))
                                         state = STATE_SIGNAL_ARG_TYPE;
+                                else if (streq_ptr(name, "direction"))
+                                        state = STATE_SIGNAL_ARG_DIRECTION;
                                 else {
                                         log_error("Unexpected signal <arg> attribute %s.", name);
                                         return -EBADMSG;
@@ -599,8 +603,11 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
                                    (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
 
                                 if (argument_type) {
-                                        if (!strextend(&context->member_signature, argument_type, NULL))
-                                                return log_oom();
+                                        if (!argument_direction || streq(argument_direction, "out")) {
+                                                if (!strextend(&context->member_signature, argument_type, NULL))
+                                                        return log_oom();
+                                        } else
+                                                log_error("Unexpected signal <arg> direction value '%s'.", argument_direction);
 
                                         argument_type = mfree(argument_type);
                                 }
@@ -639,6 +646,19 @@ static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth
 
                         break;
 
+                case STATE_SIGNAL_ARG_DIRECTION:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                free_and_replace(argument_direction, name);
+
+                                state = STATE_SIGNAL_ARG;
+                        } else {
+                                log_error("Unexpected token in signal <arg>. (4)");
+                                return -EINVAL;
+                        }
+
+                        break;
+
                 case STATE_PROPERTY:
 
                         if (t == XML_ATTRIBUTE_NAME) {