This patch makes the following changes: -Documentation in block.h is now more consistent and helps explain a few things that I found to be confusing at first. -Creates two macros for the compressed size and uncompressed size being present in the block header to help avoid using magic numbers. -Adds a NULL check to lzma_block_header_decoder. A comment in block.h mentions that a NULL check would be performed for the filters, but it was not being done.
I have one question about the behavior of lzma_block_header_decode(). Why does lzma_block_header_decode() require the header_size to be set before calling the function? Inside the function, lzma_block_header_decode() calls lzma_block_header_size_decode() on the buffer to check if it matches what is in the block struct and will return an error if they do not. It seems unnecessary to require that lzma_block_header_size_decode() is called before the function and then to call it inside the function anyway. Jia Tan
From 5fc4e51ccd9d4cec48fad224ea47aaf50255cbd0 Mon Sep 17 00:00:00 2001 From: jiat75 <jiat0...@gmail.com> Date: Fri, 29 Apr 2022 21:14:41 +0800 Subject: [PATCH] Defined macros for compressed and uncompressed size set masks Standardized documentation comments in block.h to all have param and return parts. Updated and clarified descriptions of functions in block.h --- src/liblzma/api/lzma/block.h | 68 ++++++++++++++++++++++- src/liblzma/common/block_header_decoder.c | 7 ++- src/liblzma/common/block_header_encoder.c | 4 +- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/liblzma/api/lzma/block.h b/src/liblzma/api/lzma/block.h index 082e5583..8f69542d 100644 --- a/src/liblzma/api/lzma/block.h +++ b/src/liblzma/api/lzma/block.h @@ -270,6 +270,23 @@ typedef struct { } lzma_block; +/** + * \brief + * + * Flag mask value for the compressed size being present in the block + * header. Written by lzma_block_header_encode() and read by + * lzma_block_header_decode(). + */ +#define LZMA_BLOCK_COMPRESS_SIZE_SET_FLAG 0x40 + +/** + * \brief + * + * Flag mask value for the uncompressed size being present in the block + * header. Written by lzma_block_header_encode() and read by + * lzma_block_header_decode(). + */ +#define LZMA_BLOCK_UNCOMPRESS_SIZE_SET_FLAG 0x80 /** * \brief Decode the Block Header Size field @@ -294,6 +311,9 @@ typedef struct { * four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size * just means that lzma_block_header_encode() will add Header Padding. * + * \param block Block options for header size calculation + * and destination of result on success + * * \return - LZMA_OK: Size calculated successfully and stored to * block->header_size. * - LZMA_OPTIONS_ERROR: Unsupported version, filters or @@ -303,7 +323,7 @@ typedef struct { * \note This doesn't check that all the options are valid i.e. this * may return LZMA_OK even if lzma_block_header_encode() or * lzma_block_encoder() would fail. If you want to validate the - * filter chain, consider using lzma_memlimit_encoder() which as + * filter chain, consider using lzma_raw_encoder() which as * a side-effect validates the filter chain. */ extern LZMA_API(lzma_ret) lzma_block_header_size(lzma_block *block) @@ -398,6 +418,9 @@ extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block, * field so that it can properly validate Compressed Size if it * was present in Block Header. * + * \param block Block options to be validated and set + * \param unpadded_size Size of the block without padding + * * \return - LZMA_OK: block->compressed_size was set successfully. * - LZMA_DATA_ERROR: unpadded_size is too small compared to * block->header_size and lzma_check_size(block->check). @@ -419,6 +442,8 @@ extern LZMA_API(lzma_ret) lzma_block_compressed_size( * Compressed Size, and size of the Check field. This is where this function * is needed. * + * \param block Block options to be validated + * * \return Unpadded Size on success, or zero on error. */ extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block) @@ -431,6 +456,8 @@ extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block) * This is equivalent to lzma_block_unpadded_size() except that the returned * value includes the size of the Block Padding field. * + * \param block Block options to be validated + * * \return On success, total encoded size of the Block. On error, * zero is returned. */ @@ -441,9 +468,17 @@ extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block) /** * \brief Initialize .xz Block encoder * + * This encoder does not encode the block header, so the block header must + * be either encoded or have space allocated and have been skipped before + * invoking this function. * Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the * filter chain supports it), and LZMA_FINISH. * + * \param strm Pointer to lzma_stream that is at least + * initialized with LZMA_STREAM_INIT. + * \param block Block options: block->version, block->check, + * and block->filters must have been initialized. + * * \return - LZMA_OK: All good, continue with lzma_code(). * - LZMA_MEM_ERROR * - LZMA_OPTIONS_ERROR @@ -460,9 +495,16 @@ extern LZMA_API(lzma_ret) lzma_block_encoder( /** * \brief Initialize .xz Block decoder * + * This decoder does not decode the block header, so the block + * header must have already been decoded before invoking this function. * Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using * LZMA_FINISH is not required. It is supported only for convenience. * + * \param strm Pointer to lzma_stream that is at least + * initialized with LZMA_STREAM_INIT. + * \param block Block options already used when decoding + * the block header. + * * \return - LZMA_OK: All good, continue with lzma_code(). * - LZMA_PROG_ERROR * - LZMA_MEM_ERROR @@ -477,6 +519,12 @@ extern LZMA_API(lzma_ret) lzma_block_decoder( * * This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks. * See the documentation of lzma_stream_buffer_bound(). + * + * \param uncompressed_size Number of bytes of the uncompressed + * size of what needs to be encoded + * + * \return Maximum number of bytes needed to encode the input + * */ extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size) lzma_nothrow; @@ -537,6 +585,24 @@ extern LZMA_API(lzma_ret) lzma_block_buffer_encode( * Since the data won't be compressed, this function ignores block->filters. * This function doesn't take lzma_allocator because this function doesn't * allocate any memory from the heap. + * + * \param block Block options: block->version, block->check, + * and block->filters must have been initialized. + * \param in Beginning of the input buffer + * \param in_size Size of the input buffer + * \param out Beginning of the output buffer + * \param out_pos The next byte will be written to out[*out_pos]. + * *out_pos is updated only if encoding succeeds. + * \param out_size Size of the out buffer; the first byte into + * which no data is written to is out[out_size]. + * + * \return - LZMA_OK: Encoding was successful. + * - LZMA_BUF_ERROR: Not enough output buffer space. + * - LZMA_UNSUPPORTED_CHECK + * - LZMA_OPTIONS_ERROR + * - LZMA_MEM_ERROR + * - LZMA_DATA_ERROR + * - LZMA_PROG_ERROR */ extern LZMA_API(lzma_ret) lzma_block_uncomp_encode(lzma_block *block, const uint8_t *in, size_t in_size, diff --git a/src/liblzma/common/block_header_decoder.c b/src/liblzma/common/block_header_decoder.c index 24588c56..d4c3ef88 100644 --- a/src/liblzma/common/block_header_decoder.c +++ b/src/liblzma/common/block_header_decoder.c @@ -39,6 +39,9 @@ lzma_block_header_decode(lzma_block *block, // are invalid or over 63 bits, or if the header is too small // to contain the claimed information. + if(block->filters == NULL) + return LZMA_PROG_ERROR; + // Initialize the filter options array. This way the caller can // safely free() the options even if an error occurs in this function. for (size_t i = 0; i <= LZMA_FILTERS_MAX; ++i) { @@ -81,7 +84,7 @@ lzma_block_header_decode(lzma_block *block, size_t in_pos = 2; // Compressed Size - if (in[1] & 0x40) { + if (in[1] & LZMA_BLOCK_COMPRESS_SIZE_SET_FLAG) { return_if_error(lzma_vli_decode(&block->compressed_size, NULL, in, &in_pos, in_size)); @@ -94,7 +97,7 @@ lzma_block_header_decode(lzma_block *block, } // Uncompressed Size - if (in[1] & 0x80) + if (in[1] & LZMA_BLOCK_UNCOMPRESS_SIZE_SET_FLAG) return_if_error(lzma_vli_decode(&block->uncompressed_size, NULL, in, &in_pos, in_size)); else diff --git a/src/liblzma/common/block_header_encoder.c b/src/liblzma/common/block_header_encoder.c index 160425d2..6a202192 100644 --- a/src/liblzma/common/block_header_encoder.c +++ b/src/liblzma/common/block_header_encoder.c @@ -93,7 +93,7 @@ lzma_block_header_encode(const lzma_block *block, uint8_t *out) return_if_error(lzma_vli_encode(block->compressed_size, NULL, out, &out_pos, out_size)); - out[1] |= 0x40; + out[1] |= LZMA_BLOCK_COMPRESS_SIZE_SET_FLAG; } // Uncompressed Size @@ -101,7 +101,7 @@ lzma_block_header_encode(const lzma_block *block, uint8_t *out) return_if_error(lzma_vli_encode(block->uncompressed_size, NULL, out, &out_pos, out_size)); - out[1] |= 0x80; + out[1] |= LZMA_BLOCK_UNCOMPRESS_SIZE_SET_FLAG; } // Filter Flags -- 2.25.1