[glib: 2/17] gkeyfile: Add a length argument to is_key_name()
- From: Sebastian Dröge <sdroege src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 2/17] gkeyfile: Add a length argument to is_key_name()
- Date: Tue, 2 Nov 2021 11:08:16 +0000 (UTC)
commit 960030712d4456e1dcada3a8492f3bce8b52ef61
Author: Philip Withnall <pwithnall endlessos org>
Date: Sun Mar 14 13:47:26 2021 +0000
gkeyfile: Add a length argument to is_key_name()
This allows it to be called on a substring of a larger string, without
having to allocate a nul-terminated copy of the substring with
`g_strndup()` before knowing that the key name is actually valid.
This speeds up parsing of highly invalid key files, but doesn’t affect
performance in the normal case of a valid key file.
oss-fuzz#31796
Signed-off-by: Philip Withnall <pwithnall endlessos org>
glib/gkeyfile.c | 43 +++++++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 14 deletions(-)
---
diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c
index c9de2ab23..f1b7f961d 100644
--- a/glib/gkeyfile.c
+++ b/glib/gkeyfile.c
@@ -575,7 +575,8 @@ static void g_key_file_add_key (GKeyFile
static void g_key_file_add_group (GKeyFile *key_file,
const gchar *group_name);
static gboolean g_key_file_is_group_name (const gchar *name);
-static gboolean g_key_file_is_key_name (const gchar *name);
+static gboolean g_key_file_is_key_name (const gchar *name,
+ gsize len);
static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair);
static gboolean g_key_file_line_is_comment (const gchar *line);
static gboolean g_key_file_line_is_group (const gchar *line);
@@ -1380,17 +1381,16 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file,
g_warn_if_fail (key_len <= length);
- key = g_strndup (line, key_len - 1);
-
- if (!g_key_file_is_key_name (key))
+ if (!g_key_file_is_key_name (line, key_len - 1))
{
g_set_error (error, G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_PARSE,
- _("Invalid key name: %s"), key);
- g_free (key);
+ _("Invalid key name: %.*s"), (int) key_len - 1, line);
return;
}
+ key = g_strndup (line, key_len - 1);
+
/* Pull the value from the line (chugging leading whitespace)
*/
while (g_ascii_isspace (*value_start))
@@ -1877,7 +1877,7 @@ g_key_file_set_value (GKeyFile *key_file,
g_return_if_fail (key_file != NULL);
g_return_if_fail (g_key_file_is_group_name (group_name));
- g_return_if_fail (g_key_file_is_key_name (key));
+ g_return_if_fail (g_key_file_is_key_name (key, strlen (key)));
g_return_if_fail (value != NULL);
group = g_key_file_lookup_group (key_file, group_name);
@@ -4166,20 +4166,26 @@ g_key_file_is_group_name (const gchar *name)
}
static gboolean
-g_key_file_is_key_name (const gchar *name)
+g_key_file_is_key_name (const gchar *name,
+ gsize len)
{
- const gchar *p, *q;
+ const gchar *p, *q, *end;
if (name == NULL)
return FALSE;
p = q = name;
+ end = name + len;
/* We accept a little more than the desktop entry spec says,
* since gnome-vfs uses mime-types as keys in its cache.
*/
- while (*q && *q != '=' && *q != '[' && *q != ']')
- q = g_utf8_find_next_char (q, NULL);
+ while (q < end && *q && *q != '=' && *q != '[' && *q != ']')
+ {
+ q = g_utf8_find_next_char (q, end);
+ if (q == NULL)
+ q = end;
+ }
/* No empty keys, please */
if (q == p)
@@ -4196,8 +4202,17 @@ g_key_file_is_key_name (const gchar *name)
if (*q == '[')
{
q++;
- while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q ==
'.' || *q == '@'))
- q = g_utf8_find_next_char (q, NULL);
+ while (q < end &&
+ *q != '\0' &&
+ (g_unichar_isalnum (g_utf8_get_char_validated (q, end - q)) || *q == '-' || *q == '_' || *q ==
'.' || *q == '@'))
+ {
+ q = g_utf8_find_next_char (q, end);
+ if (q == NULL)
+ {
+ q = end;
+ break;
+ }
+ }
if (*q != ']')
return FALSE;
@@ -4205,7 +4220,7 @@ g_key_file_is_key_name (const gchar *name)
q++;
}
- if (*q != '\0')
+ if (q < end)
return FALSE;
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]