source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mandoc: Avoid the layering violation of re-parsing for \E in
@ 2022-06-02 11:29 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2022-06-02 11:29 UTC (permalink / raw)
  To: source

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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-02 11:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 11:29 mandoc: Avoid the layering violation of re-parsing for \E in schwarze

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).