]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix contrib/hstore to throw an error for keys or values that don't fit in its
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Mar 2009 22:05:44 +0000 (22:05 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Mar 2009 22:05:44 +0000 (22:05 +0000)
data structure, rather than silently truncating them.  Andrew Gierth

contrib/hstore/README.hstore
contrib/hstore/hstore.h
contrib/hstore/hstore_io.c
contrib/hstore/hstore_op.c

index 5fdceb1b986d4c30169a511de94e05c3b07af74e..d1b9d44d1c2a7a21d110de0fcb4f57151066ff19 100644 (file)
@@ -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.
index 20ae203416a38abbbe0a9082e9185365c8578387..776dc888920738902688b4a2238008a7374e84c3 100644 (file)
@@ -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
index e01cb4e7599fe57401bf9586336a11875b23d27a..08fc32e5099b28e3defc7f08def4d86ab911bf40 100644 (file)
@@ -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
index 971e93cf314c77ced41b12794eb71cc9ae99cf1a..03c7c67e0d711bdc22e795fb0a274978ee424fe9 100644 (file)
@@ -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;