From 3dba9f0fd46f84cc1f9b8d54743b72a9b4b1627c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 23 Mar 2017 16:08:50 +0100 Subject: [PATCH] pod: handle NULL --- pinos/client/connection.c | 4 +- pinos/client/protocol-native.c | 28 ++---- pinos/modules/module-protocol-native.c | 13 +-- pinos/server/protocol-native.c | 35 +++---- spa/include/spa/defs.h | 1 + spa/include/spa/pod-builder.h | 6 +- spa/include/spa/pod-iter.h | 7 +- spa/include/spa/pod-utils.h | 128 ++++++++++++++---------- spa/lib/debug.c | 6 +- spa/plugins/audiotestsrc/audiotestsrc.c | 4 +- 10 files changed, 121 insertions(+), 111 deletions(-) diff --git a/pinos/client/connection.c b/pinos/client/connection.c index 703f0ad85..4eb3f01dc 100644 --- a/pinos/client/connection.c +++ b/pinos/client/connection.c @@ -277,6 +277,8 @@ again: *dt = buf->data; *sz = buf->size; + spa_debug_pod (data); + return true; } @@ -308,7 +310,7 @@ pinos_connection_end_write (PinosConnection *conn, buf->buffer_size += 8 + size; -// spa_debug_pod (p); + spa_debug_pod (p); pinos_signal_emit (&conn->need_flush, conn); } diff --git a/pinos/client/protocol-native.c b/pinos/client/protocol-native.c index 00d5dae65..ada61bf1f 100644 --- a/pinos/client/protocol-native.c +++ b/pinos/client/protocol-native.c @@ -461,17 +461,11 @@ client_node_marshal_update (void *object, core_update_map (proxy->context); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, + spa_pod_builder_struct (&b.b, &f, SPA_POD_TYPE_INT, change_mask, SPA_POD_TYPE_INT, max_input_ports, SPA_POD_TYPE_INT, max_output_ports, - SPA_POD_TYPE_INT, props ? 1 : 0, - 0); - - if (props) - spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, props, 0); - spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); + SPA_POD_TYPE_POD, props); pinos_connection_end_write (connection, proxy->id, 0, b.b.offset); } @@ -506,12 +500,11 @@ client_node_marshal_port_update (void *object, for (i = 0; i < n_possible_formats; i++) spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, possible_formats[i], 0); - spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, format ? 1 : 0, 0); - if (format) - spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, format, 0); - spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, props ? 1 : 0, 0); - if (props) - spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, props, 0); + spa_pod_builder_add (&b.b, + SPA_POD_TYPE_POD, format, + SPA_POD_TYPE_POD, props, + 0); + spa_pod_builder_add (&b.b, SPA_POD_TYPE_INT, info ? 1 : 0, 0); if (info) { spa_pod_builder_add (&b.b, @@ -678,7 +671,7 @@ client_node_demarshal_set_format (void *object, { PinosProxy *proxy = object; SpaPODIter it; - uint32_t seq, direction, port_id, flags, have_format; + uint32_t seq, direction, port_id, flags; const SpaFormat *format = NULL; if (!spa_pod_iter_struct (&it, data, size) || @@ -687,13 +680,10 @@ client_node_demarshal_set_format (void *object, SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, SPA_POD_TYPE_INT, &flags, - SPA_POD_TYPE_INT, &have_format, + SPA_POD_TYPE_OBJECT, &format, 0)) return false; - if (have_format && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &format, 0)) - return false; - ((PinosClientNodeEvents*)proxy->implementation)->set_format (proxy, seq, direction, port_id, flags, format); return true; diff --git a/pinos/modules/module-protocol-native.c b/pinos/modules/module-protocol-native.c index 09ec5ed6b..1e5aa0598 100644 --- a/pinos/modules/module-protocol-native.c +++ b/pinos/modules/module-protocol-native.c @@ -153,14 +153,15 @@ connection_data (SpaSource *source, } if (opcode >= resource->iface->n_methods) { pinos_log_error ("protocol-native %p: invalid method %u", client->impl, opcode); - continue; + client_destroy (client); + break; } demarshal = resource->iface->methods; - if (demarshal[opcode]) { - if (!demarshal[opcode] (resource, message, size)) - pinos_log_error ("protocol-native %p: invalid message received", client->impl); - } else - pinos_log_error ("protocol-native %p: function %d not implemented", client->impl, opcode); + if (!demarshal[opcode] || !demarshal[opcode] (resource, message, size)) { + pinos_log_error ("protocol-native %p: invalid message received", client->impl); + client_destroy (client); + break; + } } } } diff --git a/pinos/server/protocol-native.c b/pinos/server/protocol-native.c index c11fb46ce..31693727a 100644 --- a/pinos/server/protocol-native.c +++ b/pinos/server/protocol-native.c @@ -619,16 +619,12 @@ client_node_marshal_set_format (void *object, core_update_map (resource->client); - spa_pod_builder_add (&b.b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_INT, flags, - SPA_POD_TYPE_INT, format ? 1 : 0, 0); - if (format) - spa_pod_builder_add (&b.b, SPA_POD_TYPE_POD, format, 0); - spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_struct (&b.b, &f, + SPA_POD_TYPE_INT, seq, + SPA_POD_TYPE_INT, direction, + SPA_POD_TYPE_INT, port_id, + SPA_POD_TYPE_INT, flags, + SPA_POD_TYPE_POD, format); pinos_connection_end_write (connection, resource->id, 4, b.b.offset); } @@ -807,21 +803,18 @@ client_node_demarshal_update (void *object, { PinosResource *resource = object; SpaPODIter it; - uint32_t change_mask, max_input_ports, max_output_ports, have_props; - const SpaProps *props = NULL; + uint32_t change_mask, max_input_ports, max_output_ports; + const SpaProps *props; if (!spa_pod_iter_struct (&it, data, size) || !spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &change_mask, SPA_POD_TYPE_INT, &max_input_ports, SPA_POD_TYPE_INT, &max_output_ports, - SPA_POD_TYPE_INT, &have_props, + SPA_POD_TYPE_OBJECT, &props, 0)) return false; - if (have_props && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &props, 0)) - return false; - ((PinosClientNodeMethods*)resource->implementation)->update (resource, change_mask, max_input_ports, max_output_ports, props); return true; } @@ -852,12 +845,10 @@ client_node_demarshal_port_update (void *object, if (!spa_pod_iter_get (&it,SPA_POD_TYPE_OBJECT, &possible_formats[i], 0)) return false; - if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0) || - (t && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &format, 0))) - return false; - - if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0) || - (t && !spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, &props, 0))) + if (!spa_pod_iter_get (&it, + SPA_POD_TYPE_OBJECT, &format, + SPA_POD_TYPE_OBJECT, &props, + 0)) return false; if (!spa_pod_iter_get (&it, SPA_POD_TYPE_INT, &t, 0)) diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h index ed669bafd..a4f436877 100644 --- a/spa/include/spa/defs.h +++ b/spa/include/spa/defs.h @@ -104,6 +104,7 @@ typedef void (*SpaNotify) (void *data); #define SPA_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) #define SPA_MIN(a,b) ((a)<(b) ? (a) : (b)) #define SPA_MAX(a,b) ((a)>(b) ? (a) : (b)) +#define SPA_ABS(a) ((a)>0 ? (a) : -(a)) #define SPA_CLAMP(v,a,b) ((v)>(b) ? (b) : ((v) < (a) ? (a) : (v))) #define SPA_MEMBER(b,o,t) ((t*)((uint8_t*)(b) + (o))) diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index e11d0b0d0..42413cc77 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -495,7 +495,11 @@ spa_pod_builder_addv (SpaPODBuilder *builder, spa_pod_builder_pop (builder, f); break; case SPA_POD_TYPE_POD: - body = va_arg (args, void *); + if ((body = va_arg (args, void *)) == NULL) { + head.pod.type = SPA_POD_TYPE_NONE; + head.pod.size = 0; + body = &head; + } body_size = SPA_POD_SIZE (body); goto extra; } diff --git a/spa/include/spa/pod-iter.h b/spa/include/spa/pod-iter.h index 86b061041..e1a91e1a3 100644 --- a/spa/include/spa/pod-iter.h +++ b/spa/include/spa/pod-iter.h @@ -121,14 +121,13 @@ spa_pod_iter_getv (SpaPODIter *iter, while (type && (res = spa_pod_iter_has_next (iter))) { SpaPOD *pod = spa_pod_iter_next (iter); - if (type != SPA_POD_TYPE_POD && pod->type != type) - return false; - - SPA_POD_COLLECT (pod, type, args); + SPA_POD_COLLECT (pod, type, args, error); type = va_arg (args, uint32_t); } return res; +error: + return false; } static inline bool diff --git a/spa/include/spa/pod-utils.h b/spa/include/spa/pod-utils.h index 2e0be95a0..e2ce112f4 100644 --- a/spa/include/spa/pod-utils.h +++ b/spa/include/spa/pod-utils.h @@ -24,6 +24,7 @@ extern "C" { #endif +#include #include #include @@ -90,61 +91,78 @@ spa_pod_object_find_prop (const SpaPODObject *obj, uint32_t key) return spa_pod_contents_find_prop (&obj->pod, sizeof (SpaPODObject), key); } -#define SPA_POD_COLLECT(pod,type,args) \ - switch (type) { \ - case SPA_POD_TYPE_BOOL: \ - case SPA_POD_TYPE_URI: \ - case SPA_POD_TYPE_INT: \ - *(va_arg (args, int32_t*)) = SPA_POD_VALUE(SpaPODInt, pod); \ - break; \ - case SPA_POD_TYPE_LONG: \ - *(va_arg (args, int64_t*)) = SPA_POD_VALUE (SpaPODLong, pod); \ - break; \ - case SPA_POD_TYPE_FLOAT: \ - *(va_arg (args, float*)) = SPA_POD_VALUE (SpaPODFloat, pod); \ - break; \ - case SPA_POD_TYPE_DOUBLE: \ - *(va_arg (args, double*)) = SPA_POD_VALUE (SpaPODDouble, pod); \ - break; \ - case SPA_POD_TYPE_STRING: \ - *(va_arg (args, char **)) = SPA_POD_CONTENTS (SpaPODString, pod); \ - break; \ - case -SPA_POD_TYPE_STRING: \ - { \ - char *dest = va_arg (args, char *); \ - uint32_t maxlen = va_arg (args, uint32_t); \ - strncpy (dest, SPA_POD_CONTENTS (SpaPODString, pod), maxlen-1); \ - break; \ +#define SPA_POD_COLLECT(pod,type,args,error) \ + do { \ + if (type == SPA_POD_TYPE_POD) { \ + *(va_arg (args, SpaPOD **)) = pod; \ + } else if ((pod)->type == SPA_POD_TYPE_NONE) { \ + switch (type) { \ + case SPA_POD_TYPE_ARRAY: \ + case SPA_POD_TYPE_STRUCT: \ + case SPA_POD_TYPE_OBJECT: \ + case SPA_POD_TYPE_PROP: \ + *(va_arg (args, SpaPOD **)) = NULL; \ + break; \ + default: \ + goto error; \ } \ - case SPA_POD_TYPE_BYTES: \ - *(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); \ - *(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \ - break; \ - case SPA_POD_TYPE_POINTER: \ - { \ - SpaPODPointerBody *b = SPA_POD_BODY (pod); \ - *(va_arg (args, void **)) = b->value; \ - break; \ + } else if ((pod)->type == type) { \ + switch (type) { \ + case SPA_POD_TYPE_BOOL: \ + case SPA_POD_TYPE_URI: \ + case SPA_POD_TYPE_INT: \ + *(va_arg (args, int32_t*)) = SPA_POD_VALUE(SpaPODInt, pod); \ + break; \ + case SPA_POD_TYPE_LONG: \ + *(va_arg (args, int64_t*)) = SPA_POD_VALUE (SpaPODLong, pod); \ + break; \ + case SPA_POD_TYPE_FLOAT: \ + *(va_arg (args, float*)) = SPA_POD_VALUE (SpaPODFloat, pod); \ + break; \ + case SPA_POD_TYPE_DOUBLE: \ + *(va_arg (args, double*)) = SPA_POD_VALUE (SpaPODDouble, pod); \ + break; \ + case SPA_POD_TYPE_STRING: \ + *(va_arg (args, char **)) = SPA_POD_CONTENTS (SpaPODString, pod); \ + break; \ + case -SPA_POD_TYPE_STRING: \ + { \ + char *dest = va_arg (args, char *); \ + uint32_t maxlen = va_arg (args, uint32_t); \ + strncpy (dest, SPA_POD_CONTENTS (SpaPODString, pod), maxlen-1); \ + break; \ + } \ + case SPA_POD_TYPE_BYTES: \ + *(va_arg (args, void **)) = SPA_POD_CONTENTS (SpaPODBytes, pod); \ + *(va_arg (args, uint32_t *)) = SPA_POD_BODY_SIZE (pod); \ + break; \ + case SPA_POD_TYPE_POINTER: \ + { \ + SpaPODPointerBody *b = SPA_POD_BODY (pod); \ + *(va_arg (args, void **)) = b->value; \ + break; \ + } \ + case SPA_POD_TYPE_RECTANGLE: \ + *(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \ + break; \ + case SPA_POD_TYPE_FRACTION: \ + *(va_arg (args, SpaFraction *)) = SPA_POD_VALUE (SpaPODFraction, pod); \ + break; \ + case SPA_POD_TYPE_BITMASK: \ + *(va_arg (args, uint32_t **)) = SPA_POD_CONTENTS (SpaPOD, pod); \ + break; \ + case SPA_POD_TYPE_ARRAY: \ + case SPA_POD_TYPE_STRUCT: \ + case SPA_POD_TYPE_OBJECT: \ + case SPA_POD_TYPE_PROP: \ + *(va_arg (args, SpaPOD **)) = pod; \ + break; \ + default: \ + goto error; \ } \ - case SPA_POD_TYPE_RECTANGLE: \ - *(va_arg (args, SpaRectangle *)) = SPA_POD_VALUE (SpaPODRectangle, pod); \ - break; \ - case SPA_POD_TYPE_FRACTION: \ - *(va_arg (args, SpaFraction *)) = SPA_POD_VALUE (SpaPODFraction, pod); \ - break; \ - case SPA_POD_TYPE_BITMASK: \ - *(va_arg (args, uint32_t **)) = SPA_POD_CONTENTS (SpaPOD, pod); \ - break; \ - case SPA_POD_TYPE_ARRAY: \ - case SPA_POD_TYPE_STRUCT: \ - case SPA_POD_TYPE_OBJECT: \ - case SPA_POD_TYPE_PROP: \ - case SPA_POD_TYPE_POD: \ - *(va_arg (args, SpaPOD **)) = pod; \ - break; \ - default: \ - break; \ - } \ + } else \ + goto error; \ + } while (false); \ #define SPA_POD_COLLECT_SKIP(type,args) \ switch (type) { \ @@ -184,13 +202,13 @@ spa_pod_contents_queryv (const SpaPOD *pod, uint32_t offset, uint32_t key, va_li type = va_arg (args, uint32_t); if (prop && prop->body.key == key && - (type == SPA_POD_TYPE_POD || prop->body.value.type == type) && !(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) { - SPA_POD_COLLECT (&prop->body.value, type, args); + SPA_POD_COLLECT (&prop->body.value, type, args, next); count++; } else { SPA_POD_COLLECT_SKIP (type, args); } +next: key = va_arg (args, uint32_t); } return count; diff --git a/spa/lib/debug.c b/spa/lib/debug.c index 9cddd3843..2c660ba73 100644 --- a/spa/lib/debug.c +++ b/spa/lib/debug.c @@ -187,7 +187,7 @@ struct pod_type_name { const char *CCName; } pod_type_names[] = { { "invalid", "*Invalid*" }, - { "ignored", "ignored" }, + { "none", "None" }, { "bool", "Bool" }, { "uri", "URI" }, { "int", "Int" }, @@ -310,6 +310,10 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix) printf ("%-*sBytes\n", prefix, ""); spa_debug_dump_mem (body, size); break; + case SPA_POD_TYPE_NONE: + printf ("%-*sNone\n", prefix, ""); + spa_debug_dump_mem (body, size); + break; default: printf ("unhandled POD type %d\n", type); break; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 1c1834e94..9333ae036 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -69,8 +69,8 @@ init_uri (URI *uri, SpaIDMap *map) uri->prop_wave = spa_id_map_get_id (map, SPA_PROPS__waveType); uri->prop_freq = spa_id_map_get_id (map, SPA_PROPS__frequency); uri->prop_volume = spa_id_map_get_id (map, SPA_PROPS__volume); - uri->wave_sine = spa_id_map_get_id (map, SPA_PROPS__waveType ":Sine"); - uri->wave_square = spa_id_map_get_id (map, SPA_PROPS__waveType ":Square"); + uri->wave_sine = spa_id_map_get_id (map, SPA_PROPS__waveType ":sine"); + uri->wave_square = spa_id_map_get_id (map, SPA_PROPS__waveType ":square"); spa_media_types_fill (&uri->media_types, map); spa_media_subtypes_map (map, &uri->media_subtypes); spa_prop_audio_map (map, &uri->prop_audio);