shithub: neatroff

Download patch

ref: 2b1a13e49778f57b8c6495ae3edc7c0456077da1
parent: ac60e4b6a01cc80ede183342be54f98117306a4a
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon Feb 13 18:49:39 EST 2017

char: do not limit the length of quoted arguments

--- a/char.c
+++ b/char.c
@@ -1,6 +1,7 @@
 /* reading characters and escapes */
 #include <ctype.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include "roff.h"
 
@@ -54,45 +55,51 @@
 }
 
 /* read quoted arguments of escape sequences (ESC_Q) */
-void quotednext(char *d, int (*next)(void), void (*back)(int))
+char *quotednext(int (*next)(void), void (*back)(int))
 {
 	char delim[GNLEN], cs[GNLEN];
+	struct sbuf sb;
+	char d[GNLEN];
 	charnext(delim, next, back);
+	sbuf_init(&sb);
 	while (charnext_delim(cs, next, back, delim) >= 0) {
 		charnext_str(d, cs);
-		d = strchr(d, '\0');
+		sbuf_append(&sb, d);
 	}
+	return sbuf_out(&sb);
 }
 
 /* read unquoted arguments of escape sequences (ESC_P) */
-void unquotednext(char *d, int cmd, int (*next)(void), void (*back)(int))
+char *unquotednext(int cmd, int (*next)(void), void (*back)(int))
 {
 	int c = next();
+	struct sbuf sb;
+	sbuf_init(&sb);
 	if (cmd == 's' && (c == '-' || c == '+')) {
 		cmd = c;
-		*d++ = c;
+		sbuf_add(&sb, c);
 		c = next();
 	}
 	if (c == '(') {
-		*d++ = next();
-		*d++ = next();
+		sbuf_add(&sb, next());
+		sbuf_add(&sb, next());
 	} else if (!n_cp && c == '[') {
 		c = next();
 		while (c > 0 && c != '\n' && c != ']') {
-			*d++ = c;
+			sbuf_add(&sb, c);
 			c = next();
 		}
 	} else {
-		*d++ = c;
+		sbuf_add(&sb, c);
 		if (cmd == 's' && c >= '1' && c <= '3') {
 			c = next();
 			if (isdigit(c))
-				*d++ = c;
+				sbuf_add(&sb, c);
 			else
 				back(c);
 		}
 	}
-	*d = '\0';
+	return sbuf_out(&sb);
 }
 
 /*
@@ -131,7 +138,9 @@
 			c[l] = '\0';
 			return '[';
 		} else if (c[1] == 'C') {
-			quotednext(c, next, back);
+			char *chr = quotednext(next, back);
+			snprintf(c, GNLEN, "%s", chr);
+			free(chr);
 			return 'C';
 		}
 		return '\\';
--- a/cp.c
+++ b/cp.c
@@ -110,32 +110,37 @@
 /* define a register as \R'xyz expr' */
 static void cp_numdef(void)
 {
-	char arg[ILNLEN];
-	char *s;
-	quotednext(arg, cp_noninext, cp_back);
-	s = arg;
+	char *arg = quotednext(cp_noninext, cp_back);
+	char *s = arg;
 	while (*s && *s != ' ')
 		s++;
-	if (!*s)
+	if (!*s) {
+		free(arg);
 		return;
+	}
 	*s++ = '\0';
 	num_set(map(arg), eval_re(s, num_get(map(arg)), 'u'));
+	free(arg);
 }
 
 /* conditional interpolation as \?'cond@expr1@expr2@' */
 static void cp_cond(void)
 {
-	char arg[ILNLEN];
 	char delim[GNLEN], cs[GNLEN];
-	char *r, *s = arg;
+	char *r, *s;
 	char *s1, *s2;
 	int n;
-	quotednext(arg, cp_noninext, cp_back);
+	char *arg = quotednext(cp_noninext, cp_back);
+	s = arg;
 	n = eval_up(&s, '\0');
-	if (charread(&s, delim) < 0)
+	if (charread(&s, delim) < 0) {
+		free(arg);
 		return;
-	if (!strcmp(delim, "\\&") && charread(&s, delim) < 0)
+	}
+	if (!strcmp(delim, "\\&") && charread(&s, delim) < 0) {
+		free(arg);
 		return;
+	}
 	s1 = s;
 	r = s;
 	while (charread_delim(&s, cs, delim) >= 0)
@@ -147,6 +152,7 @@
 		r = s;
 	*r = '\0';
 	in_push(n > 0 ? s1 : s2, NULL);
+	free(arg);
 }
 
 static int cp_raw(void)
--- a/ren.c
+++ b/ren.c
@@ -717,7 +717,6 @@
 /* insert a character, escape sequence, field or etc into wb */
 static void ren_put(struct wb *wb, char *c, int (*next)(void), void (*back)(int))
 {
-	char arg[ILNLEN];
 	int w;
 	if (c[0] == ' ' || c[0] == '\n') {
 		wb_put(wb, c);
@@ -739,11 +738,11 @@
 			return;
 		}
 		if (strchr(" bCcDdefHhjkLlmNoprSsuvXxZz0^|!{}&/,", c[1])) {
-			arg[0] = '\0';
+			char *arg = NULL;
 			if (strchr(ESC_P, c[1]))
-				unquotednext(arg, c[1], next, back);
+				arg = unquotednext(c[1], next, back);
 			if (strchr(ESC_Q, c[1]))
-				quotednext(arg, next, back);
+				arg = quotednext(next, back);
 			if (c[1] == 'e') {
 				snprintf(c, GNLEN, "%c%c", c_ec, c_ec);
 			} else if (c[1] == 'N') {
@@ -750,8 +749,10 @@
 				snprintf(c, GNLEN, "GID=%s", arg);
 			} else {
 				ren_cmd(wb, c[1], arg);
+				free(arg);
 				return;
 			}
+			free(arg);
 		}
 	}
 	if (ren_div) {
--- a/roff.h
+++ b/roff.h
@@ -402,8 +402,8 @@
 int charnext_delim(char *c, int (*next)(void), void (*back)(int), char *delim);
 int charread_delim(char **s, char *c, char *delim);
 void charnext_str(char *d, char *c);
-void quotednext(char *d, int (*next)(void), void (*back)(int));
-void unquotednext(char *d, int cmd, int (*next)(void), void (*back)(int));
+char *quotednext(int (*next)(void), void (*back)(int));
+char *unquotednext(int cmd, int (*next)(void), void (*back)(int));
 int escread(char **s, char **d);
 /* string streams; nested next()/back() interface for string buffers */
 void sstr_push(char *s);