aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/liblzma/api/lzma/block.h50
-rw-r--r--src/liblzma/common/block_buffer_encoder.c2
-rw-r--r--src/liblzma/common/block_decoder.c18
-rw-r--r--src/liblzma/common/block_encoder.c2
-rw-r--r--src/liblzma/common/block_header_decoder.c12
-rw-r--r--src/liblzma/common/block_header_encoder.c2
-rw-r--r--src/liblzma/common/block_util.c2
7 files changed, 68 insertions, 20 deletions
diff --git a/src/liblzma/api/lzma/block.h b/src/liblzma/api/lzma/block.h
index 2e982e1c..7bdcfd7c 100644
--- a/src/liblzma/api/lzma/block.h
+++ b/src/liblzma/api/lzma/block.h
@@ -31,11 +31,16 @@ typedef struct {
/**
* \brief Block format version
*
- * To prevent API and ABI breakages if new features are needed in
- * the Block field, a version number is used to indicate which
- * fields in this structure are in use. For now, version must always
- * be zero. With non-zero version, most Block related functions will
- * return LZMA_OPTIONS_ERROR.
+ * To prevent API and ABI breakages when new features are needed,
+ * a version number is used to indicate which fields in this
+ * structure are in use:
+ * - liblzma >= 5.0.0: version = 0 is supported.
+ * - liblzma >= 5.1.4beta: Support for version = 1 was added,
+ * which adds the ignore_check field.
+ *
+ * If version is greater than one, most Block related functions
+ * will return LZMA_OPTIONS_ERROR (lzma_block_header_decode() works
+ * with any version value).
*
* Read by:
* - All functions that take pointer to lzma_block as argument,
@@ -233,7 +238,28 @@ typedef struct {
lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
- lzma_bool reserved_bool1;
+
+ /**
+ * \brief A flag to Block decoder to not verify the Check field
+ *
+ * This field is supported by liblzma >= 5.1.4beta if .version >= 1.
+ *
+ * If this is set to true, the integrity check won't be calculated
+ * and verified. Unless you know what you are doing, you should
+ * leave this to false. (A reason to set this to true is when the
+ * file integrity is verified externally anyway and you want to
+ * speed up the decompression, which matters mostly when using
+ * SHA-256 as the integrity check.)
+ *
+ * If .version >= 1, read by:
+ * - lzma_block_decoder()
+ * - lzma_block_buffer_decode()
+ *
+ * Written by (.version is ignored):
+ * - lzma_block_header_decode() always sets this to false
+ */
+ lzma_bool ignore_check;
+
lzma_bool reserved_bool2;
lzma_bool reserved_bool3;
lzma_bool reserved_bool4;
@@ -310,10 +336,14 @@ extern LZMA_API(lzma_ret) lzma_block_header_encode(
/**
* \brief Decode Block Header
*
- * block->version should be set to the highest value supported by the
- * application; currently the only possible version is zero. This function
- * will set version to the lowest value that still supports all the features
- * required by the Block Header.
+ * block->version should (usually) be set to the highest value supported
+ * by the application. If the application sets block->version to a value
+ * higher than supported by the current liblzma version, this function will
+ * downgrade block->version to the highest value supported by it. Thus one
+ * should check the value of block->version after calling this function if
+ * block->version was set to a non-zero value and the application doesn't
+ * otherwise know that the liblzma version being used is new enough to
+ * support the specified block->version.
*
* The size of the Block Header must have already been decoded with
* lzma_block_header_size_decode() macro and stored to block->header_size.
diff --git a/src/liblzma/common/block_buffer_encoder.c b/src/liblzma/common/block_buffer_encoder.c
index dcd574e9..39e263aa 100644
--- a/src/liblzma/common/block_buffer_encoder.c
+++ b/src/liblzma/common/block_buffer_encoder.c
@@ -233,7 +233,7 @@ block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
// The contents of the structure may depend on the version so
// check the version before validating the contents of *block.
- if (block->version != 0)
+ if (block->version > 1)
return LZMA_OPTIONS_ERROR;
if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
diff --git a/src/liblzma/common/block_decoder.c b/src/liblzma/common/block_decoder.c
index cee6c782..685c3b03 100644
--- a/src/liblzma/common/block_decoder.c
+++ b/src/liblzma/common/block_decoder.c
@@ -45,6 +45,9 @@ struct lzma_coder_s {
/// Check of the uncompressed data
lzma_check_state check;
+
+ /// True if the integrity check won't be calculated and verified.
+ bool ignore_check;
};
@@ -97,8 +100,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
coder->block->uncompressed_size))
return LZMA_DATA_ERROR;
- lzma_check_update(&coder->check, coder->block->check,
- out + out_start, out_used);
+ if (!coder->ignore_check)
+ lzma_check_update(&coder->check, coder->block->check,
+ out + out_start, out_used);
if (ret != LZMA_STREAM_END)
return ret;
@@ -140,7 +144,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
if (coder->block->check == LZMA_CHECK_NONE)
return LZMA_STREAM_END;
- lzma_check_finish(&coder->check, coder->block->check);
+ if (!coder->ignore_check)
+ lzma_check_finish(&coder->check, coder->block->check);
+
coder->sequence = SEQ_CHECK;
// Fall through
@@ -155,7 +161,8 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
// Validate the Check only if we support it.
// coder->check.buffer may be uninitialized
// when the Check ID is not supported.
- if (lzma_check_is_supported(coder->block->check)
+ if (!coder->ignore_check
+ && lzma_check_is_supported(coder->block->check)
&& memcmp(coder->block->raw_check,
coder->check.buffer.u8,
check_size) != 0)
@@ -224,6 +231,9 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
next->coder->check_pos = 0;
lzma_check_init(&next->coder->check, block->check);
+ next->coder->ignore_check = block->version >= 1
+ ? block->ignore_check : false;
+
// Initialize the filter chain.
return lzma_raw_decoder_init(&next->coder->next, allocator,
block->filters);
diff --git a/src/liblzma/common/block_encoder.c b/src/liblzma/common/block_encoder.c
index 15f55f7a..def58641 100644
--- a/src/liblzma/common/block_encoder.c
+++ b/src/liblzma/common/block_encoder.c
@@ -166,7 +166,7 @@ lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
// The contents of the structure may depend on the version so
// check the version first.
- if (block->version != 0)
+ if (block->version > 1)
return LZMA_OPTIONS_ERROR;
// If the Check ID is not supported, we cannot calculate the check and
diff --git a/src/liblzma/common/block_header_decoder.c b/src/liblzma/common/block_header_decoder.c
index 416642cd..1dd982f6 100644
--- a/src/liblzma/common/block_header_decoder.c
+++ b/src/liblzma/common/block_header_decoder.c
@@ -46,8 +46,16 @@ lzma_block_header_decode(lzma_block *block,
block->filters[i].options = NULL;
}
- // Always zero for now.
- block->version = 0;
+ // Versions 0 and 1 are supported. If a newer version was specified,
+ // we need to downgrade it.
+ if (block->version > 1)
+ block->version = 1;
+
+ // This isn't a Block Header option, but since the decompressor will
+ // read it if version >= 1, it's better to initialize it here than
+ // to expect the caller to do it since in almost all cases this
+ // should be false.
+ block->ignore_check = false;
// Validate Block Header Size and Check type. The caller must have
// already set these, so it is a programming error if this test fails.
diff --git a/src/liblzma/common/block_header_encoder.c b/src/liblzma/common/block_header_encoder.c
index 707dd0cb..5c5f5424 100644
--- a/src/liblzma/common/block_header_encoder.c
+++ b/src/liblzma/common/block_header_encoder.c
@@ -17,7 +17,7 @@
extern LZMA_API(lzma_ret)
lzma_block_header_size(lzma_block *block)
{
- if (block->version != 0)
+ if (block->version > 1)
return LZMA_OPTIONS_ERROR;
// Block Header Size + Block Flags + CRC32.
diff --git a/src/liblzma/common/block_util.c b/src/liblzma/common/block_util.c
index 62c93454..00c7fe8d 100644
--- a/src/liblzma/common/block_util.c
+++ b/src/liblzma/common/block_util.c
@@ -51,7 +51,7 @@ lzma_block_unpadded_size(const lzma_block *block)
// NOTE: This function is used for validation too, so it is
// essential that these checks are always done even if
// Compressed Size is unknown.
- if (block == NULL || block->version != 0
+ if (block == NULL || block->version > 1
|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
|| (block->header_size & 3)