aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2015-07-08 20:44:21 -0400
committerNoah Misch <noah@leadboat.com>2015-07-08 20:44:25 -0400
commitaaf15ee33a63c582fbb61b67befdd620e85da2ce (patch)
tree1f24f7828c9f7b24e7fe4ff4350e29b15004a034 /src/backend/utils/adt/selfuncs.c
parent8ed6e70ace8e8d2f0747c16a796a21147ffaf404 (diff)
downloadpostgresql-aaf15ee33a63c582fbb61b67befdd620e85da2ce.tar.gz
postgresql-aaf15ee33a63c582fbb61b67befdd620e85da2ce.zip
Revoke support for strxfrm() that write past the specified array length.
This formalizes a decision implicit in commit 4ea51cdfe85ceef8afabceb03c446574daa0ac23 and adds clean detection of affected systems. Vendor updates are available for each such known bug. Back-patch to 9.5, where the aforementioned commit first appeared.
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 04ed07b762d..64b6ae4838f 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3932,16 +3932,8 @@ convert_string_datum(Datum value, Oid typid)
size_t xfrmlen2 PG_USED_FOR_ASSERTS_ONLY;
/*
- * Note: originally we guessed at a suitable output buffer size, and
- * only needed to call strxfrm twice if our guess was too small.
- * However, it seems that some versions of Solaris have buggy strxfrm
- * that can write past the specified buffer length in that scenario.
- * So, do it the dumb way for portability.
- *
- * Yet other systems (e.g., glibc) sometimes return a smaller value
- * from the second call than the first; thus the Assert must be <= not
- * == as you'd expect. Can't any of these people program their way
- * out of a paper bag?
+ * XXX: We could guess at a suitable output buffer size and only call
+ * strxfrm twice if our guess is too small.
*
* XXX: strxfrm doesn't support UTF-8 encoding on Win32, it can return
* bogus data or set an error. This is not really a problem unless it
@@ -3974,6 +3966,11 @@ convert_string_datum(Datum value, Oid typid)
#endif
xfrmstr = (char *) palloc(xfrmlen + 1);
xfrmlen2 = strxfrm(xfrmstr, val, xfrmlen + 1);
+
+ /*
+ * Some systems (e.g., glibc) can return a smaller value from the
+ * second call than the first; thus the Assert must be <= not ==.
+ */
Assert(xfrmlen2 <= xfrmlen);
pfree(val);
val = xfrmstr;