Skip to content

Commit

Permalink
fixup parser bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
nicowilliams committed Jan 30, 2017
1 parent 3c08c3b commit cdf23ea
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 36 deletions.
8 changes: 8 additions & 0 deletions src/jv.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ int64_t jv_int64_value(jv j)
return (int64_t)j.u.uint64;
return INT64_MAX;
}
if (j.u.number > 0 && (int64_t)j.u.number < 0)
return INT64_MAX;
if (j.u.number < 0 && (int64_t)j.u.number > 0)
return INT64_MIN;
#endif
return j.u.number;
}
Expand All @@ -207,6 +211,10 @@ uint64_t jv_uint64_value(jv j)
return j.u.int64;
return 0;
}
if (j.u.number < 0)
return 0;
if (j.u.number > (double)UINT64_MAX)
return UINT64_MAX;
#endif
return j.u.number;
}
Expand Down
66 changes: 30 additions & 36 deletions src/jv_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,53 +495,47 @@ static pfunc check_literal(struct jv_parser* p) {
} else {
// FIXME: better parser
p->tokenbuf[p->tokenpos] = 0;
char* end = 0;
double d = jvp_strtod(&p->dtoa, p->tokenbuf, &end);
if (end == 0 || *end != 0)
return "Invalid numeric literal";
char *end = 0;

#ifndef JQ_OMIT_INTS
if (d == (int64_t)d || d == (uint64_t)d) {
if (d >= INT64_MIN && d <= INT64_MAX) {
TRY(value(p, jv_int64(d)));
goto out;
} else if (d >= 0 && d <= UINT64_MAX) {
TRY(value(p, jv_uint64(d)));
goto out;
}

char *q = p->tokenbuf;
int is_signed = 0;
while (isspace(*q))
q++;
if (*q == '-') {
is_signed = 1;
q++;
}
errno = 0;
if (is_signed) {
char *q = p->tokenbuf;
int is_signed = 0;
while (isspace(*q))
q++;
if (*q == '-') {
is_signed = 1;
q++;
}
errno = 0;
if (is_signed) {
#ifdef HAVE_STRTOIMAX
int64_t i64 = strtoimax(p->tokenbuf, &q, 10);
int64_t i64 = strtoimax(p->tokenbuf, &end, 10);
#else
int64_t i64 = strtoll(p->tokenbuf, &q, 10);
int64_t i64 = strtoll(p->tokenbuf, &end, 10);
#endif
if (q == end && i64 < 0 && errno == 0) {
TRY(value(p, jv_int64(i64)));
goto out;
}
} else {
if (end != 0 && *end == 0 && i64 < 0 && errno == 0) {
TRY(value(p, jv_int64(i64)));
goto out;
}
} else {
#ifdef HAVE_STRTOUMAX
uint64_t u64 = strtoumax(p->tokenbuf, &q, 10);
uint64_t u64 = strtoumax(p->tokenbuf, &end, 10);
#else
uint64_t u64 = strtoull(p->tokenbuf, &q, 10);
uint64_t u64 = strtoull(p->tokenbuf, &end, 10);
#endif
if (q == end && errno == 0) {
TRY(value(p, jv_int64(u64)));
goto out;
}
if (end != 0 && *end == 0 && errno == 0) {
TRY(value(p, jv_uint64(u64)));
goto out;
}
}
#endif
double d = jvp_strtod(&p->dtoa, p->tokenbuf, &end);
if (end == 0 || *end != 0)
return "Invalid numeric literal";
/*
* So there was a decimal or exponent; this might still be an
* integer, but we'll go with double.
*/
TRY(value(p, jv_number(d)));
}
out:
Expand Down

0 comments on commit cdf23ea

Please sign in to comment.