/src/xz/src/liblzma/common/block_util.c
Line | Count | Source (jump to first uncovered line) |
1 | | /////////////////////////////////////////////////////////////////////////////// |
2 | | // |
3 | | /// \file block_util.c |
4 | | /// \brief Utility functions to handle lzma_block |
5 | | // |
6 | | // Author: Lasse Collin |
7 | | // |
8 | | // This file has been put into the public domain. |
9 | | // You can do whatever you want with this file. |
10 | | // |
11 | | /////////////////////////////////////////////////////////////////////////////// |
12 | | |
13 | | #include "common.h" |
14 | | #include "index.h" |
15 | | |
16 | | |
17 | | extern LZMA_API(lzma_ret) |
18 | | lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size) |
19 | 0 | { |
20 | | // Validate everything but Uncompressed Size and filters. |
21 | 0 | if (lzma_block_unpadded_size(block) == 0) |
22 | 0 | return LZMA_PROG_ERROR; |
23 | | |
24 | 0 | const uint32_t container_size = block->header_size |
25 | 0 | + lzma_check_size(block->check); |
26 | | |
27 | | // Validate that Compressed Size will be greater than zero. |
28 | 0 | if (unpadded_size <= container_size) |
29 | 0 | return LZMA_DATA_ERROR; |
30 | | |
31 | | // Calculate what Compressed Size is supposed to be. |
32 | | // If Compressed Size was present in Block Header, |
33 | | // compare that the new value matches it. |
34 | 0 | const lzma_vli compressed_size = unpadded_size - container_size; |
35 | 0 | if (block->compressed_size != LZMA_VLI_UNKNOWN |
36 | 0 | && block->compressed_size != compressed_size) |
37 | 0 | return LZMA_DATA_ERROR; |
38 | | |
39 | 0 | block->compressed_size = compressed_size; |
40 | |
|
41 | 0 | return LZMA_OK; |
42 | 0 | } |
43 | | |
44 | | |
45 | | extern LZMA_API(lzma_vli) |
46 | | lzma_block_unpadded_size(const lzma_block *block) |
47 | 556k | { |
48 | | // Validate the values that we are interested in i.e. all but |
49 | | // Uncompressed Size and the filters. |
50 | | // |
51 | | // NOTE: This function is used for validation too, so it is |
52 | | // essential that these checks are always done even if |
53 | | // Compressed Size is unknown. |
54 | 556k | if (block == NULL || block->version > 1 |
55 | 556k | || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN |
56 | 556k | || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX |
57 | 556k | || (block->header_size & 3) |
58 | 556k | || !lzma_vli_is_valid(block->compressed_size) |
59 | 556k | || block->compressed_size == 0 |
60 | 556k | || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX) |
61 | 1 | return 0; |
62 | | |
63 | | // If Compressed Size is unknown, return that we cannot know |
64 | | // size of the Block either. |
65 | 556k | if (block->compressed_size == LZMA_VLI_UNKNOWN) |
66 | 276k | return LZMA_VLI_UNKNOWN; |
67 | | |
68 | | // Calculate Unpadded Size and validate it. |
69 | 280k | const lzma_vli unpadded_size = block->compressed_size |
70 | 280k | + block->header_size |
71 | 280k | + lzma_check_size(block->check); |
72 | | |
73 | 280k | assert(unpadded_size >= UNPADDED_SIZE_MIN); |
74 | 280k | if (unpadded_size > UNPADDED_SIZE_MAX) |
75 | 2 | return 0; |
76 | | |
77 | 280k | return unpadded_size; |
78 | 280k | } |
79 | | |
80 | | |
81 | | extern LZMA_API(lzma_vli) |
82 | | lzma_block_total_size(const lzma_block *block) |
83 | 0 | { |
84 | 0 | lzma_vli unpadded_size = lzma_block_unpadded_size(block); |
85 | |
|
86 | 0 | if (unpadded_size != LZMA_VLI_UNKNOWN) |
87 | 0 | unpadded_size = vli_ceil4(unpadded_size); |
88 | |
|
89 | 0 | return unpadded_size; |
90 | 0 | } |