]> granicus.if.org Git - postgresql/commitdiff
When using C-string lookup keys in a dynahash.c hash table, use strncpy()
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 18 Jun 2005 20:51:30 +0000 (20:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 18 Jun 2005 20:51:30 +0000 (20:51 +0000)
not memcpy() to copy the offered key into the hash table during HASH_ENTER.
This avoids possible core dump if the passed key is located very near the
end of memory.  Per report from Stefan Kaltenbrunner.

src/backend/utils/hash/dynahash.c
src/include/utils/hsearch.h

index 8f1af2b8fa3ef628a0f74ea12d810d640a0524ac..9555e25d3021572c9e082fc22531908071e0f1df 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.61 2005/05/29 04:23:06 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.62 2005/06/18 20:51:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,6 +167,16 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
        else
                hashp->match = memcmp;
 
+       /*
+        * Similarly, the key-copying function defaults to strncpy() or memcpy().
+        */
+       if (flags & HASH_KEYCOPY)
+               hashp->keycopy = info->keycopy;
+       else if (hashp->hash == string_hash)
+               hashp->keycopy = (HashCopyFunc) strncpy;
+       else
+               hashp->keycopy = memcpy;
+
        if (flags & HASH_ALLOC)
                hashp->alloc = info->alloc;
        else
@@ -650,7 +660,7 @@ hash_search(HTAB *hashp,
 
                        /* copy key into record */
                        currBucket->hashvalue = hashvalue;
-                       memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
+                       hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize);
 
                        /* caller is expected to fill the data field on return */
 
index 881327a3e03f2822ddafb7270223426773e1b932..5bd693063acf9cef083eab7286a0e4d11d670a39 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.37 2005/06/08 23:02:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.38 2005/06/18 20:51:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 
 /*
- * Hash and comparison functions must have these signatures.  Comparison
- * functions return zero for match, nonzero for no match.  (The comparison
- * function definition is designed to allow memcmp() and strncmp() to be
- * used directly as key comparison functions.)
+ * Hash functions must have this signature.
  */
 typedef uint32 (*HashValueFunc) (const void *key, Size keysize);
+
+/*
+ * Key comparison functions must have this signature.  Comparison functions
+ * return zero for match, nonzero for no match.  (The comparison function
+ * definition is designed to allow memcmp() and strncmp() to be used directly
+ * as key comparison functions.)
+ */
 typedef int (*HashCompareFunc) (const void *key1, const void *key2,
-                                                                                       Size keysize);
+                                                               Size keysize);
+
+/*
+ * Key copying functions must have this signature.  The return value is not
+ * used.  (The definition is set up to allow memcpy() and strncpy() to be
+ * used directly.)
+ */
+typedef void *(*HashCopyFunc) (void *dest, const void *src, Size keysize);
 
 /*
  * Space allocation function for a hashtable --- designed to match malloc().
@@ -103,6 +114,7 @@ typedef struct HTAB
        HASHSEGMENT *dir;                       /* directory of segment starts */
        HashValueFunc hash;                     /* hash function */
        HashCompareFunc match;          /* key comparison function */
+       HashCopyFunc keycopy;           /* key copying function */
        HashAllocFunc alloc;            /* memory allocator */
        MemoryContext hcxt;                     /* memory context if default allocator
                                                                 * used */
@@ -123,6 +135,7 @@ typedef struct HASHCTL
        Size            entrysize;              /* total user element size in bytes */
        HashValueFunc hash;                     /* hash function */
        HashCompareFunc match;          /* key comparison function */
+       HashCopyFunc keycopy;           /* key copying function */
        HashAllocFunc alloc;            /* memory allocator */
        HASHSEGMENT *dir;                       /* directory of segment starts */
        HASHHDR    *hctl;                       /* location of header in shared mem */
@@ -140,6 +153,7 @@ typedef struct HASHCTL
 #define HASH_ALLOC             0x100   /* Set memory allocator */
 #define HASH_CONTEXT   0x200   /* Set explicit memory context */
 #define HASH_COMPARE   0x400   /* Set user defined comparison function */
+#define HASH_KEYCOPY   0x800   /* Set user defined key-copying function */
 
 
 /* max_dsize value to indicate expansible directory */