From 7be9334e45fa510b17b770ffabe4f5a1e5bef248 Mon Sep 17 00:00:00 2001 From: Mooffie Date: Sun, 25 Sep 2016 20:57:12 +0300 Subject: [PATCH] Fix quotes handling. Note: considering that this feature hasn't worked, we may consider removing it entirely or partially (e.g., escaping) in order to simplify the code, as nobody has grown used to it. It seems, based on the "hex mode" mentioned in the manual page, that in the past there was no "normal" search in hex mode, and quoted strings were the only easy way to look for text. This is no longer the case nowadays. Note: the characters in the quoted string are copied out as-is to the regexp. No regexp-quoting is currently done. We may want to revisit this issue when we work on ticket #3695. Signed-off-by: Andrew Borodin --- lib/search/hex.c | 28 +++++++++------ tests/lib/search/hex_translate_to_regex.c | 57 +++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/lib/search/hex.c b/lib/search/hex.c index dcef0061e..2fdb71631 100644 --- a/lib/search/hex.c +++ b/lib/search/hex.c @@ -43,7 +43,8 @@ typedef enum { MC_SEARCH_HEX_E_OK, MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE, - MC_SEARCH_HEX_E_INVALID_CHARACTER + MC_SEARCH_HEX_E_INVALID_CHARACTER, + MC_SEARCH_HEX_E_UNMATCHED_QUOTES } mc_search_hex_parse_error_t; /*** file scope type declarations ****************************************************************/ @@ -101,21 +102,26 @@ mc_search__hex_translate_to_regex (const GString * astr, mc_search_hex_parse_err loop += ptr; } } - else if (*(tmp_str + loop) == '"') + else if (tmp_str[loop] == '"') { - gsize loop2 = 0; + gsize loop2; - loop++; - while (loop + loop2 < tmp_str_len) + loop2 = loop + 1; + + while (loop2 < tmp_str_len) { - if (*(tmp_str + loop + loop2) == '"' && - !strutils_is_char_escaped (tmp_str, tmp_str + loop + loop2)) + if (tmp_str[loop2] == '"') break; + if (tmp_str[loop2] == '\\' && loop2 + 1 < tmp_str_len) + loop2++; + g_string_append_c (buff, tmp_str[loop2]); loop2++; } - g_string_append_len (buff, tmp_str + loop, loop2 - 1); - loop += loop2; + if (tmp_str[loop2] == '\0') + error = MC_SEARCH_HEX_E_UNMATCHED_QUOTES; + else + loop = loop2 + 1; } else error = MC_SEARCH_HEX_E_INVALID_CHARACTER; @@ -146,7 +152,6 @@ mc_search__cond_struct_new_init_hex (const char *charset, mc_search_t * lc_mc_se mc_search_hex_parse_error_t error = MC_SEARCH_HEX_E_OK; int error_pos = 0; - g_string_ascii_down (mc_search_cond->str); tmp = mc_search__hex_translate_to_regex (mc_search_cond->str, &error, &error_pos); if (tmp != NULL) { @@ -168,6 +173,9 @@ mc_search__cond_struct_new_init_hex (const char *charset, mc_search_t * lc_mc_se case MC_SEARCH_HEX_E_INVALID_CHARACTER: desc = _("Invalid character"); break; + case MC_SEARCH_HEX_E_UNMATCHED_QUOTES: + desc = _("Unmatched quotes character"); + break; default: desc = ""; } diff --git a/tests/lib/search/hex_translate_to_regex.c b/tests/lib/search/hex_translate_to_regex.c index 31a6bb73b..e2dae2f42 100644 --- a/tests/lib/search/hex_translate_to_regex.c +++ b/tests/lib/search/hex_translate_to_regex.c @@ -85,6 +85,63 @@ static const struct test_hex_translate_to_regex_ds NULL, MC_SEARCH_HEX_E_INVALID_CHARACTER }, + /* + * Quotes. + */ + { + " \"abc\" ", + "abc", + MC_SEARCH_HEX_E_OK + }, + { + /* Preserve upper/lower case */ + "\"aBc\"", + "aBc", + MC_SEARCH_HEX_E_OK + }, + { + " 12\"abc\"34 ", + "\\x12abc\\x34", + MC_SEARCH_HEX_E_OK + }, + { + "\"a\"\"b\"", + "ab", + MC_SEARCH_HEX_E_OK + }, + /* Empty quotes */ + { + "\"\"", + "", + MC_SEARCH_HEX_E_OK + }, + { + "12 \"\"", + "\\x12", + MC_SEARCH_HEX_E_OK + }, + /* Error: Unmatched quotes */ + { + "\"a", + NULL, + MC_SEARCH_HEX_E_UNMATCHED_QUOTES + }, + { + "\"", + NULL, + MC_SEARCH_HEX_E_UNMATCHED_QUOTES + }, + /* Escaped quotes */ + { + "\"a\\\"b\"", + "a\"b", + MC_SEARCH_HEX_E_OK + }, + { + "\"a\\\\b\"", + "a\\b", + MC_SEARCH_HEX_E_OK + }, }; /* *INDENT-ON* */ -- 2.11.4.GIT