[vlc-commits] [Git][videolan/vlc][master] 2 commits: json: fix escaping quotes, backslash and slash

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Aug 6 17:32:11 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
81697b56 by Alexandre Janniaux at 2026-08-06T17:17:37+00:00
json: fix escaping quotes, backslash and slash

The escaped character was consumed but never stored, so the output kept
the backslash that `c` had been initialised with \" decoded to \
instead of ", and \/ to \ instead of /. Only \\ was correct.

Because of this, any JSON string containing a quote was mangled.

- - - - -
637e6f08 by Alexandre Janniaux at 2026-08-06T17:17:37+00:00
test: json: add a regression test for the string escapes

The two-character escapes are checked to decode to the character they
are supposed to be escaping, and to not swallow the character after
them.

- - - - -


4 changed files:

- modules/demux/json/json.c
- test/Makefile.am
- + test/modules/demux/json.c
- test/modules/meson.build


Changes:

=====================================
modules/demux/json/json.c
=====================================
@@ -75,10 +75,13 @@ char *json_unescape(const char *in, size_t inlen)
         uint16_t c = *(in2++);
 
         if (c == '\\') {
-            switch (*(in2++)) {
+            uint16_t esc = *(in2++);
+
+            switch (esc) {
                 case '"':
                 case '\\':
                 case '/':
+                    c = esc;
                     break;
                 case 'b':
                     c = '\b';


=====================================
test/Makefile.am
=====================================
@@ -83,6 +83,7 @@ check_PROGRAMS = \
 	test_modules_codec_cea708_aspect_ratio \
 	test_modules_codec_cea708_integration \
 	test_modules_keystore \
+	test_modules_demux_json \
 	test_modules_demux_libmp4 \
 	test_modules_demux_timestamps \
 	test_modules_demux_timestamps_filter \
@@ -355,6 +356,9 @@ test_modules_keystore_SOURCES = modules/keystore/test.c
 test_modules_keystore_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_modules_tls_SOURCES = modules/misc/tls.c
 test_modules_tls_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_demux_json_SOURCES = modules/demux/json.c \
+				../modules/demux/json/json.h
+test_modules_demux_json_LDADD = $(LIBVLCCORE) ../modules/libvlc_json.la
 test_modules_demux_libmp4_LDADD = $(LIBVLCCORE) $(LIBVLC) $(LIBM) $(LIBZ)
 test_modules_demux_libmp4_SOURCES = modules/demux/libmp4.c \
 				../modules/demux/mp4/libmp4.c \


=====================================
test/modules/demux/json.c
=====================================
@@ -0,0 +1,108 @@
+/*****************************************************************************
+ * json.c: test for the JSON parsing library
+ *****************************************************************************
+ * Copyright (C) 2026 Alexandre Janniaux <ajanni at videolabs.io>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vlc_common.h>
+
+#include "../modules/demux/json/json.h"
+
+struct reader {
+    const char *buf;
+    size_t len;
+};
+
+size_t json_read(void *opaque, void *buf, size_t max)
+{
+    struct reader *reader = opaque;
+    size_t len = reader->len < max ? reader->len : max;
+
+    memcpy(buf, reader->buf, len);
+    reader->buf += len;
+    reader->len -= len;
+    return len;
+}
+
+void json_parse_error(void *opaque, const char *msg)
+{
+    (void) opaque;
+    fprintf(stderr, "json parse error: %s\n", msg);
+}
+
+static int parse(const char *doc, struct json_object *obj)
+{
+    struct reader reader = { doc, strlen(doc) };
+
+    return json_parse(&reader, obj);
+}
+
+/* Checks that `escaped`, used as the body of a JSON string, decodes
+ * to `expected`. */
+static void assert_unescapes_to(const char *escaped, const char *expected)
+{
+    char *doc;
+
+    assert(asprintf(&doc, "{ \"v\": \"%s\" }", escaped) >= 0);
+
+    struct json_object obj;
+    assert(parse(doc, &obj) == 0);
+
+    const char *value = json_get_str(&obj, "v");
+    assert(value != NULL);
+
+    if (strcmp(value, expected) != 0)
+        fprintf(stderr, "unescaping \"%s\": got \"%s\", expected \"%s\"\n",
+                escaped, value, expected);
+    assert(strcmp(value, expected) == 0);
+
+    json_free(&obj);
+    free(doc);
+}
+
+static void test_two_character_escapes(void)
+{
+    assert_unescapes_to("\\\"", "\"");
+    assert_unescapes_to("\\\\", "\\");
+    assert_unescapes_to("\\/", "/");
+    assert_unescapes_to("\\b", "\b");
+    assert_unescapes_to("\\f", "\f");
+    assert_unescapes_to("\\n", "\n");
+    assert_unescapes_to("\\r", "\r");
+    assert_unescapes_to("\\t", "\t");
+
+    /* an escape must not swallow the character behind it */
+    assert_unescapes_to("a\\\"b\\\\c\\/d", "a\"b\\c/d");
+    assert_unescapes_to("\\\\\\\"", "\\\"");
+    assert_unescapes_to("\\\"\\\"", "\"\"");
+}
+
+int main(void)
+{
+    test_two_character_escapes();
+    return 0;
+}


=====================================
test/modules/meson.build
=====================================
@@ -83,6 +83,13 @@ vlc_tests += {
 }
 endif
 
+vlc_tests += {
+    'name' : 'test_modules_demux_json',
+    'sources' : files('demux/json.c'),
+    'suite' : ['modules', 'test_modules'],
+    'link_with' : [vlc_json_lib, libvlccore],
+}
+
 vlc_tests += {
     'name' : 'test_modules_demux_libmp4',
     'sources' : files(



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ce7c67776dff8a469a4aa7b5f9eb54702b4cdc21...637e6f08e57e6cbc9e2092206f5ddda93773e173

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ce7c67776dff8a469a4aa7b5f9eb54702b4cdc21...637e6f08e57e6cbc9e2092206f5ddda93773e173
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list