Skip to content

Commit 71f8020

Browse files
committed
[AlamofireBackend] Fix a critical issue about multipart data form encoding
1 parent 795b057 commit 71f8020

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

Sources/Backends/AlamofireBackend.swift

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,7 @@ public class AlamofireBackend: Backend {
124124
self.manager.upload(request,
125125
multipartFormData: {
126126
multipartFormData in
127-
for (key, value) in endpoint.parameters {
128-
if let value = value as? AlamofireMultipartFormDataEncodable {
129-
value.encode(toAlamofireMultipartFormData: multipartFormData, forName: key)
130-
} else {
131-
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name: key)
132-
}
133-
}
127+
self.encodeMultipartFormData(to: multipartFormData, parameters: endpoint.parameters)
134128
},
135129
encodingMemoryThreshold: self.multipartFormDataEncodingMemoryThreshold,
136130
encodingCompletion: {
@@ -201,6 +195,51 @@ public class AlamofireBackend: Backend {
201195
return (request, AlamofireBackendError.errorWithCode(.UnsupportParameterEncoding, failureReason: "\(parameterEncoding) can't encode by Alamofire's ParameterEncoding."))
202196
}
203197
}
198+
199+
private func encodeMultipartFormData(to multipartFormData: Alamofire.MultipartFormData, parameters: [String: AnyObject]) {
200+
var components: [(String, AnyObject)] = []
201+
202+
for key in parameters.keys.sort(<) {
203+
let value = parameters[key]!
204+
components += self.flattenQueryComponents(key, value)
205+
}
206+
207+
for (key, value) in components {
208+
switch value {
209+
case let value as AlamofireMultipartFormDataEncodable:
210+
value.encode(toAlamofireMultipartFormData: multipartFormData, forName: key)
211+
case let value as String:
212+
let data = self.escape(value).dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
213+
multipartFormData.appendBodyPart(data: data, name: key)
214+
default:
215+
continue
216+
}
217+
}
218+
}
219+
220+
private func flattenQueryComponents(key: String, _ value: AnyObject) -> [(String, AnyObject)] {
221+
var components: [(String, AnyObject)] = []
222+
223+
if let dictionary = value as? [String: AnyObject] {
224+
for (nestedKey, value) in dictionary {
225+
components += flattenQueryComponents("\(key)[\(nestedKey)]", value)
226+
}
227+
} else if let array = value as? [AnyObject] {
228+
for value in array {
229+
components += flattenQueryComponents("\(key)[]", value)
230+
}
231+
} else if let placeholder = value as? AlamofireMultipartFormDataEncodable {
232+
components.append((escape(key), placeholder))
233+
} else {
234+
components.append((escape(key), escape("\(value)")))
235+
}
236+
237+
return components
238+
}
239+
240+
private func escape(string: String) -> String {
241+
return Alamofire.ParameterEncoding.URL.escape(string)
242+
}
204243
}
205244

206245
public struct AlamofireBackendError {

0 commit comments

Comments
 (0)