Projects
Factory:RISC-V:Gnome
glib2
_service:tar_scm:backport-gregex-Use-pcre2-erro...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch of Package glib2
From 6caf952e48dbed40b5dcff01a94f57ba079b526c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net> Date: Tue, 20 Sep 2022 18:06:35 +0200 Subject: [PATCH] gregex: Use pcre2 error messages if we don't provide a specific one In case we got a compilation or match error we should try to provide some useful error message, if possible, before returning a quite obscure "internal error" or "unknown error" string. So rely on PCRE2 strings even if they're not translated they can provide better information than the ones we're currently giving. Related to: https://gitlab.gnome.org/GNOME/glib/-/issues/2691 Related to: https://gitlab.gnome.org/GNOME/glib/-/issues/2760 Conflict:NA Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6caf952e48dbed40b5dcff01a94f57ba079b526c --- glib/gregex.c | 64 ++++++++++++++++++++++++++++++++++++++++------ glib/tests/regex.c | 2 ++ 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/glib/gregex.c b/glib/gregex.c index 220a1a11ac..fcc28d62f4 100644 --- a/glib/gregex.c +++ b/glib/gregex.c @@ -456,8 +456,25 @@ get_pcre2_bsr_match_options (GRegexMatchFlags match_flags) return 0; } +static char * +get_pcre2_error_string (int errcode) +{ + PCRE2_UCHAR8 error_msg[2048]; + int err_length; + + err_length = pcre2_get_error_message (errcode, error_msg, + G_N_ELEMENTS (error_msg)); + + if (err_length <= 0) + return NULL; + + /* The array is always filled with a trailing zero */ + g_assert ((size_t) err_length < G_N_ELEMENTS (error_msg)); + return g_memdup2 (error_msg, err_length + 1); +} + static const gchar * -match_error (gint errcode) +translate_match_error (gint errcode) { switch (errcode) { @@ -511,7 +528,24 @@ match_error (gint errcode) default: break; } - return _("unknown error"); + return NULL; +} + +static char * +get_match_error_message (int errcode) +{ + const char *msg = translate_match_error (errcode); + char *error_string; + + if (msg) + return g_strdup (msg); + + error_string = get_pcre2_error_string (errcode); + + if (error_string) + return error_string; + + return g_strdup (_("unknown error")); } static void @@ -743,7 +777,6 @@ translate_compile_error (gint *errcode, const gchar **errmsg) case PCRE2_ERROR_INTERNAL_BAD_CODE: case PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP: *errcode = G_REGEX_ERROR_INTERNAL; - *errmsg = _("internal error"); break; case PCRE2_ERROR_INVALID_SUBPATTERN_NAME: case PCRE2_ERROR_CLASS_INVALID_RANGE: @@ -772,12 +805,10 @@ translate_compile_error (gint *errcode, const gchar **errmsg) case PCRE2_ERROR_BAD_LITERAL_OPTIONS: default: *errcode = G_REGEX_ERROR_COMPILE; - *errmsg = _("internal error"); break; } g_assert (*errcode != -1); - g_assert (*errmsg != NULL); } /* GMatchInfo */ @@ -1096,9 +1127,12 @@ g_match_info_next (GMatchInfo *match_info, if (IS_PCRE2_ERROR (match_info->matches)) { + gchar *error_msg = get_match_error_message (match_info->matches); + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, _("Error while matching regular expression %s: %s"), - match_info->regex->pattern, match_error (match_info->matches)); + match_info->regex->pattern, error_msg); + g_clear_pointer (&error_msg, g_free); return FALSE; } else if (match_info->matches == 0) @@ -1800,11 +1834,20 @@ regex_compile (const gchar *pattern, { GError *tmp_error; gchar *offset_str; + gchar *pcre2_errmsg = NULL; + int original_errcode; /* Translate the PCRE error code to GRegexError and use a translated * error message if possible */ + original_errcode = errcode; translate_compile_error (&errcode, &errmsg); + if (!errmsg) + { + errmsg = _("unknown error"); + pcre2_errmsg = get_pcre2_error_string (original_errcode); + } + /* PCRE uses byte offsets but we want to show character offsets */ erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]); @@ -1812,9 +1855,11 @@ regex_compile (const gchar *pattern, tmp_error = g_error_new (G_REGEX_ERROR, errcode, _("Error while compiling regular expression ‘%s’ " "at char %s: %s"), - pattern, offset_str, errmsg); + pattern, offset_str, + pcre2_errmsg ? pcre2_errmsg : errmsg); g_propagate_error (error, tmp_error); g_free (offset_str); + g_clear_pointer (&pcre2_errmsg, g_free); return NULL; } @@ -2402,9 +2447,12 @@ g_regex_match_all_full (const GRegex *regex, } else if (IS_PCRE2_ERROR (info->matches)) { + gchar *error_msg = get_match_error_message (info->matches); + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, _("Error while matching regular expression %s: %s"), - regex->pattern, match_error (info->matches)); + regex->pattern, error_msg); + g_clear_pointer (&error_msg, g_free); } else if (info->matches != PCRE2_ERROR_NOMATCH) { diff --git a/glib/tests/regex.c b/glib/tests/regex.c index 9803d49659..52af212f29 100644 --- a/glib/tests/regex.c +++ b/glib/tests/regex.c @@ -2560,6 +2560,7 @@ main (int argc, char *argv[]) TEST_NEW_FAIL ("[a-z", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS); TEST_NEW_FAIL ("[\\B]", 0, G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS); TEST_NEW_FAIL ("[z-a]", 0, G_REGEX_ERROR_RANGE_OUT_OF_ORDER); + TEST_NEW_FAIL ("^[[:alnum:]-_.]+$", 0, G_REGEX_ERROR_COMPILE); TEST_NEW_FAIL ("{2,4}", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); TEST_NEW_FAIL ("a(?u)", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER); TEST_NEW_FAIL ("a(?<$foo)bar", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME); @@ -2636,6 +2637,7 @@ main (int argc, char *argv[]) TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE); TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE); TEST_MATCH_SIMPLE("\\C\\C", "ab", G_REGEX_OPTIMIZE | G_REGEX_RAW, 0, TRUE); + TEST_MATCH_SIMPLE("^[[:alnum:]\\-_.]+$", "admin-foo", 0, 0, TRUE); /* These are needed to test extended properties. */ TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE); TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE); -- GitLab
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2