35FILE_RCSID(
"@(#)$File: is_json.c,v 1.30 2022/09/27 19:12:40 christos Exp $")
47#define DPRINTF(a, b, c) \
48 printf("%*s%s [%.2x/%c] %.*s\n", (int)lvl, "", (a), *(b), *(b), \
49 (int)(b - c), (const char *)(c))
50#define __file_debugused
52#define DPRINTF(a, b, c) do { } while (0)
53#define __file_debugused __attribute__((__unused__))
57#define JSON_CONSTANT 1
74static int json_parse(
const unsigned char **,
const unsigned char *,
size_t *,
78json_isspace(
const unsigned char uc)
92json_isdigit(
unsigned char uc)
95 case '0':
case '1':
case '2':
case '3':
case '4':
96 case '5':
case '6':
case '7':
case '8':
case '9':
104json_isxdigit(
unsigned char uc)
106 if (json_isdigit(uc))
109 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
110 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
117static const unsigned char *
118json_skip_space(
const unsigned char *uc,
const unsigned char *ue)
120 while (uc < ue && json_isspace(*uc))
127json_parse_string(
const unsigned char **ucp,
const unsigned char *ue,
130 const unsigned char *uc = *ucp;
133 DPRINTF(
"Parse string: ", uc, *ucp);
158 for (i = 0; i < 4; i++)
159 if (!json_isxdigit(*uc++))
166 DPRINTF(
"Good string: ", uc, *ucp);
174 DPRINTF(
"Bad string: ", uc, *ucp);
180json_parse_array(
const unsigned char **ucp,
const unsigned char *ue,
181 size_t *st,
size_t lvl)
183 const unsigned char *uc = *ucp;
185 DPRINTF(
"Parse array: ", uc, *ucp);
187 uc = json_skip_space(uc, ue);
192 if (!json_parse(&uc, ue, st, lvl + 1))
203 DPRINTF(
"Good array: ", uc, *ucp);
211 DPRINTF(
"Bad array: ", uc, *ucp);
217json_parse_object(
const unsigned char **ucp,
const unsigned char *ue,
218 size_t *st,
size_t lvl)
220 const unsigned char *uc = *ucp;
221 DPRINTF(
"Parse object: ", uc, *ucp);
223 uc = json_skip_space(uc, ue);
231 DPRINTF(
"not string", uc, *ucp);
234 DPRINTF(
"next field", uc, *ucp);
235 if (!json_parse_string(&uc, ue, lvl)) {
236 DPRINTF(
"not string", uc, *ucp);
239 uc = json_skip_space(uc, ue);
243 DPRINTF(
"not colon", uc, *ucp);
246 if (!json_parse(&uc, ue, st, lvl + 1)) {
257 DPRINTF(
"Good object: ", uc, *ucp);
267 DPRINTF(
"Bad object: ", uc, *ucp);
274json_parse_number(
const unsigned char **ucp,
const unsigned char *ue,
277 const unsigned char *uc = *ucp;
280 DPRINTF(
"Parse number: ", uc, *ucp);
286 for (; uc < ue; uc++) {
287 if (!json_isdigit(*uc))
295 for (; uc < ue; uc++) {
296 if (!json_isdigit(*uc))
302 if (got && (*uc ==
'e' || *uc ==
'E')) {
307 if (*uc ==
'+' || *uc ==
'-')
309 for (; uc < ue; uc++) {
310 if (!json_isdigit(*uc))
317 DPRINTF(
"Bad number: ", uc, *ucp);
319 DPRINTF(
"Good number: ", uc, *ucp);
326json_parse_const(
const unsigned char **ucp,
const unsigned char *ue,
329 const unsigned char *uc = *ucp;
331 DPRINTF(
"Parse const: ", uc, *ucp);
335 for (; uc < ue && --
len;) {
336 if (*uc++ != *++str) {
337 DPRINTF(
"Bad const: ", uc, *ucp);
341 DPRINTF(
"Good const: ", uc, *ucp);
346json_parse(
const unsigned char **ucp,
const unsigned char *ue,
347 size_t *st,
size_t lvl)
349 const unsigned char *uc, *ouc;
353 ouc = uc = json_skip_space(*ucp, ue);
359 DPRINTF(
"Too many levels", uc, *ucp);
368 DPRINTF(
"Parse general: ", uc, *ucp);
371 rv = json_parse_string(&uc, ue, lvl + 1);
375 rv = json_parse_array(&uc, ue, st, lvl + 1);
379 rv = json_parse_object(&uc, ue, st, lvl + 1);
383 rv = json_parse_const(&uc, ue,
"true",
sizeof(
"true"), lvl + 1);
387 rv = json_parse_const(&uc, ue,
"false",
sizeof(
"false"),
392 rv = json_parse_const(&uc, ue,
"null",
sizeof(
"null"), lvl + 1);
397 rv = json_parse_number(&uc, ue, lvl + 1);
403 uc = json_skip_space(uc, ue);
405 DPRINTF(
"End general: ", uc, *ucp);
412 if (*ouc == *uc && json_parse(&uc, ue, st, 1))
424 const unsigned char *uc =
CAST(
const unsigned char *, b->
fbuf);
425 const unsigned char *ue = uc + b->
flen;
434 memset(st, 0,
sizeof(st));
436 if ((jt = json_parse(&uc, ue, st, 0)) == 0)
443 jt == 1 ?
"json" :
"x-ndjson") == -1)
448 jt == 1 ?
"" :
"New Line Delimited ") == -1)
451#define P(n) st[n], st[n] > 1 ? "s" : ""
466#include <sys/types.h>
476main(
int argc,
char *argv[])
483 if ((
fd = open(argv[1], O_RDONLY)) == -1)
484 err(EXIT_FAILURE,
"Can't open `%s'", argv[1]);
487 err(EXIT_FAILURE,
"Can't stat `%s'", argv[1]);
489 if ((
p =
CAST(
char *, malloc(st.st_size))) ==
NULL)
490 err(EXIT_FAILURE,
"Can't allocate %jd bytes",
491 (intmax_t)st.st_size);
492 if (read(
fd,
p, st.st_size) != st.st_size)
493 err(EXIT_FAILURE,
"Can't read %jd bytes",
494 (intmax_t)st.st_size);
495 memset(stats, 0,
sizeof(stats));
496 printf(
"is json %d\n", json_parse((
const unsigned char **)&
p,
497 p + st.st_size, stats, 0));
printf(string $format, mixed ... $values)
memset(ptr, 0, type->size)
file_protected int file_printf(struct magic_set *, const char *,...) __attribute__((__format__(__printf__
int file_is_json(struct magic_set *ms, const struct buffer *b)
#define MAGIC_MIME_ENCODING