         case .lzma:
             #if (!SWCOMPRESSION_POD_ZIP) || (SWCOMPRESSION_POD_ZIP && SWCOMPRESSION_POD_LZMA)
                 pointerData.index += 4 // Skipping LZMA SDK version and size of properties.
-                let lzmaDecoder = try LZMADecoder(pointerData)
-                try lzmaDecoder.decodeLZMA(uncompSize)
-                fileBytes = lzmaDecoder.out
+
+                let decoder = try LZMATempDecoder(pointerData)
+
+                try decoder.setProperties(from: pointerData.byte())
+                decoder.resetStateAndDecoders()
+                decoder.dictionarySize = pointerData.uint32().toInt()
+
+                if uncompSize == UInt64.max {
+                    decoder.uncompressedSize = -1
+                } else {
+                    decoder.uncompressedSize = Int(truncatingIfNeeded: uncompSize)
+                }
+
+                try decoder.decode()
+                fileBytes = decoder.out
             #else
                 throw ZipError.compressionNotSupported
             #endif


        // If file has data descriptor, then some values in local header are absent.
        // So we need to use values from CD entry.
        // TODO:
        var uncompSize = hasDataDescriptor ?
            Int(truncatingIfNeeded: info.cdEntry.uncompSize) :
            Int(truncatingIfNeeded: info.localHeader.uncompSize)
        var compSize = hasDataDescriptor ?
            Int(truncatingIfNeeded: info.cdEntry.compSize) :
            Int(truncatingIfNeeded: info.localHeader.compSize)

            crc32 = pointerData.uint32()
            let sizeOfSizeField: UInt64 = info.localHeader.zip64FieldsArePresent ? 8 : 4
            compSize = Int(truncatingIfNeeded: pointerData.uint64(count: sizeOfSizeField))
            uncompSize = pointerData.uint64(count: sizeOfSizeField)
        }

        guard compSize == realCompSize && uncompSize == fileBytes.count
