diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-10-11 18:40:53 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-10-11 18:40:53 -0400 |
commit | 8c8ba6d11b06e5a8b9fe5653a1cd17c437af5f7b (patch) | |
tree | c3a34c5dbafbba2e3e8fcee0482e7cfeaff849bb /src/backend/access/nbtree/nbtree.c | |
parent | cb6771fb32cbdb11c8d84b7d62ee940bdba38d52 (diff) | |
download | postgresql-8c8ba6d11b06e5a8b9fe5653a1cd17c437af5f7b.tar.gz postgresql-8c8ba6d11b06e5a8b9fe5653a1cd17c437af5f7b.zip |
Add comment on why pulling data from a "name" index column can't crash.
It's been bothering me for several days that pretending that the cstring
data stored in a btree name_ops column is really a "name" Datum could lead
to reading past the end of memory. However, given the current memory
layout used for index-only scans in the btree code, a crash is in fact not
possible. Document that so we don't break it. I have not thought of any
other solutions that aren't fairly ugly too, and most of them lose the
functionality of index-only scans on name columns altogether, so this seems
like the way to go.
Diffstat (limited to 'src/backend/access/nbtree/nbtree.c')
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 80e703b1906..3401bc5bdb2 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -433,6 +433,16 @@ btrescan(PG_FUNCTION_ARGS) * not already done in a previous rescan call. To save on palloc * overhead, both workspaces are allocated as one palloc block; only this * function and btendscan know that. + * + * NOTE: this data structure also makes it safe to return data from a + * "name" column, even though btree name_ops uses an underlying storage + * datatype of cstring. The risk there is that "name" is supposed to be + * padded to NAMEDATALEN, but the actual index tuple is probably shorter. + * However, since we only return data out of tuples sitting in the + * currTuples array, a fetch of NAMEDATALEN bytes can at worst pull some + * data out of the markTuples array --- running off the end of memory for + * a SIGSEGV is not possible. Yeah, this is ugly as sin, but it beats + * adding special-case treatment for name_ops elsewhere. */ if (scan->xs_want_itup && so->currTuples == NULL) { |