Skip to content

Fix for [SR-1250] NSJSONSerialization emits non-floating-point number… #914

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

Merged
merged 1 commit into from
Mar 20, 2017

Conversation

saiHemak
Copy link
Contributor

@saiHemak saiHemak commented Mar 9, 2017

JSON serialization behaves differently on Linux.

eg : Serializing
let subject = "[12.1,10.0,0.0]"

on Darwin gives - 12.1,10,0
where as on Linux - 12.1,10.0,0.0 //.0 needs to be truncated

This fix aligns the JSONSerialization.jsonObject(with: data) behavior to Darwin.

@alblue
Copy link
Contributor

alblue commented Mar 9, 2017

@swift-ci please test

@alblue
Copy link
Contributor

alblue commented Mar 9, 2017

Wouldn't this change impact existing code, which would assume that such numbers are doubles? Does this behaviour also exist on Darwin platforms?

@saiHemak
Copy link
Contributor Author

saiHemak commented Mar 9, 2017

@alblue : Yeah ..That's what I observed on Darwin ..I updated the description with details.In my fix am just converting to int when I am sure that the double value returned by strtod and the rounded values are equal .I have tested with different inputs and could see the output with fix is same as we observe on Darwin version.

@parkera
Copy link
Contributor

parkera commented Mar 9, 2017

This is all tied up in the same discussion about what the proper role of NSNumber is in Swift (cc @phausler), but in the meantime it looks reasonable to me.

@saiHemak saiHemak force-pushed the nsjson-serialization branch from 0423af9 to 8a1bd9a Compare March 10, 2017 05:32
}
guard doubleDistance > 0 else {
return nil
if doubleResult == roundedDouble || doubleResult == 0.0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the second half of this if statement necessary? Shouldn't this be if doubleResult == doubleResult.rounded()?

guard intDistance > 0 || doubleDistance > 0 else {
return nil
}

if intDistance == doubleDistance {
Copy link
Contributor

@xwu xwu Mar 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing these lines seems suspect. First, intResult is now unused. Second--more importantly--there are values of Int that cannot be exactly represented in Double (those above 2^53), which is why intResult isn't totally redundant given Int(doubleResult). Was there a reason why you removed these lines?

You will almost certainly want the second guard statement below before proceeding to use doubleResult.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xwu Thanks for the review. I agree with you .I have missed to test with huge integers and thought that it would be redundant .We need to retain the intResult too and added the check to handle of rounded doubles . I have modified the fix now ..

@@ -468,7 +468,7 @@ extension TestNSJSONSerialization {
XCTAssertEqual(result?[1] as? Int, -1)
XCTAssertEqual(result?[2] as? Double, 1.3)
XCTAssertEqual(result?[3] as? Double, -1.3)
XCTAssertEqual(result?[4] as? Double, 1000)
XCTAssertEqual(result?[4] as? Int, 1000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please follow file convention and align 1000 with the line above.

do {
let data = decimalArray.data(using: String.Encoding.utf8)
let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [Any]
XCTAssertEqual(result?[0] as! Double,12.1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can you put a space after the comma here and on subsequent lines?

}
}

fileprivate func createTestFile(_ path: String,_contents: Data) -> String? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please restore the original indent of four spaces and not three here.

let intResult = strtol(startPointer, intEndPointer, 10)
let intDistance = startPointer.distance(to: intEndPointer[0]!)
let doubleResult = strtod(startPointer, doubleEndPointer)
let doubleDistance = startPointer.distance(to: doubleEndPointer[0]!)

let roundedDouble = doubleResult.rounded()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At minimum, this is best moved after the guard doubleDistance > 0 statement that should be restored below. As mentioned earlier, you may not need to have this line at all.

@saiHemak saiHemak force-pushed the nsjson-serialization branch from 8a1bd9a to 3f6938f Compare March 15, 2017 07:49
@pushkarnk
Copy link
Member

@swift-ci please test

@saiHemak saiHemak force-pushed the nsjson-serialization branch from 3f6938f to eb8fa91 Compare March 20, 2017 12:18
@saiHemak saiHemak force-pushed the nsjson-serialization branch from eb8fa91 to b8f0af1 Compare March 20, 2017 12:21
@saiHemak
Copy link
Contributor Author

@phausler Please review

@phausler
Copy link
Contributor

This seems reasonable, but for compatability it is worth noting that NSNumbers returned are a bit strange in Swift.

let n = NSNumber(value: 4.3)
if n is Int {
    // this is true as of the current build of Swift on Darwin... which imho seems a bit incorrect.
}

@phausler phausler merged commit ba5134d into swiftlang:master Mar 20, 2017
@saiHemak saiHemak deleted the nsjson-serialization branch July 20, 2017 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants