Skip to content

Commit

Permalink
Fix: URLEncodedFormDecoder ignores empty value when decoding Array (v…
Browse files Browse the repository at this point in the history
…apor#2584)

* Add test case

* Don't omit empty string when parsing unindexed array

* Refactor unindexed array parsing

* Reduce closure usage

Co-authored-by: Tim Condon <[email protected]>
  • Loading branch information
t-ae and 0xTim authored Mar 31, 2021
1 parent 9195a38 commit 73d5795
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
17 changes: 8 additions & 9 deletions Sources/Vapor/URLEncodedForm/URLEncodedFormDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,17 +286,16 @@ private struct _Decoder: Decoder {
if let valuesInBracket = data.children[""] {
values = values + valuesInBracket.values
}

// parse out any character separated array values
for explodeArraysOn in configuration.arraySeparators {
var explodedValues: [URLQueryFragment] = []
for value in values {
explodedValues = try explodedValues + value.asUrlEncoded().split(separator: explodeArraysOn).map({ (ss: Substring) -> URLQueryFragment in
return .urlEncoded(String(ss))
})
}
values = explodedValues
self.values = try values.flatMap { value in
try value.asUrlEncoded()
.split(omittingEmptySubsequences: false,
whereSeparator: configuration.arraySeparators.contains)
.map { (ss: Substring) in
URLQueryFragment.urlEncoded(String(ss))
}
}
self.values = values
}
}

Expand Down
21 changes: 19 additions & 2 deletions Tests/VaporTests/URLEncodedFormTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,28 @@ final class URLEncodedFormTests: XCTestCase {
}

let data = """
array[0]=a&array[1]=b
array[0]=a&array[1]=&array[2]=b&array[3]=
"""
let test = try URLEncodedFormDecoder().decode(Test.self, from: data)
XCTAssertEqual(test.array[0], "a")
XCTAssertEqual(test.array[1], "b")
XCTAssertEqual(test.array[1], "")
XCTAssertEqual(test.array[2], "b")
XCTAssertEqual(test.array[3], "")
}

func testDecodeUnindexedArray() throws {
struct Test: Decodable {
let array: [String]
}

let data = """
array[]=a&array[]=&array[]=b&array[]=
"""
let test = try URLEncodedFormDecoder().decode(Test.self, from: data)
XCTAssertEqual(test.array[0], "a")
XCTAssertEqual(test.array[1], "")
XCTAssertEqual(test.array[2], "b")
XCTAssertEqual(test.array[3], "")
}

func testDecodeIndexedArray_dictionary() throws {
Expand Down

0 comments on commit 73d5795

Please sign in to comment.