LCOV - code coverage report
Current view: | top level - Modules - _lzmamodule.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 69 | 646 | 10.7 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 7 | 47 | 14.9 %
|  |  | Branches: | 53 | 414 | 12.8 %

               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                 :          0 : 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                 :          0 :     allocated = _BlocksOutputBuffer_InitAndGrow(
          34                 :            :                     buffer, max_length, (void**) next_out);
          35                 :          0 :     *avail_out = (size_t) allocated;
          36                 :          0 :     return allocated;
          37                 :            : }
          38                 :            :
          39                 :            : /* On success, return value >= 0
          40                 :            :    On failure, return -1 */
          41                 :            : static inline Py_ssize_t
          42                 :          0 : OutputBuffer_Grow(_BlocksOutputBuffer *buffer,
          43                 :            :                   uint8_t **next_out, size_t *avail_out)
          44                 :            : {
          45                 :            :     Py_ssize_t allocated;
          46                 :            :
          47                 :          0 :     allocated = _BlocksOutputBuffer_Grow(
          48                 :          0 :                     buffer, (void**) next_out, (Py_ssize_t) *avail_out);
          49                 :          0 :     *avail_out = (size_t) allocated;
          50                 :          0 :     return allocated;
          51                 :            : }
          52                 :            :
          53                 :            : static inline Py_ssize_t
          54                 :          0 : OutputBuffer_GetDataSize(_BlocksOutputBuffer *buffer, size_t avail_out)
          55                 :            : {
          56                 :          0 :     return _BlocksOutputBuffer_GetDataSize(buffer, (Py_ssize_t) avail_out);
          57                 :            : }
          58                 :            :
          59                 :            : static inline PyObject *
          60                 :          0 : OutputBuffer_Finish(_BlocksOutputBuffer *buffer, size_t avail_out)
          61                 :            : {
          62                 :          0 :     return _BlocksOutputBuffer_Finish(buffer, (Py_ssize_t) avail_out);
          63                 :            : }
          64                 :            :
          65                 :            : static inline void
          66                 :          0 : OutputBuffer_OnError(_BlocksOutputBuffer *buffer)
          67                 :            : {
          68                 :          0 :     _BlocksOutputBuffer_OnError(buffer);
          69                 :          0 : }
          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                 :         55 : get_lzma_state(PyObject *module)
          89                 :            : {
          90                 :         55 :     void *state = PyModule_GetState(module);
          91                 :            :     assert(state != NULL);
          92                 :         55 :     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                 :          0 : catch_lzma_error(_lzma_state *state, lzma_ret lzret)
         131                 :            : {
         132   [ #  #  #  #  :          0 :     switch (lzret) {
              #  #  #  #  #
                          # ]
         133                 :          0 :         case LZMA_OK:
         134                 :            :         case LZMA_GET_CHECK:
         135                 :            :         case LZMA_NO_CHECK:
         136                 :            :         case LZMA_STREAM_END:
         137                 :          0 :             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                 :          0 :             PyErr_NoMemory();
         143                 :          0 :             return 1;
         144                 :          0 :         case LZMA_MEMLIMIT_ERROR:
         145                 :          0 :             PyErr_SetString(state->error, "Memory usage limit exceeded");
         146                 :          0 :             return 1;
         147                 :          0 :         case LZMA_FORMAT_ERROR:
         148                 :          0 :             PyErr_SetString(state->error, "Input format not supported by decoder");
         149                 :          0 :             return 1;
         150                 :          0 :         case LZMA_OPTIONS_ERROR:
         151                 :          0 :             PyErr_SetString(state->error, "Invalid or unsupported options");
         152                 :          0 :             return 1;
         153                 :          0 :         case LZMA_DATA_ERROR:
         154                 :          0 :             PyErr_SetString(state->error, "Corrupt input data");
         155                 :          0 :             return 1;
         156                 :          0 :         case LZMA_BUF_ERROR:
         157                 :          0 :             PyErr_SetString(state->error, "Insufficient buffer space");
         158                 :          0 :             return 1;
         159                 :          0 :         case LZMA_PROG_ERROR:
         160                 :          0 :             PyErr_SetString(state->error, "Internal error");
         161                 :          0 :             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                 :          0 : PyLzma_Malloc(void *opaque, size_t items, size_t size)
         170                 :            : {
         171   [ #  #  #  # ]:          0 :     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                 :          0 :     return PyMem_RawMalloc(items * size);
         177                 :            : }
         178                 :            :
         179                 :            : static void
         180                 :          0 : PyLzma_Free(void *opaque, void *ptr)
         181                 :            : {
         182                 :          0 :     PyMem_RawFree(ptr);
         183                 :          0 : }
         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   [ #  #  #  # ]:          0 : INT_TYPE_CONVERTER_FUNC(uint32_t, uint32_converter)
         220         [ #  # ]:          0 : 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                 :          0 : 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                 :          0 :     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                 :          0 :     preset_obj = PyMapping_GetItemString(spec, "preset");
         246         [ #  # ]:          0 :     if (preset_obj == NULL) {
         247         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_KeyError)) {
         248                 :          0 :             PyErr_Clear();
         249                 :            :         }
         250                 :            :         else {
         251                 :          0 :             return NULL;
         252                 :            :         }
         253                 :            :     } else {
         254                 :          0 :         int ok = uint32_converter(preset_obj, &preset);
         255                 :          0 :         Py_DECREF(preset_obj);
         256         [ #  # ]:          0 :         if (!ok) {
         257                 :          0 :             return NULL;
         258                 :            :         }
         259                 :            :     }
         260                 :            :
         261                 :          0 :     options = (lzma_options_lzma *)PyMem_Calloc(1, sizeof *options);
         262         [ #  # ]:          0 :     if (options == NULL) {
         263                 :          0 :         return PyErr_NoMemory();
         264                 :            :     }
         265                 :            :
         266         [ #  # ]:          0 :     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         [ #  # ]:          0 :     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                 :          0 :         PyErr_SetString(PyExc_ValueError,
         284                 :            :                         "Invalid filter specifier for LZMA filter");
         285                 :          0 :         PyMem_Free(options);
         286                 :          0 :         return NULL;
         287                 :            :     }
         288                 :            :
         289                 :          0 :     return options;
         290                 :            : }
         291                 :            :
         292                 :            : static void *
         293                 :          0 : parse_filter_spec_delta(_lzma_state *state, PyObject *spec)
         294                 :            : {
         295                 :            :     static char *optnames[] = {"id", "dist", NULL};
         296                 :            :     PyObject *id;
         297                 :          0 :     uint32_t dist = 1;
         298                 :            :     lzma_options_delta *options;
         299                 :            :
         300         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(state->empty_tuple, spec, "|OO&", optnames,
         301                 :            :                                      &id, uint32_converter, &dist)) {
         302                 :          0 :         PyErr_SetString(PyExc_ValueError,
         303                 :            :                         "Invalid filter specifier for delta filter");
         304                 :          0 :         return NULL;
         305                 :            :     }
         306                 :            :
         307                 :          0 :     options = (lzma_options_delta *)PyMem_Calloc(1, sizeof *options);
         308         [ #  # ]:          0 :     if (options == NULL) {
         309                 :          0 :         return PyErr_NoMemory();
         310                 :            :     }
         311                 :          0 :     options->type = LZMA_DELTA_TYPE_BYTE;
         312                 :          0 :     options->dist = dist;
         313                 :          0 :     return options;
         314                 :            : }
         315                 :            :
         316                 :            : static void *
         317                 :          0 : parse_filter_spec_bcj(_lzma_state *state, PyObject *spec)
         318                 :            : {
         319                 :            :     static char *optnames[] = {"id", "start_offset", NULL};
         320                 :            :     PyObject *id;
         321                 :          0 :     uint32_t start_offset = 0;
         322                 :            :     lzma_options_bcj *options;
         323                 :            :
         324         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(state->empty_tuple, spec, "|OO&", optnames,
         325                 :            :                                      &id, uint32_converter, &start_offset)) {
         326                 :          0 :         PyErr_SetString(PyExc_ValueError,
         327                 :            :                         "Invalid filter specifier for BCJ filter");
         328                 :          0 :         return NULL;
         329                 :            :     }
         330                 :            :
         331                 :          0 :     options = (lzma_options_bcj *)PyMem_Calloc(1, sizeof *options);
         332         [ #  # ]:          0 :     if (options == NULL) {
         333                 :          0 :         return PyErr_NoMemory();
         334                 :            :     }
         335                 :          0 :     options->start_offset = start_offset;
         336                 :          0 :     return options;
         337                 :            : }
         338                 :            :
         339                 :            : static int
         340                 :          0 : lzma_filter_converter(_lzma_state *state, PyObject *spec, void *ptr)
         341                 :            : {
         342                 :          0 :     lzma_filter *f = (lzma_filter *)ptr;
         343                 :            :     PyObject *id_obj;
         344                 :            :
         345         [ #  # ]:          0 :     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                 :          0 :     id_obj = PyMapping_GetItemString(spec, "id");
         351         [ #  # ]:          0 :     if (id_obj == NULL) {
         352         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_KeyError))
         353                 :          0 :             PyErr_SetString(PyExc_ValueError,
         354                 :            :                             "Filter specifier must have an \"id\" entry");
         355                 :          0 :         return 0;
         356                 :            :     }
         357                 :          0 :     f->id = PyLong_AsUnsignedLongLong(id_obj);
         358                 :          0 :     Py_DECREF(id_obj);
         359         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         360                 :          0 :         return 0;
         361                 :            :     }
         362                 :            :
         363   [ #  #  #  # ]:          0 :     switch (f->id) {
         364                 :          0 :         case LZMA_FILTER_LZMA1:
         365                 :            :         case LZMA_FILTER_LZMA2:
         366                 :          0 :             f->options = parse_filter_spec_lzma(state, spec);
         367                 :          0 :             return f->options != NULL;
         368                 :          0 :         case LZMA_FILTER_DELTA:
         369                 :          0 :             f->options = parse_filter_spec_delta(state, spec);
         370                 :          0 :             return f->options != NULL;
         371                 :          0 :         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                 :          0 :             f->options = parse_filter_spec_bcj(state, spec);
         378                 :          0 :             return f->options != NULL;
         379                 :          0 :         default:
         380                 :          0 :             PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id);
         381                 :          0 :             return 0;
         382                 :            :     }
         383                 :            : }
         384                 :            :
         385                 :            : static void
         386                 :          0 : free_filter_chain(lzma_filter filters[])
         387                 :            : {
         388         [ #  # ]:          0 :     for (int i = 0; filters[i].id != LZMA_VLI_UNKNOWN; i++) {
         389                 :          0 :         PyMem_Free(filters[i].options);
         390                 :            :     }
         391                 :          0 : }
         392                 :            :
         393                 :            : static int
         394                 :          0 : parse_filter_chain_spec(_lzma_state *state, lzma_filter filters[], PyObject *filterspecs)
         395                 :            : {
         396                 :            :     Py_ssize_t i, num_filters;
         397                 :            :
         398                 :          0 :     num_filters = PySequence_Length(filterspecs);
         399         [ #  # ]:          0 :     if (num_filters == -1) {
         400                 :          0 :         return -1;
         401                 :            :     }
         402         [ #  # ]:          0 :     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         [ #  # ]:          0 :     for (i = 0; i < num_filters; i++) {
         410                 :          0 :         int ok = 1;
         411                 :          0 :         PyObject *spec = PySequence_GetItem(filterspecs, i);
         412   [ #  #  #  # ]:          0 :         if (spec == NULL || !lzma_filter_converter(state, spec, &filters[i])) {
         413                 :          0 :             ok = 0;
         414                 :            :         }
         415                 :          0 :         Py_XDECREF(spec);
         416         [ #  # ]:          0 :         if (!ok) {
         417                 :          0 :             filters[i].id = LZMA_VLI_UNKNOWN;
         418                 :          0 :             free_filter_chain(filters);
         419                 :          0 :             return -1;
         420                 :            :         }
         421                 :            :     }
         422                 :          0 :     filters[num_filters].id = LZMA_VLI_UNKNOWN;
         423                 :          0 :     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                 :          0 : spec_add_field(PyObject *spec, const char *key, unsigned long long value)
         434                 :            : {
         435                 :          0 :     PyObject *value_object = PyLong_FromUnsignedLongLong(value);
         436         [ #  # ]:          0 :     if (value_object == NULL) {
         437                 :          0 :         return -1;
         438                 :            :     }
         439                 :          0 :     PyObject *key_object = PyUnicode_InternFromString(key);
         440         [ #  # ]:          0 :     if (key_object == NULL) {
         441                 :          0 :         Py_DECREF(value_object);
         442                 :          0 :         return -1;
         443                 :            :     }
         444                 :          0 :     int status = PyDict_SetItem(spec, key_object, value_object);
         445                 :          0 :     Py_DECREF(key_object);
         446                 :          0 :     Py_DECREF(value_object);
         447                 :          0 :     return status;
         448                 :            : }
         449                 :            :
         450                 :            : static PyObject *
         451                 :          0 : build_filter_spec(const lzma_filter *f)
         452                 :            : {
         453                 :            :     PyObject *spec;
         454                 :            :
         455                 :          0 :     spec = PyDict_New();
         456         [ #  # ]:          0 :     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         [ #  # ]:          0 :     ADD_FIELD(f, id);
         467                 :            :
         468   [ #  #  #  #  :          0 :     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                 :          0 :         case LZMA_FILTER_LZMA1: {
         473                 :          0 :             lzma_options_lzma *options = f->options;
         474         [ #  # ]:          0 :             ADD_FIELD(options, lc);
         475         [ #  # ]:          0 :             ADD_FIELD(options, lp);
         476         [ #  # ]:          0 :             ADD_FIELD(options, pb);
         477         [ #  # ]:          0 :             ADD_FIELD(options, dict_size);
         478                 :          0 :             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                 :          0 :     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                 :          0 : compress(Compressor *c, uint8_t *data, size_t len, lzma_action action)
         548                 :            : {
         549                 :            :     PyObject *result;
         550                 :          0 :     _BlocksOutputBuffer buffer = {.list = NULL};
         551                 :          0 :     _lzma_state *state = PyType_GetModuleState(Py_TYPE(c));
         552                 :            :     assert(state != NULL);
         553                 :            :
         554         [ #  # ]:          0 :     if (OutputBuffer_InitAndGrow(&buffer, -1, &c->lzs.next_out, &c->lzs.avail_out) < 0) {
         555                 :          0 :         goto error;
         556                 :            :     }
         557                 :          0 :     c->lzs.next_in = data;
         558                 :          0 :     c->lzs.avail_in = len;
         559                 :            :
         560                 :          0 :     for (;;) {
         561                 :            :         lzma_ret lzret;
         562                 :            :
         563                 :          0 :         Py_BEGIN_ALLOW_THREADS
         564                 :          0 :         lzret = lzma_code(&c->lzs, action);
         565                 :          0 :         Py_END_ALLOW_THREADS
         566                 :            :
         567   [ #  #  #  #  :          0 :         if (lzret == LZMA_BUF_ERROR && len == 0 && c->lzs.avail_out > 0) {
                       #  # ]
         568                 :          0 :             lzret = LZMA_OK; /* That wasn't a real error */
         569                 :            :         }
         570         [ #  # ]:          0 :         if (catch_lzma_error(state, lzret)) {
         571                 :          0 :             goto error;
         572                 :            :         }
         573   [ #  #  #  #  :          0 :         if ((action == LZMA_RUN && c->lzs.avail_in == 0) ||
                       #  # ]
         574         [ #  # ]:          0 :             (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) {
         575                 :            :             break;
         576         [ #  # ]:          0 :         } else if (c->lzs.avail_out == 0) {
         577         [ #  # ]:          0 :             if (OutputBuffer_Grow(&buffer, &c->lzs.next_out, &c->lzs.avail_out) < 0) {
         578                 :          0 :                 goto error;
         579                 :            :             }
         580                 :            :         }
         581                 :            :     }
         582                 :            :
         583                 :          0 :     result = OutputBuffer_Finish(&buffer, c->lzs.avail_out);
         584         [ #  # ]:          0 :     if (result != NULL) {
         585                 :          0 :         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                 :          0 : _lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data)
         609                 :            : /*[clinic end generated code: output=31f615136963e00f input=64019eac7f2cc8d0]*/
         610                 :            : {
         611                 :          0 :     PyObject *result = NULL;
         612                 :            :
         613         [ #  # ]:          0 :     ACQUIRE_LOCK(self);
         614         [ #  # ]:          0 :     if (self->flushed) {
         615                 :          0 :         PyErr_SetString(PyExc_ValueError, "Compressor has been flushed");
         616                 :            :     }
         617                 :            :     else {
         618                 :          0 :         result = compress(self, data->buf, data->len, LZMA_RUN);
         619                 :            :     }
         620                 :          0 :     RELEASE_LOCK(self);
         621                 :          0 :     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                 :          0 : _lzma_LZMACompressor_flush_impl(Compressor *self)
         636                 :            : /*[clinic end generated code: output=fec21f3e22504f50 input=6b369303f67ad0a8]*/
         637                 :            : {
         638                 :          0 :     PyObject *result = NULL;
         639                 :            :
         640         [ #  # ]:          0 :     ACQUIRE_LOCK(self);
         641         [ #  # ]:          0 :     if (self->flushed) {
         642                 :          0 :         PyErr_SetString(PyExc_ValueError, "Repeated call to flush()");
         643                 :            :     } else {
         644                 :          0 :         self->flushed = 1;
         645                 :          0 :         result = compress(self, NULL, 0, LZMA_FINISH);
         646                 :            :     }
         647                 :          0 :     RELEASE_LOCK(self);
         648                 :          0 :     return result;
         649                 :            : }
         650                 :            :
         651                 :            : static int
         652                 :          0 : Compressor_init_xz(_lzma_state *state, lzma_stream *lzs,
         653                 :            :                    int check, uint32_t preset, PyObject *filterspecs)
         654                 :            : {
         655                 :            :     lzma_ret lzret;
         656                 :            :
         657         [ #  # ]:          0 :     if (filterspecs == Py_None) {
         658                 :          0 :         lzret = lzma_easy_encoder(lzs, preset, check);
         659                 :            :     } else {
         660                 :            :         lzma_filter filters[LZMA_FILTERS_MAX + 1];
         661                 :            :
         662         [ #  # ]:          0 :         if (parse_filter_chain_spec(state, filters, filterspecs) == -1)
         663                 :          0 :             return -1;
         664                 :          0 :         lzret = lzma_stream_encoder(lzs, filters, check);
         665                 :          0 :         free_filter_chain(filters);
         666                 :            :     }
         667         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret)) {
         668                 :          0 :         return -1;
         669                 :            :     }
         670                 :            :     else {
         671                 :          0 :         return 0;
         672                 :            :     }
         673                 :            : }
         674                 :            :
         675                 :            : static int
         676                 :          0 : Compressor_init_alone(_lzma_state *state, lzma_stream *lzs, uint32_t preset, PyObject *filterspecs)
         677                 :            : {
         678                 :            :     lzma_ret lzret;
         679                 :            :
         680         [ #  # ]:          0 :     if (filterspecs == Py_None) {
         681                 :            :         lzma_options_lzma options;
         682                 :            :
         683         [ #  # ]:          0 :         if (lzma_lzma_preset(&options, preset)) {
         684                 :          0 :             PyErr_Format(state->error, "Invalid compression preset: %u", preset);
         685                 :          0 :             return -1;
         686                 :            :         }
         687                 :          0 :         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   [ #  #  #  # ]:          0 :     if (PyErr_Occurred() || catch_lzma_error(state, lzret)) {
         705                 :          0 :         return -1;
         706                 :            :     }
         707                 :            :     else {
         708                 :          0 :         return 0;
         709                 :            :     }
         710                 :            : }
         711                 :            :
         712                 :            : static int
         713                 :          0 : 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         [ #  # ]:          0 :     if (filterspecs == Py_None) {
         719                 :          0 :         PyErr_SetString(PyExc_ValueError,
         720                 :            :                         "Must specify filters for FORMAT_RAW");
         721                 :          0 :         return -1;
         722                 :            :     }
         723         [ #  # ]:          0 :     if (parse_filter_chain_spec(state, filters, filterspecs) == -1) {
         724                 :          0 :         return -1;
         725                 :            :     }
         726                 :          0 :     lzret = lzma_raw_encoder(lzs, filters);
         727                 :          0 :     free_filter_chain(filters);
         728         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret)) {
         729                 :          0 :         return -1;
         730                 :            :     }
         731                 :            :     else {
         732                 :          0 :         return 0;
         733                 :            :     }
         734                 :            : }
         735                 :            :
         736                 :            : /*[-clinic input]
         737                 :            : @classmethod
         738                 :            : _lzma.LZMACompressor.__new__
         739                 :            :
         740                 :            :     format: int(c_default="FORMAT_XZ") = FORMAT_XZ
         741                 :            :         The container format to use for the output.  This can
         742                 :            :         be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.
         743                 :            :
         744                 :            :     check: int(c_default="-1") = unspecified
         745                 :            :         The integrity check to use.  For FORMAT_XZ, the default
         746                 :            :         is CHECK_CRC64.  FORMAT_ALONE and FORMAT_RAW do not support integrity
         747                 :            :         checks; for these formats, check must be omitted, or be CHECK_NONE.
         748                 :            :
         749                 :            :     preset: object = None
         750                 :            :         If provided should be an integer in the range 0-9, optionally
         751                 :            :         OR-ed with the constant PRESET_EXTREME.
         752                 :            :
         753                 :            :     filters: object = None
         754                 :            :         If provided should be a sequence of dicts.  Each dict should
         755                 :            :         have an entry for "id" indicating the ID of the filter, plus
         756                 :            :         additional entries for options to the filter.
         757                 :            :
         758                 :            : Create a compressor object for compressing data incrementally.
         759                 :            :
         760                 :            : The settings used by the compressor can be specified either as a
         761                 :            : preset compression level (with the 'preset' argument), or in detail
         762                 :            : as a custom filter chain (with the 'filters' argument).  For FORMAT_XZ
         763                 :            : and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset
         764                 :            : level.  For FORMAT_RAW, the caller must always specify a filter chain;
         765                 :            : the raw compressor does not support preset compression levels.
         766                 :            :
         767                 :            : For one-shot compression, use the compress() function instead.
         768                 :            : [-clinic start generated code]*/
         769                 :            : static PyObject *
         770                 :          0 : Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
         771                 :            : {
         772                 :            :     static char *arg_names[] = {"format", "check", "preset", "filters", NULL};
         773                 :          0 :     int format = FORMAT_XZ;
         774                 :          0 :     int check = -1;
         775                 :          0 :     uint32_t preset = LZMA_PRESET_DEFAULT;
         776                 :          0 :     PyObject *preset_obj = Py_None;
         777                 :          0 :     PyObject *filterspecs = Py_None;
         778                 :            :     Compressor *self;
         779                 :            :
         780                 :          0 :     _lzma_state *state = PyType_GetModuleState(type);
         781                 :            :     assert(state != NULL);
         782         [ #  # ]:          0 :     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
         783                 :            :                                      "|iiOO:LZMACompressor", arg_names,
         784                 :            :                                      &format, &check, &preset_obj,
         785                 :            :                                      &filterspecs)) {
         786                 :          0 :         return NULL;
         787                 :            :     }
         788                 :            :
         789   [ #  #  #  #  :          0 :     if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) {
                       #  # ]
         790                 :          0 :         PyErr_SetString(PyExc_ValueError,
         791                 :            :                         "Integrity checks are only supported by FORMAT_XZ");
         792                 :          0 :         return NULL;
         793                 :            :     }
         794                 :            :
         795   [ #  #  #  # ]:          0 :     if (preset_obj != Py_None && filterspecs != Py_None) {
         796                 :          0 :         PyErr_SetString(PyExc_ValueError,
         797                 :            :                         "Cannot specify both preset and filter chain");
         798                 :          0 :         return NULL;
         799                 :            :     }
         800                 :            :
         801   [ #  #  #  # ]:          0 :     if (preset_obj != Py_None && !uint32_converter(preset_obj, &preset)) {
         802                 :          0 :         return NULL;
         803                 :            :     }
         804                 :            :
         805                 :            :     assert(type != NULL && type->tp_alloc != NULL);
         806                 :          0 :     self = (Compressor *)type->tp_alloc(type, 0);
         807         [ #  # ]:          0 :     if (self == NULL) {
         808                 :          0 :         return NULL;
         809                 :            :     }
         810                 :            :
         811                 :          0 :     self->alloc.opaque = NULL;
         812                 :          0 :     self->alloc.alloc = PyLzma_Malloc;
         813                 :          0 :     self->alloc.free = PyLzma_Free;
         814                 :          0 :     self->lzs.allocator = &self->alloc;
         815                 :            :
         816                 :          0 :     self->lock = PyThread_allocate_lock();
         817         [ #  # ]:          0 :     if (self->lock == NULL) {
         818                 :          0 :         Py_DECREF(self);
         819                 :          0 :         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
         820                 :          0 :         return NULL;
         821                 :            :     }
         822                 :            :
         823                 :          0 :     self->flushed = 0;
         824   [ #  #  #  # ]:          0 :     switch (format) {
         825                 :          0 :         case FORMAT_XZ:
         826         [ #  # ]:          0 :             if (check == -1) {
         827                 :          0 :                 check = LZMA_CHECK_CRC64;
         828                 :            :             }
         829         [ #  # ]:          0 :             if (Compressor_init_xz(state, &self->lzs, check, preset, filterspecs) != 0) {
         830                 :          0 :                 goto error;
         831                 :            :             }
         832                 :          0 :             break;
         833                 :            :
         834                 :          0 :         case FORMAT_ALONE:
         835         [ #  # ]:          0 :             if (Compressor_init_alone(state, &self->lzs, preset, filterspecs) != 0) {
         836                 :          0 :                 goto error;
         837                 :            :             }
         838                 :          0 :             break;
         839                 :            :
         840                 :          0 :         case FORMAT_RAW:
         841         [ #  # ]:          0 :             if (Compressor_init_raw(state, &self->lzs, filterspecs) != 0) {
         842                 :          0 :                 goto error;
         843                 :            :             }
         844                 :          0 :             break;
         845                 :            :
         846                 :          0 :         default:
         847                 :          0 :             PyErr_Format(PyExc_ValueError,
         848                 :            :                          "Invalid container format: %d", format);
         849                 :          0 :             goto error;
         850                 :            :     }
         851                 :            :
         852                 :          0 :     return (PyObject *)self;
         853                 :            :
         854                 :          0 : error:
         855                 :          0 :     Py_DECREF(self);
         856                 :          0 :     return NULL;
         857                 :            : }
         858                 :            :
         859                 :            : static void
         860                 :          0 : Compressor_dealloc(Compressor *self)
         861                 :            : {
         862                 :          0 :     lzma_end(&self->lzs);
         863         [ #  # ]:          0 :     if (self->lock != NULL) {
         864                 :          0 :         PyThread_free_lock(self->lock);
         865                 :            :     }
         866                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
         867                 :          0 :     tp->tp_free((PyObject *)self);
         868                 :          0 :     Py_DECREF(tp);
         869                 :          0 : }
         870                 :            :
         871                 :            : static PyMethodDef Compressor_methods[] = {
         872                 :            :     _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
         873                 :            :     _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
         874                 :            :     {NULL}
         875                 :            : };
         876                 :            :
         877                 :            : static int
         878                 :          0 : Compressor_traverse(Compressor *self, visitproc visit, void *arg)
         879                 :            : {
         880   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
         881                 :          0 :     return 0;
         882                 :            : }
         883                 :            :
         884                 :            : PyDoc_STRVAR(Compressor_doc,
         885                 :            : "LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)\n"
         886                 :            : "\n"
         887                 :            : "Create a compressor object for compressing data incrementally.\n"
         888                 :            : "\n"
         889                 :            : "format specifies the container format to use for the output. This can\n"
         890                 :            : "be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW.\n"
         891                 :            : "\n"
         892                 :            : "check specifies the integrity check to use. For FORMAT_XZ, the default\n"
         893                 :            : "is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity\n"
         894                 :            : "checks; for these formats, check must be omitted, or be CHECK_NONE.\n"
         895                 :            : "\n"
         896                 :            : "The settings used by the compressor can be specified either as a\n"
         897                 :            : "preset compression level (with the 'preset' argument), or in detail\n"
         898                 :            : "as a custom filter chain (with the 'filters' argument). For FORMAT_XZ\n"
         899                 :            : "and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset\n"
         900                 :            : "level. For FORMAT_RAW, the caller must always specify a filter chain;\n"
         901                 :            : "the raw compressor does not support preset compression levels.\n"
         902                 :            : "\n"
         903                 :            : "preset (if provided) should be an integer in the range 0-9, optionally\n"
         904                 :            : "OR-ed with the constant PRESET_EXTREME.\n"
         905                 :            : "\n"
         906                 :            : "filters (if provided) should be a sequence of dicts. Each dict should\n"
         907                 :            : "have an entry for \"id\" indicating the ID of the filter, plus\n"
         908                 :            : "additional entries for options to the filter.\n"
         909                 :            : "\n"
         910                 :            : "For one-shot compression, use the compress() function instead.\n");
         911                 :            :
         912                 :            : static PyType_Slot lzma_compressor_type_slots[] = {
         913                 :            :     {Py_tp_dealloc, Compressor_dealloc},
         914                 :            :     {Py_tp_methods, Compressor_methods},
         915                 :            :     {Py_tp_new, Compressor_new},
         916                 :            :     {Py_tp_doc, (char *)Compressor_doc},
         917                 :            :     {Py_tp_traverse, Compressor_traverse},
         918                 :            :     {0, 0}
         919                 :            : };
         920                 :            :
         921                 :            : static PyType_Spec lzma_compressor_type_spec = {
         922                 :            :     .name = "_lzma.LZMACompressor",
         923                 :            :     .basicsize = sizeof(Compressor),
         924                 :            :     // Calling PyType_GetModuleState() on a subclass is not safe.
         925                 :            :     // lzma_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
         926                 :            :     // which prevents to create a subclass.
         927                 :            :     // So calling PyType_GetModuleState() in this file is always safe.
         928                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
         929                 :            :     .slots = lzma_compressor_type_slots,
         930                 :            : };
         931                 :            :
         932                 :            : /* LZMADecompressor class. */
         933                 :            :
         934                 :            : /* Decompress data of length d->lzs.avail_in in d->lzs.next_in.  The output
         935                 :            :    buffer is allocated dynamically and returned.  At most max_length bytes are
         936                 :            :    returned, so some of the input may not be consumed. d->lzs.next_in and
         937                 :            :    d->lzs.avail_in are updated to reflect the consumed input. */
         938                 :            : static PyObject*
         939                 :          0 : decompress_buf(Decompressor *d, Py_ssize_t max_length)
         940                 :            : {
         941                 :            :     PyObject *result;
         942                 :          0 :     lzma_stream *lzs = &d->lzs;
         943                 :          0 :     _BlocksOutputBuffer buffer = {.list = NULL};
         944                 :          0 :     _lzma_state *state = PyType_GetModuleState(Py_TYPE(d));
         945                 :            :     assert(state != NULL);
         946                 :            :
         947         [ #  # ]:          0 :     if (OutputBuffer_InitAndGrow(&buffer, max_length, &lzs->next_out, &lzs->avail_out) < 0) {
         948                 :          0 :         goto error;
         949                 :            :     }
         950                 :            :
         951                 :          0 :     for (;;) {
         952                 :            :         lzma_ret lzret;
         953                 :            :
         954                 :          0 :         Py_BEGIN_ALLOW_THREADS
         955                 :          0 :         lzret = lzma_code(lzs, LZMA_RUN);
         956                 :          0 :         Py_END_ALLOW_THREADS
         957                 :            :
         958   [ #  #  #  #  :          0 :         if (lzret == LZMA_BUF_ERROR && lzs->avail_in == 0 && lzs->avail_out > 0) {
                       #  # ]
         959                 :          0 :             lzret = LZMA_OK; /* That wasn't a real error */
         960                 :            :         }
         961         [ #  # ]:          0 :         if (catch_lzma_error(state, lzret)) {
         962                 :          0 :             goto error;
         963                 :            :         }
         964   [ #  #  #  # ]:          0 :         if (lzret == LZMA_GET_CHECK || lzret == LZMA_NO_CHECK) {
         965                 :          0 :             d->check = lzma_get_check(&d->lzs);
         966                 :            :         }
         967         [ #  # ]:          0 :         if (lzret == LZMA_STREAM_END) {
         968                 :          0 :             d->eof = 1;
         969                 :          0 :             break;
         970         [ #  # ]:          0 :         } else if (lzs->avail_out == 0) {
         971                 :            :             /* Need to check lzs->avail_out before lzs->avail_in.
         972                 :            :                Maybe lzs's internal state still have a few bytes
         973                 :            :                can be output, grow the output buffer and continue
         974                 :            :                if max_lengh < 0. */
         975         [ #  # ]:          0 :             if (OutputBuffer_GetDataSize(&buffer, lzs->avail_out) == max_length) {
         976                 :          0 :                 break;
         977                 :            :             }
         978         [ #  # ]:          0 :             if (OutputBuffer_Grow(&buffer, &lzs->next_out, &lzs->avail_out) < 0) {
         979                 :          0 :                 goto error;
         980                 :            :             }
         981         [ #  # ]:          0 :         } else if (lzs->avail_in == 0) {
         982                 :          0 :             break;
         983                 :            :         }
         984                 :            :     }
         985                 :            :
         986                 :          0 :     result = OutputBuffer_Finish(&buffer, lzs->avail_out);
         987         [ #  # ]:          0 :     if (result != NULL) {
         988                 :          0 :         return result;
         989                 :            :     }
         990                 :            :
         991                 :          0 : error:
         992                 :          0 :     OutputBuffer_OnError(&buffer);
         993                 :          0 :     return NULL;
         994                 :            : }
         995                 :            :
         996                 :            : static PyObject *
         997                 :          0 : decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length)
         998                 :            : {
         999                 :            :     char input_buffer_in_use;
        1000                 :            :     PyObject *result;
        1001                 :          0 :     lzma_stream *lzs = &d->lzs;
        1002                 :            :
        1003                 :            :     /* Prepend unconsumed input if necessary */
        1004         [ #  # ]:          0 :     if (lzs->next_in != NULL) {
        1005                 :            :         size_t avail_now, avail_total;
        1006                 :            :
        1007                 :            :         /* Number of bytes we can append to input buffer */
        1008                 :          0 :         avail_now = (d->input_buffer + d->input_buffer_size)
        1009                 :          0 :             - (lzs->next_in + lzs->avail_in);
        1010                 :            :
        1011                 :            :         /* Number of bytes we can append if we move existing
        1012                 :            :            contents to beginning of buffer (overwriting
        1013                 :            :            consumed input) */
        1014                 :          0 :         avail_total = d->input_buffer_size - lzs->avail_in;
        1015                 :            :
        1016         [ #  # ]:          0 :         if (avail_total < len) {
        1017                 :          0 :             size_t offset = lzs->next_in - d->input_buffer;
        1018                 :            :             uint8_t *tmp;
        1019                 :          0 :             size_t new_size = d->input_buffer_size + len - avail_now;
        1020                 :            :
        1021                 :            :             /* Assign to temporary variable first, so we don't
        1022                 :            :                lose address of allocated buffer if realloc fails */
        1023                 :          0 :             tmp = PyMem_Realloc(d->input_buffer, new_size);
        1024         [ #  # ]:          0 :             if (tmp == NULL) {
        1025                 :          0 :                 PyErr_SetNone(PyExc_MemoryError);
        1026                 :          0 :                 return NULL;
        1027                 :            :             }
        1028                 :          0 :             d->input_buffer = tmp;
        1029                 :          0 :             d->input_buffer_size = new_size;
        1030                 :            :
        1031                 :          0 :             lzs->next_in = d->input_buffer + offset;
        1032                 :            :         }
        1033         [ #  # ]:          0 :         else if (avail_now < len) {
        1034                 :          0 :             memmove(d->input_buffer, lzs->next_in,
        1035                 :            :                     lzs->avail_in);
        1036                 :          0 :             lzs->next_in = d->input_buffer;
        1037                 :            :         }
        1038                 :          0 :         memcpy((void*)(lzs->next_in + lzs->avail_in), data, len);
        1039                 :          0 :         lzs->avail_in += len;
        1040                 :          0 :         input_buffer_in_use = 1;
        1041                 :            :     }
        1042                 :            :     else {
        1043                 :          0 :         lzs->next_in = data;
        1044                 :          0 :         lzs->avail_in = len;
        1045                 :          0 :         input_buffer_in_use = 0;
        1046                 :            :     }
        1047                 :            :
        1048                 :          0 :     result = decompress_buf(d, max_length);
        1049         [ #  # ]:          0 :     if (result == NULL) {
        1050                 :          0 :         lzs->next_in = NULL;
        1051                 :          0 :         return NULL;
        1052                 :            :     }
        1053                 :            :
        1054         [ #  # ]:          0 :     if (d->eof) {
        1055                 :          0 :         d->needs_input = 0;
        1056         [ #  # ]:          0 :         if (lzs->avail_in > 0) {
        1057                 :          0 :             Py_XSETREF(d->unused_data,
        1058                 :            :                       PyBytes_FromStringAndSize((char *)lzs->next_in, lzs->avail_in));
        1059         [ #  # ]:          0 :             if (d->unused_data == NULL) {
        1060                 :          0 :                 goto error;
        1061                 :            :             }
        1062                 :            :         }
        1063                 :            :     }
        1064         [ #  # ]:          0 :     else if (lzs->avail_in == 0) {
        1065                 :          0 :         lzs->next_in = NULL;
        1066                 :            :
        1067         [ #  # ]:          0 :         if (lzs->avail_out == 0) {
        1068                 :            :             /* (avail_in==0 && avail_out==0)
        1069                 :            :                Maybe lzs's internal state still have a few bytes can
        1070                 :            :                be output, try to output them next time. */
        1071                 :          0 :             d->needs_input = 0;
        1072                 :            :
        1073                 :            :             /* If max_length < 0, lzs->avail_out always > 0 */
        1074                 :            :             assert(max_length >= 0);
        1075                 :            :         } else {
        1076                 :            :             /* Input buffer exhausted, output buffer has space. */
        1077                 :          0 :             d->needs_input = 1;
        1078                 :            :         }
        1079                 :            :     }
        1080                 :            :     else {
        1081                 :          0 :         d->needs_input = 0;
        1082                 :            :
        1083                 :            :         /* If we did not use the input buffer, we now have
        1084                 :            :            to copy the tail from the caller's buffer into the
        1085                 :            :            input buffer */
        1086         [ #  # ]:          0 :         if (!input_buffer_in_use) {
        1087                 :            :
        1088                 :            :             /* Discard buffer if it's too small
        1089                 :            :                (resizing it may needlessly copy the current contents) */
        1090         [ #  # ]:          0 :             if (d->input_buffer != NULL &&
        1091         [ #  # ]:          0 :                 d->input_buffer_size < lzs->avail_in) {
        1092                 :          0 :                 PyMem_Free(d->input_buffer);
        1093                 :          0 :                 d->input_buffer = NULL;
        1094                 :            :             }
        1095                 :            :
        1096                 :            :             /* Allocate if necessary */
        1097         [ #  # ]:          0 :             if (d->input_buffer == NULL) {
        1098                 :          0 :                 d->input_buffer = PyMem_Malloc(lzs->avail_in);
        1099         [ #  # ]:          0 :                 if (d->input_buffer == NULL) {
        1100                 :          0 :                     PyErr_SetNone(PyExc_MemoryError);
        1101                 :          0 :                     goto error;
        1102                 :            :                 }
        1103                 :          0 :                 d->input_buffer_size = lzs->avail_in;
        1104                 :            :             }
        1105                 :            :
        1106                 :            :             /* Copy tail */
        1107                 :          0 :             memcpy(d->input_buffer, lzs->next_in, lzs->avail_in);
        1108                 :          0 :             lzs->next_in = d->input_buffer;
        1109                 :            :         }
        1110                 :            :     }
        1111                 :            :
        1112                 :          0 :     return result;
        1113                 :            :
        1114                 :          0 : error:
        1115                 :          0 :     Py_XDECREF(result);
        1116                 :          0 :     return NULL;
        1117                 :            : }
        1118                 :            :
        1119                 :            : /*[clinic input]
        1120                 :            : _lzma.LZMADecompressor.decompress
        1121                 :            :
        1122                 :            :     data: Py_buffer
        1123                 :            :     max_length: Py_ssize_t=-1
        1124                 :            :
        1125                 :            : Decompress *data*, returning uncompressed data as bytes.
        1126                 :            :
        1127                 :            : If *max_length* is nonnegative, returns at most *max_length* bytes of
        1128                 :            : decompressed data. If this limit is reached and further output can be
        1129                 :            : produced, *self.needs_input* will be set to ``False``. In this case, the next
        1130                 :            : call to *decompress()* may provide *data* as b'' to obtain more of the output.
        1131                 :            :
        1132                 :            : If all of the input data was decompressed and returned (either because this
        1133                 :            : was less than *max_length* bytes, or because *max_length* was negative),
        1134                 :            : *self.needs_input* will be set to True.
        1135                 :            :
        1136                 :            : Attempting to decompress data after the end of stream is reached raises an
        1137                 :            : EOFError.  Any data found after the end of the stream is ignored and saved in
        1138                 :            : the unused_data attribute.
        1139                 :            : [clinic start generated code]*/
        1140                 :            :
        1141                 :            : static PyObject *
        1142                 :          0 : _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data,
        1143                 :            :                                        Py_ssize_t max_length)
        1144                 :            : /*[clinic end generated code: output=ef4e20ec7122241d input=60c1f135820e309d]*/
        1145                 :            : {
        1146                 :          0 :     PyObject *result = NULL;
        1147                 :            :
        1148         [ #  # ]:          0 :     ACQUIRE_LOCK(self);
        1149         [ #  # ]:          0 :     if (self->eof)
        1150                 :          0 :         PyErr_SetString(PyExc_EOFError, "Already at end of stream");
        1151                 :            :     else
        1152                 :          0 :         result = decompress(self, data->buf, data->len, max_length);
        1153                 :          0 :     RELEASE_LOCK(self);
        1154                 :          0 :     return result;
        1155                 :            : }
        1156                 :            :
        1157                 :            : static int
        1158                 :          0 : Decompressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspecs)
        1159                 :            : {
        1160                 :            :     lzma_filter filters[LZMA_FILTERS_MAX + 1];
        1161                 :            :     lzma_ret lzret;
        1162                 :            :
        1163         [ #  # ]:          0 :     if (parse_filter_chain_spec(state, filters, filterspecs) == -1) {
        1164                 :          0 :         return -1;
        1165                 :            :     }
        1166                 :          0 :     lzret = lzma_raw_decoder(lzs, filters);
        1167                 :          0 :     free_filter_chain(filters);
        1168         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret)) {
        1169                 :          0 :         return -1;
        1170                 :            :     }
        1171                 :            :     else {
        1172                 :          0 :         return 0;
        1173                 :            :     }
        1174                 :            : }
        1175                 :            :
        1176                 :            : /*[clinic input]
        1177                 :            : @classmethod
        1178                 :            : _lzma.LZMADecompressor.__new__
        1179                 :            :
        1180                 :            :     format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
        1181                 :            :         Specifies the container format of the input stream.  If this is
        1182                 :            :         FORMAT_AUTO (the default), the decompressor will automatically detect
        1183                 :            :         whether the input is FORMAT_XZ or FORMAT_ALONE.  Streams created with
        1184                 :            :         FORMAT_RAW cannot be autodetected.
        1185                 :            :
        1186                 :            :     memlimit: object = None
        1187                 :            :         Limit the amount of memory used by the decompressor.  This will cause
        1188                 :            :         decompression to fail if the input cannot be decompressed within the
        1189                 :            :         given limit.
        1190                 :            :
        1191                 :            :     filters: object = None
        1192                 :            :         A custom filter chain.  This argument is required for FORMAT_RAW, and
        1193                 :            :         not accepted with any other format.  When provided, this should be a
        1194                 :            :         sequence of dicts, each indicating the ID and options for a single
        1195                 :            :         filter.
        1196                 :            :
        1197                 :            : Create a decompressor object for decompressing data incrementally.
        1198                 :            :
        1199                 :            : For one-shot decompression, use the decompress() function instead.
        1200                 :            : [clinic start generated code]*/
        1201                 :            :
        1202                 :            : static PyObject *
        1203                 :          0 : _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
        1204                 :            :                             PyObject *memlimit, PyObject *filters)
        1205                 :            : /*[clinic end generated code: output=2d46d5e70f10bc7f input=ca40cd1cb1202b0d]*/
        1206                 :            : {
        1207                 :            :     Decompressor *self;
        1208                 :          0 :     const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
        1209                 :          0 :     uint64_t memlimit_ = UINT64_MAX;
        1210                 :            :     lzma_ret lzret;
        1211                 :          0 :     _lzma_state *state = PyType_GetModuleState(type);
        1212                 :            :     assert(state != NULL);
        1213                 :            :
        1214         [ #  # ]:          0 :     if (memlimit != Py_None) {
        1215         [ #  # ]:          0 :         if (format == FORMAT_RAW) {
        1216                 :          0 :             PyErr_SetString(PyExc_ValueError,
        1217                 :            :                             "Cannot specify memory limit with FORMAT_RAW");
        1218                 :          0 :             return NULL;
        1219                 :            :         }
        1220                 :          0 :         memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
        1221         [ #  # ]:          0 :         if (PyErr_Occurred()) {
        1222                 :          0 :             return NULL;
        1223                 :            :         }
        1224                 :            :     }
        1225                 :            :
        1226   [ #  #  #  # ]:          0 :     if (format == FORMAT_RAW && filters == Py_None) {
        1227                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1228                 :            :                         "Must specify filters for FORMAT_RAW");
        1229                 :          0 :         return NULL;
        1230   [ #  #  #  # ]:          0 :     } else if (format != FORMAT_RAW && filters != Py_None) {
        1231                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1232                 :            :                         "Cannot specify filters except with FORMAT_RAW");
        1233                 :          0 :         return NULL;
        1234                 :            :     }
        1235                 :            :
        1236                 :            :     assert(type != NULL && type->tp_alloc != NULL);
        1237                 :          0 :     self = (Decompressor *)type->tp_alloc(type, 0);
        1238         [ #  # ]:          0 :     if (self == NULL) {
        1239                 :          0 :         return NULL;
        1240                 :            :     }
        1241                 :          0 :     self->alloc.opaque = NULL;
        1242                 :          0 :     self->alloc.alloc = PyLzma_Malloc;
        1243                 :          0 :     self->alloc.free = PyLzma_Free;
        1244                 :          0 :     self->lzs.allocator = &self->alloc;
        1245                 :          0 :     self->lzs.next_in = NULL;
        1246                 :            :
        1247                 :          0 :     self->lock = PyThread_allocate_lock();
        1248         [ #  # ]:          0 :     if (self->lock == NULL) {
        1249                 :          0 :         Py_DECREF(self);
        1250                 :          0 :         PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
        1251                 :          0 :         return NULL;
        1252                 :            :     }
        1253                 :            :
        1254                 :          0 :     self->check = LZMA_CHECK_UNKNOWN;
        1255                 :          0 :     self->needs_input = 1;
        1256                 :          0 :     self->input_buffer = NULL;
        1257                 :          0 :     self->input_buffer_size = 0;
        1258                 :          0 :     Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
        1259         [ #  # ]:          0 :     if (self->unused_data == NULL) {
        1260                 :          0 :         goto error;
        1261                 :            :     }
        1262                 :            :
        1263   [ #  #  #  #  :          0 :     switch (format) {
                          # ]
        1264                 :          0 :         case FORMAT_AUTO:
        1265                 :          0 :             lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
        1266         [ #  # ]:          0 :             if (catch_lzma_error(state, lzret)) {
        1267                 :          0 :                 goto error;
        1268                 :            :             }
        1269                 :          0 :             break;
        1270                 :            :
        1271                 :          0 :         case FORMAT_XZ:
        1272                 :          0 :             lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
        1273         [ #  # ]:          0 :             if (catch_lzma_error(state, lzret)) {
        1274                 :          0 :                 goto error;
        1275                 :            :             }
        1276                 :          0 :             break;
        1277                 :            :
        1278                 :          0 :         case FORMAT_ALONE:
        1279                 :          0 :             self->check = LZMA_CHECK_NONE;
        1280                 :          0 :             lzret = lzma_alone_decoder(&self->lzs, memlimit_);
        1281         [ #  # ]:          0 :             if (catch_lzma_error(state, lzret)) {
        1282                 :          0 :                 goto error;
        1283                 :            :             }
        1284                 :          0 :             break;
        1285                 :            :
        1286                 :          0 :         case FORMAT_RAW:
        1287                 :          0 :             self->check = LZMA_CHECK_NONE;
        1288         [ #  # ]:          0 :             if (Decompressor_init_raw(state, &self->lzs, filters) == -1) {
        1289                 :          0 :                 goto error;
        1290                 :            :             }
        1291                 :          0 :             break;
        1292                 :            :
        1293                 :          0 :         default:
        1294                 :          0 :             PyErr_Format(PyExc_ValueError,
        1295                 :            :                          "Invalid container format: %d", format);
        1296                 :          0 :             goto error;
        1297                 :            :     }
        1298                 :            :
        1299                 :          0 :     return (PyObject *)self;
        1300                 :            :
        1301                 :          0 : error:
        1302                 :          0 :     Py_DECREF(self);
        1303                 :          0 :     return NULL;
        1304                 :            : }
        1305                 :            :
        1306                 :            : static void
        1307                 :          0 : Decompressor_dealloc(Decompressor *self)
        1308                 :            : {
        1309         [ #  # ]:          0 :     if(self->input_buffer != NULL)
        1310                 :          0 :         PyMem_Free(self->input_buffer);
        1311                 :            :
        1312                 :          0 :     lzma_end(&self->lzs);
        1313         [ #  # ]:          0 :     Py_CLEAR(self->unused_data);
        1314         [ #  # ]:          0 :     if (self->lock != NULL) {
        1315                 :          0 :         PyThread_free_lock(self->lock);
        1316                 :            :     }
        1317                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
        1318                 :          0 :     tp->tp_free((PyObject *)self);
        1319                 :          0 :     Py_DECREF(tp);
        1320                 :          0 : }
        1321                 :            :
        1322                 :            : static int
        1323                 :          0 : Decompressor_traverse(Decompressor *self, visitproc visit, void *arg)
        1324                 :            : {
        1325   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
        1326                 :          0 :     return 0;
        1327                 :            : }
        1328                 :            :
        1329                 :            : static PyMethodDef Decompressor_methods[] = {
        1330                 :            :     _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
        1331                 :            :     {NULL}
        1332                 :            : };
        1333                 :            :
        1334                 :            : PyDoc_STRVAR(Decompressor_check_doc,
        1335                 :            : "ID of the integrity check used by the input stream.");
        1336                 :            :
        1337                 :            : PyDoc_STRVAR(Decompressor_eof_doc,
        1338                 :            : "True if the end-of-stream marker has been reached.");
        1339                 :            :
        1340                 :            : PyDoc_STRVAR(Decompressor_needs_input_doc,
        1341                 :            : "True if more input is needed before more decompressed data can be produced.");
        1342                 :            :
        1343                 :            : PyDoc_STRVAR(Decompressor_unused_data_doc,
        1344                 :            : "Data found after the end of the compressed stream.");
        1345                 :            :
        1346                 :            : static PyMemberDef Decompressor_members[] = {
        1347                 :            :     {"check", T_INT, offsetof(Decompressor, check), READONLY,
        1348                 :            :      Decompressor_check_doc},
        1349                 :            :     {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY,
        1350                 :            :      Decompressor_eof_doc},
        1351                 :            :     {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY,
        1352                 :            :      Decompressor_needs_input_doc},
        1353                 :            :     {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY,
        1354                 :            :      Decompressor_unused_data_doc},
        1355                 :            :     {NULL}
        1356                 :            : };
        1357                 :            :
        1358                 :            : static PyType_Slot lzma_decompressor_type_slots[] = {
        1359                 :            :     {Py_tp_dealloc, Decompressor_dealloc},
        1360                 :            :     {Py_tp_methods, Decompressor_methods},
        1361                 :            :     {Py_tp_new, _lzma_LZMADecompressor},
        1362                 :            :     {Py_tp_doc, (char *)_lzma_LZMADecompressor__doc__},
        1363                 :            :     {Py_tp_traverse, Decompressor_traverse},
        1364                 :            :     {Py_tp_members, Decompressor_members},
        1365                 :            :     {0, 0}
        1366                 :            : };
        1367                 :            :
        1368                 :            : static PyType_Spec lzma_decompressor_type_spec = {
        1369                 :            :     .name = "_lzma.LZMADecompressor",
        1370                 :            :     .basicsize = sizeof(Decompressor),
        1371                 :            :     // Calling PyType_GetModuleState() on a subclass is not safe.
        1372                 :            :     // lzma_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
        1373                 :            :     // which prevents to create a subclass.
        1374                 :            :     // So calling PyType_GetModuleState() in this file is always safe.
        1375                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
        1376                 :            :     .slots = lzma_decompressor_type_slots,
        1377                 :            : };
        1378                 :            :
        1379                 :            :
        1380                 :            : /* Module-level functions. */
        1381                 :            :
        1382                 :            : /*[clinic input]
        1383                 :            : _lzma.is_check_supported
        1384                 :            :     check_id: int
        1385                 :            :     /
        1386                 :            :
        1387                 :            : Test whether the given integrity check is supported.
        1388                 :            :
        1389                 :            : Always returns True for CHECK_NONE and CHECK_CRC32.
        1390                 :            : [clinic start generated code]*/
        1391                 :            :
        1392                 :            : static PyObject *
        1393                 :          0 : _lzma_is_check_supported_impl(PyObject *module, int check_id)
        1394                 :            : /*[clinic end generated code: output=e4f14ba3ce2ad0a5 input=5518297b97b2318f]*/
        1395                 :            : {
        1396                 :          0 :     return PyBool_FromLong(lzma_check_is_supported(check_id));
        1397                 :            : }
        1398                 :            :
        1399                 :            : PyDoc_STRVAR(_lzma__encode_filter_properties__doc__,
        1400                 :            : "_encode_filter_properties($module, filter, /)\n"
        1401                 :            : "--\n"
        1402                 :            : "\n"
        1403                 :            : "Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
        1404                 :            : "\n"
        1405                 :            : "The result does not include the filter ID itself, only the options.");
        1406                 :            :
        1407                 :            : #define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF    \
        1408                 :            :     {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_O, _lzma__encode_filter_properties__doc__},
        1409                 :            :
        1410                 :            : static PyObject *
        1411                 :            : _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter);
        1412                 :            :
        1413                 :            : static PyObject *
        1414                 :          0 : _lzma__encode_filter_properties(PyObject *module, PyObject *arg)
        1415                 :            : {
        1416                 :          0 :     PyObject *return_value = NULL;
        1417                 :          0 :     lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL};
        1418                 :          0 :     _lzma_state *state = get_lzma_state(module);
        1419                 :            :     assert(state != NULL);
        1420         [ #  # ]:          0 :     if (!lzma_filter_converter(state, arg, &filter)) {
        1421                 :          0 :         goto exit;
        1422                 :            :     }
        1423                 :          0 :     return_value = _lzma__encode_filter_properties_impl(module, filter);
        1424                 :            :
        1425                 :          0 : exit:
        1426                 :            :     /* Cleanup for filter */
        1427         [ #  # ]:          0 :     if (filter.id != LZMA_VLI_UNKNOWN) {
        1428                 :          0 :        PyMem_Free(filter.options);
        1429                 :            :     }
        1430                 :            :
        1431                 :          0 :     return return_value;
        1432                 :            : }
        1433                 :            :
        1434                 :            : static PyObject *
        1435                 :          0 : _lzma__encode_filter_properties_impl(PyObject *module, lzma_filter filter)
        1436                 :            : {
        1437                 :            :     lzma_ret lzret;
        1438                 :            :     uint32_t encoded_size;
        1439                 :          0 :     PyObject *result = NULL;
        1440                 :          0 :     _lzma_state *state = get_lzma_state(module);
        1441                 :            :     assert(state != NULL);
        1442                 :            :
        1443                 :          0 :     lzret = lzma_properties_size(&encoded_size, &filter);
        1444         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret))
        1445                 :          0 :         goto error;
        1446                 :            :
        1447                 :          0 :     result = PyBytes_FromStringAndSize(NULL, encoded_size);
        1448         [ #  # ]:          0 :     if (result == NULL)
        1449                 :          0 :         goto error;
        1450                 :            :
        1451                 :          0 :     lzret = lzma_properties_encode(
        1452                 :          0 :             &filter, (uint8_t *)PyBytes_AS_STRING(result));
        1453         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret)) {
        1454                 :          0 :         goto error;
        1455                 :            :     }
        1456                 :            :
        1457                 :          0 :     return result;
        1458                 :            :
        1459                 :          0 : error:
        1460                 :          0 :     Py_XDECREF(result);
        1461                 :          0 :     return NULL;
        1462                 :            : }
        1463                 :            :
        1464                 :            :
        1465                 :            : /*[clinic input]
        1466                 :            : _lzma._decode_filter_properties
        1467                 :            :     filter_id: lzma_vli
        1468                 :            :     encoded_props: Py_buffer
        1469                 :            :     /
        1470                 :            :
        1471                 :            : Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).
        1472                 :            :
        1473                 :            : The result does not include the filter ID itself, only the options.
        1474                 :            : [clinic start generated code]*/
        1475                 :            :
        1476                 :            : static PyObject *
        1477                 :          0 : _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id,
        1478                 :            :                                      Py_buffer *encoded_props)
        1479                 :            : /*[clinic end generated code: output=714fd2ef565d5c60 input=246410800782160c]*/
        1480                 :            : {
        1481                 :            :     lzma_filter filter;
        1482                 :            :     lzma_ret lzret;
        1483                 :          0 :     PyObject *result = NULL;
        1484                 :          0 :     filter.id = filter_id;
        1485                 :          0 :     _lzma_state *state = get_lzma_state(module);
        1486                 :            :     assert(state != NULL);
        1487                 :            :
        1488                 :          0 :     lzret = lzma_properties_decode(
        1489                 :          0 :             &filter, NULL, encoded_props->buf, encoded_props->len);
        1490         [ #  # ]:          0 :     if (catch_lzma_error(state, lzret)) {
        1491                 :          0 :         return NULL;
        1492                 :            :     }
        1493                 :            :
        1494                 :          0 :     result = build_filter_spec(&filter);
        1495                 :            :
        1496                 :            :     /* We use vanilla free() here instead of PyMem_Free() - filter.options was
        1497                 :            :        allocated by lzma_properties_decode() using the default allocator. */
        1498                 :          0 :     free(filter.options);
        1499                 :          0 :     return result;
        1500                 :            : }
        1501                 :            :
        1502                 :            : /* Some of our constants are more than 32 bits wide, so PyModule_AddIntConstant
        1503                 :            :    would not work correctly on platforms with 32-bit longs. */
        1504                 :            : static int
        1505                 :         72 : module_add_int_constant(PyObject *m, const char *name, long long value)
        1506                 :            : {
        1507                 :         72 :     PyObject *o = PyLong_FromLongLong(value);
        1508         [ -  + ]:         72 :     if (o == NULL) {
        1509                 :          0 :         return -1;
        1510                 :            :     }
        1511         [ +  - ]:         72 :     if (PyModule_AddObject(m, name, o) == 0) {
        1512                 :         72 :         return 0;
        1513                 :            :     }
        1514                 :          0 :     Py_DECREF(o);
        1515                 :          0 :     return -1;
        1516                 :            : }
        1517                 :            :
        1518                 :            : static int
        1519                 :          3 : lzma_exec(PyObject *module)
        1520                 :            : {
        1521                 :            : #define ADD_INT_PREFIX_MACRO(module, macro)                                 \
        1522                 :            :     do {                                                                    \
        1523                 :            :         if (module_add_int_constant(module, #macro, LZMA_ ## macro) < 0) {  \
        1524                 :            :             return -1;                                                      \
        1525                 :            :         }                                                                   \
        1526                 :            :     } while(0)
        1527                 :            :
        1528                 :            : #define ADD_INT_MACRO(module, macro)                                        \
        1529                 :            :     do {                                                                    \
        1530                 :            :         if (PyModule_AddIntMacro(module, macro) < 0) {                      \
        1531                 :            :             return -1;                                                      \
        1532                 :            :         }                                                                   \
        1533                 :            :     } while (0)
        1534                 :            :
        1535                 :            :
        1536                 :          3 :     _lzma_state *state = get_lzma_state(module);
        1537                 :            :
        1538                 :          3 :     state->empty_tuple = PyTuple_New(0);
        1539         [ -  + ]:          3 :     if (state->empty_tuple == NULL) {
        1540                 :          0 :         return -1;
        1541                 :            :     }
        1542                 :            :
        1543         [ -  + ]:          3 :     ADD_INT_MACRO(module, FORMAT_AUTO);
        1544         [ -  + ]:          3 :     ADD_INT_MACRO(module, FORMAT_XZ);
        1545         [ -  + ]:          3 :     ADD_INT_MACRO(module, FORMAT_ALONE);
        1546         [ -  + ]:          3 :     ADD_INT_MACRO(module, FORMAT_RAW);
        1547         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_NONE);
        1548         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_CRC32);
        1549         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_CRC64);
        1550         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_SHA256);
        1551         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_ID_MAX);
        1552         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, CHECK_UNKNOWN);
        1553         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_LZMA1);
        1554         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_LZMA2);
        1555         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_DELTA);
        1556         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_X86);
        1557         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_IA64);
        1558         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_ARM);
        1559         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_ARMTHUMB);
        1560         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_SPARC);
        1561         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, FILTER_POWERPC);
        1562         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MF_HC3);
        1563         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MF_HC4);
        1564         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MF_BT2);
        1565         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MF_BT3);
        1566         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MF_BT4);
        1567         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MODE_FAST);
        1568         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, MODE_NORMAL);
        1569         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, PRESET_DEFAULT);
        1570         [ -  + ]:          3 :     ADD_INT_PREFIX_MACRO(module, PRESET_EXTREME);
        1571                 :            :
        1572                 :          3 :     state->error = PyErr_NewExceptionWithDoc("_lzma.LZMAError", "Call to liblzma failed.", NULL, NULL);
        1573         [ -  + ]:          3 :     if (state->error == NULL) {
        1574                 :          0 :         return -1;
        1575                 :            :     }
        1576                 :            :
        1577         [ -  + ]:          3 :     if (PyModule_AddType(module, (PyTypeObject *)state->error) < 0) {
        1578                 :          0 :         return -1;
        1579                 :            :     }
        1580                 :            :
        1581                 :            :
        1582                 :          3 :     state->lzma_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
        1583                 :            :                                                             &lzma_compressor_type_spec, NULL);
        1584         [ -  + ]:          3 :     if (state->lzma_compressor_type == NULL) {
        1585                 :          0 :         return -1;
        1586                 :            :     }
        1587                 :            :
        1588         [ -  + ]:          3 :     if (PyModule_AddType(module, state->lzma_compressor_type) < 0) {
        1589                 :          0 :         return -1;
        1590                 :            :     }
        1591                 :            :
        1592                 :          3 :     state->lzma_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
        1593                 :            :                                                          &lzma_decompressor_type_spec, NULL);
        1594         [ -  + ]:          3 :     if (state->lzma_decompressor_type == NULL) {
        1595                 :          0 :         return -1;
        1596                 :            :     }
        1597                 :            :
        1598         [ -  + ]:          3 :     if (PyModule_AddType(module, state->lzma_decompressor_type) < 0) {
        1599                 :          0 :         return -1;
        1600                 :            :     }
        1601                 :            :
        1602                 :          3 :     return 0;
        1603                 :            : }
        1604                 :            :
        1605                 :            : static PyMethodDef lzma_methods[] = {
        1606                 :            :     _LZMA_IS_CHECK_SUPPORTED_METHODDEF
        1607                 :            :     _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF
        1608                 :            :     _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF
        1609                 :            :     {NULL}
        1610                 :            : };
        1611                 :            :
        1612                 :            : static PyModuleDef_Slot lzma_slots[] = {
        1613                 :            :     {Py_mod_exec, lzma_exec},
        1614                 :            :     {0, NULL}
        1615                 :            : };
        1616                 :            :
        1617                 :            : static int
        1618                 :         46 : lzma_traverse(PyObject *module, visitproc visit, void *arg)
        1619                 :            : {
        1620                 :         46 :     _lzma_state *state = get_lzma_state(module);
        1621   [ +  -  -  + ]:         46 :     Py_VISIT(state->lzma_compressor_type);
        1622   [ +  -  -  + ]:         46 :     Py_VISIT(state->lzma_decompressor_type);
        1623   [ +  -  -  + ]:         46 :     Py_VISIT(state->error);
        1624   [ +  -  -  + ]:         46 :     Py_VISIT(state->empty_tuple);
        1625                 :         46 :     return 0;
        1626                 :            : }
        1627                 :            :
        1628                 :            : static int
        1629                 :          6 : lzma_clear(PyObject *module)
        1630                 :            : {
        1631                 :          6 :     _lzma_state *state = get_lzma_state(module);
        1632         [ +  + ]:          6 :     Py_CLEAR(state->lzma_compressor_type);
        1633         [ +  + ]:          6 :     Py_CLEAR(state->lzma_decompressor_type);
        1634         [ +  + ]:          6 :     Py_CLEAR(state->error);
        1635         [ +  + ]:          6 :     Py_CLEAR(state->empty_tuple);
        1636                 :          6 :     return 0;
        1637                 :            : }
        1638                 :            :
        1639                 :            : static void
        1640                 :          3 : lzma_free(void *module)
        1641                 :            : {
        1642                 :          3 :     lzma_clear((PyObject *)module);
        1643                 :          3 : }
        1644                 :            :
        1645                 :            : static PyModuleDef _lzmamodule = {
        1646                 :            :     PyModuleDef_HEAD_INIT,
        1647                 :            :     .m_name = "_lzma",
        1648                 :            :     .m_size = sizeof(_lzma_state),
        1649                 :            :     .m_methods = lzma_methods,
        1650                 :            :     .m_slots = lzma_slots,
        1651                 :            :     .m_traverse = lzma_traverse,
        1652                 :            :     .m_clear = lzma_clear,
        1653                 :            :     .m_free = lzma_free,
        1654                 :            : };
        1655                 :            :
        1656                 :            : PyMODINIT_FUNC
        1657                 :          3 : PyInit__lzma(void)
        1658                 :            : {
        1659                 :          3 :     return PyModuleDef_Init(&_lzmamodule);
        1660                 :            : }

Generated by: LCOV version 1.14