/src/swift-protobuf/Sources/SwiftProtobuf/BinaryDecoder.swift
Line | Count | Source |
1 | | // Sources/SwiftProtobuf/BinaryDecoder.swift - Binary decoding |
2 | | // |
3 | | // Copyright (c) 2014 - 2016 Apple Inc. and the project authors |
4 | | // Licensed under Apache License v2.0 with Runtime Library Exception |
5 | | // |
6 | | // See LICENSE.txt for license information: |
7 | | // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt |
8 | | // |
9 | | // ----------------------------------------------------------------------------- |
10 | | /// |
11 | | /// Protobuf binary format decoding engine. |
12 | | /// |
13 | | /// This provides the Decoder interface that interacts directly |
14 | | /// with the generated code. |
15 | | /// |
16 | | // ----------------------------------------------------------------------------- |
17 | | |
18 | | #if canImport(FoundationEssentials) |
19 | | import FoundationEssentials |
20 | | #else |
21 | | import Foundation |
22 | | #endif |
23 | | |
24 | | internal struct BinaryDecoder: Decoder { |
25 | | // Current position |
26 | | private var p: UnsafeRawPointer |
27 | | // Remaining bytes in input. |
28 | | private var available: Int |
29 | | // Position of start of field currently being parsed |
30 | | private var fieldStartP: UnsafeRawPointer |
31 | | // Position of end of field currently being parsed, nil if we don't know. |
32 | | private var fieldEndP: UnsafeRawPointer? |
33 | | // Whether or not the field value has actually been parsed |
34 | 32.1M | private var consumed = true |
35 | | // Wire format for last-examined field |
36 | 32.1M | internal var fieldWireFormat = WireFormat.varint |
37 | | // Field number for last-parsed field tag |
38 | 32.1M | private var fieldNumber: Int = 0 |
39 | | // Collection of extension fields for this decode |
40 | | private var extensions: (any ExtensionMap)? |
41 | | // The current group number. See decodeFullGroup(group:fieldNumber:) for how |
42 | | // this is used. |
43 | | private var groupFieldNumber: Int? |
44 | | // The options for decoding. |
45 | | private var options: BinaryDecodingOptions |
46 | | |
47 | | private var recursionBudget: Int |
48 | | |
49 | | // Collects the unknown data found while decoding a message. |
50 | | private var unknownData: Data? |
51 | | // Custom data to use as the unknown data while parsing a field. Used only by |
52 | | // packed repeated enums; see below |
53 | | private var unknownOverride: Data? |
54 | | |
55 | 44.9M | private var complete: Bool { available == 0 } |
56 | | |
57 | | internal init( |
58 | | forReadingFrom pointer: UnsafeRawPointer, |
59 | | count: Int, |
60 | | options: BinaryDecodingOptions, |
61 | | extensions: (any ExtensionMap)? = nil |
62 | 30.8M | ) { |
63 | 30.8M | // Assuming baseAddress is not nil. |
64 | 30.8M | p = pointer |
65 | 30.8M | available = count |
66 | 30.8M | fieldStartP = p |
67 | 30.8M | self.extensions = extensions |
68 | 30.8M | self.options = options |
69 | 30.8M | recursionBudget = options.messageDepthLimit |
70 | 30.8M | } |
71 | | |
72 | | internal init( |
73 | | forReadingFrom pointer: UnsafeRawPointer, |
74 | | count: Int, |
75 | | parent: BinaryDecoder |
76 | 13.3M | ) { |
77 | 13.3M | self.init( |
78 | 13.3M | forReadingFrom: pointer, |
79 | 13.3M | count: count, |
80 | 13.3M | options: parent.options, |
81 | 13.3M | extensions: parent.extensions |
82 | 13.3M | ) |
83 | 13.3M | recursionBudget = parent.recursionBudget |
84 | 13.3M | } |
85 | | |
86 | 2.26M | private mutating func incrementRecursionDepth() throws { |
87 | 2.26M | recursionBudget -= 1 |
88 | 2.26M | if recursionBudget < 0 { |
89 | 224 | throw BinaryDecodingError.messageDepthLimit |
90 | 2.26M | } |
91 | 2.26M | } |
92 | | |
93 | 2.10M | private mutating func decrementRecursionDepth() { |
94 | 2.10M | recursionBudget += 1 |
95 | 2.10M | // This should never happen, if it does, something is probably corrupting memory, and |
96 | 2.10M | // simply throwing doesn't make much sense. |
97 | 2.10M | if recursionBudget > options.messageDepthLimit { |
98 | 0 | fatalError("Somehow BinaryDecoding unwound more objects than it started") |
99 | 0 | } |
100 | 2.10M | } |
101 | | |
102 | 221k | internal mutating func handleConflictingOneOf() throws { |
103 | 221k | /// Protobuf simply allows conflicting oneof values to overwrite |
104 | 221k | } |
105 | | |
106 | | /// Return the next field number or nil if there are no more fields. |
107 | 113M | internal mutating func nextFieldNumber() throws -> Int? { |
108 | 113M | // Since this is called for every field, I've taken some pains |
109 | 113M | // to optimize it, including unrolling a tweaked version of |
110 | 113M | // the varint parser. |
111 | 113M | if fieldNumber > 0 { |
112 | 112M | if let override = unknownOverride { |
113 | 45.9k | assert(!options.discardUnknownFields) |
114 | 45.9k | assert(fieldWireFormat != .startGroup && fieldWireFormat != .endGroup) |
115 | 45.9k | if unknownData == nil { |
116 | 1.37k | unknownData = override |
117 | 44.5k | } else { |
118 | 44.5k | unknownData!.append(override) |
119 | 44.5k | } |
120 | 45.9k | unknownOverride = nil |
121 | 112M | } else if !consumed { |
122 | 28.1M | if options.discardUnknownFields { |
123 | 2.39M | try skip() |
124 | 25.7M | } else { |
125 | 25.7M | let u = try getRawField() |
126 | 25.7M | if unknownData == nil { |
127 | 407k | unknownData = u |
128 | 25.3M | } else { |
129 | 25.3M | unknownData!.append(u) |
130 | 25.3M | } |
131 | 28.0M | } |
132 | 112M | } |
133 | 113M | } |
134 | 113M | |
135 | 113M | // Quit if end of input |
136 | 113M | if available == 0 { |
137 | 1.45M | return nil |
138 | 112M | } |
139 | 112M | |
140 | 112M | // Get the next field number |
141 | 112M | fieldStartP = p |
142 | 112M | fieldEndP = nil |
143 | 112M | let start = p |
144 | 112M | let c0 = start[0] |
145 | 112M | if let wireFormat = WireFormat(rawValue: c0 & 7) { |
146 | 112M | fieldWireFormat = wireFormat |
147 | 112M | } else { |
148 | 19.1k | throw BinaryDecodingError.malformedProtobuf |
149 | 112M | } |
150 | 112M | if (c0 & 0x80) == 0 { |
151 | 105M | p += 1 |
152 | 105M | available -= 1 |
153 | 105M | fieldNumber = Int(c0) >> 3 |
154 | 105M | } else { |
155 | 6.54M | fieldNumber = Int(c0 & 0x7f) >> 3 |
156 | 6.54M | if available < 2 { |
157 | 1.27k | throw BinaryDecodingError.malformedProtobuf |
158 | 6.54M | } |
159 | 6.54M | let c1 = start[1] |
160 | 6.54M | if (c1 & 0x80) == 0 { |
161 | 6.15M | p += 2 |
162 | 6.15M | available &-= 2 |
163 | 6.15M | fieldNumber |= Int(c1) &<< 4 |
164 | 6.15M | } else { |
165 | 385k | fieldNumber |= Int(c1 & 0x7f) &<< 4 |
166 | 385k | if available < 3 { |
167 | 260 | throw BinaryDecodingError.malformedProtobuf |
168 | 385k | } |
169 | 385k | let c2 = start[2] |
170 | 385k | fieldNumber |= Int(c2 & 0x7f) &<< 11 |
171 | 385k | if (c2 & 0x80) == 0 { |
172 | 290k | p += 3 |
173 | 290k | available &-= 3 |
174 | 290k | } else { |
175 | 94.7k | if available < 4 { |
176 | 582 | throw BinaryDecodingError.malformedProtobuf |
177 | 94.1k | } |
178 | 94.1k | let c3 = start[3] |
179 | 94.1k | fieldNumber |= Int(c3 & 0x7f) &<< 18 |
180 | 94.1k | if (c3 & 0x80) == 0 { |
181 | 76.8k | p += 4 |
182 | 76.8k | available &-= 4 |
183 | 76.8k | } else { |
184 | 17.2k | if available < 5 { |
185 | 340 | throw BinaryDecodingError.malformedProtobuf |
186 | 16.9k | } |
187 | 16.9k | let c4 = start[4] |
188 | 16.9k | if c4 > 15 { |
189 | 708 | throw BinaryDecodingError.malformedProtobuf |
190 | 16.1k | } |
191 | 16.1k | fieldNumber |= Int(c4 & 0x7f) &<< 25 |
192 | 16.1k | p += 5 |
193 | 16.1k | available &-= 5 |
194 | 93.0k | } |
195 | 383k | } |
196 | 6.54M | } |
197 | 112M | } |
198 | 112M | if fieldNumber != 0 { |
199 | 112M | consumed = false |
200 | 112M | |
201 | 112M | if fieldWireFormat == .endGroup { |
202 | 24.3k | if groupFieldNumber == fieldNumber { |
203 | 11.7k | // Reached the end of the current group, single the |
204 | 11.7k | // end of the message. |
205 | 11.7k | return nil |
206 | 12.5k | } else { |
207 | 12.5k | // .endGroup when not in a group or for a different |
208 | 12.5k | // group is an invalid binary. |
209 | 12.5k | throw BinaryDecodingError.malformedProtobuf |
210 | 12.5k | } |
211 | 112M | } |
212 | 112M | return fieldNumber |
213 | 112M | } |
214 | 4.68k | throw BinaryDecodingError.malformedProtobuf |
215 | 113M | } |
216 | | |
217 | 20.8k | internal mutating func decodeSingularFloatField(value: inout Float) throws { |
218 | 20.8k | guard fieldWireFormat == WireFormat.fixed32 else { |
219 | 19.1k | return |
220 | 19.1k | } |
221 | 1.69k | value = try decodeFloat() |
222 | 1.68k | consumed = true |
223 | 1.68k | } |
224 | | |
225 | 958k | internal mutating func decodeSingularFloatField(value: inout Float?) throws { |
226 | 958k | guard fieldWireFormat == WireFormat.fixed32 else { |
227 | 883k | return |
228 | 883k | } |
229 | 74.4k | value = try decodeFloat() |
230 | 74.4k | consumed = true |
231 | 74.4k | } |
232 | | |
233 | 282k | internal mutating func decodeRepeatedFloatField(value: inout [Float]) throws { |
234 | 282k | switch fieldWireFormat { |
235 | 282k | case WireFormat.fixed32: |
236 | 153k | let i = try decodeFloat() |
237 | 153k | value.append(i) |
238 | 153k | consumed = true |
239 | 282k | case WireFormat.lengthDelimited: |
240 | 90.5k | let bodyBytes = try decodeVarint() |
241 | 90.5k | if bodyBytes > 0 { |
242 | 78.8k | let itemSize = UInt64(MemoryLayout<Float>.size) |
243 | 78.8k | let itemCount = bodyBytes / itemSize |
244 | 83.8k | if bodyBytes % itemSize != 0 || bodyBytes > available { |
245 | 407 | throw BinaryDecodingError.truncated |
246 | 78.4k | } |
247 | 78.4k | value.reserveCapacity(value.count + Int(truncatingIfNeeded: itemCount)) |
248 | 1.03M | for _ in 1...itemCount { |
249 | 1.03M | value.append(try decodeFloat()) |
250 | 1.03M | } |
251 | 90.1k | } |
252 | 90.1k | consumed = true |
253 | 282k | default: |
254 | 38.4k | return |
255 | 282k | } |
256 | 243k | } |
257 | | |
258 | 11.8k | internal mutating func decodeSingularDoubleField(value: inout Double) throws { |
259 | 11.8k | guard fieldWireFormat == WireFormat.fixed64 else { |
260 | 11.0k | return |
261 | 11.0k | } |
262 | 827 | value = try decodeDouble() |
263 | 812 | consumed = true |
264 | 812 | } |
265 | | |
266 | 935k | internal mutating func decodeSingularDoubleField(value: inout Double?) throws { |
267 | 935k | guard fieldWireFormat == WireFormat.fixed64 else { |
268 | 818k | return |
269 | 818k | } |
270 | 117k | value = try decodeDouble() |
271 | 117k | consumed = true |
272 | 117k | } |
273 | | |
274 | 319k | internal mutating func decodeRepeatedDoubleField(value: inout [Double]) throws { |
275 | 319k | switch fieldWireFormat { |
276 | 319k | case WireFormat.fixed64: |
277 | 177k | let i = try decodeDouble() |
278 | 177k | value.append(i) |
279 | 177k | consumed = true |
280 | 319k | case WireFormat.lengthDelimited: |
281 | 136k | let bodyBytes = try decodeVarint() |
282 | 136k | if bodyBytes > 0 { |
283 | 136k | let itemSize = UInt64(MemoryLayout<Double>.size) |
284 | 136k | let itemCount = bodyBytes / itemSize |
285 | 142k | if bodyBytes % itemSize != 0 || bodyBytes > available { |
286 | 483 | throw BinaryDecodingError.truncated |
287 | 135k | } |
288 | 135k | value.reserveCapacity(value.count + Int(truncatingIfNeeded: itemCount)) |
289 | 474k | for _ in 1...itemCount { |
290 | 474k | let i = try decodeDouble() |
291 | 474k | value.append(i) |
292 | 474k | } |
293 | 136k | } |
294 | 136k | consumed = true |
295 | 319k | default: |
296 | 5.53k | return |
297 | 319k | } |
298 | 313k | } |
299 | | |
300 | 112k | internal mutating func decodeSingularInt32Field(value: inout Int32) throws { |
301 | 112k | guard fieldWireFormat == WireFormat.varint else { |
302 | 33.3k | return |
303 | 78.9k | } |
304 | 78.9k | let varint = try decodeVarint() |
305 | 78.9k | value = Int32(truncatingIfNeeded: varint) |
306 | 78.9k | consumed = true |
307 | 78.9k | } |
308 | | |
309 | 18.7M | internal mutating func decodeSingularInt32Field(value: inout Int32?) throws { |
310 | 18.7M | guard fieldWireFormat == WireFormat.varint else { |
311 | 477k | return |
312 | 18.2M | } |
313 | 18.2M | let varint = try decodeVarint() |
314 | 18.2M | value = Int32(truncatingIfNeeded: varint) |
315 | 18.2M | consumed = true |
316 | 18.2M | } |
317 | | |
318 | 285k | internal mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws { |
319 | 285k | switch fieldWireFormat { |
320 | 285k | case WireFormat.varint: |
321 | 181k | let varint = try decodeVarint() |
322 | 181k | value.append(Int32(truncatingIfNeeded: varint)) |
323 | 181k | consumed = true |
324 | 285k | case WireFormat.lengthDelimited: |
325 | 49.7k | var n: Int = 0 |
326 | 49.7k | let p = try getFieldBodyBytes(count: &n) |
327 | 49.4k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
328 | 49.4k | value.reserveCapacity(value.count + ints) |
329 | 49.4k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
330 | 3.50M | while !decoder.complete { |
331 | 3.45M | let varint = try decoder.decodeVarint() |
332 | 3.45M | value.append(Int32(truncatingIfNeeded: varint)) |
333 | 3.45M | } |
334 | 49.4k | consumed = true |
335 | 285k | default: |
336 | 54.1k | return |
337 | 285k | } |
338 | 230k | } |
339 | | |
340 | 796k | internal mutating func decodeSingularInt64Field(value: inout Int64) throws { |
341 | 796k | guard fieldWireFormat == WireFormat.varint else { |
342 | 683k | return |
343 | 683k | } |
344 | 113k | let v = try decodeVarint() |
345 | 113k | value = Int64(bitPattern: v) |
346 | 113k | consumed = true |
347 | 113k | } |
348 | | |
349 | 38.3M | internal mutating func decodeSingularInt64Field(value: inout Int64?) throws { |
350 | 38.3M | guard fieldWireFormat == WireFormat.varint else { |
351 | 407k | return |
352 | 37.9M | } |
353 | 37.9M | let varint = try decodeVarint() |
354 | 37.9M | value = Int64(bitPattern: varint) |
355 | 37.9M | consumed = true |
356 | 37.9M | } |
357 | | |
358 | 257k | internal mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws { |
359 | 257k | switch fieldWireFormat { |
360 | 257k | case WireFormat.varint: |
361 | 189k | let varint = try decodeVarint() |
362 | 189k | value.append(Int64(bitPattern: varint)) |
363 | 189k | consumed = true |
364 | 257k | case WireFormat.lengthDelimited: |
365 | 64.1k | var n: Int = 0 |
366 | 64.1k | let p = try getFieldBodyBytes(count: &n) |
367 | 63.8k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
368 | 63.8k | value.reserveCapacity(value.count + ints) |
369 | 63.8k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
370 | 2.92M | while !decoder.complete { |
371 | 2.86M | let varint = try decoder.decodeVarint() |
372 | 2.86M | value.append(Int64(bitPattern: varint)) |
373 | 2.86M | } |
374 | 63.8k | consumed = true |
375 | 257k | default: |
376 | 4.39k | return |
377 | 257k | } |
378 | 252k | } |
379 | | |
380 | 9.72k | internal mutating func decodeSingularUInt32Field(value: inout UInt32) throws { |
381 | 9.72k | guard fieldWireFormat == WireFormat.varint else { |
382 | 775 | return |
383 | 8.95k | } |
384 | 8.95k | let varint = try decodeVarint() |
385 | 8.94k | value = UInt32(truncatingIfNeeded: varint) |
386 | 8.94k | consumed = true |
387 | 8.94k | } |
388 | | |
389 | 19.4M | internal mutating func decodeSingularUInt32Field(value: inout UInt32?) throws { |
390 | 19.4M | guard fieldWireFormat == WireFormat.varint else { |
391 | 219k | return |
392 | 19.1M | } |
393 | 19.1M | let varint = try decodeVarint() |
394 | 19.1M | value = UInt32(truncatingIfNeeded: varint) |
395 | 19.1M | consumed = true |
396 | 19.1M | } |
397 | | |
398 | 220k | internal mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws { |
399 | 220k | switch fieldWireFormat { |
400 | 220k | case WireFormat.varint: |
401 | 121k | let varint = try decodeVarint() |
402 | 121k | value.append(UInt32(truncatingIfNeeded: varint)) |
403 | 121k | consumed = true |
404 | 220k | case WireFormat.lengthDelimited: |
405 | 97.4k | var n: Int = 0 |
406 | 97.4k | let p = try getFieldBodyBytes(count: &n) |
407 | 97.1k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
408 | 97.1k | value.reserveCapacity(value.count + ints) |
409 | 97.1k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
410 | 4.08M | while !decoder.complete { |
411 | 3.98M | let t = try decoder.decodeVarint() |
412 | 3.98M | value.append(UInt32(truncatingIfNeeded: t)) |
413 | 3.98M | } |
414 | 97.1k | consumed = true |
415 | 220k | default: |
416 | 1.82k | return |
417 | 220k | } |
418 | 218k | } |
419 | | |
420 | 32.5M | internal mutating func decodeSingularUInt64Field(value: inout UInt64) throws { |
421 | 32.5M | guard fieldWireFormat == WireFormat.varint else { |
422 | 3.65k | return |
423 | 32.5M | } |
424 | 32.5M | value = try decodeVarint() |
425 | 32.5M | consumed = true |
426 | 32.5M | } |
427 | | |
428 | 1.34M | internal mutating func decodeSingularUInt64Field(value: inout UInt64?) throws { |
429 | 1.34M | guard fieldWireFormat == WireFormat.varint else { |
430 | 132k | return |
431 | 1.21M | } |
432 | 1.21M | value = try decodeVarint() |
433 | 1.21M | consumed = true |
434 | 1.21M | } |
435 | | |
436 | 104k | internal mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws { |
437 | 104k | switch fieldWireFormat { |
438 | 104k | case WireFormat.varint: |
439 | 55.0k | let varint = try decodeVarint() |
440 | 55.0k | value.append(varint) |
441 | 55.0k | consumed = true |
442 | 104k | case WireFormat.lengthDelimited: |
443 | 45.7k | var n: Int = 0 |
444 | 45.7k | let p = try getFieldBodyBytes(count: &n) |
445 | 45.5k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
446 | 45.5k | value.reserveCapacity(value.count + ints) |
447 | 45.5k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
448 | 4.17M | while !decoder.complete { |
449 | 4.13M | let t = try decoder.decodeVarint() |
450 | 4.13M | value.append(t) |
451 | 4.13M | } |
452 | 45.4k | consumed = true |
453 | 104k | default: |
454 | 4.19k | return |
455 | 104k | } |
456 | 100k | } |
457 | | |
458 | 0 | internal mutating func decodeSingularSInt32Field(value: inout Int32) throws { |
459 | 0 | guard fieldWireFormat == WireFormat.varint else { |
460 | 0 | return |
461 | 0 | } |
462 | 0 | let varint = try decodeVarint() |
463 | 0 | let t = UInt32(truncatingIfNeeded: varint) |
464 | 0 | value = ZigZag.decoded(t) |
465 | 0 | consumed = true |
466 | 0 | } |
467 | | |
468 | 1.53M | internal mutating func decodeSingularSInt32Field(value: inout Int32?) throws { |
469 | 1.53M | guard fieldWireFormat == WireFormat.varint else { |
470 | 191k | return |
471 | 1.34M | } |
472 | 1.34M | let varint = try decodeVarint() |
473 | 1.34M | let t = UInt32(truncatingIfNeeded: varint) |
474 | 1.34M | value = ZigZag.decoded(t) |
475 | 1.34M | consumed = true |
476 | 1.34M | } |
477 | | |
478 | 161k | internal mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws { |
479 | 161k | switch fieldWireFormat { |
480 | 161k | case WireFormat.varint: |
481 | 102k | let varint = try decodeVarint() |
482 | 102k | let t = UInt32(truncatingIfNeeded: varint) |
483 | 102k | value.append(ZigZag.decoded(t)) |
484 | 102k | consumed = true |
485 | 161k | case WireFormat.lengthDelimited: |
486 | 59.0k | var n: Int = 0 |
487 | 59.0k | let p = try getFieldBodyBytes(count: &n) |
488 | 58.7k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
489 | 58.7k | value.reserveCapacity(value.count + ints) |
490 | 58.7k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
491 | 2.75M | while !decoder.complete { |
492 | 2.69M | let varint = try decoder.decodeVarint() |
493 | 2.69M | let t = UInt32(truncatingIfNeeded: varint) |
494 | 2.69M | value.append(ZigZag.decoded(t)) |
495 | 2.69M | } |
496 | 58.7k | consumed = true |
497 | 161k | default: |
498 | 664 | return |
499 | 161k | } |
500 | 160k | } |
501 | | |
502 | 0 | internal mutating func decodeSingularSInt64Field(value: inout Int64) throws { |
503 | 0 | guard fieldWireFormat == WireFormat.varint else { |
504 | 0 | return |
505 | 0 | } |
506 | 0 | let varint = try decodeVarint() |
507 | 0 | value = ZigZag.decoded(varint) |
508 | 0 | consumed = true |
509 | 0 | } |
510 | | |
511 | 1.40M | internal mutating func decodeSingularSInt64Field(value: inout Int64?) throws { |
512 | 1.40M | guard fieldWireFormat == WireFormat.varint else { |
513 | 115k | return |
514 | 1.28M | } |
515 | 1.28M | let varint = try decodeVarint() |
516 | 1.28M | value = ZigZag.decoded(varint) |
517 | 1.28M | consumed = true |
518 | 1.28M | } |
519 | | |
520 | 156k | internal mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws { |
521 | 156k | switch fieldWireFormat { |
522 | 156k | case WireFormat.varint: |
523 | 36.0k | let varint = try decodeVarint() |
524 | 36.0k | value.append(ZigZag.decoded(varint)) |
525 | 36.0k | consumed = true |
526 | 156k | case WireFormat.lengthDelimited: |
527 | 119k | var n: Int = 0 |
528 | 119k | let p = try getFieldBodyBytes(count: &n) |
529 | 119k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
530 | 119k | value.reserveCapacity(value.count + ints) |
531 | 119k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
532 | 5.77M | while !decoder.complete { |
533 | 5.65M | let varint = try decoder.decodeVarint() |
534 | 5.65M | value.append(ZigZag.decoded(varint)) |
535 | 5.65M | } |
536 | 119k | consumed = true |
537 | 156k | default: |
538 | 861 | return |
539 | 156k | } |
540 | 155k | } |
541 | | |
542 | 1.41M | internal mutating func decodeSingularFixed32Field(value: inout UInt32) throws { |
543 | 1.41M | guard fieldWireFormat == WireFormat.fixed32 else { |
544 | 0 | return |
545 | 1.41M | } |
546 | 1.41M | value = try decodeLittleEndianInteger() |
547 | 1.41M | consumed = true |
548 | 1.41M | } |
549 | | |
550 | 2.40M | internal mutating func decodeSingularFixed32Field(value: inout UInt32?) throws { |
551 | 2.40M | guard fieldWireFormat == WireFormat.fixed32 else { |
552 | 2.33M | return |
553 | 2.33M | } |
554 | 63.6k | value = try decodeLittleEndianInteger() |
555 | 63.6k | consumed = true |
556 | 63.6k | } |
557 | | |
558 | 152k | internal mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws { |
559 | 152k | switch fieldWireFormat { |
560 | 152k | case WireFormat.fixed32: |
561 | 41.5k | value.append(try decodeLittleEndianInteger()) |
562 | 41.5k | consumed = true |
563 | 152k | case WireFormat.lengthDelimited: |
564 | 107k | var n: Int = 0 |
565 | 107k | let p = try getFieldBodyBytes(count: &n) |
566 | 107k | value.reserveCapacity(value.count + n / MemoryLayout<UInt32>.size) |
567 | 107k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
568 | 887k | while !decoder.complete { |
569 | 780k | value.append(try decoder.decodeLittleEndianInteger()) |
570 | 780k | } |
571 | 107k | consumed = true |
572 | 152k | default: |
573 | 3.00k | return |
574 | 152k | } |
575 | 149k | } |
576 | | |
577 | 3.90M | internal mutating func decodeSingularFixed64Field(value: inout UInt64) throws { |
578 | 3.90M | guard fieldWireFormat == WireFormat.fixed64 else { |
579 | 0 | return |
580 | 3.90M | } |
581 | 3.90M | value = try decodeLittleEndianInteger() |
582 | 3.90M | consumed = true |
583 | 3.90M | } |
584 | | |
585 | 1.89M | internal mutating func decodeSingularFixed64Field(value: inout UInt64?) throws { |
586 | 1.89M | guard fieldWireFormat == WireFormat.fixed64 else { |
587 | 1.67M | return |
588 | 1.67M | } |
589 | 214k | value = try decodeLittleEndianInteger() |
590 | 214k | consumed = true |
591 | 214k | } |
592 | | |
593 | 175k | internal mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws { |
594 | 175k | switch fieldWireFormat { |
595 | 175k | case WireFormat.fixed64: |
596 | 99.8k | value.append(try decodeLittleEndianInteger()) |
597 | 99.8k | consumed = true |
598 | 175k | case WireFormat.lengthDelimited: |
599 | 73.8k | var n: Int = 0 |
600 | 73.8k | let p = try getFieldBodyBytes(count: &n) |
601 | 73.5k | value.reserveCapacity(value.count + n / MemoryLayout<UInt64>.size) |
602 | 73.5k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
603 | 617k | while !decoder.complete { |
604 | 544k | value.append(try decoder.decodeLittleEndianInteger()) |
605 | 544k | } |
606 | 73.4k | consumed = true |
607 | 175k | default: |
608 | 1.41k | return |
609 | 175k | } |
610 | 173k | } |
611 | | |
612 | 0 | internal mutating func decodeSingularSFixed32Field(value: inout Int32) throws { |
613 | 0 | guard fieldWireFormat == WireFormat.fixed32 else { |
614 | 0 | return |
615 | 0 | } |
616 | 0 | value = try decodeLittleEndianInteger() |
617 | 0 | consumed = true |
618 | 0 | } |
619 | | |
620 | 3.15M | internal mutating func decodeSingularSFixed32Field(value: inout Int32?) throws { |
621 | 3.15M | guard fieldWireFormat == WireFormat.fixed32 else { |
622 | 3.01M | return |
623 | 3.01M | } |
624 | 138k | value = try decodeLittleEndianInteger() |
625 | 138k | consumed = true |
626 | 138k | } |
627 | | |
628 | 155k | internal mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws { |
629 | 155k | switch fieldWireFormat { |
630 | 155k | case WireFormat.fixed32: |
631 | 129k | value.append(try decodeLittleEndianInteger()) |
632 | 129k | consumed = true |
633 | 155k | case WireFormat.lengthDelimited: |
634 | 22.0k | var n: Int = 0 |
635 | 22.0k | let p = try getFieldBodyBytes(count: &n) |
636 | 21.7k | value.reserveCapacity(value.count + n / MemoryLayout<Int32>.size) |
637 | 21.7k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
638 | 313k | while !decoder.complete { |
639 | 291k | value.append(try decoder.decodeLittleEndianInteger()) |
640 | 291k | } |
641 | 21.6k | consumed = true |
642 | 155k | default: |
643 | 3.68k | return |
644 | 155k | } |
645 | 151k | } |
646 | | |
647 | 0 | internal mutating func decodeSingularSFixed64Field(value: inout Int64) throws { |
648 | 0 | guard fieldWireFormat == WireFormat.fixed64 else { |
649 | 0 | return |
650 | 0 | } |
651 | 0 | value = try decodeLittleEndianInteger() |
652 | 0 | consumed = true |
653 | 0 | } |
654 | | |
655 | 1.53M | internal mutating func decodeSingularSFixed64Field(value: inout Int64?) throws { |
656 | 1.53M | guard fieldWireFormat == WireFormat.fixed64 else { |
657 | 1.47M | return |
658 | 1.47M | } |
659 | 63.7k | value = try decodeLittleEndianInteger() |
660 | 63.7k | consumed = true |
661 | 63.7k | } |
662 | | |
663 | 147k | internal mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws { |
664 | 147k | switch fieldWireFormat { |
665 | 147k | case WireFormat.fixed64: |
666 | 83.6k | value.append(try decodeLittleEndianInteger()) |
667 | 83.6k | consumed = true |
668 | 147k | case WireFormat.lengthDelimited: |
669 | 52.7k | var n: Int = 0 |
670 | 52.7k | let p = try getFieldBodyBytes(count: &n) |
671 | 52.4k | value.reserveCapacity(value.count + n / MemoryLayout<Int64>.size) |
672 | 52.4k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
673 | 264k | while !decoder.complete { |
674 | 211k | value.append(try decoder.decodeLittleEndianInteger()) |
675 | 211k | } |
676 | 52.4k | consumed = true |
677 | 147k | default: |
678 | 11.2k | return |
679 | 147k | } |
680 | 136k | } |
681 | | |
682 | 66.5k | internal mutating func decodeSingularBoolField(value: inout Bool) throws { |
683 | 66.5k | guard fieldWireFormat == WireFormat.varint else { |
684 | 4.21k | return |
685 | 62.3k | } |
686 | 62.3k | value = try decodeVarint() != 0 |
687 | 62.2k | consumed = true |
688 | 62.2k | } |
689 | | |
690 | 536k | internal mutating func decodeSingularBoolField(value: inout Bool?) throws { |
691 | 536k | guard fieldWireFormat == WireFormat.varint else { |
692 | 93.6k | return |
693 | 442k | } |
694 | 442k | value = try decodeVarint() != 0 |
695 | 442k | consumed = true |
696 | 442k | } |
697 | | |
698 | 133k | internal mutating func decodeRepeatedBoolField(value: inout [Bool]) throws { |
699 | 133k | switch fieldWireFormat { |
700 | 133k | case WireFormat.varint: |
701 | 42.0k | let varint = try decodeVarint() |
702 | 42.0k | value.append(varint != 0) |
703 | 42.0k | consumed = true |
704 | 133k | case WireFormat.lengthDelimited: |
705 | 82.1k | var n: Int = 0 |
706 | 82.1k | let p = try getFieldBodyBytes(count: &n) |
707 | 81.7k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
708 | 81.7k | value.reserveCapacity(value.count + ints) |
709 | 81.7k | var decoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
710 | 4.86M | while !decoder.complete { |
711 | 4.77M | let t = try decoder.decodeVarint() |
712 | 4.77M | value.append(t != 0) |
713 | 4.77M | } |
714 | 81.6k | consumed = true |
715 | 133k | default: |
716 | 9.14k | return |
717 | 133k | } |
718 | 123k | } |
719 | | |
720 | 195k | internal mutating func decodeSingularStringField(value: inout String) throws { |
721 | 195k | guard fieldWireFormat == WireFormat.lengthDelimited else { |
722 | 183k | return |
723 | 183k | } |
724 | 12.2k | var n: Int = 0 |
725 | 12.2k | let p = try getFieldBodyBytes(count: &n) |
726 | 11.9k | if let s = utf8ToString(bytes: p, count: n) { |
727 | 11.8k | value = s |
728 | 11.8k | consumed = true |
729 | 11.8k | } else { |
730 | 53 | throw BinaryDecodingError.invalidUTF8 |
731 | 11.8k | } |
732 | 11.8k | } |
733 | | |
734 | 1.10M | internal mutating func decodeSingularStringField(value: inout String?) throws { |
735 | 1.10M | guard fieldWireFormat == WireFormat.lengthDelimited else { |
736 | 1.07M | return |
737 | 1.07M | } |
738 | 32.4k | var n: Int = 0 |
739 | 32.4k | let p = try getFieldBodyBytes(count: &n) |
740 | 32.0k | if let s = utf8ToString(bytes: p, count: n) { |
741 | 31.9k | value = s |
742 | 31.9k | consumed = true |
743 | 31.9k | } else { |
744 | 131 | throw BinaryDecodingError.invalidUTF8 |
745 | 31.9k | } |
746 | 31.9k | } |
747 | | |
748 | 89.9k | internal mutating func decodeRepeatedStringField(value: inout [String]) throws { |
749 | 89.9k | switch fieldWireFormat { |
750 | 89.9k | case WireFormat.lengthDelimited: |
751 | 38.4k | var n: Int = 0 |
752 | 38.4k | let p = try getFieldBodyBytes(count: &n) |
753 | 38.1k | if let s = utf8ToString(bytes: p, count: n) { |
754 | 38.1k | value.append(s) |
755 | 38.1k | consumed = true |
756 | 38.1k | } else { |
757 | 56 | throw BinaryDecodingError.invalidUTF8 |
758 | 56 | } |
759 | 89.9k | default: |
760 | 51.4k | return |
761 | 89.9k | } |
762 | 38.1k | } |
763 | | |
764 | 881k | internal mutating func decodeSingularBytesField(value: inout Data) throws { |
765 | 881k | guard fieldWireFormat == WireFormat.lengthDelimited else { |
766 | 417k | return |
767 | 463k | } |
768 | 463k | var n: Int = 0 |
769 | 463k | let p = try getFieldBodyBytes(count: &n) |
770 | 462k | value = Data(bytes: p, count: n) |
771 | 462k | consumed = true |
772 | 462k | } |
773 | | |
774 | 1.42M | internal mutating func decodeSingularBytesField(value: inout Data?) throws { |
775 | 1.42M | guard fieldWireFormat == WireFormat.lengthDelimited else { |
776 | 1.15M | return |
777 | 1.15M | } |
778 | 269k | var n: Int = 0 |
779 | 269k | let p = try getFieldBodyBytes(count: &n) |
780 | 268k | value = Data(bytes: p, count: n) |
781 | 268k | consumed = true |
782 | 268k | } |
783 | | |
784 | 26.5k | internal mutating func decodeRepeatedBytesField(value: inout [Data]) throws { |
785 | 26.5k | switch fieldWireFormat { |
786 | 26.5k | case WireFormat.lengthDelimited: |
787 | 25.7k | var n: Int = 0 |
788 | 25.7k | let p = try getFieldBodyBytes(count: &n) |
789 | 25.4k | value.append(Data(bytes: p, count: n)) |
790 | 25.4k | consumed = true |
791 | 26.5k | default: |
792 | 814 | return |
793 | 26.5k | } |
794 | 25.4k | } |
795 | | |
796 | 123k | internal mutating func decodeSingularEnumField<E: Enum>(value: inout E?) throws where E.RawValue == Int { |
797 | 123k | guard fieldWireFormat == WireFormat.varint else { |
798 | 21.7k | return |
799 | 101k | } |
800 | 101k | let varint = try decodeVarint() |
801 | 101k | if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { |
802 | 56.0k | value = v |
803 | 56.0k | consumed = true |
804 | 56.0k | } |
805 | 101k | } |
806 | | |
807 | 73.7k | internal mutating func decodeSingularEnumField<E: Enum>(value: inout E) throws where E.RawValue == Int { |
808 | 73.7k | guard fieldWireFormat == WireFormat.varint else { |
809 | 3.89k | return |
810 | 69.8k | } |
811 | 69.8k | let varint = try decodeVarint() |
812 | 69.8k | if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { |
813 | 69.8k | value = v |
814 | 69.8k | consumed = true |
815 | 69.8k | } |
816 | 69.8k | } |
817 | | |
818 | 80.8k | internal mutating func decodeRepeatedEnumField<E: Enum>(value: inout [E]) throws where E.RawValue == Int { |
819 | 80.8k | switch fieldWireFormat { |
820 | 80.8k | case WireFormat.varint: |
821 | 31.1k | let varint = try decodeVarint() |
822 | 31.0k | if let v = E(rawValue: Int(Int32(truncatingIfNeeded: varint))) { |
823 | 2.22k | value.append(v) |
824 | 2.22k | consumed = true |
825 | 2.22k | } |
826 | 80.8k | case WireFormat.lengthDelimited: |
827 | 49.5k | var n: Int = 0 |
828 | 49.5k | var extras: [Int32]? |
829 | 49.5k | let p = try getFieldBodyBytes(count: &n) |
830 | 49.2k | let ints = Varint.countVarintsInBuffer(start: p, count: n) |
831 | 49.2k | value.reserveCapacity(value.count + ints) |
832 | 49.2k | var subdecoder = BinaryDecoder(forReadingFrom: p, count: n, parent: self) |
833 | 8.48M | while !subdecoder.complete { |
834 | 8.43M | let u64 = try subdecoder.decodeVarint() |
835 | 8.43M | let i32 = Int32(truncatingIfNeeded: u64) |
836 | 8.43M | if let v = E(rawValue: Int(i32)) { |
837 | 168k | value.append(v) |
838 | 8.27M | } else if !options.discardUnknownFields { |
839 | 8.19M | if extras == nil { |
840 | 46.0k | extras = [] |
841 | 46.0k | } |
842 | 8.19M | extras!.append(i32) |
843 | 8.19M | } |
844 | 8.43M | } |
845 | 49.1k | if let extras = extras { |
846 | 45.9k | let fieldTag = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited) |
847 | 8.69M | let bodySize = extras.reduce(0) { $0 + Varint.encodedSize(of: Int64($1)) } |
848 | 45.9k | let fieldSize = |
849 | 45.9k | Varint.encodedSize(of: fieldTag.rawValue) + Varint.encodedSize(of: Int64(bodySize)) + bodySize |
850 | 45.9k | var field = Data(count: fieldSize) |
851 | 58.6k | field.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in |
852 | 58.6k | var encoder = BinaryEncoder(forWritingInto: body) |
853 | 58.6k | encoder.startField(tag: fieldTag) |
854 | 58.6k | encoder.putVarInt(value: Int64(bodySize)) |
855 | 8.69M | for v in extras { |
856 | 8.69M | encoder.putVarInt(value: Int64(v)) |
857 | 8.69M | } |
858 | 58.6k | } |
859 | 45.9k | unknownOverride = field |
860 | 45.9k | } |
861 | 49.1k | consumed = true |
862 | 80.8k | default: |
863 | 245 | return |
864 | 80.8k | } |
865 | 80.2k | } |
866 | | |
867 | 1.06M | internal mutating func decodeSingularMessageField<M: Message>(value: inout M?) throws { |
868 | 1.06M | guard fieldWireFormat == WireFormat.lengthDelimited else { |
869 | 655k | return |
870 | 655k | } |
871 | 414k | var count: Int = 0 |
872 | 414k | let p = try getFieldBodyBytes(count: &count) |
873 | 413k | if value == nil { |
874 | 103k | value = M() |
875 | 103k | } |
876 | 413k | var subDecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) |
877 | 413k | try subDecoder.decodeFullMessage(message: &value!) |
878 | 407k | consumed = true |
879 | 407k | } |
880 | | |
881 | 1.35M | internal mutating func decodeRepeatedMessageField<M: Message>(value: inout [M]) throws { |
882 | 1.35M | guard fieldWireFormat == WireFormat.lengthDelimited else { |
883 | 371k | return |
884 | 980k | } |
885 | 980k | var count: Int = 0 |
886 | 980k | let p = try getFieldBodyBytes(count: &count) |
887 | 979k | var newValue = M() |
888 | 979k | var subDecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) |
889 | 979k | try subDecoder.decodeFullMessage(message: &newValue) |
890 | 978k | value.append(newValue) |
891 | 978k | consumed = true |
892 | 978k | } |
893 | | |
894 | 1.46M | internal mutating func decodeFullMessage<M: Message>(message: inout M) throws { |
895 | 1.46M | assert(unknownData == nil) |
896 | 1.46M | try incrementRecursionDepth() |
897 | 1.46M | try message.decodeMessage(decoder: &self) |
898 | 1.43M | decrementRecursionDepth() |
899 | 1.43M | guard complete else { |
900 | 0 | throw BinaryDecodingError.trailingGarbage |
901 | 1.43M | } |
902 | 1.43M | if let unknownData = unknownData { |
903 | 384k | message.unknownFields.append(protobufData: unknownData) |
904 | 384k | } |
905 | 1.43M | } |
906 | | |
907 | 17.0k | internal mutating func decodeSingularGroupField<G: Message>(value: inout G?) throws { |
908 | 19.0k | var group = value ?? G() |
909 | 17.0k | if try decodeFullGroup(group: &group, fieldNumber: fieldNumber) { |
910 | 7.66k | value = group |
911 | 7.66k | consumed = true |
912 | 7.66k | } |
913 | 16.5k | } |
914 | | |
915 | 24.1k | internal mutating func decodeRepeatedGroupField<G: Message>(value: inout [G]) throws { |
916 | 24.1k | var group = G() |
917 | 24.1k | if try decodeFullGroup(group: &group, fieldNumber: fieldNumber) { |
918 | 4.11k | value.append(group) |
919 | 4.11k | consumed = true |
920 | 4.11k | } |
921 | 23.8k | } |
922 | | |
923 | 66.8k | private mutating func decodeFullGroup<G: Message>(group: inout G, fieldNumber: Int) throws -> Bool { |
924 | 66.8k | guard fieldWireFormat == WireFormat.startGroup else { |
925 | 38.4k | return false |
926 | 38.4k | } |
927 | 28.4k | try incrementRecursionDepth() |
928 | 28.4k | |
929 | 28.4k | // This works by making a clone of the current decoder state and |
930 | 28.4k | // setting `groupFieldNumber` to signal `nextFieldNumber()` to watch |
931 | 28.4k | // for that as a marker for having reached the end of a group/message. |
932 | 28.4k | // Groups within groups works because this effectively makes a stack |
933 | 28.4k | // of decoders, each one looking for their ending tag. |
934 | 28.4k | |
935 | 28.4k | var subDecoder = self |
936 | 28.4k | subDecoder.groupFieldNumber = fieldNumber |
937 | 28.4k | // startGroup was read, so current tag/data is done (otherwise the |
938 | 28.4k | // startTag will end up in the unknowns of the first thing decoded). |
939 | 28.4k | subDecoder.consumed = true |
940 | 28.4k | // The group (message) doesn't get any existing unknown fields from |
941 | 28.4k | // the parent. |
942 | 28.4k | subDecoder.unknownData = nil |
943 | 28.4k | try group.decodeMessage(decoder: &subDecoder) |
944 | 27.5k | guard subDecoder.fieldNumber == fieldNumber && subDecoder.fieldWireFormat == .endGroup else { |
945 | 472 | throw BinaryDecodingError.truncated |
946 | 27.0k | } |
947 | 27.0k | if let groupUnknowns = subDecoder.unknownData { |
948 | 15.3k | group.unknownFields.append(protobufData: groupUnknowns) |
949 | 15.3k | } |
950 | 27.0k | // Advance over what was parsed. |
951 | 27.0k | consume(length: available - subDecoder.available) |
952 | 27.0k | assert(recursionBudget == subDecoder.recursionBudget) |
953 | 27.0k | decrementRecursionDepth() |
954 | 27.0k | return true |
955 | 66.8k | } |
956 | | |
957 | | internal mutating func decodeMapField<KeyType, ValueType: MapValueType>( |
958 | | fieldType: _ProtobufMap<KeyType, ValueType>.Type, |
959 | | value: inout _ProtobufMap<KeyType, ValueType>.BaseType |
960 | 1.12M | ) throws { |
961 | 1.12M | guard fieldWireFormat == WireFormat.lengthDelimited else { |
962 | 284k | return |
963 | 843k | } |
964 | 843k | var k: KeyType.BaseType? |
965 | 843k | var v: ValueType.BaseType? |
966 | 843k | var count: Int = 0 |
967 | 843k | let p = try getFieldBodyBytes(count: &count) |
968 | 842k | var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) |
969 | 7.10M | while let tag = try subdecoder.getTag() { |
970 | 7.10M | if tag.wireFormat == .endGroup { |
971 | 28 | throw BinaryDecodingError.malformedProtobuf |
972 | 7.10M | } |
973 | 7.10M | let fieldNumber = tag.fieldNumber |
974 | 7.10M | switch fieldNumber { |
975 | 7.10M | case 1: |
976 | 1.37M | try KeyType.decodeSingular(value: &k, from: &subdecoder) |
977 | 7.10M | case 2: |
978 | 3.27M | try ValueType.decodeSingular(value: &v, from: &subdecoder) |
979 | 7.10M | default: // Skip any other fields within the map entry object |
980 | 2.46M | try subdecoder.skip() |
981 | 7.10M | } |
982 | 7.10M | } |
983 | 841k | if !subdecoder.complete { |
984 | 0 | throw BinaryDecodingError.trailingGarbage |
985 | 841k | } |
986 | 841k | // A map<> definition can't provide a default value for the keys/values, |
987 | 841k | // so it is safe to use the proto3 default to get the right |
988 | 841k | // integer/string/bytes. The one catch is a proto2 enum (which can be the |
989 | 841k | // value) can have a non zero value, but that case is the next |
990 | 841k | // custom decodeMapField<>() method and handles it. |
991 | 1.08M | value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType.proto3DefaultValue |
992 | 841k | consumed = true |
993 | 841k | } |
994 | | |
995 | | internal mutating func decodeMapField<KeyType, ValueType>( |
996 | | fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type, |
997 | | value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType |
998 | 65.5k | ) throws where ValueType.RawValue == Int { |
999 | 65.5k | guard fieldWireFormat == WireFormat.lengthDelimited else { |
1000 | 16.4k | return |
1001 | 49.0k | } |
1002 | 49.0k | var k: KeyType.BaseType? |
1003 | 49.0k | var v: ValueType? |
1004 | 49.0k | var count: Int = 0 |
1005 | 49.0k | let p = try getFieldBodyBytes(count: &count) |
1006 | 48.6k | var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) |
1007 | 220k | while let tag = try subdecoder.getTag() { |
1008 | 220k | if tag.wireFormat == .endGroup { |
1009 | 16 | throw BinaryDecodingError.malformedProtobuf |
1010 | 220k | } |
1011 | 220k | let fieldNumber = tag.fieldNumber |
1012 | 220k | switch fieldNumber { |
1013 | 220k | case 1: // Keys are basic types |
1014 | 91.5k | try KeyType.decodeSingular(value: &k, from: &subdecoder) |
1015 | 220k | case 2: // Value is an Enum type |
1016 | 32.5k | try subdecoder.decodeSingularEnumField(value: &v) |
1017 | 32.5k | if v == nil && tag.wireFormat == .varint { |
1018 | 16.4k | // Enum decode fail and wire format was varint, so this had to |
1019 | 16.4k | // have been a proto2 unknown enum value. This whole map entry |
1020 | 16.4k | // into the parent message's unknown fields. If the wire format |
1021 | 16.4k | // was wrong, treat it like an unknown field and drop it with |
1022 | 16.4k | // the map entry. |
1023 | 16.4k | return |
1024 | 16.4k | } |
1025 | 220k | default: // Skip any other fields within the map entry object |
1026 | 96.4k | try subdecoder.skip() |
1027 | 220k | } |
1028 | 204k | } |
1029 | 31.7k | if !subdecoder.complete { |
1030 | 0 | throw BinaryDecodingError.trailingGarbage |
1031 | 31.7k | } |
1032 | 31.7k | // A map<> definition can't provide a default value for the keys, so it |
1033 | 31.7k | // is safe to use the proto3 default to get the right integer/string/bytes. |
1034 | 51.8k | value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType() |
1035 | 31.7k | consumed = true |
1036 | 31.7k | } |
1037 | | |
1038 | | internal mutating func decodeMapField<KeyType, ValueType>( |
1039 | | fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type, |
1040 | | value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType |
1041 | 156k | ) throws { |
1042 | 156k | guard fieldWireFormat == WireFormat.lengthDelimited else { |
1043 | 48.4k | return |
1044 | 107k | } |
1045 | 107k | var k: KeyType.BaseType? |
1046 | 107k | var v: ValueType? |
1047 | 107k | var count: Int = 0 |
1048 | 107k | let p = try getFieldBodyBytes(count: &count) |
1049 | 107k | var subdecoder = BinaryDecoder(forReadingFrom: p, count: count, parent: self) |
1050 | 1.08M | while let tag = try subdecoder.getTag() { |
1051 | 1.08M | if tag.wireFormat == .endGroup { |
1052 | 24 | throw BinaryDecodingError.malformedProtobuf |
1053 | 1.08M | } |
1054 | 1.08M | let fieldNumber = tag.fieldNumber |
1055 | 1.08M | switch fieldNumber { |
1056 | 1.08M | case 1: // Keys are basic types |
1057 | 236k | try KeyType.decodeSingular(value: &k, from: &subdecoder) |
1058 | 1.08M | case 2: // Value is a message type |
1059 | 599k | try subdecoder.decodeSingularMessageField(value: &v) |
1060 | 1.08M | default: // Skip any other fields within the map entry object |
1061 | 245k | try subdecoder.skip() |
1062 | 1.08M | } |
1063 | 1.08M | } |
1064 | 106k | if !subdecoder.complete { |
1065 | 0 | throw BinaryDecodingError.trailingGarbage |
1066 | 106k | } |
1067 | 106k | // A map<> definition can't provide a default value for the keys, so it |
1068 | 106k | // is safe to use the proto3 default to get the right integer/string/bytes. |
1069 | 136k | value[k ?? KeyType.proto3DefaultValue] = v ?? ValueType() |
1070 | 106k | consumed = true |
1071 | 106k | } |
1072 | | |
1073 | | internal mutating func decodeExtensionField( |
1074 | | values: inout ExtensionFieldValueSet, |
1075 | | messageType: any Message.Type, |
1076 | | fieldNumber: Int |
1077 | 2.92M | ) throws { |
1078 | 2.92M | if let ext = extensions?[messageType, fieldNumber] { |
1079 | 2.83M | try decodeExtensionField( |
1080 | 2.83M | values: &values, |
1081 | 2.83M | messageType: messageType, |
1082 | 2.83M | fieldNumber: fieldNumber, |
1083 | 2.83M | messageExtension: ext |
1084 | 2.83M | ) |
1085 | 2.91M | } |
1086 | 2.91M | } |
1087 | | |
1088 | | /// Helper to reuse between Extension decoding and MessageSet Extension decoding. |
1089 | | private mutating func decodeExtensionField( |
1090 | | values: inout ExtensionFieldValueSet, |
1091 | | messageType: any Message.Type, |
1092 | | fieldNumber: Int, |
1093 | | messageExtension ext: any AnyMessageExtension |
1094 | 3.25M | ) throws { |
1095 | 3.25M | assert(!consumed) |
1096 | 3.25M | assert(fieldNumber == ext.fieldNumber) |
1097 | 3.25M | |
1098 | 3.25M | try values.modify(index: fieldNumber) { fieldValue in |
1099 | 3.25M | // Message/Group extensions both will call back into the matching |
1100 | 3.25M | // decode methods, so the recursion depth will be tracked there. |
1101 | 3.25M | if fieldValue != nil { |
1102 | 2.70M | try fieldValue!.decodeExtensionField(decoder: &self) |
1103 | 2.70M | } else { |
1104 | 554k | fieldValue = try ext._protobuf_newField(decoder: &self) |
1105 | 3.25M | } |
1106 | 3.25M | if consumed && fieldValue == nil { |
1107 | 0 | // Really things should never get here, if the decoder says |
1108 | 0 | // the bytes were consumed, then there should have been a |
1109 | 0 | // field that consumed them (existing or created). This |
1110 | 0 | // specific error result is to allow this to be more detectable. |
1111 | 0 | throw BinaryDecodingError.internalExtensionError |
1112 | 3.25M | } |
1113 | 3.25M | } |
1114 | 3.25M | } |
1115 | | |
1116 | | internal mutating func decodeExtensionFieldsAsMessageSet( |
1117 | | values: inout ExtensionFieldValueSet, |
1118 | | messageType: any Message.Type |
1119 | 34.9k | ) throws { |
1120 | 34.9k | // Anything not in an acceptable form will go into unknown fields |
1121 | 579k | while let fieldNumber = try self.nextFieldNumber() { |
1122 | 579k | // Normal MessageSet wire format (nested in a group) |
1123 | 579k | if fieldNumber == WireFormat.MessageSet.FieldNumbers.item && fieldWireFormat == WireFormat.startGroup { |
1124 | 2.05k | // This is similar to decodeFullGroup |
1125 | 2.05k | |
1126 | 2.05k | try incrementRecursionDepth() |
1127 | 2.05k | var subDecoder = self |
1128 | 2.05k | subDecoder.groupFieldNumber = fieldNumber |
1129 | 2.05k | subDecoder.consumed = true |
1130 | 2.05k | |
1131 | 2.05k | let itemResult = try subDecoder.decodeMessageSetItem( |
1132 | 2.05k | values: &values, |
1133 | 2.05k | messageType: messageType |
1134 | 2.05k | ) |
1135 | 1.61k | switch itemResult { |
1136 | 1.61k | case .success: |
1137 | 1.35k | // Advance over what was parsed. |
1138 | 1.35k | consume(length: available - subDecoder.available) |
1139 | 1.35k | consumed = true |
1140 | 1.61k | case .handleAsUnknown: |
1141 | 225 | // Nothing to do. |
1142 | 225 | break |
1143 | 1.61k | |
1144 | 1.61k | case .malformed: |
1145 | 31 | throw BinaryDecodingError.malformedProtobuf |
1146 | 1.61k | } |
1147 | 1.58k | |
1148 | 1.65k | assert(recursionBudget == subDecoder.recursionBudget) |
1149 | 1.58k | decrementRecursionDepth() |
1150 | 577k | } else if fieldWireFormat == WireFormat.lengthDelimited, |
1151 | 579k | let ext = extensions?[messageType, fieldNumber] |
1152 | 579k | { |
1153 | 5.61k | // This was a raw extension field, this is possible if some encoder doesn't |
1154 | 5.61k | // know the MessageSet wire format. Since we know the extension, promote it. |
1155 | 5.61k | // _upb_Decoder_FindField() has this same basic logic. |
1156 | 5.61k | try decodeExtensionField( |
1157 | 5.61k | values: &values, |
1158 | 5.61k | messageType: messageType, |
1159 | 5.61k | fieldNumber: fieldNumber, |
1160 | 5.61k | messageExtension: ext |
1161 | 5.61k | ) |
1162 | 5.47k | if !consumed { |
1163 | 0 | throw BinaryDecodingError.malformedProtobuf |
1164 | 5.47k | } |
1165 | 579k | } |
1166 | 579k | } |
1167 | 33.9k | } |
1168 | | |
1169 | | private enum DecodeMessageSetItemResult { |
1170 | | case success |
1171 | | case handleAsUnknown |
1172 | | case malformed |
1173 | | } |
1174 | | |
1175 | | private mutating func decodeMessageSetItem( |
1176 | | values: inout ExtensionFieldValueSet, |
1177 | | messageType: any Message.Type |
1178 | 3.85k | ) throws -> DecodeMessageSetItemResult { |
1179 | 3.85k | // This is loosely based on the C++: |
1180 | 3.85k | // ExtensionSet::ParseMessageSetItem() |
1181 | 3.85k | // WireFormat::ParseAndMergeMessageSetItem() |
1182 | 3.85k | // And more implementation seem to draw from: |
1183 | 3.85k | // upb_Decoder_DecodeMessageSetItem() |
1184 | 3.85k | |
1185 | 3.85k | var msgExtension: (any AnyMessageExtension)? |
1186 | 3.85k | var fieldData: Data? |
1187 | 3.85k | var gotData: Bool = false |
1188 | 3.85k | |
1189 | 3.85k | // In this loop, if wire types are wrong, things don't decode, |
1190 | 3.85k | // just bail instead of letting things go into unknown fields. |
1191 | 3.85k | // Wrongly formed MessageSets don't seem don't have real |
1192 | 3.85k | // spelled out behaviors. |
1193 | 61.5k | while let fieldNumber = try self.nextFieldNumber() { |
1194 | 61.5k | switch fieldNumber { |
1195 | 61.5k | case WireFormat.MessageSet.FieldNumbers.typeId: |
1196 | 902 | var extensionFieldNumber: Int32 = 0 |
1197 | 902 | try decodeSingularInt32Field(value: &extensionFieldNumber) |
1198 | 877 | if extensionFieldNumber == 0 { return .malformed } |
1199 | 861 | if let _ = msgExtension { |
1200 | 0 | // The field appears more than once, only the first value counts. |
1201 | 0 | continue |
1202 | 861 | } |
1203 | 861 | guard let ext = extensions?[messageType, Int(extensionFieldNumber)] else { |
1204 | 861 | // At this point it is an unknown extension, so it will be treated as |
1205 | 861 | // an unknown field. |
1206 | 861 | // |
1207 | 861 | // NOTE: There are other repeated `type_id` or `message` fields within |
1208 | 861 | // the group they are preserved. No attempt is made to prune them down |
1209 | 861 | // to be conformant. |
1210 | 861 | return .handleAsUnknown |
1211 | 861 | } |
1212 | 0 | msgExtension = ext |
1213 | 0 |
|
1214 | 0 | // If there already was fieldData, decode it. |
1215 | 0 | if let data = fieldData { |
1216 | 0 | var wasDecoded = false |
1217 | 0 | try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in |
1218 | 0 | if let baseAddress = body.baseAddress, body.count > 0 { |
1219 | 0 | var extDecoder = BinaryDecoder( |
1220 | 0 | forReadingFrom: baseAddress, |
1221 | 0 | count: body.count, |
1222 | 0 | parent: self |
1223 | 0 | ) |
1224 | 0 | // Prime the decode to be correct. |
1225 | 0 | extDecoder.consumed = false |
1226 | 0 | extDecoder.fieldWireFormat = .lengthDelimited |
1227 | 0 | try extDecoder.decodeExtensionField( |
1228 | 0 | values: &values, |
1229 | 0 | messageType: messageType, |
1230 | 0 | fieldNumber: ext.fieldNumber, |
1231 | 0 | messageExtension: ext |
1232 | 0 | ) |
1233 | 0 | wasDecoded = extDecoder.consumed |
1234 | 0 | } |
1235 | 0 | } |
1236 | 0 | if !wasDecoded { |
1237 | 0 | return .malformed |
1238 | 0 | } |
1239 | 0 | fieldData = nil |
1240 | 0 | } |
1241 | 61.5k | |
1242 | 61.5k | case WireFormat.MessageSet.FieldNumbers.message: |
1243 | 1.74k | if gotData { |
1244 | 412 | // first one sticks, skip any additional occurances of the field. |
1245 | 412 | guard fieldWireFormat == .lengthDelimited else { return .malformed } |
1246 | 393 | try skip() |
1247 | 375 | consumed = true |
1248 | 375 | } else if let ext = msgExtension { |
1249 | 0 | assert(consumed == false) |
1250 | 0 | gotData = true |
1251 | 0 | try decodeExtensionField( |
1252 | 0 | values: &values, |
1253 | 0 | messageType: messageType, |
1254 | 0 | fieldNumber: ext.fieldNumber, |
1255 | 0 | messageExtension: ext |
1256 | 0 | ) |
1257 | 0 | if !consumed { |
1258 | 0 | return .malformed |
1259 | 0 | } |
1260 | 1.33k | } else { |
1261 | 1.33k | // Haven't gotten the type_id yet, to cache the data for later. |
1262 | 1.33k | assert(fieldData == .none) |
1263 | 1.33k | var d: Data? |
1264 | 1.33k | try decodeSingularBytesField(value: &d) |
1265 | 1.08k | guard let data = d else { return .malformed } |
1266 | 1.07k | // Save it as length delimited |
1267 | 1.07k | let payloadSize = Varint.encodedSize(of: Int64(data.count)) + data.count |
1268 | 1.07k | var payload = Data(count: payloadSize) |
1269 | 1.07k | payload.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in |
1270 | 1.07k | var encoder = BinaryEncoder(forWritingInto: body) |
1271 | 1.07k | encoder.putBytesValue(value: data) |
1272 | 1.07k | } |
1273 | 1.07k | fieldData = payload |
1274 | 1.07k | gotData = true |
1275 | 1.07k | } |
1276 | 61.5k | |
1277 | 61.5k | default: |
1278 | 58.9k | // Skip everything else |
1279 | 58.9k | try skip() |
1280 | 58.7k | consumed = true |
1281 | 61.5k | } |
1282 | 60.2k | } |
1283 | 2.38k | |
1284 | 2.38k | return .success |
1285 | 3.85k | } |
1286 | | |
1287 | | // |
1288 | | // Private building blocks for the parsing above. |
1289 | | // |
1290 | | // Having these be private gives the compiler maximum latitude for |
1291 | | // inlining. |
1292 | | // |
1293 | | |
1294 | | /// Private: Advance the current position. |
1295 | 40.8M | private mutating func consume(length: Int) { |
1296 | 40.8M | available -= length |
1297 | 40.8M | p += length |
1298 | 40.8M | } |
1299 | | |
1300 | | /// Private: Skip the body for the given tag. If the given tag is |
1301 | | /// a group, it parses up through the corresponding group end. |
1302 | 48.8M | private mutating func skipOver(tag: FieldTag) throws { |
1303 | 48.8M | switch tag.wireFormat { |
1304 | 48.8M | case .varint: |
1305 | 42.4M | // Don't need the value, just ensuring it is validly encoded. |
1306 | 42.4M | let _ = try decodeVarint() |
1307 | 48.8M | case .fixed64: |
1308 | 2.48M | if available < 8 { |
1309 | 16.5k | throw BinaryDecodingError.truncated |
1310 | 2.47M | } |
1311 | 2.47M | p += 8 |
1312 | 2.47M | available -= 8 |
1313 | 48.8M | case .lengthDelimited: |
1314 | 1.52M | let n = try decodeVarint() |
1315 | 1.52M | if n <= UInt64(available) { |
1316 | 1.45M | p += Int(n) |
1317 | 1.45M | available -= Int(n) |
1318 | 1.45M | } else { |
1319 | 67.0k | throw BinaryDecodingError.truncated |
1320 | 67.0k | } |
1321 | 48.8M | case .startGroup: |
1322 | 125k | try incrementRecursionDepth() |
1323 | 1.84M | while true { |
1324 | 1.84M | if let innerTag = try getTagWithoutUpdatingFieldStart() { |
1325 | 1.83M | if innerTag.wireFormat == .endGroup { |
1326 | 48.8k | if innerTag.fieldNumber == tag.fieldNumber { |
1327 | 46.3k | decrementRecursionDepth() |
1328 | 46.3k | break |
1329 | 46.3k | } else { |
1330 | 2.50k | // .endGroup for a something other than the current |
1331 | 2.50k | // group is an invalid binary. |
1332 | 2.50k | throw BinaryDecodingError.malformedProtobuf |
1333 | 2.50k | } |
1334 | 1.78M | } else { |
1335 | 1.78M | try skipOver(tag: innerTag) |
1336 | 1.72M | } |
1337 | 1.72M | } else { |
1338 | 2.63k | throw BinaryDecodingError.truncated |
1339 | 1.72M | } |
1340 | 1.72M | } |
1341 | 48.8M | case .endGroup: |
1342 | 0 | throw BinaryDecodingError.truncated |
1343 | 48.8M | case .fixed32: |
1344 | 2.24M | if available < 4 { |
1345 | 5.31k | throw BinaryDecodingError.truncated |
1346 | 2.24M | } |
1347 | 2.24M | p += 4 |
1348 | 2.24M | available -= 4 |
1349 | 48.8M | } |
1350 | 48.6M | } |
1351 | | |
1352 | | /// Private: Skip to the end of the current field. |
1353 | | /// |
1354 | | /// Assumes that fieldStartP was bookmarked by a previous |
1355 | | /// call to getTagType(). |
1356 | | /// |
1357 | | /// On exit, fieldStartP points to the first byte of the tag, fieldEndP points |
1358 | | /// to the first byte after the field contents, and p == fieldEndP. |
1359 | 47.0M | private mutating func skip() throws { |
1360 | 47.0M | if let end = fieldEndP { |
1361 | 0 | p = end |
1362 | 47.0M | } else { |
1363 | 47.0M | // Rewind to start of current field. |
1364 | 47.0M | available += p - fieldStartP |
1365 | 47.0M | p = fieldStartP |
1366 | 47.0M | guard let tag = try getTagWithoutUpdatingFieldStart() else { |
1367 | 0 | throw BinaryDecodingError.truncated |
1368 | 47.0M | } |
1369 | 47.0M | try skipOver(tag: tag) |
1370 | 46.9M | fieldEndP = p |
1371 | 46.9M | } |
1372 | 46.9M | } |
1373 | | |
1374 | | /// Private: Parse the next raw varint from the input. |
1375 | 268M | private mutating func decodeVarint() throws -> UInt64 { |
1376 | 268M | if available < 1 { |
1377 | 32.2k | throw BinaryDecodingError.truncated |
1378 | 268M | } |
1379 | 268M | var start = p |
1380 | 268M | var length = available |
1381 | 268M | var c = start.load(fromByteOffset: 0, as: UInt8.self) |
1382 | 268M | start += 1 |
1383 | 268M | length &-= 1 |
1384 | 268M | if c & 0x80 == 0 { |
1385 | 259M | p = start |
1386 | 259M | available = length |
1387 | 259M | return UInt64(c) |
1388 | 259M | } |
1389 | 9.55M | var value = UInt64(c & 0x7f) |
1390 | 9.55M | var shift = UInt64(7) |
1391 | 11.4M | while true { |
1392 | 11.4M | if length < 1 || shift > 63 { |
1393 | 6.99k | throw BinaryDecodingError.malformedProtobuf |
1394 | 11.4M | } |
1395 | 11.4M | c = start.load(fromByteOffset: 0, as: UInt8.self) |
1396 | 11.4M | start += 1 |
1397 | 11.4M | length &-= 1 |
1398 | 11.4M | value |= UInt64(c & 0x7f) &<< shift |
1399 | 11.4M | if c & 0x80 == 0 { |
1400 | 9.54M | p = start |
1401 | 9.54M | available = length |
1402 | 9.54M | return value |
1403 | 9.54M | } |
1404 | 1.91M | shift &+= 7 |
1405 | 1.91M | } |
1406 | 0 | } |
1407 | | |
1408 | | /// Private: Get the tag that starts a new field. |
1409 | | /// This also bookmarks the start of field for a possible skip(). |
1410 | 76.2M | internal mutating func getTag() throws -> FieldTag? { |
1411 | 76.2M | fieldStartP = p |
1412 | 76.2M | fieldEndP = nil |
1413 | 76.2M | return try getTagWithoutUpdatingFieldStart() |
1414 | 76.2M | } |
1415 | | |
1416 | | /// Private: Parse and validate the next tag without |
1417 | | /// bookmarking the start of the field. This is used within |
1418 | | /// skip() to skip over fields within a group. |
1419 | 226M | private mutating func getTagWithoutUpdatingFieldStart() throws -> FieldTag? { |
1420 | 226M | if available < 1 { |
1421 | 4.51M | return nil |
1422 | 221M | } |
1423 | 221M | let t = try decodeVarint() |
1424 | 221M | if t < UInt64(UInt32.max) { |
1425 | 221M | guard let tag = FieldTag(rawValue: UInt32(truncatingIfNeeded: t)) else { |
1426 | 18.5k | throw BinaryDecodingError.malformedProtobuf |
1427 | 221M | } |
1428 | 221M | fieldWireFormat = tag.wireFormat |
1429 | 221M | fieldNumber = tag.fieldNumber |
1430 | 221M | return tag |
1431 | 221M | } else { |
1432 | 3.90k | throw BinaryDecodingError.malformedProtobuf |
1433 | 3.90k | } |
1434 | 221M | } |
1435 | | |
1436 | | /// Private: Return a Data containing the entirety of |
1437 | | /// the current field, including tag. |
1438 | 39.0M | private mutating func getRawField() throws -> Data { |
1439 | 39.0M | try skip() |
1440 | 39.0M | return Data(bytes: fieldStartP, count: fieldEndP! - fieldStartP) |
1441 | 39.0M | } |
1442 | | |
1443 | | /// Private: decode a fixed-length number. |
1444 | 24.6M | private mutating func decodeLittleEndianInteger<T: FixedWidthInteger>() throws -> T { |
1445 | 24.6M | let size = MemoryLayout<T>.size |
1446 | 24.6M | assert(size == 4 || size == 8) |
1447 | 24.6M | guard available >= size else { throw BinaryDecodingError.truncated } |
1448 | 24.6M | defer { consume(length: size) } |
1449 | 24.6M | return T(littleEndian: p.loadUnaligned(as: T.self)) |
1450 | 24.6M | } |
1451 | | |
1452 | 1.39M | private mutating func decodeFloat() throws -> Float { |
1453 | 1.39M | let nativeEndianBytes: UInt32 = try decodeLittleEndianInteger() |
1454 | 1.39M | return Float(bitPattern: nativeEndianBytes) |
1455 | 1.39M | } |
1456 | | |
1457 | 825k | private mutating func decodeDouble() throws -> Double { |
1458 | 825k | let nativeEndianBytes: UInt64 = try decodeLittleEndianInteger() |
1459 | 825k | return Double(bitPattern: nativeEndianBytes) |
1460 | 825k | } |
1461 | | |
1462 | | /// Private: Get the start and length for the body of |
1463 | | /// a length-delimited field. |
1464 | 16.1M | private mutating func getFieldBodyBytes(count: inout Int) throws -> UnsafeRawPointer { |
1465 | 16.1M | let length = try decodeVarint() |
1466 | 16.1M | |
1467 | 16.1M | // Bytes and Strings have a max size of 2GB. And since messages are on |
1468 | 16.1M | // the wire as bytes/length delimited, they also have a 2GB size limit. |
1469 | 16.1M | // The upstream C++ does the same sort of enforcement (see |
1470 | 16.1M | // parse_context, delimited_message_util, message_lite, etc.). |
1471 | 16.1M | // https://protobuf.dev/programming-guides/encoding/#cheat-sheet |
1472 | 16.1M | // |
1473 | 16.1M | // This function does get called in some package decode handling, but |
1474 | 16.1M | // that is length delimited on the wire, so the spec would imply |
1475 | 16.1M | // the limit still applies. |
1476 | 16.1M | guard length < 0x7fff_ffff else { |
1477 | 13.6k | // Reuse existing error to avoid breaking change of changing thrown error |
1478 | 13.6k | throw BinaryDecodingError.malformedProtobuf |
1479 | 16.1M | } |
1480 | 16.1M | |
1481 | 16.1M | guard length <= UInt64(available) else { |
1482 | 21.1k | throw BinaryDecodingError.truncated |
1483 | 16.0M | } |
1484 | 16.0M | |
1485 | 16.0M | count = Int(length) |
1486 | 16.0M | let body = p |
1487 | 16.0M | consume(length: count) |
1488 | 16.0M | return body |
1489 | 16.1M | } |
1490 | | } |