123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- From e429db7e8c266045aee25e153fb2308bd61fe233 Mon Sep 17 00:00:00 2001
- From: Julian Bouzas <julian.bouzas@collabora.com>
- Date: Wed, 9 Feb 2022 07:59:59 -0500
- Subject: [PATCH] spa-json: fix va_list APIs for different architectures
- The va_list type might not always be a pointer in some architectures, so we
- cannot guarantee it will be modified after using it for a second time in another
- function. This fixes the issue by using macros so args does not get copied, and
- always gets modified when using it more than once.
- Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
- Upstream: https://gitlab.freedesktop.org/pipewire/wireplumber/-/commit/e429db7e8c266045aee25e153fb2308bd61fe233
- ---
- lib/wp/spa-json.c | 156 ++++++++++++++++++++++++----------------------
- 1 file changed, 80 insertions(+), 76 deletions(-)
- diff --git a/lib/wp/spa-json.c b/lib/wp/spa-json.c
- index f14f395d..c5e59a3e 100644
- --- a/lib/wp/spa-json.c
- +++ b/lib/wp/spa-json.c
- @@ -363,33 +363,33 @@ wp_spa_json_new_string (const gchar *value)
- wp_spa_json_builder_new_formatted ("\"%s\"", value));
- }
-
- -static void
- -wp_spa_json_builder_add_value (WpSpaJsonBuilder *self, const gchar *fmt,
- - va_list args)
- -{
- - switch (*fmt) {
- - case 'n':
- - wp_spa_json_builder_add_null (self);
- - break;
- - case 'b':
- - wp_spa_json_builder_add_boolean (self, va_arg(args, gboolean));
- - break;
- - case 'i':
- - wp_spa_json_builder_add_int (self, va_arg(args, gint));
- - break;
- - case 'f':
- - wp_spa_json_builder_add_float (self, (float)va_arg(args, double));
- - break;
- - case 's':
- - wp_spa_json_builder_add_string (self, va_arg(args, const gchar *));
- - break;
- - case 'J':
- - wp_spa_json_builder_add_json (self, va_arg(args, WpSpaJson *));
- - break;
- - default:
- - return;
- - }
- -}
- +/* Args is not a pointer in some architectures, so this needs to be a macro to
- + * avoid args being copied */
- +#define wp_spa_json_builder_add_value(self,fmt,args) \
- +do { \
- + switch (*fmt) { \
- + case 'n': \
- + wp_spa_json_builder_add_null (self); \
- + break; \
- + case 'b': \
- + wp_spa_json_builder_add_boolean (self, va_arg(args, gboolean)); \
- + break; \
- + case 'i': \
- + wp_spa_json_builder_add_int (self, va_arg(args, gint)); \
- + break; \
- + case 'f': \
- + wp_spa_json_builder_add_float (self, (float)va_arg(args, double)); \
- + break; \
- + case 's': \
- + wp_spa_json_builder_add_string (self, va_arg(args, const gchar *)); \
- + break; \
- + case 'J': \
- + wp_spa_json_builder_add_json (self, va_arg(args, WpSpaJson *)); \
- + break; \
- + default: \
- + break; \
- + } \
- +} while(false)
-
- /*!
- * \brief Creates a spa json of type array
- @@ -724,48 +724,46 @@ wp_spa_json_parse_object_valist (WpSpaJson *self, va_list args)
- return res;
- }
-
- -static gboolean
- -wp_spa_json_parse_value (const gchar *data, int len, const gchar *fmt,
- - va_list args)
- -{
- - switch (*fmt) {
- - case 'n':
- - if (!spa_json_is_null (data, len))
- - return FALSE;
- - break;
- - case 'b':
- - if (!wp_spa_json_parse_boolean_internal (data, len,
- - va_arg(args, gboolean *)))
- - return FALSE;
- - break;
- - case 'i':
- - if (spa_json_parse_int (data, len, va_arg(args, gint *)) < 0)
- - return FALSE;
- - break;
- - case 'f':
- - if (spa_json_parse_float (data, len,
- - (float *)va_arg(args, double *)) < 0)
- - return FALSE;
- - break;
- - case 's': {
- - gchar *str = wp_spa_json_parse_string_internal (data, len);
- - if (!str)
- - return FALSE;
- - *va_arg(args, gchar **) = str;
- - break;
- - }
- - case 'J': {
- - WpSpaJson *j = wp_spa_json_new (data, len);
- - if (!j)
- - return FALSE;
- - *va_arg(args, WpSpaJson **) = j;
- - break;
- - }
- - default:
- - return FALSE;
- - }
- - return TRUE;
- -}
- +/* Args is not a pointer in some architectures, so this needs to be a macro to
- + * avoid args being copied */
- +#define wp_spa_json_parse_value(data,len,fmt,args) \
- +do { \
- + switch (*fmt) { \
- + case 'n': \
- + if (!spa_json_is_null (data, len)) \
- + return FALSE; \
- + break; \
- + case 'b': \
- + if (!wp_spa_json_parse_boolean_internal (data, len, \
- + va_arg(args, gboolean *))) \
- + return FALSE; \
- + break; \
- + case 'i': \
- + if (spa_json_parse_int (data, len, va_arg(args, gint *)) < 0) \
- + return FALSE; \
- + break; \
- + case 'f': \
- + if (spa_json_parse_float (data, len, va_arg(args, float *)) < 0) \
- + return FALSE; \
- + break; \
- + case 's': { \
- + gchar *str = wp_spa_json_parse_string_internal (data, len); \
- + if (!str) \
- + return FALSE; \
- + *va_arg(args, gchar **) = str; \
- + break; \
- + } \
- + case 'J': { \
- + WpSpaJson *j = wp_spa_json_new (data, len); \
- + if (!j) \
- + return FALSE; \
- + *va_arg(args, WpSpaJson **) = j; \
- + break; \
- + } \
- + default: \
- + return FALSE; \
- + } \
- +} while(false)
-
- /*!
- * \brief Parses the object property values of a spa json object
- @@ -827,8 +825,7 @@ wp_spa_json_object_get_valist (WpSpaJson *self, va_list args)
- value = g_value_get_boxed (&item);
-
- if (g_strcmp0 (key_str, lookup_key) == 0) {
- - if (!wp_spa_json_parse_value (value->data, value->size, lookup_fmt, args))
- - return FALSE;
- + wp_spa_json_parse_value (value->data, value->size, lookup_fmt, args);
- lookup_key = va_arg(args, const gchar *);
- if (!lookup_key)
- return TRUE;
- @@ -1366,9 +1363,12 @@ gboolean
- wp_spa_json_parser_get_value (WpSpaJsonParser *self, const gchar *fmt,
- va_list args)
- {
- - return wp_spa_json_parser_advance (self) &&
- - wp_spa_json_parse_value (self->curr.cur,
- - self->curr.end - self->curr.cur, fmt, args);
- + if (wp_spa_json_parser_advance (self)) {
- + wp_spa_json_parse_value (self->curr.cur, self->curr.end - self->curr.cur,
- + fmt, args);
- + return TRUE;
- + }
- + return FALSE;
- }
-
- /*!
- @@ -1419,9 +1419,13 @@ wp_spa_json_parser_get_valist (WpSpaJsonParser *self, va_list args)
- if (!format)
- return TRUE;
-
- - /* parse value */
- - if (!wp_spa_json_parser_get_value (self, format, args))
- + /* advance */
- + if (!wp_spa_json_parser_advance (self))
- return FALSE;
- +
- + /* parse value */
- + wp_spa_json_parse_value (self->curr.cur, self->curr.end - self->curr.cur,
- + format, args);
- } while (TRUE);
-
- return FALSE;
- --
- GitLab
|