diff --git a/gdk/gdkrgba.c b/gdk/gdkrgba.c index a900850395..5313b88a36 100644 --- a/gdk/gdkrgba.c +++ b/gdk/gdkrgba.c @@ -27,6 +27,8 @@ #include "config.h" #include "gdkrgba.h" #include +#include +#include /** * SECTION:rgba_colors @@ -101,14 +103,17 @@ gdk_rgba_free (GdkRGBA *rgba) * - We accept mixed percentages and non-percentages in a single * rgb() or rgba() specification. */ -static double -parse_rgb_value (const char *str, - char **endp) +static gboolean +parse_rgb_value (const gchar *str, + gchar **endp, + gdouble *number) { - double number; const char *p; - number = g_ascii_strtod (str, endp); + *number = g_ascii_strtod (str, endp); + if (errno == ERANGE || *endp == str || + isinf (*number) || isnan (*number)) + return FALSE; p = *endp; @@ -117,12 +122,14 @@ parse_rgb_value (const char *str, if (*p == '%') { *endp = (char *)(p + 1); - return CLAMP(number / 100., 0., 1.); + *number = CLAMP(*number / 100., 0., 1.); } else { - return CLAMP(number / 255., 0., 1.); + *number = CLAMP(*number / 255., 0., 1.); } + + return TRUE; } /** @@ -168,6 +175,7 @@ gdk_rgba_parse (GdkRGBA *rgba, gboolean has_alpha; gdouble r, g, b, a; gchar *str = (gchar *) spec; + gchar *p; if (strncmp (str, "rgba", 4) == 0) { @@ -212,7 +220,8 @@ gdk_rgba_parse (GdkRGBA *rgba, /* Parse red */ SKIP_WHITESPACES (str); - r = parse_rgb_value (str, &str); + if (!parse_rgb_value (str, &str, &r)) + return FALSE; SKIP_WHITESPACES (str); if (*str != ',') @@ -222,7 +231,8 @@ gdk_rgba_parse (GdkRGBA *rgba, /* Parse green */ SKIP_WHITESPACES (str); - g = parse_rgb_value (str, &str); + if (!parse_rgb_value (str, &str, &g)) + return FALSE; SKIP_WHITESPACES (str); if (*str != ',') @@ -232,7 +242,8 @@ gdk_rgba_parse (GdkRGBA *rgba, /* Parse blue */ SKIP_WHITESPACES (str); - b = parse_rgb_value (str, &str); + if (!parse_rgb_value (str, &str, &b)) + return FALSE; SKIP_WHITESPACES (str); if (has_alpha) @@ -243,13 +254,24 @@ gdk_rgba_parse (GdkRGBA *rgba, str++; SKIP_WHITESPACES (str); - a = g_ascii_strtod (str, &str); + a = g_ascii_strtod (str, &p); + if (errno == ERANGE || p == str || + isinf (a) || isnan (a)) + return FALSE; + str = p; SKIP_WHITESPACES (str); } if (*str != ')') return FALSE; + str++; + + SKIP_WHITESPACES (str); + + if (*str != '\0') + return FALSE; + if (rgba) { rgba->red = CLAMP (r, 0, 1);