[groonga-dev,00152] 存在しないカラムをgrn_obj_column()すると落ちる

Back to archive index

Kouhei Sutou kou****@clear*****
2009年 8月 9日 (日) 21:53:32 JST


須藤です。

grn_obj_column(context, table, "nonexistent", strlen("nonexistent"))
など、存在しないカラムを指定すると落ちてしまいます。

-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード (http://www.clear-code.com/)


diff --git a/lib/db.c b/lib/db.c
index 07f8844..02bc179 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -2605,8 +2605,8 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned name
       /* if obj->header.type == GRN_TYPE ... lookup table */
       for (rp = &res; ; rp = &(*rp)->next) {
         grn_obj *column = grn_obj_column_(ctx, obj, name, len);
-        *rp = accessor_new(ctx);
         if (column) {
+          *rp = accessor_new(ctx);
           (*rp)->obj = column;
           /*
           switch (column->header.type) {
@@ -2621,6 +2621,12 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned name
           (*rp)->action = GRN_ACCESSOR_GET_COLUMN_VALUE;
           break;
         } else {
+          if (!obj->header.domain) {
+            ERR(GRN_INVALID_ARGUMENT, "no such column: <%s>", name);
+            res = NULL;
+            goto exit;
+          }
+          *rp = accessor_new(ctx);
           (*rp)->obj = obj;
           obj = grn_ctx_at(ctx, obj->header.domain);
           switch (obj->header.type) {
diff --git a/test/unit/core/test-table.c b/test/unit/core/test-table.c
index e82824c..b68f212 100644
--- a/test/unit/core/test-table.c
+++ b/test/unit/core/test-table.c
@@ -32,6 +32,7 @@ void data_temporary_table_default_tokenizer(void);
 void test_temporary_table_default_tokenizer(gpointer data);
 void data_temporary_table_add(void);
 void test_temporary_table_add(gpointer data);
+void test_nonexistent_column(void);
 
 static grn_logger_info *logger;
 static grn_ctx context;
@@ -152,3 +153,22 @@ test_temporary_table_add(gpointer data)
 
   cut_assert_equal_int(1, grn_table_size(&context, table));
 }
+
+void
+test_nonexistent_column(void)
+{
+  grn_obj *table;
+  char table_name[] = "users";
+  char nonexistent_column_name[] = "nonexistent";
+
+  table = grn_table_create(&context, table_name, strlen(table_name),
+                           NULL,
+                           GRN_OBJ_TABLE_NO_KEY,
+                           NULL, NULL);
+  grn_test_assert_null(&context,
+                       grn_obj_column(&context, table,
+                                      nonexistent_column_name,
+                                      strlen(nonexistent_column_name)));
+  grn_test_assert_error(GRN_INVALID_ARGUMENT, "no such column: <nonexistent>",
+                        &context);
+}
diff --git a/test/unit/lib/grn-assertions.c b/test/unit/lib/grn-assertions.c
index acafa69..be87970 100644
--- a/test/unit/lib/grn-assertions.c
+++ b/test/unit/lib/grn-assertions.c
@@ -98,6 +98,31 @@ grn_test_assert_context_helper (grn_ctx *context, const gchar *expression)
 }
 
 void
+grn_test_assert_error_helper (grn_rc expected_rc, const gchar *expected_message,
+                              grn_ctx *context, const gchar *expression)
+{
+  if (!context) {
+    cut_set_message("context should not NULL");
+    cut_assert_null_helper(context, expression);
+  } else if (context->rc == expected_rc &&
+             cut_equal_string(expected_message, context->errbuf)) {
+    cut_test_pass();
+  } else {
+    cut_test_fail(cut_take_printf("<%s>\n"
+                                  "expected: <%s>(%s)\n"
+                                  "  actual: <%s>(%s)\n"
+                                  "%s:%d: %s():",
+                                  expression,
+                                  expected_message,
+                                  grn_rc_to_string(expected_rc),
+                                  context->errbuf,
+                                  grn_rc_to_string(context->rc),
+                                  context->errfile, context->errline,
+                                  context->errfunc));
+  }
+}
+
+void
 grn_test_assert_null_helper (grn_ctx *context,
                              grn_obj *object, const gchar *expression)
 {
diff --git a/test/unit/lib/grn-assertions.h b/test/unit/lib/grn-assertions.h
index b29aefb..9f45ded 100644
--- a/test/unit/lib/grn-assertions.h
+++ b/test/unit/lib/grn-assertions.h
@@ -42,10 +42,15 @@
     grn_test_assert_not_nil_helper((expression), #expression),  \
     grn_test_assert_not_nil(expression))
 
-#define grn_test_assert_context(expression)                     \
+#define grn_test_assert_context(context)                        \
   cut_trace_with_info_expression(                               \
-    grn_test_assert_context_helper((expression), #expression),  \
-    grn_test_assert_context(expression))
+    grn_test_assert_context_helper((context), #context),        \
+    grn_test_assert_context(context))
+
+#define grn_test_assert_error(rc, message, context)                     \
+  cut_trace_with_info_expression(                                       \
+    grn_test_assert_error_helper((rc), (message), (context), #context), \
+    grn_test_assert_error(context))
 
 #define grn_test_assert_null(context, object)                   \
   cut_trace_with_info_expression(                               \
@@ -71,6 +76,10 @@ void     grn_test_assert_not_nil_helper (grn_id       id,
                                          const gchar *expression);
 void     grn_test_assert_context_helper (grn_ctx     *context,
                                          const gchar *expression);
+void     grn_test_assert_error_helper   (grn_rc       expected_rc,
+                                         const gchar *expected_message,
+                                         grn_ctx     *context,
+                                         const gchar *expression);
 void     grn_test_assert_null_helper    (grn_ctx     *context,
                                          grn_obj     *object,
                                          const gchar *expression);




groonga-dev メーリングリストの案内
Back to archive index