git clone https://orangeshoelaces.net/git/tttm.git
Author: Vasily Kolobkov on 05/28/2016
Committer: Vasily Kolobkov on 05/28/2016
Don't tread on critical parser errors
parser.c | 190 +++-----
1 file changed, 77 insertions(+), 113 deletions(-)
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: