@@ -906,11 +906,11 @@ rightmost_sep(Py_UCS4 *s)
906906
907907/* Like rightmost_sep, but operate on unicode objects. */
908908static Py_ssize_t
909- rightmost_sep_obj (PyObject * o )
909+ rightmost_sep_obj (PyObject * o , Py_ssize_t start , Py_ssize_t end )
910910{
911911 Py_ssize_t found , i ;
912912 Py_UCS4 c ;
913- for (found = -1 , i = 0 ; i < PyUnicode_GET_LENGTH ( o ) ; i ++ ) {
913+ for (found = -1 , i = start ; i < end ; i ++ ) {
914914 c = PyUnicode_READ_CHAR (o , i );
915915 if (c == SEP
916916#ifdef ALTSEP
@@ -947,7 +947,7 @@ make_compiled_pathname(PyObject *pathstr, int debug)
947947 len = PyUnicode_GET_LENGTH (pathstr );
948948 /* If there is no separator, this returns -1, so
949949 lastsep will be 0. */
950- fname = rightmost_sep_obj (pathstr ) + 1 ;
950+ fname = rightmost_sep_obj (pathstr , 0 , len ) + 1 ;
951951 ext = fname - 1 ;
952952 for (i = fname ; i < len ; i ++ )
953953 if (PyUnicode_READ_CHAR (pathstr , i ) == '.' )
@@ -992,63 +992,66 @@ make_compiled_pathname(PyObject *pathstr, int debug)
992992 (...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py */
993993
994994static PyObject *
995- make_source_pathname (PyObject * pathobj )
995+ make_source_pathname (PyObject * path )
996996{
997- Py_UCS4 buf [MAXPATHLEN ];
998- Py_UCS4 * pathname ;
999- Py_UCS4 * left , * right , * dot0 , * dot1 , sep ;
1000- size_t i , j ;
997+ Py_ssize_t left , right , dot0 , dot1 , len ;
998+ Py_ssize_t i , j ;
999+ PyObject * result ;
1000+ int kind ;
1001+ void * data ;
10011002
1002- if (PyUnicode_GET_LENGTH (pathobj ) > MAXPATHLEN )
1003- return NULL ;
1004- pathname = PyUnicode_AsUCS4Copy (pathobj );
1005- if (!pathname )
1003+ len = PyUnicode_GET_LENGTH (path );
1004+ if (len > MAXPATHLEN )
10061005 return NULL ;
10071006
10081007 /* Look back two slashes from the end. In between these two slashes
10091008 must be the string __pycache__ or this is not a PEP 3147 style
10101009 path. It's possible for there to be only one slash.
10111010 */
1012- right = rightmost_sep ( pathname );
1013- if (right == NULL )
1011+ right = rightmost_sep_obj ( path , 0 , len );
1012+ if (right == -1 )
10141013 return NULL ;
1015- sep = * right ;
1016- * right = '\0' ;
1017- left = rightmost_sep (pathname );
1018- * right = sep ;
1019- if (left == NULL )
1020- left = pathname ;
1014+ left = rightmost_sep_obj (path , 0 , right );
1015+ if (left == -1 )
1016+ left = 0 ;
10211017 else
10221018 left ++ ;
1023- if (right - left != Py_UCS4_strlen (CACHEDIR_UNICODE ) ||
1024- Py_UCS4_strncmp (left , CACHEDIR_UNICODE , right - left ) != 0 )
1025- goto error ;
1019+ if (right - left != sizeof (CACHEDIR )- 1 )
1020+ return NULL ;
1021+ for (i = 0 ; i < sizeof (CACHEDIR )- 1 ; i ++ )
1022+ if (PyUnicode_READ_CHAR (path , left + i ) != CACHEDIR [i ])
1023+ return NULL ;
10261024
10271025 /* Now verify that the path component to the right of the last slash
10281026 has two dots in it.
10291027 */
1030- if ((dot0 = Py_UCS4_strchr (right + 1 , '.' )) == NULL )
1031- goto error ;
1032- if ((dot1 = Py_UCS4_strchr (dot0 + 1 , '.' )) == NULL )
1033- goto error ;
1028+ dot0 = PyUnicode_FindChar (path , '.' , right + 1 , len , 1 );
1029+ if (dot0 < 0 )
1030+ return NULL ;
1031+ dot1 = PyUnicode_FindChar (path , '.' , dot0 + 1 , len , 1 );
1032+ if (dot1 < 0 )
1033+ return NULL ;
10341034 /* Too many dots? */
1035- if (Py_UCS4_strchr ( dot1 + 1 , '.' ) != NULL )
1036- goto error ;
1035+ if (PyUnicode_FindChar ( path , '.' , dot1 + 1 , len , 1 ) != -1 )
1036+ return NULL ;
10371037
10381038 /* This is a PEP 3147 path. Start by copying everything from the
10391039 start of pathname up to and including the leftmost slash. Then
10401040 copy the file's basename, removing the magic tag and adding a .py
10411041 suffix.
10421042 */
1043- Py_UCS4_strncpy (buf , pathname , (i = left - pathname ));
1044- Py_UCS4_strncpy (buf + i , right + 1 , (j = dot0 - right ));
1045- buf [i + j ] = 'p' ;
1046- buf [i + j + 1 ] = 'y' ;
1047- PyMem_Free (pathname );
1048- return PyUnicode_FromKindAndData (PyUnicode_4BYTE_KIND , buf , i + j + 2 );
1049- error :
1050- PyMem_Free (pathname );
1051- return NULL ;
1043+ result = PyUnicode_New (left + (dot0 - right ) + 2 ,
1044+ PyUnicode_MAX_CHAR_VALUE (path ));
1045+ if (!result )
1046+ return NULL ;
1047+ kind = PyUnicode_KIND (result );
1048+ data = PyUnicode_DATA (result );
1049+ PyUnicode_CopyCharacters (result , 0 , path , 0 , (i = left ));
1050+ PyUnicode_CopyCharacters (result , left , path , right + 1 ,
1051+ (j = dot0 - right ));
1052+ PyUnicode_WRITE (kind , data , i + j , 'p' );
1053+ PyUnicode_WRITE (kind , data , i + j + 1 , 'y' );
1054+ return result ;
10521055}
10531056
10541057/* Given a pathname for a Python source file, its time of last
0 commit comments