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