1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_ZUCCHINI_PATCH_READER_H_
6 #define COMPONENTS_ZUCCHINI_PATCH_READER_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <map>
12 #include <optional>
13 #include <vector>
14
15 #include "base/debug/stack_trace.h"
16 #include "base/logging.h"
17 #include "base/numerics/checked_math.h"
18 #include "components/zucchini/buffer_source.h"
19 #include "components/zucchini/buffer_view.h"
20 #include "components/zucchini/image_utils.h"
21 #include "components/zucchini/patch_utils.h"
22
23 namespace zucchini {
24
25 namespace patch {
26
27 // The Parse*() functions below attempt to extract data of a specific type from
28 // the beginning of |source|. A parse function: On success, consumes the used
29 // portion of |source|, writes data into the output parameter, and returns
30 // true. Otherwise returns false and does not consume |source|.
31
32 // Parses |source| for the next ElementMatch.
33 bool ParseElementMatch(BufferSource* source, ElementMatch* element_match);
34
35 // Parses |source| for the next embedded BufferSource.
36 bool ParseBuffer(BufferSource* source, BufferSource* buffer);
37
38 // Parses |source| for the next VarUInt.
39 template <class T>
ParseVarUInt(BufferSource * source,T * value)40 bool ParseVarUInt(BufferSource* source, T* value) {
41 auto bytes_read = DecodeVarUInt(source->begin(), source->end(), value);
42 if (!bytes_read) {
43 LOG(ERROR) << "Impossible to read VarUInt from source.";
44 LOG(ERROR) << base::debug::StackTrace().ToString();
45 return false;
46 }
47 // Advance |source| beyond the VarUInt value.
48 source->Skip(bytes_read);
49 return true;
50 }
51
52 // Parses |source| for the next VarInt.
53 template <class T>
ParseVarInt(BufferSource * source,T * value)54 bool ParseVarInt(BufferSource* source, T* value) {
55 auto bytes_read = DecodeVarInt(source->begin(), source->end(), value);
56 if (!bytes_read) {
57 LOG(ERROR) << "Impossible to read VarInt from source.";
58 LOG(ERROR) << base::debug::StackTrace().ToString();
59 return false;
60 }
61 // Advance |source| beyond the VarInt value.
62 source->Skip(bytes_read);
63 return true;
64 }
65
66 } // namespace patch
67
68 // The *Source classes below are light-weight (i.e., allows copying) visitors to
69 // read patch data. Each of them has an associated "main type", and performs the
70 // following:
71 // - Consumes portions of a BufferSource (required to remain valid for the
72 // lifetime of the object).
73 // - Decodes consumed data, which represent a list of items with "main type".
74 // - Dispenses "main type" elements (hence "Source" in the name).
75 //
76 // Common "core functions" implemented by *Source classes are:
77 // - bool Initialize(BufferSource* source): Consumes data from BufferSource and
78 // initializes internal states. Returns true if successful, and false
79 // otherwise (|source| may be partially consumed).
80 // - std::optional<MAIN_TYPE> GetNext(OPT_PARAMS): Decodes consumed data and
81 // returns the next item as std::optional (returns std::nullopt on failure).
82 // - bool Done() const: Returns true if no more items remain; otherwise false.
83 //
84 // Usage of *Source instances don't mix, and GetNext() have dissimilar
85 // interfaces. Therefore we do not use inheritance to relate *Source classes,
86 // and simply implement "core functions" with matching names.
87
88 // Source for Equivalences.
89 class EquivalenceSource {
90 public:
91 EquivalenceSource();
92 EquivalenceSource(const EquivalenceSource&);
93 ~EquivalenceSource();
94
95 // Core functions.
96 bool Initialize(BufferSource* source);
97 std::optional<Equivalence> GetNext();
Done()98 bool Done() const {
99 return src_skip_.empty() && dst_skip_.empty() && copy_count_.empty();
100 }
101
102 // Accessors for unittest.
src_skip()103 BufferSource src_skip() const { return src_skip_; }
dst_skip()104 BufferSource dst_skip() const { return dst_skip_; }
copy_count()105 BufferSource copy_count() const { return copy_count_; }
106
107 private:
108 BufferSource src_skip_;
109 BufferSource dst_skip_;
110 BufferSource copy_count_;
111
112 base::CheckedNumeric<offset_t> previous_src_offset_ = 0;
113 base::CheckedNumeric<offset_t> previous_dst_offset_ = 0;
114 };
115
116 // Source for extra data.
117 class ExtraDataSource {
118 public:
119 ExtraDataSource();
120 ExtraDataSource(const ExtraDataSource&);
121 ~ExtraDataSource();
122
123 // Core functions.
124 bool Initialize(BufferSource* source);
125 // |size| is the size in bytes of the buffer requested.
126 std::optional<ConstBufferView> GetNext(offset_t size);
Done()127 bool Done() const { return extra_data_.empty(); }
128
129 // Accessors for unittest.
extra_data()130 BufferSource extra_data() const { return extra_data_; }
131
132 private:
133 BufferSource extra_data_;
134 };
135
136 // Source for raw delta.
137 class RawDeltaSource {
138 public:
139 RawDeltaSource();
140 RawDeltaSource(const RawDeltaSource&);
141 ~RawDeltaSource();
142
143 // Core functions.
144 bool Initialize(BufferSource* source);
145 std::optional<RawDeltaUnit> GetNext();
Done()146 bool Done() const {
147 return raw_delta_skip_.empty() && raw_delta_diff_.empty();
148 }
149
150 // Accessors for unittest.
raw_delta_skip()151 BufferSource raw_delta_skip() const { return raw_delta_skip_; }
raw_delta_diff()152 BufferSource raw_delta_diff() const { return raw_delta_diff_; }
153
154 private:
155 BufferSource raw_delta_skip_;
156 BufferSource raw_delta_diff_;
157
158 base::CheckedNumeric<offset_t> copy_offset_compensation_ = 0;
159 };
160
161 // Source for reference delta.
162 class ReferenceDeltaSource {
163 public:
164 ReferenceDeltaSource();
165 ReferenceDeltaSource(const ReferenceDeltaSource&);
166 ~ReferenceDeltaSource();
167
168 // Core functions.
169 bool Initialize(BufferSource* source);
170 std::optional<int32_t> GetNext();
Done()171 bool Done() const { return source_.empty(); }
172
173 // Accessors for unittest.
reference_delta()174 BufferSource reference_delta() const { return source_; }
175
176 private:
177 BufferSource source_;
178 };
179
180 // Source for additional targets.
181 class TargetSource {
182 public:
183 TargetSource();
184 TargetSource(const TargetSource&);
185 ~TargetSource();
186
187 // Core functions.
188 bool Initialize(BufferSource* source);
189 std::optional<offset_t> GetNext();
Done()190 bool Done() const { return extra_targets_.empty(); }
191
192 // Accessors for unittest.
extra_targets()193 BufferSource extra_targets() const { return extra_targets_; }
194
195 private:
196 BufferSource extra_targets_;
197
198 base::CheckedNumeric<offset_t> target_compensation_ = 0;
199 };
200
201 // Following are utility classes providing a structured view on data forming a
202 // patch.
203
204 // Utility to read a patch element. A patch element contains all the information
205 // necessary to patch a single element. This class provide access
206 // to the multiple streams of data forming the patch element.
207 class PatchElementReader {
208 public:
209 PatchElementReader();
210 PatchElementReader(PatchElementReader&&);
211 ~PatchElementReader();
212
213 // If data read from |source| is well-formed, initialize cached sources to
214 // read from it, and returns true. Otherwise returns false.
215 bool Initialize(BufferSource* source);
216
element_match()217 const ElementMatch& element_match() const { return element_match_; }
old_element()218 const Element& old_element() const { return element_match_.old_element; }
new_element()219 const Element& new_element() const { return element_match_.new_element; }
220
221 // The Get*() functions below return copies of cached sources. Callers may
222 // assume the following:
223 // - Equivalences satisfy basic boundary constraints
224 // - "Old" / "new" blocks lie entirely in "old" / "new" images.
225 // - "New" blocks are sorted.
GetEquivalenceSource()226 EquivalenceSource GetEquivalenceSource() const { return equivalences_; }
GetExtraDataSource()227 ExtraDataSource GetExtraDataSource() const { return extra_data_; }
GetRawDeltaSource()228 RawDeltaSource GetRawDeltaSource() const { return raw_delta_; }
GetReferenceDeltaSource()229 ReferenceDeltaSource GetReferenceDeltaSource() const {
230 return reference_delta_;
231 }
GetExtraTargetSource(PoolTag tag)232 TargetSource GetExtraTargetSource(PoolTag tag) const {
233 auto pos = extra_targets_.find(tag);
234 return pos != extra_targets_.end() ? pos->second : TargetSource();
235 }
236
237 private:
238 // Checks that "old" and "new" blocks of each item in |equivalences_| satisfy
239 // basic order and image bound constraints (using |element_match_| data). Also
240 // validates that the amount of extra data is correct. Returns true if
241 // successful.
242 bool ValidateEquivalencesAndExtraData();
243
244 ElementMatch element_match_;
245
246 // Cached sources.
247 EquivalenceSource equivalences_;
248 ExtraDataSource extra_data_;
249 RawDeltaSource raw_delta_;
250 ReferenceDeltaSource reference_delta_;
251 std::map<PoolTag, TargetSource> extra_targets_;
252 };
253
254 // Utility to read a Zucchini ensemble patch. An ensemble patch is the
255 // concatenation of a patch header with a vector of patch elements.
256 class EnsemblePatchReader {
257 public:
258 // If data read from |buffer| is well-formed, initializes and returns
259 // an instance of EnsemblePatchReader. Otherwise returns std::nullopt.
260 static std::optional<EnsemblePatchReader> Create(ConstBufferView buffer);
261
262 EnsemblePatchReader();
263 EnsemblePatchReader(EnsemblePatchReader&&);
264 ~EnsemblePatchReader();
265
266 // If data read from |source| is well-formed, initialize internal state to
267 // read from it, and returns true. Otherwise returns false.
268 bool Initialize(BufferSource* source);
269
270 // Check old / new image file validity, comparing against expected size and
271 // CRC32. Return true if file matches expectations, false otherwise.
272 bool CheckOldFile(ConstBufferView old_image) const;
273 bool CheckNewFile(ConstBufferView new_image) const;
274
header()275 const PatchHeader& header() const { return header_; }
elements()276 const std::vector<PatchElementReader>& elements() const { return elements_; }
277
278 private:
279 PatchHeader header_;
280 std::vector<PatchElementReader> elements_;
281 };
282
283 } // namespace zucchini
284
285 #endif // COMPONENTS_ZUCCHINI_PATCH_READER_H_
286