Browse Source
bpo-36301: Error if decoding pybuilddir.txt fails (GH-12422)
Python initialization now fails if decoding pybuilddir.txt
configuration file fails at startup.
_PyPathConfig_Calculate() now reports memory allocation failure and
decoding error on decoding pybuilddir.txt content from
UTF-8/surrogateescape.
pull/12425/head
Victor Stinner
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with
32 additions and
16 deletions
Include/internal/pycore_fileutils.h
Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst
Modules/getpath.c
Objects/unicodeobject.c
Python/pathconfig.c
@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
PyAPI_FUNC ( wchar_t * ) _Py_DecodeUTF8_surrogateescape (
const char * arg ,
Py_ssize_t arglen ) ;
Py_ssize_t arglen ,
size_t * wlen ) ;
PyAPI_FUNC ( int ) _Py_GetForceASCII ( void ) ;
@ -0,0 +1,2 @@
Python initialization now fails if decoding `` pybuilddir.txt `` configuration
file fails at startup.
@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
}
else {
char buf [ MAXPATHLEN + 1 ] ;
wchar_t * rel_builddir_path ;
n = fread ( buf , 1 , MAXPATHLEN , f ) ;
buf [ n ] = ' \0 ' ;
fclose ( f ) ;
rel_builddir_path = _Py_DecodeUTF8_surrogateescape ( buf , n ) ;
if ( rel_builddir_path ) {
wcsncpy ( exec_prefix , calculate - > argv0_path , MAXPATHLEN ) ;
exec_prefix [ MAXPATHLEN ] = L ' \0 ' ;
err = joinpath ( exec_prefix , rel_builddir_path ) ;
PyMem_RawFree ( rel_builddir_path ) ;
if ( _Py_INIT_FAILED ( err ) ) {
return err ;
}
* found = - 1 ;
return _Py_INIT_OK ( ) ;
size_t dec_len ;
wchar_t * pybuilddir ;
pybuilddir = _Py_DecodeUTF8_surrogateescape ( buf , n , & dec_len ) ;
if ( ! pybuilddir ) {
return DECODE_LOCALE_ERR ( " pybuilddir.txt " , dec_len ) ;
}
wcsncpy ( exec_prefix , calculate - > argv0_path , MAXPATHLEN ) ;
exec_prefix [ MAXPATHLEN ] = L ' \0 ' ;
err = joinpath ( exec_prefix , pybuilddir ) ;
PyMem_RawFree ( pybuilddir ) ;
if ( _Py_INIT_FAILED ( err ) ) {
return err ;
}
* found = - 1 ;
return _Py_INIT_OK ( ) ;
}
}
@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,
return 0 ;
}
wchar_t *
_Py_DecodeUTF8_surrogateescape ( const char * arg , Py_ssize_t arglen )
_Py_DecodeUTF8_surrogateescape ( const char * arg , Py_ssize_t arglen ,
size_t * wlen )
{
wchar_t * wstr ;
int res = _Py_DecodeUTF8Ex ( arg , arglen , & wstr , NULL , NULL , 1 ) ;
int res = _Py_DecodeUTF8Ex ( arg , arglen ,
& wstr , wlen ,
NULL , _Py_ERROR_SURROGATEESCAPE ) ;
if ( res ! = 0 ) {
/* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */
assert ( res ! = - 3 ) ;
if ( wlen ) {
* wlen = ( size_t ) res ;
}
return NULL ;
}
return wstr ;
@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
continue ;
}
wchar_t * tmpbuffer = _Py_DecodeUTF8_surrogateescape ( buffer , n ) ;
wchar_t * tmpbuffer = _Py_DecodeUTF8_surrogateescape ( buffer , n , NULL ) ;
if ( tmpbuffer ) {
wchar_t * state ;
wchar_t * tok = WCSTOK ( tmpbuffer , L " \t \r \n " , & state ) ;