Skip to content

Commit 1e91c07

Browse files
zhu-xiaoweixiaoweii
and
xiaoweii
authored
fix: crash when converting infinite values to JSON string (#66)
Co-authored-by: xiaoweii <[email protected]>
1 parent d302585 commit 1e91c07

File tree

5 files changed

+66
-1
lines changed

5 files changed

+66
-1
lines changed

Sources/Clickstream/Dependency/Clickstream/ClickstreamContext.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ extension UserDefaults: UserDefaultsBehaviour {
124124
self.globalAttributes = globalAttributes
125125
return self
126126
}
127-
127+
128128
public func withInitialGlobalAttributesObjc(_ globalAttributes: NSDictionary) -> ClickstreamConfiguration {
129129
self.globalAttributes = ClickstreamObjc.getAttributes(globalAttributes)
130130
return self

Sources/Clickstream/Dependency/Clickstream/Event/Event.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum Event {
9393
static let ATTRIBUTE_NAME_INVALID = 2_002
9494
static let ATTRIBUTE_VALUE_LENGTH_EXCEED = 2_003
9595
static let ATTRIBUTE_SIZE_EXCEED = 2_004
96+
static let ATTRIBUTE_VALUE_INFINITE = 2_005
9697
static let USER_ATTRIBUTE_SIZE_EXCEED = 3_001
9798
static let USER_ATTRIBUTE_NAME_LENGTH_EXCEED = 3_002
9899
static let USER_ATTRIBUTE_NAME_INVALID = 3_003

Sources/Clickstream/Dependency/Clickstream/Event/EventChecker.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,35 @@ class EventChecker {
8282
error.errorCode = Event.ErrorCode.ATTRIBUTE_VALUE_LENGTH_EXCEED
8383
error.errorMessage = getErrorMessage(errorString)
8484
}
85+
} else if !checkFinite(value) {
86+
errorMsg = """
87+
the value for attribute : \(key), is infinite\
88+
and the attribute will not be recorded
89+
"""
90+
let errorString = "the value for attribute name: \(key) is infinite"
91+
error.errorCode = Event.ErrorCode.ATTRIBUTE_VALUE_INFINITE
92+
error.errorMessage = getErrorMessage(errorString)
8593
}
8694
if errorMsg != nil {
8795
log.warn(errorMsg!)
8896
}
8997
return error
9098
}
9199

100+
/// Check the Dboule or Decimal whether is finite
101+
/// - Parameters:
102+
/// - value: attribute value
103+
/// - Returns: the isFinite boolean result
104+
static func checkFinite(_ value: Any) -> Bool {
105+
if let value = value as? Double, !value.isFinite {
106+
return false
107+
}
108+
if let value = value as? Decimal, !value.isFinite {
109+
return false
110+
}
111+
return true
112+
}
113+
92114
/// Check the user attribute error.
93115
/// - Parameters:
94116
/// - currentNumber: current attribute number

Tests/ClickstreamTests/Clickstream/ClickstreamEventTest.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,24 @@ class ClickstreamEventTest: XCTestCase {
6363
XCTAssertTrue(errorValueString.contains("testKey"))
6464
}
6565

66+
func testAddAttributeErrorForDoubleValueisNotFinite() {
67+
clickstreamEvent.addAttribute(Double.infinity, forKey: "testKey")
68+
XCTAssertNil(clickstreamEvent.attribute(forKey: "testKey"))
69+
let errorCode = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_CODE) as! Int
70+
let errorValueString = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_MESSAGE) as! String
71+
XCTAssertEqual(Event.ErrorCode.ATTRIBUTE_VALUE_INFINITE, errorCode)
72+
XCTAssertTrue(errorValueString.contains("testKey"))
73+
}
74+
75+
func testAddAttributeErrorForDecimalValueisNotFinite() {
76+
clickstreamEvent.addAttribute(Decimal.nan, forKey: "testKey")
77+
XCTAssertNil(clickstreamEvent.attribute(forKey: "testKey"))
78+
let errorCode = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_CODE) as! Int
79+
let errorValueString = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_MESSAGE) as! String
80+
XCTAssertEqual(Event.ErrorCode.ATTRIBUTE_VALUE_INFINITE, errorCode)
81+
XCTAssertTrue(errorValueString.contains("testKey"))
82+
}
83+
6684
func testAddItemWithCustomAttributeScuccess() {
6785
let item: ClickstreamAttribute = [
6886
ClickstreamAnalytics.Item.ITEM_ID: 123,

Tests/ClickstreamTests/EventCheckerTest.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,28 @@ class EventCheckerTest: XCTestCase {
2525
XCTAssertFalse(EventChecker.checkEventType(eventType: "9Abc").errorCode == noError)
2626
XCTAssertTrue(EventChecker.checkEventType(eventType: "A9bc").errorCode == noError)
2727
}
28+
29+
func testDoubleIsFinite() {
30+
XCTAssertTrue(EventChecker.checkFinite(123.31))
31+
XCTAssertTrue(EventChecker.checkFinite(355 / 113.0))
32+
XCTAssertTrue(EventChecker.checkFinite(0))
33+
XCTAssertTrue(EventChecker.checkFinite(Double.pi))
34+
XCTAssertTrue(EventChecker.checkFinite(Double.leastNormalMagnitude))
35+
XCTAssertTrue(EventChecker.checkFinite(Double.leastNonzeroMagnitude))
36+
XCTAssertTrue(EventChecker.checkFinite(Double.ulpOfOne))
37+
XCTAssertFalse(EventChecker.checkFinite(Double.nan))
38+
XCTAssertFalse(EventChecker.checkFinite(Double.infinity))
39+
XCTAssertFalse(EventChecker.checkFinite(-Double.infinity))
40+
XCTAssertFalse(EventChecker.checkFinite(Double.signalingNaN))
41+
}
42+
43+
func testDecimalIsFinite() {
44+
XCTAssertTrue(EventChecker.checkFinite(Decimal.pi))
45+
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastNormalMagnitude))
46+
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastNonzeroMagnitude))
47+
XCTAssertTrue(EventChecker.checkFinite(Decimal.greatestFiniteMagnitude))
48+
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastFiniteMagnitude))
49+
XCTAssertFalse(EventChecker.checkFinite(Decimal.nan))
50+
XCTAssertFalse(EventChecker.checkFinite(Decimal.quietNaN))
51+
}
2852
}

0 commit comments

Comments
 (0)