Branch Coverage

c/jsonparse.c
Criterion Covered Total %
branch 207 238 86.9


line true false branch
11 4462 655 while (ctx->buf < ctx->end) {
13 4461 1 if (!(x == 0x09 || x == 0x0a || x == 0x0d || x == 0x20)) break;
4456 5 if (!(x == 0x09 || x == 0x0a || x == 0x0d || x == 0x20)) break;
4455 1 if (!(x == 0x09 || x == 0x0a || x == 0x0d || x == 0x20)) break;
4364 91 if (!(x == 0x09 || x == 0x0a || x == 0x0d || x == 0x20)) break;
21 1 35 if (UNLIKELY(ctx->buf == ctx->end)) return 1;
34 2 16 if (ctx->end - ctx->buf < 4) return 1;
36 15 1 if (n >= 0x10000 || (n & 0xfc00) == 0xdc00) return 1;
2 13 if (n >= 0x10000 || (n & 0xfc00) == 0xdc00) return 1;
38 3 10 if ((n & 0xfc00) == 0xd800) { /* high surrogate */
39 1 2 if (ctx->end - ctx->buf < 6) return 1;
40 2 0 if (ctx->buf[0] != '\\' || ctx->buf[1] != 'u') return 1;
0 2 if (ctx->buf[0] != '\\' || ctx->buf[1] != 'u') return 1;
42 2 0 if (s >= 0x10000 || (s & 0xfc00) != 0xdc00) return 1;
0 2 if (s >= 0x10000 || (s & 0xfc00) != 0xdc00) return 1;
47 8 4 if (n >= 0x80) r->setutf8 = 1;
62 1 4744135 if (UNLIKELY(ctx->buf == ctx->end)) return 1;
64 1143 4742992 if (UNLIKELY(x == '"')) {
67 36 4742956 } else if (UNLIKELY(x == '\\')) {
68 8 28 if (fujson_parse_string_escape(aTHX_ ctx, r)) return 1;
69 17 4742939 } else if (x >= 0x80) {
70 1 16 if (UNLIKELY((len = isC9_STRICT_UTF8_CHAR(ctx->buf, ctx->end)) == 0)) return 1;
75 4742938 1 } else if (x >= 0x20) {
85 11 622 if (fujson_parse_string_buf(aTHX_ ctx, &r)) {
86 0 11 if (r.sv) SvREFCNT_dec(r.sv);
97 8 34 if (*ctx->buf == '-') ctx->buf++;
98 0 42 if (ctx->buf == ctx->end) return -1;
99 10 32 if (*ctx->buf == '0' && (ctx->buf+1 == ctx->end ||
9 1 if (*ctx->buf == '0' && (ctx->buf+1 == ctx->end ||
100 6 3 !(ctx->buf[1] == '.' || ctx->buf[1] == 'e' || ctx->buf[1] == 'E'))) {
6 0 !(ctx->buf[1] == '.' || ctx->buf[1] == 'e' || ctx->buf[1] == 'E'))) {
6 0 !(ctx->buf[1] == '.' || ctx->buf[1] == 'e' || ctx->buf[1] == 'E'))) {
111 35 0 DIG1;
34 1 DIG1;
0 34 DIG1;
122 6 DIG1;
105 17 DIG1;
94 11 DIG1;
113 28 6 if (ctx->buf != ctx->end && *ctx->buf == '.') {
10 18 if (ctx->buf != ctx->end && *ctx->buf == '.') {
116 9 1 DIG1;
8 1 DIG1;
0 8 DIG1;
85 2 DIG1;
83 2 DIG1;
79 4 DIG1;
119 24 8 if (ctx->buf != ctx->end && (*ctx->buf == 'e' || *ctx->buf == 'E')) {
13 11 if (ctx->buf != ctx->end && (*ctx->buf == 'e' || *ctx->buf == 'E')) {
1 12 if (ctx->buf != ctx->end && (*ctx->buf == 'e' || *ctx->buf == 'E')) {
122 1 11 if (ctx->buf == ctx->end) return -1;
123 9 2 if (*ctx->buf == '+' || *ctx->buf == '-') ctx->buf++;
3 6 if (*ctx->buf == '+' || *ctx->buf == '-') ctx->buf++;
124 9 2 DIG1;
9 0 DIG1;
1 8 DIG1;
2 6 DIG1;
0 2 DIG1;
0 0 DIG1;
134 7 35 if (isnum == -1) return NULL;
139 23 12 if (!isnum && grok_atoUV((const char *)(*start == '-' ? start+1 : start), &uv, &end)) {
5 18 if (!isnum && grok_atoUV((const char *)(*start == '-' ? start+1 : start), &uv, &end)) {
22 1 if (!isnum && grok_atoUV((const char *)(*start == '-' ? start+1 : start), &uv, &end)) {
140 17 5 if (*start != '-') return newSVuv(uv);
141 4 1 if (uv <= ((UV)IV_MAX)+1) return newSViv(-uv);
153 1 519 if (--ctx->depth == 0) return NULL;
156 1 518 if (ctx->buf == ctx->end) goto err;
157 511 7 if (*ctx->buf == ']') goto done;
159 6 521 if (!(r = fujson_parse(aTHX_ ctx))) goto err;
162 0 521 if (ctx->buf == ctx->end) goto err;
163 505 16 if (*ctx->buf == ']') goto done;
164 0 16 if (*ctx->buf != ',') goto err;
184 1 521 if (--ctx->depth == 0) return NULL;
187 1 520 if (ctx->buf == ctx->end) goto err;
188 5 515 if (*ctx->buf == '}') goto done;
191 3 521 if (*ctx->buf != '"') goto err;
192 0 521 if (fujson_parse_string_buf(aTHX_ ctx, &key)) goto err;
193 0 521 keystart = fustr_start(&key);
194 4 517 if (key.setutf8) keyhash = 0;
195 517 0 else PERL_HASH(keyhash, keystart, key.cur - keystart);
196 2 519 if (hv_common(hv, NULL, keystart, key.cur - keystart, key.setutf8, HV_FETCH_ISEXISTS, NULL, keyhash)) goto err;
200 0 519 if (ctx->buf == ctx->end) goto err;
201 1 518 if (*ctx->buf != ':') goto err;
205 4 514 if (!(val = fujson_parse(aTHX_ ctx))) goto err;
211 1 513 if (ctx->buf == ctx->end) goto err;
212 504 9 if (*ctx->buf == '}') goto done;
213 0 9 if (*ctx->buf != ',') goto err;
218 0 509 if (key.sv) SvREFCNT_dec(key.sv);
223 0 12 if (key.sv) SvREFCNT_dec(key.sv);
230 1 1749 if (ctx->buf == ctx->end) return NULL;
236 2 10 if (ctx->end - ctx->buf < 4) return NULL;
237 0 10 if (memcmp(ctx->buf, "true", 4) != 0) return NULL;
241 1 6 if (ctx->end - ctx->buf < 5) return NULL;
242 0 6 if (memcmp(ctx->buf, "false", 5) != 0) return NULL;
246 1 7 if (ctx->end - ctx->buf < 4) return NULL;
247 0 7 if (memcmp(ctx->buf, "null", 4) != 0) return NULL;
251 39 8 if (*ctx->buf == '-' || (*ctx->buf >= '0' && *ctx->buf <= '9'))
36 3 if (*ctx->buf == '-' || (*ctx->buf >= '0' && *ctx->buf <= '9'))
34 2 if (*ctx->buf == '-' || (*ctx->buf >= '0' && *ctx->buf <= '9'))
268 26 708 while (i < argc) {
271 0 26 if (i == argc) croak("Odd name/value argument for json_parse()");
275 7 19 if (strcmp(arg, "utf8") == 0) decutf8 = SvTRUEx(r);
276 4 15 else if (strcmp(arg, "max_size") == 0) maxlen = SvUV(r);
277 2 13 else if (strcmp(arg, "max_depth") == 0) ctx.depth = SvUV(r);
278 12 1 else if (strcmp(arg, "allow_control") == 0) {}
279 12 0 else if (strcmp(arg, "offset") == 0) offset = r;
282 704 4 if (maxlen == 0) maxlen = 1<<30;
283 706 2 if (ctx.depth == 0) ctx.depth = 512;
285 7 701 arg = decutf8 ? SvPVbyte(val, buflen) : SvPVutf8(val, buflen);
289 12 696 if (offset) {
290 0 12 if (!SvROK(offset)) croak("Offset must be a reference to a scalar");
292 11 1 if (!looks_like_number(offset) || SvIV(offset) < 0) croak("Offset must be a positive integer");
0 11 if (!looks_like_number(offset) || SvIV(offset) < 0) croak("Offset must be a positive integer");
293 1 10 if (SvUV(offset) >= buflen) croak("Offset too large");
295 2 8 if ((UV)(ctx.end - ctx.buf) > maxlen) ctx.end = ctx.buf + maxlen;
297 1 695 } else if ((UV)(ctx.end - ctx.buf) > maxlen)
301 39 666 if (!r) croak("JSON parsing failed at offset %"UVuf, (UV)((char *)ctx.buf - arg));
304 9 657 if (offset) {
305 1 8 if (ctx.buf == ctx.end) sv_set_undef(offset);
307 7 650 } else if (ctx.buf != ctx.end) {