Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Avoid hitting ArgumentError for parsing integers and floats. #98

Closed
wants to merge 1 commit into from

2 participants

@headius
Collaborator

This patch is not quite perfect. There are cases that Integer and
Float handle that this does not, and the to_i and to_f methods
have the annoying tendency to ignore unparsable sections of the
string. We may just need to write a simple Ruby version of integer
and float parsing to use here. I'd be very surprised if it didn't
still balance out with regards to the exception-rescuing logic.

@headius headius Avoid hitting ArgumentError for parsing integers and floats.
This patch is not quite perfect. There are cases that Integer and
Float handle that this does not, and the to_i and to_f methods
have the annoying tendency to ignore unparsable sections of the
string. We may just need to write a simple Ruby version of integer
and float parsing to use here. I'd be very surprised if it didn't
still balance out with regards to the exception-rescuing logic.
c151879
@headius
Collaborator

The build failure is expected. It appears to fail handling things like hexadecimal integers, etc. In line with expectations for my minimal patch.

@tenderlove
Owner

Cool, thanks. I can work with it from here.

@tenderlove
Owner

Hey @headius, I fixed this in 9d7be25

Thanks!

@tenderlove tenderlove closed this
@headius
Collaborator

Excellent! I just pulled in updated .rb from psych master for JRuby 1.7.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 2, 2012
  1. @headius

    Avoid hitting ArgumentError for parsing integers and floats.

    headius authored
    This patch is not quite perfect. There are cases that Integer and
    Float handle that this does not, and the to_i and to_f methods
    have the annoying tendency to ignore unparsable sections of the
    string. We may just need to write a simple Ruby version of integer
    and float parsing to use here. I'd be very surprised if it didn't
    still balance out with regards to the exception-rescuing logic.
This page is out of date. Refresh to see the latest.
Showing with 31 additions and 8 deletions.
  1. +31 −8 lib/psych/scalar_scanner.rb
View
39 lib/psych/scalar_scanner.rb
@@ -86,19 +86,15 @@ def tokenize string
end
i
when FLOAT
- begin
- return Float(string.gsub(/[,_]/, ''))
- rescue ArgumentError
- end
+ float = parse_float(string)
+ return float if float
@string_cache[string] = true
string
else
if string.count('.') < 2
- begin
- return Integer(string.gsub(/[,_]/, ''))
- rescue ArgumentError
- end
+ integer = parse_integer(string)
+ return integer if integer
end
@string_cache[string] = true
@@ -107,6 +103,33 @@ def tokenize string
end
###
+ # Parse a string and attempt to return an integer, or nil if unparsable.
+ def parse_integer(string)
+ subbed_string = string.gsub(/[,_]/, '')
+ integer = subbed_string.to_i
+
+ # if result is zero, confirm there's no non-zero characters
+ return integer if integer != 0 || /^0+$/.match(subbed_string)
+
+ nil
+ end
+
+ ###
+ # Parse a string and attempt to return an integer, or nil if unparsable.
+ def parse_float(string)
+ # more than one . means it should not be a float
+ return nil if /\..*\./.match(string)
+
+ subbed_string = string.gsub(/[,_]/, '')
+ float = subbed_string.to_f
+
+ # if result is zero, confirm there's no non-zero characters
+ return float if float != 0.0 || /^0*\.0+$/.match(subbed_string)
+
+ nil
+ end
+
+ ###
# Parse and return a Time from +string+
def parse_time string
date, time = *(string.split(/[ tT]/, 2))
Something went wrong with that request. Please try again.