[gtk+] Tighten up GdkRGBA parsing



commit e5e6d25a503e211147ba353ffebb9927aabe4de2
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jan 8 22:16:36 2012 -0500

    Tighten up GdkRGBA parsing
    
    gdk_rgba_parse was accepting too much nonsense, as pointed out
    in bug 667485.

 gdk/gdkrgba.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)
---
diff --git a/gdk/gdkrgba.c b/gdk/gdkrgba.c
index a900850..5313b88 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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]