/* Given a path to a Zip file and a toc_entry, return the (uncompressed) data as a new reference. */ static PyObject * get_data(char *archive, PyObject *toc_entry) { PyObject *raw_data, *data = NULL, *decompress; char *buf; FILE *fp; int err; Py_ssize_t bytes_read = 0; long l; char *datapath; long compress, data_size, file_size, file_offset; long time, date, crc; if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress, &data_size, &file_size, &file_offset, &time, &date, &crc)) { return NULL; } fp = fopen(archive, "rb"); if (!fp) { PyErr_Format(PyExc_IOError, "zipimport: can not open file %s", archive); return NULL; } /* Check to make sure the local file header is correct */ fseek(fp, file_offset, 0); l = PyMarshal_ReadLongFromFile(fp); if (l != 0x04034B50) { /* Bad: Local File Header */ PyErr_Format(ZipImportError, "bad local file header in %s", archive); fclose(fp); return NULL; } fseek(fp, file_offset + 26, 0); l = 30 + PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp); /* local header size */ file_offset += l; /* Start of file data */ raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ? data_size : data_size + 1); if (raw_data == NULL) { fclose(fp); return NULL; } buf = PyString_AsString(raw_data); err = fseek(fp, file_offset, 0); if (err == 0) bytes_read = fread(buf, 1, data_size, fp); fclose(fp); if (err || bytes_read != data_size) { PyErr_SetString(PyExc_IOError, "zipimport: can't read data"); Py_DECREF(raw_data); return NULL; } if (compress != 0) { buf[data_size] = 'Z'; /* saw this in zipfile.py */ data_size++; } buf[data_size] = '\0'; if (compress == 0) /* data is not compressed */ return raw_data; /* Decompress with zlib */ decompress = get_decompress_func(); if (decompress == NULL) { PyErr_SetString(ZipImportError, "can't decompress data; " "zlib not available"); goto error; } data = PyObject_CallFunction(decompress, "Oi", raw_data, -15); error: Py_DECREF(raw_data); return data; }
/* Given a path to a Zip file and a toc_entry, return the (uncompressed) data as a new reference. */ static PyObject * get_data(PyObject *archive, PyObject *toc_entry) { PyObject *raw_data = NULL, *data, *decompress; char *buf; FILE *fp; PyObject *datapath; unsigned short compress, time, date; unsigned int crc; Py_ssize_t data_size, file_size, bytes_size; long file_offset, header_size; unsigned char buffer[30]; const char *errmsg = NULL; if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress, &data_size, &file_size, &file_offset, &time, &date, &crc)) { return NULL; } if (data_size < 0) { PyErr_Format(ZipImportError, "negative data size"); return NULL; } fp = _Py_fopen_obj(archive, "rb"); if (!fp) { return NULL; } /* Check to make sure the local file header is correct */ if (fseek(fp, file_offset, 0) == -1) { goto file_error; } if (fread(buffer, 1, 30, fp) != 30) { goto eof_error; } if (get_uint32(buffer) != 0x04034B50u) { /* Bad: Local File Header */ errmsg = "bad local file header"; goto invalid_header; } header_size = (unsigned int)30 + get_uint16(buffer + 26) /* file name */ + get_uint16(buffer + 28) /* extra field */; if (file_offset > LONG_MAX - header_size) { errmsg = "bad local file header size"; goto invalid_header; } file_offset += header_size; /* Start of file data */ if (data_size > LONG_MAX - 1) { fclose(fp); PyErr_NoMemory(); return NULL; } bytes_size = compress == 0 ? data_size : data_size + 1; if (bytes_size == 0) { bytes_size++; } raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size); if (raw_data == NULL) { goto error; } buf = PyBytes_AsString(raw_data); if (fseek(fp, file_offset, 0) == -1) { goto file_error; } if (fread(buf, 1, data_size, fp) != (size_t)data_size) { PyErr_SetString(PyExc_IOError, "zipimport: can't read data"); goto error; } fclose(fp); fp = NULL; if (compress != 0) { buf[data_size] = 'Z'; /* saw this in zipfile.py */ data_size++; } buf[data_size] = '\0'; if (compress == 0) { /* data is not compressed */ data = PyBytes_FromStringAndSize(buf, data_size); Py_DECREF(raw_data); return data; } /* Decompress with zlib */ decompress = get_decompress_func(); if (decompress == NULL) { PyErr_SetString(ZipImportError, "can't decompress data; " "zlib not available"); goto error; } data = PyObject_CallFunction(decompress, "Oi", raw_data, -15); Py_DECREF(decompress); Py_DECREF(raw_data); return data; eof_error: set_file_error(archive, !ferror(fp)); goto error; file_error: PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); goto error; invalid_header: assert(errmsg != NULL); PyErr_Format(ZipImportError, "%s: %R", errmsg, archive); goto error; error: if (fp != NULL) { fclose(fp); } Py_XDECREF(raw_data); return NULL; }