1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-07 12:02:30 +03:00

Revoke support for strxfrm() that write past the specified array length.

This formalizes a decision implicit in commit
4ea51cdfe8 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.
This commit is contained in:
Noah Misch
2015-07-08 20:44:21 -04:00
parent b28244abe5
commit be8b06c364
5 changed files with 70 additions and 10 deletions

View File

@@ -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;