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

Commit1c99cde

Browse files
committed
Improve JsonLexContext's freeability
Previously, the JSON code didn't have to worry too much about freeingJsonLexContext, because it was never too long-lived. With new featuresbeing added for SQL/JSON this is no longer the case. Add a routinethat knows how to free this struct and apply that to a few places, toprevent this from becoming problematic.At the same time, we change the API of makeJsonLexContextCstringLen tomake it receive a pointer to JsonLexContext for callers that want it tobe stack-allocated; it can also be passed as NULL to get the originalbehavior of a palloc'ed one.This also causes an ABI break due to the addition of flags toJsonLexContext, so we can't easily backpatch it. AFAICS that's not muchof a problem; apparently some leaks might exist in JSON usage oftext-search, for example via json_to_tsvector, but I haven't seen anycomplaints about that.Per Coverity complaint about datum_to_jsonb_internal().Discussion:https://postgr.es/m/20230808174110.oq3iymllsv6amkih@alvherre.pgsql
1 parenta8a968a commit1c99cde

File tree

7 files changed

+153
-86
lines changed

7 files changed

+153
-86
lines changed

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

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ json_in(PG_FUNCTION_ARGS)
106106
{
107107
char*json=PG_GETARG_CSTRING(0);
108108
text*result=cstring_to_text(json);
109-
JsonLexContext*lex;
109+
JsonLexContextlex;
110110

111111
/* validate it */
112-
lex=makeJsonLexContext(result, false);
113-
if (!pg_parse_json_or_errsave(lex,&nullSemAction,fcinfo->context))
112+
makeJsonLexContext(&lex,result, false);
113+
if (!pg_parse_json_or_errsave(&lex,&nullSemAction,fcinfo->context))
114114
PG_RETURN_NULL();
115115

116116
/* Internal representation is the same as text */
@@ -152,13 +152,14 @@ json_recv(PG_FUNCTION_ARGS)
152152
StringInfobuf= (StringInfo)PG_GETARG_POINTER(0);
153153
char*str;
154154
intnbytes;
155-
JsonLexContext*lex;
155+
JsonLexContextlex;
156156

157157
str=pq_getmsgtext(buf,buf->len-buf->cursor,&nbytes);
158158

159159
/* Validate it. */
160-
lex=makeJsonLexContextCstringLen(str,nbytes,GetDatabaseEncoding(), false);
161-
pg_parse_json_or_ereport(lex,&nullSemAction);
160+
makeJsonLexContextCstringLen(&lex,str,nbytes,GetDatabaseEncoding(),
161+
false);
162+
pg_parse_json_or_ereport(&lex,&nullSemAction);
162163

163164
PG_RETURN_TEXT_P(cstring_to_text_with_len(str,nbytes));
164165
}
@@ -1625,14 +1626,16 @@ json_unique_object_field_start(void *_state, char *field, bool isnull)
16251626
bool
16261627
json_validate(text*json,boolcheck_unique_keys,boolthrow_error)
16271628
{
1628-
JsonLexContext*lex=makeJsonLexContext(json,check_unique_keys);
1629+
JsonLexContextlex;
16291630
JsonSemActionuniqueSemAction= {0};
16301631
JsonUniqueParsingStatestate;
16311632
JsonParseErrorTyperesult;
16321633

1634+
makeJsonLexContext(&lex,json,check_unique_keys);
1635+
16331636
if (check_unique_keys)
16341637
{
1635-
state.lex=lex;
1638+
state.lex=&lex;
16361639
state.stack=NULL;
16371640
state.id_counter=0;
16381641
state.unique= true;
@@ -1644,12 +1647,12 @@ json_validate(text *json, bool check_unique_keys, bool throw_error)
16441647
uniqueSemAction.object_end=json_unique_object_end;
16451648
}
16461649

1647-
result=pg_parse_json(lex,check_unique_keys ?&uniqueSemAction :&nullSemAction);
1650+
result=pg_parse_json(&lex,check_unique_keys ?&uniqueSemAction :&nullSemAction);
16481651

16491652
if (result!=JSON_SUCCESS)
16501653
{
16511654
if (throw_error)
1652-
json_errsave_error(result,lex,NULL);
1655+
json_errsave_error(result,&lex,NULL);
16531656

16541657
return false;/* invalid json */
16551658
}
@@ -1664,6 +1667,9 @@ json_validate(text *json, bool check_unique_keys, bool throw_error)
16641667
return false;/* not unique keys */
16651668
}
16661669

1670+
if (check_unique_keys)
1671+
freeJsonLexContext(&lex);
1672+
16671673
return true;/* ok */
16681674
}
16691675

@@ -1683,18 +1689,17 @@ Datum
16831689
json_typeof(PG_FUNCTION_ARGS)
16841690
{
16851691
text*json=PG_GETARG_TEXT_PP(0);
1686-
JsonLexContext*lex=makeJsonLexContext(json, false);
1692+
JsonLexContextlex;
16871693
char*type;
1688-
JsonTokenTypetok;
16891694
JsonParseErrorTyperesult;
16901695

16911696
/* Lex exactly one token from the input and check its type. */
1692-
result=json_lex(lex);
1697+
makeJsonLexContext(&lex,json, false);
1698+
result=json_lex(&lex);
16931699
if (result!=JSON_SUCCESS)
1694-
json_errsave_error(result,lex,NULL);
1695-
tok=lex->token_type;
1700+
json_errsave_error(result,&lex,NULL);
16961701

1697-
switch (tok)
1702+
switch (lex.token_type)
16981703
{
16991704
caseJSON_TOKEN_OBJECT_START:
17001705
type="object";
@@ -1716,7 +1721,7 @@ json_typeof(PG_FUNCTION_ARGS)
17161721
type="null";
17171722
break;
17181723
default:
1719-
elog(ERROR,"unexpected json token: %d",tok);
1724+
elog(ERROR,"unexpected json token: %d",lex.token_type);
17201725
}
17211726

17221727
PG_RETURN_TEXT_P(cstring_to_text(type));

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,13 @@ jsonb_typeof(PG_FUNCTION_ARGS)
252252
staticinlineDatum
253253
jsonb_from_cstring(char*json,intlen,boolunique_keys,Node*escontext)
254254
{
255-
JsonLexContext*lex;
255+
JsonLexContextlex;
256256
JsonbInStatestate;
257257
JsonSemActionsem;
258258

259259
memset(&state,0,sizeof(state));
260260
memset(&sem,0,sizeof(sem));
261-
lex=makeJsonLexContextCstringLen(json,len,GetDatabaseEncoding(), true);
261+
makeJsonLexContextCstringLen(&lex,json,len,GetDatabaseEncoding(), true);
262262

263263
state.unique_keys=unique_keys;
264264
state.escontext=escontext;
@@ -271,7 +271,7 @@ jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
271271
sem.scalar=jsonb_in_scalar;
272272
sem.object_field_start=jsonb_in_object_field_start;
273273

274-
if (!pg_parse_json_or_errsave(lex,&sem,escontext))
274+
if (!pg_parse_json_or_errsave(&lex,&sem,escontext))
275275
return (Datum)0;
276276

277277
/* after parsing, the item member has the composed jsonb structure */
@@ -755,11 +755,11 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
755755
caseJSONTYPE_JSON:
756756
{
757757
/* parse the json right into the existing result object */
758-
JsonLexContext*lex;
758+
JsonLexContextlex;
759759
JsonSemActionsem;
760760
text*json=DatumGetTextPP(val);
761761

762-
lex=makeJsonLexContext(json, true);
762+
makeJsonLexContext(&lex,json, true);
763763

764764
memset(&sem,0,sizeof(sem));
765765

@@ -772,7 +772,8 @@ datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
772772
sem.scalar=jsonb_in_scalar;
773773
sem.object_field_start=jsonb_in_object_field_start;
774774

775-
pg_parse_json_or_ereport(lex,&sem);
775+
pg_parse_json_or_ereport(&lex,&sem);
776+
freeJsonLexContext(&lex);
776777
}
777778
break;
778779
caseJSONTYPE_JSONB:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp