gpattern: Fix use of narrow types to contain string offsets

When parsing the pattern in `g_pattern_spec_new()`, the offsets of
wildcards and jokers were stored in a `gint`. This could overflow with
exceptionally long patterns.

Split the sign out into a separate boolean for `hw_pos` and `hj_pos`
(it’s not necessary for `tw_pos` or `tj_pos` because their sign was
never queried), and use `size_t` to correctly store string offsets.

Fixes a `-Wshorten-64-to-32` warning.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3527
This commit is contained in:
Philip Withnall 2024-11-07 13:39:48 +00:00
parent 66f4a52bd6
commit 8c37608c0d
No known key found for this signature in database
GPG Key ID: C5C42CFB268637CA

View File

@ -289,12 +289,13 @@ g_pattern_spec_new (const gchar *pattern)
{
GPatternSpec *pspec;
gboolean seen_joker = FALSE, seen_wildcard = FALSE, more_wildcards = FALSE;
gint hw_pos = -1, tw_pos = -1, hj_pos = -1, tj_pos = -1;
size_t hw_pos = 0, tw_pos = 0, hj_pos = 0, tj_pos = 0;
gboolean hw_pos_set = FALSE, hj_pos_set = FALSE;
gboolean follows_wildcard = FALSE;
guint pending_jokers = 0;
const gchar *s;
gchar *d;
guint i;
size_t i;
g_return_val_if_fail (pattern != NULL, NULL);
@ -316,8 +317,11 @@ g_pattern_spec_new (const gchar *pattern)
continue;
}
follows_wildcard = TRUE;
if (hw_pos < 0)
if (!hw_pos_set)
{
hw_pos = i;
hw_pos_set = TRUE;
}
tw_pos = i;
break;
case '?':
@ -328,8 +332,11 @@ g_pattern_spec_new (const gchar *pattern)
default:
for (; pending_jokers; pending_jokers--, i++) {
*d++ = '?';
if (hj_pos < 0)
if (!hj_pos_set)
{
hj_pos = i;
hj_pos_set = TRUE;
}
tj_pos = i;
}
follows_wildcard = FALSE;
@ -342,13 +349,16 @@ g_pattern_spec_new (const gchar *pattern)
}
for (; pending_jokers; pending_jokers--) {
*d++ = '?';
if (hj_pos < 0)
if (!hj_pos_set)
{
hj_pos = i;
hj_pos_set = TRUE;
}
tj_pos = i;
}
*d++ = 0;
seen_joker = hj_pos >= 0;
seen_wildcard = hw_pos >= 0;
seen_joker = hj_pos_set;
seen_wildcard = hw_pos_set;
more_wildcards = seen_wildcard && hw_pos != tw_pos;
if (seen_wildcard)
pspec->max_length = G_MAXUINT;