v9-0006-Add-safe-input-function-for-jsonb.patch
text/x-patch
Filename: v9-0006-Add-safe-input-function-for-jsonb.patch
Type: text/x-patch
Part: 5
Message:
Re: SQL/JSON features for v15
Patch
Format: format-patch
Series: patch v9-0006
Subject: Add safe input function for jsonb
| File | + | − |
|---|---|---|
| src/backend/utils/adt/jsonb.c | 18 | 8 |
| src/include/utils/jsonb.h | 2 | 0 |
From 62a27e0b243cebc5e3eb8628cbb222533a02338f Mon Sep 17 00:00:00 2001
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
Date: Mon, 29 Aug 2022 23:56:45 +0300
Subject: [PATCH v9 6/9] Add safe input function for jsonb
---
src/backend/utils/adt/jsonb.c | 26 ++++++++++++++++++--------
src/include/utils/jsonb.h | 2 ++
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index f700c5b4c93..1da519daaef 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -46,7 +46,6 @@ typedef struct JsonbAggState
Oid val_output_func;
} JsonbAggState;
-static inline Datum jsonb_from_cstring(char *json, int len, bool unique_keys);
static size_t checkStringLen(size_t len);
static void jsonb_in_object_start(void *pstate);
static void jsonb_in_object_end(void *pstate);
@@ -77,7 +76,7 @@ jsonb_in(PG_FUNCTION_ARGS)
{
char *json = PG_GETARG_CSTRING(0);
- return jsonb_from_cstring(json, strlen(json), false);
+ PG_RETURN_DATUM(jsonb_from_cstring(json, strlen(json), false, NULL));
}
/*
@@ -101,7 +100,7 @@ jsonb_recv(PG_FUNCTION_ARGS)
else
elog(ERROR, "unsupported jsonb version number %d", version);
- return jsonb_from_cstring(str, nbytes, false);
+ return jsonb_from_cstring(str, nbytes, false, NULL);
}
/*
@@ -147,7 +146,7 @@ jsonb_from_text(text *js, bool unique_keys)
{
return jsonb_from_cstring(VARDATA_ANY(js),
VARSIZE_ANY_EXHDR(js),
- unique_keys);
+ unique_keys, NULL);
}
/*
@@ -239,12 +238,13 @@ jsonb_typeof(PG_FUNCTION_ARGS)
*
* Uses the json parser (with hooks) to construct a jsonb.
*/
-static inline Datum
-jsonb_from_cstring(char *json, int len, bool unique_keys)
+Datum
+jsonb_from_cstring(char *json, int len, bool unique_keys, bool *error)
{
JsonLexContext *lex;
JsonbInState state;
JsonSemAction sem;
+ JsonParseErrorType result;
memset(&state, 0, sizeof(state));
memset(&sem, 0, sizeof(sem));
@@ -261,10 +261,20 @@ jsonb_from_cstring(char *json, int len, bool unique_keys)
sem.scalar = jsonb_in_scalar;
sem.object_field_start = jsonb_in_object_field_start;
- pg_parse_json_or_ereport(lex, &sem);
+ result = pg_parse_json(lex, &sem);
+ if (result != JSON_SUCCESS)
+ {
+ if (error)
+ {
+ *error = true;
+ return (Datum) 0;
+ }
+
+ json_ereport_error(result, lex);
+ }
/* after parsing, the item member has the composed jsonb structure */
- PG_RETURN_POINTER(JsonbValueToJsonb(state.res));
+ return JsonbPGetDatum(JsonbValueToJsonb(state.res));
}
static size_t
diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index bae466b5234..d5574faa79e 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -420,6 +420,8 @@ extern void JsonbHashScalarValueExtended(const JsonbValue *scalarVal,
/* jsonb.c support functions */
extern Datum jsonb_from_text(text *js, bool unique_keys);
+extern Datum jsonb_from_cstring(char *json, int len, bool unique_keys,
+ bool *error);
extern char *JsonbToCString(StringInfo out, JsonbContainer *in,
int estimated_len);
extern char *JsonbToCStringIndent(StringInfo out, JsonbContainer *in,
--
2.17.1