*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.94 2008/01/01 19:45:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.95 2008/04/11 22:54:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parse_type.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Datum
stringTypeDatum(Type tp, char *string, int32 atttypmod)
{
- Oid typinput;
- Oid typioparam;
+ Form_pg_type typform = (Form_pg_type) GETSTRUCT(tp);
+ Oid typinput = typform->typinput;
+ Oid typioparam = getTypeIOParam(tp);
+ Datum result;
- typinput = ((Form_pg_type) GETSTRUCT(tp))->typinput;
- typioparam = getTypeIOParam(tp);
- return OidInputFunctionCall(typinput, string,
- typioparam, atttypmod);
+ result = OidInputFunctionCall(typinput, string,
+ typioparam, atttypmod);
+
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /*
+ * For pass-by-reference data types, repeat the conversion to see if the
+ * input function leaves any uninitialized bytes in the result. We can
+ * only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is enabled,
+ * so we don't bother testing otherwise. The reason we don't want any
+ * instability in the input function is that comparison of Const nodes
+ * relies on bytewise comparison of the datums, so if the input function
+ * leaves garbage then subexpressions that should be identical may not get
+ * recognized as such. See pgsql-hackers discussion of 2008-04-04.
+ */
+ if (string && !typform->typbyval)
+ {
+ Datum result2;
+
+ result2 = OidInputFunctionCall(typinput, string,
+ typioparam, atttypmod);
+ if (!datumIsEqual(result, result2, typform->typbyval, typform->typlen))
+ elog(WARNING, "type %s has unstable input conversion for \"%s\"",
+ NameStr(typform->typname), string);
+ }
+#endif
+
+ return result;
}
/* given a typeid, return the type's typrelid (associated relation, if any) */
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.76 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.77 2008/04/11 22:54:23 tgl Exp $
*
* NOTE:
* This is a new (Feb. 05, 1999) implementation of the allocation set
return idx;
}
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+
+/*
+ * Fill a just-allocated piece of memory with "random" data. It's not really
+ * very random, just a repeating sequence with a length that's prime. What
+ * we mainly want out of it is to have a good probability that two palloc's
+ * of the same number of bytes start out containing different data.
+ */
+static void
+randomize_mem(char *ptr, size_t size)
+{
+ static int save_ctr = 1;
+ int ctr;
+
+ ctr = save_ctr;
+ while (size-- > 0)
+ {
+ *ptr++ = ctr;
+ if (++ctr > 251)
+ ctr = 1;
+ }
+ save_ctr = ctr;
+}
+
+#endif /* RANDOMIZE_ALLOCATED_MEMORY */
+
/*
* Public routines
if (size < chunk_size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /* fill the allocated space with junk */
+ randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
/*
* Stick the new block underneath the active allocation block, so that
if (size < chunk->size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /* fill the allocated space with junk */
+ randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
/* isReset must be false already */
Assert(!set->isReset);
if (size < chunk->size)
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
#endif
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /* fill the allocated space with junk */
+ randomize_mem((char *) AllocChunkGetPointer(chunk), size);
+#endif
set->isReset = false;
if (oldsize >= size)
{
#ifdef MEMORY_CONTEXT_CHECKING
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /* We can only fill the extra space if we know the prior request */
+ if (size > chunk->requested_size)
+ randomize_mem((char *) AllocChunkGetPointer(chunk) + chunk->requested_size,
+ size - chunk->requested_size);
+#endif
+
chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */
if (size < oldsize)
chunk->size = chksize;
#ifdef MEMORY_CONTEXT_CHECKING
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+ /* We can only fill the extra space if we know the prior request */
+ randomize_mem((char *) AllocChunkGetPointer(chunk) + chunk->requested_size,
+ size - chunk->requested_size);
+#endif
+
chunk->requested_size = size;
/* set mark to catch clobber of "unused" space */
if (size < chunk->size)
* for developers. If you edit any of these, be sure to do a *full*
* rebuild (and an initdb if noted).
*
- * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.30 2008/03/27 03:57:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/pg_config_manual.h,v 1.31 2008/04/11 22:54:23 tgl Exp $
*------------------------------------------------------------------------
*/
*------------------------------------------------------------------------
*/
+/*
+ * Define this to cause palloc()'d memory to be filled with random data, to
+ * facilitate catching code that depends on the contents of uninitialized
+ * memory. Right now, this gets defined automatically if --enable-cassert.
+ */
+#ifdef USE_ASSERT_CHECKING
+#define RANDOMIZE_ALLOCATED_MEMORY
+#endif
+
/*
* Define this to cause pfree()'d memory to be cleared immediately, to
- * facilitate catching bugs that refer to already-freed values. XXX
- * Right now, this gets defined automatically if --enable-cassert. In
- * the long term it probably doesn't need to be on by default.
+ * facilitate catching bugs that refer to already-freed values.
+ * Right now, this gets defined automatically if --enable-cassert.
*/
#ifdef USE_ASSERT_CHECKING
#define CLOBBER_FREED_MEMORY
/*
* Define this to check memory allocation errors (scribbling on more
* bytes than were allocated). Right now, this gets defined
- * automatically if --enable-cassert. In the long term it probably
- * doesn't need to be on by default.
+ * automatically if --enable-cassert.
*/
#ifdef USE_ASSERT_CHECKING
#define MEMORY_CONTEXT_CHECKING