tttm

git clone https://orangeshoelaces.net/git/tttm.git

63581c896a2f82dd9503432ca0d3c30ee5ba2a20

Author: Vasily Kolobkov on 05/28/2016

Committer: Vasily Kolobkov on 05/28/2016

Don't tread on critical parser errors

Stats

parser.c | 190 +++-----
1 file changed, 77 insertions(+), 113 deletions(-)

Patch

diff --git a/parser.c b/parser.c
index 37dbd5d..ecb0ed8 100644
--- a/parser.c
+++ b/parser.c
@@ -157,7 +157,7 @@ struct parctx {
 
 typedef int parfn(struct parctx *);
 
-static union parnode * par_seldlist(union parnode *, va_list);
+static union parnode * par_vseld(union parnode *, va_list);
 static int cmpchr(const void *, const void *);
 static int contains(const char *, size_t, char);
 
@@ -342,7 +342,7 @@ par_sel(union parnode *n, ...)
 	va_start(ap, n);
 	prod = va_arg(ap, int);
 	if (prod != -1 && n->type == PN_INTER && n->inter.prod == prod) {
-		n = par_seldlist(n, ap);
+		n = par_vseld(n, ap);
 	} else {
 		n = 0;
 	}
@@ -356,13 +356,13 @@ par_seld(union parnode *n, ...)
 	va_list ap;
 
 	va_start(ap, n);
-	n = par_seldlist(n, ap);
+	n = par_vseld(n, ap);
 	va_end(ap);
 	return n;
 }
 
 union parnode *
-par_seldlist(union parnode *n, va_list ap)
+par_vseld(union parnode *n, va_list ap)
 {
 	int prod;
 	union parnode *end;
@@ -641,7 +641,7 @@ int
 p_chk(struct parctx *p, struct parcur *cp)
 {
 	*cp = p->cur;
-	return 1;
+	return p->e <= TE_PARSE;
 }
 
 int
@@ -657,7 +657,6 @@ p_insint(struct parctx *p, int prod, size_t len)
 	cur->inter.type = PN_INTER;
 	cur->inter.prod = prod;
 	cur->inter.len = len;
-	p->e = TE_OK;
 	p->cur.pt++;
 	return 1;
 }
@@ -674,7 +673,6 @@ p_inslit(struct parctx *p, int val)
 	}
 	cur->lit.type = PN_LIT;
 	cur->lit.val = val;
-	p->e = TE_OK;
 	p->cur.pt++;
 	return 1;
 }
@@ -691,7 +689,6 @@ p_insnum(struct parctx *p, uint32_t val)
 	}
 	cur->lit.type = PN_NUM;
 	cur->lit.val = val;
-	p->e = TE_OK;
 	p->cur.pt++;
 	return 1;
 }
@@ -709,7 +706,6 @@ p_insstr(struct parctx *p, int type, size_t off, uint32_t len)
 	cur->str.type = type;
 	cur->str.off = off;
 	cur->str.len = len;
-	p->e = TE_OK;
 	p->cur.pt++;
 	return 1;
 }
@@ -724,7 +720,6 @@ int
 p_end(struct parctx *p, struct parcur *beg)
 {
 	beg->pt->inter.len = p->cur.pt - beg->pt - 1;
-	p->e = TE_OK;
 	return 1;
 }
 
@@ -734,7 +729,6 @@ p_rwd(struct parctx *p, struct parcur *cp)
 	p->cur = *cp;
 	if (!p->e)
 		p->e = TE_PARSE;
-
 	return 0;
 }
 
@@ -743,7 +737,6 @@ p_opt(struct parctx *p)
 {
 	if (p->e == TE_PARSE)
 		p->e = TE_OK;
-
 	return !p->e;
 }
 
@@ -753,7 +746,8 @@ p_list(struct parctx *p, parfn *prod)
 {
 	int res;
 
-	for (res = prod(p); res && p_2xcombo(p, IL_SP, prod);)
+	res = (p->e <= TE_PARSE) && prod(p);
+	while (res && p_2xcombo(p, IL_SP, prod))
 		;
 	return res && p_opt(p);
 }
@@ -763,7 +757,8 @@ p_listsep(struct parctx *p, parfn *prod, int sep)
 {
 	int res;
 
-	for (res = prod(p); res && p_2xcombo(p, sep, prod);)
+	res = (p->e <= TE_PARSE) && prod(p);
+	while (res && p_2xcombo(p, sep, prod))
 		;
 	return res && p_opt(p);
 }
@@ -774,7 +769,8 @@ p_rep(struct parctx *p, parfn *prod)
 {
 	int res;
 
-	for (res = prod(p); res && prod(p);)
+	res = (p->e <= TE_PARSE) && prod(p);
+	while (res && prod(p))
 		;
 	return res && p_opt(p);
 }
@@ -789,6 +785,9 @@ p_repchr(struct parctx *p, const char *except, size_t elen, int strtype)
 	size_t leeway;
 	size_t len;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	pr = p->cur.off;
 	while ((p->e = par_procure(p, pr, 1)) == TE_OK) {
 		wndlag = pr - p->wndoff;
@@ -800,25 +799,16 @@ p_repchr(struct parctx *p, const char *except, size_t elen, int strtype)
 		}
 	}
  stop:
-	if (p->e == TE_EOF)
-		p->e = TE_OK;
-
-	if (p->e != TE_OK)
-		goto exit;
-
 	len = pr - p->cur.off;
-	if (len == 0)
-		goto eparse;
-
-	if (len > UINT32_MAX)
-		goto exl;
+	if (p->e == TE_EOF && len)
+		p->e = TE_OK;
 
-	if (!p_insstr(p, strtype, p->cur.off, (uint32_t)len))
-		goto exit;
+	if (p->e) goto exit;
+	if (!len) goto eparse;
+	if (len > UINT32_MAX) goto exl;
+	if (!p_insstr(p, strtype, p->cur.off, len)) goto exit;
 
 	p->cur.off = pr;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -926,7 +916,8 @@ int
 p_base64(struct parctx *p)
 {
 	/* brush 6 bit encoding off yet */
-	p->e = TE_PARSE;
+	if (!p->e)
+		p->e = TE_PARSE;
 	return 0;
 }
 
@@ -1176,6 +1167,9 @@ p_dig(struct parctx *p, size_t count)
 	uint32_t n, prev;
 	size_t d;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	pr = p->cur.off;
 	n = prev = 0;
 	d = count == SIZE_MAX ? 0 : 1;
@@ -1197,22 +1191,15 @@ p_dig(struct parctx *p, size_t count)
 		}
 	}
  stop:
-	if (p->e == TE_EOF)
-		p->e = TE_OK;
-
-	if (p->e != TE_OK)
-		goto exit;
-
 	len = pr - p->cur.off;
-	if (len == 0)
-		goto eparse;
+	if (p->e == TE_EOF && len)
+		p->e = TE_OK;
 
-	if (!p_insnum(p, n))
-		goto exit;
+	if (p->e) goto exit;
+	if (!len) goto eparse;
+	if (!p_insnum(p, n)) goto exit;
 
 	p->cur.off = pr;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -1320,6 +1307,9 @@ p_genctext(struct parctx *p)
 	size_t leeway;
 	size_t len;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	pr = p->cur.off;
 	while ((p->e = par_procure(p, pr, 1)) == TE_OK) {
 		wndlag = pr - p->wndoff;
@@ -1332,25 +1322,16 @@ p_genctext(struct parctx *p)
 		}
 	}
  stop:
-	if (p->e == TE_EOF)
-		p->e = TE_OK;
-
-	if (p->e != TE_OK)
-		goto exit;
-
 	len = pr - p->cur.off;
-	if (len == 0)
-		goto eparse;
+	if (p->e == TE_EOF && len)
+		p->e = TE_OK;
 
-	if (len > UINT32_MAX)
-		goto exl;
-
-	if (!p_insstr(p, PN_STR, p->cur.off, (uint32_t)len))
-		goto exit;
+	if (p->e) goto exit;
+	if (!len) goto eparse;
+	if (len > UINT32_MAX) goto exl;
+	if (!p_insstr(p, PN_STR, p->cur.off, len)) goto exit;
 
 	p->cur.off = pr;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -1382,6 +1363,9 @@ p_lit(struct parctx *p, int val)
 	struct literal *lit;
 	size_t match, chunk, wndlag;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	lit = literals + val;
 	match = 0;
 
@@ -1390,17 +1374,16 @@ p_lit(struct parctx *p, int val)
 			goto exit;
 		wndlag = p->cur.off + match - p->wndoff;
 		chunk = MIN(lit->slen - match, p->wndlee - wndlag);
-		if (strncasecmp(p->wnd + wndlag + match, lit->srep + match, chunk) == 0) {
+		if (strncasecmp(p->wnd + wndlag + match, lit->srep + match,
+		    chunk) == 0) {
 			match += chunk;
 		} else {
 			goto eparse;
 		}
 	}
 
-	if (p_inslit(p, val)) {
+	if (p_inslit(p, val))
 		p->cur.off += lit->slen;
-		p->e = TE_OK;
-	}
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -1418,22 +1401,14 @@ p_lstr(struct parctx *p)
 	    p_chk(p, &n) && p_num(p) && p_lit(p, IL_CBRACE) &&
 	    p_lit(p, IL_EOL) || p_rwd(p, &b);
 
-	if (p->e != TE_OK)
-		goto exit;
-
+	if (p->e) goto exit;
 	len = n.pt->num.val;
-	if (len > UINT32_MAX)
-		goto exl;
-
+	if (len > UINT32_MAX) goto exl;
 	if (len > 0 && (p->e = par_procure(p, p->cur.off + len - 1, 1)))
 		goto eproc;
-
-	if (!p_insstr(p, PN_LSTR, p->cur.off, (uint32_t)len))
-		goto exit;
+	if (!p_insstr(p, PN_LSTR, p->cur.off, len)) goto exit;
 
 	p->cur.off += len;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eproc:
@@ -1588,17 +1563,15 @@ p_mblistosfl(struct parctx *p)
 	int res;
 	struct parcur b;
 
-	p_chk(p, &b);
-
-	res = p_list(p, p_mblistofl) &&
+	res = p_chk(p, &b) && p_list(p, p_mblistofl) &&
 	    p_sp(p) || p_rwd(p, &b) || p_opt(p);
 
 	res = res && p_mblistsfl(p);
 
-	res = res && p_chk(p, &b) && p_sp(p) &&
-	    p_list(p, p_mblistofl) || p_rwd(p, &b) || p_opt(p);
+	res = res && (p_chk(p, &b) && p_sp(p) &&
+	    p_list(p, p_mblistofl) || p_rwd(p, &b) || p_opt(p));
 
-	return res || p_rwd(p, &b);
+	return res;
 }
 
 int
@@ -1739,6 +1712,9 @@ p_nznum(struct parctx *p)
 	size_t wndlag;
 	const char *prp;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	if ((p->e = par_procure(p, p->cur.off, 1)))
 		goto exit;
 
@@ -1749,7 +1725,6 @@ p_nznum(struct parctx *p)
 		goto eparse;
 
 	p_num(p);
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -1780,6 +1755,9 @@ p_qchar(struct parctx *p)
 	char x, y;
 	int len;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	if ((p->e = par_peek(p, p->cur.off, &x)))
 		goto exit;
 	if (x >= '\1' && x <= '\x7f' && x != '\r' &&
@@ -1796,12 +1774,10 @@ p_qchar(struct parctx *p)
 	goto eparse;
 
  ins:
-	if (!p_insstr(p, PN_QSTR, p->cur.off, (uint32_t)len))
+	if (!p_insstr(p, PN_QSTR, p->cur.off, len))
 		goto exit;
 
 	p->cur.off += len;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -1819,6 +1795,9 @@ p_qchars(struct parctx *p)
 	size_t len;
 	int esc;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	pr = p->cur.off;
 	esc = 0;
 
@@ -1842,25 +1821,16 @@ p_qchars(struct parctx *p)
 		}
 	}
  stop:
-	if (p->e == TE_EOF)
-		p->e = TE_OK;
-
-	if (p->e != TE_OK)
-		goto exit;
-
 	len = pr - p->cur.off;
-	if (len == 0)
-		goto eparse;
-
-	if (len > UINT32_MAX)
-		goto exl;
+	if (p->e == TE_EOF && len)
+		p->e = TE_OK;
 
-	if (!p_insstr(p, PN_QSTR, p->cur.off, (uint32_t)len))
-		goto exit;
+	if (p->e) goto exit;
+	if (!len) goto eparse;
+	if (len > UINT32_MAX) goto exl;
+	if (!p_insstr(p, PN_QSTR, p->cur.off, len)) goto exit;
 
 	p->cur.off = pr;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse:
@@ -2041,6 +2011,9 @@ p_text(struct parctx *p)
 	size_t leeway;
 	size_t len;
 
+	if (p->e > TE_PARSE)
+		goto exit;
+
 	pr = p->cur.off;
 	while ((p->e = par_procure(p, pr, 1)) == TE_OK) {
 		wndlag = pr - p->wndoff;
@@ -2053,25 +2026,16 @@ p_text(struct parctx *p)
 		}
 	}
  stop:
-	if (p->e == TE_EOF)
-		p->e = TE_OK;
-
-	if (p->e != TE_OK)
-		goto exit;
-
 	len = pr - p->cur.off;
-	if (len == 0)
-		goto eparse;
+	if (p->e == TE_EOF && len)
+		p->e = TE_OK;
 
-	if (len > UINT32_MAX)
-		goto exl;
-
-	if (!p_insstr(p, PN_STR, p->cur.off, (uint32_t)len))
-		goto exit;
+	if (p->e) goto exit;
+	if (!len) goto eparse;
+	if (len > UINT32_MAX) goto exl;
+	if (!p_insstr(p, PN_STR, p->cur.off, len)) goto exit;
 
 	p->cur.off = pr;
-	p->e = TE_OK;
-
  exit:
 	return p->e == TE_OK;
  eparse: