aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/hstore/README.hstore4
-rw-r--r--contrib/hstore/hstore.h8
-rw-r--r--contrib/hstore/hstore_io.c25
-rw-r--r--contrib/hstore/hstore_op.c4
4 files changed, 37 insertions, 4 deletions
diff --git a/contrib/hstore/README.hstore b/contrib/hstore/README.hstore
index 5fdceb1b986..d1b9d44d1c2 100644
--- a/contrib/hstore/README.hstore
+++ b/contrib/hstore/README.hstore
@@ -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.
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
index 20ae203416a..776dc888920 100644
--- a/contrib/hstore/hstore.h
+++ b/contrib/hstore/hstore.h
@@ -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
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index e01cb4e7599..08fc32e5099 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -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
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index 971e93cf314..03c7c67e0d7 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -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;