mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-31 12:53:07 +02:00
add g_regex_escape_nul
The function can be used to let regex compile non-NUL-terminated strings without redesigning the way the pattern is stored in GRegex objects and retrieved with g_regex_get_pattern. https://bugzilla.gnome.org/show_bug.cgi?id=615895
This commit is contained in:
parent
653c2f701a
commit
5eee90fbbc
@ -981,6 +981,7 @@ g_regex_get_string_number
|
|||||||
g_regex_get_compile_flags
|
g_regex_get_compile_flags
|
||||||
g_regex_get_match_flags
|
g_regex_get_match_flags
|
||||||
g_regex_escape_string
|
g_regex_escape_string
|
||||||
|
g_regex_escape_nul
|
||||||
g_regex_match_simple
|
g_regex_match_simple
|
||||||
g_regex_match
|
g_regex_match
|
||||||
g_regex_match_full
|
g_regex_match_full
|
||||||
|
@ -1352,6 +1352,7 @@ g_regex_get_string_number
|
|||||||
g_regex_get_compile_flags
|
g_regex_get_compile_flags
|
||||||
g_regex_get_match_flags
|
g_regex_get_match_flags
|
||||||
g_regex_escape_string
|
g_regex_escape_string
|
||||||
|
g_regex_escape_nul
|
||||||
g_regex_match_simple
|
g_regex_match_simple
|
||||||
g_regex_match
|
g_regex_match
|
||||||
g_regex_match_full
|
g_regex_match_full
|
||||||
|
@ -2832,6 +2832,74 @@ g_regex_check_replacement (const gchar *replacement,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_regex_escape_nul:
|
||||||
|
* @string: the string to escape
|
||||||
|
* @length: the length of @string
|
||||||
|
*
|
||||||
|
* Escapes the nul characters in @string to "\x00". It can be used
|
||||||
|
* to compile a regex with embedded nul characters.
|
||||||
|
*
|
||||||
|
* For completeness, @length can be -1 for a nul-terminated string.
|
||||||
|
* In this case the output string will be of course equal to @string.
|
||||||
|
*
|
||||||
|
* Returns: a newly-allocated escaped string
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
g_regex_escape_nul (const gchar *string,
|
||||||
|
gint length)
|
||||||
|
{
|
||||||
|
GString *escaped;
|
||||||
|
const gchar *p, *piece_start, *end;
|
||||||
|
gint backslashes;
|
||||||
|
|
||||||
|
g_return_val_if_fail (string != NULL, NULL);
|
||||||
|
|
||||||
|
if (length < 0)
|
||||||
|
return g_strdup (string);
|
||||||
|
|
||||||
|
end = string + length;
|
||||||
|
p = piece_start = string;
|
||||||
|
escaped = g_string_sized_new (length + 1);
|
||||||
|
|
||||||
|
backslashes = 0;
|
||||||
|
while (p < end)
|
||||||
|
{
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
if (p != piece_start)
|
||||||
|
{
|
||||||
|
/* copy the previous piece. */
|
||||||
|
g_string_append_len (escaped, piece_start, p - piece_start);
|
||||||
|
}
|
||||||
|
if ((backslashes & 1) == 0)
|
||||||
|
g_string_append_c (escaped, '\\');
|
||||||
|
g_string_append_c (escaped, 'x');
|
||||||
|
g_string_append_c (escaped, '0');
|
||||||
|
g_string_append_c (escaped, '0');
|
||||||
|
piece_start = ++p;
|
||||||
|
backslashes = 0;
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
backslashes++;
|
||||||
|
++p;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
backslashes = 0;
|
||||||
|
p = g_utf8_next_char (p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (piece_start < end)
|
||||||
|
g_string_append_len (escaped, piece_start, end - piece_start);
|
||||||
|
|
||||||
|
return g_string_free (escaped, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_regex_escape_string:
|
* g_regex_escape_string:
|
||||||
* @string: (array length=length): the string to escape
|
* @string: (array length=length): the string to escape
|
||||||
|
@ -364,6 +364,8 @@ gint g_regex_get_string_number (const GRegex *regex,
|
|||||||
const gchar *name);
|
const gchar *name);
|
||||||
gchar *g_regex_escape_string (const gchar *string,
|
gchar *g_regex_escape_string (const gchar *string,
|
||||||
gint length);
|
gint length);
|
||||||
|
gchar *g_regex_escape_nul (const gchar *string,
|
||||||
|
gint length);
|
||||||
|
|
||||||
GRegexCompileFlags g_regex_get_compile_flags (const GRegex *regex);
|
GRegexCompileFlags g_regex_get_compile_flags (const GRegex *regex);
|
||||||
GRegexMatchFlags g_regex_get_match_flags (const GRegex *regex);
|
GRegexMatchFlags g_regex_get_match_flags (const GRegex *regex);
|
||||||
|
@ -1129,6 +1129,31 @@ test_escape (gconstpointer d)
|
|||||||
g_free (path); \
|
g_free (path); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_escape_nul (gconstpointer d)
|
||||||
|
{
|
||||||
|
const TestEscapeData *data = d;
|
||||||
|
gchar *escaped;
|
||||||
|
|
||||||
|
escaped = g_regex_escape_nul (data->string, data->length);
|
||||||
|
|
||||||
|
g_assert_cmpstr (escaped, ==, data->expected);
|
||||||
|
|
||||||
|
g_free (escaped);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_ESCAPE_NUL(_string, _length, _expected) { \
|
||||||
|
TestEscapeData *data; \
|
||||||
|
gchar *path; \
|
||||||
|
data = g_new0 (TestEscapeData, 1); \
|
||||||
|
data->string = _string; \
|
||||||
|
data->length = _length; \
|
||||||
|
data->expected = _expected; \
|
||||||
|
path = g_strdup_printf ("/regex/escape_nul/%d", ++total); \
|
||||||
|
g_test_add_data_func (path, data, test_escape_nul); \
|
||||||
|
g_free (path); \
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const gchar *pattern;
|
const gchar *pattern;
|
||||||
const gchar *string;
|
const gchar *string;
|
||||||
@ -2574,6 +2599,23 @@ main (int argc, char *argv[])
|
|||||||
TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "A", 1);
|
TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "A", 1);
|
||||||
TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "B", -1);
|
TEST_GET_STRING_NUMBER("(?:a)(?P<A>.)", "B", -1);
|
||||||
|
|
||||||
|
/* TEST_ESCAPE_NUL(string, length, expected) */
|
||||||
|
TEST_ESCAPE_NUL("hello world", -1, "hello world");
|
||||||
|
TEST_ESCAPE_NUL("hello\0world", -1, "hello");
|
||||||
|
TEST_ESCAPE_NUL("\0world", -1, "");
|
||||||
|
TEST_ESCAPE_NUL("hello world", 5, "hello");
|
||||||
|
TEST_ESCAPE_NUL("hello.world", 11, "hello.world");
|
||||||
|
TEST_ESCAPE_NUL("a(b\\b.$", 7, "a(b\\b.$");
|
||||||
|
TEST_ESCAPE_NUL("hello\0", 6, "hello\\x00");
|
||||||
|
TEST_ESCAPE_NUL("\0world", 6, "\\x00world");
|
||||||
|
TEST_ESCAPE_NUL("\0\0", 2, "\\x00\\x00");
|
||||||
|
TEST_ESCAPE_NUL("hello\0world", 11, "hello\\x00world");
|
||||||
|
TEST_ESCAPE_NUL("hello\0world\0", 12, "hello\\x00world\\x00");
|
||||||
|
TEST_ESCAPE_NUL("hello\\\0world", 12, "hello\\x00world");
|
||||||
|
TEST_ESCAPE_NUL("hello\\\\\0world", 13, "hello\\\\\\x00world");
|
||||||
|
TEST_ESCAPE_NUL("|()[]{}^$*+?.", 13, "|()[]{}^$*+?.");
|
||||||
|
TEST_ESCAPE_NUL("|()[]{}^$*+?.\\\\", 15, "|()[]{}^$*+?.\\\\");
|
||||||
|
|
||||||
/* TEST_ESCAPE(string, length, expected) */
|
/* TEST_ESCAPE(string, length, expected) */
|
||||||
TEST_ESCAPE("hello world", -1, "hello world");
|
TEST_ESCAPE("hello world", -1, "hello world");
|
||||||
TEST_ESCAPE("hello world", 5, "hello");
|
TEST_ESCAPE("hello world", 5, "hello");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user