Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * jsonapi.c
4 : * JSON parser and lexer interfaces
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/common/jsonapi.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 : #ifndef FRONTEND
15 : #include "postgres.h"
16 : #else
17 : #include "postgres_fe.h"
18 : #endif
19 :
20 : #include "common/jsonapi.h"
21 : #include "mb/pg_wchar.h"
22 : #include "port/pg_lfind.h"
23 :
24 : #ifndef FRONTEND
25 : #include "miscadmin.h"
26 : #endif
27 :
28 : /*
29 : * The context of the parser is maintained by the recursive descent
30 : * mechanism, but is passed explicitly to the error reporting routine
31 : * for better diagnostics.
32 : */
33 : typedef enum /* contexts of JSON parser */
34 : {
35 : JSON_PARSE_VALUE, /* expecting a value */
36 : JSON_PARSE_STRING, /* expecting a string (for a field name) */
37 : JSON_PARSE_ARRAY_START, /* saw '[', expecting value or ']' */
38 : JSON_PARSE_ARRAY_NEXT, /* saw array element, expecting ',' or ']' */
39 : JSON_PARSE_OBJECT_START, /* saw '{', expecting label or '}' */
40 : JSON_PARSE_OBJECT_LABEL, /* saw object label, expecting ':' */
41 : JSON_PARSE_OBJECT_NEXT, /* saw object value, expecting ',' or '}' */
42 : JSON_PARSE_OBJECT_COMMA, /* saw object ',', expecting next label */
43 : JSON_PARSE_END /* saw the end of a document, expect nothing */
44 : } JsonParseContext;
45 :
46 : static inline JsonParseErrorType json_lex_string(JsonLexContext *lex);
47 : static inline JsonParseErrorType json_lex_number(JsonLexContext *lex, char *s,
48 : bool *num_err, int *total_len);
49 : static inline JsonParseErrorType parse_scalar(JsonLexContext *lex, JsonSemAction *sem);
50 : static JsonParseErrorType parse_object_field(JsonLexContext *lex, JsonSemAction *sem);
51 : static JsonParseErrorType parse_object(JsonLexContext *lex, JsonSemAction *sem);
52 : static JsonParseErrorType parse_array_element(JsonLexContext *lex, JsonSemAction *sem);
53 : static JsonParseErrorType parse_array(JsonLexContext *lex, JsonSemAction *sem);
54 : static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex);
55 :
56 : /* the null action object used for pure validation */
57 : JsonSemAction nullSemAction =
58 : {
59 : NULL, NULL, NULL, NULL, NULL,
60 : NULL, NULL, NULL, NULL, NULL
61 : };
62 :
63 : /* Recursive Descent parser support routines */
64 :
65 : /*
66 : * lex_peek
67 : *
68 : * what is the current look_ahead token?
69 : */
70 : static inline JsonTokenType
1171 rhaas 71 GIC 2859529 : lex_peek(JsonLexContext *lex)
1171 rhaas 72 ECB : {
1171 rhaas 73 GIC 2859529 : return lex->token_type;
1171 rhaas 74 ECB : }
75 :
76 : /*
77 : * lex_expect
78 : *
79 : * move the lexer to the next token if the current look_ahead token matches
80 : * the parameter token. Otherwise, report an error.
81 : */
82 : static inline JsonParseErrorType
1171 rhaas 83 GIC 521781 : lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
1171 rhaas 84 ECB : {
1178 rhaas 85 GIC 521781 : if (lex_peek(lex) == token)
1168 rhaas 86 CBC 521727 : return json_lex(lex);
1178 rhaas 87 ECB : else
1168 rhaas 88 GIC 54 : return report_parse_error(ctx, lex);
1171 rhaas 89 ECB : }
90 :
91 : /* chars to consider as part of an alphanumeric token */
92 : #define JSON_ALPHANUMERIC_CHAR(c) \
93 : (((c) >= 'a' && (c) <= 'z') || \
94 : ((c) >= 'A' && (c) <= 'Z') || \
95 : ((c) >= '0' && (c) <= '9') || \
96 : (c) == '_' || \
97 : IS_HIGHBIT_SET(c))
98 :
99 : /*
100 : * Utility function to check if a string is a valid JSON number.
101 : *
102 : * str is of length len, and need not be null-terminated.
103 : */
104 : bool
1171 rhaas 105 GIC 1399 : IsValidJsonNumber(const char *str, int len)
1171 rhaas 106 ECB : {
107 : bool numeric_error;
108 : int total_len;
109 : JsonLexContext dummy_lex;
110 :
1171 rhaas 111 GIC 1399 : if (len <= 0)
1171 rhaas 112 LBC 0 : return false;
1171 rhaas 113 EUB :
114 : /*
115 : * json_lex_number expects a leading '-' to have been eaten already.
116 : *
117 : * having to cast away the constness of str is ugly, but there's not much
118 : * easy alternative.
119 : */
1171 rhaas 120 GIC 1399 : if (*str == '-')
1171 rhaas 121 ECB : {
1058 tgl 122 GIC 29 : dummy_lex.input = unconstify(char *, str) + 1;
1171 rhaas 123 CBC 29 : dummy_lex.input_length = len - 1;
1171 rhaas 124 ECB : }
125 : else
126 : {
1171 rhaas 127 GIC 1370 : dummy_lex.input = unconstify(char *, str);
1171 rhaas 128 CBC 1370 : dummy_lex.input_length = len;
1171 rhaas 129 ECB : }
130 :
1171 rhaas 131 GIC 1399 : json_lex_number(&dummy_lex, dummy_lex.input, &numeric_error, &total_len);
1171 rhaas 132 ECB :
1171 rhaas 133 GIC 1399 : return (!numeric_error) && (total_len == dummy_lex.input_length);
1171 rhaas 134 ECB : }
135 :
136 : /*
137 : * makeJsonLexContextCstringLen
138 : *
139 : * lex constructor, with or without StringInfo object for de-escaped lexemes.
140 : *
141 : * Without is better as it makes the processing faster, so only make one
142 : * if really required.
143 : */
144 : JsonLexContext *
1166 rhaas 145 GIC 17583 : makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
1171 rhaas 146 ECB : {
1171 rhaas 147 GIC 17583 : JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
1171 rhaas 148 ECB :
1171 rhaas 149 GIC 17583 : lex->input = lex->token_terminator = lex->line_start = json;
1171 rhaas 150 CBC 17583 : lex->line_number = 1;
151 17583 : lex->input_length = len;
1166 152 17583 : lex->input_encoding = encoding;
1171 153 17583 : if (need_escapes)
154 14005 : lex->strval = makeStringInfo();
155 17583 : return lex;
1171 rhaas 156 ECB : }
157 :
158 : /*
159 : * pg_parse_json
160 : *
161 : * Publicly visible entry point for the JSON parser.
162 : *
163 : * lex is a lexing context, set up for the json to be processed by calling
164 : * makeJsonLexContext(). sem is a structure of function pointers to semantic
165 : * action routines to be called at appropriate spots during parsing, and a
166 : * pointer to a state object to be passed to those routines.
167 : */
168 : JsonParseErrorType
1171 rhaas 169 GIC 17217 : pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 170 ECB : {
171 : JsonTokenType tok;
172 : JsonParseErrorType result;
173 :
174 : /* get the initial token */
1168 rhaas 175 GIC 17217 : result = json_lex(lex);
1168 rhaas 176 CBC 17217 : if (result != JSON_SUCCESS)
177 105 : return result;
1171 rhaas 178 ECB :
1171 rhaas 179 GIC 17112 : tok = lex_peek(lex);
1171 rhaas 180 ECB :
181 : /* parse by recursive descent */
1171 rhaas 182 GIC 17112 : switch (tok)
1171 rhaas 183 ECB : {
1171 rhaas 184 GIC 11754 : case JSON_TOKEN_OBJECT_START:
1168 rhaas 185 CBC 11754 : result = parse_object(lex, sem);
1171 186 11721 : break;
187 2620 : case JSON_TOKEN_ARRAY_START:
1168 188 2620 : result = parse_array(lex, sem);
1171 189 2568 : break;
190 2738 : default:
1060 tgl 191 2738 : result = parse_scalar(lex, sem); /* json can be a bare scalar */
1171 rhaas 192 ECB : }
193 :
1168 rhaas 194 GIC 16991 : if (result == JSON_SUCCESS)
1168 rhaas 195 CBC 16774 : result = lex_expect(JSON_PARSE_END, lex, JSON_TOKEN_END);
1168 rhaas 196 ECB :
1168 rhaas 197 GIC 16991 : return result;
1168 rhaas 198 ECB : }
199 :
200 : /*
201 : * json_count_array_elements
202 : *
203 : * Returns number of array elements in lex context at start of array token
204 : * until end of array token at same nesting level.
205 : *
206 : * Designed to be called from array_start routines.
207 : */
208 : JsonParseErrorType
1168 rhaas 209 GIC 3 : json_count_array_elements(JsonLexContext *lex, int *elements)
1171 rhaas 210 ECB : {
211 : JsonLexContext copylex;
212 : int count;
213 : JsonParseErrorType result;
214 :
215 : /*
216 : * It's safe to do this with a shallow copy because the lexical routines
217 : * don't scribble on the input. They do scribble on the other pointers
218 : * etc, so doing this with a copy makes that safe.
219 : */
1171 rhaas 220 GIC 3 : memcpy(©lex, lex, sizeof(JsonLexContext));
1171 rhaas 221 CBC 3 : copylex.strval = NULL; /* not interested in values here */
222 3 : copylex.lex_level++;
1171 rhaas 223 ECB :
1171 rhaas 224 GIC 3 : count = 0;
1168 rhaas 225 CBC 3 : result = lex_expect(JSON_PARSE_ARRAY_START, ©lex,
1168 rhaas 226 ECB : JSON_TOKEN_ARRAY_START);
1168 rhaas 227 GIC 3 : if (result != JSON_SUCCESS)
1168 rhaas 228 LBC 0 : return result;
1171 rhaas 229 GBC 3 : if (lex_peek(©lex) != JSON_TOKEN_ARRAY_END)
1171 rhaas 230 ECB : {
231 : while (1)
232 : {
1171 rhaas 233 GIC 24 : count++;
1168 rhaas 234 CBC 24 : result = parse_array_element(©lex, &nullSemAction);
235 24 : if (result != JSON_SUCCESS)
1168 rhaas 236 LBC 0 : return result;
1178 rhaas 237 GBC 24 : if (copylex.token_type != JSON_TOKEN_COMMA)
1178 rhaas 238 CBC 3 : break;
1168 239 21 : result = json_lex(©lex);
240 21 : if (result != JSON_SUCCESS)
1168 rhaas 241 LBC 0 : return result;
1171 rhaas 242 EUB : }
243 : }
1168 rhaas 244 GIC 3 : result = lex_expect(JSON_PARSE_ARRAY_NEXT, ©lex,
1060 tgl 245 ECB : JSON_TOKEN_ARRAY_END);
1168 rhaas 246 GIC 3 : if (result != JSON_SUCCESS)
1168 rhaas 247 LBC 0 : return result;
1171 rhaas 248 EUB :
1168 rhaas 249 GIC 3 : *elements = count;
1168 rhaas 250 CBC 3 : return JSON_SUCCESS;
1171 rhaas 251 ECB : }
252 :
253 : /*
254 : * Recursive Descent parse routines. There is one for each structural
255 : * element in a json document:
256 : * - scalar (string, number, true, false, null)
257 : * - array ( [ ] )
258 : * - array element
259 : * - object ( { } )
260 : * - object field
261 : */
262 : static inline JsonParseErrorType
1171 rhaas 263 GIC 397691 : parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 264 ECB : {
1171 rhaas 265 GIC 397691 : char *val = NULL;
1171 rhaas 266 CBC 397691 : json_scalar_action sfunc = sem->scalar;
267 397691 : JsonTokenType tok = lex_peek(lex);
1168 rhaas 268 ECB : JsonParseErrorType result;
269 :
270 : /* a scalar must be a string, a number, true, false, or null */
1178 rhaas 271 GIC 397691 : if (tok != JSON_TOKEN_STRING && tok != JSON_TOKEN_NUMBER &&
1178 rhaas 272 CBC 11870 : tok != JSON_TOKEN_TRUE && tok != JSON_TOKEN_FALSE &&
1178 rhaas 273 ECB : tok != JSON_TOKEN_NULL)
1168 rhaas 274 GIC 90 : return report_parse_error(JSON_PARSE_VALUE, lex);
1178 rhaas 275 ECB :
276 : /* if no semantic function, just consume the token */
1178 rhaas 277 GIC 397601 : if (sfunc == NULL)
1168 rhaas 278 CBC 5160 : return json_lex(lex);
1178 rhaas 279 ECB :
280 : /* extract the de-escaped string value, or the raw lexeme */
1178 rhaas 281 GIC 392441 : if (lex_peek(lex) == JSON_TOKEN_STRING)
1178 rhaas 282 ECB : {
1178 rhaas 283 GIC 263431 : if (lex->strval != NULL)
1178 rhaas 284 CBC 260527 : val = pstrdup(lex->strval->data);
1171 rhaas 285 ECB : }
286 : else
287 : {
1178 rhaas 288 GIC 129010 : int len = (lex->token_terminator - lex->token_start);
1171 rhaas 289 ECB :
1178 rhaas 290 GIC 129010 : val = palloc(len + 1);
1178 rhaas 291 CBC 129010 : memcpy(val, lex->token_start, len);
292 129010 : val[len] = '\0';
1178 rhaas 293 ECB : }
294 :
295 : /* consume the token */
1168 rhaas 296 GIC 392441 : result = json_lex(lex);
1168 rhaas 297 CBC 392441 : if (result != JSON_SUCCESS)
1168 rhaas 298 LBC 0 : return result;
1178 rhaas 299 EUB :
300 : /* invoke the callback */
119 tgl 301 GNC 392441 : result = (*sfunc) (sem->semstate, val, tok);
1168 rhaas 302 ECB :
119 tgl 303 GNC 392394 : return result;
1171 rhaas 304 ECB : }
305 :
306 : static JsonParseErrorType
1171 rhaas 307 GIC 398657 : parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 308 ECB : {
309 : /*
310 : * An object field is "fieldname" : value where value can be a scalar,
311 : * object or array. Note: in user-facing docs and error messages, we
312 : * generally call a field name a "key".
313 : */
314 :
1171 rhaas 315 GIC 398657 : char *fname = NULL; /* keep compiler quiet */
1171 rhaas 316 CBC 398657 : json_ofield_action ostart = sem->object_field_start;
317 398657 : json_ofield_action oend = sem->object_field_end;
1171 rhaas 318 ECB : bool isnull;
319 : JsonTokenType tok;
320 : JsonParseErrorType result;
321 :
1178 rhaas 322 GIC 398657 : if (lex_peek(lex) != JSON_TOKEN_STRING)
1168 rhaas 323 CBC 6 : return report_parse_error(JSON_PARSE_STRING, lex);
1178 324 398651 : if ((ostart != NULL || oend != NULL) && lex->strval != NULL)
325 375713 : fname = pstrdup(lex->strval->data);
1168 326 398651 : result = json_lex(lex);
327 398651 : if (result != JSON_SUCCESS)
328 6 : return result;
1171 rhaas 329 ECB :
1168 rhaas 330 GIC 398645 : result = lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON);
1168 rhaas 331 CBC 398645 : if (result != JSON_SUCCESS)
332 45 : return result;
1171 rhaas 333 ECB :
1171 rhaas 334 GIC 398600 : tok = lex_peek(lex);
1171 rhaas 335 CBC 398600 : isnull = tok == JSON_TOKEN_NULL;
1171 rhaas 336 ECB :
1171 rhaas 337 GIC 398600 : if (ostart != NULL)
338 : {
119 tgl 339 GNC 375671 : result = (*ostart) (sem->semstate, fname, isnull);
340 375667 : if (result != JSON_SUCCESS)
119 tgl 341 UNC 0 : return result;
342 : }
343 :
1171 rhaas 344 CBC 398596 : switch (tok)
1171 rhaas 345 ECB : {
1171 rhaas 346 GBC 5876 : case JSON_TOKEN_OBJECT_START:
1168 rhaas 347 GIC 5876 : result = parse_object(lex, sem);
1171 348 1964 : break;
1171 rhaas 349 CBC 7473 : case JSON_TOKEN_ARRAY_START:
1168 rhaas 350 GIC 7473 : result = parse_array(lex, sem);
1171 rhaas 351 CBC 7456 : break;
352 385247 : default:
1168 353 385247 : result = parse_scalar(lex, sem);
1171 rhaas 354 ECB : }
1168 rhaas 355 CBC 394665 : if (result != JSON_SUCCESS)
356 21 : return result;
1171 rhaas 357 ECB :
1171 rhaas 358 CBC 394644 : if (oend != NULL)
359 : {
119 tgl 360 GNC 56855 : result = (*oend) (sem->semstate, fname, isnull);
361 56855 : if (result != JSON_SUCCESS)
119 tgl 362 UNC 0 : return result;
363 : }
364 :
1168 rhaas 365 CBC 394644 : return JSON_SUCCESS;
1171 rhaas 366 ECB : }
367 :
1168 368 : static JsonParseErrorType
1171 rhaas 369 GIC 82727 : parse_object(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 370 ECB : {
371 : /*
1171 rhaas 372 EUB : * an object is a possibly empty sequence of object fields, separated by
373 : * commas and surrounded by curly braces.
374 : */
1171 rhaas 375 CBC 82727 : json_struct_action ostart = sem->object_start;
1171 rhaas 376 GIC 82727 : json_struct_action oend = sem->object_end;
377 : JsonTokenType tok;
378 : JsonParseErrorType result;
1171 rhaas 379 ECB :
380 : #ifndef FRONTEND
1171 rhaas 381 GIC 23556 : check_stack_depth();
382 : #endif
383 :
384 82721 : if (ostart != NULL)
385 : {
119 tgl 386 GNC 72979 : result = (*ostart) (sem->semstate);
387 72969 : if (result != JSON_SUCCESS)
119 tgl 388 UNC 0 : return result;
389 : }
1171 rhaas 390 ECB :
391 : /*
392 : * Data inside an object is at a higher nesting level than the object
393 : * itself. Note that we increment this after we call the semantic routine
394 : * for the object start and restore it before we call the routine for the
395 : * object end.
396 : */
1171 rhaas 397 GIC 82711 : lex->lex_level++;
1171 rhaas 398 ECB :
1178 rhaas 399 GIC 82711 : Assert(lex_peek(lex) == JSON_TOKEN_OBJECT_START);
1168 rhaas 400 CBC 82711 : result = json_lex(lex);
401 82711 : if (result != JSON_SUCCESS)
1168 rhaas 402 GBC 30 : return result;
403 :
1171 rhaas 404 GIC 82681 : tok = lex_peek(lex);
405 82681 : switch (tok)
406 : {
407 78826 : case JSON_TOKEN_STRING:
1168 408 78826 : result = parse_object_field(lex, sem);
409 394722 : while (result == JSON_SUCCESS && lex_peek(lex) == JSON_TOKEN_COMMA)
410 : {
1168 rhaas 411 CBC 319831 : result = json_lex(lex);
1168 rhaas 412 GIC 319831 : if (result != JSON_SUCCESS)
1168 rhaas 413 LBC 0 : break;
1168 rhaas 414 CBC 319831 : result = parse_object_field(lex, sem);
1178 rhaas 415 ECB : }
1171 rhaas 416 CBC 74891 : break;
1171 rhaas 417 GIC 3848 : case JSON_TOKEN_OBJECT_END:
1171 rhaas 418 CBC 3848 : break;
419 7 : default:
420 : /* case of an invalid initial token inside the object */
1168 421 7 : result = report_parse_error(JSON_PARSE_OBJECT_START, lex);
1171 rhaas 422 ECB : }
1168 rhaas 423 CBC 78746 : if (result != JSON_SUCCESS)
1168 rhaas 424 GIC 85 : return result;
1171 rhaas 425 ECB :
1168 rhaas 426 CBC 78661 : result = lex_expect(JSON_PARSE_OBJECT_NEXT, lex, JSON_TOKEN_OBJECT_END);
1168 rhaas 427 GBC 78661 : if (result != JSON_SUCCESS)
1168 rhaas 428 CBC 18 : return result;
429 :
1171 430 78643 : lex->lex_level--;
1171 rhaas 431 ECB :
1171 rhaas 432 CBC 78643 : if (oend != NULL)
433 : {
119 tgl 434 GNC 69751 : result = (*oend) (sem->semstate);
435 69728 : if (result != JSON_SUCCESS)
119 tgl 436 UNC 0 : return result;
437 : }
438 :
1168 rhaas 439 CBC 78620 : return JSON_SUCCESS;
440 : }
1171 rhaas 441 ECB :
1168 442 : static JsonParseErrorType
1171 rhaas 443 GIC 80814 : parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 444 ECB : {
1171 rhaas 445 CBC 80814 : json_aelem_action astart = sem->array_element_start;
446 80814 : json_aelem_action aend = sem->array_element_end;
1171 rhaas 447 GIC 80814 : JsonTokenType tok = lex_peek(lex);
1168 rhaas 448 ECB : JsonParseErrorType result;
1171 449 : bool isnull;
450 :
1171 rhaas 451 CBC 80814 : isnull = tok == JSON_TOKEN_NULL;
1171 rhaas 452 ECB :
1171 rhaas 453 GBC 80814 : if (astart != NULL)
454 : {
119 tgl 455 GNC 3890 : result = (*astart) (sem->semstate, isnull);
456 3890 : if (result != JSON_SUCCESS)
119 tgl 457 UNC 0 : return result;
458 : }
459 :
1171 rhaas 460 ECB : /* an array element is any object, array or scalar */
1171 rhaas 461 GIC 80814 : switch (tok)
462 : {
463 65097 : case JSON_TOKEN_OBJECT_START:
1168 rhaas 464 CBC 65097 : result = parse_object(lex, sem);
1171 rhaas 465 GIC 65068 : break;
1171 rhaas 466 CBC 6011 : case JSON_TOKEN_ARRAY_START:
1168 467 6011 : result = parse_array(lex, sem);
1171 468 1601 : break;
1171 rhaas 469 GIC 9706 : default:
1168 470 9706 : result = parse_scalar(lex, sem);
471 : }
1171 rhaas 472 ECB :
1168 rhaas 473 GIC 76366 : if (result != JSON_SUCCESS)
1168 rhaas 474 CBC 33 : return result;
475 :
1171 476 76333 : if (aend != NULL)
477 : {
119 tgl 478 GNC 3635 : result = (*aend) (sem->semstate, isnull);
479 3629 : if (result != JSON_SUCCESS)
119 tgl 480 UNC 0 : return result;
481 : }
1168 rhaas 482 EUB :
1168 rhaas 483 GIC 76327 : return JSON_SUCCESS;
484 : }
485 :
1168 rhaas 486 ECB : static JsonParseErrorType
1171 rhaas 487 GIC 16104 : parse_array(JsonLexContext *lex, JsonSemAction *sem)
1171 rhaas 488 ECB : {
489 : /*
490 : * an array is a possibly empty sequence of array elements, separated by
491 : * commas and surrounded by square brackets.
492 : */
1171 rhaas 493 CBC 16104 : json_struct_action astart = sem->array_start;
494 16104 : json_struct_action aend = sem->array_end;
1168 rhaas 495 ECB : JsonParseErrorType result;
496 :
497 : #ifndef FRONTEND
1171 rhaas 498 CBC 15960 : check_stack_depth();
646 michael 499 ECB : #endif
500 :
1171 rhaas 501 CBC 16098 : if (astart != NULL)
502 : {
119 tgl 503 GNC 7025 : result = (*astart) (sem->semstate);
504 7018 : if (result != JSON_SUCCESS)
119 tgl 505 UNC 0 : return result;
506 : }
1171 rhaas 507 ECB :
508 : /*
1171 rhaas 509 EUB : * Data inside an array is at a higher nesting level than the array
510 : * itself. Note that we increment this after we call the semantic routine
511 : * for the array start and restore it before we call the routine for the
1171 rhaas 512 ECB : * array end.
513 : */
1171 rhaas 514 GIC 16091 : lex->lex_level++;
515 :
1168 rhaas 516 CBC 16091 : result = lex_expect(JSON_PARSE_ARRAY_START, lex, JSON_TOKEN_ARRAY_START);
1168 rhaas 517 GIC 16091 : if (result == JSON_SUCCESS && lex_peek(lex) != JSON_TOKEN_ARRAY_END)
518 : {
519 12723 : result = parse_array_element(lex, sem);
520 :
521 76336 : while (result == JSON_SUCCESS && lex_peek(lex) == JSON_TOKEN_COMMA)
1178 rhaas 522 ECB : {
1168 rhaas 523 CBC 68067 : result = json_lex(lex);
1168 rhaas 524 GIC 68067 : if (result != JSON_SUCCESS)
1168 rhaas 525 UIC 0 : break;
1168 rhaas 526 GIC 68067 : result = parse_array_element(lex, sem);
1178 rhaas 527 ECB : }
528 : }
1168 rhaas 529 GIC 11637 : if (result != JSON_SUCCESS)
1168 rhaas 530 CBC 33 : return result;
531 :
532 11604 : result = lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END);
533 11604 : if (result != JSON_SUCCESS)
1168 rhaas 534 GBC 12 : return result;
535 :
1171 rhaas 536 GIC 11592 : lex->lex_level--;
537 :
538 11592 : if (aend != NULL)
539 : {
119 tgl 540 GNC 3711 : result = (*aend) (sem->semstate);
541 3699 : if (result != JSON_SUCCESS)
119 tgl 542 UNC 0 : return result;
543 : }
544 :
1168 rhaas 545 GIC 11580 : return JSON_SUCCESS;
546 : }
1171 rhaas 547 ECB :
548 : /*
549 : * Lex one token from the input stream.
550 : */
551 : JsonParseErrorType
1171 rhaas 552 CBC 1806192 : json_lex(JsonLexContext *lex)
553 : {
1171 rhaas 554 ECB : char *s;
275 john.naylor 555 GNC 1806192 : char *const end = lex->input + lex->input_length;
1060 tgl 556 ECB : JsonParseErrorType result;
1171 rhaas 557 :
1171 rhaas 558 EUB : /* Skip leading whitespace. */
1171 rhaas 559 CBC 1806192 : s = lex->token_terminator;
275 john.naylor 560 GNC 4140731 : while (s < end && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
1171 rhaas 561 ECB : {
769 tgl 562 GIC 2334539 : if (*s++ == '\n')
769 tgl 563 ECB : {
1171 rhaas 564 CBC 145025 : ++lex->line_number;
769 tgl 565 145025 : lex->line_start = s;
566 : }
567 : }
1171 rhaas 568 1806192 : lex->token_start = s;
569 :
1171 rhaas 570 ECB : /* Determine token type. */
275 john.naylor 571 GNC 1806192 : if (s >= end)
1171 rhaas 572 EUB : {
1171 rhaas 573 GIC 33638 : lex->token_start = NULL;
574 33638 : lex->prev_token_terminator = lex->token_terminator;
1171 rhaas 575 CBC 33638 : lex->token_terminator = s;
1171 rhaas 576 GIC 33638 : lex->token_type = JSON_TOKEN_END;
577 : }
578 : else
579 : {
580 1772554 : switch (*s)
581 : {
1171 rhaas 582 ECB : /* Single-character token, some kind of punctuation mark. */
1171 rhaas 583 GIC 82880 : case '{':
584 82880 : lex->prev_token_terminator = lex->token_terminator;
1171 rhaas 585 CBC 82880 : lex->token_terminator = s + 1;
1171 rhaas 586 GIC 82880 : lex->token_type = JSON_TOKEN_OBJECT_START;
587 82880 : break;
588 78660 : case '}':
1171 rhaas 589 CBC 78660 : lex->prev_token_terminator = lex->token_terminator;
590 78660 : lex->token_terminator = s + 1;
1171 rhaas 591 GIC 78660 : lex->token_type = JSON_TOKEN_OBJECT_END;
1171 rhaas 592 CBC 78660 : break;
1171 rhaas 593 GIC 16173 : case '[':
1171 rhaas 594 CBC 16173 : lex->prev_token_terminator = lex->token_terminator;
595 16173 : lex->token_terminator = s + 1;
1171 rhaas 596 GIC 16173 : lex->token_type = JSON_TOKEN_ARRAY_START;
597 16173 : break;
1171 rhaas 598 CBC 11667 : case ']':
1171 rhaas 599 GIC 11667 : lex->prev_token_terminator = lex->token_terminator;
600 11667 : lex->token_terminator = s + 1;
1171 rhaas 601 CBC 11667 : lex->token_type = JSON_TOKEN_ARRAY_END;
1171 rhaas 602 GIC 11667 : break;
1171 rhaas 603 CBC 387946 : case ',':
604 387946 : lex->prev_token_terminator = lex->token_terminator;
605 387946 : lex->token_terminator = s + 1;
606 387946 : lex->token_type = JSON_TOKEN_COMMA;
1171 rhaas 607 GIC 387946 : break;
608 398645 : case ':':
609 398645 : lex->prev_token_terminator = lex->token_terminator;
1171 rhaas 610 CBC 398645 : lex->token_terminator = s + 1;
1171 rhaas 611 GIC 398645 : lex->token_type = JSON_TOKEN_COLON;
612 398645 : break;
1171 rhaas 613 CBC 663606 : case '"':
1171 rhaas 614 ECB : /* string */
1168 rhaas 615 CBC 663606 : result = json_lex_string(lex);
616 663606 : if (result != JSON_SUCCESS)
617 72 : return result;
1171 618 663534 : lex->token_type = JSON_TOKEN_STRING;
619 663534 : break;
620 71 : case '-':
1171 rhaas 621 ECB : /* Negative number. */
1168 rhaas 622 CBC 71 : result = json_lex_number(lex, s + 1, NULL, NULL);
623 71 : if (result != JSON_SUCCESS)
1168 rhaas 624 LBC 0 : return result;
1171 rhaas 625 CBC 71 : lex->token_type = JSON_TOKEN_NUMBER;
626 71 : break;
627 117346 : case '0':
1171 rhaas 628 ECB : case '1':
629 : case '2':
630 : case '3':
631 : case '4':
632 : case '5':
633 : case '6':
634 : case '7':
635 : case '8':
636 : case '9':
637 : /* Positive number. */
1168 rhaas 638 CBC 117346 : result = json_lex_number(lex, s, NULL, NULL);
639 117346 : if (result != JSON_SUCCESS)
640 24 : return result;
1171 641 117322 : lex->token_type = JSON_TOKEN_NUMBER;
642 117322 : break;
643 15560 : default:
644 : {
1171 rhaas 645 ECB : char *p;
646 :
647 : /*
648 : * We're not dealing with a string, number, legal
649 : * punctuation mark, or end of string. The only legal
650 : * tokens we might find here are true, false, and null,
651 : * but for error reporting purposes we scan until we see a
652 : * non-alphanumeric character. That way, we can report
653 : * the whole word as an unexpected token, rather than just
1171 rhaas 654 EUB : * some unintuitive prefix thereof.
1171 rhaas 655 ECB : */
275 john.naylor 656 GNC 87108 : for (p = s; p < end && JSON_ALPHANUMERIC_CHAR(*p); p++)
1171 rhaas 657 ECB : /* skip */ ;
658 :
659 : /*
660 : * We got some sort of unexpected punctuation or an
661 : * otherwise unexpected character, so just complain about
662 : * that one character.
663 : */
1171 rhaas 664 GIC 15560 : if (p == s)
665 : {
666 12 : lex->prev_token_terminator = lex->token_terminator;
667 12 : lex->token_terminator = s + 1;
1168 rhaas 668 CBC 12 : return JSON_INVALID_TOKEN;
1171 rhaas 669 ECB : }
670 :
671 : /*
672 : * We've got a real alphanumeric token here. If it
673 : * happens to be true, false, or null, all is well. If
674 : * not, error out.
675 : */
1171 rhaas 676 GIC 15548 : lex->prev_token_terminator = lex->token_terminator;
677 15548 : lex->token_terminator = p;
678 15548 : if (p - s == 4)
679 : {
680 6024 : if (memcmp(s, "true", 4) == 0)
681 3654 : lex->token_type = JSON_TOKEN_TRUE;
682 2370 : else if (memcmp(s, "null", 4) == 0)
683 2364 : lex->token_type = JSON_TOKEN_NULL;
684 : else
1168 685 6 : return JSON_INVALID_TOKEN;
1171 rhaas 686 ECB : }
1171 rhaas 687 GIC 9524 : else if (p - s == 5 && memcmp(s, "false", 5) == 0)
688 9455 : lex->token_type = JSON_TOKEN_FALSE;
689 : else
1168 690 69 : return JSON_INVALID_TOKEN;
691 : }
692 : } /* end of switch */
693 : }
1168 rhaas 694 ECB :
1168 rhaas 695 GIC 1806009 : return JSON_SUCCESS;
1171 rhaas 696 ECB : }
697 :
698 : /*
699 : * The next token in the input stream is known to be a string; lex it.
700 : *
701 : * If lex->strval isn't NULL, fill it with the decoded string.
702 : * Set lex->token_terminator to the end of the decoded input, and in
703 : * success cases, transfer its previous value to lex->prev_token_terminator.
704 : * Return JSON_SUCCESS or an error code.
705 : *
27 tgl 706 : * Note: be careful that all error exits advance lex->token_terminator
707 : * to the point after the character we detected the error on.
1171 rhaas 708 : */
709 : static inline JsonParseErrorType
1171 rhaas 710 CBC 663606 : json_lex_string(JsonLexContext *lex)
1171 rhaas 711 ECB : {
712 : char *s;
275 john.naylor 713 GNC 663606 : char *const end = lex->input + lex->input_length;
1171 rhaas 714 GIC 663606 : int hi_surrogate = -1;
1171 rhaas 715 ECB :
716 : /* Convenience macros for error exits */
27 tgl 717 : #define FAIL_AT_CHAR_START(code) \
718 : do { \
719 : lex->token_terminator = s; \
720 : return code; \
721 : } while (0)
722 : #define FAIL_AT_CHAR_END(code) \
723 : do { \
724 : lex->token_terminator = \
725 : s + pg_encoding_mblen_bounded(lex->input_encoding, s); \
726 : return code; \
727 : } while (0)
728 :
1171 rhaas 729 GIC 663606 : if (lex->strval != NULL)
730 640447 : resetStringInfo(lex->strval);
731 :
732 663606 : Assert(lex->input_length > 0);
733 663606 : s = lex->token_start;
734 : for (;;)
735 : {
736 1327605 : s++;
737 : /* Premature end of the string. */
275 john.naylor 738 GNC 1327605 : if (s >= end)
27 tgl 739 GIC 6 : FAIL_AT_CHAR_START(JSON_INVALID_TOKEN);
271 john.naylor 740 1327599 : else if (*s == '"')
271 john.naylor 741 CBC 663534 : break;
1171 rhaas 742 GIC 664065 : else if (*s == '\\')
743 : {
744 : /* OK, we have an escape character. */
745 381 : s++;
275 john.naylor 746 GNC 381 : if (s >= end)
27 tgl 747 UIC 0 : FAIL_AT_CHAR_START(JSON_INVALID_TOKEN);
1171 rhaas 748 GIC 381 : else if (*s == 'u')
749 : {
1171 rhaas 750 ECB : int i;
1171 rhaas 751 CBC 174 : int ch = 0;
752 :
753 828 : for (i = 1; i <= 4; i++)
1171 rhaas 754 ECB : {
1171 rhaas 755 GIC 672 : s++;
275 john.naylor 756 GNC 672 : if (s >= end)
27 tgl 757 UIC 0 : FAIL_AT_CHAR_START(JSON_INVALID_TOKEN);
1171 rhaas 758 CBC 672 : else if (*s >= '0' && *s <= '9')
759 423 : ch = (ch * 16) + (*s - '0');
760 249 : else if (*s >= 'a' && *s <= 'f')
761 219 : ch = (ch * 16) + (*s - 'a') + 10;
762 30 : else if (*s >= 'A' && *s <= 'F')
1171 rhaas 763 GIC 12 : ch = (ch * 16) + (*s - 'A') + 10;
764 : else
27 tgl 765 CBC 18 : FAIL_AT_CHAR_END(JSON_UNICODE_ESCAPE_FORMAT);
1171 rhaas 766 ECB : }
1171 rhaas 767 GBC 156 : if (lex->strval != NULL)
1171 rhaas 768 ECB : {
769 : /*
770 : * Combine surrogate pairs.
1129 tgl 771 : */
1129 tgl 772 GIC 102 : if (is_utf16_surrogate_first(ch))
1171 rhaas 773 ECB : {
1171 rhaas 774 GIC 36 : if (hi_surrogate != -1)
27 tgl 775 CBC 6 : FAIL_AT_CHAR_END(JSON_UNICODE_HIGH_SURROGATE);
1129 776 30 : hi_surrogate = ch;
1171 rhaas 777 GBC 30 : continue;
1171 rhaas 778 ECB : }
1129 tgl 779 CBC 66 : else if (is_utf16_surrogate_second(ch))
1171 rhaas 780 ECB : {
1171 rhaas 781 CBC 30 : if (hi_surrogate == -1)
27 tgl 782 12 : FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE);
1129 783 18 : ch = surrogate_pair_to_codepoint(hi_surrogate, ch);
1171 rhaas 784 GIC 18 : hi_surrogate = -1;
1171 rhaas 785 ECB : }
786 :
1171 rhaas 787 CBC 54 : if (hi_surrogate != -1)
27 tgl 788 UIC 0 : FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE);
789 :
790 : /*
791 : * Reject invalid cases. We can't have a value above
1129 tgl 792 ECB : * 0xFFFF here (since we only accepted 4 hex digits
793 : * above), so no need to test for out-of-range chars.
1171 rhaas 794 : */
1171 rhaas 795 CBC 54 : if (ch == 0)
1171 rhaas 796 ECB : {
797 : /* We can't allow this, since our TEXT type doesn't */
27 tgl 798 GIC 12 : FAIL_AT_CHAR_END(JSON_UNICODE_CODE_POINT_ZERO);
1171 rhaas 799 ECB : }
800 :
1129 tgl 801 : /*
802 : * Add the represented character to lex->strval. In the
803 : * backend, we can let pg_unicode_to_server_noerror()
804 : * handle any required character set conversion; in
805 : * frontend, we can only deal with trivial conversions.
806 : */
807 : #ifndef FRONTEND
808 : {
809 : char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
810 :
119 tgl 811 GNC 42 : if (!pg_unicode_to_server_noerror(ch, (unsigned char *) cbuf))
27 tgl 812 UNC 0 : FAIL_AT_CHAR_END(JSON_UNICODE_UNTRANSLATABLE);
1129 tgl 813 GIC 42 : appendStringInfoString(lex->strval, cbuf);
814 : }
1129 tgl 815 ECB : #else
1129 tgl 816 UIC 0 : if (lex->input_encoding == PG_UTF8)
817 : {
818 : /* OK, we can map the code point to UTF8 easily */
819 : char utf8str[5];
820 : int utf8len;
821 :
1171 rhaas 822 0 : unicode_to_utf8(ch, (unsigned char *) utf8str);
823 0 : utf8len = pg_utf_mblen((unsigned char *) utf8str);
824 0 : appendBinaryStringInfo(lex->strval, utf8str, utf8len);
825 : }
826 0 : else if (ch <= 0x007f)
827 : {
1129 tgl 828 ECB : /* The ASCII range is the same in all encodings */
1171 rhaas 829 UBC 0 : appendStringInfoChar(lex->strval, (char) ch);
1171 rhaas 830 ECB : }
831 : else
27 tgl 832 UIC 0 : FAIL_AT_CHAR_END(JSON_UNICODE_HIGH_ESCAPE);
1129 tgl 833 EUB : #endif /* FRONTEND */
834 : }
835 : }
1171 rhaas 836 GIC 207 : else if (lex->strval != NULL)
837 : {
838 150 : if (hi_surrogate != -1)
27 tgl 839 UBC 0 : FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE);
1171 rhaas 840 EUB :
1171 rhaas 841 GBC 150 : switch (*s)
842 : {
843 102 : case '"':
844 : case '\\':
845 : case '/':
846 102 : appendStringInfoChar(lex->strval, *s);
1171 rhaas 847 GIC 102 : break;
848 18 : case 'b':
1171 rhaas 849 GBC 18 : appendStringInfoChar(lex->strval, '\b');
1171 rhaas 850 GIC 18 : break;
1171 rhaas 851 UIC 0 : case 'f':
852 0 : appendStringInfoChar(lex->strval, '\f');
1171 rhaas 853 LBC 0 : break;
1171 rhaas 854 GIC 27 : case 'n':
1171 rhaas 855 CBC 27 : appendStringInfoChar(lex->strval, '\n');
1171 rhaas 856 GBC 27 : break;
1171 rhaas 857 UIC 0 : case 'r':
1171 rhaas 858 LBC 0 : appendStringInfoChar(lex->strval, '\r');
1171 rhaas 859 UIC 0 : break;
1171 rhaas 860 LBC 0 : case 't':
1171 rhaas 861 UIC 0 : appendStringInfoChar(lex->strval, '\t');
862 0 : break;
1171 rhaas 863 CBC 3 : default:
27 tgl 864 ECB :
865 : /*
866 : * Not a valid string escape, so signal error. We
867 : * adjust token_start so that just the escape sequence
27 tgl 868 EUB : * is reported, not the whole string.
869 : */
1168 rhaas 870 GBC 3 : lex->token_start = s;
27 tgl 871 CBC 3 : FAIL_AT_CHAR_END(JSON_ESCAPING_INVALID);
1171 rhaas 872 ECB : }
873 : }
1171 rhaas 874 GBC 57 : else if (strchr("\"\\/bfnrt", *s) == NULL)
1171 rhaas 875 EUB : {
876 : /*
877 : * Simpler processing if we're not bothered about de-escaping
878 : *
879 : * It's very tempting to remove the strchr() call here and
1171 rhaas 880 ECB : * replace it with a switch statement, but testing so far has
881 : * shown it's not a performance win.
882 : */
1168 rhaas 883 GIC 3 : lex->token_start = s;
27 tgl 884 3 : FAIL_AT_CHAR_END(JSON_ESCAPING_INVALID);
885 : }
886 : }
887 : else
1171 rhaas 888 ECB : {
221 john.naylor 889 GNC 663684 : char *p = s;
890 :
1171 rhaas 891 GIC 663684 : if (hi_surrogate != -1)
27 tgl 892 6 : FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE);
1171 rhaas 893 ECB :
894 : /*
895 : * Skip to the first byte that requires special handling, so we
896 : * can batch calls to appendBinaryStringInfo.
897 : */
221 john.naylor 898 GNC 663678 : while (p < end - sizeof(Vector8) &&
899 811007 : !pg_lfind8('\\', (uint8 *) p, sizeof(Vector8)) &&
900 1635273 : !pg_lfind8('"', (uint8 *) p, sizeof(Vector8)) &&
901 160834 : !pg_lfind8_le(31, (uint8 *) p, sizeof(Vector8)))
902 160834 : p += sizeof(Vector8);
903 :
904 5233972 : for (; p < end; p++)
905 : {
282 906 5233966 : if (*p == '\\' || *p == '"')
907 : break;
221 908 4570300 : else if ((unsigned char) *p <= 31)
909 : {
910 : /* Per RFC4627, these characters MUST be escaped. */
911 : /*
912 : * Since *p isn't printable, exclude it from the context
913 : * string
914 : */
282 915 6 : lex->token_terminator = p;
916 6 : return JSON_ESCAPING_REQUIRED;
917 : }
918 : }
919 :
920 663672 : if (lex->strval != NULL)
921 640495 : appendBinaryStringInfo(lex->strval, s, p - s);
922 :
923 : /*
924 : * s will be incremented at the top of the loop, so set it to just
925 : * behind our lookahead position
926 : */
927 663672 : s = p - 1;
928 : }
929 : }
930 :
271 john.naylor 931 GIC 663534 : if (hi_surrogate != -1)
932 : {
27 tgl 933 UIC 0 : lex->token_terminator = s + 1;
271 john.naylor 934 0 : return JSON_UNICODE_LOW_SURROGATE;
27 tgl 935 ECB : }
271 john.naylor 936 :
937 : /* Hooray, we found the end of the string! */
271 john.naylor 938 GIC 663534 : lex->prev_token_terminator = lex->token_terminator;
939 663534 : lex->token_terminator = s + 1;
940 663534 : return JSON_SUCCESS;
27 tgl 941 ECB :
942 : #undef FAIL_AT_CHAR_START
943 : #undef FAIL_AT_CHAR_END
1171 rhaas 944 : }
945 :
946 : /*
947 : * The next token in the input stream is known to be a number; lex it.
948 : *
949 : * In JSON, a number consists of four parts:
950 : *
951 : * (1) An optional minus sign ('-').
952 : *
953 : * (2) Either a single '0', or a string of one or more digits that does not
954 : * begin with a '0'.
955 : *
956 : * (3) An optional decimal part, consisting of a period ('.') followed by
957 : * one or more digits. (Note: While this part can be omitted
958 : * completely, it's not OK to have only the decimal point without
959 : * any digits afterwards.)
960 : *
961 : * (4) An optional exponent part, consisting of 'e' or 'E', optionally
962 : * followed by '+' or '-', followed by one or more digits. (Note:
963 : * As with the decimal part, if 'e' or 'E' is present, it must be
964 : * followed by at least one digit.)
965 : *
966 : * The 's' argument to this function points to the ostensible beginning
967 : * of part 2 - i.e. the character after any optional minus sign, or the
968 : * first character of the string if there is none.
969 : *
970 : * If num_err is not NULL, we return an error flag to *num_err rather than
971 : * raising an error for a badly-formed number. Also, if total_len is not NULL
972 : * the distance from lex->input to the token end+1 is returned to *total_len.
973 : */
974 : static inline JsonParseErrorType
1171 rhaas 975 GIC 118816 : json_lex_number(JsonLexContext *lex, char *s,
976 : bool *num_err, int *total_len)
977 : {
978 118816 : bool error = false;
1171 rhaas 979 CBC 118816 : int len = s - lex->input;
980 :
981 : /* Part (1): leading sign indicator. */
982 : /* Caller already did this for us; so do nothing. */
1171 rhaas 983 ECB :
984 : /* Part (2): parse main digit string. */
1171 rhaas 985 GBC 118816 : if (len < lex->input_length && *s == '0')
1171 rhaas 986 EUB : {
1171 rhaas 987 GIC 18240 : s++;
988 18240 : len++;
989 : }
1171 rhaas 990 CBC 100576 : else if (len < lex->input_length && *s >= '1' && *s <= '9')
1171 rhaas 991 ECB : {
992 : do
993 : {
1171 rhaas 994 GIC 335447 : s++;
995 335447 : len++;
996 335447 : } while (len < lex->input_length && *s >= '0' && *s <= '9');
997 : }
998 : else
999 10 : error = true;
1000 :
1001 : /* Part (3): parse optional decimal portion. */
1002 118816 : if (len < lex->input_length && *s == '.')
1003 : {
1004 18635 : s++;
1005 18635 : len++;
1006 18635 : if (len == lex->input_length || *s < '0' || *s > '9')
1007 6 : error = true;
1008 : else
1009 : {
1010 : do
1011 : {
1012 45820 : s++;
1013 45820 : len++;
1014 45820 : } while (len < lex->input_length && *s >= '0' && *s <= '9');
1015 : }
1016 : }
1017 :
1018 : /* Part (4): parse optional exponent. */
1019 118816 : if (len < lex->input_length && (*s == 'e' || *s == 'E'))
1020 : {
1021 32 : s++;
1022 32 : len++;
1023 32 : if (len < lex->input_length && (*s == '+' || *s == '-'))
1024 : {
1025 5 : s++;
1026 5 : len++;
1171 rhaas 1027 ECB : }
1171 rhaas 1028 GIC 32 : if (len == lex->input_length || *s < '0' || *s > '9')
1029 6 : error = true;
1171 rhaas 1030 ECB : else
1031 : {
1032 : do
1033 : {
1171 rhaas 1034 GIC 82 : s++;
1035 82 : len++;
1036 82 : } while (len < lex->input_length && *s >= '0' && *s <= '9');
1171 rhaas 1037 ECB : }
1038 : }
1039 :
1040 : /*
1041 : * Check for trailing garbage. As in json_lex(), any alphanumeric stuff
1042 : * here should be considered part of the token for error-reporting
1043 : * purposes.
1044 : */
1171 rhaas 1045 GIC 118951 : for (; len < lex->input_length && JSON_ALPHANUMERIC_CHAR(*s); s++, len++)
1171 rhaas 1046 CBC 135 : error = true;
1171 rhaas 1047 ECB :
1171 rhaas 1048 CBC 118816 : if (total_len != NULL)
1171 rhaas 1049 GIC 1399 : *total_len = len;
1050 :
1171 rhaas 1051 CBC 118816 : if (num_err != NULL)
1052 : {
1053 : /* let the caller handle any error */
1054 1399 : *num_err = error;
1055 : }
1171 rhaas 1056 ECB : else
1057 : {
1058 : /* return token endpoint */
1171 rhaas 1059 CBC 117417 : lex->prev_token_terminator = lex->token_terminator;
1171 rhaas 1060 GIC 117417 : lex->token_terminator = s;
1061 : /* handle error if any */
1062 117417 : if (error)
1168 1063 24 : return JSON_INVALID_TOKEN;
1171 rhaas 1064 ECB : }
1168 1065 :
1168 rhaas 1066 CBC 118792 : return JSON_SUCCESS;
1067 : }
1068 :
1069 : /*
1070 : * Report a parse error.
1171 rhaas 1071 ECB : *
1072 : * lex->token_start and lex->token_terminator must identify the current token.
1073 : */
1168 1074 : static JsonParseErrorType
1171 rhaas 1075 CBC 157 : report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
1076 : {
1171 rhaas 1077 ECB : /* Handle case where the input ended prematurely. */
1171 rhaas 1078 CBC 157 : if (lex->token_start == NULL || lex->token_type == JSON_TOKEN_END)
1168 rhaas 1079 GIC 64 : return JSON_EXPECTED_MORE;
1171 rhaas 1080 ECB :
1168 1081 : /* Otherwise choose the error type based on the parsing context. */
1168 rhaas 1082 GIC 93 : switch (ctx)
1083 : {
1084 12 : case JSON_PARSE_END:
1085 12 : return JSON_EXPECTED_END;
1168 rhaas 1086 CBC 51 : case JSON_PARSE_VALUE:
1087 51 : return JSON_EXPECTED_JSON;
1088 6 : case JSON_PARSE_STRING:
1168 rhaas 1089 GIC 6 : return JSON_EXPECTED_STRING;
1168 rhaas 1090 UIC 0 : case JSON_PARSE_ARRAY_START:
1091 0 : return JSON_EXPECTED_ARRAY_FIRST;
1092 0 : case JSON_PARSE_ARRAY_NEXT:
1093 0 : return JSON_EXPECTED_ARRAY_NEXT;
1168 rhaas 1094 GIC 6 : case JSON_PARSE_OBJECT_START:
1095 6 : return JSON_EXPECTED_OBJECT_FIRST;
1096 12 : case JSON_PARSE_OBJECT_LABEL:
1168 rhaas 1097 CBC 12 : return JSON_EXPECTED_COLON;
1098 6 : case JSON_PARSE_OBJECT_NEXT:
1168 rhaas 1099 GIC 6 : return JSON_EXPECTED_OBJECT_NEXT;
1168 rhaas 1100 LBC 0 : case JSON_PARSE_OBJECT_COMMA:
1101 0 : return JSON_EXPECTED_STRING;
1102 : }
1168 tgl 1103 ECB :
1104 : /*
1105 : * We don't use a default: case, so that the compiler will warn about
646 michael 1106 : * unhandled enum values.
1107 : */
646 michael 1108 UIC 0 : Assert(false);
1109 : return JSON_SUCCESS; /* silence stupider compilers */
1110 : }
1171 rhaas 1111 ECB :
646 michael 1112 :
1113 : #ifndef FRONTEND
1114 : /*
1115 : * Extract the current token from a lexing context, for error reporting.
1116 : */
1117 : static char *
646 michael 1118 CBC 129 : extract_token(JsonLexContext *lex)
1119 : {
646 michael 1120 GIC 129 : int toklen = lex->token_terminator - lex->token_start;
1121 129 : char *token = palloc(toklen + 1);
1122 :
1123 129 : memcpy(token, lex->token_start, toklen);
1124 129 : token[toklen] = '\0';
1125 129 : return token;
1126 : }
646 michael 1127 ECB :
1128 : /*
1129 : * Construct an (already translated) detail message for a JSON error.
1130 : *
1131 : * Note that the error message generated by this routine may not be
1132 : * palloc'd, making it unsafe for frontend code as there is no way to
1133 : * know if this can be safely pfree'd or not.
1171 rhaas 1134 : */
1135 : char *
1168 rhaas 1136 CBC 219 : json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
1171 rhaas 1137 ECB : {
1168 rhaas 1138 CBC 219 : switch (error)
1168 rhaas 1139 ECB : {
1168 rhaas 1140 LBC 0 : case JSON_SUCCESS:
1168 tgl 1141 ECB : /* fall through to the error code after switch */
1168 rhaas 1142 UBC 0 : break;
1168 rhaas 1143 GBC 6 : case JSON_ESCAPING_INVALID:
1144 6 : return psprintf(_("Escape sequence \"\\%s\" is invalid."),
1168 rhaas 1145 EUB : extract_token(lex));
1168 rhaas 1146 CBC 6 : case JSON_ESCAPING_REQUIRED:
1147 6 : return psprintf(_("Character with value 0x%02x must be escaped."),
1148 6 : (unsigned char) *(lex->token_terminator));
1149 12 : case JSON_EXPECTED_END:
1150 12 : return psprintf(_("Expected end of input, but found \"%s\"."),
1168 rhaas 1151 ECB : extract_token(lex));
1168 rhaas 1152 UBC 0 : case JSON_EXPECTED_ARRAY_FIRST:
1153 0 : return psprintf(_("Expected array element or \"]\", but found \"%s\"."),
1154 : extract_token(lex));
1168 rhaas 1155 UIC 0 : case JSON_EXPECTED_ARRAY_NEXT:
1156 0 : return psprintf(_("Expected \",\" or \"]\", but found \"%s\"."),
1157 : extract_token(lex));
1168 rhaas 1158 GIC 12 : case JSON_EXPECTED_COLON:
1159 12 : return psprintf(_("Expected \":\", but found \"%s\"."),
1168 rhaas 1160 EUB : extract_token(lex));
1168 rhaas 1161 GIC 24 : case JSON_EXPECTED_JSON:
1162 24 : return psprintf(_("Expected JSON value, but found \"%s\"."),
1163 : extract_token(lex));
1164 30 : case JSON_EXPECTED_MORE:
1165 30 : return _("The input string ended unexpectedly.");
1166 6 : case JSON_EXPECTED_OBJECT_FIRST:
1167 6 : return psprintf(_("Expected string or \"}\", but found \"%s\"."),
1168 : extract_token(lex));
1169 6 : case JSON_EXPECTED_OBJECT_NEXT:
1168 rhaas 1170 CBC 6 : return psprintf(_("Expected \",\" or \"}\", but found \"%s\"."),
1171 : extract_token(lex));
1172 6 : case JSON_EXPECTED_STRING:
1173 6 : return psprintf(_("Expected string, but found \"%s\"."),
1174 : extract_token(lex));
1175 57 : case JSON_INVALID_TOKEN:
1176 57 : return psprintf(_("Token \"%s\" is invalid."),
1168 rhaas 1177 ECB : extract_token(lex));
1168 rhaas 1178 GIC 12 : case JSON_UNICODE_CODE_POINT_ZERO:
1179 12 : return _("\\u0000 cannot be converted to text.");
1180 18 : case JSON_UNICODE_ESCAPE_FORMAT:
1181 18 : return _("\"\\u\" must be followed by four hexadecimal digits.");
1168 rhaas 1182 UIC 0 : case JSON_UNICODE_HIGH_ESCAPE:
1183 : /* note: this case is only reachable in frontend not backend */
1129 tgl 1184 0 : return _("Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8.");
119 tgl 1185 UNC 0 : case JSON_UNICODE_UNTRANSLATABLE:
1186 : /* note: this case is only reachable in backend not frontend */
1187 0 : return psprintf(_("Unicode escape value could not be translated to the server's encoding %s."),
1188 : GetDatabaseEncodingName());
1168 rhaas 1189 GIC 6 : case JSON_UNICODE_HIGH_SURROGATE:
1190 6 : return _("Unicode high surrogate must not follow a high surrogate.");
1191 18 : case JSON_UNICODE_LOW_SURROGATE:
1168 rhaas 1192 CBC 18 : return _("Unicode low surrogate must follow a high surrogate.");
119 tgl 1193 UNC 0 : case JSON_SEM_ACTION_FAILED:
1194 : /* fall through to the error code after switch */
1195 0 : break;
1196 : }
1168 tgl 1197 ECB :
1198 : /*
1168 tgl 1199 EUB : * We don't use a default: case, so that the compiler will warn about
1200 : * unhandled enum values. But this needs to be here anyway to cover the
1201 : * possibility of an incorrect input.
1168 tgl 1202 ECB : */
646 michael 1203 LBC 0 : elog(ERROR, "unexpected json parse error type: %d", (int) error);
1204 : return NULL;
1171 rhaas 1205 ECB : }
646 michael 1206 : #endif
|