@@ -607,32 +607,51 @@ PyModule_GetName(PyObject *m)
607607}
608608
609609PyObject *
610- PyModule_GetFilenameObject (PyObject * mod )
610+ _PyModule_GetFilenameObject (PyObject * mod )
611611{
612+ // We return None to indicate "not found" or "bogus".
612613 if (!PyModule_Check (mod )) {
613614 PyErr_BadArgument ();
614615 return NULL ;
615616 }
616617 PyObject * dict = ((PyModuleObject * )mod )-> md_dict ; // borrowed reference
617618 if (dict == NULL ) {
618- goto error ;
619+ // The module has been tampered with.
620+ Py_RETURN_NONE ;
619621 }
620622 PyObject * fileobj ;
621- if (PyDict_GetItemRef (dict , & _Py_ID (__file__ ), & fileobj ) <= 0 ) {
622- // error or not found
623- goto error ;
623+ int res = PyDict_GetItemRef (dict , & _Py_ID (__file__ ), & fileobj );
624+ if (res < 0 ) {
625+ return NULL ;
626+ }
627+ if (res == 0 ) {
628+ // __file__ isn't set. There are several reasons why this might
629+ // be so, most of them valid reasons. If it's the __main__
630+ // module then we're running the REPL or with -c. Otherwise
631+ // it's a namespace package or other module with a loader that
632+ // isn't disk-based. It could also be that a user created
633+ // a module manually but without manually setting __file__.
634+ Py_RETURN_NONE ;
624635 }
625636 if (!PyUnicode_Check (fileobj )) {
626637 Py_DECREF (fileobj );
627- goto error ;
638+ Py_RETURN_NONE ;
628639 }
629640 return fileobj ;
641+ }
630642
631- error :
632- if (!PyErr_Occurred ()) {
643+ PyObject *
644+ PyModule_GetFilenameObject (PyObject * mod )
645+ {
646+ PyObject * fileobj = _PyModule_GetFilenameObject (mod );
647+ if (fileobj == NULL ) {
648+ return NULL ;
649+ }
650+ if (fileobj == Py_None ) {
633651 PyErr_SetString (PyExc_SystemError , "module filename missing" );
652+ return NULL ;
634653 }
635- return NULL ;
654+ return fileobj ;
636655}
637656
638657const char *
@@ -648,6 +667,35 @@ PyModule_GetFilename(PyObject *m)
648667 return utf8 ;
649668}
650669
670+ Py_ssize_t
671+ _PyModule_GetFilenameUTF8 (PyObject * mod , char * buffer , size_t maxlen )
672+ {
673+ // We "return" an empty string for an invalid module
674+ // and for a missing, empty, or invalid filename.
675+ Py_ssize_t size = -1 ;
676+ PyObject * filenameobj = _PyModule_GetFilenameObject (mod );
677+ if (filenameobj == NULL ) {
678+ return -1 ;
679+ }
680+ if (filenameobj == Py_None ) {
681+ // It is missing or invalid.
682+ buffer [0 ] = '\0' ;
683+ size = 0 ;
684+ }
685+ else {
686+ const char * filename = PyUnicode_AsUTF8AndSize (filenameobj , & size );
687+ if (size > maxlen ) {
688+ size = -1 ;
689+ PyErr_SetString (PyExc_ValueError , "__file__ too long" );
690+ }
691+ else {
692+ (void )strcpy (buffer , filename );
693+ }
694+ }
695+ Py_DECREF (filenameobj );
696+ return size ;
697+ }
698+
651699PyModuleDef *
652700PyModule_GetDef (PyObject * m )
653701{
0 commit comments