static inline void json_lex(JsonLexContext *lex);
static inline void json_lex_string(JsonLexContext *lex);
-static inline void json_lex_number(JsonLexContext *lex, char *s);
+static inline void json_lex_number(JsonLexContext *lex, char *s, bool *num_err);
static inline void parse_scalar(JsonLexContext *lex, JsonSemAction *sem);
static void parse_object_field(JsonLexContext *lex, JsonSemAction *sem);
static void parse_object(JsonLexContext *lex, JsonSemAction *sem);
#define TYPCATEGORY_JSON 'j'
/* fake category for types that have a cast to json */
#define TYPCATEGORY_JSON_CAST 'c'
-/* letters appearing in numeric output that aren't valid in a JSON number */
-#define NON_NUMERIC_LETTER "NnAaIiFfTtYy"
/* chars to consider as part of an alphanumeric token */
#define JSON_ALPHANUMERIC_CHAR(c) \
(((c) >= 'a' && (c) <= 'z') || \
break;
case '-':
/* Negative number. */
- json_lex_number(lex, s + 1);
+ json_lex_number(lex, s + 1, NULL);
lex->token_type = JSON_TOKEN_NUMBER;
break;
case '0':
case '8':
case '9':
/* Positive number. */
- json_lex_number(lex, s);
+ json_lex_number(lex, s, NULL);
lex->token_type = JSON_TOKEN_NUMBER;
break;
default:
*-------------------------------------------------------------------------
*/
static inline void
-json_lex_number(JsonLexContext *lex, char *s)
+json_lex_number(JsonLexContext *lex, char *s, bool *num_err)
{
bool error = false;
char *p;
*/
for (p = s; len < lex->input_length && JSON_ALPHANUMERIC_CHAR(*p); p++, len++)
error = true;
- lex->prev_token_terminator = lex->token_terminator;
- lex->token_terminator = p;
- if (error)
- report_invalid_token(lex);
+
+ if (num_err != NULL)
+ {
+ /* let the caller handle the error */
+ *num_err = error;
+ }
+ else
+ {
+ lex->prev_token_terminator = lex->token_terminator;
+ lex->token_terminator = p;
+ if (error)
+ report_invalid_token(lex);
+ }
}
/*
{
char *outputstr;
text *jsontext;
+ bool numeric_error;
+ JsonLexContext dummy_lex;
if (is_null)
{
break;
case TYPCATEGORY_NUMERIC:
outputstr = OidOutputFunctionCall(typoutputfunc, val);
-
/*
* Don't call escape_json here if it's a valid JSON number.
- * Numeric output should usually be a valid JSON number and JSON
- * numbers shouldn't be quoted. Quote cases like "Nan" and
- * "Infinity", however.
*/
- if (strpbrk(outputstr, NON_NUMERIC_LETTER) == NULL)
+ dummy_lex.input = *outputstr == '-' ? outputstr + 1 : outputstr;
+ dummy_lex.input_length = strlen(dummy_lex.input);
+ json_lex_number(&dummy_lex, dummy_lex.input, &numeric_error);
+ if (! numeric_error)
appendStringInfoString(result, outputstr);
else
escape_json(result, outputstr);