]> git.eshelyaron.com Git - emacs.git/commitdiff
More robust NS hex colour string parsing
authorMattias Engdegård <mattiase@acm.org>
Mon, 8 Jun 2020 11:06:51 +0000 (13:06 +0200)
committerMattias Engdegård <mattiase@acm.org>
Mon, 8 Jun 2020 11:24:29 +0000 (13:24 +0200)
Invalid arguments to color-values, such as "#abcdefg" or "#1234", or
valid ones like "#111222333", should not yield nonsense values.

* src/nsterm.m (ns_get_color):
Only accept "#RGB" strings with 1-4 digits per components, equal number
of digits each, and no trailing characters.  Parse 12-bit colours
correctly.

src/nsterm.m

index 19531389545872a9f8435ffa0763f6ccfac96683..3dc7e1db7c9683b6769902a6b10ae49435ba86f2 100644 (file)
@@ -2399,20 +2399,23 @@ ns_get_color (const char *name, NSColor **col)
     scaling = (snprintf (hex, sizeof hex, "%s", name + 4) - 2) / 3;
   else if (name[0] == '#')        /* An old X11 format; convert to newer */
     {
-      int len = (strlen(name) - 1);
-      int start = (len % 3 == 0) ? 1 : len / 4 + 1;
-      int i;
-      scaling = strlen(name+start) / 3;
-      for (i = 0; i < 3; i++)
-       sprintf (hex + i * (scaling + 1), "%.*s/", scaling,
-                name + start + i * scaling);
-      hex[3 * (scaling + 1) - 1] = '\0';
+      int len = 0;
+      while (isxdigit (name[len + 1]))
+        len++;
+      if (name[len + 1] == '\0' && len >= 1 && len <= 12 && len % 3 == 0)
+        {
+          scaling = len / 3;
+          for (int i = 0; i < 3; i++)
+            sprintf (hex + i * (scaling + 1), "%.*s/", scaling,
+                     name + 1 + i * scaling);
+          hex[3 * (scaling + 1) - 1] = '\0';
+        }
     }
 
   if (hex[0])
     {
       unsigned int rr, gg, bb;
-      float fscale = scaling == 4 ? 65535.0 : (scaling == 2 ? 255.0 : 15.0);
+      float fscale = (1 << (scaling * 4)) - 1;
       if (sscanf (hex, "%x/%x/%x", &rr, &gg, &bb))
         {
           r = rr / fscale;