The MinGW.OSDN Windows System Libraries. Formerly designated as "MinGW.org Windows System Libraries", this encapsulates the "mingwrt" C runtime library extensions, and the "w32api" 32-bit MS-Windows API libraries.
Please note that this project no longer owns the "MinGW.org" domain name; any software which may be distributed from that domain is NOT supported by this project.
Revisão | f5d6023e3e3bd38f5e347fec853e6967228261ed (tree) |
---|---|
Hora | 2020-03-20 06:17:25 |
Autor | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Correct a potential mbsrtowcs() surrogate pair overrun.
@@ -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 | + | |
1 | 8 | 2020-03-12 Keith Marshall <keith@users.osdn.me> |
2 | 9 | |
3 | 10 | Rationalize implementations of fwide() and mbsinit() functions. |
@@ -264,23 +264,58 @@ size_t __mingw_mbtowc_copy | ||
264 | 264 | * an internal scratch buffer, to facilitate counting the number of |
265 | 265 | * such elements which would be copied, without storing them). |
266 | 266 | */ |
267 | - wchar_t scratch[2]; size_t count = (size_t)(0); | |
267 | + size_t count = (size_t)(0); | |
268 | 268 | 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 | + */ | |
272 | 280 | do { copy = __mingw_mbtowc_convert( src, ++scan, wc, 2 ); |
273 | 281 | } while( (copy == 0) && (scan < mbrlen_cur_max) ); |
274 | 282 | |
283 | + /* Bail out, if no conversion is possible; (this can only occur | |
284 | + * if an invalid multibyte sequence is detected). | |
285 | + */ | |
275 | 286 | if( copy == 0 ) return errout( EILSEQ, (size_t)(-1) ); |
276 | 287 | |
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 | + } | |
278 | 298 | 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 | + */ | |
281 | 313 | src += scan; |
282 | 314 | } |
283 | 315 | } |
316 | + /* Finally, we return the total number of wchar_t entities which have, | |
317 | + * (or would have), been stored for this conversion. | |
318 | + */ | |
284 | 319 | return count; |
285 | 320 | } |
286 | 321 |