Report errors to the user.

Instead of silently accepting invalid patterns, we notify the user of errors.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Mooffie 2016-09-25 14:09:43 +03:00 committed by Andrew Borodin
parent 3332d1ebe4
commit b25af93874
2 changed files with 83 additions and 16 deletions

View File

@ -39,6 +39,12 @@
/*** file scope macro definitions ****************************************************************/ /*** file scope macro definitions ****************************************************************/
typedef enum
{
MC_SEARCH_HEX_E_OK,
MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE
} mc_search_hex_parse_error_t;
/*** file scope type declarations ****************************************************************/ /*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/ /*** file scope variables ************************************************************************/
@ -46,12 +52,14 @@
/*** file scope functions ************************************************************************/ /*** file scope functions ************************************************************************/
static GString * static GString *
mc_search__hex_translate_to_regex (const GString * astr) mc_search__hex_translate_to_regex (const GString * astr, mc_search_hex_parse_error_t * error_ptr,
int *error_pos_ptr)
{ {
GString *buff; GString *buff;
gchar *tmp_str, *tmp_str2; gchar *tmp_str, *tmp_str2;
gsize tmp_str_len; gsize tmp_str_len;
gsize loop = 0; gsize loop = 0;
mc_search_hex_parse_error_t error = MC_SEARCH_HEX_E_OK;
buff = g_string_sized_new (64); buff = g_string_sized_new (64);
tmp_str = g_strndup (astr->str, astr->len); tmp_str = g_strndup (astr->str, astr->len);
@ -71,7 +79,7 @@ mc_search__hex_translate_to_regex (const GString * astr)
g_strchug (tmp_str); /* trim leadind whitespaces */ g_strchug (tmp_str); /* trim leadind whitespaces */
tmp_str_len = strlen (tmp_str); tmp_str_len = strlen (tmp_str);
while (loop < tmp_str_len) while (loop < tmp_str_len && error == MC_SEARCH_HEX_E_OK)
{ {
unsigned int val; unsigned int val;
int ptr; int ptr;
@ -80,7 +88,7 @@ mc_search__hex_translate_to_regex (const GString * astr)
if (sscanf (tmp_str + loop, "%x%n", &val, &ptr)) if (sscanf (tmp_str + loop, "%x%n", &val, &ptr))
{ {
if (val > 255) if (val > 255)
loop++; error = MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE;
else else
{ {
g_string_append_printf (buff, "\\x%02X", val); g_string_append_printf (buff, "\\x%02X", val);
@ -109,6 +117,16 @@ mc_search__hex_translate_to_regex (const GString * astr)
g_free (tmp_str); g_free (tmp_str);
if (error != MC_SEARCH_HEX_E_OK)
{
g_string_free (buff, TRUE);
if (error_ptr != NULL)
*error_ptr = error;
if (error_pos_ptr != NULL)
*error_pos_ptr = loop;
return NULL;
}
return buff; return buff;
} }
@ -119,14 +137,37 @@ mc_search__cond_struct_new_init_hex (const char *charset, mc_search_t * lc_mc_se
mc_search_cond_t * mc_search_cond) mc_search_cond_t * mc_search_cond)
{ {
GString *tmp; GString *tmp;
mc_search_hex_parse_error_t error = MC_SEARCH_HEX_E_OK;
int error_pos = 0;
g_string_ascii_down (mc_search_cond->str); g_string_ascii_down (mc_search_cond->str);
tmp = mc_search__hex_translate_to_regex (mc_search_cond->str); tmp = mc_search__hex_translate_to_regex (mc_search_cond->str, &error, &error_pos);
if (tmp != NULL)
{
g_string_free (mc_search_cond->str, TRUE); g_string_free (mc_search_cond->str, TRUE);
mc_search_cond->str = tmp; mc_search_cond->str = tmp;
mc_search__cond_struct_new_init_regex (charset, lc_mc_search, mc_search_cond); mc_search__cond_struct_new_init_regex (charset, lc_mc_search, mc_search_cond);
} }
else
{
const char *desc;
switch (error)
{
case MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE:
desc =
_
("Number out of range (should be in byte range, 0 <= n <= 0xFF, expressed in hex)");
break;
default:
desc = "";
}
lc_mc_search->error = MC_SEARCH_E_INPUT;
lc_mc_search->error_str =
g_strdup_printf (_("Hex pattern error at position %d:\n%s."), error_pos + 1, desc);
}
}
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

View File

@ -34,32 +34,50 @@ static const struct test_hex_translate_to_regex_ds
{ {
const char *input_value; const char *input_value;
const char *expected_result; const char *expected_result;
mc_search_hex_parse_error_t expected_error;
} test_hex_translate_to_regex_ds[] = } test_hex_translate_to_regex_ds[] =
{ {
{ {
/* Simplest case */ /* Simplest case */
"12 34", "12 34",
"\\x12\\x34" "\\x12\\x34",
MC_SEARCH_HEX_E_OK
}, },
{ {
/* Prefixes (0x, 0X) */ /* Prefixes (0x, 0X) */
"0x12 0X34", "0x12 0X34",
"\\x12\\x34" "\\x12\\x34",
MC_SEARCH_HEX_E_OK
}, },
{ {
/* Prefix "0" doesn't signify octal! Numbers are always interpreted in hex. */ /* Prefix "0" doesn't signify octal! Numbers are always interpreted in hex. */
"012", "012",
"\\x12" "\\x12",
MC_SEARCH_HEX_E_OK
}, },
{ {
/* Extra whitespace (but not trailing one) */ /* Extra whitespace (but not trailing one) */
" 12 34", " 12 34",
"\\x12\\x34" "\\x12\\x34",
MC_SEARCH_HEX_E_OK
}, },
{ {
/* Min/max values */ /* Min/max values */
"0 ff", "0 ff",
"\\x00\\xFF" "\\x00\\xFF",
MC_SEARCH_HEX_E_OK
},
{
/* Error: Number out of range */
"100",
NULL,
MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE
},
{
/* Error: Number out of range (negative) */
"-1",
NULL,
MC_SEARCH_HEX_E_NUM_OUT_OF_RANGE
}, },
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -70,19 +88,27 @@ START_PARAMETRIZED_TEST (test_hex_translate_to_regex, test_hex_translate_to_rege
/* *INDENT-ON* */ /* *INDENT-ON* */
{ {
GString *tmp, *dest_str; GString *tmp, *dest_str;
mc_search_hex_parse_error_t error;
/* given */ /* given */
tmp = g_string_new (data->input_value); tmp = g_string_new (data->input_value);
/* when */ /* when */
dest_str = mc_search__hex_translate_to_regex (tmp); dest_str = mc_search__hex_translate_to_regex (tmp, &error, NULL);
/* then */
g_string_free (tmp, TRUE); g_string_free (tmp, TRUE);
/* then */
if (dest_str != NULL)
{
mctest_assert_str_eq (dest_str->str, data->expected_result); mctest_assert_str_eq (dest_str->str, data->expected_result);
g_string_free (dest_str, TRUE); g_string_free (dest_str, TRUE);
} }
else
{
mctest_assert_int_eq (error, data->expected_error);
}
}
/* *INDENT-OFF* */ /* *INDENT-OFF* */
END_PARAMETRIZED_TEST END_PARAMETRIZED_TEST
/* *INDENT-ON* */ /* *INDENT-ON* */