source@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: schwarze@mandoc.bsd.lv
To: source@mandoc.bsd.lv
Subject: mandoc: Avoid the layering violation of re-parsing for \E in
Date: Thu, 2 Jun 2022 06:29:38 -0500 (EST)	[thread overview]
Message-ID: <33659942088fa125@mandoc.bsd.lv> (raw)

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


                 reply	other threads:[~2022-06-02 11:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=33659942088fa125@mandoc.bsd.lv \
    --to=schwarze@mandoc.bsd.lv \
    --cc=source@mandoc.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).