mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Fix contrib/hstore to throw an error for keys or values that don't fit in its
data structure, rather than silently truncating them. Andrew Gierth
This commit is contained in:
parent
7e23229904
commit
98686e1ea1
@ -184,3 +184,7 @@ select key, count(*) from (select (each(h)).key from testhstore) as stat group b
|
||||
title | 190
|
||||
org | 189
|
||||
...................
|
||||
|
||||
In the current implementation, neither the key nor the value
|
||||
string can exceed 65535 bytes in length; an error will be thrown if this
|
||||
limit is exceeded. These maximum lengths may change in future releases.
|
||||
|
@ -20,6 +20,11 @@ typedef struct
|
||||
pos:31;
|
||||
} HEntry;
|
||||
|
||||
/* these are determined by the sizes of the keylen and vallen fields */
|
||||
/* in struct HEntry and struct Pairs */
|
||||
#define HSTORE_MAX_KEY_LEN 65535
|
||||
#define HSTORE_MAX_VALUE_LEN 65535
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -49,4 +54,7 @@ typedef struct
|
||||
int comparePairs(const void *a, const void *b);
|
||||
int uniquePairs(Pairs * a, int4 l, int4 *buflen);
|
||||
|
||||
size_t hstoreCheckKeyLen(size_t len);
|
||||
size_t hstoreCheckValLen(size_t len);
|
||||
|
||||
#endif
|
||||
|
@ -182,7 +182,7 @@ parse_hstore(HSParser * state)
|
||||
state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen);
|
||||
}
|
||||
state->pairs[state->pcur].key = state->word;
|
||||
state->pairs[state->pcur].keylen = state->cur - state->word;
|
||||
state->pairs[state->pcur].keylen = hstoreCheckKeyLen(state->cur - state->word);
|
||||
state->pairs[state->pcur].val = NULL;
|
||||
state->word = NULL;
|
||||
st = WEQ;
|
||||
@ -222,7 +222,7 @@ parse_hstore(HSParser * state)
|
||||
if (!get_val(state, true, &escaped))
|
||||
elog(ERROR, "Unexpected end of string");
|
||||
state->pairs[state->pcur].val = state->word;
|
||||
state->pairs[state->pcur].vallen = state->cur - state->word;
|
||||
state->pairs[state->pcur].vallen = hstoreCheckValLen(state->cur - state->word);
|
||||
state->pairs[state->pcur].isnull = false;
|
||||
state->pairs[state->pcur].needfree = true;
|
||||
if (state->cur - state->word == 4 && !escaped)
|
||||
@ -341,6 +341,27 @@ freeHSParse(HSParser * state)
|
||||
pfree(state->pairs);
|
||||
}
|
||||
|
||||
size_t
|
||||
hstoreCheckKeyLen(size_t len)
|
||||
{
|
||||
if (len > HSTORE_MAX_KEY_LEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("string too long for hstore key")));
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t
|
||||
hstoreCheckValLen(size_t len)
|
||||
{
|
||||
if (len > HSTORE_MAX_VALUE_LEN)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("string too long for hstore value")));
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(hstore_in);
|
||||
Datum hstore_in(PG_FUNCTION_ARGS);
|
||||
Datum
|
||||
|
@ -280,8 +280,8 @@ tconvert(PG_FUNCTION_ARGS)
|
||||
out->len = len;
|
||||
out->size = 1;
|
||||
|
||||
ARRPTR(out)->keylen = VARSIZE(key) - VARHDRSZ;
|
||||
ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ;
|
||||
ARRPTR(out)->keylen = hstoreCheckKeyLen(VARSIZE(key) - VARHDRSZ);
|
||||
ARRPTR(out)->vallen = hstoreCheckValLen(VARSIZE(val) - VARHDRSZ);
|
||||
ARRPTR(out)->valisnull = false;
|
||||
ARRPTR(out)->pos = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user