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! |
Free forum by Nabble | Edit this page |