json-tutorial
json-tutorial copied to clipboard
整数部分如果是 0 开始,只能是单个 0的问题
按照教程中提到的JSON标准,JSON数字整数部分如果是 0 开始,只能是单个 0.也就是说形如00.1
.-00.1
这样的数字在解析时应该返回LEPT_PARSE_INVALID_VALUE
才对。但是目前lept_parse_number
的校验过程没有实现这一点。
下面是原始代码:
static int lept_parse_number(lept_context* c, lept_value* v) {
const char* p = c->json;
if (*p == '-') p++;
if (*p == '0') p++;
else {
if (!ISDIGIT1TO9(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == '.') {
p++;
if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == 'e' || *p == 'E') {
p++;
if (*p == '+' || *p == '-') p++;
if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
errno = 0;
v->u.n = strtod(c->json, NULL);
if (errno == ERANGE && (v->u.n == HUGE_VAL || v->u.n == -HUGE_VAL))
return LEPT_PARSE_NUMBER_TOO_BIG;
v->type = LEPT_NUMBER;
c->json = p;
return LEPT_PARSE_OK;
}
建议改成下面这样:
static int lept_parse_number(lept_context* c, lept_value* v) {
const char* p = c->json;
if (*p == '-') p++;
if (*p == '0') p++;
else {
if (!ISDIGIT1TO9(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == '.') {
p++;
if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == 'e' || *p == 'E') {
p++;
if (*p == '+' || *p == '-') p++;
if (!ISDIGIT(*p)) return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
// added
if(*p=='0') return LEPT_PARSE_INVALID_VALUE;
errno = 0;
v->u.n = strtod(c->json, NULL);
if (errno == ERANGE && (v->u.n == HUGE_VAL || v->u.n == -HUGE_VAL))
return LEPT_PARSE_NUMBER_TOO_BIG;
v->type = LEPT_NUMBER;
c->json = p;
return LEPT_PARSE_OK;
}
然后在test_parse_invalid_value
中加上下面两条测试:
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "00.1");
TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "-00.1");
see https://github.com/miloyip/json-tutorial/issues/15
我也是刚写到这发现差点,我是直接在检测到0后看后面是不是数字:
if(*p == '-') p++;
if(*p == '0') {
p++;
if(ISDIGIT(*p))
return LC_PARSE_INVALID_VALUE;
} else {
if(!ISDIGIT1TO9(*p)) return LC_PARSE_INVALID_VALUE;
for(p++; ISDIGIT(*p); p++);
}
if(*p == '.'){
p++;
if(!ISDIGIT(*p)) return LC_PARSE_INVALID_VALUE;
for(p++; ISDIGIT(*p); p++);
}
if(*p == 'e' || *p == 'E'){
p++;
if(*p == '+' || *p == '-') p++;
if(!ISDIGIT(*p)) return LC_PARSE_INVALID_VALUE;
for(p++; ISDIGIT(*p); p++);
}