1b5975d6bSopenharmony_ciFrom e8628a7ed59e54b5a5e498de0375f101a4e76e64 Mon Sep 17 00:00:00 2001
2b5975d6bSopenharmony_ciFrom: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
3b5975d6bSopenharmony_ciDate: Tue, 6 Sep 2022 19:05:24 +0200
4b5975d6bSopenharmony_ciSubject: [PATCH] regex: Compute the offsets size based on match results
5b5975d6bSopenharmony_ci
6b5975d6bSopenharmony_ciWhile the ovector count would include all the allocated space, we only
7b5975d6bSopenharmony_cicare about the actual match values, so avoid wasting allocations and
8b5975d6bSopenharmony_cijust use the ones we need to hold the offsets.
9b5975d6bSopenharmony_ci---
10b5975d6bSopenharmony_ci glib/gregex.c | 16 +++++++++++++---
11b5975d6bSopenharmony_ci 1 file changed, 13 insertions(+), 3 deletions(-)
12b5975d6bSopenharmony_ci
13b5975d6bSopenharmony_cidiff --git a/glib/gregex.c b/glib/gregex.c
14b5975d6bSopenharmony_ciindex cf86f0fe0d..8a3be9076b 100644
15b5975d6bSopenharmony_ci--- a/glib/gregex.c
16b5975d6bSopenharmony_ci+++ b/glib/gregex.c
17b5975d6bSopenharmony_ci@@ -832,10 +832,20 @@ recalc_match_offsets (GMatchInfo *match_info,
18b5975d6bSopenharmony_ci                       GError     **error)
19b5975d6bSopenharmony_ci {
20b5975d6bSopenharmony_ci   PCRE2_SIZE *ovector;
21b5975d6bSopenharmony_ci+  uint32_t ovector_size = 0;
22b5975d6bSopenharmony_ci   uint32_t pre_n_offset;
23b5975d6bSopenharmony_ci   uint32_t i;
24b5975d6bSopenharmony_ci 
25b5975d6bSopenharmony_ci-  if (pcre2_get_ovector_count (match_info->match_data) > G_MAXUINT32 / 2)
26b5975d6bSopenharmony_ci+  g_assert (!IS_PCRE2_ERROR (match_info->matches));
27b5975d6bSopenharmony_ci+
28b5975d6bSopenharmony_ci+  if (match_info->matches == PCRE2_ERROR_PARTIAL)
29b5975d6bSopenharmony_ci+    ovector_size = 1;
30b5975d6bSopenharmony_ci+  else if (match_info->matches > 0)
31b5975d6bSopenharmony_ci+    ovector_size = match_info->matches;
32b5975d6bSopenharmony_ci+
33b5975d6bSopenharmony_ci+  g_assert (ovector_size != 0);
34b5975d6bSopenharmony_ci+
35b5975d6bSopenharmony_ci+  if (pcre2_get_ovector_count (match_info->match_data) < ovector_size)
36b5975d6bSopenharmony_ci     {
37b5975d6bSopenharmony_ci       g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
38b5975d6bSopenharmony_ci                    _("Error while matching regular expression %s: %s"),
39b5975d6bSopenharmony_ci@@ -844,7 +854,7 @@ recalc_match_offsets (GMatchInfo *match_info,
40b5975d6bSopenharmony_ci     }
41b5975d6bSopenharmony_ci 
42b5975d6bSopenharmony_ci   pre_n_offset = match_info->n_offsets;
43b5975d6bSopenharmony_ci-  match_info->n_offsets = pcre2_get_ovector_count (match_info->match_data) * 2;
44b5975d6bSopenharmony_ci+  match_info->n_offsets = ovector_size * 2;
45b5975d6bSopenharmony_ci   ovector = pcre2_get_ovector_pointer (match_info->match_data);
46b5975d6bSopenharmony_ci 
47b5975d6bSopenharmony_ci   if (match_info->n_offsets != pre_n_offset)
48b5975d6bSopenharmony_ci@@ -2387,7 +2397,7 @@ g_regex_match_all_full (const GRegex      *regex,
49b5975d6bSopenharmony_ci                        _("Error while matching regular expression %s: %s"),
50b5975d6bSopenharmony_ci                        regex->pattern, match_error (info->matches));
51b5975d6bSopenharmony_ci         }
52b5975d6bSopenharmony_ci-      else if (info->matches > 0)
53b5975d6bSopenharmony_ci+      else if (info->matches != PCRE2_ERROR_NOMATCH)
54b5975d6bSopenharmony_ci         {
55b5975d6bSopenharmony_ci           if (!recalc_match_offsets (info, error))
56b5975d6bSopenharmony_ci             info->matches = PCRE2_ERROR_NOMATCH;
57b5975d6bSopenharmony_ci-- 
58b5975d6bSopenharmony_ciGitLab
59b5975d6bSopenharmony_ci
60