From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 23142 invoked from network); 2 Jun 2022 11:29:40 -0000 Received: from bsd.lv (HELO mandoc.bsd.lv) (66.111.2.12) by inbox.vuxu.org with ESMTPUTF8; 2 Jun 2022 11:29:40 -0000 Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id 7be332f2 for ; Thu, 2 Jun 2022 06:29:38 -0500 (EST) Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id 77e2c609 for ; Thu, 2 Jun 2022 06:29:38 -0500 (EST) Date: Thu, 2 Jun 2022 06:29:38 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: Avoid the layering violation of re-parsing for \E in X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <33659942088fa125@mandoc.bsd.lv> Log Message: ----------- Avoid the layering violation of re-parsing for \E in roff_expand(). To that end, add another argument to roff_escape() returning the index of the escape name. This also makes the code in roff_escape() a bit more uniform in so far as it no longer needs the "char esc_name" local variable but now does everything with indices into buf[]. No functional change. Modified Files: -------------- mandoc: roff.c roff_escape.c roff_int.h Revision Data ------------- Index: roff_escape.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff_escape.c,v retrieving revision 1.6 retrieving revision 1.7 diff -Lroff_escape.c -Lroff_escape.c -u -p -r1.6 -r1.7 --- roff_escape.c +++ roff_escape.c @@ -41,7 +41,8 @@ mandoc_escape(const char **rendarg, cons int iarg, iendarg, iend; enum mandoc_esc rval; - rval = roff_escape(--*rendarg, 0, 0, NULL, &iarg, &iendarg, &iend); + rval = roff_escape(--*rendarg, 0, 0, + NULL, NULL, &iarg, &iendarg, &iend); assert(rval != ESCAPE_EXPAND); if (rarg != NULL) *rarg = *rendarg + iarg; @@ -63,20 +64,20 @@ mandoc_escape(const char **rendarg, cons */ enum mandoc_esc roff_escape(const char *buf, const int ln, const int aesc, - int *resc, int *rarg, int *rendarg, int *rend) + int *resc, int *rnam, int *rarg, int *rendarg, int *rend) { int iesc; /* index of leading escape char */ + int inam; /* index of escape name */ int iarg; /* index beginning the argument */ int iendarg; /* index right after the argument */ int iend; /* index right after the sequence */ - int sesc, sarg, sendarg, send; /* for sub-escape */ + int sesc, snam, sarg, sendarg, send; /* for sub-escape */ 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 mandocerr err; /* diagnostic code */ - char esc_name; char term; /* byte terminating the argument */ /* @@ -84,21 +85,20 @@ roff_escape(const char *buf, const int l * it only makes a difference in copy mode. */ - iesc = iarg = aesc; + iesc = inam = aesc; do { - iarg++; - } while (buf[iarg] == 'E'); + inam++; + } while (buf[inam] == 'E'); /* * Sort the following cases first by syntax category, * then by escape sequence type, and finally by ASCII code. */ - esc_name = buf[iarg]; - iendarg = iend = ++iarg; + iarg = iendarg = iend = inam + 1; maxl = INT_MAX; term = '\0'; - switch (esc_name) { + switch (buf[inam]) { /* Escape sequences taking no arguments at all. */ @@ -269,12 +269,12 @@ roff_escape(const char *buf, const int l if ((term == '\b' || (term == '\0' && maxl == INT_MAX)) && buf[iarg] == buf[iesc] && roff_escape(buf, ln, iendarg, - &sesc, &sarg, &sendarg, &send) == ESCAPE_EXPAND) + &sesc, &snam, &sarg, &sendarg, &send) == ESCAPE_EXPAND) goto out_sub; if (term == '\b') { - if ((esc_name == 'N' && isdigit((unsigned char)buf[iarg])) || - (esc_name == 'h' && strchr(" %&()*+-./0123456789:<=>", + if ((buf[inam] == 'N' && isdigit((unsigned char)buf[iarg])) || + (buf[inam] == 'h' && strchr(" %&()*+-./0123456789:<=>", buf[iarg]) != NULL)) { iendarg = iend = iarg + 1; rval = ESCAPE_ERROR; @@ -282,7 +282,7 @@ roff_escape(const char *buf, const int l } term = buf[iarg++]; } else if (term == '\0' && maxl == INT_MAX) { - if (esc_name == 'n' && (buf[iarg] == '+' || buf[iarg] == '-')) + if (buf[inam] == 'n' && (buf[iarg] == '+' || buf[iarg] == '-')) iarg++; switch (buf[iarg]) { case '(': @@ -310,7 +310,7 @@ roff_escape(const char *buf, const int l while (maxl > 0) { if (buf[iendarg] == '\0') { /* Ignore an incomplete argument except for \w. */ - if (esc_name != 'w') + if (buf[inam] != 'w') iendarg = iarg; break; } @@ -318,14 +318,14 @@ roff_escape(const char *buf, const int l iend = iendarg + 1; break; } - if (esc_name == 'N' && + 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, &sarg, &sendarg, &send)) { + &sesc, &snam, &sarg, &sendarg, &send)) { case ESCAPE_EXPAND: goto out_sub; case ESCAPE_UNDEF: @@ -350,7 +350,7 @@ roff_escape(const char *buf, const int l /* Post-process depending on the content of the argument. */ argl = iendarg - iarg; - switch (esc_name) { + switch (buf[inam]) { case '*': if (resc == NULL && argl == 2 && buf[iarg] == '.' && buf[iarg + 1] == 'T') @@ -449,12 +449,15 @@ roff_escape(const char *buf, const int l out_sub: iesc = sesc; + inam = snam; iarg = sarg; iendarg = sendarg; iend = send; rval = ESCAPE_EXPAND; out: + if (rnam != NULL) + *rnam = inam; if (rarg != NULL) *rarg = iarg; if (rendarg != NULL) @@ -478,7 +481,7 @@ out: err = MANDOCERR_ESC_UNSUPP; break; case ESCAPE_UNDEF: - if (esc_name == '\\') + if (buf[inam] == '\\') return rval; err = MANDOCERR_ESC_UNDEF; break; Index: roff_int.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff_int.h,v retrieving revision 1.19 retrieving revision 1.20 diff -Lroff_int.h -Lroff_int.h -u -p -r1.19 -r1.20 --- roff_int.h +++ roff_int.h @@ -83,7 +83,7 @@ enum roff_tok roffhash_find(struct oha void roffhash_free(struct ohash *); enum mandoc_esc roff_escape(const char *, const int, const int, - int *, int *, int *, int *); + int *, int *, int *, int *, int *); void roff_state_reset(struct roff_man *); void roff_validate(struct roff_man *); Index: roff.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff.c,v retrieving revision 1.391 retrieving revision 1.392 diff -Lroff.c -Lroff.c -u -p -r1.391 -r1.392 --- roff.c +++ roff.c @@ -1410,8 +1410,8 @@ roff_expand(struct roff *r, struct buf * * it to backslashes and translate backslashes to \e. */ - if (roff_escape(buf->buf, ln, pos, - &iesc, &iarg, &iendarg, &iend) != ESCAPE_EXPAND) { + if (roff_escape(buf->buf, ln, pos, &iesc, &inam, + &iarg, &iendarg, &iend) != ESCAPE_EXPAND) { while (pos < iend) { if (buf->buf[pos] == ec) { buf->buf[pos] = '\\'; @@ -1427,15 +1427,6 @@ roff_expand(struct roff *r, struct buf * } continue; } - - /* - * Treat "\E" just like "\"; - * it only makes a difference in copy mode. - */ - - inam = iesc + 1; - while (buf->buf[inam] == 'E') - inam++; /* Handle expansion. */ -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv