mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-31 21:03:10 +02:00
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>
This commit is contained in:
parent
46fe9639b9
commit
960030712d
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user