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