summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-11-14 09:51:07 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-11-14 09:51:07 +0100
commit787b4fe586456565c2dda457ad81f1dd420e9249 (patch)
treecb18bda30d8917c2a1ea360d29301a355d4c3006
parent9768733eb7d34fff6f7cdf2e6a8049d4ffb954bb (diff)
downloadUXP-787b4fe586456565c2dda457ad81f1dd420e9249.tar
UXP-787b4fe586456565c2dda457ad81f1dd420e9249.tar.gz
UXP-787b4fe586456565c2dda457ad81f1dd420e9249.tar.lz
UXP-787b4fe586456565c2dda457ad81f1dd420e9249.tar.xz
UXP-787b4fe586456565c2dda457ad81f1dd420e9249.zip
Issue #1288 - Part 2: Add a partial LZ4 decompression routine.
This function never writes beyond `aDest` + `aMaxOutputSize`, and is therefore protexted against malicious datapackets. It also ignores unconsumed input upon reaching `aMaxOutputSize` and can therefore be used for parial decompression of LZ4 input up to a desired resulting size of decompressed data.
-rw-r--r--mfbt/Compression.cpp21
-rw-r--r--mfbt/Compression.h23
2 files changed, 44 insertions, 0 deletions
diff --git a/mfbt/Compression.cpp b/mfbt/Compression.cpp
index 6be8020a9..5646b56b2 100644
--- a/mfbt/Compression.cpp
+++ b/mfbt/Compression.cpp
@@ -76,3 +76,24 @@ LZ4::decompress(const char* aSource, size_t aInputSize, char* aDest,
return false;
}
+bool
+LZ4::decompressPartial(const char* aSource, size_t aInputSize, char* aDest,
+ size_t aMaxOutputSize, size_t* aOutputSize)
+{
+ CheckedInt<int> maxOutputSizeChecked = aMaxOutputSize;
+ MOZ_ASSERT(maxOutputSizeChecked.isValid());
+ CheckedInt<int> inputSizeChecked = aInputSize;
+ MOZ_ASSERT(inputSizeChecked.isValid());
+
+ int ret = LZ4_decompress_safe_partial(aSource, aDest,
+ inputSizeChecked.value(),
+ maxOutputSizeChecked.value(),
+ maxOutputSizeChecked.value());
+ if (ret >= 0) {
+ *aOutputSize = ret;
+ return true;
+ }
+
+ *aOutputSize = 0;
+ return false;
+}
diff --git a/mfbt/Compression.h b/mfbt/Compression.h
index aa50211b3..eeb160c51 100644
--- a/mfbt/Compression.h
+++ b/mfbt/Compression.h
@@ -96,6 +96,29 @@ public:
decompress(const char* aSource, size_t aInputSize, char* aDest,
size_t aMaxOutputSize, size_t* aOutputSize);
+ /**
+ * If the source stream is malformed, the function will stop decoding
+ * and return false.
+ *
+ * This function never writes beyond aDest + aMaxOutputSize, and is
+ * therefore protected against malicious data packets. It also ignores
+ * unconsumed input upon reaching aMaxOutputSize and can therefore be used
+ * for partial decompression.
+ *
+ * Note: Destination buffer must be already allocated. This version is
+ * slightly slower than the decompress without the aMaxOutputSize.
+ *
+ * @param aInputSize is the length of the input compressed data
+ * @param aMaxOutputSize is the size of the destination buffer (which must be
+ * already allocated)
+ * @param aOutputSize the actual number of bytes decoded in the destination
+ * buffer (necessarily <= aMaxOutputSize)
+ * @return true on success, false on failure
+ */
+ static MFBT_API MOZ_MUST_USE bool
+ decompressPartial(const char* aSource, size_t aInputSize, char* aDest,
+ size_t aMaxOutputSize, size_t* aOutputSize);
+
/*
* Provides the maximum size that LZ4 may output in a "worst case"
* scenario (input data not compressible) primarily useful for memory