diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2019-03-19 22:56:11 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2019-03-19 23:03:06 +0300 |
commit | 10900b98d177c6cf01d294fa187e9d13b053b80c (patch) | |
tree | 37c8159ec8c3023aec547e3d9763429943f90b62 | |
parent | 62c66a39bdcb64c74cdd001146b1d7e1e50c687d (diff) |
Cygwin: wcsxfrm_l: Only byte swap if dest size is > 0
commit c0d7d3e1a2fa96db15613cbd68a68c96966bc402 removed the usage of the
LCMAP_BYTEREV flag in the call to LCMapStringW to workaround a strange
bug in LCMapStringW. This patch didn't take a userspace call of
wcsxfrm{_l} with NULL buffer and 0 size to evaluate the required buffer
size into account. This introduced a crash trying to byte swap the
NULL buffer. This patch fixes that problem.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/nlsfuncs.cc | 21 | ||||
-rw-r--r-- | winsup/cygwin/release/3.0.5 | 3 |
2 files changed, 15 insertions, 9 deletions
diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc index 5bf7d22ac..455afb417 100644 --- a/winsup/cygwin/nlsfuncs.cc +++ b/winsup/cygwin/nlsfuncs.cc @@ -1204,15 +1204,18 @@ wcsxfrm_l (wchar_t *__restrict ws1, const wchar_t *__restrict ws2, size_t wsn, if (ret) { ret /= sizeof (wchar_t); - /* Byte swap the array ourselves here. */ - for (size_t idx = 0; idx < ret; ++idx) - ws1[idx] = __builtin_bswap16 (ws1[idx]); - /* LCMapStringW returns byte count including the terminating NUL char. - wcsxfrm is supposed to return length in wchar_t excluding the NUL. - Since the array is only single byte NUL-terminated yet, make sure - the result is wchar_t-NUL terminated. */ - if (ret < wsn) - ws1[ret] = L'\0'; + if (wsn) + { + /* Byte swap the array ourselves here. */ + for (size_t idx = 0; idx < ret; ++idx) + ws1[idx] = __builtin_bswap16 (ws1[idx]); + /* LCMapStringW returns byte count including the terminating NUL char. + wcsxfrm is supposed to return length in wchar_t excluding the NUL. + Since the array is only single byte NUL-terminated yet, make sure + the result is wchar_t-NUL terminated. */ + if (ret < wsn) + ws1[ret] = L'\0'; + } return ret; } if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) diff --git a/winsup/cygwin/release/3.0.5 b/winsup/cygwin/release/3.0.5 index 62c8cf5ca..a52412cd2 100644 --- a/winsup/cygwin/release/3.0.5 +++ b/winsup/cygwin/release/3.0.5 @@ -11,3 +11,6 @@ Bug Fixes - Fix /proc/version after uname change Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00467.html + +- Fix a crash in wcsxfrm_l if destination size is 0. + Addresses: https://cygwin.com/ml/cygwin/2019-03/msg00492.html |