=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/roff_escape.c,v retrieving revision 1.13 retrieving revision 1.14 diff -c -r1.13 -r1.14 *** src/usr.bin/mandoc/roff_escape.c 2022/06/07 09:51:03 1.13 --- src/usr.bin/mandoc/roff_escape.c 2022/06/08 13:08:00 1.14 *************** *** 1,4 **** ! /* $OpenBSD: roff_escape.c,v 1.13 2022/06/07 09:51:03 schwarze Exp $ */ /* * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022 * Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: roff_escape.c,v 1.14 2022/06/08 13:08:00 schwarze Exp $ */ /* * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022 * Ingo Schwarze *************** *** 59,65 **** * sequence are returned in *resc ... *rend. * Otherwise, *resc is set to aesc and the positions of the escape * sequence starting at aesc are returned. ! * Diagnostic messages are generated if and only if resc != NULL, * that is, if and only if called by roff_expand(). */ enum mandoc_esc --- 59,65 ---- * sequence are returned in *resc ... *rend. * Otherwise, *resc is set to aesc and the positions of the escape * sequence starting at aesc are returned. ! * Diagnostic messages are generated if and only if ln != 0, * that is, if and only if called by roff_expand(). */ enum mandoc_esc *************** *** 72,82 **** --- 72,84 ---- int iendarg; /* index right after the argument */ int iend; /* index right after the sequence */ int sesc, snam, sarg, sendarg, send; /* for sub-escape */ + int escterm; /* whether term is escaped */ int maxl; /* expected length of the argument */ int argl; /* actual length of the argument */ int c, i; /* for \[char...] parsing */ int valid_A; /* for \A parsing */ enum mandoc_esc rval; /* return value */ + enum mandoc_esc stype; /* for sub-escape */ enum mandocerr err; /* diagnostic code */ char term; /* byte terminating the argument */ *************** *** 264,276 **** /* Decide how to end the argument. */ if ((term == '\b' || (term == '\0' && maxl == INT_MAX)) && ! buf[iarg] == buf[iesc] && roff_escape(buf, ln, iendarg, ! &sesc, &snam, &sarg, &sendarg, &send) == ESCAPE_EXPAND) ! goto out_sub; if (term == '\b') { ! if (strchr("BDHLRSvxNhl", buf[inam]) != NULL && strchr(" %&()*+-./0123456789:<=>", buf[iarg]) != NULL) { err = MANDOCERR_ESC_DELIM; if (rval != ESCAPE_EXPAND) --- 266,297 ---- /* Decide how to end the argument. */ + escterm = 0; + stype = ESCAPE_EXPAND; if ((term == '\b' || (term == '\0' && maxl == INT_MAX)) && ! buf[iarg] == buf[iesc]) { ! stype = roff_escape(buf, ln, iendarg, ! &sesc, &snam, &sarg, &sendarg, &send); ! if (stype == ESCAPE_EXPAND) ! goto out_sub; ! } if (term == '\b') { ! if (stype == ESCAPE_UNDEF) ! iarg++; ! if (stype != ESCAPE_EXPAND && stype != ESCAPE_UNDEF) { ! if (strchr("BHLRSNhlvx", buf[inam]) != NULL && ! strchr(" ,.0DLOXYZ^abdhlortuvx|~", ! buf[snam]) != NULL) { ! err = MANDOCERR_ESC_DELIM; ! iend = send; ! iarg = iendarg = sesc; ! goto out; ! } ! escterm = 1; ! iarg = send; ! term = buf[snam]; ! } else if (strchr("BDHLRSvxNhl", buf[inam]) != NULL && strchr(" %&()*+-./0123456789:<=>", buf[iarg]) != NULL) { err = MANDOCERR_ESC_DELIM; if (rval != ESCAPE_EXPAND) *************** *** 280,286 **** goto out; } } ! term = buf[iarg++]; } else if (term == '\0' && maxl == INT_MAX) { if (buf[inam] == 'n' && (buf[iarg] == '+' || buf[iarg] == '-')) iarg++; --- 301,308 ---- goto out; } } ! if (term == '\b') ! term = buf[iarg++]; } else if (term == '\0' && maxl == INT_MAX) { if (buf[inam] == 'n' && (buf[iarg] == '+' || buf[iarg] == '-')) iarg++; *************** *** 311,344 **** 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; break; } ! if (buf[iendarg] == term) { iend = iendarg + 1; break; } - if (buf[inam] == 'N' && - isdigit((unsigned char)buf[iendarg]) == 0) { - iend = iendarg + 1; - break; - } if (buf[iendarg] == buf[iesc]) { ! switch (roff_escape(buf, ln, iendarg, ! &sesc, &snam, &sarg, &sendarg, &send)) { ! case ESCAPE_EXPAND: goto out_sub; ! case ESCAPE_UNDEF: break; ! default: valid_A = 0; ! break; ! } ! iendarg = iend = send; } else { if (buf[iendarg] == ' ' || buf[iendarg] == '\t') valid_A = 0; --- 333,366 ---- while (maxl > 0) { if (buf[iendarg] == '\0') { err = MANDOCERR_ESC_INCOMPLETE; ! if (rval != ESCAPE_EXPAND && ! rval != ESCAPE_OVERSTRIKE) rval = ESCAPE_ERROR; ! /* Usually, ignore an incomplete argument. */ ! if (strchr("Aow", buf[inam]) == NULL) iendarg = iarg; break; } ! if (escterm == 0 && buf[iendarg] == term) { iend = iendarg + 1; break; } if (buf[iendarg] == buf[iesc]) { ! stype = roff_escape(buf, ln, iendarg, ! &sesc, &snam, &sarg, &sendarg, &send); ! if (stype == ESCAPE_EXPAND) goto out_sub; ! iend = send; ! if (escterm == 1 && ! (buf[snam] == term || buf[inam] == 'N')) break; ! if (stype != ESCAPE_UNDEF) valid_A = 0; ! iendarg = send; ! } else if (buf[inam] == 'N' && ! isdigit((unsigned char)buf[iendarg]) == 0) { ! iend = iendarg + 1; ! break; } else { if (buf[iendarg] == ' ' || buf[iendarg] == '\t') valid_A = 0; *************** *** 483,488 **** --- 505,512 ---- rval = ESCAPE_EXPAND; out: + if (resc != NULL) + *resc = iesc; if (rnam != NULL) *rnam = inam; if (rarg != NULL) *************** *** 491,497 **** *rendarg = iendarg; if (rend != NULL) *rend = iend; ! if (resc == NULL) return rval; /* --- 515,521 ---- *rendarg = iendarg; if (rend != NULL) *rend = iend; ! if (ln == 0) return rval; /* *************** *** 499,505 **** * from the parser, not when called from the formatters. */ - *resc = iesc; switch (rval) { case ESCAPE_UNSUPP: err = MANDOCERR_ESC_UNSUPP; --- 523,528 ----