Skip to content

Commit 09bf7a7

Browse files
committed
Closes #15897: zipimport.c doesn't check return value of fseek()
1 parent f532035 commit 09bf7a7

3 files changed

Lines changed: 40 additions & 7 deletions

File tree

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ Christopher A. Craig
227227
Jeremy Craven
228228
Laura Creighton
229229
Simon Cross
230+
Felipe Cruz
230231
Drew Csillag
231232
Joaquin Cuenca Abela
232233
John Cugini

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Core and Builtins
4949
- Issue #15020: The program name used to search for Python's path is now
5050
"python3" under Unix, not "python".
5151

52+
- Issue #15897: zipimport.c doesn't check return value of fseek().
53+
Patch by Felipe Cruz.
54+
5255
- Issue #15033: Fix the exit status bug when modules invoked using -m swith,
5356
return the proper failure return value (1). Patch contributed by Jeff Knupp.
5457

Modules/zipimport.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,12 @@ read_directory(PyObject *archive_obj)
741741
PyErr_Format(ZipImportError, "can't open Zip file: '%U'", archive_obj);
742742
return NULL;
743743
}
744-
fseek(fp, -22, SEEK_END);
744+
745+
if (fseek(fp, -22, SEEK_END) == -1) {
746+
fclose(fp);
747+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
748+
return NULL;
749+
}
745750
header_position = ftell(fp);
746751
if (fread(endof_central_dir, 1, 22, fp) != 22) {
747752
fclose(fp);
@@ -773,11 +778,13 @@ read_directory(PyObject *archive_obj)
773778
PyObject *t;
774779
int err;
775780

776-
fseek(fp, header_offset, 0); /* Start of file header */
781+
if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
782+
goto fseek_error;
777783
l = PyMarshal_ReadLongFromFile(fp);
778784
if (l != 0x02014B50)
779785
break; /* Bad: Central Dir File Header */
780-
fseek(fp, header_offset + 8, 0);
786+
if (fseek(fp, header_offset + 8, 0) == -1)
787+
goto fseek_error;
781788
flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
782789
compress = PyMarshal_ReadShortFromFile(fp);
783790
time = PyMarshal_ReadShortFromFile(fp);
@@ -789,7 +796,8 @@ read_directory(PyObject *archive_obj)
789796
header_size = 46 + name_size +
790797
PyMarshal_ReadShortFromFile(fp) +
791798
PyMarshal_ReadShortFromFile(fp);
792-
fseek(fp, header_offset + 42, 0);
799+
if (fseek(fp, header_offset + 42, 0) == -1)
800+
goto fseek_error;
793801
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
794802
if (name_size > MAXPATHLEN)
795803
name_size = MAXPATHLEN;
@@ -849,6 +857,12 @@ read_directory(PyObject *archive_obj)
849857
PySys_FormatStderr("# zipimport: found %ld names in %U\n",
850858
count, archive_obj);
851859
return files;
860+
fseek_error:
861+
fclose(fp);
862+
Py_XDECREF(files);
863+
Py_XDECREF(nameobj);
864+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
865+
return NULL;
852866
error:
853867
fclose(fp);
854868
Py_XDECREF(files);
@@ -918,7 +932,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
918932
}
919933

920934
/* Check to make sure the local file header is correct */
921-
fseek(fp, file_offset, 0);
935+
if (fseek(fp, file_offset, 0) == -1) {
936+
fclose(fp);
937+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
938+
return NULL;
939+
}
940+
922941
l = PyMarshal_ReadLongFromFile(fp);
923942
if (l != 0x04034B50) {
924943
/* Bad: Local File Header */
@@ -928,7 +947,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
928947
fclose(fp);
929948
return NULL;
930949
}
931-
fseek(fp, file_offset + 26, 0);
950+
if (fseek(fp, file_offset + 26, 0) == -1) {
951+
fclose(fp);
952+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
953+
return NULL;
954+
}
955+
932956
l = 30 + PyMarshal_ReadShortFromFile(fp) +
933957
PyMarshal_ReadShortFromFile(fp); /* local header size */
934958
file_offset += l; /* Start of file data */
@@ -945,8 +969,13 @@ get_data(PyObject *archive, PyObject *toc_entry)
945969
buf = PyBytes_AsString(raw_data);
946970

947971
err = fseek(fp, file_offset, 0);
948-
if (err == 0)
972+
if (err == 0) {
949973
bytes_read = fread(buf, 1, data_size, fp);
974+
} else {
975+
fclose(fp);
976+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
977+
return NULL;
978+
}
950979
fclose(fp);
951980
if (err || bytes_read != data_size) {
952981
PyErr_SetString(PyExc_IOError,

0 commit comments

Comments
 (0)