FTEQW
Documentation of the FTE engine source tree.
fs_xz.c File Reference

Typedefs

typedef unsigned char bool
 
typedef uint64_t vli_type
 

Enumerations

enum  xz_mode { XZ_SINGLE , XZ_PREALLOC , XZ_DYNALLOC }
 enum xz_mode - Operation mode More...
 
enum  xz_ret {
  XZ_OK , XZ_STREAM_END , XZ_UNSUPPORTED_CHECK , XZ_MEM_ERROR ,
  XZ_MEMLIMIT_ERROR , XZ_FORMAT_ERROR , XZ_OPTIONS_ERROR , XZ_DATA_ERROR ,
  XZ_BUF_ERROR
}
 enum xz_ret - Return codes @XZ_OK: Everything is OK so far. More...
 
enum  xz_check { XZ_CHECK_NONE = 0 , XZ_CHECK_CRC32 = 1 , XZ_CHECK_CRC64 = 4 , XZ_CHECK_SHA256 = 10 }
 
enum  lzma_state {
  STATE_LIT_LIT , STATE_MATCH_LIT_LIT , STATE_REP_LIT_LIT , STATE_SHORTREP_LIT_LIT ,
  STATE_MATCH_LIT , STATE_REP_LIT , STATE_SHORTREP_LIT , STATE_LIT_MATCH ,
  STATE_LIT_LONGREP , STATE_LIT_SHORTREP , STATE_NONLIT_MATCH , STATE_NONLIT_REP
}
 

Functions

XZ_EXTERN struct xz_dec * xz_dec_init (enum xz_mode mode, uint32_t dict_max)
 xz_dec_init() - Allocate and initialize a XZ decoder state @mode: Operation mode @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for multi-call decoding. More...
 
XZ_EXTERN enum xz_ret xz_dec_run (struct xz_dec *s, struct xz_buf *b)
 xz_dec_run() - Run the XZ decoder @s: Decoder state allocated using xz_dec_init() : Input and output buffers More...
 
XZ_EXTERN void xz_dec_reset (struct xz_dec *s)
 xz_dec_reset() - Reset an already allocated decoder state @s: Decoder state allocated using xz_dec_init() More...
 
XZ_EXTERN void xz_dec_end (struct xz_dec *s)
 xz_dec_end() - Free the memory allocated for the decoder state @s: Decoder state allocated using xz_dec_init(). More...
 
XZ_EXTERN void xz_crc32_init (void)
 
XZ_EXTERN uint32_t xz_crc32 (const uint8_t *buf, size_t size, uint32_t crc)
 
XZ_EXTERN void xz_crc64_init (void)
 
XZ_EXTERN uint64_t xz_crc64 (const uint8_t *buf, size_t size, uint64_t crc)
 
XZ_EXTERN struct xz_dec_lzma2 * xz_dec_lzma2_create (enum xz_mode mode, uint32_t dict_max)
 
XZ_EXTERN enum xz_ret xz_dec_lzma2_reset (struct xz_dec_lzma2 *s, uint8_t props)
 
XZ_EXTERN enum xz_ret xz_dec_lzma2_run (struct xz_dec_lzma2 *s, struct xz_buf *b)
 
XZ_EXTERN void xz_dec_lzma2_end (struct xz_dec_lzma2 *s)
 
XZ_EXTERN struct xz_dec_bcj * xz_dec_bcj_create (bool single_call)
 
XZ_EXTERN enum xz_ret xz_dec_bcj_reset (struct xz_dec_bcj *s, uint8_t id)
 
XZ_EXTERN enum xz_ret xz_dec_bcj_run (struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2, struct xz_buf *b)
 
vfsfile_tFS_XZ_DecompressWriteFilter (vfsfile_t *outfile)
 
vfsfile_tFS_XZ_DecompressReadFilter (vfsfile_t *srcfile)
 

Variables

STATIC_RW_DATA uint32_t xz_crc32_table [256]
 

Typedef Documentation

◆ bool

typedef unsigned char bool

◆ vli_type

typedef uint64_t vli_type

Enumeration Type Documentation

◆ lzma_state

enum lzma_state
Enumerator
STATE_LIT_LIT 
STATE_MATCH_LIT_LIT 
STATE_REP_LIT_LIT 
STATE_SHORTREP_LIT_LIT 
STATE_MATCH_LIT 
STATE_REP_LIT 
STATE_SHORTREP_LIT 
STATE_LIT_MATCH 
STATE_LIT_LONGREP 
STATE_LIT_SHORTREP 
STATE_NONLIT_MATCH 
STATE_NONLIT_REP 

◆ xz_check

enum xz_check
Enumerator
XZ_CHECK_NONE 
XZ_CHECK_CRC32 
XZ_CHECK_CRC64 
XZ_CHECK_SHA256 

◆ xz_mode

enum xz_mode

enum xz_mode - Operation mode

@XZ_SINGLE: Single-call mode. This uses less RAM than than multi-call modes, because the LZMA2 dictionary doesn't need to be allocated as part of the decoder state. All required data structures are allocated at initialization, so xz_dec_run() cannot return XZ_MEM_ERROR. @XZ_PREALLOC: Multi-call mode with preallocated LZMA2 dictionary buffer. All data structures are allocated at initialization, so xz_dec_run() cannot return XZ_MEM_ERROR. @XZ_DYNALLOC: Multi-call mode. The LZMA2 dictionary is allocated once the required size has been parsed from the stream headers. If the allocation fails, xz_dec_run() will return XZ_MEM_ERROR.

It is possible to enable support only for a subset of the above modes at compile time by defining XZ_DEC_SINGLE, XZ_DEC_PREALLOC, or XZ_DEC_DYNALLOC. The xz_dec kernel module is always compiled with support for all operation modes, but the preboot code may be built with fewer features to minimize code size.

Enumerator
XZ_SINGLE 
XZ_PREALLOC 
XZ_DYNALLOC 

◆ xz_ret

enum xz_ret

enum xz_ret - Return codes @XZ_OK: Everything is OK so far.

More input or more output space is required to continue. This return code is possible only in multi-call mode (XZ_PREALLOC or XZ_DYNALLOC). @XZ_STREAM_END: Operation finished successfully. @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding is still possible in multi-call mode by simply calling xz_dec_run() again. Note that this return value is used only if XZ_DEC_ANY_CHECK was defined at build time, which is not used in the kernel. Unsupported check types return XZ_OPTIONS_ERROR if XZ_DEC_ANY_CHECK was not defined at build time. @XZ_MEM_ERROR: Allocating memory failed. This return code is possible only if the decoder was initialized with XZ_DYNALLOC. The amount of memory that was tried to be allocated was no more than the dict_max argument given to xz_dec_init(). @XZ_MEMLIMIT_ERROR: A bigger LZMA2 dictionary would be needed than allowed by the dict_max argument given to xz_dec_init(). This return value is possible only in multi-call mode (XZ_PREALLOC or XZ_DYNALLOC); the single-call mode (XZ_SINGLE) ignores the dict_max argument. @XZ_FORMAT_ERROR: File format was not recognized (wrong magic bytes). @XZ_OPTIONS_ERROR: This implementation doesn't support the requested compression options. In the decoder this means that the header CRC32 matches, but the header itself specifies something that we don't support. @XZ_DATA_ERROR: Compressed data is corrupt. @XZ_BUF_ERROR: Cannot make any progress. Details are slightly different between multi-call and single-call mode; more information below.

In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls to XZ code cannot consume any input and cannot produce any new output. This happens when there is no new input available, or the output buffer is full while at least one output byte is still pending. Assuming your code is not buggy, you can get this error only when decoding a compressed stream that is truncated or otherwise corrupt.

In single-call mode, XZ_BUF_ERROR is returned only when the output buffer is too small or the compressed input is corrupt in a way that makes the decoder produce more output than the caller expected. When it is (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR is used instead of XZ_BUF_ERROR.

Enumerator
XZ_OK 
XZ_STREAM_END 
XZ_UNSUPPORTED_CHECK 
XZ_MEM_ERROR 
XZ_MEMLIMIT_ERROR 
XZ_FORMAT_ERROR 
XZ_OPTIONS_ERROR 
XZ_DATA_ERROR 
XZ_BUF_ERROR 

Function Documentation

◆ FS_XZ_DecompressReadFilter()

vfsfile_t * FS_XZ_DecompressReadFilter ( vfsfile_t srcfile)

◆ FS_XZ_DecompressWriteFilter()

vfsfile_t * FS_XZ_DecompressWriteFilter ( vfsfile_t outfile)

◆ xz_crc32()

XZ_EXTERN uint32_t xz_crc32 ( const uint8_t buf,
size_t  size,
uint32_t  crc 
)

◆ xz_crc32_init()

XZ_EXTERN void xz_crc32_init ( void  )

◆ xz_crc64()

XZ_EXTERN uint64_t xz_crc64 ( const uint8_t buf,
size_t  size,
uint64_t  crc 
)

◆ xz_crc64_init()

XZ_EXTERN void xz_crc64_init ( void  )

◆ xz_dec_bcj_create()

XZ_EXTERN struct xz_dec_bcj * xz_dec_bcj_create ( bool  single_call)

◆ xz_dec_bcj_reset()

XZ_EXTERN enum xz_ret xz_dec_bcj_reset ( struct xz_dec_bcj *  s,
uint8_t  id 
)

◆ xz_dec_bcj_run()

XZ_EXTERN enum xz_ret xz_dec_bcj_run ( struct xz_dec_bcj *  s,
struct xz_dec_lzma2 *  lzma2,
struct xz_buf *  b 
)

◆ xz_dec_end()

XZ_EXTERN void xz_dec_end ( struct xz_dec *  s)

xz_dec_end() - Free the memory allocated for the decoder state @s: Decoder state allocated using xz_dec_init().

If s is NULL, this function does nothing.

◆ xz_dec_init()

XZ_EXTERN struct xz_dec * xz_dec_init ( enum xz_mode  mode,
uint32_t  dict_max 
)

xz_dec_init() - Allocate and initialize a XZ decoder state @mode: Operation mode @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for multi-call decoding.

This is ignored in single-call mode (mode == XZ_SINGLE). LZMA2 dictionary is always 2^n bytes or 2^n + 2^(n-1) bytes (the latter sizes are less common in practice), so other values for dict_max don't make sense. In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB, 512 KiB, and 1 MiB are probably the only reasonable values, except for kernel and initramfs images where a bigger dictionary can be fine and useful.

Single-call mode (XZ_SINGLE): xz_dec_run() decodes the whole stream at once. The caller must provide enough output space or the decoding will fail. The output space is used as the dictionary buffer, which is why there is no need to allocate the dictionary as part of the decoder's internal state.

Because the output buffer is used as the workspace, streams encoded using a big dictionary are not a problem in single-call mode. It is enough that the output buffer is big enough to hold the actual uncompressed data; it can be smaller than the dictionary size stored in the stream headers.

Multi-call mode with preallocated dictionary (XZ_PREALLOC): dict_max bytes of memory is preallocated for the LZMA2 dictionary. This way there is no risk that xz_dec_run() could run out of memory, since xz_dec_run() will never allocate any memory. Instead, if the preallocated dictionary is too small for decoding the given input stream, xz_dec_run() will return XZ_MEMLIMIT_ERROR. Thus, it is important to know what kind of data will be decoded to avoid allocating excessive amount of memory for the dictionary.

Multi-call mode with dynamically allocated dictionary (XZ_DYNALLOC): dict_max specifies the maximum allowed dictionary size that xz_dec_run() may allocate once it has parsed the dictionary size from the stream headers. This way excessive allocations can be avoided while still limiting the maximum memory usage to a sane value to prevent running the system out of memory when decompressing streams from untrusted sources.

On success, xz_dec_init() returns a pointer to struct xz_dec, which is ready to be used with xz_dec_run(). If memory allocation fails, xz_dec_init() returns NULL.

◆ xz_dec_lzma2_create()

XZ_EXTERN struct xz_dec_lzma2 * xz_dec_lzma2_create ( enum xz_mode  mode,
uint32_t  dict_max 
)

◆ xz_dec_lzma2_end()

XZ_EXTERN void xz_dec_lzma2_end ( struct xz_dec_lzma2 *  s)

◆ xz_dec_lzma2_reset()

XZ_EXTERN enum xz_ret xz_dec_lzma2_reset ( struct xz_dec_lzma2 *  s,
uint8_t  props 
)

◆ xz_dec_lzma2_run()

XZ_EXTERN enum xz_ret xz_dec_lzma2_run ( struct xz_dec_lzma2 *  s,
struct xz_buf *  b 
)

◆ xz_dec_reset()

XZ_EXTERN void xz_dec_reset ( struct xz_dec *  s)

xz_dec_reset() - Reset an already allocated decoder state @s: Decoder state allocated using xz_dec_init()

This function can be used to reset the multi-call decoder state without freeing and reallocating memory with xz_dec_end() and xz_dec_init().

In single-call mode, xz_dec_reset() is always called in the beginning of xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in multi-call mode.

◆ xz_dec_run()

XZ_EXTERN enum xz_ret xz_dec_run ( struct xz_dec *  s,
struct xz_buf *  b 
)

xz_dec_run() - Run the XZ decoder @s: Decoder state allocated using xz_dec_init() : Input and output buffers

The possible return values depend on build options and operation mode. See enum xz_ret for details.

Note that if an error occurs in single-call mode (return value is not XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the contents of the output buffer from b->out[b->out_pos] onward are undefined. This is true even after XZ_BUF_ERROR, because with some filter chains, there may be a second pass over the output buffer, and this pass cannot be properly done if the output buffer is truncated. Thus, you cannot give the single-call decoder a too small buffer and then expect to get that amount valid data from the beginning of the stream. You must use the multi-call decoder if you don't want to uncompress the whole stream.

Variable Documentation

◆ xz_crc32_table

STATIC_RW_DATA uint32_t xz_crc32_table[256]