[Groonga-commit] groonga/groonga at acd8371 [master] Add grn_expr_syntax_escape_query()

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Aug 6 17:24:01 JST 2013


Kouhei Sutou	2013-08-06 17:24:01 +0900 (Tue, 06 Aug 2013)

  New Revision: acd837177f55bc5d16bde8b9f85d32bf297d1082
  https://github.com/groonga/groonga/commit/acd837177f55bc5d16bde8b9f85d32bf297d1082

  Message:
    Add grn_expr_syntax_escape_query()
    
    It escapes special characters in query syntax.

  Added files:
    test/unit/core/test-expr-syntax.c
  Modified files:
    include/groonga.h
    lib/expr.c
    test/unit/core/Makefile.am

  Modified: include/groonga.h (+4 -0)
===================================================================
--- include/groonga.h    2013-08-05 16:09:24 +0900 (bc85516)
+++ include/groonga.h    2013-08-06 17:24:01 +0900 (9438149)
@@ -2467,6 +2467,10 @@ GRN_API grn_obj *grn_expr_append_const_int(grn_ctx *ctx, grn_obj *expr, int i,
                                            grn_operator op, int nargs);
 GRN_API grn_rc grn_expr_append_op(grn_ctx *ctx, grn_obj *expr, grn_operator op, int nargs);
 
+GRN_API grn_rc grn_expr_syntax_escape_query(grn_ctx *ctx,
+                                            const char *query, int query_size,
+                                            grn_obj *escaped_query);
+
 GRN_API grn_rc grn_expr_compile(grn_ctx *ctx, grn_obj *expr);
 GRN_API grn_obj *grn_expr_exec(grn_ctx *ctx, grn_obj *expr, int nargs);
 GRN_API grn_rc grn_ctx_push(grn_ctx *ctx, grn_obj *obj);

  Modified: lib/expr.c (+57 -0)
===================================================================
--- lib/expr.c    2013-08-05 16:09:24 +0900 (b61f3eb)
+++ lib/expr.c    2013-08-06 17:24:01 +0900 (94623d2)
@@ -6487,3 +6487,60 @@ grn_column_filter(grn_ctx *ctx, grn_obj *column,
   grn_ii_resolve_sel_and(ctx, (grn_hash *)result_set, set_operation);
   return ctx->rc;
 }
+
+grn_rc
+grn_expr_syntax_escape_query(grn_ctx *ctx, const char *query, int query_size,
+                             grn_obj *escaped_query)
+{
+  grn_rc rc = GRN_SUCCESS;
+  const char *current, *query_end;
+
+  if (!query) {
+    return GRN_INVALID_ARGUMENT;
+  }
+
+  GRN_API_ENTER;
+  if (query_size < 0) {
+    query_size = strlen(query);
+  }
+  query_end = query + query_size;
+
+  current = query;
+  while (current < query_end) {
+    unsigned int char_size;
+    char_size = grn_charlen(ctx, current, query_end);
+    switch (char_size) {
+    case 0 :
+      /* query includes malformed multibyte character. */
+      return GRN_INVALID_ARGUMENT;
+      break;
+    case 1 :
+      switch (*current) {
+      case GRN_QUERY_AND :
+      case GRN_QUERY_AND_NOT :
+      case GRN_QUERY_ADJ_INC :
+      case GRN_QUERY_ADJ_DEC :
+      case GRN_QUERY_ADJ_NEG :
+      case GRN_QUERY_PREFIX :
+      case GRN_QUERY_PARENL :
+      case GRN_QUERY_PARENR :
+      case GRN_QUERY_QUOTEL :
+      case GRN_QUERY_ESCAPE :
+      case GRN_QUERY_COLUMN :
+        GRN_TEXT_PUTC(ctx, escaped_query, GRN_QUERY_ESCAPE);
+        break;
+      default:
+        break;
+      }
+      GRN_TEXT_PUT(ctx, escaped_query, current, char_size);
+      current += char_size;
+      break;
+    default :
+      GRN_TEXT_PUT(ctx, escaped_query, current, char_size);
+      current += char_size;
+      break;
+    }
+  }
+
+  GRN_API_RETURN(rc);
+}

  Modified: test/unit/core/Makefile.am (+2 -0)
===================================================================
--- test/unit/core/Makefile.am    2013-08-05 16:09:24 +0900 (d5a6bac)
+++ test/unit/core/Makefile.am    2013-08-06 17:24:01 +0900 (8c5470b)
@@ -29,6 +29,7 @@ noinst_LTLIBRARIES =				\
 	test-expr-script.la			\
 	test-expr-query.la			\
 	test-expr-parse.la			\
+	test-expr-syntax.la			\
 	test-text.la				\
 	test-cast-basic.la			\
 	test-cast-table.la			\
@@ -118,6 +119,7 @@ test_expr_la_SOURCES			= test-expr.c
 test_expr_script_la_SOURCES		= test-expr-script.c
 test_expr_query_la_SOURCES		= test-expr-query.c
 test_expr_parse_la_SOURCES		= test-expr-parse.c
+test_expr_syntax_la_SOURCES		= test-expr-syntax.c
 test_text_la_SOURCES			= test-text.c
 test_cast_basic_la_SOURCES		= test-cast-basic.c
 test_cast_table_la_SOURCES		= test-cast-table.c

  Added: test/unit/core/test-expr-syntax.c (+110 -0) 100644
===================================================================
--- /dev/null
+++ test/unit/core/test-expr-syntax.c    2013-08-06 17:24:01 +0900 (ef58d36)
@@ -0,0 +1,110 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+  Copyright(C) 2013 Kouhei Sutou <kou �� clear-code.com>
+
+  This library 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 library 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 library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <groonga.h>
+
+#include <gcutter.h>
+
+#include "../lib/grn-assertions.h"
+
+static gchar *tmp_directory;
+static gchar *path;
+static grn_ctx context;
+static grn_obj *database;
+static grn_obj escaped_query;
+
+void data_escape_query(void);
+void test_escape_query(gconstpointer data);
+
+void
+cut_startup(void)
+{
+  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
+                                   "test-expr-syntax",
+                                   NULL);
+}
+
+void
+cut_shutdown(void)
+{
+  g_free(tmp_directory);
+}
+
+void
+cut_setup(void)
+{
+  cut_remove_path(tmp_directory, NULL);
+  g_mkdir_with_parents(tmp_directory, 0700);
+  path = g_build_filename(tmp_directory, "text-expr-syntax", NULL);
+  grn_ctx_init(&context, 0);
+  database = grn_db_create(&context, path, NULL);
+
+  GRN_TEXT_INIT(&escaped_query, 0);
+}
+
+void
+cut_teardown(void)
+{
+  grn_obj_close(&context, &escaped_query);
+  grn_db_close(&context, database);
+  grn_ctx_fin(&context);
+  cut_remove_path(tmp_directory, NULL);
+  g_free(path);
+}
+
+void
+data_escape_query(void)
+{
+#define ADD_DATUM(label,                                                \
+                  expected, query)                                      \
+  gcut_add_datum(label,                                                 \
+                 "expected", G_TYPE_STRING, expected,                   \
+                 "query", G_TYPE_STRING, query,                         \
+                 NULL)
+
+  ADD_DATUM("+",  "a\\+b",  "a+b");
+  ADD_DATUM("-",  "a\\-b",  "a-b");
+  ADD_DATUM(">",  "a\\>b",  "a>b");
+  ADD_DATUM("<",  "a\\<b",  "a<b");
+  ADD_DATUM("~",  "a\\~b",  "a~b");
+  ADD_DATUM("*",  "a\\*b",  "a*b");
+  ADD_DATUM("(",  "a\\(b",  "a(b");
+  ADD_DATUM(")",  "a\\)b",  "a)b");
+  ADD_DATUM("\"", "a\\\"b", "a\"b");
+  ADD_DATUM("\\", "a\\\\b", "a\\b");
+  ADD_DATUM(":",  "a\\:b",  "a:b");
+
+#undef ADD_DATUM
+}
+
+void
+test_escape_query(gconstpointer data)
+{
+  const gchar *expected;
+  const gchar *query;
+
+  query = gcut_data_get_string(data, "query");
+  grn_test_assert(grn_expr_syntax_escape_query(&context,
+                                               query, -1,
+                                               &escaped_query));
+
+  expected = gcut_data_get_string(data, "expected");
+  GRN_TEXT_PUTC(&context, &escaped_query, '\0');
+  cut_assert_equal_string(expected, GRN_TEXT_VALUE(&escaped_query));
+}
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index