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