Skip to content

Commit

Permalink
Support "-nan" in TextFormat.
Browse files Browse the repository at this point in the history
As odd as it sounds, upstream supports this and there is a unittest that
ensure it parses:

https://github.com/protocolbuffers/protobuf/blob/3c03e9351c57081d0dffae120ed37497017f105c/src/google/protobuf/compiler/parser_unittest.cc#L464

It seems to have come from:

protocolbuffers/protobuf#15017

So make sure Swift is also able to parse it.
  • Loading branch information
thomasvl committed May 9, 2024
1 parent a1ce4a0 commit 664524c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 3 deletions.
16 changes: 13 additions & 3 deletions Sources/SwiftProtobuf/TextFormatScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,18 @@ internal struct TextFormatScanner {

// If the next token is the identifier "nan", return true.
private mutating func skipOptionalNaN() -> Bool {
return skipOptionalKeyword(bytes:
[asciiLowerN, asciiLowerA, asciiLowerN])
let start = p
// "-nan" doesn't mean anything, but upstream handles it, so skip
// over any leading minus when checking for "nan".
if p != end && p[0] == asciiMinus {
p += 1
}
if skipOptionalKeyword(bytes: [asciiLowerN, asciiLowerA, asciiLowerN]) {
return true
} else {
p = start // It wasn't "nan", rewind incase we skipped a minus sign.
return false
}
}

// If the next token is a recognized spelling of "infinity",
Expand Down Expand Up @@ -1311,7 +1321,7 @@ internal struct TextFormatScanner {
}
}

// This will also cover "true", "false" for booleans, "nan" for floats.
// This will also cover "true", "false" for booleans, "nan"/"inf" for floats.
if let _ = try nextOptionalEnumName() {
skipWhitespace() // `nextOptionalEnumName()` doesn't skip trailing whitespace
return
Expand Down
2 changes: 2 additions & 0 deletions Sources/protoc-gen-swift/Descriptor+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,15 @@ extension FieldDescriptor {
case "inf": return "Double.infinity"
case "-inf": return "-Double.infinity"
case "nan": return "Double.nan"
case "-nan": return "Double.nan"
default: return defaultValue
}
case .float:
switch defaultValue {
case "inf": return "Float.infinity"
case "-inf": return "-Float.infinity"
case "nan": return "Float.nan"
case "-nan": return "Float.nan"
default: return defaultValue
}
case .string:
Expand Down
5 changes: 5 additions & 0 deletions Tests/SwiftProtobufTests/Test_TextFormatDecodingOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,13 @@ final class Test_TextFormatDecodingOptions: XCTestCase {
assertDecodeIgnoringUnknownsSucceeds("double", "-1e-9999")

assertDecodeIgnoringUnknownsSucceeds("float", "nan")
assertDecodeIgnoringUnknownsSucceeds("float", "-nan")
assertDecodeIgnoringUnknownsSucceeds("float", "inf")
assertDecodeIgnoringUnknownsSucceeds("float", "-inf")
assertDecodeIgnoringUnknownsSucceeds("double", "nan")
assertDecodeIgnoringUnknownsSucceeds("double", "-nan")
assertDecodeIgnoringUnknownsSucceeds("double", "inf")
assertDecodeIgnoringUnknownsSucceeds("double", "-inf")
}

func testIgnoreUnknown_Messages() {
Expand Down

0 comments on commit 664524c

Please sign in to comment.