Skip to content

Commit ccc0cc7

Browse files
committed
Validate length before turning into an Int.
1 parent 2ad9bad commit ccc0cc7

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

Sources/SwiftProtobufCore/BinaryDelimited.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public enum BinaryDelimited {
2828
/// While reading/writing to the stream, less than the expected bytes was
2929
/// read/written.
3030
case truncated
31+
32+
/// When decoding (parsing), the length is larger than what will fit in
33+
/// an Int for the compiled platform, so the message can't be parsed.
34+
case decodeTooLarge
3135
}
3236

3337
/// Serialize a single size-delimited message from the given stream. Delimited
@@ -155,12 +159,17 @@ public enum BinaryDelimited {
155159
partial: Bool = false,
156160
options: BinaryDecodingOptions = BinaryDecodingOptions()
157161
) throws {
158-
let length = try Int(decodeVarint(stream))
159-
if length == 0 {
162+
let unsignedLength = try decodeVarint(stream)
163+
if unsignedLength == 0 {
160164
// The message was all defaults, nothing to actually read.
161165
return
162166
}
163-
167+
guard unsignedLength <= Int.max else {
168+
// Due to the trip through an Array below, it has to fit, and Array uses
169+
// Int (signed) for Count.
170+
throw BinaryDelimited.Error.decodeTooLarge
171+
}
172+
let length = Int(unsignedLength)
164173
var data: [UInt8] = Array(repeating: 0, count: length)
165174
var bytesRead: Int = 0
166175
data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in

0 commit comments

Comments
 (0)