Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: crash when converting infinite values to JSON string #66

Merged
merged 4 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ extension UserDefaults: UserDefaultsBehaviour {
self.globalAttributes = globalAttributes
return self
}

public func withInitialGlobalAttributesObjc(_ globalAttributes: NSDictionary) -> ClickstreamConfiguration {
self.globalAttributes = ClickstreamObjc.getAttributes(globalAttributes)
return self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ enum Event {
static let ATTRIBUTE_NAME_INVALID = 2_002
static let ATTRIBUTE_VALUE_LENGTH_EXCEED = 2_003
static let ATTRIBUTE_SIZE_EXCEED = 2_004
static let ATTRIBUTE_VALUE_NOT_FINITE = 2_005
zhu-xiaowei marked this conversation as resolved.
Show resolved Hide resolved
static let USER_ATTRIBUTE_SIZE_EXCEED = 3_001
static let USER_ATTRIBUTE_NAME_LENGTH_EXCEED = 3_002
static let USER_ATTRIBUTE_NAME_INVALID = 3_003
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,35 @@ class EventChecker {
error.errorCode = Event.ErrorCode.ATTRIBUTE_VALUE_LENGTH_EXCEED
error.errorMessage = getErrorMessage(errorString)
}
} else if !checkFinite(value) {
errorMsg = """
the value for attribute : \(key), is not finite\
and the attribute will not be recorded
"""
let errorString = "the value for attribute name: \(key) is not finite"
zhu-xiaowei marked this conversation as resolved.
Show resolved Hide resolved
error.errorCode = Event.ErrorCode.ATTRIBUTE_VALUE_NOT_FINITE
error.errorMessage = getErrorMessage(errorString)
}
if errorMsg != nil {
log.warn(errorMsg!)
}
return error
}

/// Check the Dboule or Decimal whether is finite
/// - Parameters:
/// - value: attribute value
/// - Returns: the isFinite boolean result
static func checkFinite(_ value: Any) -> Bool {
if let value = value as? Double, !value.isFinite {
return false
}
if let value = value as? Decimal, !value.isFinite {
return false
}
return true
}

/// Check the user attribute error.
/// - Parameters:
/// - currentNumber: current attribute number
Expand Down
18 changes: 18 additions & 0 deletions Tests/ClickstreamTests/Clickstream/ClickstreamEventTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ class ClickstreamEventTest: XCTestCase {
XCTAssertTrue(errorValueString.contains("testKey"))
}

func testAddAttributeErrorForDoubleValueisNotFinite() {
clickstreamEvent.addAttribute(Double.infinity, forKey: "testKey")
XCTAssertNil(clickstreamEvent.attribute(forKey: "testKey"))
let errorCode = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_CODE) as! Int
let errorValueString = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_MESSAGE) as! String
XCTAssertEqual(Event.ErrorCode.ATTRIBUTE_VALUE_NOT_FINITE, errorCode)
XCTAssertTrue(errorValueString.contains("testKey"))
}

func testAddAttributeErrorForDecimalValueisNotFinite() {
clickstreamEvent.addAttribute(Decimal.nan, forKey: "testKey")
XCTAssertNil(clickstreamEvent.attribute(forKey: "testKey"))
let errorCode = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_CODE) as! Int
let errorValueString = clickstreamEvent.attribute(forKey: Event.ReservedAttribute.ERROR_MESSAGE) as! String
XCTAssertEqual(Event.ErrorCode.ATTRIBUTE_VALUE_NOT_FINITE, errorCode)
XCTAssertTrue(errorValueString.contains("testKey"))
}

func testAddItemWithCustomAttributeScuccess() {
let item: ClickstreamAttribute = [
ClickstreamAnalytics.Item.ITEM_ID: 123,
Expand Down
24 changes: 24 additions & 0 deletions Tests/ClickstreamTests/EventCheckerTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,28 @@ class EventCheckerTest: XCTestCase {
XCTAssertFalse(EventChecker.checkEventType(eventType: "9Abc").errorCode == noError)
XCTAssertTrue(EventChecker.checkEventType(eventType: "A9bc").errorCode == noError)
}

func testDoubleIsFinite() {
XCTAssertTrue(EventChecker.checkFinite(123.31))
XCTAssertTrue(EventChecker.checkFinite(355 / 113.0))
XCTAssertTrue(EventChecker.checkFinite(0))
XCTAssertTrue(EventChecker.checkFinite(Double.pi))
XCTAssertTrue(EventChecker.checkFinite(Double.leastNormalMagnitude))
XCTAssertTrue(EventChecker.checkFinite(Double.leastNonzeroMagnitude))
XCTAssertTrue(EventChecker.checkFinite(Double.ulpOfOne))
XCTAssertFalse(EventChecker.checkFinite(Double.nan))
XCTAssertFalse(EventChecker.checkFinite(Double.infinity))
XCTAssertFalse(EventChecker.checkFinite(-Double.infinity))
XCTAssertFalse(EventChecker.checkFinite(Double.signalingNaN))
}

func testDecimalIsFinite() {
XCTAssertTrue(EventChecker.checkFinite(Decimal.pi))
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastNormalMagnitude))
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastNonzeroMagnitude))
XCTAssertTrue(EventChecker.checkFinite(Decimal.greatestFiniteMagnitude))
XCTAssertTrue(EventChecker.checkFinite(Decimal.leastFiniteMagnitude))
XCTAssertFalse(EventChecker.checkFinite(Decimal.nan))
XCTAssertFalse(EventChecker.checkFinite(Decimal.quietNaN))
}
}
Loading