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

Commit29dcf7d

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 parenta133bf7 commit29dcf7d

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

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

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ typedef enum/* contexts of JSON parser */
5050

5151
staticinlinevoidjson_lex(JsonLexContext*lex);
5252
staticinlinevoidjson_lex_string(JsonLexContext*lex);
53-
staticinlinevoidjson_lex_number(JsonLexContext*lex,char*s);
53+
staticinlinevoidjson_lex_number(JsonLexContext*lex,char*s,bool*num_err);
5454
staticinlinevoidparse_scalar(JsonLexContext*lex,JsonSemAction*sem);
5555
staticvoidparse_object_field(JsonLexContext*lex,JsonSemAction*sem);
5656
staticvoidparse_object(JsonLexContext*lex,JsonSemAction*sem);
@@ -147,8 +147,6 @@ lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
147147
#defineTYPCATEGORY_JSON 'j'
148148
/* fake category for types that have a cast to json */
149149
#defineTYPCATEGORY_JSON_CAST 'c'
150-
/* letters appearing in numeric output that aren't valid in a JSON number */
151-
#defineNON_NUMERIC_LETTER "NnAaIiFfTtYy"
152150
/* chars to consider as part of an alphanumeric token */
153151
#defineJSON_ALPHANUMERIC_CHAR(c) \
154152
(((c) >= 'a' && (c) <= 'z') || \
@@ -567,7 +565,7 @@ json_lex(JsonLexContext *lex)
567565
break;
568566
case'-':
569567
/* Negative number. */
570-
json_lex_number(lex,s+1);
568+
json_lex_number(lex,s+1,NULL);
571569
lex->token_type=JSON_TOKEN_NUMBER;
572570
break;
573571
case'0':
@@ -581,7 +579,7 @@ json_lex(JsonLexContext *lex)
581579
case'8':
582580
case'9':
583581
/* Positive number. */
584-
json_lex_number(lex,s);
582+
json_lex_number(lex,s,NULL);
585583
lex->token_type=JSON_TOKEN_NUMBER;
586584
break;
587585
default:
@@ -903,7 +901,7 @@ json_lex_string(JsonLexContext *lex)
903901
*-------------------------------------------------------------------------
904902
*/
905903
staticinlinevoid
906-
json_lex_number(JsonLexContext*lex,char*s)
904+
json_lex_number(JsonLexContext*lex,char*s,bool*num_err)
907905
{
908906
boolerror= false;
909907
char*p;
@@ -976,10 +974,19 @@ json_lex_number(JsonLexContext *lex, char *s)
976974
*/
977975
for (p=s;len<lex->input_length&&JSON_ALPHANUMERIC_CHAR(*p);p++,len++)
978976
error= true;
979-
lex->prev_token_terminator=lex->token_terminator;
980-
lex->token_terminator=p;
981-
if (error)
982-
report_invalid_token(lex);
977+
978+
if (num_err!=NULL)
979+
{
980+
/* let the caller handle the error */
981+
*num_err=error;
982+
}
983+
else
984+
{
985+
lex->prev_token_terminator=lex->token_terminator;
986+
lex->token_terminator=p;
987+
if (error)
988+
report_invalid_token(lex);
989+
}
983990
}
984991

985992
/*
@@ -1214,6 +1221,8 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
12141221
{
12151222
char*outputstr;
12161223
text*jsontext;
1224+
boolnumeric_error;
1225+
JsonLexContextdummy_lex;
12171226

12181227
if (is_null)
12191228
{
@@ -1237,14 +1246,13 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
12371246
break;
12381247
caseTYPCATEGORY_NUMERIC:
12391248
outputstr=OidOutputFunctionCall(typoutputfunc,val);
1240-
12411249
/*
12421250
* Don't call escape_json here if it's a valid JSON number.
1243-
* Numeric output should usually be a valid JSON number and JSON
1244-
* numbers shouldn't be quoted. Quote cases like "Nan" and
1245-
* "Infinity", however.
12461251
*/
1247-
if (strpbrk(outputstr,NON_NUMERIC_LETTER)==NULL)
1252+
dummy_lex.input=*outputstr=='-' ?outputstr+1 :outputstr;
1253+
dummy_lex.input_length=strlen(dummy_lex.input);
1254+
json_lex_number(&dummy_lex,dummy_lex.input,&numeric_error);
1255+
if (!numeric_error)
12481256
appendStringInfoString(result,outputstr);
12491257
else
12501258
escape_json(result,outputstr);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp