Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4825a9e

Browse files
committed
Properly detect invalid JSON numbers when generating JSON.
Instead of looking for characters that aren't valid in JSON numbers, wesimply pass the output string through the JSON number parser, and if itfails the string is quoted. This means among other things that money anddomains over money will be quoted correctly and generate valid JSON.Fixes bug #8676 reported by Anderson Cristian da Silva.Backpatched to 9.2 where JSON generation was introduced.
1 parent150a30e commit4825a9e

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

‎src/backend/utils/adt/json.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ typedef enum/* required operations on state stack */
7373
staticvoidjson_validate_cstring(char*input);
7474
staticvoidjson_lex(JsonLexContext*lex);
7575
staticvoidjson_lex_string(JsonLexContext*lex);
76-
staticvoidjson_lex_number(JsonLexContext*lex,char*s);
76+
staticvoidjson_lex_number(JsonLexContext*lex,char*s,bool*num_err);
7777
staticvoidreport_parse_error(JsonParseStack*stack,JsonLexContext*lex);
7878
staticvoidreport_invalid_token(JsonLexContext*lex);
7979
staticintreport_json_context(JsonLexContext*lex);
@@ -89,8 +89,6 @@ static void array_to_json_internal(Datum array, StringInfo result,
8989

9090
/* fake type category for JSON so we can distinguish it in datum_to_json */
9191
#defineTYPCATEGORY_JSON 'j'
92-
/* letters appearing in numeric output that aren't valid in a JSON number */
93-
#defineNON_NUMERIC_LETTER "NnAaIiFfTtYy"
9492
/* chars to consider as part of an alphanumeric token */
9593
#defineJSON_ALPHANUMERIC_CHAR(c) \
9694
(((c) >= 'a' && (c) <= 'z') || \
@@ -361,13 +359,13 @@ json_lex(JsonLexContext *lex)
361359
elseif (*s=='-')
362360
{
363361
/* Negative number. */
364-
json_lex_number(lex,s+1);
362+
json_lex_number(lex,s+1,NULL);
365363
lex->token_type=JSON_VALUE_NUMBER;
366364
}
367365
elseif (*s >='0'&&*s <='9')
368366
{
369367
/* Positive number. */
370-
json_lex_number(lex,s);
368+
json_lex_number(lex,s,NULL);
371369
lex->token_type=JSON_VALUE_NUMBER;
372370
}
373371
else
@@ -530,7 +528,7 @@ json_lex_string(JsonLexContext *lex)
530528
*-------------------------------------------------------------------------
531529
*/
532530
staticvoid
533-
json_lex_number(JsonLexContext*lex,char*s)
531+
json_lex_number(JsonLexContext*lex,char*s,bool*num_err)
534532
{
535533
boolerror= false;
536534
char*p;
@@ -584,15 +582,24 @@ json_lex_number(JsonLexContext *lex, char *s)
584582
}
585583

586584
/*
587-
* Check for trailing garbage.As in json_lex(), any alphanumeric stuff
585+
* Check for trailing garbage.As in json_lex(), any alphanumeric stuff
588586
* here should be considered part of the token for error-reporting
589587
* purposes.
590588
*/
591589
for (p=s;JSON_ALPHANUMERIC_CHAR(*p);p++)
592590
error= true;
593-
lex->token_terminator=p;
594-
if (error)
595-
report_invalid_token(lex);
591+
592+
if (num_err!=NULL)
593+
{
594+
/* let the caller handle the error */
595+
*num_err=error;
596+
}
597+
else
598+
{
599+
lex->token_terminator=p;
600+
if (error)
601+
report_invalid_token(lex);
602+
}
596603
}
597604

598605
/*
@@ -819,6 +826,8 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
819826
TYPCATEGORYtcategory,Oidtypoutputfunc)
820827
{
821828
char*outputstr;
829+
boolnumeric_error;
830+
JsonLexContextdummy_lex;
822831

823832
if (is_null)
824833
{
@@ -845,11 +854,10 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
845854

846855
/*
847856
* Don't call escape_json here if it's a valid JSON number.
848-
* Numeric output should usually be a valid JSON number and JSON
849-
* numbers shouldn't be quoted. Quote cases like "Nan" and
850-
* "Infinity", however.
851857
*/
852-
if (strpbrk(outputstr,NON_NUMERIC_LETTER)==NULL)
858+
dummy_lex.input=*outputstr=='-' ?outputstr+1 :outputstr;
859+
json_lex_number(&dummy_lex,dummy_lex.input,&numeric_error);
860+
if (!numeric_error)
853861
appendStringInfoString(result,outputstr);
854862
else
855863
escape_json(result,outputstr);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp