diff -r 01676a4c16ff Modules/zipimport.c --- a/Modules/zipimport.c Sun Dec 08 10:06:04 2013 +0100 +++ b/Modules/zipimport.c Sun Dec 08 12:07:33 2013 +0100 @@ -818,16 +818,12 @@ static PyTypeObject ZipImporter_Type = { 4 bytes, encoded as little endian. This partially reimplements marshal.c:r_long() */ static long -get_long(unsigned char *buf) { - long x; +get_ulong(unsigned char *buf) { + unsigned long x; x = buf[0]; - x |= (long)buf[1] << 8; - x |= (long)buf[2] << 16; - x |= (long)buf[3] << 24; -#if SIZEOF_LONG > 4 - /* Sign extension for 64-bit machines */ - x |= -(x & 0x80000000L); -#endif + x |= (unsigned long)buf[1] << 8; + x |= (unsigned long)buf[2] << 16; + x |= (unsigned long)buf[3] << 24; return x; } @@ -860,10 +856,12 @@ read_directory(PyObject *archive) FILE *fp; unsigned short flags; short compress, time, date, name_size; - long crc, data_size, file_size, header_size; - Py_ssize_t file_offset, header_position, header_offset; - long l, count; - Py_ssize_t i; + long crc, data_size, file_size; + unsigned long header_size, header_offset; + Py_ssize_t file_offset, header_position; + long l; + unsigned long count; + size_t i; char name[MAXPATHLEN + 5]; char dummy[8]; /* Buffer to read unused header values into */ PyObject *nameobj = NULL; @@ -880,28 +878,25 @@ read_directory(PyObject *archive) return NULL; } - if (fseek(fp, -22, SEEK_END) == -1) { - fclose(fp); - PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); - return NULL; - } + if (fseek(fp, -22, SEEK_END) == -1) + goto invalid_header; header_position = ftell(fp); - if (fread(endof_central_dir, 1, 22, fp) != 22) { - fclose(fp); - PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); - return NULL; - } - if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) { + if (fread(endof_central_dir, 1, 22, fp) != 22) + goto invalid_header; + if (get_ulong((unsigned char *)endof_central_dir) != 0x06054B50UL) /* Bad: End of Central Dir signature */ - fclose(fp); - PyErr_Format(ZipImportError, "not a Zip file: %R", archive); - return NULL; - } + goto invalid_header; - header_size = get_long((unsigned char *)endof_central_dir + 12); - header_offset = get_long((unsigned char *)endof_central_dir + 16); + header_size = get_ulong((unsigned char *)endof_central_dir + 12); + header_offset = get_ulong((unsigned char *)endof_central_dir + 16); + if (header_offset > ULONG_MAX - header_size) + goto invalid_header; + if (header_position < header_offset + header_size) + goto invalid_header; arc_offset = header_position - header_offset - header_size; - header_offset += arc_offset; + if (header_position < header_size) + goto invalid_header; + header_offset = header_position - header_size; files = PyDict_New(); if (files == NULL) @@ -949,7 +944,7 @@ read_directory(PyObject *archive) name_size = MAXPATHLEN; p = name; - for (i = 0; i < (Py_ssize_t)name_size; i++) { + for (i = 0; i < (size_t)name_size; i++) { *p = (char)getc(fp); if (*p == '/') *p = SEP; @@ -1002,7 +997,7 @@ read_directory(PyObject *archive) } fclose(fp); if (Py_VerboseFlag) - PySys_FormatStderr("# zipimport: found %ld names in %R\n", + PySys_FormatStderr("# zipimport: found %lu names in %R\n", count, archive); return files; file_error: @@ -1011,6 +1006,8 @@ file_error: Py_XDECREF(nameobj); PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); return NULL; +invalid_header: + PyErr_Format(ZipImportError, "not a Zip file: %R", archive); error: fclose(fp); Py_XDECREF(files); @@ -1196,7 +1193,7 @@ unmarshal_code(PyObject *pathname, PyObj return NULL; } - if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) { + if (get_ulong((unsigned char *)buf) != PyImport_GetMagicNumber()) { if (Py_VerboseFlag) PySys_FormatStderr("# %R has bad magic\n", pathname); @@ -1204,7 +1201,7 @@ unmarshal_code(PyObject *pathname, PyObj return Py_None; /* signal caller to try alternative */ } - if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), + if (mtime != 0 && !eq_mtime(get_ulong((unsigned char *)buf + 4), mtime)) { if (Py_VerboseFlag) PySys_FormatStderr("# %R has bad mtime\n",