Skip to content

Commit fb22f54

Browse files
committed
MERGE: Closes #15897: zipimport.c doesn't check return value of fseek()
2 parents 3430fb8 + 09bf7a7 commit fb22f54

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
@@ -246,6 +246,7 @@ Christopher A. Craig
246246
Jeremy Craven
247247
Laura Creighton
248248
Simon Cross
249+
Felipe Cruz
249250
Drew Csillag
250251
Joaquin Cuenca Abela
251252
John Cugini

Misc/NEWS

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

470+
- Issue #15897: zipimport.c doesn't check return value of fseek().
471+
Patch by Felipe Cruz.
472+
470473
- Issue #15033: Fix the exit status bug when modules invoked using -m swith,
471474
return the proper failure return value (1). Patch contributed by Jeff Knupp.
472475

Modules/zipimport.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,12 @@ read_directory(PyObject *archive)
875875
PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
876876
return NULL;
877877
}
878-
fseek(fp, -22, SEEK_END);
878+
879+
if (fseek(fp, -22, SEEK_END) == -1) {
880+
fclose(fp);
881+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
882+
return NULL;
883+
}
879884
header_position = ftell(fp);
880885
if (fread(endof_central_dir, 1, 22, fp) != 22) {
881886
fclose(fp);
@@ -904,11 +909,13 @@ read_directory(PyObject *archive)
904909
PyObject *t;
905910
int err;
906911

907-
fseek(fp, header_offset, 0); /* Start of file header */
912+
if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
913+
goto fseek_error;
908914
l = PyMarshal_ReadLongFromFile(fp);
909915
if (l != 0x02014B50)
910916
break; /* Bad: Central Dir File Header */
911-
fseek(fp, header_offset + 8, 0);
917+
if (fseek(fp, header_offset + 8, 0) == -1)
918+
goto fseek_error;
912919
flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
913920
compress = PyMarshal_ReadShortFromFile(fp);
914921
time = PyMarshal_ReadShortFromFile(fp);
@@ -920,7 +927,8 @@ read_directory(PyObject *archive)
920927
header_size = 46 + name_size +
921928
PyMarshal_ReadShortFromFile(fp) +
922929
PyMarshal_ReadShortFromFile(fp);
923-
fseek(fp, header_offset + 42, 0);
930+
if (fseek(fp, header_offset + 42, 0) == -1)
931+
goto fseek_error;
924932
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
925933
if (name_size > MAXPATHLEN)
926934
name_size = MAXPATHLEN;
@@ -980,6 +988,12 @@ read_directory(PyObject *archive)
980988
PySys_FormatStderr("# zipimport: found %ld names in %R\n",
981989
count, archive);
982990
return files;
991+
fseek_error:
992+
fclose(fp);
993+
Py_XDECREF(files);
994+
Py_XDECREF(nameobj);
995+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
996+
return NULL;
983997
error:
984998
fclose(fp);
985999
Py_XDECREF(files);
@@ -1050,7 +1064,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
10501064
}
10511065

10521066
/* Check to make sure the local file header is correct */
1053-
fseek(fp, file_offset, 0);
1067+
if (fseek(fp, file_offset, 0) == -1) {
1068+
fclose(fp);
1069+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1070+
return NULL;
1071+
}
1072+
10541073
l = PyMarshal_ReadLongFromFile(fp);
10551074
if (l != 0x04034B50) {
10561075
/* Bad: Local File Header */
@@ -1060,7 +1079,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
10601079
fclose(fp);
10611080
return NULL;
10621081
}
1063-
fseek(fp, file_offset + 26, 0);
1082+
if (fseek(fp, file_offset + 26, 0) == -1) {
1083+
fclose(fp);
1084+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1085+
return NULL;
1086+
}
1087+
10641088
l = 30 + PyMarshal_ReadShortFromFile(fp) +
10651089
PyMarshal_ReadShortFromFile(fp); /* local header size */
10661090
file_offset += l; /* Start of file data */
@@ -1077,8 +1101,13 @@ get_data(PyObject *archive, PyObject *toc_entry)
10771101
buf = PyBytes_AsString(raw_data);
10781102

10791103
err = fseek(fp, file_offset, 0);
1080-
if (err == 0)
1104+
if (err == 0) {
10811105
bytes_read = fread(buf, 1, data_size, fp);
1106+
} else {
1107+
fclose(fp);
1108+
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1109+
return NULL;
1110+
}
10821111
fclose(fp);
10831112
if (err || bytes_read != data_size) {
10841113
PyErr_SetString(PyExc_IOError,

0 commit comments

Comments
 (0)