Tighten Unicode escape name parsing.
authorIngo Schwarze <schwarze@openbsd.org>
Tue, 28 Oct 2014 13:24:44 +0000 (13:24 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Tue, 28 Oct 2014 13:24:44 +0000 (13:24 +0000)
Accept only 0xXXXX, 0xYXXXX, 0x10XXXX with Y != 0.
This simplifies mchars_num2uc().

chars.c
mandoc.c

diff --git a/chars.c b/chars.c
index 8c99d0a0fb72298f67bcdaffc9c98755e1162afb..6d26208d7e574a6062026680308b676ee45053ef 100644 (file)
--- a/chars.c
+++ b/chars.c
@@ -1,4 +1,4 @@
-/*     $Id: chars.c,v 1.62 2014/10/27 13:31:04 schwarze Exp $ */
+/*     $Id: chars.c,v 1.63 2014/10/28 13:24:44 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -123,14 +123,9 @@ mchars_num2uc(const char *p, size_t sz)
 {
        int      i;
 
-       if ((i = mandoc_strntoi(p, sz, 16)) < 0)
-               return(0xFFFD);
-
-       /*
-        * XXX Code is missing here to exclude bogus ranges.
-        */
-
-       return(i <= 0x10FFFF ? i : 0xFFFD);
+       i = mandoc_strntoi(p, sz, 16);
+       assert(i >= 0 && i <= 0x10FFFF);
+       return(i);
 }
 
 const char *
index e82093b935dbbe55c524f31ff1b29d61183a2671..2ec179ea2302ffd906662c202b508d2ce565812a 100644 (file)
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.c,v 1.87 2014/10/13 17:17:45 schwarze Exp $ */
+/*     $Id: mandoc.c,v 1.88 2014/10/28 13:24:44 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -334,13 +334,18 @@ mandoc_escape(const char **end, const char **start, int *sz)
                if (1 == *sz && 'c' == **start)
                        gly = ESCAPE_NOSPACE;
                /*
-                * Unicode escapes are defined in groff as \[uXXXX]
+                * Unicode escapes are defined in groff as \[u0000]
                 * to \[u10FFFF], where the contained value must be
                 * a valid Unicode codepoint.  Here, however, only
-                * check the length and the validity of all digits.
+                * check the length and range.
                 */
-               else if (*sz > 4 && *sz < 8 && **start == 'u' &&
-                   (int)strspn(*start + 1, "0123456789ABCDEFabcdef")
+               if (**start != 'u' || *sz < 5 || *sz > 7)
+                       break;
+               if (*sz == 7 && ((*start)[1] != '1' || (*start)[2] != '0'))
+                       break;
+               if (*sz == 6 && (*start)[1] == '0')
+                       break;
+               if ((int)strspn(*start + 1, "0123456789ABCDEFabcdef")
                    + 1 == *sz)
                        gly = ESCAPE_UNICODE;
                break;