[json-glib/handle-utf8-bom] parser: Ignore UTF-8 BOM if necessary




commit 45981321e655a2712aea37eb458a5b47ac60fcf5
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Tue Dec 29 11:31:38 2020 +0100

    parser: Ignore UTF-8 BOM if necessary
    
    According to JSON spec BOM shouldn't be part of the JSON data, but
    also recommends to tolerate files with a BOM marker. As this is common
    in several Windows JSON generators, handle it graceful in json-glib and
    skip it for UTF-8 BOM.
    
    Fixes: https://gitlab.gnome.org/GNOME/json-glib/-/issues/56

 json-glib/json-parser.c       | 15 ++++++++++++++-
 json-glib/tests/messages.json |  3 +++
 json-glib/tests/reader.c      | 27 +++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 1 deletion(-)
---
diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c
index 4e08848..7381697 100644
--- a/json-glib/json-parser.c
+++ b/json-glib/json-parser.c
@@ -970,7 +970,7 @@ json_parser_new_immutable (void)
 
 static gboolean
 json_parser_load (JsonParser   *parser,
-                  const gchar  *data,
+                  const gchar  *input_data,
                   gsize         length,
                   GError      **error)
 {
@@ -979,6 +979,7 @@ json_parser_load (JsonParser   *parser,
   gboolean done;
   gboolean retval = TRUE;
   gint i;
+  gchar *data = input_data;
 
   json_parser_clear (parser);
 
@@ -991,6 +992,18 @@ json_parser_load (JsonParser   *parser,
       return FALSE;
     }
 
+  if (length >= 3)
+    {
+      /* Check for UTF-8 signature and skip it if necessary */
+       if (((data[0] & 0xFF) == 0xEF) &&
+           ((data[1] & 0xFF) == 0xBB) &&
+           ((data[2] & 0xFF) == 0xBF))
+         {
+           data += 3;
+           length -= 3;
+         }
+    }
+
   scanner = json_scanner_create (parser);
   json_scanner_input_text (scanner, data, length);
 
diff --git a/json-glib/tests/messages.json b/json-glib/tests/messages.json
new file mode 100644
index 0000000..9362585
--- /dev/null
+++ b/json-glib/tests/messages.json
@@ -0,0 +1,3 @@
+{
+       "appName": "Sample WebExtensions"
+}
diff --git a/json-glib/tests/reader.c b/json-glib/tests/reader.c
index d0a046b..be7051c 100644
--- a/json-glib/tests/reader.c
+++ b/json-glib/tests/reader.c
@@ -212,6 +212,32 @@ test_reader_null_value (void)
   g_object_unref (parser);
 }
 
+static void
+test_reader_bom (void)
+{
+  JsonParser *parser = json_parser_new ();
+  JsonReader *reader = json_reader_new (NULL);
+  GError *error = NULL;
+  char *path;
+
+  path = g_test_build_filename (G_TEST_DIST, "messages.json", NULL);
+
+  json_parser_load_from_mapped_file (parser, path, &error);
+  g_assert_no_error (error);
+
+  json_reader_set_root (reader, json_parser_get_root (parser));
+
+  json_reader_read_member (reader, "appName");
+  g_assert_true (json_reader_is_value (reader));
+  g_assert_no_error (json_reader_get_error (reader));
+  g_assert_nonnull (json_reader_get_value (reader));
+  g_print ("Got: %s\n", json_reader_get_string_value (reader));
+
+  g_free (path);
+  g_object_unref (reader);
+  g_object_unref (parser);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -223,6 +249,7 @@ main (int   argc,
   g_test_add_func ("/reader/base-object", test_base_object);
   g_test_add_func ("/reader/level", test_reader_level);
   g_test_add_func ("/reader/null-value", test_reader_null_value);
+  g_test_add_func ("/reader/bom", test_reader_bom);
 
   return g_test_run ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]