• R/O
  • HTTP
  • SSH
  • HTTPS

mingw-org-wsl: Commit

The MinGW.org Windows System Libraries


Commit MetaInfo

Revisionf5d6023e3e3bd38f5e347fec853e6967228261ed (tree)
Time2020-03-20 06:17:25
AuthorKeith Marshall <keith@user...>
CommiterKeith Marshall

Log Message

Correct a potential mbsrtowcs() surrogate pair overrun.

Change Summary

Incremental Difference

--- a/mingwrt/ChangeLog
+++ b/mingwrt/ChangeLog
@@ -1,3 +1,10 @@
1+2020-03-19 Keith Marshall <keith@users.osdn.me>
2+
3+ Correct a potential mbsrtowcs() surrogate pair overrun.
4+
5+ * mingwex/mbrscan.c (__mingw_mbtowc_copy) [(count + 1) == len)]: Stop,
6+ without storing current multibyte conversion, if surrogate pair.
7+
18 2020-03-12 Keith Marshall <keith@users.osdn.me>
29
310 Rationalize implementations of fwide() and mbsinit() functions.
--- a/mingwrt/mingwex/mbrscan.c
+++ b/mingwrt/mingwex/mbrscan.c
@@ -264,23 +264,58 @@ size_t __mingw_mbtowc_copy
264264 * an internal scratch buffer, to facilitate counting the number of
265265 * such elements which would be copied, without storing them).
266266 */
267- wchar_t scratch[2]; size_t count = (size_t)(0);
267+ size_t count = (size_t)(0);
268268 while( count < len )
269- {
270- int copy, scan = 0;
271- wchar_t *wc = (wcs == NULL) ? scratch : wcs;
269+ { /* Scan the multibyte sequence, one character at a time, while we
270+ * still have sufficient space to store each conversion, (ensuring
271+ * that there is always at least enough space to accommodate one
272+ * full conversion, avoiding possible surrogate pair overflow.
273+ */
274+ int copy, scan = 0, gap = len - count;
275+ wchar_t scratch[2], *wc = ((wcs == NULL) || (gap < 2)) ? scratch : wcs;
276+
277+ /* Determine the length of the next multibyte character, and the
278+ * number of wchar_t entities required to store it.
279+ */
272280 do { copy = __mingw_mbtowc_convert( src, ++scan, wc, 2 );
273281 } while( (copy == 0) && (scan < mbrlen_cur_max) );
274282
283+ /* Bail out, if no conversion is possible; (this can only occur
284+ * if an invalid multibyte sequence is detected).
285+ */
275286 if( copy == 0 ) return errout( EILSEQ, (size_t)(-1) );
276287
277- if( *wc == L'\0' ) len = count;
288+ /* Stop at any terminating NUL character, or if a surrogate pair
289+ * will overflow at the end of the designated buffer...
290+ */
291+ if( (*wc == L'\0') || (gap < copy) )
292+ {
293+ /* ...storing a NUL terminator, if necessary...
294+ */
295+ if( (wcs != NULL) && (*wc == L'\0') ) *wcs = L'\0';
296+ len = count;
297+ }
278298 else
279- { count += copy;
280- if( wcs != NULL ) wcs += copy;
299+ { /* ...otherwise, adjust the count of wchar_t entities, which
300+ * have been converted thus far...
301+ */
302+ count += copy;
303+ if( wcs != NULL )
304+ { /* ...ensuring that the conversion is appropriately stored,
305+ * and the storage buffer pointer is advanced...
306+ */
307+ if( wc == scratch ) while( copy-- > 0 ) *wcs++ = *wc++;
308+ else wcs += copy;
309+ }
310+ /* ...and that the scan pointer is repositioned, to process
311+ * the next multibyte character, (if any).
312+ */
281313 src += scan;
282314 }
283315 }
316+ /* Finally, we return the total number of wchar_t entities which have,
317+ * (or would have), been stored for this conversion.
318+ */
284319 return count;
285320 }
286321
Show on old repository browser