Commit 42db4157 authored by Jesus Cea's avatar Jesus Cea

MERGE: Closes #15897: zipimport.c doesn't check return value of fseek()

parents cf774549 fb22f542
...@@ -246,6 +246,7 @@ Christopher A. Craig ...@@ -246,6 +246,7 @@ Christopher A. Craig
Jeremy Craven Jeremy Craven
Laura Creighton Laura Creighton
Simon Cross Simon Cross
Felipe Cruz
Drew Csillag Drew Csillag
Joaquin Cuenca Abela Joaquin Cuenca Abela
John Cugini John Cugini
......
...@@ -27,6 +27,9 @@ Core and Builtins ...@@ -27,6 +27,9 @@ Core and Builtins
- Issue #15846: Fix SystemError which happened when using `ast.parse()` in an - Issue #15846: Fix SystemError which happened when using `ast.parse()` in an
exception handler on code with syntax errors. exception handler on code with syntax errors.
- Issue #15897: zipimport.c doesn't check return value of fseek().
Patch by Felipe Cruz.
- Issue #15801: Make sure mappings passed to '%' formatting are actually - Issue #15801: Make sure mappings passed to '%' formatting are actually
subscriptable. subscriptable.
......
...@@ -875,7 +875,12 @@ read_directory(PyObject *archive) ...@@ -875,7 +875,12 @@ read_directory(PyObject *archive)
PyErr_Format(ZipImportError, "can't open Zip file: %R", archive); PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
return NULL; return NULL;
} }
fseek(fp, -22, SEEK_END);
if (fseek(fp, -22, SEEK_END) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
header_position = ftell(fp); header_position = ftell(fp);
if (fread(endof_central_dir, 1, 22, fp) != 22) { if (fread(endof_central_dir, 1, 22, fp) != 22) {
fclose(fp); fclose(fp);
...@@ -904,11 +909,13 @@ read_directory(PyObject *archive) ...@@ -904,11 +909,13 @@ read_directory(PyObject *archive)
PyObject *t; PyObject *t;
int err; int err;
fseek(fp, header_offset, 0); /* Start of file header */ if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
goto fseek_error;
l = PyMarshal_ReadLongFromFile(fp); l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x02014B50) if (l != 0x02014B50)
break; /* Bad: Central Dir File Header */ break; /* Bad: Central Dir File Header */
fseek(fp, header_offset + 8, 0); if (fseek(fp, header_offset + 8, 0) == -1)
goto fseek_error;
flags = (unsigned short)PyMarshal_ReadShortFromFile(fp); flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
compress = PyMarshal_ReadShortFromFile(fp); compress = PyMarshal_ReadShortFromFile(fp);
time = PyMarshal_ReadShortFromFile(fp); time = PyMarshal_ReadShortFromFile(fp);
...@@ -920,7 +927,8 @@ read_directory(PyObject *archive) ...@@ -920,7 +927,8 @@ read_directory(PyObject *archive)
header_size = 46 + name_size + header_size = 46 + name_size +
PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp); PyMarshal_ReadShortFromFile(fp);
fseek(fp, header_offset + 42, 0); if (fseek(fp, header_offset + 42, 0) == -1)
goto fseek_error;
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset; file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
if (name_size > MAXPATHLEN) if (name_size > MAXPATHLEN)
name_size = MAXPATHLEN; name_size = MAXPATHLEN;
...@@ -980,6 +988,12 @@ read_directory(PyObject *archive) ...@@ -980,6 +988,12 @@ read_directory(PyObject *archive)
PySys_FormatStderr("# zipimport: found %ld names in %R\n", PySys_FormatStderr("# zipimport: found %ld names in %R\n",
count, archive); count, archive);
return files; return files;
fseek_error:
fclose(fp);
Py_XDECREF(files);
Py_XDECREF(nameobj);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
error: error:
fclose(fp); fclose(fp);
Py_XDECREF(files); Py_XDECREF(files);
...@@ -1050,7 +1064,12 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -1050,7 +1064,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
} }
/* Check to make sure the local file header is correct */ /* Check to make sure the local file header is correct */
fseek(fp, file_offset, 0); if (fseek(fp, file_offset, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = PyMarshal_ReadLongFromFile(fp); l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x04034B50) { if (l != 0x04034B50) {
/* Bad: Local File Header */ /* Bad: Local File Header */
...@@ -1060,7 +1079,12 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -1060,7 +1079,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
fclose(fp); fclose(fp);
return NULL; return NULL;
} }
fseek(fp, file_offset + 26, 0); if (fseek(fp, file_offset + 26, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = 30 + PyMarshal_ReadShortFromFile(fp) + l = 30 + PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp); /* local header size */ PyMarshal_ReadShortFromFile(fp); /* local header size */
file_offset += l; /* Start of file data */ file_offset += l; /* Start of file data */
...@@ -1077,8 +1101,13 @@ get_data(PyObject *archive, PyObject *toc_entry) ...@@ -1077,8 +1101,13 @@ get_data(PyObject *archive, PyObject *toc_entry)
buf = PyBytes_AsString(raw_data); buf = PyBytes_AsString(raw_data);
err = fseek(fp, file_offset, 0); err = fseek(fp, file_offset, 0);
if (err == 0) if (err == 0) {
bytes_read = fread(buf, 1, data_size, fp); bytes_read = fread(buf, 1, data_size, fp);
} else {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
fclose(fp); fclose(fp);
if (err || bytes_read != data_size) { if (err || bytes_read != data_size) {
PyErr_SetString(PyExc_IOError, PyErr_SetString(PyExc_IOError,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment