1 /* _lzma - Low-level Python interface to liblzma.
2 
3    Initial implementation by Per Øyvind Karlsen.
4    Rewritten by Nadeem Vawda.
5 
6 */
7 
8 #define PY_SSIZE_T_CLEAN
9 
10 #include "Python.h"
11 #include "structmember.h"
12 #ifdef WITH_THREAD
13 #include "pythread.h"
14 #endif
15 
16 #include <stdarg.h>
17 #include <string.h>
18 
19 #include <lzma.h>
20 
21 #ifdef WITH_THREAD
22 #define ACQUIRE_LOCK(obj) do { \
23     if (!PyThread_acquire_lock((obj)->lock, 0)) { \
24         Py_BEGIN_ALLOW_THREADS \
25         PyThread_acquire_lock((obj)->lock, 1); \
26         Py_END_ALLOW_THREADS \
27     } } while (0)
28 #define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
29 #else
30 #define ACQUIRE_LOCK(obj)
31 #define RELEASE_LOCK(obj)
32 #endif
33 
34 
35 /* Container formats: */
36 enum {
37     FORMAT_AUTO,
38     FORMAT_XZ,
39     FORMAT_ALONE,
40     FORMAT_RAW,
41 };
42 
43 #define LZMA_CHECK_UNKNOWN (LZMA_CHECK_ID_MAX + 1)
44 
45 
46 typedef struct {
47     PyObject_HEAD
48     lzma_allocator alloc;
49     lzma_stream lzs;
50     int flushed;
51 #ifdef WITH_THREAD
52     PyThread_type_lock lock;
53 #endif
54 } Compressor;
55 
56 typedef struct {
57     PyObject_HEAD
58     lzma_allocator alloc;
59     lzma_stream lzs;
60     int check;
61     char eof;
62     PyObject *unused_data;
63     char needs_input;
64     uint8_t *input_buffer;
65     size_t input_buffer_size;
66 #ifdef WITH_THREAD
67     PyThread_type_lock lock;
68 #endif
69 } Decompressor;
70 
71 /* LZMAError class object. */
72 static PyObject *Error;
73 
74 /* An empty tuple, used by the filter specifier parsing code. */
75 static PyObject *empty_tuple;
76 
77 
78 /* Helper functions. */
79 
80 static int
catch_lzma_error(lzma_ret lzret)81 catch_lzma_error(lzma_ret lzret)
82 {
83     switch (lzret) {
84         case LZMA_OK:
85         case LZMA_GET_CHECK:
86         case LZMA_NO_CHECK:
87         case LZMA_STREAM_END:
88             return 0;
89         case LZMA_UNSUPPORTED_CHECK:
90             PyErr_SetString(Error, "Unsupported integrity check");
91             return 1;
92         case LZMA_MEM_ERROR:
93             PyErr_NoMemory();
94             return 1;
95         case LZMA_MEMLIMIT_ERROR:
96             PyErr_SetString(Error, "Memory usage limit exceeded");
97             return 1;
98         case LZMA_FORMAT_ERROR:
99             PyErr_SetString(Error, "Input format not supported by decoder");
100             return 1;
101         case LZMA_OPTIONS_ERROR:
102             PyErr_SetString(Error, "Invalid or unsupported options");
103             return 1;
104         case LZMA_DATA_ERROR:
105             PyErr_SetString(Error, "Corrupt input data");
106             return 1;
107         case LZMA_BUF_ERROR:
108             PyErr_SetString(Error, "Insufficient buffer space");
109             return 1;
110         case LZMA_PROG_ERROR:
111             PyErr_SetString(Error, "Internal error");
112             return 1;
113         default:
114             PyErr_Format(Error, "Unrecognized error from liblzma: %d", lzret);
115             return 1;
116     }
117 }
118 
119 static void*
PyLzma_Malloc(void * opaque,size_t items,size_t size)120 PyLzma_Malloc(void *opaque, size_t items, size_t size)
121 {
122     if (items > (size_t)PY_SSIZE_T_MAX / size)
123         return NULL;
124     /* PyMem_Malloc() cannot be used:
125        the GIL is not held when lzma_code() is called */
126     return PyMem_RawMalloc(items * size);
127 }
128 
129 static void
PyLzma_Free(void * opaque,void * ptr)130 PyLzma_Free(void *opaque, void *ptr)
131 {
132     PyMem_RawFree(ptr);
133 }
134 
135 #if BUFSIZ < 8192
136 #define INITIAL_BUFFER_SIZE 8192
137 #else
138 #define INITIAL_BUFFER_SIZE BUFSIZ
139 #endif
140 
141 static int
grow_buffer(PyObject ** buf,Py_ssize_t max_length)142 grow_buffer(PyObject **buf, Py_ssize_t max_length)
143 {
144     Py_ssize_t size = PyBytes_GET_SIZE(*buf);
145     Py_ssize_t newsize = size + (size >> 3) + 6;
146 
147     if (max_length > 0 && newsize > max_length)
148         newsize = max_length;
149 
150     return _PyBytes_Resize(buf, newsize);
151 }
152 
153 
154 /* Some custom type conversions for PyArg_ParseTupleAndKeywords(),
155    since the predefined conversion specifiers do not suit our needs:
156 
157       uint32_t - the "I" (unsigned int) specifier is the right size, but
158       silently ignores overflows on conversion.
159 
160       lzma_vli - the "K" (unsigned long long) specifier is the right
161       size, but like "I" it silently ignores overflows on conversion.
162 
163       lzma_mode and lzma_match_finder - these are enumeration types, and
164       so the size of each is implementation-defined. Worse, different
165       enum types can be of different sizes within the same program, so
166       to be strictly correct, we need to define two separate converters.
167  */
168 
169 #define INT_TYPE_CONVERTER_FUNC(TYPE, FUNCNAME) \
170     static int \
171     FUNCNAME(PyObject *obj, void *ptr) \
172     { \
173         unsigned long long val; \
174         \
175         val = PyLong_AsUnsignedLongLong(obj); \
176         if (PyErr_Occurred()) \
177             return 0; \
178         if ((unsigned long long)(TYPE)val != val) { \
179             PyErr_SetString(PyExc_OverflowError, \
180                             "Value too large for " #TYPE " type"); \
181             return 0; \
182         } \
183         *(TYPE *)ptr = (TYPE)val; \
184         return 1; \
185     }
186 
INT_TYPE_CONVERTER_FUNC(uint32_t,uint32_converter)187 INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter)
188 INT_TYPE_CONVERTER_FUNC(lzma_vli, lzma_vli_converter)
189 INT_TYPE_CONVERTER_FUNC(lzma_mode, lzma_mode_converter)
190 INT_TYPE_CONVERTER_FUNC(lzma_match_finder, lzma_mf_converter)
191 
192 #undef INT_TYPE_CONVERTER_FUNC
193 
194 
195 /* Filter specifier parsing.
196 
197    This code handles converting filter specifiers (Python dicts) into
198    the C lzma_filter structs expected by liblzma. */
199 
200 static void *
201 parse_filter_spec_lzma(PyObject *spec)
202 {
203     static char *optnames[] = {"id", "preset", "dict_size", "lc", "lp",
204                                "pb", "mode", "nice_len", "mf", "depth", NULL};
205     PyObject *id;
206     PyObject *preset_obj;
207     uint32_t preset = LZMA_PRESET_DEFAULT;
208     lzma_options_lzma *options;
209 
210     /* First, fill in default values for all the options using a preset.
211        Then, override the defaults with any values given by the caller. */
212 
213     preset_obj = PyMapping_GetItemString(spec, "preset");
214     if (preset_obj == NULL) {
215         if (PyErr_ExceptionMatches(PyExc_KeyError))
216             PyErr_Clear();
217         else
218             return NULL;
219     } else {
220         int ok = uint32_converter(preset_obj, &preset);
221         Py_DECREF(preset_obj);
222         if (!ok)
223             return NULL;
224     }
225 
226     options = (lzma_options_lzma *)PyMem_Malloc(sizeof *options);
227     if (options == NULL)
228         return PyErr_NoMemory();
229     memset(options, 0, sizeof *options);
230 
231     if (lzma_lzma_preset(options, preset)) {
232         PyMem_Free(options);
233         PyErr_Format(Error, "Invalid compression preset: %d", preset);
234         return NULL;
235     }
236 
237     if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec,
238                                      "|OOO&O&O&O&O&O&O&O&", optnames,
239                                      &id, &preset_obj,
240                                      uint32_converter, &options->dict_size,
241                                      uint32_converter, &options->lc,
242                                      uint32_converter, &options->lp,
243                                      uint32_converter, &options->pb,
244                                      lzma_mode_converter, &options->mode,
245                                      uint32_converter, &options->nice_len,
246                                      lzma_mf_converter, &options->mf,
247                                      uint32_converter, &options->depth)) {
248         PyErr_SetString(PyExc_ValueError,
249                         "Invalid filter specifier for LZMA filter");
250         PyMem_Free(options);
251         options = NULL;
252     }
253     return options;
254 }
255 
256 static void *
parse_filter_spec_delta(PyObject * spec)257 parse_filter_spec_delta(PyObject *spec)
258 {
259     static char *optnames[] = {"id", "dist", NULL};
260     PyObject *id;
261     uint32_t dist = 1;
262     lzma_options_delta *options;
263 
264     if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames,
265                                      &id, uint32_converter, &dist)) {
266         PyErr_SetString(PyExc_ValueError,
267                         "Invalid filter specifier for delta filter");
268         return NULL;
269     }
270 
271     options = (lzma_options_delta *)PyMem_Malloc(sizeof *options);
272     if (options == NULL)
273         return PyErr_NoMemory();
274     memset(options, 0, sizeof *options);
275     options->type = LZMA_DELTA_TYPE_BYTE;
276     options->dist = dist;
277     return options;
278 }
279 
280 static void *
parse_filter_spec_bcj(PyObject * spec)281 parse_filter_spec_bcj(PyObject *spec)
282 {
283     static char *optnames[] = {"id", "start_offset", NULL};
284     PyObject *id;
285     uint32_t start_offset = 0;
286     lzma_options_bcj *options;
287 
288     if (!PyArg_ParseTupleAndKeywords(empty_tuple, spec, "|OO&", optnames,
289                                      &id, uint32_converter, &start_offset)) {
290         PyErr_SetString(PyExc_ValueError,
291                         "Invalid filter specifier for BCJ filter");
292         return NULL;
293     }
294 
295     options = (lzma_options_bcj *)PyMem_Malloc(sizeof *options);
296     if (options == NULL)
297         return PyErr_NoMemory();
298     memset(options, 0, sizeof *options);
299     options->start_offset = start_offset;
300     return options;
301 }
302 
303 static int
lzma_filter_converter(PyObject * spec,void * ptr)304 lzma_filter_converter(PyObject *spec, void *ptr)
305 {
306     lzma_filter *f = (lzma_filter *)ptr;
307     PyObject *id_obj;
308 
309     if (!PyMapping_Check(spec)) {
310         PyErr_SetString(PyExc_TypeError,
311                         "Filter specifier must be a dict or dict-like object");
312         return 0;
313     }
314     id_obj = PyMapping_GetItemString(spec, "id");
315     if (id_obj == NULL) {
316         if (PyErr_ExceptionMatches(PyExc_KeyError))
317             PyErr_SetString(PyExc_ValueError,
318                             "Filter specifier must have an \"id\" entry");
319         return 0;
320     }
321     f->id = PyLong_AsUnsignedLongLong(id_obj);
322     Py_DECREF(id_obj);
323     if (PyErr_Occurred())
324         return 0;
325 
326     switch (f->id) {
327         case LZMA_FILTER_LZMA1:
328         case LZMA_FILTER_LZMA2:
329             f->options = parse_filter_spec_lzma(spec);
330             return f->options != NULL;
331         case LZMA_FILTER_DELTA:
332             f->options = parse_filter_spec_delta(spec);
333             return f->options != NULL;
334         case LZMA_FILTER_X86:
335         case LZMA_FILTER_POWERPC:
336         case LZMA_FILTER_IA64:
337         case LZMA_FILTER_ARM:
338         case LZMA_FILTER_ARMTHUMB:
339         case LZMA_FILTER_SPARC:
340             f->options = parse_filter_spec_bcj(spec);
341             return f->options != NULL;
342         default:
343             PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id);
344             return 0;
345     }
346 }
347 
348 static void
free_filter_chain(lzma_filter filters[])349 free_filter_chain(lzma_filter filters[])
350 {
351     int i;
352 
353     for (i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++)
354         PyMem_Free(filters[i].options);
355 }
356 
357 static int
parse_filter_chain_spec(lzma_filter filters[],PyObject * filterspecs)358 parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs)
359 {
360     Py_ssize_t i, num_filters;
361 
362     num_filters = PySequence_Length(filterspecs);
363     if (num_filters == -1)
364         return -1;
365     if (num_filters > LZMA_FILTERS_MAX) {
366         PyErr_Format(PyExc_ValueError,
367                      "Too many filters - liblzma supports a maximum of %d",
368                      LZMA_FILTERS_MAX);
369         return -1;
370     }
371 
372     for (i = 0; i < num_filters; i++) {
373         int ok = 1;
374         PyObject *spec = PySequence_GetItem(filterspecs, i);
375         if (spec == NULL || !lzma_filter_converter(spec, &filters[i]))
376             ok = 0;
377         Py_XDECREF(spec);
378         if (!ok) {
379             filters[i].id = LZMA_VLI_UNKNOWN;
380             free_filter_chain(filters);
381             return -1;
382         }
383     }
384     filters[num_filters].id = LZMA_VLI_UNKNOWN;
385     return 0;
386 }
387 
388 
389 /* Filter specifier construction.
390 
391    This code handles converting C lzma_filter structs into
392    Python-level filter specifiers (represented as dicts). */
393 
394 static int
spec_add_field(PyObject * spec,_Py_Identifier * key,unsigned long long value)395 spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value)
396 {
397     int status;
398     PyObject *value_object;
399 
400     value_object = PyLong_FromUnsignedLongLong(value);
401     if (value_object == NULL)
402         return -1;
403 
404     status = _PyDict_SetItemId(spec, key, value_object);
405     Py_DECREF(value_object);
406     return status;
407 }
408 
409 static PyObject *
build_filter_spec(const lzma_filter * f)410 build_filter_spec(const lzma_filter *f)
411 {
412     PyObject *spec;
413 
414     spec = PyDict_New();
415     if (spec == NULL)
416         return NULL;
417 
418 #define ADD_FIELD(SOURCE, FIELD) \
419     do { \
420         _Py_IDENTIFIER(FIELD); \
421         if (spec_add_field(spec, &PyId_##FIELD, SOURCE->FIELD) == -1) \
422             goto error;\
423     } while (0)
424 
425     ADD_FIELD(f, id);
426 
427     switch (f->id) {
428         /* For LZMA1 filters, lzma_properties_{encode,decode}() only look at the
429            lc, lp, pb, and dict_size fields. For LZMA2 filters, only the
430            dict_size field is used. */
431         case LZMA_FILTER_LZMA1: {
432             lzma_options_lzma *options = f->options;
433             ADD_FIELD(options, lc);
434             ADD_FIELD(options, lp);
435             ADD_FIELD(options, pb);
436             ADD_FIELD(options, dict_size);
437             break;
438         }
439         case LZMA_FILTER_LZMA2: {
440             lzma_options_lzma *options = f->options;
441             ADD_FIELD(options, dict_size);
442             break;
443         }
444         case LZMA_FILTER_DELTA: {
445             lzma_options_delta *options = f->options;
446             ADD_FIELD(options, dist);
447             break;
448         }
449         case LZMA_FILTER_X86:
450         case LZMA_FILTER_POWERPC:
451         case LZMA_FILTER_IA64:
452         case LZMA_FILTER_ARM:
453         case LZMA_FILTER_ARMTHUMB:
454         case LZMA_FILTER_SPARC: {
455             lzma_options_bcj *options = f->options;
456             ADD_FIELD(options, start_offset);
457             break;
458         }
459         default:
460             PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id);
461             goto error;
462     }
463 
464 #undef ADD_FIELD
465 
466     return spec;
467 
468 error:
469     Py_DECREF(spec);
470     return NULL;
471 }
472 
473 
474 /*[clinic input]
475 module _lzma
476 class _lzma.LZMACompressor "Compressor *" "&Compressor_type"
477 class _lzma.LZMADecompressor "Decompressor *" "&Decompressor_type"
478 [clinic start generated code]*/
479 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2c14bbe05ff0c147]*/
480 
481 #include "clinic/_lzmamodule.c.h"
482 
483 /*[python input]
484 
485 class lzma_vli_converter(CConverter):
486     type = 'lzma_vli'
487     converter = 'lzma_vli_converter'
488 
489 class lzma_filter_converter(CConverter):
490     type = 'lzma_filter'
491     converter = 'lzma_filter_converter'
492     c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}"
493 
494     def cleanup(self):
495         name = ensure_legal_c_identifier(self.name)
496         return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n'
497                 '   PyMem_Free(%(name)s.options);\n') % {'name': name}
498 
499 [python start generated code]*/
500 /*[python end generated code: output=da39a3ee5e6b4b0d input=74fe7631ce377a94]*/
501 
502 
503 /* LZMACompressor class. */
504 
505 static PyObject *
compress(Compressor * c,uint8_t * data,size_t len,lzma_action action)506 compress(Compressor *c, uint8_t *data, size_t len, lzma_action action)
507 {
508     Py_ssize_t data_size = 0;
509     PyObject *result;
510 
511     result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
512     if (result == NULL)
513         return NULL;
514     c->lzs.next_in = data;
515     c->lzs.avail_in = len;
516     c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result);
517     c->lzs.avail_out = PyBytes_GET_SIZE(result);
518     for (;;) {
519         lzma_ret lzret;
520 
521         Py_BEGIN_ALLOW_THREADS
522         lzret = lzma_code(&c->lzs, action);
523         data_size = (char *)c->lzs.next_out - PyBytes_AS_STRING(result);
524         if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0)
525             lzret = LZMA_OK; /* That wasn't a real error */
526         Py_END_ALLOW_THREADS
527         if (catch_lzma_error(lzret))
528             goto error;
529         if ((action == LZMA_RUN && c->lzs.avail_in == 0) ||
530             (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) {
531             break;
532         } else if (c->lzs.avail_out == 0) {
533             if (grow_buffer(&result, -1) == -1)
534                 goto error;
535             c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size;
536             c->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size;
537         }
538     }
539     if (data_size != PyBytes_GET_SIZE(result))
540         if (_PyBytes_Resize(&result, data_size) == -1)
541             goto error;
542     return result;
543 
544 error:
545     Py_XDECREF(result);
546     return NULL;
547 }
548 
549 /*[clinic input]
550 _lzma.LZMACompressor.compress
551 
552     data: Py_buffer
553     /
554 
555 Provide data to the compressor object.
556 
557 Returns a chunk of compressed data if possible, or b'' otherwise.
558 
559 When you have finished providing data to the compressor, call the
560 flush() method to finish the compression process.
561 [clinic start generated code]*/
562 
563 static PyObject *
_lzma_LZMACompressor_compress_impl(Compressor * self,Py_buffer * data)564 _lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data)
565 /*[clinic end generated code: output=31f615136963e00f input=64019eac7f2cc8d0]*/
566 {
567     PyObject *result = NULL;
568 
569     ACQUIRE_LOCK(self);
570     if (self->flushed)
571         PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
572     else
573         result = compress(self, data->buf, data->len, LZMA_RUN);
574     RELEASE_LOCK(self);
575     return result;
576 }
577 
578 /*[clinic input]
579 _lzma.LZMACompressor.flush
580 
581 Finish the compression process.
582 
583 Returns the compressed data left in internal buffers.
584 
585 The compressor object may not be used after this method is called.
586 [clinic start generated code]*/
587 
588 static PyObject *
_lzma_LZMACompressor_flush_impl(Compressor * self)589 _lzma_LZMACompressor_flush_impl(Compressor *self)
590 /*[clinic end generated code: output=fec21f3e22504f50 input=6b369303f67ad0a8]*/
591 {
592     PyObject *result = NULL;
593 
594     ACQUIRE_LOCK(self);
595     if (self->flushed) {
596         PyErr_SetString(PyExc_ValueError, "Repeated call to flush()");
597     } else {
598         self->flushed = 1;
599         result = compress(self, NULL, 0, LZMA_FINISH);
600     }
601     RELEASE_LOCK(self);
602     return result;
603 }
604 
605 static PyObject *
Compressor_getstate(Compressor * self,PyObject * noargs)606 Compressor_getstate(Compressor *self, PyObject *noargs)
607 {
608     PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
609                  Py_TYPE(self)->tp_name);
610     return NULL;
611 }
612 
613 static int
Compressor_init_xz(lzma_stream * lzs,int check,uint32_t preset,PyObject * filterspecs)614 Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset,
615                    PyObject *filterspecs)
616 {
617     lzma_ret lzret;
618 
619     if (filterspecs == Py_None) {
620         lzret = lzma_easy_encoder(lzs, preset, check);
621     } else {
622         lzma_filter filters[LZMA_FILTERS_MAX + 1];
623 
624         if (parse_filter_chain_spec(filters, filterspecs) == -1)
625             return -1;
626         lzret = lzma_stream_encoder(lzs, filters, check);
627         free_filter_chain(filters);
628     }
629     if (catch_lzma_error(lzret))
630         return -1;
631     else
632         return 0;
633 }
634 
635 static int
Compressor_init_alone(lzma_stream * lzs,uint32_t preset,PyObject * filterspecs)636 Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs)
637 {
638     lzma_ret lzret;
639 
640     if (filterspecs == Py_None) {
641         lzma_options_lzma options;
642 
643         if (lzma_lzma_preset(&options, preset)) {
644             PyErr_Format(Error, "Invalid compression preset: %d", preset);
645             return -1;
646         }
647         lzret = lzma_alone_encoder(lzs, &options);
648     } else {
649         lzma_filter filters[LZMA_FILTERS_MAX + 1];
650 
651         if (parse_filter_chain_spec(filters, filterspecs) == -1)
652             return -1;
653         if (filters[0].id == LZMA_FILTER_LZMA1 &&
654             filters[1].id == LZMA_VLI_UNKNOWN) {
655             lzret = lzma_alone_encoder(lzs, filters[0].options);
656         } else {
657             PyErr_SetString(PyExc_ValueError,
658                             "Invalid filter chain for FORMAT_ALONE - "
659                             "must be a single LZMA1 filter");
660             lzret = LZMA_PROG_ERROR;
661         }
662         free_filter_chain(filters);
663     }
664     if (PyErr_Occurred() || catch_lzma_error(lzret))
665         return -1;
666     else
667         return 0;
668 }
669 
670 static int
Compressor_init_raw(lzma_stream * lzs,PyObject * filterspecs)671 Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
672 {
673     lzma_filter filters[LZMA_FILTERS_MAX + 1];
674     lzma_ret lzret;
675 
676     if (filterspecs == Py_None) {
677         PyErr_SetString(PyExc_ValueError,
678                         "Must specify filters for FORMAT_RAW");
679         return -1;
680     }
681     if (parse_filter_chain_spec(filters, filterspecs) == -1)
682         return -1;
683     lzret = lzma_raw_encoder(lzs, filters);
684     free_filter_chain(filters);
685     if (catch_lzma_error(lzret))
686         return -1;
687     else
688         return 0;
689 }
690 
691 /*[-clinic input]
692 _lzma.LZMACompressor.__init__
693 
694     format: int(c_default="FORMAT_XZ") = FORMAT_XZ
695         The container format to use for the output.  This can
696         be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.
697 
698     check: int(c_default="-1") = unspecified
699         The integrity check to use.  For FORMAT_XZ, the default
700         is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not support integrity
701         checks; for these formats, check must be omitted, or be CHECK_NONE.
702 
703     preset: object = None
704         If provided should be an integer in the range 0-9, optionally
705         OR-ed with the constant PRESET_EXTREME.
706 
707     filters: object = None
708         If provided should be a sequence of dicts.  Each dict should
709         have an entry for "id" indicating the ID of the filter, plus
710         additional entries for options to the filter.
711 
712 Create a compressor object for compressing data incrementally.
713 
714 The settings used by the compressor can be specified either as a
715 preset compression level (with the 'preset' argument), or in detail
716 as a custom filter chain (with the 'filters' argument).  For FORMAT_XZ
717 and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
718 level.  For FORMAT_RAW, the caller must always specify a filter chain;
719 the raw compressor does not support preset compression levels.
720 
721 For one-shot compression, use the compress() function instead.
722 [-clinic start generated code]*/
723 static int
Compressor_init(Compressor * self,PyObject * args,PyObject * kwargs)724 Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
725 {
726     static char *arg_names[] = {"format", "check", "preset", "filters", NULL};
727     int format = FORMAT_XZ;
728     int check = -1;
729     uint32_t preset = LZMA_PRESET_DEFAULT;
730     PyObject *preset_obj = Py_None;
731     PyObject *filterspecs = Py_None;
732 
733     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
734                                      "|iiOO:LZMACompressor", arg_names,
735                                      &format, &check, &preset_obj,
736                                      &filterspecs))
737         return -1;
738 
739     if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) {
740         PyErr_SetString(PyExc_ValueError,
741                         "Integrity checks are only supported by FORMAT_XZ");
742         return -1;
743     }
744 
745     if (preset_obj != Py_None && filterspecs != Py_None) {
746         PyErr_SetString(PyExc_ValueError,
747                         "Cannot specify both preset and filter chain");
748         return -1;
749     }
750 
751     if (preset_obj != Py_None)
752         if (!uint32_converter(preset_obj, &preset))
753             return -1;
754 
755     self->alloc.opaque = NULL;
756     self->alloc.alloc = PyLzma_Malloc;
757     self->alloc.free = PyLzma_Free;
758     self->lzs.allocator = &self->alloc;
759 
760 #ifdef WITH_THREAD
761     self->lock = PyThread_allocate_lock();
762     if (self->lock == NULL) {
763         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
764         return -1;
765     }
766 #endif
767 
768     self->flushed = 0;
769     switch (format) {
770         case FORMAT_XZ:
771             if (check == -1)
772                 check = LZMA_CHECK_CRC64;
773             if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0)
774                 break;
775             return 0;
776 
777         case FORMAT_ALONE:
778             if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0)
779                 break;
780             return 0;
781 
782         case FORMAT_RAW:
783             if (Compressor_init_raw(&self->lzs, filterspecs) != 0)
784                 break;
785             return 0;
786 
787         default:
788             PyErr_Format(PyExc_ValueError,
789                          "Invalid container format: %d", format);
790             break;
791     }
792 
793 #ifdef WITH_THREAD
794     PyThread_free_lock(self->lock);
795     self->lock = NULL;
796 #endif
797     return -1;
798 }
799 
800 static void
Compressor_dealloc(Compressor * self)801 Compressor_dealloc(Compressor *self)
802 {
803     lzma_end(&self->lzs);
804 #ifdef WITH_THREAD
805     if (self->lock != NULL)
806         PyThread_free_lock(self->lock);
807 #endif
808     Py_TYPE(self)->tp_free((PyObject *)self);
809 }
810 
811 static PyMethodDef Compressor_methods[] = {
812     _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
813     _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
814     {"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS},
815     {NULL}
816 };
817 
818 PyDoc_STRVAR(Compressor_doc,
819 "LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n"
820 "\n"
821 "Create a compressor object for compressing data incrementally.\n"
822 "\n"
823 "format specifies the container format to use for the output. This can\n"
824 "be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n"
825 "\n"
826 "check specifies the integrity check to use. For FORMAT_XZ, the default\n"
827 "is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not suport integrity\n"
828 "checks; for these formats, check must be omitted, or be CHECK_NONE.\n"
829 "\n"
830 "The settings used by the compressor can be specified either as a\n"
831 "preset compression level (with the 'preset' argument), or in detail\n"
832 "as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n"
833 "and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n"
834 "level. For FORMAT_RAW, the caller must always specify a filter chain;\n"
835 "the raw compressor does not support preset compression levels.\n"
836 "\n"
837 "preset (if provided) should be an integer in the range 0-9, optionally\n"
838 "OR-ed with the constant PRESET_EXTREME.\n"
839 "\n"
840 "filters (if provided) should be a sequence of dicts. Each dict should\n"
841 "have an entry for \"id\" indicating the ID of the filter, plus\n"
842 "additional entries for options to the filter.\n"
843 "\n"
844 "For one-shot compression, use the compress() function instead.\n");
845 
846 static PyTypeObject Compressor_type = {
847     PyVarObject_HEAD_INIT(NULL, 0)
848     "_lzma.LZMACompressor",             /* tp_name */
849     sizeof(Compressor),                 /* tp_basicsize */
850     0,                                  /* tp_itemsize */
851     (destructor)Compressor_dealloc,     /* tp_dealloc */
852     0,                                  /* tp_print */
853     0,                                  /* tp_getattr */
854     0,                                  /* tp_setattr */
855     0,                                  /* tp_reserved */
856     0,                                  /* tp_repr */
857     0,                                  /* tp_as_number */
858     0,                                  /* tp_as_sequence */
859     0,                                  /* tp_as_mapping */
860     0,                                  /* tp_hash */
861     0,                                  /* tp_call */
862     0,                                  /* tp_str */
863     0,                                  /* tp_getattro */
864     0,                                  /* tp_setattro */
865     0,                                  /* tp_as_buffer */
866     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
867     Compressor_doc,                     /* tp_doc */
868     0,                                  /* tp_traverse */
869     0,                                  /* tp_clear */
870     0,                                  /* tp_richcompare */
871     0,                                  /* tp_weaklistoffset */
872     0,                                  /* tp_iter */
873     0,                                  /* tp_iternext */
874     Compressor_methods,                 /* tp_methods */
875     0,                                  /* tp_members */
876     0,                                  /* tp_getset */
877     0,                                  /* tp_base */
878     0,                                  /* tp_dict */
879     0,                                  /* tp_descr_get */
880     0,                                  /* tp_descr_set */
881     0,                                  /* tp_dictoffset */
882     (initproc)Compressor_init,          /* tp_init */
883     0,                                  /* tp_alloc */
884     PyType_GenericNew,                  /* tp_new */
885 };
886 
887 
888 /* LZMADecompressor class. */
889 
890 /* Decompress data of length d->lzs.avail_in in d->lzs.next_in.  The output
891    buffer is allocated dynamically and returned.  At most max_length bytes are
892    returned, so some of the input may not be consumed. d->lzs.next_in and
893    d->lzs.avail_in are updated to reflect the consumed input. */
894 static PyObject*
decompress_buf(Decompressor * d,Py_ssize_t max_length)895 decompress_buf(Decompressor *d, Py_ssize_t max_length)
896 {
897     Py_ssize_t data_size = 0;
898     PyObject *result;
899     lzma_stream *lzs = &d->lzs;
900 
901     if (lzs->avail_in == 0)
902         return PyBytes_FromStringAndSize(NULL, 0);
903 
904     if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE)
905         result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
906     else
907         result = PyBytes_FromStringAndSize(NULL, max_length);
908     if (result == NULL)
909         return NULL;
910 
911     lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result);
912     lzs->avail_out = PyBytes_GET_SIZE(result);
913 
914     for (;;) {
915         lzma_ret lzret;
916 
917         Py_BEGIN_ALLOW_THREADS
918         lzret = lzma_code(lzs, LZMA_RUN);
919         data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result);
920         Py_END_ALLOW_THREADS
921         if (catch_lzma_error(lzret))
922             goto error;
923         if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK)
924             d->check = lzma_get_check(&d->lzs);
925         if (lzret == LZMA_STREAM_END) {
926             d->eof = 1;
927             break;
928         } else if (lzs->avail_in == 0) {
929             break;
930         } else if (lzs->avail_out == 0) {
931             if (data_size == max_length)
932                 break;
933             if (grow_buffer(&result, max_length) == -1)
934                 goto error;
935             lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size;
936             lzs->avail_out = PyBytes_GET_SIZE(result) - data_size;
937         }
938     }
939     if (data_size != PyBytes_GET_SIZE(result))
940         if (_PyBytes_Resize(&result, data_size) == -1)
941             goto error;
942 
943     return result;
944 
945 error:
946     Py_XDECREF(result);
947     return NULL;
948 }
949 
950 static PyObject *
decompress(Decompressor * d,uint8_t * data,size_t len,Py_ssize_t max_length)951 decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
952 {
953     char input_buffer_in_use;
954     PyObject *result;
955     lzma_stream *lzs = &d->lzs;
956 
957     /* Prepend unconsumed input if necessary */
958     if (lzs->next_in != NULL) {
959         size_t avail_now, avail_total;
960 
961         /* Number of bytes we can append to input buffer */
962         avail_now = (d->input_buffer + d->input_buffer_size)
963             - (lzs->next_in + lzs->avail_in);
964 
965         /* Number of bytes we can append if we move existing
966            contents to beginning of buffer (overwriting
967            consumed input) */
968         avail_total = d->input_buffer_size - lzs->avail_in;
969 
970         if (avail_total < len) {
971             size_t offset = lzs->next_in - d->input_buffer;
972             uint8_t *tmp;
973             size_t new_size = d->input_buffer_size + len - avail_now;
974 
975             /* Assign to temporary variable first, so we don't
976                lose address of allocated buffer if realloc fails */
977             tmp = PyMem_Realloc(d->input_buffer, new_size);
978             if (tmp == NULL) {
979                 PyErr_SetNone(PyExc_MemoryError);
980                 return NULL;
981             }
982             d->input_buffer = tmp;
983             d->input_buffer_size = new_size;
984 
985             lzs->next_in = d->input_buffer + offset;
986         }
987         else if (avail_now < len) {
988             memmove(d->input_buffer, lzs->next_in,
989                     lzs->avail_in);
990             lzs->next_in = d->input_buffer;
991         }
992         memcpy((void*)(lzs->next_in + lzs->avail_in), data, len);
993         lzs->avail_in += len;
994         input_buffer_in_use = 1;
995     }
996     else {
997         lzs->next_in = data;
998         lzs->avail_in = len;
999         input_buffer_in_use = 0;
1000     }
1001 
1002     result = decompress_buf(d, max_length);
1003     if (result == NULL) {
1004         lzs->next_in = NULL;
1005         return NULL;
1006     }
1007 
1008     if (d->eof) {
1009         d->needs_input = 0;
1010         if (lzs->avail_in > 0) {
1011             Py_XSETREF(d->unused_data,
1012                       PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in));
1013             if (d->unused_data == NULL)
1014                 goto error;
1015         }
1016     }
1017     else if (lzs->avail_in == 0) {
1018         lzs->next_in = NULL;
1019         d->needs_input = 1;
1020     }
1021     else {
1022         d->needs_input = 0;
1023 
1024         /* If we did not use the input buffer, we now have
1025            to copy the tail from the caller's buffer into the
1026            input buffer */
1027         if (!input_buffer_in_use) {
1028 
1029             /* Discard buffer if it's too small
1030                (resizing it may needlessly copy the current contents) */
1031             if (d->input_buffer != NULL &&
1032                 d->input_buffer_size < lzs->avail_in) {
1033                 PyMem_Free(d->input_buffer);
1034                 d->input_buffer = NULL;
1035             }
1036 
1037             /* Allocate if necessary */
1038             if (d->input_buffer == NULL) {
1039                 d->input_buffer = PyMem_Malloc(lzs->avail_in);
1040                 if (d->input_buffer == NULL) {
1041                     PyErr_SetNone(PyExc_MemoryError);
1042                     goto error;
1043                 }
1044                 d->input_buffer_size = lzs->avail_in;
1045             }
1046 
1047             /* Copy tail */
1048             memcpy(d->input_buffer, lzs->next_in, lzs->avail_in);
1049             lzs->next_in = d->input_buffer;
1050         }
1051     }
1052 
1053     return result;
1054 
1055 error:
1056     Py_XDECREF(result);
1057     return NULL;
1058 }
1059 
1060 /*[clinic input]
1061 _lzma.LZMADecompressor.decompress
1062 
1063     data: Py_buffer
1064     max_length: Py_ssize_t=-1
1065 
1066 Decompress *data*, returning uncompressed data as bytes.
1067 
1068 If *max_length* is nonnegative, returns at most *max_length* bytes of
1069 decompressed data. If this limit is reached and further output can be
1070 produced, *self.needs_input* will be set to ``False``. In this case, the next
1071 call to *decompress()* may provide *data* as b'' to obtain more of the output.
1072 
1073 If all of the input data was decompressed and returned (either because this
1074 was less than *max_length* bytes, or because *max_length* was negative),
1075 *self.needs_input* will be set to True.
1076 
1077 Attempting to decompress data after the end of stream is reached raises an
1078 EOFError.  Any data found after the end of the stream is ignored and saved in
1079 the unused_data attribute.
1080 [clinic start generated code]*/
1081 
1082 static PyObject *
_lzma_LZMADecompressor_decompress_impl(Decompressor * self,Py_buffer * data,Py_ssize_t max_length)1083 _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data,
1084                                        Py_ssize_t max_length)
1085 /*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/
1086 {
1087     PyObject *result = NULL;
1088 
1089     ACQUIRE_LOCK(self);
1090     if (self->eof)
1091         PyErr_SetString(PyExc_EOFError, "Already at end of stream");
1092     else
1093         result = decompress(self, data->buf, data->len, max_length);
1094     RELEASE_LOCK(self);
1095     return result;
1096 }
1097 
1098 static PyObject *
Decompressor_getstate(Decompressor * self,PyObject * noargs)1099 Decompressor_getstate(Decompressor *self, PyObject *noargs)
1100 {
1101     PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
1102                  Py_TYPE(self)->tp_name);
1103     return NULL;
1104 }
1105 
1106 static int
Decompressor_init_raw(lzma_stream * lzs,PyObject * filterspecs)1107 Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
1108 {
1109     lzma_filter filters[LZMA_FILTERS_MAX + 1];
1110     lzma_ret lzret;
1111 
1112     if (parse_filter_chain_spec(filters, filterspecs) == -1)
1113         return -1;
1114     lzret = lzma_raw_decoder(lzs, filters);
1115     free_filter_chain(filters);
1116     if (catch_lzma_error(lzret))
1117         return -1;
1118     else
1119         return 0;
1120 }
1121 
1122 /*[clinic input]
1123 _lzma.LZMADecompressor.__init__
1124 
1125     format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
1126         Specifies the container format of the input stream.  If this is
1127         FORMAT_AUTO (the default), the decompressor will automatically detect
1128         whether the input is FORMAT_XZ or FORMAT_ALONE.  Streams created with
1129         FORMAT_RAW cannot be autodetected.
1130 
1131     memlimit: object = None
1132         Limit the amount of memory used by the decompressor.  This will cause
1133         decompression to fail if the input cannot be decompressed within the
1134         given limit.
1135 
1136     filters: object = None
1137         A custom filter chain.  This argument is required for FORMAT_RAW, and
1138         not accepted with any other format.  When provided, this should be a
1139         sequence of dicts, each indicating the ID and options for a single
1140         filter.
1141 
1142 Create a decompressor object for decompressing data incrementally.
1143 
1144 For one-shot decompression, use the decompress() function instead.
1145 [clinic start generated code]*/
1146 
1147 static int
_lzma_LZMADecompressor___init___impl(Decompressor * self,int format,PyObject * memlimit,PyObject * filters)1148 _lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
1149                                      PyObject *memlimit, PyObject *filters)
1150 /*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/
1151 {
1152     const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
1153     uint64_t memlimit_ = UINT64_MAX;
1154     lzma_ret lzret;
1155 
1156     if (memlimit != Py_None) {
1157         if (format == FORMAT_RAW) {
1158             PyErr_SetString(PyExc_ValueError,
1159                             "Cannot specify memory limit with FORMAT_RAW");
1160             return -1;
1161         }
1162         memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
1163         if (PyErr_Occurred())
1164             return -1;
1165     }
1166 
1167     if (format == FORMAT_RAW && filters == Py_None) {
1168         PyErr_SetString(PyExc_ValueError,
1169                         "Must specify filters for FORMAT_RAW");
1170         return -1;
1171     } else if (format != FORMAT_RAW && filters != Py_None) {
1172         PyErr_SetString(PyExc_ValueError,
1173                         "Cannot specify filters except with FORMAT_RAW");
1174         return -1;
1175     }
1176 
1177     self->alloc.opaque = NULL;
1178     self->alloc.alloc = PyLzma_Malloc;
1179     self->alloc.free = PyLzma_Free;
1180     self->lzs.allocator = &self->alloc;
1181     self->lzs.next_in = NULL;
1182 
1183 #ifdef WITH_THREAD
1184     self->lock = PyThread_allocate_lock();
1185     if (self->lock == NULL) {
1186         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
1187         return -1;
1188     }
1189 #endif
1190 
1191     self->check = LZMA_CHECK_UNKNOWN;
1192     self->needs_input = 1;
1193     self->input_buffer = NULL;
1194     self->input_buffer_size = 0;
1195     self->unused_data = PyBytes_FromStringAndSize(NULL, 0);
1196     if (self->unused_data == NULL)
1197         goto error;
1198 
1199     switch (format) {
1200         case FORMAT_AUTO:
1201             lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
1202             if (catch_lzma_error(lzret))
1203                 break;
1204             return 0;
1205 
1206         case FORMAT_XZ:
1207             lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
1208             if (catch_lzma_error(lzret))
1209                 break;
1210             return 0;
1211 
1212         case FORMAT_ALONE:
1213             self->check = LZMA_CHECK_NONE;
1214             lzret = lzma_alone_decoder(&self->lzs, memlimit_);
1215             if (catch_lzma_error(lzret))
1216                 break;
1217             return 0;
1218 
1219         case FORMAT_RAW:
1220             self->check = LZMA_CHECK_NONE;
1221             if (Decompressor_init_raw(&self->lzs, filters) == -1)
1222                 break;
1223             return 0;
1224 
1225         default:
1226             PyErr_Format(PyExc_ValueError,
1227                          "Invalid container format: %d", format);
1228             break;
1229     }
1230 
1231 error:
1232     Py_CLEAR(self->unused_data);
1233 #ifdef WITH_THREAD
1234     PyThread_free_lock(self->lock);
1235     self->lock = NULL;
1236 #endif
1237     return -1;
1238 }
1239 
1240 static void
Decompressor_dealloc(Decompressor * self)1241 Decompressor_dealloc(Decompressor *self)
1242 {
1243     if(self->input_buffer != NULL)
1244         PyMem_Free(self->input_buffer);
1245 
1246     lzma_end(&self->lzs);
1247     Py_CLEAR(self->unused_data);
1248 #ifdef WITH_THREAD
1249     if (self->lock != NULL)
1250         PyThread_free_lock(self->lock);
1251 #endif
1252     Py_TYPE(self)->tp_free((PyObject *)self);
1253 }
1254 
1255 static PyMethodDef Decompressor_methods[] = {
1256     _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
1257     {"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS},
1258     {NULL}
1259 };
1260 
1261 PyDoc_STRVAR(Decompressor_check_doc,
1262 "ID of the integrity check used by the input stream.");
1263 
1264 PyDoc_STRVAR(Decompressor_eof_doc,
1265 "True if the end-of-stream marker has been reached.");
1266 
1267 PyDoc_STRVAR(Decompressor_needs_input_doc,
1268 "True if more input is needed before more decompressed data can be produced.");
1269 
1270 PyDoc_STRVAR(Decompressor_unused_data_doc,
1271 "Data found after the end of the compressed stream.");
1272 
1273 static PyMemberDef Decompressor_members[] = {
1274     {"check", T_INT, offsetof(Decompressor, check), READONLY,
1275      Decompressor_check_doc},
1276     {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY,
1277      Decompressor_eof_doc},
1278     {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY,
1279      Decompressor_needs_input_doc},
1280     {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY,
1281      Decompressor_unused_data_doc},
1282     {NULL}
1283 };
1284 
1285 static PyTypeObject Decompressor_type = {
1286     PyVarObject_HEAD_INIT(NULL, 0)
1287     "_lzma.LZMADecompressor",           /* tp_name */
1288     sizeof(Decompressor),               /* tp_basicsize */
1289     0,                                  /* tp_itemsize */
1290     (destructor)Decompressor_dealloc,   /* tp_dealloc */
1291     0,                                  /* tp_print */
1292     0,                                  /* tp_getattr */
1293     0,                                  /* tp_setattr */
1294     0,                                  /* tp_reserved */
1295     0,                                  /* tp_repr */
1296     0,                                  /* tp_as_number */
1297     0,                                  /* tp_as_sequence */
1298     0,                                  /* tp_as_mapping */
1299     0,                                  /* tp_hash */
1300     0,                                  /* tp_call */
1301     0,                                  /* tp_str */
1302     0,                                  /* tp_getattro */
1303     0,                                  /* tp_setattro */
1304     0,                                  /* tp_as_buffer */
1305     Py_TPFLAGS_DEFAULT,                 /* tp_flags */
1306     _lzma_LZMADecompressor___init____doc__,  /* tp_doc */
1307     0,                                  /* tp_traverse */
1308     0,                                  /* tp_clear */
1309     0,                                  /* tp_richcompare */
1310     0,                                  /* tp_weaklistoffset */
1311     0,                                  /* tp_iter */
1312     0,                                  /* tp_iternext */
1313     Decompressor_methods,               /* tp_methods */
1314     Decompressor_members,               /* tp_members */
1315     0,                                  /* tp_getset */
1316     0,                                  /* tp_base */
1317     0,                                  /* tp_dict */
1318     0,                                  /* tp_descr_get */
1319     0,                                  /* tp_descr_set */
1320     0,                                  /* tp_dictoffset */
1321     _lzma_LZMADecompressor___init__,    /* tp_init */
1322     0,                                  /* tp_alloc */
1323     PyType_GenericNew,                  /* tp_new */
1324 };
1325 
1326 
1327 /* Module-level functions. */
1328 
1329 /*[clinic input]
1330 _lzma.is_check_supported
1331     check_id: int
1332     /
1333 
1334 Test whether the given integrity check is supported.
1335 
1336 Always returns True for CHECK_NONE and CHECK_CRC32.
1337 [clinic start generated code]*/
1338 
1339 static PyObject *
_lzma_is_check_supported_impl(PyObject * module,int check_id)1340 _lzma_is_check_supported_impl(PyObject *module, int check_id)
1341 /*[clinic end generated code: output=e4f14ba3ce2ad0a5 input=5518297b97b2318f]*/
1342 {
1343     return PyBool_FromLong(lzma_check_is_supported(check_id));
1344 }
1345 
1346 
1347 /*[clinic input]
1348 _lzma._encode_filter_properties
1349     filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}")
1350     /
1351 
1352 Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
1353 
1354 The result does not include the filter ID itself, only the options.
1355 [clinic start generated code]*/
1356 
1357 static PyObject *
_lzma__encode_filter_properties_impl(PyObject * module,lzma_filter filter)1358 _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter)
1359 /*[clinic end generated code: output=5c93c8e14e7be5a8 input=d4c64f1b557c77d4]*/
1360 {
1361     lzma_ret lzret;
1362     uint32_t encoded_size;
1363     PyObject *result = NULL;
1364 
1365     lzret = lzma_properties_size(&encoded_size, &filter);
1366     if (catch_lzma_error(lzret))
1367         goto error;
1368 
1369     result = PyBytes_FromStringAndSize(NULL, encoded_size);
1370     if (result == NULL)
1371         goto error;
1372 
1373     lzret = lzma_properties_encode(
1374             &filter, (uint8_t *)PyBytes_AS_STRING(result));
1375     if (catch_lzma_error(lzret))
1376         goto error;
1377 
1378     return result;
1379 
1380 error:
1381     Py_XDECREF(result);
1382     return NULL;
1383 }
1384 
1385 
1386 /*[clinic input]
1387 _lzma._decode_filter_properties
1388     filter_id: lzma_vli
1389     encoded_props: Py_buffer
1390     /
1391 
1392 Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
1393 
1394 The result does not include the filter ID itself, only the options.
1395 [clinic start generated code]*/
1396 
1397 static PyObject *
_lzma__decode_filter_properties_impl(PyObject * module,lzma_vli filter_id,Py_buffer * encoded_props)1398 _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id,
1399                                      Py_buffer *encoded_props)
1400 /*[clinic end generated code: output=714fd2ef565d5c60 input=246410800782160c]*/
1401 {
1402     lzma_filter filter;
1403     lzma_ret lzret;
1404     PyObject *result = NULL;
1405     filter.id = filter_id;
1406 
1407     lzret = lzma_properties_decode(
1408             &filter, NULL, encoded_props->buf, encoded_props->len);
1409     if (catch_lzma_error(lzret))
1410         return NULL;
1411 
1412     result = build_filter_spec(&filter);
1413 
1414     /* We use vanilla free() here instead of PyMem_Free() - filter.options was
1415        allocated by lzma_properties_decode() using the default allocator. */
1416     free(filter.options);
1417     return result;
1418 }
1419 
1420 
1421 /* Module initialization. */
1422 
1423 static PyMethodDef module_methods[] = {
1424     _LZMA_IS_CHECK_SUPPORTED_METHODDEF
1425     _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF
1426     _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF
1427     {NULL}
1428 };
1429 
1430 static PyModuleDef _lzmamodule = {
1431     PyModuleDef_HEAD_INIT,
1432     "_lzma",
1433     NULL,
1434     -1,
1435     module_methods,
1436     NULL,
1437     NULL,
1438     NULL,
1439     NULL,
1440 };
1441 
1442 /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant
1443    would not work correctly on platforms with 32-bit longs. */
1444 static int
module_add_int_constant(PyObject * m,const char * name,long long value)1445 module_add_int_constant(PyObject *m, const char *name, long long value)
1446 {
1447     PyObject *o = PyLong_FromLongLong(value);
1448     if (o == NULL)
1449         return -1;
1450     if (PyModule_AddObject(m, name, o) == 0)
1451         return 0;
1452     Py_DECREF(o);
1453     return -1;
1454 }
1455 
1456 #define ADD_INT_PREFIX_MACRO(m, macro) \
1457     module_add_int_constant(m, #macro, LZMA_ ## macro)
1458 
1459 PyMODINIT_FUNC
PyInit__lzma(void)1460 PyInit__lzma(void)
1461 {
1462     PyObject *m;
1463 
1464     empty_tuple = PyTuple_New(0);
1465     if (empty_tuple == NULL)
1466         return NULL;
1467 
1468     m = PyModule_Create(&_lzmamodule);
1469     if (m == NULL)
1470         return NULL;
1471 
1472     if (PyModule_AddIntMacro(m, FORMAT_AUTO) == -1 ||
1473         PyModule_AddIntMacro(m, FORMAT_XZ) == -1 ||
1474         PyModule_AddIntMacro(m, FORMAT_ALONE) == -1 ||
1475         PyModule_AddIntMacro(m, FORMAT_RAW) == -1 ||
1476         ADD_INT_PREFIX_MACRO(m, CHECK_NONE) == -1 ||
1477         ADD_INT_PREFIX_MACRO(m, CHECK_CRC32) == -1 ||
1478         ADD_INT_PREFIX_MACRO(m, CHECK_CRC64) == -1 ||
1479         ADD_INT_PREFIX_MACRO(m, CHECK_SHA256) == -1 ||
1480         ADD_INT_PREFIX_MACRO(m, CHECK_ID_MAX) == -1 ||
1481         ADD_INT_PREFIX_MACRO(m, CHECK_UNKNOWN) == -1 ||
1482         ADD_INT_PREFIX_MACRO(m, FILTER_LZMA1) == -1 ||
1483         ADD_INT_PREFIX_MACRO(m, FILTER_LZMA2) == -1 ||
1484         ADD_INT_PREFIX_MACRO(m, FILTER_DELTA) == -1 ||
1485         ADD_INT_PREFIX_MACRO(m, FILTER_X86) == -1 ||
1486         ADD_INT_PREFIX_MACRO(m, FILTER_IA64) == -1 ||
1487         ADD_INT_PREFIX_MACRO(m, FILTER_ARM) == -1 ||
1488         ADD_INT_PREFIX_MACRO(m, FILTER_ARMTHUMB) == -1 ||
1489         ADD_INT_PREFIX_MACRO(m, FILTER_SPARC) == -1 ||
1490         ADD_INT_PREFIX_MACRO(m, FILTER_POWERPC) == -1 ||
1491         ADD_INT_PREFIX_MACRO(m, MF_HC3) == -1 ||
1492         ADD_INT_PREFIX_MACRO(m, MF_HC4) == -1 ||
1493         ADD_INT_PREFIX_MACRO(m, MF_BT2) == -1 ||
1494         ADD_INT_PREFIX_MACRO(m, MF_BT3) == -1 ||
1495         ADD_INT_PREFIX_MACRO(m, MF_BT4) == -1 ||
1496         ADD_INT_PREFIX_MACRO(m, MODE_FAST) == -1 ||
1497         ADD_INT_PREFIX_MACRO(m, MODE_NORMAL) == -1 ||
1498         ADD_INT_PREFIX_MACRO(m, PRESET_DEFAULT) == -1 ||
1499         ADD_INT_PREFIX_MACRO(m, PRESET_EXTREME) == -1)
1500         return NULL;
1501 
1502     Error = PyErr_NewExceptionWithDoc(
1503             "_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL);
1504     if (Error == NULL)
1505         return NULL;
1506     Py_INCREF(Error);
1507     if (PyModule_AddObject(m, "LZMAError", Error) == -1)
1508         return NULL;
1509 
1510     if (PyType_Ready(&Compressor_type) == -1)
1511         return NULL;
1512     Py_INCREF(&Compressor_type);
1513     if (PyModule_AddObject(m, "LZMACompressor",
1514                            (PyObject *)&Compressor_type) == -1)
1515         return NULL;
1516 
1517     if (PyType_Ready(&Decompressor_type) == -1)
1518         return NULL;
1519     Py_INCREF(&Decompressor_type);
1520     if (PyModule_AddObject(m, "LZMADecompressor",
1521                            (PyObject *)&Decompressor_type) == -1)
1522         return NULL;
1523 
1524     return m;
1525 }
1526