[Groonga-commit] groonga/groonga [master] add error check to JSON reader. #807

Back to archive index

null+****@clear***** null+****@clear*****
2010年 12月 29日 (水) 17:58:04 JST


Kouhei Sutou	2010-12-29 08:58:04 +0000 (Wed, 29 Dec 2010)

  New Revision: 6b3f6c68d64f24a133e200c3b9375ccd23f83e8a

  Log:
    add error check to JSON reader. #807

  Modified files:
    lib/db.c
    test/unit/core/test-command-load.c

  Modified: lib/db.c (+41 -10)
===================================================================
--- lib/db.c    2010-12-29 09:51:04 +0000 (a45faa8)
+++ lib/db.c    2010-12-29 08:58:04 +0000 (4077b0f)
@@ -7736,6 +7736,22 @@ brace_close(grn_ctx *ctx, grn_loader *loader)
   }
 }
 
+#define JSON_READ_OPEN_BRACKET() {\
+  GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
+  values_add(ctx, loader);\
+  loader->last->header.domain = OPEN_BRACKET;\
+  loader->stat = GRN_LOADER_TOKEN;\
+  str++;\
+}\
+
+#define JSON_READ_OPEN_BRACE() {\
+  GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);\
+  values_add(ctx, loader);\
+  loader->last->header.domain = OPEN_BRACE;\
+  loader->stat = GRN_LOADER_TOKEN;\
+  str++;\
+}\
+
 static void
 json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned str_len)
 {
@@ -7747,9 +7763,29 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned str_len)
     c = *str;
     switch (loader->stat) {
     case GRN_LOADER_BEGIN :
+      if ((len = grn_isspace(str, ctx->encoding))) {
+        str += len;
+        c = *str;
+        continue;
+      }
+      switch (c) {
+      case '[' :
+        JSON_READ_OPEN_BRACKET();
+        break;
+      case '{' :
+        JSON_READ_OPEN_BRACE();
+        break;
+      default :
+        ERR(GRN_INVALID_ARGUMENT,
+            "must be start with '[' or '{': <%.*s>", str_len, beg);
+        loader->stat = GRN_LOADER_END;
+        break;
+      }
+      break;
     case GRN_LOADER_TOKEN :
       if ((len = grn_isspace(str, ctx->encoding))) {
         str += len;
+        c = *str;
         continue;
       }
       switch (c) {
@@ -7759,18 +7795,10 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned str_len)
         str++;
         break;
       case '[' :
-        GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);
-        values_add(ctx, loader);
-        loader->last->header.domain = OPEN_BRACKET;
-        loader->stat = GRN_LOADER_TOKEN;
-        str++;
+        JSON_READ_OPEN_BRACKET();
         break;
       case '{' :
-        GRN_UINT32_PUT(ctx, &loader->level, loader->values_size);
-        values_add(ctx, loader);
-        loader->last->header.domain = OPEN_BRACE;
-        loader->stat = GRN_LOADER_TOKEN;
-        str++;
+        JSON_READ_OPEN_BRACE();
         break;
       case ':' :
         str++;
@@ -8031,6 +8059,9 @@ json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned str_len)
   }
 }
 
+#undef JSON_READ_OPEN_BRACKET
+#undef JSON_READ_OPEN_BRACE
+
 static grn_rc
 parse_load_columns(grn_ctx *ctx, grn_obj *table,
                    const char *str, unsigned str_size, grn_obj *res)

  Modified: test/unit/core/test-command-load.c (+35 -2)
===================================================================
--- test/unit/core/test-command-load.c    2010-12-29 09:51:04 +0000 (4cf2559)
+++ test/unit/core/test-command-load.c    2010-12-29 08:58:04 +0000 (2bd79da)
@@ -34,8 +34,10 @@ void test_index_geo_point(void);
 void test_nonexistent_columns(void);
 void test_no_key_table(void);
 void test_two_bigram_indexes_to_key(void);
+void test_invalid_start_with_symbol(void);
 
 static gchar *tmp_directory;
+static const gchar *database_path;
 
 static grn_ctx *context;
 static grn_obj *database;
@@ -63,8 +65,6 @@ remove_tmp_directory(void)
 void
 cut_setup(void)
 {
-  const gchar *database_path;
-
   remove_tmp_directory();
   g_mkdir_with_parents(tmp_directory, 0700);
 
@@ -397,3 +397,36 @@ test_two_bigram_indexes_to_key(void)
                  "--query 'mori' "
                  "--output_columns '_key, author, _score'"));
 }
+
+void
+test_invalid_start_with_symbol(void)
+{
+  const gchar *table_list_result;
+
+  table_list_result =
+    cut_take_printf("["
+                    "[[\"id\",\"UInt32\"],"
+                     "[\"name\",\"ShortText\"],"
+                     "[\"path\",\"ShortText\"],"
+                     "[\"flags\",\"ShortText\"],"
+                     "[\"domain\",\"ShortText\"],"
+                     "[\"range\",\"ShortText\"]],"
+                    "[256,"
+                     "\"Authors\","
+                     "\"%s.0000100\","
+                     "\"TABLE_PAT_KEY|PERSISTENT\","
+                     "\"ShortText\","
+                     "\"null\"]]",
+                    database_path);
+
+  assert_send_command("table_create Authors TABLE_PAT_KEY ShortText");
+  cut_assert_equal_string(table_list_result, send_command("table_list"));
+  grn_test_assert_send_command_error(context,
+                                     GRN_INVALID_ARGUMENT,
+                                     "must be start with '[' or '{': <invalid>",
+                                     "load "
+                                     "--table Authors "
+                                     "--columns '_key' "
+                                     "--values 'invalid'");
+  cut_assert_equal_string(table_list_result, send_command("table_list"));
+}




Groonga-commit メーリングリストの案内
Back to archive index