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