It's unclear whether PyMarshal_XXX() are part of the public or private API.
They're named as if public, so I did a Bad Thing by changing PyMarshal_ReadObjectFromFile() to suck up the remainder of the file in one gulp: anyone who counted on that leaving the file pointer merely at the end of the next object would be screwed. So restored PyMarshal_ReadObjectFromFile() to its earlier state, renamed the new greedy code to PyMarshal_ReadLastObjectFromFile(), and changed Python internals to call the latter instead.
This commit is contained in:
parent
09ac1fde1c
commit
d9b9ac855c
|
@ -15,6 +15,7 @@ DL_IMPORT(PyObject *) PyMarshal_WriteObjectToString(PyObject *);
|
|||
DL_IMPORT(long) PyMarshal_ReadLongFromFile(FILE *);
|
||||
DL_IMPORT(int) PyMarshal_ReadShortFromFile(FILE *);
|
||||
DL_IMPORT(PyObject *) PyMarshal_ReadObjectFromFile(FILE *);
|
||||
DL_IMPORT(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *);
|
||||
DL_IMPORT(PyObject *) PyMarshal_ReadObjectFromString(char *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -555,7 +555,7 @@ read_compiled_module(char *cpathname, FILE *fp)
|
|||
{
|
||||
PyObject *co;
|
||||
|
||||
co = PyMarshal_ReadObjectFromFile(fp);
|
||||
co = PyMarshal_ReadLastObjectFromFile(fp);
|
||||
/* Ugly: rd_object() may return NULL with or without error */
|
||||
if (co == NULL || !PyCode_Check(co)) {
|
||||
if (!PyErr_Occurred())
|
||||
|
|
|
@ -631,16 +631,17 @@ getfilesize(FILE *fp)
|
|||
/* If we can get the size of the file up-front, and it's reasonably small,
|
||||
* read it in one gulp and delegate to ...FromString() instead. Much quicker
|
||||
* than reading a byte at a time from file; speeds .pyc imports.
|
||||
* CAUTION: since this may read the entire remainder of the file, don't
|
||||
* call it unless you know you're done with the file.
|
||||
*/
|
||||
PyObject *
|
||||
PyMarshal_ReadObjectFromFile(FILE *fp)
|
||||
PyMarshal_ReadLastObjectFromFile(FILE *fp)
|
||||
{
|
||||
/* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
|
||||
* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
|
||||
*/
|
||||
#define SMALL_FILE_LIMIT (1L << 14)
|
||||
#define REASONABLE_FILE_LIMIT (1L << 18)
|
||||
RFILE rf;
|
||||
#ifdef HAVE_FSTAT
|
||||
off_t filesize;
|
||||
#endif
|
||||
|
@ -668,12 +669,27 @@ PyMarshal_ReadObjectFromFile(FILE *fp)
|
|||
|
||||
}
|
||||
#endif
|
||||
rf.fp = fp;
|
||||
return r_object(&rf);
|
||||
/* We don't have fstat, or we do but the file is larger than
|
||||
* REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
|
||||
*/
|
||||
return PyMarshal_ReadObjectFromFile(fp);
|
||||
|
||||
#undef SMALL_FILE_LIMIT
|
||||
#undef REASONABLE_FILE_LIMIT
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyMarshal_ReadObjectFromFile(FILE *fp)
|
||||
{
|
||||
RFILE rf;
|
||||
if (PyErr_Occurred()) {
|
||||
fprintf(stderr, "XXX rd_object called with exception set\n");
|
||||
return NULL;
|
||||
}
|
||||
rf.fp = fp;
|
||||
return r_object(&rf);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyMarshal_ReadObjectFromString(char *str, int len)
|
||||
{
|
||||
|
|
|
@ -936,7 +936,7 @@ run_pyc_file(FILE *fp, char *filename, PyObject *globals, PyObject *locals)
|
|||
return NULL;
|
||||
}
|
||||
(void) PyMarshal_ReadLongFromFile(fp);
|
||||
v = PyMarshal_ReadObjectFromFile(fp);
|
||||
v = PyMarshal_ReadLastObjectFromFile(fp);
|
||||
fclose(fp);
|
||||
if (v == NULL || !PyCode_Check(v)) {
|
||||
Py_XDECREF(v);
|
||||
|
|
Loading…
Reference in New Issue