@@ -560,20 +560,37 @@ Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
560560
561561
562562static const char *
563- source_as_string (PyObject * cmd , const char * funcname , const char * what , PyCompilerFlags * cf , Py_buffer * view )
563+ source_as_string (PyObject * cmd , const char * funcname , const char * what , PyCompilerFlags * cf , PyObject * * cmd_copy )
564564{
565565 const char * str ;
566566 Py_ssize_t size ;
567+ Py_buffer view ;
567568
569+ * cmd_copy = NULL ;
568570 if (PyUnicode_Check (cmd )) {
569571 cf -> cf_flags |= PyCF_IGNORE_COOKIE ;
570572 str = PyUnicode_AsUTF8AndSize (cmd , & size );
571573 if (str == NULL )
572574 return NULL ;
573575 }
574- else if (PyObject_GetBuffer (cmd , view , PyBUF_SIMPLE ) == 0 ) {
575- str = (const char * )view -> buf ;
576- size = view -> len ;
576+ else if (PyBytes_Check (cmd )) {
577+ str = PyBytes_AS_STRING (cmd );
578+ size = PyBytes_GET_SIZE (cmd );
579+ }
580+ else if (PyByteArray_Check (cmd )) {
581+ str = PyByteArray_AS_STRING (cmd );
582+ size = PyByteArray_GET_SIZE (cmd );
583+ }
584+ else if (PyObject_GetBuffer (cmd , & view , PyBUF_SIMPLE ) == 0 ) {
585+ /* Copy to NUL-terminated buffer. */
586+ * cmd_copy = PyBytes_FromStringAndSize (
587+ (const char * )view .buf , view .len );
588+ PyBuffer_Release (& view );
589+ if (* cmd_copy == NULL ) {
590+ return NULL ;
591+ }
592+ str = PyBytes_AS_STRING (* cmd_copy );
593+ size = PyBytes_GET_SIZE (* cmd_copy );
577594 }
578595 else {
579596 PyErr_Format (PyExc_TypeError ,
@@ -585,7 +602,7 @@ source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompil
585602 if (strlen (str ) != size ) {
586603 PyErr_SetString (PyExc_TypeError ,
587604 "source code string cannot contain null bytes" );
588- PyBuffer_Release ( view );
605+ Py_CLEAR ( * cmd_copy );
589606 return NULL ;
590607 }
591608 return str ;
@@ -594,7 +611,7 @@ source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompil
594611static PyObject *
595612builtin_compile (PyObject * self , PyObject * args , PyObject * kwds )
596613{
597- Py_buffer view = { NULL , NULL } ;
614+ PyObject * cmd_copy ;
598615 const char * str ;
599616 PyObject * filename ;
600617 char * startstr ;
@@ -681,12 +698,12 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds)
681698 goto finally ;
682699 }
683700
684- str = source_as_string (cmd , "compile" , "string, bytes or AST" , & cf , & view );
701+ str = source_as_string (cmd , "compile" , "string, bytes or AST" , & cf , & cmd_copy );
685702 if (str == NULL )
686703 goto error ;
687704
688705 result = Py_CompileStringObject (str , filename , start [mode ], & cf , optimize );
689- PyBuffer_Release ( & view );
706+ Py_XDECREF ( cmd_copy );
690707 goto finally ;
691708
692709error :
@@ -754,9 +771,8 @@ Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x.");
754771static PyObject *
755772builtin_eval (PyObject * self , PyObject * args )
756773{
757- PyObject * cmd , * result , * tmp = NULL ;
774+ PyObject * cmd , * result , * cmd_copy ;
758775 PyObject * globals = Py_None , * locals = Py_None ;
759- Py_buffer view = {NULL , NULL };
760776 const char * str ;
761777 PyCompilerFlags cf ;
762778
@@ -806,7 +822,7 @@ builtin_eval(PyObject *self, PyObject *args)
806822 }
807823
808824 cf .cf_flags = PyCF_SOURCE_IS_UTF8 ;
809- str = source_as_string (cmd , "eval" , "string, bytes or code" , & cf , & view );
825+ str = source_as_string (cmd , "eval" , "string, bytes or code" , & cf , & cmd_copy );
810826 if (str == NULL )
811827 return NULL ;
812828
@@ -815,8 +831,7 @@ builtin_eval(PyObject *self, PyObject *args)
815831
816832 (void )PyEval_MergeCompilerFlags (& cf );
817833 result = PyRun_StringFlags (str , Py_eval_input , globals , locals , & cf );
818- PyBuffer_Release (& view );
819- Py_XDECREF (tmp );
834+ Py_XDECREF (cmd_copy );
820835 return result ;
821836}
822837
@@ -882,20 +897,21 @@ builtin_exec(PyObject *self, PyObject *args)
882897 v = PyEval_EvalCode (prog , globals , locals );
883898 }
884899 else {
885- Py_buffer view = { NULL , NULL } ;
900+ PyObject * prog_copy ;
886901 const char * str ;
887902 PyCompilerFlags cf ;
888903 cf .cf_flags = PyCF_SOURCE_IS_UTF8 ;
889904 str = source_as_string (prog , "exec" ,
890- "string, bytes or code" , & cf , & view );
905+ "string, bytes or code" , & cf ,
906+ & prog_copy );
891907 if (str == NULL )
892908 return NULL ;
893909 if (PyEval_MergeCompilerFlags (& cf ))
894910 v = PyRun_StringFlags (str , Py_file_input , globals ,
895911 locals , & cf );
896912 else
897913 v = PyRun_String (str , Py_file_input , globals , locals );
898- PyBuffer_Release ( & view );
914+ Py_XDECREF ( prog_copy );
899915 }
900916 if (v == NULL )
901917 return NULL ;
0 commit comments