=================================================================== RCS file: /cvs/mandoc/roff_escape.c,v retrieving revision 1.8 retrieving revision 1.11 diff -u -p -r1.8 -r1.11 --- mandoc/roff_escape.c 2022/06/02 14:51:41 1.8 +++ mandoc/roff_escape.c 2022/06/06 12:09:48 1.11 @@ -1,4 +1,4 @@ -/* $OpenBSD: roff_escape.c,v 1.8 2022/06/02 14:51:41 schwarze Exp $ */ +/* $OpenBSD: roff_escape.c,v 1.11 2022/06/06 12:09:48 schwarze Exp $ */ /* * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022 * Ingo Schwarze @@ -98,6 +98,7 @@ roff_escape(const char *buf, const int ln, const int a iarg = iendarg = iend = inam + 1; maxl = INT_MAX; term = '\0'; + err = MANDOCERR_OK; switch (buf[inam]) { /* Escape sequences taking no arguments at all. */ @@ -205,10 +206,6 @@ roff_escape(const char *buf, const int ln, const int a term = '\b'; break; case 'C': - if (buf[iarg] != '\'') { - rval = ESCAPE_ERROR; - goto out; - } rval = ESCAPE_SPECIAL; term = '\b'; break; @@ -309,6 +306,9 @@ roff_escape(const char *buf, const int ln, const int a iendarg = iarg; while (maxl > 0) { if (buf[iendarg] == '\0') { + err = MANDOCERR_ESC_INCOMPLETE; + if (rval != ESCAPE_EXPAND) + rval = ESCAPE_ERROR; /* Ignore an incomplete argument except for \w. */ if (buf[inam] != 'w') iendarg = iarg; @@ -343,9 +343,6 @@ roff_escape(const char *buf, const int ln, const int a iend = ++iendarg; } } - if (resc != NULL && ((maxl != INT_MAX && maxl != 0) || - (term != '\0' && buf[iendarg] != term))) - mandoc_msg(MANDOCERR_ESC_BAD, ln, iesc, "%s", buf + iesc); /* Post-process depending on the content of the argument. */ @@ -390,6 +387,11 @@ roff_escape(const char *buf, const int ln, const int a break; case ESCAPE_SPECIAL: + if (argl == 0) { + err = MANDOCERR_ESC_BADCHAR; + rval = ESCAPE_ERROR; + break; + } /* * The file chars.c only provides one common list of @@ -399,6 +401,7 @@ roff_escape(const char *buf, const int ln, const int a */ if (term != '\0' && argl == 1 && buf[iarg] != '-') { + err = MANDOCERR_ESC_BADCHAR; rval = ESCAPE_ERROR; break; } @@ -414,8 +417,10 @@ roff_escape(const char *buf, const int ln, const int a c = 0; for (i = iarg; i < iendarg; i++) c = 10 * c + (buf[i] - '0'); - if (c < 0x21 || (c > 0x7e && c < 0xa0) || c > 0xff) + if (c < 0x21 || (c > 0x7e && c < 0xa0) || c > 0xff) { + err = MANDOCERR_ESC_BADCHAR; break; + } iarg += 4; rval = ESCAPE_NUMBERED; break; @@ -431,13 +436,19 @@ roff_escape(const char *buf, const int ln, const int a if (buf[iarg] != 'u' || argl < 5 || argl > 7) break; if (argl == 7 && - (buf[iarg + 1] != '1' || buf[iarg + 2] != '0')) + (buf[iarg + 1] != '1' || buf[iarg + 2] != '0')) { + err = MANDOCERR_ESC_BADCHAR; break; - if (argl == 6 && buf[iarg + 1] == '0') + } + if (argl == 6 && buf[iarg + 1] == '0') { + err = MANDOCERR_ESC_BADCHAR; break; + } if (argl == 5 && buf[iarg + 1] == 'D' && - strchr("89ABCDEF", buf[iarg + 2]) != NULL) + strchr("89ABCDEF", buf[iarg + 2]) != NULL) { + err = MANDOCERR_ESC_BADCHAR; break; + } if ((int)strspn(buf + iarg + 1, "0123456789ABCDEFabcdef") + 1 == argl) rval = ESCAPE_UNICODE; @@ -475,24 +486,26 @@ out: *resc = iesc; switch (rval) { case ESCAPE_ERROR: - err = MANDOCERR_ESC_BAD; + if (err == MANDOCERR_OK) + err = MANDOCERR_ESC_BAD; break; case ESCAPE_UNSUPP: err = MANDOCERR_ESC_UNSUPP; break; case ESCAPE_UNDEF: - if (buf[inam] == '\\' || buf[inam] == '.') - return rval; - err = MANDOCERR_ESC_UNDEF; + if (buf[inam] != '\\' && buf[inam] != '.') + err = MANDOCERR_ESC_UNDEF; break; case ESCAPE_SPECIAL: if (mchars_spec2cp(buf + iarg, argl) >= 0) - return rval; - err = MANDOCERR_ESC_BAD; + err = MANDOCERR_OK; + else if (err == MANDOCERR_OK) + err = MANDOCERR_ESC_UNKCHAR; break; default: - return rval; + break; } - mandoc_msg(err, ln, iesc, "%.*s", iend - iesc, buf + iesc); + if (err != MANDOCERR_OK) + mandoc_msg(err, ln, iesc, "%.*s", iend - iesc, buf + iesc); return rval; }