|
64 | 64 | #define FSE_STATIC_LINKING_ONLY
|
65 | 65 | #include "../common/fse.h"
|
66 | 66 | #include "../common/huf.h"
|
67 |
| -#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */ |
| 67 | +#include "../common/sha256.h" /* ZSTD_SHA256_Result, ZSTD_SHA256_hash, ZSTD_SHA256_DIGEST_SIZE */ |
| 68 | +#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */ |
68 | 69 | #include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
69 | 70 | #include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
70 | 71 | #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
|
@@ -623,6 +624,7 @@ size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
|
623 | 624 |
|
624 | 625 | /* check input validity */
|
625 | 626 | RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
|
| 627 | + FORWARD_IF_ERROR(skippableFrameSize, ""); |
626 | 628 | RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
|
627 | 629 | RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
|
628 | 630 |
|
@@ -2408,3 +2410,40 @@ size_t ZSTD_decompressStream_simpleArgs (
|
2408 | 2410 | return cErr;
|
2409 | 2411 | }
|
2410 | 2412 | }
|
| 2413 | + |
| 2414 | +size_t ZSTD_readHeaderForHTTPDCZ( |
| 2415 | + void* dst, size_t dstCapacity, |
| 2416 | + const void* src, size_t srcSize) { |
| 2417 | + unsigned variant; |
| 2418 | + size_t result; |
| 2419 | + RETURN_ERROR_IF(dst == NULL, dstBuffer_null, "NULL dst buffer."); |
| 2420 | + RETURN_ERROR_IF(dstCapacity < ZSTD_SHA256_DIGEST_SIZE, dstSize_tooSmall, "Too small"); |
| 2421 | + |
| 2422 | + result = ZSTD_readSkippableFrame(dst, dstCapacity, &variant, src, srcSize); |
| 2423 | + |
| 2424 | + FORWARD_IF_ERROR(result, "Couldn't read skippable frame."); |
| 2425 | + RETURN_ERROR_IF(variant != ZSTD_HTTPDCZ_HEADER_SKIPPABLE_VARIANT, prefix_unknown, "Skippable frame magic is wrong for DCZ."); |
| 2426 | + RETURN_ERROR_IF(result != ZSTD_SHA256_DIGEST_SIZE, corruption_detected, "Wrong skippable frame size for DCZ."); |
| 2427 | + return result; |
| 2428 | +} |
| 2429 | + |
| 2430 | +size_t ZSTD_readHeaderForHTTPDCZ_validateDictMatches( |
| 2431 | + const void* src, size_t srcSize, |
| 2432 | + const void* dict, size_t dictSize) { |
| 2433 | + ZSTD_SHA256_Result frameHash, dictHash; |
| 2434 | + size_t result = ZSTD_readHeaderForHTTPDCZ(frameHash.digest, ZSTD_SHA256_DIGEST_SIZE, src, srcSize); |
| 2435 | + FORWARD_IF_ERROR(result, "Couldn't read DCZ header."); |
| 2436 | + RETURN_ERROR_IF(dict == NULL, dictionary_corrupted, "Dictionary invalid: NULL pointer."); |
| 2437 | + RETURN_ERROR_IF(dictSize < ZSTD_DICTIONARYSIZE_MIN, dictionary_corrupted, "Dictionary invalid: too small."); |
| 2438 | + dictHash = ZSTD_SHA256_hash(dict, dictSize); |
| 2439 | + RETURN_ERROR_IF(memcmp(frameHash.digest, dictHash.digest, ZSTD_SHA256_DIGEST_SIZE), dictionary_wrong, "DCZ hashes don't match."); |
| 2440 | + return 1; |
| 2441 | +} |
| 2442 | + |
| 2443 | +size_t ZSTD_readHeaderForHTTPDCZ_validateDDictMatches( |
| 2444 | + const void* src, size_t srcSize, |
| 2445 | + const ZSTD_DDict* ddict) { |
| 2446 | + RETURN_ERROR_IF(ddict == NULL, parameter_unsupported, "NULL ddict pointer."); |
| 2447 | + RETURN_ERROR_IF(ZSTD_DDict_type(ddict) != ZSTD_dct_rawContent, dictionary_corrupted, "Dictionary invalid: must be loaded as raw content for DCZ."); |
| 2448 | + return ZSTD_readHeaderForHTTPDCZ_validateDictMatches(src, srcSize, ZSTD_DDict_dictContent(ddict), ZSTD_DDict_dictSize(ddict)); |
| 2449 | +} |
0 commit comments