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

Reply via email to