Skip to content

Commit 08328aa

Browse files
tbkkathomasvl
authored andcommitted
Fix ordering bug in MessageSet parsing
MessageSet encodes protobuf groups each containing an extension ID and a payload. According to standard protobuf conventions, these two fields can occur in either order within the group. Add two tests that check decoding of each possible order and fix the bug that this uncovers.
1 parent d36b824 commit 08328aa

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

Sources/SwiftProtobuf/BinaryDecoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ internal struct BinaryDecoder: Decoder {
12131213
extDecoder.fieldWireFormat = .lengthDelimited
12141214
try extDecoder.decodeExtensionField(values: &values,
12151215
messageType: messageType,
1216-
fieldNumber: fieldNumber,
1216+
fieldNumber: ext.fieldNumber,
12171217
messageExtension: ext)
12181218
wasDecoded = extDecoder.consumed
12191219
}

Tests/SwiftProtobufTests/Test_MessageSet.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,44 @@ final class Test_MessageSet: XCTestCase {
144144
"}\n"
145145
)
146146

147+
func testParseOrder1() throws {
148+
let serialized = Data([11,
149+
16, 176, 166, 94, // Extension ID
150+
26, 2, 120, 123, // Payload message
151+
12])
152+
153+
let msg: SwiftProtoTesting_WireFormat_TestMessageSet
154+
do {
155+
msg = try SwiftProtoTesting_WireFormat_TestMessageSet(
156+
serializedBytes: serialized,
157+
extensions: SwiftProtoTesting_UnittestMset_Extensions)
158+
} catch let e {
159+
XCTFail("Failed to parse: \(e)")
160+
return
161+
}
162+
XCTAssertEqual(
163+
msg.SwiftProtoTesting_TestMessageSetExtension1_messageSetExtension.i, 123)
164+
}
165+
166+
func testParseOrder2() throws {
167+
let serialized = Data([11,
168+
26, 2, 120, 123, // Payload message
169+
16, 176, 166, 94, // Extension ID
170+
12])
171+
172+
let msg: SwiftProtoTesting_WireFormat_TestMessageSet
173+
do {
174+
msg = try SwiftProtoTesting_WireFormat_TestMessageSet(
175+
serializedBytes: serialized,
176+
extensions: SwiftProtoTesting_UnittestMset_Extensions)
177+
} catch let e {
178+
XCTFail("Failed to parse: \(e)")
179+
return
180+
}
181+
XCTAssertEqual(
182+
msg.SwiftProtoTesting_TestMessageSetExtension1_messageSetExtension.i, 123)
183+
}
184+
147185
// text_format_unittest.cc: TEST_F(TextFormatMessageSetTest, Serialize)
148186
func testTextFormat_Serialize() {
149187
let msg = SwiftProtoTesting_TestMessageSetContainer.with {

0 commit comments

Comments
 (0)