summaryrefslogtreecommitdiff
path: root/Modules/zipimport.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/zipimport.c')
-rw-r--r--Modules/zipimport.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 009480bac5..1d0e0ba913 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -1,4 +1,5 @@
#include "Python.h"
+#include "internal/import.h"
#include "internal/pystate.h"
#include "structmember.h"
#include "osdefs.h"
@@ -1305,7 +1306,7 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Py_ssize_t size = PyBytes_Size(data);
- if (size < 12) {
+ if (size < 16) {
PyErr_SetString(ZipImportError,
"bad pyc data");
return NULL;
@@ -1319,7 +1320,16 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Py_RETURN_NONE; /* signal caller to try alternative */
}
- if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
+ uint32_t flags = get_uint32(buf + 4);
+ if (flags != 0) {
+ // Hash-based pyc. We currently refuse to handle checked hash-based
+ // pycs. We could validate hash-based pycs against the source, but it
+ // seems likely that most people putting hash-based pycs in a zipfile
+ // will use unchecked ones.
+ if (strcmp(_Py_CheckHashBasedPycsMode, "never") &&
+ (flags != 0x1 || !strcmp(_Py_CheckHashBasedPycsMode, "always")))
+ Py_RETURN_NONE;
+ } else if ((mtime != 0 && !eq_mtime(get_uint32(buf + 8), mtime))) {
if (Py_VerboseFlag) {
PySys_FormatStderr("# %R has bad mtime\n",
pathname);
@@ -1329,7 +1339,7 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
/* XXX the pyc's size field is ignored; timestamp collisions are probably
unimportant with zip files. */
- code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
+ code = PyMarshal_ReadObjectFromString((char *)buf + 16, size - 16);
if (code == NULL) {
return NULL;
}