[Pkg] The Trunk: WebClient-Core-nice.119.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Sep 11 22:55:54 UTC 2019
Nicolas Cellier uploaded a new version of WebClient-Core to project The Trunk:
http://source.squeak.org/trunk/WebClient-Core-nice.119.mcz
==================== Summary ====================
Name: WebClient-Core-nice.119
Author: nice
Time: 12 September 2019, 12:55:52.391336 am
UUID: 7a017a9c-1a85-4a4e-bbfb-63ed34c747e9
Ancestors: WebClient-Core-topa.118
Fix a bunch of serious bugs in json number decoding
Implementation will now answer the nearest Float, what it failed to previously.
=============== Diff against WebClient-Core-topa.118 ===============
Item was added:
+ ----- Method: WebUtils class>>jsonFloatSignificand:exp10: (in category 'json-decode') -----
+ jsonFloatSignificand: value exp10: exponent
+ "Take care to convert to nearest Float"
+ ^self jsonFloatSignificand: value exp10: exponent scale: (10 raisedTo: exponent abs)!
Item was added:
+ ----- Method: WebUtils class>>jsonFloatSignificand:exp10:scale: (in category 'json-decode') -----
+ jsonFloatSignificand: value exp10: exponent scale: scale
+ "Take care to convert to nearest Float"
+ "self assert: scale = (10 raisedTo: exponent abs)."
+ ^(value isAnExactFloat and: ["scale isAnExactFloat"
+ exponent between: -22 and: 22
+ "(1 to: 100) detect: [:i | (10 raisedTo: i) isAnExactFloat not]"])
+ ifTrue: [exponent >= 0
+ ifTrue: [value asExactFloat * scale asExactFloat]
+ ifFalse: [value asExactFloat / scale asExactFloat]]
+ ifFalse: [exponent >= 0
+ ifTrue: [(value * scale) asFloat]
+ ifFalse: [(Fraction numerator: value denominator: scale) asFloat]]!
Item was changed:
----- Method: WebUtils class>>jsonNumberFrom: (in category 'json-decode') -----
jsonNumberFrom: stream
"Decodes a JSON number from the stream"
+ | ascii ch integer fraction scale sign expSign exponent exp value beFloat |
+ integer := fraction := exponent := exp := 0. sign := scale := expSign := 1.
- | ascii integer fraction scale sign expSign exponent value ch |
- integer := fraction := 0. sign := scale := exponent := expSign := 1.
ascii := stream next asciiValue.
ascii = 45 "$- asciiValue" ifTrue:[
sign := -1.
ascii := stream next asciiValue.
].
"JSON requires at least one digit"
(ascii >= 48 and:[ascii <= 57]) ifFalse:[^self error: 'Digit expected'].
"Read the integer part"
integer := ascii - 48.
[ch := stream next ifNil:[^integer * sign].
ascii := ch asciiValue.
ascii >= 48 and:[ascii <= 57]] whileTrue:[
integer := (integer * 10) + (ascii - 48).
].
+ (beFloat := ascii = 46) "$. asciiValue" ifTrue:[
- ascii = 46 "$. asciiValue" ifTrue:[
"Read the fraction part"
+ [ch := stream next ifNil:
+ [value := integer * scale + fraction * sign.
+ ^self jsonFloatSignificand: value exp10: exponent scale: scale].
- [ch := stream next ifNil:[^(integer * scale + fraction * sign) asFloat / scale].
ascii := ch asciiValue.
ascii >= 48 and:[ascii <= 57]] whileTrue:[
fraction := (fraction * 10) + (ascii - 48).
+ exponent := exponent - 1.
scale := scale * 10.
].
+ value := integer * scale + fraction * sign.
- value := (integer * scale + fraction * sign) asFloat / scale asFloat.
] ifFalse:[value := integer * sign].
-
(ascii = 69 "$E asciiValue" or:[ascii = 101 "$e asciiValue"]) ifTrue:[
"Read exponent"
ascii := stream next asciiValue.
+ ascii = 45 "$- asciiValue" ifTrue:[
- ascii = $- ifTrue:[
expSign := -1.
ascii := stream next asciiValue.
+ ] ifFalse:[ascii = 43 "$+ asciiValue" ifTrue:[ascii := stream next asciiValue]].
+ exp := ascii - 48.
+ [ch := stream next ifNil:
+ [exponent := exp * expSign + exponent.
+ (beFloat or: [expSign = -1]) ifTrue: [^self jsonFloatSignificand: value exp10: exponent].
+ ^value * (10 raisedTo: exponent)].
- ] ifFalse:[ascii = $+ ifTrue:[ascii := stream next asciiValue]].
- exponent := ascii - 48.
- [ch := stream next ifNil:[^value * (10 raisedTo: expSign * exponent)].
ascii := ch asciiValue.
ascii >= 48 and:[ascii <= 57]] whileTrue:[
+ exp := (exp * 10) + (ascii - 48).
- exponent := (exponent * 10) + (ascii - 48).
].
+ exponent := exp * expSign + exponent
- exponent := exponent * expSign.
].
"Skip back before last character since number might be part of a sequence
like 1, 2, 3, 4, etc (which would eat the trailing comma)"
ch isAlphaNumeric ifTrue:[^self error: 'Delimiter expected'].
stream skip: -1.
+ (beFloat or: [expSign = -1]) ifTrue: [^self jsonFloatSignificand: value exp10: exponent].
+ ^value * (10 raisedTo: exponent)!
- exponent = 1 ifFalse:[
- exponent < 0 ifTrue:[value := value asFloat].
- value := value * (10 raisedTo: exponent).
- ].
- ^value!
More information about the Packages
mailing list