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: %d", 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 PyObject *
Compressor_getstate(Compressor * self,PyObject * noargs)595 Compressor_getstate(Compressor *self, PyObject *noargs)
596 {
597 PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
598 Py_TYPE(self)->tp_name);
599 return NULL;
600 }
601
602 static int
Compressor_init_xz(lzma_stream * lzs,int check,uint32_t preset,PyObject * filterspecs)603 Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset,
604 PyObject *filterspecs)
605 {
606 lzma_ret lzret;
607
608 if (filterspecs == Py_None) {
609 lzret = lzma_easy_encoder(lzs, preset, check);
610 } else {
611 lzma_filter filters[LZMA_FILTERS_MAX + 1];
612
613 if (parse_filter_chain_spec(filters, filterspecs) == -1)
614 return -1;
615 lzret = lzma_stream_encoder(lzs, filters, check);
616 free_filter_chain(filters);
617 }
618 if (catch_lzma_error(lzret))
619 return -1;
620 else
621 return 0;
622 }
623
624 static int
Compressor_init_alone(lzma_stream * lzs,uint32_t preset,PyObject * filterspecs)625 Compressor_init_alone(lzma_stream *lzs, uint32_t preset, PyObject *filterspecs)
626 {
627 lzma_ret lzret;
628
629 if (filterspecs == Py_None) {
630 lzma_options_lzma options;
631
632 if (lzma_lzma_preset(&options, preset)) {
633 PyErr_Format(Error, "Invalid compression preset: %d", preset);
634 return -1;
635 }
636 lzret = lzma_alone_encoder(lzs, &options);
637 } else {
638 lzma_filter filters[LZMA_FILTERS_MAX + 1];
639
640 if (parse_filter_chain_spec(filters, filterspecs) == -1)
641 return -1;
642 if (filters[0].id == LZMA_FILTER_LZMA1 &&
643 filters[1].id == LZMA_VLI_UNKNOWN) {
644 lzret = lzma_alone_encoder(lzs, filters[0].options);
645 } else {
646 PyErr_SetString(PyExc_ValueError,
647 "Invalid filter chain for FORMAT_ALONE - "
648 "must be a single LZMA1 filter");
649 lzret = LZMA_PROG_ERROR;
650 }
651 free_filter_chain(filters);
652 }
653 if (PyErr_Occurred() || catch_lzma_error(lzret))
654 return -1;
655 else
656 return 0;
657 }
658
659 static int
Compressor_init_raw(lzma_stream * lzs,PyObject * filterspecs)660 Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
661 {
662 lzma_filter filters[LZMA_FILTERS_MAX + 1];
663 lzma_ret lzret;
664
665 if (filterspecs == Py_None) {
666 PyErr_SetString(PyExc_ValueError,
667 "Must specify filters for FORMAT_RAW");
668 return -1;
669 }
670 if (parse_filter_chain_spec(filters, filterspecs) == -1)
671 return -1;
672 lzret = lzma_raw_encoder(lzs, filters);
673 free_filter_chain(filters);
674 if (catch_lzma_error(lzret))
675 return -1;
676 else
677 return 0;
678 }
679
680 /*[-clinic input]
681 _lzma.LZMACompressor.__init__
682
683 format: int(c_default="FORMAT_XZ") = FORMAT_XZ
684 The container format to use for the output. This can
685 be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.
686
687 check: int(c_default="-1") = unspecified
688 The integrity check to use. For FORMAT_XZ, the default
689 is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity
690 checks; for these formats, check must be omitted, or be CHECK_NONE.
691
692 preset: object = None
693 If provided should be an integer in the range 0-9, optionally
694 OR-ed with the constant PRESET_EXTREME.
695
696 filters: object = None
697 If provided should be a sequence of dicts. Each dict should
698 have an entry for "id" indicating the ID of the filter, plus
699 additional entries for options to the filter.
700
701 Create a compressor object for compressing data incrementally.
702
703 The settings used by the compressor can be specified either as a
704 preset compression level (with the 'preset' argument), or in detail
705 as a custom filter chain (with the 'filters' argument). For FORMAT_XZ
706 and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
707 level. For FORMAT_RAW, the caller must always specify a filter chain;
708 the raw compressor does not support preset compression levels.
709
710 For one-shot compression, use the compress() function instead.
711 [-clinic start generated code]*/
712 static int
Compressor_init(Compressor * self,PyObject * args,PyObject * kwargs)713 Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
714 {
715 static char *arg_names[] = {"format", "check", "preset", "filters", NULL};
716 int format = FORMAT_XZ;
717 int check = -1;
718 uint32_t preset = LZMA_PRESET_DEFAULT;
719 PyObject *preset_obj = Py_None;
720 PyObject *filterspecs = Py_None;
721
722 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
723 "|iiOO:LZMACompressor", arg_names,
724 &format, &check, &preset_obj,
725 &filterspecs))
726 return -1;
727
728 if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) {
729 PyErr_SetString(PyExc_ValueError,
730 "Integrity checks are only supported by FORMAT_XZ");
731 return -1;
732 }
733
734 if (preset_obj != Py_None && filterspecs != Py_None) {
735 PyErr_SetString(PyExc_ValueError,
736 "Cannot specify both preset and filter chain");
737 return -1;
738 }
739
740 if (preset_obj != Py_None)
741 if (!uint32_converter(preset_obj, &preset))
742 return -1;
743
744 self->alloc.opaque = NULL;
745 self->alloc.alloc = PyLzma_Malloc;
746 self->alloc.free = PyLzma_Free;
747 self->lzs.allocator = &self->alloc;
748
749 self->lock = PyThread_allocate_lock();
750 if (self->lock == NULL) {
751 PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
752 return -1;
753 }
754
755 self->flushed = 0;
756 switch (format) {
757 case FORMAT_XZ:
758 if (check == -1)
759 check = LZMA_CHECK_CRC64;
760 if (Compressor_init_xz(&self->lzs, check, preset, filterspecs) != 0)
761 break;
762 return 0;
763
764 case FORMAT_ALONE:
765 if (Compressor_init_alone(&self->lzs, preset, filterspecs) != 0)
766 break;
767 return 0;
768
769 case FORMAT_RAW:
770 if (Compressor_init_raw(&self->lzs, filterspecs) != 0)
771 break;
772 return 0;
773
774 default:
775 PyErr_Format(PyExc_ValueError,
776 "Invalid container format: %d", format);
777 break;
778 }
779
780 PyThread_free_lock(self->lock);
781 self->lock = NULL;
782 return -1;
783 }
784
785 static void
Compressor_dealloc(Compressor * self)786 Compressor_dealloc(Compressor *self)
787 {
788 lzma_end(&self->lzs);
789 if (self->lock != NULL)
790 PyThread_free_lock(self->lock);
791 Py_TYPE(self)->tp_free((PyObject *)self);
792 }
793
794 static PyMethodDef Compressor_methods[] = {
795 _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
796 _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
797 {"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS},
798 {NULL}
799 };
800
801 PyDoc_STRVAR(Compressor_doc,
802 "LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n"
803 "\n"
804 "Create a compressor object for compressing data incrementally.\n"
805 "\n"
806 "format specifies the container format to use for the output. This can\n"
807 "be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n"
808 "\n"
809 "check specifies the integrity check to use. For FORMAT_XZ, the default\n"
810 "is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity\n"
811 "checks; for these formats, check must be omitted, or be CHECK_NONE.\n"
812 "\n"
813 "The settings used by the compressor can be specified either as a\n"
814 "preset compression level (with the 'preset' argument), or in detail\n"
815 "as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n"
816 "and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n"
817 "level. For FORMAT_RAW, the caller must always specify a filter chain;\n"
818 "the raw compressor does not support preset compression levels.\n"
819 "\n"
820 "preset (if provided) should be an integer in the range 0-9, optionally\n"
821 "OR-ed with the constant PRESET_EXTREME.\n"
822 "\n"
823 "filters (if provided) should be a sequence of dicts. Each dict should\n"
824 "have an entry for \"id\" indicating the ID of the filter, plus\n"
825 "additional entries for options to the filter.\n"
826 "\n"
827 "For one-shot compression, use the compress() function instead.\n");
828
829 static PyTypeObject Compressor_type = {
830 PyVarObject_HEAD_INIT(NULL, 0)
831 "_lzma.LZMACompressor", /* tp_name */
832 sizeof(Compressor), /* tp_basicsize */
833 0, /* tp_itemsize */
834 (destructor)Compressor_dealloc, /* tp_dealloc */
835 0, /* tp_print */
836 0, /* tp_getattr */
837 0, /* tp_setattr */
838 0, /* tp_reserved */
839 0, /* tp_repr */
840 0, /* tp_as_number */
841 0, /* tp_as_sequence */
842 0, /* tp_as_mapping */
843 0, /* tp_hash */
844 0, /* tp_call */
845 0, /* tp_str */
846 0, /* tp_getattro */
847 0, /* tp_setattro */
848 0, /* tp_as_buffer */
849 Py_TPFLAGS_DEFAULT, /* tp_flags */
850 Compressor_doc, /* tp_doc */
851 0, /* tp_traverse */
852 0, /* tp_clear */
853 0, /* tp_richcompare */
854 0, /* tp_weaklistoffset */
855 0, /* tp_iter */
856 0, /* tp_iternext */
857 Compressor_methods, /* tp_methods */
858 0, /* tp_members */
859 0, /* tp_getset */
860 0, /* tp_base */
861 0, /* tp_dict */
862 0, /* tp_descr_get */
863 0, /* tp_descr_set */
864 0, /* tp_dictoffset */
865 (initproc)Compressor_init, /* tp_init */
866 0, /* tp_alloc */
867 PyType_GenericNew, /* tp_new */
868 };
869
870
871 /* LZMADecompressor class. */
872
873 /* Decompress data of length d->lzs.avail_in in d->lzs.next_in. The output
874 buffer is allocated dynamically and returned. At most max_length bytes are
875 returned, so some of the input may not be consumed. d->lzs.next_in and
876 d->lzs.avail_in are updated to reflect the consumed input. */
877 static PyObject*
decompress_buf(Decompressor * d,Py_ssize_t max_length)878 decompress_buf(Decompressor *d, Py_ssize_t max_length)
879 {
880 Py_ssize_t data_size = 0;
881 PyObject *result;
882 lzma_stream *lzs = &d->lzs;
883
884 if (lzs->avail_in == 0)
885 return PyBytes_FromStringAndSize(NULL, 0);
886
887 if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE)
888 result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE);
889 else
890 result = PyBytes_FromStringAndSize(NULL, max_length);
891 if (result == NULL)
892 return NULL;
893
894 lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result);
895 lzs->avail_out = PyBytes_GET_SIZE(result);
896
897 for (;;) {
898 lzma_ret lzret;
899
900 Py_BEGIN_ALLOW_THREADS
901 lzret = lzma_code(lzs, LZMA_RUN);
902 data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result);
903 Py_END_ALLOW_THREADS
904 if (catch_lzma_error(lzret))
905 goto error;
906 if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK)
907 d->check = lzma_get_check(&d->lzs);
908 if (lzret == LZMA_STREAM_END) {
909 d->eof = 1;
910 break;
911 } else if (lzs->avail_in == 0) {
912 break;
913 } else if (lzs->avail_out == 0) {
914 if (data_size == max_length)
915 break;
916 if (grow_buffer(&result, max_length) == -1)
917 goto error;
918 lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size;
919 lzs->avail_out = PyBytes_GET_SIZE(result) - data_size;
920 }
921 }
922 if (data_size != PyBytes_GET_SIZE(result))
923 if (_PyBytes_Resize(&result, data_size) == -1)
924 goto error;
925
926 return result;
927
928 error:
929 Py_XDECREF(result);
930 return NULL;
931 }
932
933 static PyObject *
decompress(Decompressor * d,uint8_t * data,size_t len,Py_ssize_t max_length)934 decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
935 {
936 char input_buffer_in_use;
937 PyObject *result;
938 lzma_stream *lzs = &d->lzs;
939
940 /* Prepend unconsumed input if necessary */
941 if (lzs->next_in != NULL) {
942 size_t avail_now, avail_total;
943
944 /* Number of bytes we can append to input buffer */
945 avail_now = (d->input_buffer + d->input_buffer_size)
946 - (lzs->next_in + lzs->avail_in);
947
948 /* Number of bytes we can append if we move existing
949 contents to beginning of buffer (overwriting
950 consumed input) */
951 avail_total = d->input_buffer_size - lzs->avail_in;
952
953 if (avail_total < len) {
954 size_t offset = lzs->next_in - d->input_buffer;
955 uint8_t *tmp;
956 size_t new_size = d->input_buffer_size + len - avail_now;
957
958 /* Assign to temporary variable first, so we don't
959 lose address of allocated buffer if realloc fails */
960 tmp = PyMem_Realloc(d->input_buffer, new_size);
961 if (tmp == NULL) {
962 PyErr_SetNone(PyExc_MemoryError);
963 return NULL;
964 }
965 d->input_buffer = tmp;
966 d->input_buffer_size = new_size;
967
968 lzs->next_in = d->input_buffer + offset;
969 }
970 else if (avail_now < len) {
971 memmove(d->input_buffer, lzs->next_in,
972 lzs->avail_in);
973 lzs->next_in = d->input_buffer;
974 }
975 memcpy((void*)(lzs->next_in + lzs->avail_in), data, len);
976 lzs->avail_in += len;
977 input_buffer_in_use = 1;
978 }
979 else {
980 lzs->next_in = data;
981 lzs->avail_in = len;
982 input_buffer_in_use = 0;
983 }
984
985 result = decompress_buf(d, max_length);
986 if (result == NULL) {
987 lzs->next_in = NULL;
988 return NULL;
989 }
990
991 if (d->eof) {
992 d->needs_input = 0;
993 if (lzs->avail_in > 0) {
994 Py_XSETREF(d->unused_data,
995 PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in));
996 if (d->unused_data == NULL)
997 goto error;
998 }
999 }
1000 else if (lzs->avail_in == 0) {
1001 lzs->next_in = NULL;
1002 d->needs_input = 1;
1003 }
1004 else {
1005 d->needs_input = 0;
1006
1007 /* If we did not use the input buffer, we now have
1008 to copy the tail from the caller's buffer into the
1009 input buffer */
1010 if (!input_buffer_in_use) {
1011
1012 /* Discard buffer if it's too small
1013 (resizing it may needlessly copy the current contents) */
1014 if (d->input_buffer != NULL &&
1015 d->input_buffer_size < lzs->avail_in) {
1016 PyMem_Free(d->input_buffer);
1017 d->input_buffer = NULL;
1018 }
1019
1020 /* Allocate if necessary */
1021 if (d->input_buffer == NULL) {
1022 d->input_buffer = PyMem_Malloc(lzs->avail_in);
1023 if (d->input_buffer == NULL) {
1024 PyErr_SetNone(PyExc_MemoryError);
1025 goto error;
1026 }
1027 d->input_buffer_size = lzs->avail_in;
1028 }
1029
1030 /* Copy tail */
1031 memcpy(d->input_buffer, lzs->next_in, lzs->avail_in);
1032 lzs->next_in = d->input_buffer;
1033 }
1034 }
1035
1036 return result;
1037
1038 error:
1039 Py_XDECREF(result);
1040 return NULL;
1041 }
1042
1043 /*[clinic input]
1044 _lzma.LZMADecompressor.decompress
1045
1046 data: Py_buffer
1047 max_length: Py_ssize_t=-1
1048
1049 Decompress *data*, returning uncompressed data as bytes.
1050
1051 If *max_length* is nonnegative, returns at most *max_length* bytes of
1052 decompressed data. If this limit is reached and further output can be
1053 produced, *self.needs_input* will be set to ``False``. In this case, the next
1054 call to *decompress()* may provide *data* as b'' to obtain more of the output.
1055
1056 If all of the input data was decompressed and returned (either because this
1057 was less than *max_length* bytes, or because *max_length* was negative),
1058 *self.needs_input* will be set to True.
1059
1060 Attempting to decompress data after the end of stream is reached raises an
1061 EOFError. Any data found after the end of the stream is ignored and saved in
1062 the unused_data attribute.
1063 [clinic start generated code]*/
1064
1065 static PyObject *
_lzma_LZMADecompressor_decompress_impl(Decompressor * self,Py_buffer * data,Py_ssize_t max_length)1066 _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data,
1067 Py_ssize_t max_length)
1068 /*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/
1069 {
1070 PyObject *result = NULL;
1071
1072 ACQUIRE_LOCK(self);
1073 if (self->eof)
1074 PyErr_SetString(PyExc_EOFError, "Already at end of stream");
1075 else
1076 result = decompress(self, data->buf, data->len, max_length);
1077 RELEASE_LOCK(self);
1078 return result;
1079 }
1080
1081 static PyObject *
Decompressor_getstate(Decompressor * self,PyObject * noargs)1082 Decompressor_getstate(Decompressor *self, PyObject *noargs)
1083 {
1084 PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
1085 Py_TYPE(self)->tp_name);
1086 return NULL;
1087 }
1088
1089 static int
Decompressor_init_raw(lzma_stream * lzs,PyObject * filterspecs)1090 Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
1091 {
1092 lzma_filter filters[LZMA_FILTERS_MAX + 1];
1093 lzma_ret lzret;
1094
1095 if (parse_filter_chain_spec(filters, filterspecs) == -1)
1096 return -1;
1097 lzret = lzma_raw_decoder(lzs, filters);
1098 free_filter_chain(filters);
1099 if (catch_lzma_error(lzret))
1100 return -1;
1101 else
1102 return 0;
1103 }
1104
1105 /*[clinic input]
1106 _lzma.LZMADecompressor.__init__
1107
1108 format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
1109 Specifies the container format of the input stream. If this is
1110 FORMAT_AUTO (the default), the decompressor will automatically detect
1111 whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with
1112 FORMAT_RAW cannot be autodetected.
1113
1114 memlimit: object = None
1115 Limit the amount of memory used by the decompressor. This will cause
1116 decompression to fail if the input cannot be decompressed within the
1117 given limit.
1118
1119 filters: object = None
1120 A custom filter chain. This argument is required for FORMAT_RAW, and
1121 not accepted with any other format. When provided, this should be a
1122 sequence of dicts, each indicating the ID and options for a single
1123 filter.
1124
1125 Create a decompressor object for decompressing data incrementally.
1126
1127 For one-shot decompression, use the decompress() function instead.
1128 [clinic start generated code]*/
1129
1130 static int
_lzma_LZMADecompressor___init___impl(Decompressor * self,int format,PyObject * memlimit,PyObject * filters)1131 _lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
1132 PyObject *memlimit, PyObject *filters)
1133 /*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/
1134 {
1135 const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
1136 uint64_t memlimit_ = UINT64_MAX;
1137 lzma_ret lzret;
1138
1139 if (memlimit != Py_None) {
1140 if (format == FORMAT_RAW) {
1141 PyErr_SetString(PyExc_ValueError,
1142 "Cannot specify memory limit with FORMAT_RAW");
1143 return -1;
1144 }
1145 memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
1146 if (PyErr_Occurred())
1147 return -1;
1148 }
1149
1150 if (format == FORMAT_RAW && filters == Py_None) {
1151 PyErr_SetString(PyExc_ValueError,
1152 "Must specify filters for FORMAT_RAW");
1153 return -1;
1154 } else if (format != FORMAT_RAW && filters != Py_None) {
1155 PyErr_SetString(PyExc_ValueError,
1156 "Cannot specify filters except with FORMAT_RAW");
1157 return -1;
1158 }
1159
1160 self->alloc.opaque = NULL;
1161 self->alloc.alloc = PyLzma_Malloc;
1162 self->alloc.free = PyLzma_Free;
1163 self->lzs.allocator = &self->alloc;
1164 self->lzs.next_in = NULL;
1165
1166 PyThread_type_lock lock = PyThread_allocate_lock();
1167 if (lock == NULL) {
1168 PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
1169 return -1;
1170 }
1171 if (self->lock != NULL) {
1172 PyThread_free_lock(self->lock);
1173 }
1174 self->lock = lock;
1175
1176 self->check = LZMA_CHECK_UNKNOWN;
1177 self->needs_input = 1;
1178 self->input_buffer = NULL;
1179 self->input_buffer_size = 0;
1180 Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
1181 if (self->unused_data == NULL)
1182 goto error;
1183
1184 switch (format) {
1185 case FORMAT_AUTO:
1186 lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
1187 if (catch_lzma_error(lzret))
1188 break;
1189 return 0;
1190
1191 case FORMAT_XZ:
1192 lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
1193 if (catch_lzma_error(lzret))
1194 break;
1195 return 0;
1196
1197 case FORMAT_ALONE:
1198 self->check = LZMA_CHECK_NONE;
1199 lzret = lzma_alone_decoder(&self->lzs, memlimit_);
1200 if (catch_lzma_error(lzret))
1201 break;
1202 return 0;
1203
1204 case FORMAT_RAW:
1205 self->check = LZMA_CHECK_NONE;
1206 if (Decompressor_init_raw(&self->lzs, filters) == -1)
1207 break;
1208 return 0;
1209
1210 default:
1211 PyErr_Format(PyExc_ValueError,
1212 "Invalid container format: %d", format);
1213 break;
1214 }
1215
1216 error:
1217 Py_CLEAR(self->unused_data);
1218 PyThread_free_lock(self->lock);
1219 self->lock = NULL;
1220 return -1;
1221 }
1222
1223 static void
Decompressor_dealloc(Decompressor * self)1224 Decompressor_dealloc(Decompressor *self)
1225 {
1226 if(self->input_buffer != NULL)
1227 PyMem_Free(self->input_buffer);
1228
1229 lzma_end(&self->lzs);
1230 Py_CLEAR(self->unused_data);
1231 if (self->lock != NULL)
1232 PyThread_free_lock(self->lock);
1233 Py_TYPE(self)->tp_free((PyObject *)self);
1234 }
1235
1236 static PyMethodDef Decompressor_methods[] = {
1237 _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
1238 {"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS},
1239 {NULL}
1240 };
1241
1242 PyDoc_STRVAR(Decompressor_check_doc,
1243 "ID of the integrity check used by the input stream.");
1244
1245 PyDoc_STRVAR(Decompressor_eof_doc,
1246 "True if the end-of-stream marker has been reached.");
1247
1248 PyDoc_STRVAR(Decompressor_needs_input_doc,
1249 "True if more input is needed before more decompressed data can be produced.");
1250
1251 PyDoc_STRVAR(Decompressor_unused_data_doc,
1252 "Data found after the end of the compressed stream.");
1253
1254 static PyMemberDef Decompressor_members[] = {
1255 {"check", T_INT, offsetof(Decompressor, check), READONLY,
1256 Decompressor_check_doc},
1257 {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY,
1258 Decompressor_eof_doc},
1259 {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY,
1260 Decompressor_needs_input_doc},
1261 {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY,
1262 Decompressor_unused_data_doc},
1263 {NULL}
1264 };
1265
1266 static PyTypeObject Decompressor_type = {
1267 PyVarObject_HEAD_INIT(NULL, 0)
1268 "_lzma.LZMADecompressor", /* tp_name */
1269 sizeof(Decompressor), /* tp_basicsize */
1270 0, /* tp_itemsize */
1271 (destructor)Decompressor_dealloc, /* tp_dealloc */
1272 0, /* tp_print */
1273 0, /* tp_getattr */
1274 0, /* tp_setattr */
1275 0, /* tp_reserved */
1276 0, /* tp_repr */
1277 0, /* tp_as_number */
1278 0, /* tp_as_sequence */
1279 0, /* tp_as_mapping */
1280 0, /* tp_hash */
1281 0, /* tp_call */
1282 0, /* tp_str */
1283 0, /* tp_getattro */
1284 0, /* tp_setattro */
1285 0, /* tp_as_buffer */
1286 Py_TPFLAGS_DEFAULT, /* tp_flags */
1287 _lzma_LZMADecompressor___init____doc__, /* tp_doc */
1288 0, /* tp_traverse */
1289 0, /* tp_clear */
1290 0, /* tp_richcompare */
1291 0, /* tp_weaklistoffset */
1292 0, /* tp_iter */
1293 0, /* tp_iternext */
1294 Decompressor_methods, /* tp_methods */
1295 Decompressor_members, /* tp_members */
1296 0, /* tp_getset */
1297 0, /* tp_base */
1298 0, /* tp_dict */
1299 0, /* tp_descr_get */
1300 0, /* tp_descr_set */
1301 0, /* tp_dictoffset */
1302 _lzma_LZMADecompressor___init__, /* tp_init */
1303 0, /* tp_alloc */
1304 PyType_GenericNew, /* tp_new */
1305 };
1306
1307
1308 /* Module-level functions. */
1309
1310 /*[clinic input]
1311 _lzma.is_check_supported
1312 check_id: int
1313 /
1314
1315 Test whether the given integrity check is supported.
1316
1317 Always returns True for CHECK_NONE and CHECK_CRC32.
1318 [clinic start generated code]*/
1319
1320 static PyObject *
_lzma_is_check_supported_impl(PyObject * module,int check_id)1321 _lzma_is_check_supported_impl(PyObject *module, int check_id)
1322 /*[clinic end generated code: output=e4f14ba3ce2ad0a5 input=5518297b97b2318f]*/
1323 {
1324 return PyBool_FromLong(lzma_check_is_supported(check_id));
1325 }
1326
1327
1328 /*[clinic input]
1329 _lzma._encode_filter_properties
1330 filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}")
1331 /
1332
1333 Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
1334
1335 The result does not include the filter ID itself, only the options.
1336 [clinic start generated code]*/
1337
1338 static PyObject *
_lzma__encode_filter_properties_impl(PyObject * module,lzma_filter filter)1339 _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter)
1340 /*[clinic end generated code: output=5c93c8e14e7be5a8 input=d4c64f1b557c77d4]*/
1341 {
1342 lzma_ret lzret;
1343 uint32_t encoded_size;
1344 PyObject *result = NULL;
1345
1346 lzret = lzma_properties_size(&encoded_size, &filter);
1347 if (catch_lzma_error(lzret))
1348 goto error;
1349
1350 result = PyBytes_FromStringAndSize(NULL, encoded_size);
1351 if (result == NULL)
1352 goto error;
1353
1354 lzret = lzma_properties_encode(
1355 &filter, (uint8_t *)PyBytes_AS_STRING(result));
1356 if (catch_lzma_error(lzret))
1357 goto error;
1358
1359 return result;
1360
1361 error:
1362 Py_XDECREF(result);
1363 return NULL;
1364 }
1365
1366
1367 /*[clinic input]
1368 _lzma._decode_filter_properties
1369 filter_id: lzma_vli
1370 encoded_props: Py_buffer
1371 /
1372
1373 Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
1374
1375 The result does not include the filter ID itself, only the options.
1376 [clinic start generated code]*/
1377
1378 static PyObject *
_lzma__decode_filter_properties_impl(PyObject * module,lzma_vli filter_id,Py_buffer * encoded_props)1379 _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id,
1380 Py_buffer *encoded_props)
1381 /*[clinic end generated code: output=714fd2ef565d5c60 input=246410800782160c]*/
1382 {
1383 lzma_filter filter;
1384 lzma_ret lzret;
1385 PyObject *result = NULL;
1386 filter.id = filter_id;
1387
1388 lzret = lzma_properties_decode(
1389 &filter, NULL, encoded_props->buf, encoded_props->len);
1390 if (catch_lzma_error(lzret))
1391 return NULL;
1392
1393 result = build_filter_spec(&filter);
1394
1395 /* We use vanilla free() here instead of PyMem_Free() - filter.options was
1396 allocated by lzma_properties_decode() using the default allocator. */
1397 free(filter.options);
1398 return result;
1399 }
1400
1401
1402 /* Module initialization. */
1403
1404 static PyMethodDef module_methods[] = {
1405 _LZMA_IS_CHECK_SUPPORTED_METHODDEF
1406 _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF
1407 _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF
1408 {NULL}
1409 };
1410
1411 static PyModuleDef _lzmamodule = {
1412 PyModuleDef_HEAD_INIT,
1413 "_lzma",
1414 NULL,
1415 -1,
1416 module_methods,
1417 NULL,
1418 NULL,
1419 NULL,
1420 NULL,
1421 };
1422
1423 /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant
1424 would not work correctly on platforms with 32-bit longs. */
1425 static int
module_add_int_constant(PyObject * m,const char * name,long long value)1426 module_add_int_constant(PyObject *m, const char *name, long long value)
1427 {
1428 PyObject *o = PyLong_FromLongLong(value);
1429 if (o == NULL)
1430 return -1;
1431 if (PyModule_AddObject(m, name, o) == 0)
1432 return 0;
1433 Py_DECREF(o);
1434 return -1;
1435 }
1436
1437 #define ADD_INT_PREFIX_MACRO(m, macro) \
1438 module_add_int_constant(m, #macro, LZMA_ ## macro)
1439
1440 PyMODINIT_FUNC
PyInit__lzma(void)1441 PyInit__lzma(void)
1442 {
1443 PyObject *m;
1444
1445 empty_tuple = PyTuple_New(0);
1446 if (empty_tuple == NULL)
1447 return NULL;
1448
1449 m = PyModule_Create(&_lzmamodule);
1450 if (m == NULL)
1451 return NULL;
1452
1453 if (PyModule_AddIntMacro(m, FORMAT_AUTO) == -1 ||
1454 PyModule_AddIntMacro(m, FORMAT_XZ) == -1 ||
1455 PyModule_AddIntMacro(m, FORMAT_ALONE) == -1 ||
1456 PyModule_AddIntMacro(m, FORMAT_RAW) == -1 ||
1457 ADD_INT_PREFIX_MACRO(m, CHECK_NONE) == -1 ||
1458 ADD_INT_PREFIX_MACRO(m, CHECK_CRC32) == -1 ||
1459 ADD_INT_PREFIX_MACRO(m, CHECK_CRC64) == -1 ||
1460 ADD_INT_PREFIX_MACRO(m, CHECK_SHA256) == -1 ||
1461 ADD_INT_PREFIX_MACRO(m, CHECK_ID_MAX) == -1 ||
1462 ADD_INT_PREFIX_MACRO(m, CHECK_UNKNOWN) == -1 ||
1463 ADD_INT_PREFIX_MACRO(m, FILTER_LZMA1) == -1 ||
1464 ADD_INT_PREFIX_MACRO(m, FILTER_LZMA2) == -1 ||
1465 ADD_INT_PREFIX_MACRO(m, FILTER_DELTA) == -1 ||
1466 ADD_INT_PREFIX_MACRO(m, FILTER_X86) == -1 ||
1467 ADD_INT_PREFIX_MACRO(m, FILTER_IA64) == -1 ||
1468 ADD_INT_PREFIX_MACRO(m, FILTER_ARM) == -1 ||
1469 ADD_INT_PREFIX_MACRO(m, FILTER_ARMTHUMB) == -1 ||
1470 ADD_INT_PREFIX_MACRO(m, FILTER_SPARC) == -1 ||
1471 ADD_INT_PREFIX_MACRO(m, FILTER_POWERPC) == -1 ||
1472 ADD_INT_PREFIX_MACRO(m, MF_HC3) == -1 ||
1473 ADD_INT_PREFIX_MACRO(m, MF_HC4) == -1 ||
1474 ADD_INT_PREFIX_MACRO(m, MF_BT2) == -1 ||
1475 ADD_INT_PREFIX_MACRO(m, MF_BT3) == -1 ||
1476 ADD_INT_PREFIX_MACRO(m, MF_BT4) == -1 ||
1477 ADD_INT_PREFIX_MACRO(m, MODE_FAST) == -1 ||
1478 ADD_INT_PREFIX_MACRO(m, MODE_NORMAL) == -1 ||
1479 ADD_INT_PREFIX_MACRO(m, PRESET_DEFAULT) == -1 ||
1480 ADD_INT_PREFIX_MACRO(m, PRESET_EXTREME) == -1)
1481 return NULL;
1482
1483 Error = PyErr_NewExceptionWithDoc(
1484 "_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL);
1485 if (Error == NULL)
1486 return NULL;
1487 Py_INCREF(Error);
1488 if (PyModule_AddObject(m, "LZMAError", Error) == -1)
1489 return NULL;
1490
1491 if (PyType_Ready(&Compressor_type) == -1)
1492 return NULL;
1493 Py_INCREF(&Compressor_type);
1494 if (PyModule_AddObject(m, "LZMACompressor",
1495 (PyObject *)&Compressor_type) == -1)
1496 return NULL;
1497
1498 if (PyType_Ready(&Decompressor_type) == -1)
1499 return NULL;
1500 Py_INCREF(&Decompressor_type);
1501 if (PyModule_AddObject(m, "LZMADecompressor",
1502 (PyObject *)&Decompressor_type) == -1)
1503 return NULL;
1504
1505 return m;
1506 }
1507