-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Large integers do not work #157
Comments
@stleary I'm not sure this should be closed yet. It could be considered a bug under the same assumptions you made in #126 (comment) If this was in a shop, it would probably be flagged as a bug and fixed. The actual JSON is specifying an INT value, but the conversion from a JSON-String to a JSONObject is not seeing it as such. |
I don't think the JSON spec requires an implementation to maintain any particular level of numeric support, but agree that it is not optimal to be inconsistent, My recollection from the code fix was that this particular result fell under the requirement not to inconvenience users by changing existing behavior. Is there a particular use case that you think might override this requirement? |
While I can see the problem of backward compatibility, I think it intolerable that you cannot make an identical copy of a JSONObject by using Here's a full example:
I also agree that JSON does not require a particular level of numeric support, but since this implementation does support BigDecimal it should do so in a consistent way. If any current usage of the library relies on the fact that { x: 123..lotsofdigits... } returns a string while { x: 123...notsomanydigits...} returns a Number object ... I would consider such usage broken and my guess is that more people will be affected by the inconsistent handling |
I'd prefer that { x: 123...321} always returned a Number object rather than a String, regardless of how big that number is. |
@effad, So far as I can tell, the API makes no representation that the JSONObject(String) ctor and toString() are reversible. Are you saying the library should be required to have this behavior? The big numbers enhancement came with a requirement to absolutely guarantee existing apps are not impacted. I don't think our use case can be that their apps were pre-broken anyway, or at least I would not feel comfortable taking that position. |
My pull request doesn't fix the double rounding issues that currently exist, it only extends the range of doubles so that if converting a valid decimal value to double would cause NaN or +-Infinity to be returned, it returns a BigDecimal instead. It does however fix the BigInteger problem so that all values of large integers are stored correctly. You could make the argument that the API should store all numeric values as either BigDecimal or BigInteger. The get/opt methods are already doing the conversions on the fly: /**
* Get the long value associated with a key.
*
* @param key
* A key string.
* @return The long value.
* @throws JSONException
* if the key is not found or if the value cannot be converted
* to a long.
*/
public long getLong(String key) throws JSONException {
Object object = this.get(key);
try {
return object instanceof Number ? ((Number) object).longValue()
: Long.parseLong((String) object);
} catch (Exception e) {
throw new JSONException("JSONObject[" + quote(key)
+ "] is not a long.");
}
} |
@stleary the JSON spec states that {x:123456789123456789123456789} is a number. If the API converts it to a string, then the API is not following the JSON spec. I'd say this is a bug, and anyone relying on this functionality now is doing so as a workaround to this bug. |
If we do fix this though, we should be very clear in the release notes about this fix, and that it could break existing code. |
The JSON spec allows implementations to put reasonable limits on things. Is this actually a bug, or are you just staying so? |
Thanks, I missed that in the RFC, I was going off the flow chart @ http://json.org. I found the note though:
|
although, in this issues defense, http://json.org, nor this projects README references the RFC that I pulled the text from. JSON.org references ECMA-404 The JSON Data Interchange Standard I propose that if we do not fix this, then we note in the ReadMe what the limitation on integer and double values are as well as link to the RFC : https://tools.ietf.org/html/rfc7159 |
While there is nothing in RFC-4627 that prevents a parser to transform JSON input into whatever it wants to I find the current state of affairs extremely misleading. On the one hand the library suggests it supports BigDecimal while on the other hand it does not and does so in a silent and most unexpected way. BTW at 9a0471d the behaviour was also changed by removing an API function. |
@effad that was before the API was "stable" and also to enforce the "json keys are unordered". The golang JSON implementation purposefully randomizes the keys so that people don't even rely on the hash function hashing the keys into the same order. However, I still feel that if we are going to support "java8" and BigDecimal/BigInteger, this should be corrected and not put off as "but the RFC says we can be lazy about it" |
if anyone cares, I updated my branch for this change to use exact precision for all numbers as well as to validate that string input matches JSON numbers and not any java number. you can see the changes at branch https://github.com/johnjaylward/JSON-java/tree/FixBigIntRead I also updated all the test cases to pass for these changes which can be seen at https://github.com/johnjaylward/JSON-Java-unit-test/tree/FixBigIntRead I made updates after pr #158 was closed. The new changes remove exceptions as flow control and clean up a lot of my initial implementation. |
-0 is in the JSON spec, and it's not a huge number and it gets converted to a string. Can this particular part of the bug be fixed? I don't mind large numbers not being handled. I realize NEGATIVE_ZERO may not be a Java primitive value. Puleese? This is breaking JSON Schema validation as -0 is not a number. |
you should comment on your open issue, not this closed one |
k |
The following piece of code surprisingly outputs
class java.lang.String
, instead of a number-class like BigDecimal or BigInteger.Since JSON does not limit the size of numbers (to the best of my knowledge) I consider this to be a bug.
The culprit is JSONObject.stringToValue which will not work with numbers beyond the range of Java Long.
The text was updated successfully, but these errors were encountered: