summaryrefslogtreecommitdiffstats
path: root/Modules/zlibmodule.c
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2016-06-05 10:48:34 (GMT)
committerMartin Panter <vadmium+py@gmail.com>2016-06-05 10:48:34 (GMT)
commit3f0ee83f14f2ce2c05360f5ed326844388353b6f (patch)
tree7a222185d5377d9b6e3e423c29a849fad47859a3 /Modules/zlibmodule.c
parent484c913ed9fc438cedd2757d6124ab1bac4239be (diff)
downloadcpython-3f0ee83f14f2ce2c05360f5ed326844388353b6f.zip
cpython-3f0ee83f14f2ce2c05360f5ed326844388353b6f.tar.gz
cpython-3f0ee83f14f2ce2c05360f5ed326844388353b6f.tar.bz2
Issue #27164: Allow decompressing raw Deflate streams with predefined zdict
Based on patch by Xiang Zhang.
Diffstat (limited to 'Modules/zlibmodule.c')
-rw-r--r--Modules/zlibmodule.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 02c747e..16cc178 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -22,6 +22,10 @@
#define LEAVE_ZLIB(obj)
#endif
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
+#define AT_LEAST_ZLIB_1_2_2_1
+#endif
+
/* The following parameters are copied from zutil.h, version 0.95 */
#define DEFLATED 8
#if MAX_MEM_LEVEL >= 8
@@ -474,6 +478,31 @@ zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits,
return (PyObject*)self;
}
+static int
+set_inflate_zdict(compobject *self)
+{
+ Py_buffer zdict_buf;
+ int err;
+
+ if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) {
+ return -1;
+ }
+ if ((size_t)zdict_buf.len > UINT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "zdict length does not fit in an unsigned int");
+ PyBuffer_Release(&zdict_buf);
+ return -1;
+ }
+ err = inflateSetDictionary(&(self->zst),
+ zdict_buf.buf, (unsigned int)zdict_buf.len);
+ PyBuffer_Release(&zdict_buf);
+ if (err != Z_OK) {
+ zlib_error(self->zst, err, "while setting zdict");
+ return -1;
+ }
+ return 0;
+}
+
/*[clinic input]
zlib.decompressobj
@@ -515,6 +544,20 @@ zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict)
switch(err) {
case (Z_OK):
self->is_initialised = 1;
+ if (self->zdict != NULL && wbits < 0) {
+#ifdef AT_LEAST_ZLIB_1_2_2_1
+ if (set_inflate_zdict(self) < 0) {
+ Py_DECREF(self);
+ return NULL;
+ }
+#else
+ PyErr_Format(ZlibError,
+ "zlib version %s does not allow raw inflate with dictionary",
+ ZLIB_VERSION);
+ Py_DECREF(self);
+ return NULL;
+#endif
+ }
return (PyObject*)self;
case(Z_STREAM_ERROR):
Py_DECREF(self);
@@ -741,29 +784,12 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data,
Py_END_ALLOW_THREADS
if (err == Z_NEED_DICT && self->zdict != NULL) {
- Py_buffer zdict_buf;
- if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) {
+ if (set_inflate_zdict(self) < 0) {
Py_DECREF(RetVal);
RetVal = NULL;
goto error;
}
- if ((size_t)zdict_buf.len > UINT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "zdict length does not fit in an unsigned int");
- PyBuffer_Release(&zdict_buf);
- Py_CLEAR(RetVal);
- goto error;
- }
-
- err = inflateSetDictionary(&(self->zst),
- zdict_buf.buf, (unsigned int)zdict_buf.len);
- PyBuffer_Release(&zdict_buf);
- if (err != Z_OK) {
- zlib_error(self->zst, err, "while decompressing data");
- Py_CLEAR(RetVal);
- goto error;
- }
/* Repeat the call to inflate. */
Py_BEGIN_ALLOW_THREADS
err = inflate(&(self->zst), Z_SYNC_FLUSH);