diff --git a/ChangeLog b/ChangeLog index 42e3dc8c8e..a379891d8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-06-26 Richard Hult + + * gtk/gtkbuilder.c: (gtk_builder_value_from_string_type): Fix a + bunch of small bugs when parsing property values + (boolean/int/uint/long/ulong/float/double). Bug #451353. + + * tests/buildertest.c: Add tests for the above. + 2007-06-26 Emmanuele Bassi * gtk/gtkfilechooserdefault.c (list_mtime_data_func): Fix diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 145f7d9356..5cf0e97224 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -993,18 +993,30 @@ gtk_builder_value_from_string_type (GType type, { gboolean b; - if (g_ascii_tolower (string[0]) == 't') - b = TRUE; - else if (g_ascii_tolower (string[0]) == 'y') - b = FALSE; - else { - errno = 0; - b = strtol (string, NULL, 0); - if (errno) { - g_warning ("could not parse int `%s'", string); + switch (g_ascii_tolower (string[0])) + { + case 't': + case 'y': + b = TRUE; + break; + case 'f': + case 'n': + b = FALSE; + break; + default: + { + gchar *endptr; + errno = 0; + b = strtol (string, &endptr, 0); + if (errno || endptr == string) + { + g_warning ("could not parse int `%s'", string); + ret = FALSE; + break; + } + } break; } - } g_value_set_boolean (value, b); break; } @@ -1012,12 +1024,15 @@ gtk_builder_value_from_string_type (GType type, case G_TYPE_LONG: { long l; + gchar *endptr; errno = 0; - l = strtol (string, NULL, 0); - if (errno) { - g_warning ("could not parse long `%s'", string); - break; - } + l = strtol (string, &endptr, 0); + if (errno || endptr == string) + { + g_warning ("could not parse long `%s'", string); + ret = FALSE; + break; + } if (G_VALUE_HOLDS_INT (value)) g_value_set_int (value, l); else @@ -1028,17 +1043,19 @@ gtk_builder_value_from_string_type (GType type, case G_TYPE_ULONG: { gulong ul; + gchar *endptr; errno = 0; - ul = strtoul (string, NULL, 0); - if (errno) + ul = strtoul (string, &endptr, 0); + if (errno || endptr == string) { g_warning ("could not parse ulong `%s'", string); + ret = FALSE; break; } if (G_VALUE_HOLDS_UINT (value)) - g_value_set_uint (value, strtoul (string, NULL, 0)); + g_value_set_uint (value, ul); else - g_value_set_ulong (value, strtoul (string, NULL, 0)); + g_value_set_ulong (value, ul); break; } case G_TYPE_ENUM: @@ -1051,11 +1068,13 @@ gtk_builder_value_from_string_type (GType type, case G_TYPE_DOUBLE: { double d; + gchar *endptr; errno = 0; - d = g_ascii_strtod (string, NULL); - if (errno) + d = g_ascii_strtod (string, &endptr); + if (errno || endptr == string) { g_warning ("could not parse double `%s'", string); + ret = FALSE; break; } if (G_VALUE_HOLDS_FLOAT (value)) diff --git a/tests/buildertest.c b/tests/buildertest.c index b5fbc6bf5b..3c6ab29b17 100644 --- a/tests/buildertest.c +++ b/tests/buildertest.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -74,7 +75,7 @@ gboolean test_parser (void) return TRUE; } - int normal; +int normal; int after; int object; int object_after; @@ -1369,6 +1370,78 @@ gboolean test_widget (void) return TRUE; } +static gboolean +test_value_from_string (void) +{ + GValue value = { 0 }; + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_STRING, "test", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_STRING (&value), FALSE); + g_return_val_if_fail (strcmp (g_value_get_string (&value), "test") == 0, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "true", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "false", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == FALSE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "yes", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "no", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == FALSE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "0", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == FALSE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "1", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_BOOLEAN, "blaurgh", &value) == FALSE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_INT, "12345", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_INT (&value), FALSE); + g_return_val_if_fail (g_value_get_int (&value) == 12345, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_LONG, "9912345", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_LONG (&value), FALSE); + g_return_val_if_fail (g_value_get_long (&value) == 9912345, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_UINT, "2345", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_UINT (&value), FALSE); + g_return_val_if_fail (g_value_get_uint (&value) == 2345, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_FLOAT, "1.454", &value), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_FLOAT (&value), FALSE); + g_return_val_if_fail (fabs (g_value_get_float (&value) - 1.454) < 0.00001, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_FLOAT, "abc", &value) == FALSE, FALSE); + g_value_unset (&value); + + g_return_val_if_fail (gtk_builder_value_from_string_type (G_TYPE_INT, "/-+,abc", &value) == FALSE, FALSE); + g_value_unset (&value); + + return TRUE; +} + int main (int argc, char **argv) { @@ -1458,5 +1531,9 @@ main (int argc, char **argv) if (!test_widget ()) g_error ("test_widget failed"); + g_print ("Testing value from string\n"); + if (!test_value_from_string ()) + g_error ("test_value_from_string failed"); + return 0; }