From 71a86877b7287001219af6ea3aabafef779447a2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 28 Jan 2022 10:01:12 +0100 Subject: [PATCH] modules: refactor parse_dict Make a macro from parse_dict and move the n_items parsing and alloca in it. This should make it easier to check the data. See #2070 --- .../module-client-device/protocol-native.c | 45 +++--- .../module-client-node/protocol-native.c | 72 ++++------ .../module-protocol-native/protocol-native.c | 130 +++++------------- 3 files changed, 86 insertions(+), 161 deletions(-) diff --git a/src/modules/module-client-device/protocol-native.c b/src/modules/module-client-device/protocol-native.c index 950e7b015..77bfbe7dd 100644 --- a/src/modules/module-client-device/protocol-native.c +++ b/src/modules/module-client-device/protocol-native.c @@ -55,16 +55,20 @@ static inline int parse_item(struct spa_pod_parser *prs, struct spa_dict_item *i return 0; } -static inline int parse_dict(struct spa_pod_parser *prs, struct spa_dict *dict) -{ - uint32_t i; - int res; - for (i = 0; i < dict->n_items; i++) { - if ((res = parse_item(prs, (struct spa_dict_item *) &dict->items[i])) < 0) - return res; - } - return 0; -} +#define parse_dict(prs,d) \ +do { \ + uint32_t i; \ + if (spa_pod_parser_get(prs, \ + SPA_POD_Int(&(d)->n_items), NULL) < 0) \ + return -EINVAL; \ + if ((d)->n_items > 0) { \ + (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ + for (i = 0; i < (d)->n_items; i++) { \ + if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ + return -EINVAL; \ + } \ + } \ +} while(0) static int device_marshal_add_listener(void *object, struct spa_hook *listener, @@ -259,21 +263,17 @@ static int device_demarshal_info(void *object, if (spa_pod_parser_push_struct(&p2, &f2) < 0 || spa_pod_parser_get(&p2, SPA_POD_Long(&info.change_mask), - SPA_POD_Long(&info.flags), - SPA_POD_Int(&props.n_items), NULL) < 0) + SPA_POD_Long(&info.flags), NULL) < 0) return -EINVAL; info.change_mask &= SPA_DEVICE_CHANGE_MASK_FLAGS | SPA_DEVICE_CHANGE_MASK_PROPS | SPA_DEVICE_CHANGE_MASK_PARAMS; - if (props.n_items > 0) { + parse_dict(&p2, &props); + if (props.n_items > 0) info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&p2, &props) < 0) - return -EINVAL; - } if (spa_pod_parser_get(&p2, SPA_POD_Int(&info.n_params), NULL) < 0) return -EINVAL; @@ -467,20 +467,15 @@ static int device_demarshal_object_info(void *object, spa_pod_parser_get(&p2, SPA_POD_String(&info.type), SPA_POD_Long(&info.change_mask), - SPA_POD_Long(&info.flags), - SPA_POD_Int(&props.n_items), NULL) < 0) + SPA_POD_Long(&info.flags), NULL) < 0) return -EINVAL; info.change_mask &= SPA_DEVICE_OBJECT_CHANGE_MASK_FLAGS | SPA_DEVICE_CHANGE_MASK_PROPS; - if (props.n_items > 0) { + parse_dict(&p2, &props); + if (props.n_items > 0) info.props = &props; - - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&p2, &props) < 0) - return -EINVAL; - } } else { infop = NULL; } diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 7eb199faf..708ff6077 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -73,16 +73,28 @@ static inline int parse_item(struct spa_pod_parser *prs, struct spa_dict_item *i return 0; } -static inline int parse_dict(struct spa_pod_parser *prs, struct spa_dict *dict) -{ - uint32_t i; - int res; - for (i = 0; i < dict->n_items; i++) { - if ((res = parse_item(prs, (struct spa_dict_item *) &dict->items[i])) < 0) - return res; - } - return 0; -} +#define parse_dict(prs,d) \ +do { \ + uint32_t i; \ + if (spa_pod_parser_get(prs, \ + SPA_POD_Int(&(d)->n_items), NULL) < 0) \ + return -EINVAL; \ + if ((d)->n_items > 0) { \ + (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ + for (i = 0; i < (d)->n_items; i++) { \ + if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ + return -EINVAL; \ + } \ + } \ +} while(0) + +#define parse_dict_struct(prs,f,dict) \ +do { \ + if (spa_pod_parser_push_struct(prs, f) < 0) \ + return -EINVAL; \ + parse_dict(prs, dict); \ + spa_pod_parser_pop(prs, f); \ +} while(0) static int client_node_marshal_add_listener(void *object, struct spa_hook *listener, @@ -407,15 +419,7 @@ static int client_node_demarshal_add_port(void *object, const struct pw_protocol SPA_POD_Int(&port_id), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0) - return -EINVAL; - if (spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; - - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); pw_proxy_notify(proxy, struct pw_client_node_events, add_port, 0, direction, port_id, props.n_items ? &props : NULL); @@ -594,15 +598,7 @@ static int client_node_demarshal_port_set_mix_info(void *object, const struct pw SPA_POD_Int(&peer_id), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0) - return -EINVAL; - if (spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; - - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); pw_proxy_notify(proxy, struct pw_client_node_events, port_set_mix_info, 1, direction, port_id, mix_id, @@ -960,21 +956,17 @@ static int client_node_demarshal_update(void *object, const struct pw_protocol_n SPA_POD_Int(&info.max_input_ports), SPA_POD_Int(&info.max_output_ports), SPA_POD_Long(&info.change_mask), - SPA_POD_Long(&info.flags), - SPA_POD_Int(&props.n_items), NULL) < 0) + SPA_POD_Long(&info.flags), NULL) < 0) return -EINVAL; info.change_mask &= SPA_NODE_CHANGE_MASK_FLAGS | SPA_NODE_CHANGE_MASK_PROPS | SPA_NODE_CHANGE_MASK_PARAMS; - if (props.n_items > 0) { + parse_dict(&p2, &props); + if (props.n_items > 0) info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&p2, &props) < 0) - return -EINVAL; - } if (spa_pod_parser_get(&p2, SPA_POD_Int(&info.n_params), NULL) < 0) return -EINVAL; @@ -1037,8 +1029,7 @@ static int client_node_demarshal_port_update(void *object, const struct pw_proto SPA_POD_Long(&info.change_mask), SPA_POD_Long(&info.flags), SPA_POD_Int(&info.rate.num), - SPA_POD_Int(&info.rate.denom), - SPA_POD_Int(&props.n_items), NULL) < 0) + SPA_POD_Int(&info.rate.denom), NULL) < 0) return -EINVAL; info.change_mask &= SPA_PORT_CHANGE_MASK_FLAGS | @@ -1046,13 +1037,10 @@ static int client_node_demarshal_port_update(void *object, const struct pw_proto SPA_PORT_CHANGE_MASK_PROPS | SPA_PORT_CHANGE_MASK_PARAMS; - if (props.n_items > 0) { + parse_dict(&p2, &props); + if (props.n_items > 0) info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&p2, &props) < 0) - return -EINVAL; - } if (spa_pod_parser_get(&p2, SPA_POD_Int(&info.n_params), NULL) < 0) return -EINVAL; diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index c796fc318..6feebaa71 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -167,16 +167,29 @@ static inline int parse_item(struct spa_pod_parser *prs, struct spa_dict_item *i return 0; } -static inline int parse_dict(struct spa_pod_parser *prs, struct spa_dict *dict) -{ - uint32_t i; - int res; - for (i = 0; i < dict->n_items; i++) { - if ((res = parse_item(prs, (struct spa_dict_item *) &dict->items[i])) < 0) - return res; - } - return 0; -} +#define parse_dict(prs,d) \ +do { \ + if (spa_pod_parser_get(prs, \ + SPA_POD_Int(&(d)->n_items), NULL) < 0) \ + return -EINVAL; \ + if ((d)->n_items > 0) { \ + uint32_t i; \ + (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ + for (i = 0; i < (d)->n_items; i++) { \ + if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ + return -EINVAL; \ + } \ + } \ +} while(0) + +#define parse_dict_struct(prs,f,dict) \ +do { \ + if (spa_pod_parser_push_struct(prs, f) < 0) \ + return -EINVAL; \ + parse_dict(prs, dict); \ + spa_pod_parser_pop(prs, f); \ +} while(0) + static void push_params(struct spa_pod_builder *b, uint32_t n_params, const struct spa_param_info *params) @@ -264,16 +277,10 @@ static int core_event_demarshal_info(void *object, const struct pw_protocol_nati SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0) - return -EINVAL; - if (spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; return pw_proxy_notify(proxy, struct pw_core_events, info, 0, &info); } @@ -611,15 +618,7 @@ static int core_method_demarshal_create_object(void *object, const struct pw_pro NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; - - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; - spa_pod_parser_pop(&prs, &f[1]); + parse_dict_struct(&prs, &f[1], &props); if (spa_pod_parser_get(&prs, SPA_POD_Int(&new_id), NULL) < 0) @@ -782,15 +781,9 @@ static int module_demarshal_info(void *object, const struct pw_protocol_native_m SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; return pw_proxy_notify(proxy, struct pw_module_events, info, 0, &info); } @@ -841,16 +834,9 @@ static int device_demarshal_info(void *object, const struct pw_protocol_native_m SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; - spa_pod_parser_pop(&prs, &f[1]); if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || spa_pod_parser_get(&prs, @@ -1062,15 +1048,9 @@ static int factory_demarshal_info(void *object, const struct pw_protocol_native_ SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; return pw_proxy_notify(proxy, struct pw_factory_events, info, 0, &info); } @@ -1133,16 +1113,9 @@ static int node_demarshal_info(void *object, const struct pw_protocol_native_mes SPA_POD_String(&info.error), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; - spa_pod_parser_pop(&prs, &f[1]); if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || spa_pod_parser_get(&prs, @@ -1377,16 +1350,9 @@ static int port_demarshal_info(void *object, const struct pw_protocol_native_mes SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; - spa_pod_parser_pop(&prs, &f[1]); if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || spa_pod_parser_get(&prs, @@ -1559,15 +1525,9 @@ static int client_demarshal_info(void *object, const struct pw_protocol_native_m SPA_POD_Long(&info.change_mask), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; return pw_proxy_notify(proxy, struct pw_client_events, info, 0, &info); } @@ -1700,15 +1660,10 @@ static int client_demarshal_update_properties(void *object, const struct pw_prot struct spa_pod_frame f[2]; spa_pod_parser_init(&prs, msg->data, msg->size); - if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || - spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) + if (spa_pod_parser_push_struct(&prs, &f[0]) < 0) return -EINVAL; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); return pw_resource_notify(resource, struct pw_client_methods, update_properties, 0, &props); @@ -1833,15 +1788,9 @@ static int link_demarshal_info(void *object, const struct pw_protocol_native_mes SPA_POD_Pod(&info.format), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); info.props = &props; - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; return pw_proxy_notify(proxy, struct pw_link_events, info, 0, &info); } @@ -1864,14 +1813,7 @@ static int registry_demarshal_global(void *object, const struct pw_protocol_nati SPA_POD_Int(&version), NULL) < 0) return -EINVAL; - if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || - spa_pod_parser_get(&prs, - SPA_POD_Int(&props.n_items), NULL) < 0) - return -EINVAL; - - props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); - if (parse_dict(&prs, &props) < 0) - return -EINVAL; + parse_dict_struct(&prs, &f[1], &props); return pw_proxy_notify(proxy, struct pw_registry_events, global, 0, id, permissions, type, version,