ref: b0b32305ca510490c3edb78950655b26c9b22947
parent: d794e275a102ac50d3924c7407d0de25c0b3e4f4
author: Ori Bernstein <[email protected]>
date: Tue Jun 10 08:33:58 EDT 2014
Strip out '_' from what we pass to strtol() and friends.
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -623,10 +623,16 @@
int c;
int isfloat;
int unsignedval;
+ /* because we allow '_' in numbers, and strtod/stroull don't, we
+ * need a buffer that holds the number without '_'.
+ */
+ char buf[128];
+ size_t nbuf;
t = NULL;
isfloat = 0;
start = fidx;
+ nbuf = 0;
for (c = peek(); isxdigit(c) || c == '.' || c == '_'; c = peek()) {
next();
if (c == '_')
@@ -635,17 +641,23 @@
isfloat = 1;
else if (hexval(c) < 0 || hexval(c) > base)
fatal(line, "Integer digit '%c' outside of base %d", c, base);
+ if (nbuf >= sizeof buf) {
+ buf[nbuf] = '\0';
+ fatal(line, "number %s... too long to represent", buf);
+ }
+ buf[nbuf++] = c;
}
+ buf[nbuf] = '\0';
/* we only support base 10 floats */
if (isfloat && base == 10) {
t = mktok(Tfloatlit);
t->str = strdupn(&fbuf[start], fidx - start);
- t->fltval = strtod(t->str, NULL);
+ t->fltval = strtod(buf, NULL);
} else {
t = mktok(Tintlit);
t->str = strdupn(&fbuf[start], fidx - start);
- t->intval = strtoull(t->str, NULL, base);
+ t->intval = strtoull(buf, NULL, base);
/* check suffixes:
* u -> unsigned
* l -> 64 bit