24 #ifdef JSONAPI_USE_PQEXPBUFFER
35 #ifdef JSONAPI_USE_PQEXPBUFFER
37 #define STRDUP(s) strdup(s)
38 #define ALLOC(size) malloc(size)
39 #define ALLOC0(size) calloc(1, size)
40 #define REALLOC realloc
41 #define FREE(s) free(s)
43 #define jsonapi_appendStringInfo appendPQExpBuffer
44 #define jsonapi_appendBinaryStringInfo appendBinaryPQExpBuffer
45 #define jsonapi_appendStringInfoChar appendPQExpBufferChar
47 #define jsonapi_appendStringInfoCharMacro appendPQExpBufferChar
48 #define jsonapi_makeStringInfo createPQExpBuffer
49 #define jsonapi_initStringInfo initPQExpBuffer
50 #define jsonapi_resetStringInfo resetPQExpBuffer
51 #define jsonapi_termStringInfo termPQExpBuffer
52 #define jsonapi_destroyStringInfo destroyPQExpBuffer
56 #define STRDUP(s) pstrdup(s)
57 #define ALLOC(size) palloc(size)
58 #define ALLOC0(size) palloc0(size)
59 #define REALLOC repalloc
69 #define FREE(s) do { \
76 #define jsonapi_appendStringInfo appendStringInfo
77 #define jsonapi_appendBinaryStringInfo appendBinaryStringInfo
78 #define jsonapi_appendStringInfoChar appendStringInfoChar
79 #define jsonapi_appendStringInfoCharMacro appendStringInfoCharMacro
80 #define jsonapi_makeStringInfo makeStringInfo
81 #define jsonapi_initStringInfo initStringInfo
82 #define jsonapi_resetStringInfo resetStringInfo
83 #define jsonapi_termStringInfo(s) pfree((s)->data)
84 #define jsonapi_destroyStringInfo destroyStringInfo
173 #define JSON_NUM_TERMINALS 13
174 #define JSON_NUM_NONTERMINALS 5
175 #define JSON_NT_OFFSET JSON_NT_JSON
177 #define OFS(NT) (NT) - JSON_NT_OFFSET
179 #define IS_SEM(x) ((x) & 0x40)
180 #define IS_NT(x) ((x) & 0x20)
239 #define TD_ENTRY(PROD) { sizeof(PROD) - 1, (PROD) }
276 bool *num_err,
size_t *total_len);
289 NULL, NULL, NULL, NULL, NULL,
290 NULL, NULL, NULL, NULL, NULL
326 #define JSON_ALPHANUMERIC_CHAR(c) \
327 (((c) >= 'a' && (c) <= 'z') || \
328 ((c) >= 'A' && (c) <= 'Z') || \
329 ((c) >= '0' && (c) <= '9') || \
369 return (!numeric_error) && (total_len == dummy_lex.
input_length);
429 #define JS_STACK_CHUNK_SIZE 64
430 #define JS_MAX_PROD_LEN 10
431 #define JSON_TD_MAX_STACK 6400
447 #ifdef JSONAPI_USE_PQEXPBUFFER
555 if (owned_by_context)
566 size_t new_stack_size;
567 char *new_prediction;
575 #ifdef JSONAPI_USE_PQEXPBUFFER
582 new_stack_size *
sizeof(
char *));
583 #ifdef JSONAPI_USE_PQEXPBUFFER
590 #ifdef JSONAPI_USE_PQEXPBUFFER
747 #ifdef FORCE_JSON_PSTACK
1021 if ((ostart != NULL || oend != NULL) && lex->
need_escapes)
1045 result = (*ostart) (
sem->
semstate, fname, isnull);
1327 if ((ostart != NULL || oend != NULL) && lex->
need_escapes)
1352 result = (*ostart) (
sem->
semstate, fname, isnull);
1354 goto ofield_cleanup;
1369 goto ofield_cleanup;
1375 goto ofield_cleanup;
1607 #ifdef JSONAPI_USE_PQEXPBUFFER
1624 bool tok_done =
false;
1628 if (ptok->data[0] ==
'"')
1636 for (
int i = ptok->len - 1;
i > 0;
i--)
1639 if (ptok->data[
i] ==
'\\')
1651 if (
c ==
'"' && escapes % 2 == 0)
1665 char c = ptok->data[0];
1667 if (
c ==
'-' || (
c >=
'0' &&
c <=
'9'))
1671 bool numend =
false;
1749 lex->
input += added;
1761 partial_result =
json_lex(&dummy_lex);
1795 return partial_result;
1800 while (s < end && (*s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r'))
1927 if (memcmp(s,
"true", 4) == 0)
1929 else if (memcmp(s,
"null", 4) == 0)
1934 else if (p - s == 5 && memcmp(s,
"false", 5) == 0)
1964 int hi_surrogate = -1;
1967 #define FAIL_OR_INCOMPLETE_AT_CHAR_START(code) \
1969 if (lex->incremental && !lex->inc_state->is_last_chunk) \
1971 jsonapi_appendBinaryStringInfo(&lex->inc_state->partial_token, \
1973 end - lex->token_start); \
1974 return JSON_INCOMPLETE; \
1976 lex->token_terminator = s; \
1979 #define FAIL_AT_CHAR_END(code) \
1981 const char *term = s + pg_encoding_mblen(lex->input_encoding, s); \
1982 lex->token_terminator = (term <= end) ? term : end; \
1988 #ifdef JSONAPI_USE_PQEXPBUFFER
2006 else if (*s ==
'\\')
2017 for (
i = 1;
i <= 4;
i++)
2022 else if (*s >=
'0' && *s <=
'9')
2023 ch = (ch * 16) + (*s -
'0');
2024 else if (*s >=
'a' && *s <=
'f')
2025 ch = (ch * 16) + (*s -
'a') + 10;
2026 else if (*s >=
'A' && *s <=
'F')
2027 ch = (ch * 16) + (*s -
'A') + 10;
2038 if (hi_surrogate != -1)
2045 if (hi_surrogate == -1)
2051 if (hi_surrogate != -1)
2090 else if (ch <= 0x007f)
2102 if (hi_surrogate != -1)
2138 else if (strchr(
"\"\\/bfnrt", *s) == NULL)
2155 if (hi_surrogate != -1)
2162 while (p < end -
sizeof(
Vector8) &&
2168 for (; p < end; p++)
2170 if (*p ==
'\\' || *p ==
'"')
2172 else if ((
unsigned char) *p <= 31)
2195 if (hi_surrogate != -1)
2201 #ifdef JSONAPI_USE_PQEXPBUFFER
2211 #undef FAIL_OR_INCOMPLETE_AT_CHAR_START
2212 #undef FAIL_AT_CHAR_END
2245 bool *num_err,
size_t *total_len)
2254 if (len < lex->input_length && *s ==
'0')
2259 else if (len < lex->input_length && *s >=
'1' && *s <=
'9')
2265 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2271 if (len < lex->input_length && *s ==
'.')
2283 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2288 if (len < lex->input_length && (*s ==
'e' || *s ==
'E'))
2292 if (len < lex->input_length && (*s ==
'+' || *s ==
'-'))
2305 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
2317 if (total_len != NULL)
2325 if (num_err != NULL)
2330 else if (num_err != NULL)
2403 return _(
"out of memory");
2415 #define json_token_error(lex, format) \
2416 jsonapi_appendStringInfo((lex)->errormsg, _(format), \
2417 (int) ((lex)->token_terminator - (lex)->token_start), \
2418 (lex)->token_start);
2428 return _(
"Recursive descent parser cannot use incremental lexer.");
2430 return _(
"Incremental parser requires incremental lexer.");
2432 return (
_(
"JSON nested too deep, maximum permitted depth is 6400."));
2438 _(
"Character with value 0x%02x must be escaped."),
2445 json_token_error(lex,
"Expected array element or \"]\", but found \"%.*s\".");
2457 return _(
"The input string ended unexpectedly.");
2474 return _(
"\\u0000 cannot be converted to text.");
2476 return _(
"\"\\u\" must be followed by four hexadecimal digits.");
2479 return _(
"Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8.");
2488 return psprintf(
_(
"Unicode escape value could not be translated to the server's encoding %s."),
2495 return _(
"Unicode high surrogate must not follow a high surrogate.");
2497 return _(
"Unicode low surrogate must follow a high surrogate.");
2502 #undef json_token_error
2513 "unexpected json parse error type: %d",
2517 #ifdef JSONAPI_USE_PQEXPBUFFER
2519 return _(
"out of memory while constructing error description");
#define Assert(condition)
JsonParseErrorType pg_parse_json_incremental(JsonLexContext *lex, const JsonSemAction *sem, const char *json, size_t len, bool is_last)
#define JSON_TD_MAX_STACK
@ JSON_PARSE_OBJECT_LABEL
@ JSON_PARSE_OBJECT_START
@ JSON_PARSE_OBJECT_COMMA
static void set_fnull(JsonLexContext *lex, bool fnull)
#define JSON_NUM_TERMINALS
static char JSON_PROD_MORE_KEY_PAIRS[]
bool IsValidJsonNumber(const char *str, size_t len)
#define jsonapi_destroyStringInfo
static JsonParseErrorType json_lex_string(JsonLexContext *lex)
#define JSON_ALPHANUMERIC_CHAR(c)
static char JSON_PROD_KEY_PAIRS[]
#define JSON_NUM_NONTERMINALS
static char JSON_PROD_SCALAR_STRING[]
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
static bool inc_lex_level(JsonLexContext *lex)
static char JSON_PROD_ARRAY_ELEMENTS[]
static bool have_prediction(JsonParserStack *pstack)
static void set_fname(JsonLexContext *lex, char *fname)
static char JSON_PROD_SCALAR_NUMBER[]
#define json_token_error(lex, format)
static char next_prediction(JsonParserStack *pstack)
static void push_prediction(JsonParserStack *pstack, td_entry entry)
static JsonLexContext failed_oom
#define jsonapi_appendStringInfoCharMacro
static char JSON_PROD_GOAL[]
#define jsonapi_makeStringInfo
static JsonTokenType lex_peek(JsonLexContext *lex)
static char JSON_PROD_EPSILON[]
char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
static JsonParseErrorType parse_object(JsonLexContext *lex, const JsonSemAction *sem)
#define jsonapi_initStringInfo
#define JS_STACK_CHUNK_SIZE
void setJsonLexContextOwnsTokens(JsonLexContext *lex, bool owned_by_context)
static char JSON_PROD_SCALAR_NULL[]
static bool allocate_incremental_state(JsonLexContext *lex)
#define jsonapi_resetStringInfo
static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
static JsonParseErrorType lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
static JsonIncrementalState failed_inc_oom
static JsonParseErrorType json_lex_number(JsonLexContext *lex, const char *s, bool *num_err, size_t *total_len)
static char JSON_PROD_MORE_ARRAY_ELEMENTS[]
const JsonSemAction nullSemAction
static td_entry td_parser_table[JSON_NUM_NONTERMINALS][JSON_NUM_TERMINALS]
static JsonParseErrorType parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)
static char * get_fname(JsonLexContext *lex)
static char pop_prediction(JsonParserStack *pstack)
static JsonParseErrorType parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)
#define jsonapi_termStringInfo(s)
#define jsonapi_appendBinaryStringInfo
static char JSON_PROD_SCALAR_FALSE[]
static bool get_fnull(JsonLexContext *lex)
JsonParseErrorType json_lex(JsonLexContext *lex)
#define jsonapi_appendStringInfoChar
static char JSON_PROD_OBJECT[]
#define jsonapi_appendStringInfo
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
JsonParseErrorType json_count_array_elements(JsonLexContext *lex, int *elements)
static JsonParseErrorType parse_array(JsonLexContext *lex, const JsonSemAction *sem)
static JsonParseErrorType parse_array_element(JsonLexContext *lex, const JsonSemAction *sem)
void freeJsonLexContext(JsonLexContext *lex)
@ JSON_NT_MORE_ARRAY_ELEMENTS
static char JSON_PROD_ARRAY[]
#define FAIL_OR_INCOMPLETE_AT_CHAR_START(code)
JsonLexContext * makeJsonLexContextIncremental(JsonLexContext *lex, int encoding, bool need_escapes)
static char JSON_PROD_SCALAR_TRUE[]
#define FAIL_AT_CHAR_END(code)
static void dec_lex_level(JsonLexContext *lex)
JsonParseErrorType(* json_struct_action)(void *state)
JsonParseErrorType(* json_aelem_action)(void *state, bool isnull)
#define JSONLEX_FREE_STRVAL
#define jsonapi_StrValType
@ JSON_EXPECTED_ARRAY_FIRST
@ JSON_UNICODE_HIGH_SURROGATE
@ JSON_EXPECTED_OBJECT_FIRST
@ JSON_UNICODE_CODE_POINT_ZERO
@ JSON_INVALID_LEXER_TYPE
@ JSON_UNICODE_ESCAPE_FORMAT
@ JSON_UNICODE_UNTRANSLATABLE
@ JSON_EXPECTED_OBJECT_NEXT
@ JSON_EXPECTED_ARRAY_NEXT
@ JSON_UNICODE_HIGH_ESCAPE
@ JSON_UNICODE_LOW_SURROGATE
JsonParseErrorType(* json_ofield_action)(void *state, char *fname, bool isnull)
#define JSONLEX_FREE_STRUCT
@ JSON_TOKEN_OBJECT_START
#define JSONLEX_CTX_OWNS_TOKENS
JsonParseErrorType(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)
bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)
const char * GetDatabaseEncodingName(void)
static bool pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem)
static bool pg_lfind8(uint8 key, uint8 *base, uint32 nelem)
static unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
#define MAX_UNICODE_EQUIVALENT_STRING
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
static bool is_utf16_surrogate_first(pg_wchar c)
static bool is_utf16_surrogate_second(pg_wchar c)
void check_stack_depth(void)
#define PQExpBufferBroken(str)
#define PQExpBufferDataBroken(buf)
char * psprintf(const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
jsonapi_StrValType partial_token
const char * prev_token_terminator
struct jsonapi_StrValType * strval
struct jsonapi_StrValType * errormsg
JsonIncrementalState * inc_state
const char * token_terminator
json_struct_action array_end
json_struct_action object_start
json_ofield_action object_field_start
json_aelem_action array_element_start
json_scalar_action scalar
json_aelem_action array_element_end
json_struct_action array_start
json_struct_action object_end
json_ofield_action object_field_end