Skip to content

Commit

Permalink
fix: crash when converting invalid JSON object (#68)
Browse files Browse the repository at this point in the history
Co-authored-by: xiaoweii <[email protected]>
  • Loading branch information
zhu-xiaowei and xiaoweii authored Jun 4, 2024
1 parent be5d15c commit 890b347
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class EventRecorder: AnalyticsEventRecording {
func save(_ event: ClickstreamEvent) throws {
let eventObject = event.toJsonObject()
let eventJson = eventObject.toJsonString()
if eventJson == "" { return }
let eventSize = eventJson.count
let storageEvent = StorageEvent(eventJson: eventJson, eventSize: Int64(eventSize))
try dbUtil.saveEvent(storageEvent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import Foundation

extension JsonObject {
func toJsonString() -> String {
if !JSONSerialization.isValidJSONObject(self) {
log.error("Invalid JSON object: \(self)")
return ""
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.sortedKeys])
return String(data: jsonData, encoding: .utf8) ?? ""
} catch {
print("Error serializing dictionary to JSON: \(error.localizedDescription)")
log.error("Error serializing dictionary to JSON: \(error.localizedDescription)")
}
return ""
}
Expand All @@ -23,8 +27,10 @@ extension JsonObject {
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.sortedKeys, .prettyPrinted])
return String(data: jsonData, encoding: .utf8) ?? ""
} catch {
print("Error serializing dictionary to JSON: \(error.localizedDescription)")
log.error("Error serializing dictionary to JSON: \(error.localizedDescription)")
}
return ""
}
}

extension JsonObject: ClickstreamLogger {}
6 changes: 6 additions & 0 deletions Tests/ClickstreamTests/Clickstream/EventRecorderTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ class EventRecorderTest: XCTestCase {
XCTAssertEqual("carl", (userAttributes["_user_name"] as! JsonObject)["value"] as! String)
}

func testRecordEventWithInvalidAttribute() throws {
clickstreamEvent.addGlobalAttribute(Decimal.nan, forKey: "invalidDecimal")
try eventRecorder.save(clickstreamEvent)
XCTAssertEqual(0, try dbUtil.getEventCount())
}

func testSaveMultiEvent() throws {
for _ in 0 ..< 5 {
try eventRecorder.save(clickstreamEvent)
Expand Down
46 changes: 46 additions & 0 deletions Tests/ClickstreamTests/Util/ToJsonStringUtilTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

@testable import Clickstream
import XCTest

class ToJsonStringUtilTest: XCTestCase {
func testNullObjectToJsonString() {
let attr: JsonObject = [
"user": {}
]
XCTAssertTrue(attr.toJsonString() == "")
}

func testNSObjectToJsonString() {
let attr: JsonObject = [
"user": NSObject()
]
XCTAssertTrue(attr.toJsonString() == "")
}

func testNanObjectToJsonString() {
let attr: JsonObject = [
"doubleKey": Double.nan
]
XCTAssertTrue(attr.toJsonString() == "")
}

func testInfiniteObjectToJsonString() {
let attr: JsonObject = [
"doubleKey": Double.infinity
]
XCTAssertTrue(attr.toJsonString() == "")
}

func testDateObjectToJsonString() {
let attr: JsonObject = [
"dateKey": Date()
]
XCTAssertTrue(attr.toJsonString() == "")
}
}

0 comments on commit 890b347

Please sign in to comment.