]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/block_private.h
Combine lzma_options_block validation needed by both Block
[icculus/xz.git] / src / liblzma / common / block_private.h
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       block_private.h
4 /// \brief      Common stuff for Block encoder and decoder
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #ifndef LZMA_BLOCK_COMMON_H
21 #define LZMA_BLOCK_COMMON_H
22
23 #include "common.h"
24
25 static inline bool
26 update_size(lzma_vli *size, lzma_vli add, lzma_vli limit)
27 {
28         if (limit > LZMA_VLI_VALUE_MAX)
29                 limit = LZMA_VLI_VALUE_MAX;
30
31         if (limit < *size || limit - *size < add)
32                 return true;
33
34         *size += add;
35
36         return false;
37 }
38
39
40 static inline bool
41 is_size_valid(lzma_vli size, lzma_vli reference)
42 {
43         return reference == LZMA_VLI_VALUE_UNKNOWN || reference == size;
44 }
45
46
47 /// If any of these tests fail, the caller has to return LZMA_PROG_ERROR.
48 static inline bool
49 validate_options_1(const lzma_options_block *options)
50 {
51         return options == NULL
52                         || !lzma_vli_is_valid(options->compressed_size)
53                         || !lzma_vli_is_valid(options->uncompressed_size)
54                         || !lzma_vli_is_valid(options->total_size)
55                         || !lzma_vli_is_valid(options->total_limit)
56                         || !lzma_vli_is_valid(options->uncompressed_limit);
57 }
58
59
60 /// If any of these tests fail, the encoder has to return LZMA_PROG_ERROR
61 /// because something is going horribly wrong if such values get passed
62 /// to the encoder. In contrast, the decoder has to return LZMA_DATA_ERROR,
63 /// since these tests failing indicate that something is wrong in the Stream.
64 static inline bool
65 validate_options_2(const lzma_options_block *options)
66 {
67         if ((options->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN
68                                 && options->uncompressed_size
69                                         > options->uncompressed_limit)
70                         || (options->total_size != LZMA_VLI_VALUE_UNKNOWN
71                                 && options->total_size
72                                         > options->total_limit)
73                         || (!options->has_eopm && options->uncompressed_size
74                                 == LZMA_VLI_VALUE_UNKNOWN)
75                         || options->header_size > options->total_size)
76                 return true;
77
78         if (options->compressed_size != LZMA_VLI_VALUE_UNKNOWN) {
79                 // Calculate a rough minimum possible valid Total Size of
80                 // this Block, and check that total_size and total_limit
81                 // are big enough. Note that the real minimum size can be
82                 // bigger due to the Check, Uncompressed Size, Backwards
83                 // Size, pr Padding being present. A rough check here is
84                 // enough for us to catch the most obvious errors as early
85                 // as possible.
86                 const lzma_vli total_min = options->compressed_size
87                                 + (lzma_vli)(options->header_size);
88                 if (total_min > options->total_size
89                                 || total_min > options->total_limit)
90                         return true;
91         }
92
93         return false;
94 }
95
96 #endif