@@ -23,7 +23,7 @@ extern int winerror_to_errno(int);
2323extern wchar_t * _Py_DecodeUTF8_surrogateescape (const char * s , Py_ssize_t size ,
2424 size_t * p_wlen );
2525extern char * _Py_EncodeUTF8_surrogateescape (const wchar_t * text ,
26- size_t * error_pos );
26+ size_t * error_pos , int raw_malloc );
2727
2828#ifdef O_CLOEXEC
2929/* Does open() support the O_CLOEXEC flag? Possible values:
@@ -183,7 +183,7 @@ check_force_ascii(void)
183183}
184184
185185static char *
186- encode_ascii_surrogateescape (const wchar_t * text , size_t * error_pos )
186+ encode_ascii_surrogateescape (const wchar_t * text , size_t * error_pos , int raw_malloc )
187187{
188188 char * result = NULL , * out ;
189189 size_t len , i ;
@@ -194,7 +194,13 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
194194
195195 len = wcslen (text );
196196
197- result = PyMem_Malloc (len + 1 ); /* +1 for NUL byte */
197+ /* +1 for NUL byte */
198+ if (raw_malloc ) {
199+ result = PyMem_RawMalloc (len + 1 );
200+ }
201+ else {
202+ result = PyMem_Malloc (len + 1 );
203+ }
198204 if (result == NULL )
199205 return NULL ;
200206
@@ -211,9 +217,15 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
211217 * out ++ = (char )(ch - 0xdc00 );
212218 }
213219 else {
214- if (error_pos != NULL )
220+ if (error_pos != NULL ) {
215221 * error_pos = i ;
216- PyMem_Free (result );
222+ }
223+ if (raw_malloc ) {
224+ PyMem_RawFree (result );
225+ }
226+ else {
227+ PyMem_Free (result );
228+ }
217229 return NULL ;
218230 }
219231 }
@@ -423,7 +435,7 @@ Py_DecodeLocale(const char* arg, size_t *size)
423435
424436#if !defined(__APPLE__ ) && !defined(__ANDROID__ )
425437static char *
426- encode_locale (const wchar_t * text , size_t * error_pos )
438+ encode_current_locale (const wchar_t * text , size_t * error_pos , int raw_malloc )
427439{
428440 const size_t len = wcslen (text );
429441 char * result = NULL , * bytes = NULL ;
@@ -455,8 +467,14 @@ encode_locale(const wchar_t *text, size_t *error_pos)
455467 else
456468 converted = wcstombs (NULL , buf , 0 );
457469 if (converted == (size_t )-1 ) {
458- if (result != NULL )
459- PyMem_Free (result );
470+ if (result != NULL ) {
471+ if (raw_malloc ) {
472+ PyMem_RawFree (result );
473+ }
474+ else {
475+ PyMem_Free (result );
476+ }
477+ }
460478 if (error_pos != NULL )
461479 * error_pos = i ;
462480 return NULL ;
@@ -475,10 +493,16 @@ encode_locale(const wchar_t *text, size_t *error_pos)
475493 }
476494
477495 size += 1 ; /* nul byte at the end */
478- result = PyMem_Malloc (size );
496+ if (raw_malloc ) {
497+ result = PyMem_RawMalloc (size );
498+ }
499+ else {
500+ result = PyMem_Malloc (size );
501+ }
479502 if (result == NULL ) {
480- if (error_pos != NULL )
503+ if (error_pos != NULL ) {
481504 * error_pos = (size_t )-1 ;
505+ }
482506 return NULL ;
483507 }
484508 bytes = result ;
@@ -487,6 +511,28 @@ encode_locale(const wchar_t *text, size_t *error_pos)
487511}
488512#endif
489513
514+ static char *
515+ encode_locale (const wchar_t * text , size_t * error_pos , int raw_malloc )
516+ {
517+ #if defined(__APPLE__ ) || defined(__ANDROID__ )
518+ return _Py_EncodeUTF8_surrogateescape (text , error_pos , raw_malloc );
519+ #else /* __APPLE__ */
520+ if (Py_UTF8Mode == 1 ) {
521+ return _Py_EncodeUTF8_surrogateescape (text , error_pos , raw_malloc );
522+ }
523+
524+ #ifndef MS_WINDOWS
525+ if (force_ascii == -1 )
526+ force_ascii = check_force_ascii ();
527+
528+ if (force_ascii )
529+ return encode_ascii_surrogateescape (text , error_pos , raw_malloc );
530+ #endif
531+
532+ return encode_current_locale (text , error_pos , raw_malloc );
533+ #endif /* __APPLE__ or __ANDROID__ */
534+ }
535+
490536/* Encode a wide character string to the locale encoding with the
491537 surrogateescape error handler: surrogate characters in the range
492538 U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
@@ -502,23 +548,16 @@ encode_locale(const wchar_t *text, size_t *error_pos)
502548char *
503549Py_EncodeLocale (const wchar_t * text , size_t * error_pos )
504550{
505- #if defined(__APPLE__ ) || defined(__ANDROID__ )
506- return _Py_EncodeUTF8_surrogateescape (text , error_pos );
507- #else /* __APPLE__ */
508- if (Py_UTF8Mode == 1 ) {
509- return _Py_EncodeUTF8_surrogateescape (text , error_pos );
510- }
511-
512- #ifndef MS_WINDOWS
513- if (force_ascii == -1 )
514- force_ascii = check_force_ascii ();
551+ return encode_locale (text , error_pos , 0 );
552+ }
515553
516- if (force_ascii )
517- return encode_ascii_surrogateescape (text , error_pos );
518- #endif
519554
520- return encode_locale (text , error_pos );
521- #endif /* __APPLE__ or __ANDROID__ */
555+ /* Similar to Py_EncodeLocale(), but result must be freed by PyMem_RawFree()
556+ instead of PyMem_Free(). */
557+ char *
558+ _Py_EncodeLocaleRaw (const wchar_t * text , size_t * error_pos )
559+ {
560+ return encode_locale (text , error_pos , 1 );
522561}
523562
524563
@@ -1029,11 +1068,12 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode)
10291068 errno = EINVAL ;
10301069 return NULL ;
10311070 }
1032- cpath = Py_EncodeLocale (path , NULL );
1033- if (cpath == NULL )
1071+ cpath = _Py_EncodeLocaleRaw (path , NULL );
1072+ if (cpath == NULL ) {
10341073 return NULL ;
1074+ }
10351075 f = fopen (cpath , cmode );
1036- PyMem_Free (cpath );
1076+ PyMem_RawFree (cpath );
10371077#else
10381078 f = _wfopen (path , mode );
10391079#endif
@@ -1341,13 +1381,13 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
13411381 int res ;
13421382 size_t r1 ;
13431383
1344- cpath = Py_EncodeLocale (path , NULL );
1384+ cpath = _Py_EncodeLocaleRaw (path , NULL );
13451385 if (cpath == NULL ) {
13461386 errno = EINVAL ;
13471387 return -1 ;
13481388 }
13491389 res = (int )readlink (cpath , cbuf , Py_ARRAY_LENGTH (cbuf ));
1350- PyMem_Free (cpath );
1390+ PyMem_RawFree (cpath );
13511391 if (res == -1 )
13521392 return -1 ;
13531393 if (res == Py_ARRAY_LENGTH (cbuf )) {
@@ -1386,13 +1426,13 @@ _Py_wrealpath(const wchar_t *path,
13861426 wchar_t * wresolved_path ;
13871427 char * res ;
13881428 size_t r ;
1389- cpath = Py_EncodeLocale (path , NULL );
1429+ cpath = _Py_EncodeLocaleRaw (path , NULL );
13901430 if (cpath == NULL ) {
13911431 errno = EINVAL ;
13921432 return NULL ;
13931433 }
13941434 res = realpath (cpath , cresolved_path );
1395- PyMem_Free (cpath );
1435+ PyMem_RawFree (cpath );
13961436 if (res == NULL )
13971437 return NULL ;
13981438
0 commit comments