wp_spa_json_builder_add_string() does not work with zero length strings
void
wp_spa_json_builder_add_string (WpSpaJsonBuilder *self, const gchar *value)
{
size_t size = (strlen (value) * 4) + 2;
gchar dst[size];
gint enc_size;
ensure_separator (self, FALSE);
ensure_allocated_max_size (self, size);
enc_size = spa_json_encode_string (dst, sizeof(dst), value);
builder_add (self, dst, enc_size);
}
When value
is empty size == 2
, so dst
won't be null terminated, but in builder_add()
it is passed as an argument to %s
, which expects a null terminated string.
Also, contrary to what 10f85549 says, spa_json_encode_string()
does add a null terminator (if there is enough space).
Maybe memcpy()
could be used instead of snprintf()
in builder_add()
. Or I think the whole VLA could be removed with something like:
--- a/lib/wp/spa-json.c
+++ b/lib/wp/spa-json.c
@@ -1074,13 +1074,17 @@ wp_spa_json_builder_add_float (WpSpaJsonBuilder *self, float value)
void
wp_spa_json_builder_add_string (WpSpaJsonBuilder *self, const gchar *value)
{
- size_t size = (strlen (value) * 4) + 2;
- gchar dst[size];
gint enc_size;
ensure_separator (self, FALSE);
- ensure_allocated_max_size (self, size);
- enc_size = spa_json_encode_string (dst, sizeof(dst), value);
- builder_add (self, dst, enc_size);
+
+ enc_size = spa_json_encode_string (self->data + self->size, self->max_size - self->size, value);
+ if (enc_size + 1 > self->max_size - self->size) {
+ ensure_allocated_max_size (self, enc_size);
+ enc_size = spa_json_encode_string (self->data + self->size, self->max_size - self->size, value);
+ g_assert (enc_size < self->max_size - self->size);
+ }
+
+ self->size += enc_size;
}
/*!
Due to the exponential growth of the buffer, I feel like it might be better to optimistically try to encode right into the buffer.
Edited by Barnabás Pőcze