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