|
@@ -0,0 +1,215 @@
|
|
|
+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
|
|
|
+
|