summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-10-28 20:49:38 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2013-10-28 20:49:38 -0400
commitaad45bd54b098c14bd5670ec0043a332ee4c7020 (patch)
tree48c3c7754fc416e41036fc6a2d7729e3e634ccd1
parent42ef7c87bfba63988049735e8e74eafd53d7a03e (diff)
Prevent using strncpy with src == dest in TupleDescInitEntry.
The C and POSIX standards state that strncpy's behavior is undefined when source and destination areas overlap. While it remains dubious whether any implementations really misbehave when the pointers are exactly equal, some platforms are now starting to force the issue by complaining when an undefined call occurs. (In particular OS X 10.9 has been seen to dump core here, though the exact set of circumstances needed to trigger that remain elusive. Similar behavior can be expected to be optional on Linux and other platforms in the near future.) So tweak the code to explicitly do nothing when nothing need be done. Back-patch to all active branches. In HEAD, this also lets us get rid of an exception in valgrind.supp. Per discussion of a report from Matthias Schmitt.
-rw-r--r--src/backend/access/common/tupdesc.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 2125fdfb0bd..2910f4c8474 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -427,6 +427,12 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
* TupleDescInitEntry
* This function initializes a single attribute structure in
* a previously allocated tuple descriptor.
+ *
+ * If attributeName is NULL, the attname field is set to an empty string
+ * (this is for cases where we don't know or need a name for the field).
+ * Also, some callers use this function to change the datatype-related fields
+ * in an existing tupdesc; they pass attributeName = NameStr(att->attname)
+ * to indicate that the attname field shouldn't be modified.
*/
void
TupleDescInitEntry(TupleDesc desc,
@@ -457,12 +463,12 @@ TupleDescInitEntry(TupleDesc desc,
/*
* Note: attributeName can be NULL, because the planner doesn't always
* fill in valid resname values in targetlists, particularly for resjunk
- * attributes.
+ * attributes. Also, do nothing if caller wants to re-use the old attname.
*/
- if (attributeName != NULL)
- namestrcpy(&(att->attname), attributeName);
- else
+ if (attributeName == NULL)
MemSet(NameStr(att->attname), 0, NAMEDATALEN);
+ else if (attributeName != NameStr(att->attname))
+ namestrcpy(&(att->attname), attributeName);
att->attstattarget = -1;
att->attcacheoff = -1;