in json/apr_json_decode.c [547:676]
static apr_status_t apr_json_decode_number(apr_json_scanner_t * self, apr_json_value_t * retval)
{
apr_status_t status = APR_SUCCESS;
int treat_as_float = 0, exp_occurred = 0;
const char *p = self->p, *e = self->e;
if (p >= e)
return APR_EOF;
{
unsigned char c = *(unsigned char *)p;
if (c == '-') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
}
if (!isdigit(c)) {
status = APR_BADCH;
goto out;
}
p++;
}
if (!treat_as_float) {
while (p < e) {
unsigned char c = *(unsigned char *)p;
if (c == 'e' || c == 'E') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
if (c == '-') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
}
if (!isdigit(c)) {
status = APR_BADCH;
goto out;
}
treat_as_float = 1;
exp_occurred = 1;
break;
}
else if (c == '.') {
p++;
treat_as_float = 1;
break;
}
else if (!isdigit(c))
break;
p++;
}
}
else {
while (p < e) {
unsigned char c = *(unsigned char *)p;
if (c == 'e' || c == 'E') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
if (c == '-') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
}
if (!isdigit(c)) {
status = APR_BADCH;
goto out;
}
exp_occurred = 1;
break;
}
else if (!isdigit(c))
break;
p++;
}
}
if (treat_as_float) {
if (!exp_occurred) {
while (p < e) {
unsigned char c = *(unsigned char *)p;
if (c == 'e' || c == 'E') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
if (c == '-') {
p++;
if (p >= e)
return APR_EOF;
c = *(unsigned char *)p;
}
if (!isdigit(c)) {
status = APR_BADCH;
goto out;
}
exp_occurred = 1;
break;
}
else if (!isdigit(c))
break;
p++;
}
}
if (exp_occurred) {
if (p >= e || !isdigit(*(unsigned char *)p))
return APR_EOF;
while (++p < e && isdigit(*(unsigned char *)p));
}
}
if (treat_as_float) {
retval->type = APR_JSON_DOUBLE;
retval->value.dnumber = strtod(self->p, NULL);
}
else {
retval->type = APR_JSON_LONG;
retval->value.lnumber = strtol(self->p, NULL, 10);
}
out:
self->p = p;
return status;
}