aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/json.c')
-rw-r--r--src/backend/utils/adt/json.c49
1 files changed, 15 insertions, 34 deletions
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 3c137ead1d0..951b6554007 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -806,14 +806,17 @@ json_lex_string(JsonLexContext *lex)
* For UTF8, replace the escape sequence by the actual
* utf8 character in lex->strval. Do this also for other
* encodings if the escape designates an ASCII character,
- * otherwise raise an error. We don't ever unescape a
- * \u0000, since that would result in an impermissible nul
- * byte.
+ * otherwise raise an error.
*/
if (ch == 0)
{
- appendStringInfoString(lex->strval, "\\u0000");
+ /* We can't allow this, since our TEXT type doesn't */
+ ereport(ERROR,
+ (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
+ errmsg("unsupported Unicode escape sequence"),
+ errdetail("\\u0000 cannot be converted to text."),
+ report_json_context(lex)));
}
else if (GetDatabaseEncoding() == PG_UTF8)
{
@@ -833,8 +836,8 @@ json_lex_string(JsonLexContext *lex)
else
{
ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type json"),
+ (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
+ errmsg("unsupported Unicode escape sequence"),
errdetail("Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8."),
report_json_context(lex)));
}
@@ -1284,8 +1287,8 @@ json_categorize_type(Oid typoid,
/*
* We need to get the output function for everything except date and
- * timestamp types, array and composite types, booleans,
- * and non-builtin types where there's a cast to json.
+ * timestamp types, array and composite types, booleans, and non-builtin
+ * types where there's a cast to json.
*/
switch (typoid)
@@ -1335,11 +1338,12 @@ json_categorize_type(Oid typoid,
/* but let's look for a cast to json, if it's not built-in */
if (typoid >= FirstNormalObjectId)
{
- Oid castfunc;
+ Oid castfunc;
CoercionPathType ctype;
ctype = find_coercion_pathway(JSONOID, typoid,
- COERCION_EXPLICIT, &castfunc);
+ COERCION_EXPLICIT,
+ &castfunc);
if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
{
*tcategory = JSONTYPE_CAST;
@@ -2382,30 +2386,7 @@ escape_json(StringInfo buf, const char *str)
appendStringInfoString(buf, "\\\"");
break;
case '\\':
-
- /*
- * Unicode escapes are passed through as is. There is no
- * requirement that they denote a valid character in the
- * server encoding - indeed that is a big part of their
- * usefulness.
- *
- * All we require is that they consist of \uXXXX where the Xs
- * are hexadecimal digits. It is the responsibility of the
- * caller of, say, to_json() to make sure that the unicode
- * escape is valid.
- *
- * In the case of a jsonb string value being escaped, the only
- * unicode escape that should be present is \u0000, all the
- * other unicode escapes will have been resolved.
- */
- if (p[1] == 'u' &&
- isxdigit((unsigned char) p[2]) &&
- isxdigit((unsigned char) p[3]) &&
- isxdigit((unsigned char) p[4]) &&
- isxdigit((unsigned char) p[5]))
- appendStringInfoCharMacro(buf, *p);
- else
- appendStringInfoString(buf, "\\\\");
+ appendStringInfoString(buf, "\\\\");
break;
default:
if ((unsigned char) *p < ' ')