Commit e884be67 authored by Jesus Cea's avatar Jesus Cea

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

parent 31a9e83d
...@@ -204,6 +204,7 @@ Christopher A. Craig ...@@ -204,6 +204,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
......
...@@ -38,6 +38,9 @@ Core and Builtins ...@@ -38,6 +38,9 @@ Core and Builtins
- Issue #15368: An issue that caused bytecode generation to be - Issue #15368: An issue that caused bytecode generation to be
non-deterministic when using randomized hashing (-R) has been fixed. non-deterministic when using randomized hashing (-R) has been fixed.
- 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.
......
...@@ -709,7 +709,12 @@ read_directory(char *archive) ...@@ -709,7 +709,12 @@ read_directory(char *archive)
"'%.200s'", archive); "'%.200s'", 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: %s", 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);
...@@ -743,11 +748,13 @@ read_directory(char *archive) ...@@ -743,11 +748,13 @@ read_directory(char *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 + 10, 0); if (fseek(fp, header_offset + 10, 0) == -1)
goto fseek_error;
compress = PyMarshal_ReadShortFromFile(fp); compress = PyMarshal_ReadShortFromFile(fp);
time = PyMarshal_ReadShortFromFile(fp); time = PyMarshal_ReadShortFromFile(fp);
date = PyMarshal_ReadShortFromFile(fp); date = PyMarshal_ReadShortFromFile(fp);
...@@ -758,7 +765,8 @@ read_directory(char *archive) ...@@ -758,7 +765,8 @@ read_directory(char *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;
...@@ -790,6 +798,11 @@ read_directory(char *archive) ...@@ -790,6 +798,11 @@ read_directory(char *archive)
PySys_WriteStderr("# zipimport: found %ld names in %s\n", PySys_WriteStderr("# zipimport: found %ld names in %s\n",
count, archive); count, archive);
return files; return files;
fseek_error:
fclose(fp);
Py_XDECREF(files);
PyErr_Format(ZipImportError, "can't read Zip file: %s", archive);
return NULL;
error: error:
fclose(fp); fclose(fp);
Py_XDECREF(files); Py_XDECREF(files);
...@@ -857,7 +870,12 @@ get_data(char *archive, PyObject *toc_entry) ...@@ -857,7 +870,12 @@ get_data(char *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: %s", 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 */
...@@ -867,7 +885,12 @@ get_data(char *archive, PyObject *toc_entry) ...@@ -867,7 +885,12 @@ get_data(char *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: %s", 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 */
...@@ -881,8 +904,13 @@ get_data(char *archive, PyObject *toc_entry) ...@@ -881,8 +904,13 @@ get_data(char *archive, PyObject *toc_entry)
buf = PyString_AsString(raw_data); buf = PyString_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: %s", 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