Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use a copy of PyImport_Inittab.
  • Loading branch information
ericsnowcurrently committed Nov 11, 2022
commit 492ffdf0499788f0afe410461b59816bfe094d67
1 change: 1 addition & 0 deletions Include/cpython/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct _inittab {
const char *name; /* ASCII encoded string */
PyObject* (*initfunc)(void);
};
// This is not used after Py_Initialize() is called.
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);

Expand Down
46 changes: 44 additions & 2 deletions Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ static PyObject *import_add_module(PyThreadState *tstate, PyObject *name);
/* This table is defined in config.c: */
extern struct _inittab _PyImport_Inittab[];

// This is not used after Py_Initialize() is called.
// (See _PyRuntimeState.imports.inittab.)
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
static struct _inittab *inittab_copy = NULL;

Expand Down Expand Up @@ -224,8 +226,30 @@ _PyImport_Init(void)
if (_PyRuntime.imports.inittab != NULL) {
return _PyStatus_ERR("global import state already initialized");
}
_PyRuntime.imports.inittab = PyImport_Inittab;
return _PyStatus_OK();
PyStatus status = _PyStatus_OK();

size_t size;
for (size = 0; PyImport_Inittab[size].name != NULL; size++)
;
size++;

/* Force default raw memory allocator to get a known allocator to be able
to release the memory in _PyImport_Fini() */
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

/* Make the copy. */
struct _inittab *copied = PyMem_RawMalloc(size * sizeof(struct _inittab));
if (copied == NULL) {
status = PyStatus_NoMemory();
goto done;
}
memcpy(copied, PyImport_Inittab, size * sizeof(struct _inittab));
_PyRuntime.imports.inittab = copied;

done:
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
return status;
}

static inline void _extensions_cache_clear(void);
Expand All @@ -238,7 +262,17 @@ _PyImport_Fini(void)
PyThread_free_lock(import_lock);
import_lock = NULL;
}

/* Use the same memory allocator as _PyImport_Init(). */
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

/* Free memory allocated by _PyImport_Init() */
struct _inittab *inittab = _PyRuntime.imports.inittab;
_PyRuntime.imports.inittab = NULL;
PyMem_RawFree(inittab);

PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}

void
Expand Down Expand Up @@ -2604,6 +2638,10 @@ PyImport_ExtendInittab(struct _inittab *newtab)
size_t i, n;
int res = 0;

if (_PyRuntime.imports.inittab != NULL) {
Py_FatalError("PyImport_ExtendInittab() may be be called after Py_Initialize()");
}

/* Count the number of entries in both tables */
for (n = 0; newtab[n].name != NULL; n++)
;
Expand Down Expand Up @@ -2648,6 +2686,10 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
{
struct _inittab newtab[2];

if (_PyRuntime.imports.inittab != NULL) {
Py_FatalError("PyImport_AppendInittab() may be be called after Py_Initialize()");
}

memset(newtab, '\0', sizeof newtab);

newtab[0].name = name;
Expand Down
1 change: 0 additions & 1 deletion Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ Python/frozen.c - _PyImport_FrozenBootstrap -
Python/frozen.c - _PyImport_FrozenStdlib -
Python/frozen.c - _PyImport_FrozenTest -
Python/import.c - inittab_copy -
Python/import.c - PyImport_Inittab -
Python/preconfig.c - Py_FileSystemDefaultEncoding -
Python/preconfig.c - Py_HasFileSystemDefaultEncoding -
Python/preconfig.c - Py_FileSystemDefaultEncodeErrors -
Expand Down
1 change: 1 addition & 0 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ filename funcname name reason
##################################
# mutable but known to be safe

Python/import.c - PyImport_Inittab -
Python/pylifecycle.c - _PyRuntime -

# All uses of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py.
Expand Down