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