/* Given the contents of a .pyc file in a buffer, unmarshal the data and return the code object. Return None if it the magic word doesn't match (we do this instead of raising an exception as we fall back to .py if available and we don't want to mask other errors). Returns a new reference. */ static PyObject * unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) { PyObject *code; unsigned char *buf = (unsigned char *)PyBytes_AsString(data); Py_ssize_t size = PyBytes_Size(data); if (size < 16) { PyErr_SetString(ZipImportError, "bad pyc data"); return NULL; } if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) { if (Py_VerboseFlag) { PySys_FormatStderr("# %R has bad magic\n", pathname); } Py_RETURN_NONE; /* signal caller to try alternative */ } 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); } Py_RETURN_NONE; /* signal caller to try alternative */ } /* XXX the pyc's size field is ignored; timestamp collisions are probably unimportant with zip files. */ code = PyMarshal_ReadObjectFromString((char *)buf + 16, size - 16); if (code == NULL) { return NULL; } if (!PyCode_Check(code)) { Py_DECREF(code); PyErr_Format(PyExc_TypeError, "compiled module %R is not a code object", pathname); return NULL; } return code; }
/* Given the contents of a .py[co] file in a buffer, unmarshal the data and return the code object. Return None if it the magic word doesn't match (we do this instead of raising an exception as we fall back to .py if available and we don't want to mask other errors). Returns a new reference. */ static PyObject * unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) { PyObject *code; unsigned char *buf = (unsigned char *)PyBytes_AsString(data); Py_ssize_t size = PyBytes_Size(data); if (size < 12) { PyErr_SetString(ZipImportError, "bad pyc data"); return NULL; } if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) { if (Py_VerboseFlag) { PySys_FormatStderr("# %R has bad magic\n", pathname); } Py_INCREF(Py_None); return Py_None; /* signal caller to try alternative */ } if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) { if (Py_VerboseFlag) { PySys_FormatStderr("# %R has bad mtime\n", pathname); } Py_INCREF(Py_None); return Py_None; /* signal caller to try alternative */ } /* XXX the pyc's size field is ignored; timestamp collisions are probably unimportant with zip files. */ code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12); if (code == NULL) { return NULL; } if (!PyCode_Check(code)) { Py_DECREF(code); PyErr_Format(PyExc_TypeError, "compiled module %R is not a code object", pathname); return NULL; } return code; }
/* Given the contents of a .py[co] file in a buffer, unmarshal the data and return the code object. Return None if it the magic word doesn't match (we do this instead of raising an exception as we fall back to .py if available and we don't want to mask other errors). Returns a new reference. */ static PyObject * unmarshal_code(const char *pathname, PyObject *data, time_t mtime) { PyObject *code; unsigned char *buf = (unsigned char *)PyString_AsString(data); Py_ssize_t size = PyString_Size(data); if (size < 8) { PyErr_SetString(ZipImportError, "bad pyc data"); return NULL; } if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) { if (Py_VerboseFlag) { PySys_WriteStderr("# %s has bad magic\n", pathname); } Py_INCREF(Py_None); return Py_None; /* signal caller to try alternative */ } if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) { if (Py_VerboseFlag) { PySys_WriteStderr("# %s has bad mtime\n", pathname); } Py_INCREF(Py_None); return Py_None; /* signal caller to try alternative */ } code = PyMarshal_ReadObjectFromString((char *)buf + 8, size - 8); if (code == NULL) { return NULL; } if (!PyCode_Check(code)) { Py_DECREF(code); PyErr_Format(PyExc_TypeError, "compiled module %.200s is not a code object", pathname); return NULL; } return code; }