[squeak-dev] 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 Squeak-dev mailing list