gkeyfile: Handle whitespace after boolean values

Ignore trailing whitespace when reading boolean values. Currently it is
very easy to manually edit a keyfile to be:

[section]
key=true_

Where '_' is a space character. g_key_file_get_boolean will read this value as
false and this is hard for a user to detect (it will be reported in GError
as an invalid value).

Trailing whitespace is ignored for numbers for the same reason. This was
fixed in 7a45dde4fe.

https://bugzilla.gnome.org/show_bug.cgi?id=664740
This commit is contained in:
Robert Ancell 2015-10-20 15:44:32 +13:00
parent 51ed0f0405
commit 31c45cb6ae
2 changed files with 19 additions and 2 deletions

View File

@ -4319,16 +4319,29 @@ g_key_file_parse_value_as_double (GKeyFile *key_file,
return double_value;
}
static gint
strcmp_sized (const gchar *s1, size_t len1, const gchar *s2)
{
size_t len2 = strlen (s2);
return strncmp (s1, s2, MAX (len1, len2));
}
static gboolean
g_key_file_parse_value_as_boolean (GKeyFile *key_file,
const gchar *value,
GError **error)
{
gchar *value_utf8;
gint i, length = 0;
if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
/* Count the number of non-whitespace characters */
for (i = 0; value[i]; i++)
if (!g_ascii_isspace (value[i]))
length = i + 1;
if (strcmp_sized (value, length, "true") == 0 || strcmp_sized (value, length, "1") == 0)
return TRUE;
else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
else if (strcmp_sized (value, length, "false") == 0 || strcmp_sized (value, length, "0") == 0)
return FALSE;
value_utf8 = _g_utf8_make_valid (value);

View File

@ -574,6 +574,8 @@ test_boolean (void)
"key2=false\n"
"key3=1\n"
"key4=0\n"
"key5= true\n"
"key6=true \n"
"[invalid]\n"
"key1=t\n"
"key2=f\n"
@ -586,6 +588,8 @@ test_boolean (void)
check_boolean_value (keyfile, "valid", "key2", FALSE);
check_boolean_value (keyfile, "valid", "key3", TRUE);
check_boolean_value (keyfile, "valid", "key4", FALSE);
check_boolean_value (keyfile, "valid", "key5", TRUE);
check_boolean_value (keyfile, "valid", "key6", TRUE);
g_key_file_get_boolean (keyfile, "invalid", "key1", &error);
check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);