Skip to content

Commit bc27f86

Browse files
committed
review comments
1 parent acdaae0 commit bc27f86

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

Sources/OpenAPIRuntime/Base/Base64EncodedData.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,35 @@
1515
import Foundation
1616

1717
public struct Base64EncodedData: Sendable, Codable, Hashable {
18-
var data: Foundation.Data // or [UInt8] or ArraySlice<UInt8>
18+
var data: ArraySlice<UInt8>
1919

20-
public init(data: Foundation.Data) {
20+
public init(data: ArraySlice<UInt8>) {
2121
self.data = data
2222
}
2323

2424
public init(from decoder: any Decoder) throws {
2525
let container = try decoder.singleValueContainer()
2626
let base64EncodedString = try container.decode(String.self)
27-
guard let data = Data(base64Encoded: base64EncodedString) else {
27+
28+
// permissive decoding
29+
let options = Data.Base64DecodingOptions.ignoreUnknownCharacters
30+
31+
guard let data = Data(base64Encoded: base64EncodedString, options: options) else {
2832
throw RuntimeError.invalidBase64String(base64EncodedString)
2933
}
30-
self.init(data: data)
34+
self.init(data: ArraySlice(data))
3135
}
3236

3337
public func encode(to encoder: any Encoder) throws {
3438
var container = encoder.singleValueContainer()
35-
let base64String = data.base64EncodedString()
39+
40+
// https://datatracker.ietf.org/doc/html/rfc4648#section-3.1
41+
// "Implementations MUST NOT add line feeds to base-encoded data unless
42+
// the specification referring to this document explicitly directs base
43+
// encoders to add line feeds after a specific number of characters."
44+
let options = Data.Base64EncodingOptions()
45+
46+
let base64String = Data(data).base64EncodedString(options: options)
3647
try container.encode(base64String)
3748
}
3849
}

Tests/OpenAPIRuntimeTests/Base/Test_OpenAPIValue.swift

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,27 @@ final class Test_OpenAPIValue: Test_Runtime {
267267
XCTAssertEqual(nestedValue, 2)
268268
}
269269

270-
func testEncodingDecodingRoundTrip_base64_success() throws {
271-
print(String(data: testStructData.base64EncodedData(), encoding: .utf8)!.utf8)
272-
let encodedData = Base64EncodedData(data: testStructData)
270+
func testEncoding_base64_success() throws {
271+
let encodedData = Base64EncodedData(data: ArraySlice(testStructData))
272+
273+
let JSONEncoded = try JSONEncoder().encode(encodedData)
274+
XCTAssertEqual(String(data: JSONEncoded, encoding: .utf8)!, testStructBase64EncodedString)
275+
}
276+
277+
func testDecoding_base64_success() throws {
278+
let encodedData = Base64EncodedData(data: ArraySlice(testStructData))
279+
280+
// `testStructBase64EncodedString` quoted and base64-encoded again
281+
let JSONEncoded = Data(base64Encoded: "ImV5SnVZVzFsSWpvaVJteDFabVo2SW4wPSI=")!
282+
283+
XCTAssertEqual(
284+
try JSONDecoder().decode(Base64EncodedData.self, from: JSONEncoded),
285+
encodedData
286+
)
287+
}
288+
289+
func testEncodingDecodingRoundtrip_base64_success() throws {
290+
let encodedData = Base64EncodedData(data: ArraySlice(testStructData))
273291
XCTAssertEqual(
274292
try JSONDecoder().decode(Base64EncodedData.self, from: JSONEncoder().encode(encodedData)),
275293
encodedData

Tests/OpenAPIRuntimeTests/Test_Runtime.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class Test_Runtime: XCTestCase {
107107
"age=3&name=Rover%21&type=Golden+Retriever"
108108
}
109109

110+
var testStructBase64EncodedString: String {
111+
#""eyJuYW1lIjoiRmx1ZmZ6In0=""# // {"name":"Fluffz"}
112+
}
113+
110114
var testEnum: TestHabitat {
111115
.water
112116
}

0 commit comments

Comments
 (0)