Skip to content

Commit 2d7fed2

Browse files
committed
Guard float token boundaries
1 parent e5bcc61 commit 2d7fed2

2 files changed

Lines changed: 32 additions & 12 deletions

File tree

Sources/TOMLDecoder/Parsing/Parser.swift

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,28 +1164,34 @@ extension Token {
11641164
resultCodeUnits.append(bytes[index])
11651165
index += 1
11661166
}
1167+
guard index < text.upperBound else {
1168+
throw TOMLError(.invalidFloat(context: context, lineNumber: lineNumber, reason: "expected digit, nan or inf after sign"))
1169+
}
11671170

11681171
if !bytes[index].isDecimalDigit {
1169-
guard (
1170-
bytes[index] == CodeUnits.lowerN &&
1171-
bytes[index + 1] == CodeUnits.lowerA &&
1172-
bytes[index + 2] == CodeUnits.lowerN
1173-
) ||
1174-
(
1175-
bytes[index] == CodeUnits.lowerI &&
1176-
bytes[index + 1] == CodeUnits.lowerN &&
1177-
bytes[index + 2] == CodeUnits.lowerF
1178-
)
1172+
let nameEnd = index + 3
1173+
guard nameEnd == text.upperBound,
1174+
(
1175+
bytes[index] == CodeUnits.lowerN &&
1176+
bytes[index + 1] == CodeUnits.lowerA &&
1177+
bytes[index + 2] == CodeUnits.lowerN
1178+
) ||
1179+
(
1180+
bytes[index] == CodeUnits.lowerI &&
1181+
bytes[index + 1] == CodeUnits.lowerN &&
1182+
bytes[index + 2] == CodeUnits.lowerF
1183+
)
11791184
else {
11801185
throw TOMLError(.invalidFloat(context: context, lineNumber: lineNumber, reason: "Expected nan or inf, found \(bytes[index])"))
11811186
}
11821187
resultCodeUnits.append(bytes[index])
11831188
resultCodeUnits.append(bytes[index + 1])
11841189
resultCodeUnits.append(bytes[index + 2])
11851190
} else {
1191+
let nextIndex = index + 1
11861192
if bytes[index] == CodeUnits.number0,
1187-
index < text.upperBound,
1188-
case let next = bytes[index + 1],
1193+
nextIndex < text.upperBound,
1194+
case let next = bytes[nextIndex],
11891195
next != CodeUnits.dot, next != CodeUnits.lowerE, next != CodeUnits.upperE
11901196
{
11911197
throw TOMLError(.invalidFloat(context: context, lineNumber: lineNumber, reason: "Float begins with 0 must be followed by a '.', 'e' or 'E'"))

Tests/TOMLDecoderTests/TOMLTableKeyMembershipTests.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,18 @@ struct TOMLTableKeyMembershipTests {
5959
_ = try Dictionary(TOMLTable(source: "x = 0x\n"))
6060
}
6161
}
62+
63+
@Test
64+
func singleZeroFloatAccessorDecodesWithoutTrapping() throws {
65+
let table = try TOMLTable(source: "s = 0\n")
66+
67+
#expect(try table.float(forKey: "s") == 0)
68+
}
69+
70+
@Test(arguments: ["x = +\n", "x = n\n", "x = na\n", "x = i\n", "x = in\n"])
71+
func truncatedFloatThrowsWithoutTrapping(toml: String) throws {
72+
#expect(throws: TOMLError.self) {
73+
_ = try Dictionary(TOMLTable(source: toml))
74+
}
75+
}
6276
}

0 commit comments

Comments
 (0)