Skip to content

Commit 4384644

Browse files
committed
Support field separators on the last field of a message field.
https://protobuf.dev/reference/protobuf/textformat-spec/#fields calls out that `MessageField` and `ScalarField` both can be followed by a separator (`,` or `;`). https://protobuf.dev/reference/protobuf/textformat-spec/#message then replies on this to handle the separators within a message field. The existing parsing was accepting separators after all fields for top level fields, but when the decoder was for a message field (i.e. - there is a terminator stop at), it wouldn't properly the final separator followed by terminator correctly.
1 parent 2bbade0 commit 4384644

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

Sources/SwiftProtobuf/TextFormatDecoder.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,24 @@ internal struct TextFormatDecoder: Decoder {
6363
}
6464

6565
mutating func nextFieldNumber() throws -> Int? {
66-
if let terminator = terminator {
67-
if scanner.skipOptionalObjectEnd(terminator) {
68-
return nil
69-
}
70-
}
66+
// Per https://protobuf.dev/reference/protobuf/textformat-spec/#fields, every field can be
67+
// followed by a field separator, so if we've seen a field, remove the separator before
68+
// checking for the terminator.
7169
if fieldCount > 0 {
7270
scanner.skipOptionalSeparator()
7371
}
72+
if let terminator = terminator,
73+
scanner.skipOptionalObjectEnd(terminator) {
74+
return nil
75+
}
7476
if let fieldNumber = try scanner.nextFieldNumber(names: fieldNameMap!, messageType: messageType) {
7577
fieldCount += 1
7678
return fieldNumber
7779
} else if terminator == nil {
7880
return nil
7981
} else {
82+
// If this decoder is looking for at a terminator, then if the scanner failed to
83+
// find a field number, something went wrong (end of stream).
8084
throw TextFormatDecodingError.truncated
8185
}
8286

Tests/SwiftProtobufTests/Test_TextFormat_proto3.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,12 @@ final class Test_TextFormat_proto3: XCTestCase, PBTestHelpers {
12981298
assertTextFormatDecodeSucceeds("optional_int32:1;\n") {(o: MessageTestType) in
12991299
return o.optionalInt32 == 1
13001300
}
1301+
assertTextFormatDecodeSucceeds("optional_nested_message {bb:3,},") {(o: MessageTestType) in
1302+
return o.optionalNestedMessage.bb == 3
1303+
}
1304+
assertTextFormatDecodeSucceeds("optional_nested_message {bb:7;};") {(o: MessageTestType) in
1305+
return o.optionalNestedMessage.bb == 7
1306+
}
13011307
}
13021308

13031309
//

0 commit comments

Comments
 (0)