]> git.cameronkatri.com Git - mandoc.git/commitdiff
Stricter syntax checking of Unicode character names:
authorIngo Schwarze <schwarze@openbsd.org>
Mon, 13 Oct 2014 17:17:45 +0000 (17:17 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Mon, 13 Oct 2014 17:17:45 +0000 (17:17 +0000)
Require exactly 4, 5 or 6 hex digits and allow nothing else.
This avoids mishandling stuff like \[ua] and \C'uA' as Unicode
and also fixes underlining in eqn(7) -Thtml output which uses \[ul].
Problem found and semantics suggested by kristaps@.

mandoc.c

index be3e264cf16b922e67775b6363dac331625e0662..e82093b935dbbe55c524f31ff1b29d61183a2671 100644 (file)
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/*     $Id: mandoc.c,v 1.86 2014/08/18 09:11:47 kristaps Exp $ */
+/*     $Id: mandoc.c,v 1.87 2014/10/13 17:17:45 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -79,24 +79,13 @@ mandoc_escape(const char **end, const char **start, int *sz)
                break;
        case '[':
                gly = ESCAPE_SPECIAL;
-               /*
-                * Unicode escapes are defined in groff as \[uXXXX] to
-                * \[u10FFFF], where the contained value must be a valid
-                * Unicode codepoint.  Here, however, only check whether
-                * it's not a zero-width escape.
-                */
-               if ('u' == (*start)[0] && ']' != (*start)[1])
-                       gly = ESCAPE_UNICODE;
                term = ']';
                break;
        case 'C':
                if ('\'' != **start)
                        return(ESCAPE_ERROR);
                *start = ++*end;
-               if ('u' == (*start)[0] && '\'' != (*start)[1])
-                       gly = ESCAPE_UNICODE;
-               else
-                       gly = ESCAPE_SPECIAL;
+               gly = ESCAPE_SPECIAL;
                term = '\'';
                break;
 
@@ -344,6 +333,16 @@ mandoc_escape(const char **end, const char **start, int *sz)
        case ESCAPE_SPECIAL:
                if (1 == *sz && 'c' == **start)
                        gly = ESCAPE_NOSPACE;
+               /*
+                * Unicode escapes are defined in groff as \[uXXXX]
+                * to \[u10FFFF], where the contained value must be
+                * a valid Unicode codepoint.  Here, however, only
+                * check the length and the validity of all digits.
+                */
+               else if (*sz > 4 && *sz < 8 && **start == 'u' &&
+                   (int)strspn(*start + 1, "0123456789ABCDEFabcdef")
+                   + 1 == *sz)
+                       gly = ESCAPE_UNICODE;
                break;
        default:
                break;