Skip to content

Commit a65ed3f

Browse files
committed
Do not use force unwrapping for RawRepresentable mapping
Those are very dangerous to a case: if a server side send an enum value which is not defined at the client side, then the client will suddenly crash.
1 parent acbe4b1 commit a65ed3f

3 files changed

Lines changed: 36 additions & 29 deletions

File tree

‎ObjectMapper/Core/FromJSON.swift‎

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ internal final class FromJSON {
3131

3232
/// Raw representable
3333
class func rawRepresentable<N: RawRepresentable>(inout field: N, object: N.RawValue?) {
34-
if let value = object {
35-
field = N(rawValue: value)!
34+
if let value = object, enumValue = N(rawValue: value) {
35+
field = enumValue
3636
}
3737
}
3838

@@ -53,57 +53,42 @@ internal final class FromJSON {
5353
/// Array of Raw representable
5454
class func rawRepresentableArray<N: RawRepresentable>(inout field: [N], object: [N.RawValue]?) {
5555
if let values = object {
56-
field = values.map { (v: N.RawValue) in N(rawValue: v)! }
56+
field = values.filterMap { N(rawValue: $0) }
5757
}
5858
}
5959

6060
/// Array of Raw representable
6161
class func rawRepresentableArray<N: RawRepresentable>(inout field: [N]?, object: [N.RawValue]?) {
6262
if let values = object {
63-
field = values.map { (v: N.RawValue) in N(rawValue: v)! }
63+
field = values.filterMap { N(rawValue: $0) }
6464
}
6565
}
6666

6767
/// Array of Raw representable
6868
class func rawRepresentableArray<N: RawRepresentable>(inout field: [N]!, object: [N.RawValue]?) {
6969
if let values = object {
70-
field = values.map { (v: N.RawValue) in N(rawValue: v)! }
70+
field = values.filterMap { N(rawValue: $0) }
7171
}
7272
}
7373

7474
/// Dictionary of Raw representable
7575
class func rawRepresentableDict<N: RawRepresentable>(inout field: [String: N], object: [String: N.RawValue]?) {
7676
if let values = object {
77-
field = map(values) { (k: String, v: N.RawValue) in (k, N(rawValue: v)!) }
78-
.reduce([:]) { (var d, e) in
79-
let (k, v) = e
80-
d[k] = v
81-
return d
82-
}
77+
field = values.filterMap { N(rawValue: $0) }
8378
}
8479
}
8580

8681
/// Dictionary of Raw representable
8782
class func rawRepresentableDict<N: RawRepresentable>(inout field: [String: N]?, object: [String: N.RawValue]?) {
8883
if let values = object {
89-
field = map(values) { (k: String, v: N.RawValue) in (k, N(rawValue: v)!) }
90-
.reduce([:]) { (var d, e) in
91-
var (k, v) = e
92-
d?[k] = v
93-
return d
94-
}
84+
field = values.filterMap { N(rawValue: $0) }
9585
}
9686
}
9787

9888
/// Dictionary of Raw representable
9989
class func rawRepresentableDict<N: RawRepresentable>(inout field: [String: N]!, object: [String: N.RawValue]?) {
10090
if let values = object {
101-
field = map(values) { (k: String, v: N.RawValue) in (k, N(rawValue: v)!) }
102-
.reduce([:]) { (var d, e) in
103-
let (k, v) = e
104-
d[k] = v
105-
return d
106-
}
91+
field = values.filterMap { N(rawValue: $0) }
10792
}
10893
}
10994

‎ObjectMapper/Core/Mapper.swift‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,22 @@ public final class Mapper<N: Mappable> {
352352
}
353353
}
354354

355+
extension Array {
356+
internal func filterMap<U>(@noescape f: T -> U?) -> [U] {
357+
var mapped = [U]()
358+
359+
for value in self {
360+
if let newValue = f(value) {
361+
mapped.append(newValue)
362+
}
363+
}
364+
365+
return mapped
366+
}
367+
}
368+
355369
extension Dictionary {
356-
private func map<K: Hashable, V>(f: Element -> (K, V)) -> [K : V] {
370+
internal func map<K: Hashable, V>(@noescape f: Element -> (K, V)) -> [K : V] {
357371
var mapped = [K : V]()
358372

359373
for element in self {
@@ -363,4 +377,15 @@ extension Dictionary {
363377

364378
return mapped
365379
}
380+
381+
internal func filterMap<U>(@noescape f: Value -> U?) -> [Key : U] {
382+
var mapped = [Key : U]()
383+
384+
for (key, value) in self {
385+
let newValue = f(value)
386+
mapped[key] = newValue
387+
}
388+
389+
return mapped
390+
}
366391
}

‎ObjectMapper/Core/ToJSON.swift‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,8 @@ internal final class ToJSON {
120120
}
121121

122122
class func rawRepresentableDict<N: RawRepresentable>(field: [String: N], key: String, inout dictionary: [String : AnyObject]) {
123-
let raw: [String: N.RawValue] = map(field) { (k, v) in (k, v.rawValue) }
124-
.reduce([:]) { (var d, e) in
125-
let (k, v) = e
126-
d[k] = v
127-
return d
123+
let raw: [String: N.RawValue] = field.map { key, value in
124+
return (key, value.rawValue)
128125
}
129126
basicType(raw, key: key, dictionary: &dictionary)
130127
}

0 commit comments

Comments
 (0)