summaryrefslogtreecommitdiff
path: root/gdk/gdkrgba.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2012-01-08 22:16:36 -0500
committerMatthias Clasen <mclasen@redhat.com>2012-01-09 00:31:20 -0500
commite5e6d25a503e211147ba353ffebb9927aabe4de2 (patch)
treeae2dc2e23e92fde931e40751cf9229e3c3ffc8bd /gdk/gdkrgba.c
parent7ac975bb4835e6e04b7ef2e9b9836bfe086f7c3d (diff)
downloadgtk+-e5e6d25a503e211147ba353ffebb9927aabe4de2.tar.gz
Tighten up GdkRGBA parsing
gdk_rgba_parse was accepting too much nonsense, as pointed out in bug 667485.
Diffstat (limited to 'gdk/gdkrgba.c')
-rw-r--r--gdk/gdkrgba.c44
1 files changed, 33 insertions, 11 deletions
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 <string.h>
+#include <errno.h>
+#include <math.h>
/**
* 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);