1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-08 06:02:22 +03:00

hstore: Tighten key/value parsing check for whitespaces

isspace() can be locale-sensitive depending on the platform, causing
hstore to consider as whitespaces characters it should not see as such.
For example, U+0105, being decoded as 0xC4 0x85 in UTF-8, would be
discarded from the input given.

This problem is similar to 9ae2661, though it was missed that hstore
can also manipulate non-ASCII inputs, so replace the existing isspace()
calls with scanner_isspace().

This problem exists for a long time, so backpatch all the way down.

Author: Evan Jones
Discussion: https://postgr.es/m/CA+HWA9awUW0+RV_gO9r1ABZwGoZxPztcJxPy8vMFSTbTfi4jig@mail.gmail.com
Backpatch-through: 11
This commit is contained in:
Michael Paquier
2023-06-12 09:14:17 +09:00
parent 37236ca069
commit 78bf0a256d
5 changed files with 69 additions and 5 deletions

View File

@@ -12,6 +12,7 @@
#include "hstore.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "parser/scansup.h"
#include "utils/builtins.h"
#include "utils/json.h"
#include "utils/jsonb.h"
@@ -86,7 +87,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
{
st = GV_WAITESCIN;
}
else if (!isspace((unsigned char) *(state->ptr)))
else if (!scanner_isspace((unsigned char) *(state->ptr)))
{
*(state->cur) = *(state->ptr);
state->cur++;
@@ -109,7 +110,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
state->ptr--;
return true;
}
else if (isspace((unsigned char) *(state->ptr)))
else if (scanner_isspace((unsigned char) *(state->ptr)))
{
return true;
}
@@ -217,7 +218,7 @@ parse_hstore(HSParser *state)
{
elog(ERROR, "Unexpected end of string");
}
else if (!isspace((unsigned char) *(state->ptr)))
else if (!scanner_isspace((unsigned char) *(state->ptr)))
{
elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
}
@@ -265,7 +266,7 @@ parse_hstore(HSParser *state)
{
return;
}
else if (!isspace((unsigned char) *(state->ptr)))
else if (!scanner_isspace((unsigned char) *(state->ptr)))
{
elog(ERROR, "Syntax error near '%c' at position %d", *(state->ptr), (int32) (state->ptr - state->begin));
}