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

This commit is contained in:
Jesus Cea 2012-10-03 03:00:37 +02:00
commit fb22f542d2
3 changed files with 40 additions and 7 deletions

View File

@ -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

View File

@ -467,6 +467,9 @@ Core and Builtins
- Issue #15020: The program name used to search for Python's path is now - Issue #15020: The program name used to search for Python's path is now
"python3" under Unix, not "python". "python3" under Unix, not "python".
- Issue #15897: zipimport.c doesn't check return value of fseek().
Patch by Felipe Cruz.
- Issue #15033: Fix the exit status bug when modules invoked using -m swith, - Issue #15033: Fix the exit status bug when modules invoked using -m swith,
return the proper failure return value (1). Patch contributed by Jeff Knupp. return the proper failure return value (1). Patch contributed by Jeff Knupp.

View File

@ -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)
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)
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)
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)
} }
/* 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)
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)
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,