From 73660af6afdd8309c85d5e513e319b7f0a5b006e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Oct 2013 01:43:44 +0100 Subject: Issue #19428: zipimport now handles errors when reading truncated or invalid ZIP archive. --- Misc/NEWS | 3 +++ Modules/zipimport.c | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 28ab604..5e6a17b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Projected release date: 2013-11-24 Core and Builtins ----------------- +- Issue #19428: zipimport now handles errors when reading truncated or invalid + ZIP archive. + - Issue #18408: Add a new PyFrame_FastToLocalsWithError() function to handle exceptions when merging fast locals into f_locals of a frame. PyEval_GetLocals() now raises an exception and return NULL on failure. diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 633732f..46b86a0 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -914,6 +914,8 @@ read_directory(PyObject *archive) /* Start of file header */ l = PyMarshal_ReadLongFromFile(fp); + if (l == -1 && PyErr_Occurred()) + goto error; if (l != 0x02014B50) break; /* Bad: Central Dir File Header */ @@ -937,6 +939,9 @@ read_directory(PyObject *archive) if (fread(dummy, 1, 8, fp) != 8) /* Skip unused fields, avoid fseek */ goto file_error; file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset; + if (PyErr_Occurred()) + goto error; + if (name_size > MAXPATHLEN) name_size = MAXPATHLEN; @@ -1082,9 +1087,10 @@ get_data(PyObject *archive, PyObject *toc_entry) l = PyMarshal_ReadLongFromFile(fp); if (l != 0x04034B50) { /* Bad: Local File Header */ - PyErr_Format(ZipImportError, - "bad local file header in %U", - archive); + if (!PyErr_Occurred()) + PyErr_Format(ZipImportError, + "bad local file header in %U", + archive); fclose(fp); return NULL; } @@ -1096,6 +1102,10 @@ get_data(PyObject *archive, PyObject *toc_entry) l = 30 + PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp); /* local header size */ + if (PyErr_Occurred()) { + fclose(fp); + return NULL; + } file_offset += l; /* Start of file data */ bytes_size = compress == 0 ? data_size : data_size + 1; -- cgit v0.12