Skip to content

Commit b482bb7

Browse files
authored
Fix for decoding closed ranges (#543)
1 parent 300dbd1 commit b482bb7

File tree

2 files changed

+46
-46
lines changed

2 files changed

+46
-46
lines changed

Sources/Hummingbird/Codable/URLEncodedForm/URLEncodedFormDecoder.swift

+34-46
Original file line numberDiff line numberDiff line change
@@ -276,102 +276,87 @@ private class _URLEncodedFormDecoder: Decoder {
276276
self.currentIndex = 0
277277
}
278278

279+
mutating func decodeNextNode<T: Decodable>(as: T.Type = T.self) throws -> T {
280+
guard !self.isAtEnd else {
281+
throw DecodingError.valueNotFound(
282+
T.self,
283+
.init(codingPath: self.codingPath, debugDescription: "Unkeyed container index out of range")
284+
)
285+
}
286+
let node = self.container.values[self.currentIndex]
287+
self.currentIndex += 1
288+
return try self.decoder.unbox(node, as: T.self)
289+
}
290+
279291
mutating func decodeNil() throws -> Bool {
280292
let node = self.container.values[self.currentIndex]
281293
return try self.decoder.unboxNil(node)
282294
}
283295

284296
mutating func decode(_: Bool.Type) throws -> Bool {
285-
let node = self.container.values[self.currentIndex]
286-
self.currentIndex += 1
287-
return try self.decoder.unbox(node, as: Bool.self)
297+
try self.decodeNextNode()
288298
}
289299

290300
mutating func decode(_: String.Type) throws -> String {
291-
let node = self.container.values[self.currentIndex]
292-
self.currentIndex += 1
293-
return try self.decoder.unbox(node, as: String.self)
301+
try self.decodeNextNode()
294302
}
295303

296304
mutating func decode(_: Double.Type) throws -> Double {
297-
let node = self.container.values[self.currentIndex]
298-
self.currentIndex += 1
299-
return try self.decoder.unbox(node, as: Double.self)
305+
try self.decodeNextNode()
300306
}
301307

302308
mutating func decode(_: Float.Type) throws -> Float {
303-
let node = self.container.values[self.currentIndex]
304-
self.currentIndex += 1
305-
return try self.decoder.unbox(node, as: Float.self)
309+
try self.decodeNextNode()
306310
}
307311

308312
mutating func decode(_: Int.Type) throws -> Int {
309-
let node = self.container.values[self.currentIndex]
310-
self.currentIndex += 1
311-
return try self.decoder.unbox(node, as: Int.self)
313+
try self.decodeNextNode()
312314
}
313315

314316
mutating func decode(_: Int8.Type) throws -> Int8 {
315-
let node = self.container.values[self.currentIndex]
316-
self.currentIndex += 1
317-
return try self.decoder.unbox(node, as: Int8.self)
317+
try self.decodeNextNode()
318318
}
319319

320320
mutating func decode(_: Int16.Type) throws -> Int16 {
321-
let node = self.container.values[self.currentIndex]
322-
self.currentIndex += 1
323-
return try self.decoder.unbox(node, as: Int16.self)
321+
try self.decodeNextNode()
324322
}
325323

326324
mutating func decode(_: Int32.Type) throws -> Int32 {
327-
let node = self.container.values[self.currentIndex]
328-
self.currentIndex += 1
329-
return try self.decoder.unbox(node, as: Int32.self)
325+
try self.decodeNextNode()
330326
}
331327

332328
mutating func decode(_: Int64.Type) throws -> Int64 {
333-
let node = self.container.values[self.currentIndex]
334-
self.currentIndex += 1
335-
return try self.decoder.unbox(node, as: Int64.self)
329+
try self.decodeNextNode()
336330
}
337331

338332
mutating func decode(_: UInt.Type) throws -> UInt {
339-
let node = self.container.values[self.currentIndex]
340-
self.currentIndex += 1
341-
return try self.decoder.unbox(node, as: UInt.self)
333+
try self.decodeNextNode()
342334
}
343335

344336
mutating func decode(_: UInt8.Type) throws -> UInt8 {
345-
let node = self.container.values[self.currentIndex]
346-
self.currentIndex += 1
347-
return try self.decoder.unbox(node, as: UInt8.self)
337+
try self.decodeNextNode()
348338
}
349339

350340
mutating func decode(_: UInt16.Type) throws -> UInt16 {
351-
let node = self.container.values[self.currentIndex]
352-
self.currentIndex += 1
353-
return try self.decoder.unbox(node, as: UInt16.self)
341+
try self.decodeNextNode()
354342
}
355343

356344
mutating func decode(_: UInt32.Type) throws -> UInt32 {
357-
let node = self.container.values[self.currentIndex]
358-
self.currentIndex += 1
359-
return try self.decoder.unbox(node, as: UInt32.self)
345+
try self.decodeNextNode()
360346
}
361347

362348
mutating func decode(_: UInt64.Type) throws -> UInt64 {
363-
let node = self.container.values[self.currentIndex]
364-
self.currentIndex += 1
365-
return try self.decoder.unbox(node, as: UInt64.self)
349+
try self.decodeNextNode()
366350
}
367351

368352
mutating func decode<T>(_: T.Type) throws -> T where T: Decodable {
369-
let node = self.container.values[self.currentIndex]
370-
self.currentIndex += 1
371-
return try self.decoder.unbox(node, as: T.self)
353+
try self.decodeNextNode()
372354
}
373355

374356
mutating func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey {
357+
guard !self.isAtEnd else {
358+
throw DecodingError.dataCorrupted(.init(codingPath: self.codingPath, debugDescription: "Unkeyed container index out of range"))
359+
}
375360
let node = container.values[self.currentIndex]
376361
self.currentIndex += 1
377362
guard case .map(let map) = node else {
@@ -382,10 +367,13 @@ private class _URLEncodedFormDecoder: Decoder {
382367
}
383368

384369
mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer {
370+
guard !self.isAtEnd else {
371+
throw DecodingError.dataCorrupted(.init(codingPath: self.codingPath, debugDescription: "Unkeyed container index out of range"))
372+
}
385373
let node = self.container.values[self.currentIndex]
386374
self.currentIndex += 1
387375
guard case .array(let array) = node else {
388-
throw DecodingError.dataCorrupted(.init(codingPath: self.codingPath, debugDescription: "Expected a dictionary"))
376+
throw DecodingError.dataCorrupted(.init(codingPath: self.codingPath, debugDescription: "Expected an array"))
389377
}
390378
return UKDC(container: array, decoder: self.decoder)
391379
}

Tests/HummingbirdTests/URLEncodedForm/URLDecoderTests.swift

+12
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@ class URLDecodedFormDecoderTests: XCTestCase {
155155
self.testForm(test, query: "a=VGVzdGluZw%3D%3D")
156156
}
157157

158+
func testIndexOutOfRange() {
159+
struct Test: Codable, Equatable {
160+
let a: ClosedRange<Int>
161+
}
162+
XCTAssertThrowsError(try URLEncodedFormDecoder().decode(Test.self, from: "a[]=4")) { error in
163+
if case DecodingError.valueNotFound = error {
164+
} else {
165+
XCTFail("\(error)")
166+
}
167+
}
168+
}
169+
158170
func testNestedKeyDecode() {
159171
struct Test: Decodable, Equatable {
160172
let forename: String

0 commit comments

Comments
 (0)