Skip to content

Commit 890b347

Browse files
zhu-xiaoweixiaoweii
and
xiaoweii
authored
fix: crash when converting invalid JSON object (#68)
Co-authored-by: xiaoweii <[email protected]>
1 parent be5d15c commit 890b347

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

Sources/Clickstream/Dependency/Clickstream/Analytics/EventRecorder.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class EventRecorder: AnalyticsEventRecording {
4545
func save(_ event: ClickstreamEvent) throws {
4646
let eventObject = event.toJsonObject()
4747
let eventJson = eventObject.toJsonString()
48+
if eventJson == "" { return }
4849
let eventSize = eventJson.count
4950
let storageEvent = StorageEvent(eventJson: eventJson, eventSize: Int64(eventSize))
5051
try dbUtil.saveEvent(storageEvent)

Sources/Clickstream/Support/Extension/JsonObject+ToJsonString.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@ import Foundation
99

1010
extension JsonObject {
1111
func toJsonString() -> String {
12+
if !JSONSerialization.isValidJSONObject(self) {
13+
log.error("Invalid JSON object: \(self)")
14+
return ""
15+
}
1216
do {
1317
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.sortedKeys])
1418
return String(data: jsonData, encoding: .utf8) ?? ""
1519
} catch {
16-
print("Error serializing dictionary to JSON: \(error.localizedDescription)")
20+
log.error("Error serializing dictionary to JSON: \(error.localizedDescription)")
1721
}
1822
return ""
1923
}
@@ -23,8 +27,10 @@ extension JsonObject {
2327
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.sortedKeys, .prettyPrinted])
2428
return String(data: jsonData, encoding: .utf8) ?? ""
2529
} catch {
26-
print("Error serializing dictionary to JSON: \(error.localizedDescription)")
30+
log.error("Error serializing dictionary to JSON: \(error.localizedDescription)")
2731
}
2832
return ""
2933
}
3034
}
35+
36+
extension JsonObject: ClickstreamLogger {}

Tests/ClickstreamTests/Clickstream/EventRecorderTest.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ class EventRecorderTest: XCTestCase {
183183
XCTAssertEqual("carl", (userAttributes["_user_name"] as! JsonObject)["value"] as! String)
184184
}
185185

186+
func testRecordEventWithInvalidAttribute() throws {
187+
clickstreamEvent.addGlobalAttribute(Decimal.nan, forKey: "invalidDecimal")
188+
try eventRecorder.save(clickstreamEvent)
189+
XCTAssertEqual(0, try dbUtil.getEventCount())
190+
}
191+
186192
func testSaveMultiEvent() throws {
187193
for _ in 0 ..< 5 {
188194
try eventRecorder.save(clickstreamEvent)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
@testable import Clickstream
9+
import XCTest
10+
11+
class ToJsonStringUtilTest: XCTestCase {
12+
func testNullObjectToJsonString() {
13+
let attr: JsonObject = [
14+
"user": {}
15+
]
16+
XCTAssertTrue(attr.toJsonString() == "")
17+
}
18+
19+
func testNSObjectToJsonString() {
20+
let attr: JsonObject = [
21+
"user": NSObject()
22+
]
23+
XCTAssertTrue(attr.toJsonString() == "")
24+
}
25+
26+
func testNanObjectToJsonString() {
27+
let attr: JsonObject = [
28+
"doubleKey": Double.nan
29+
]
30+
XCTAssertTrue(attr.toJsonString() == "")
31+
}
32+
33+
func testInfiniteObjectToJsonString() {
34+
let attr: JsonObject = [
35+
"doubleKey": Double.infinity
36+
]
37+
XCTAssertTrue(attr.toJsonString() == "")
38+
}
39+
40+
func testDateObjectToJsonString() {
41+
let attr: JsonObject = [
42+
"dateKey": Date()
43+
]
44+
XCTAssertTrue(attr.toJsonString() == "")
45+
}
46+
}

0 commit comments

Comments
 (0)