Skip to content

Commit f938707

Browse files
committed
merge revision(s) 42844,42845: [Backport ruby#8865]
* lib/optparse.rb: The Integer acceptable now allows binary and hexadecimal numbers per the documentation. [ruby-trunk - Bug ruby#8865] DecimalInteger, OctalInteger, DecimalNumeric now validate their input before converting to a number. [ruby-trunk - Bug ruby#8865] * test/optparse/test_acceptable.rb: Tests for the above, tests for all numeric acceptables for existing behavior. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@44935 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 9e3ed45 commit f938707

4 files changed

Lines changed: 241 additions & 10 deletions

File tree

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
Fri Feb 14 13:51:45 2014 Eric Hodel <drbrain@segment7.net>
2+
3+
* lib/optparse.rb: The Integer acceptable now allows binary and
4+
hexadecimal numbers per the documentation. [ruby-trunk - Bug #8865]
5+
6+
DecimalInteger, OctalInteger, DecimalNumeric now validate their input
7+
before converting to a number. [ruby-trunk - Bug #8865]
8+
9+
* test/optparse/test_acceptable.rb: Tests for the above, tests for all
10+
numeric acceptables for existing behavior.
11+
112
Fri Feb 14 12:52:50 2014 Kouhei Sutou <kou@cozmixng.org>
213

314
* ext/socket/raddrinfo.c (nogvl_getaddrinfo): Fix indent.

lib/optparse.rb

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,23 +1631,30 @@ def environment(env = File.basename($0, '.*'))
16311631
decimal = '\d+(?:_\d+)*'
16321632
binary = 'b[01]+(?:_[01]+)*'
16331633
hex = 'x[\da-f]+(?:_[\da-f]+)*'
1634-
octal = "0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})"
1634+
octal = "0(?:[0-7]+(?:_[0-7]+)*|#{binary}|#{hex})?"
16351635
integer = "#{octal}|#{decimal}"
1636-
accept(Integer, %r"\A[-+]?(?:#{integer})"io) {|s,| Integer(s) if s}
1636+
1637+
accept(Integer, %r"\A[-+]?(?:#{integer})\z"io) {|s,|
1638+
begin
1639+
Integer(s)
1640+
rescue ArgumentError
1641+
raise OptionParser::InvalidArgument, s
1642+
end if s
1643+
}
16371644

16381645
#
16391646
# Float number format, and converts to Float.
16401647
#
16411648
float = "(?:#{decimal}(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
1642-
floatpat = %r"\A[-+]?#{float}"io
1649+
floatpat = %r"\A[-+]?#{float}\z"io
16431650
accept(Float, floatpat) {|s,| s.to_f if s}
16441651

16451652
#
16461653
# Generic numeric format, converts to Integer for integer format, Float
16471654
# for float format, and Rational for rational format.
16481655
#
16491656
real = "[-+]?(?:#{octal}|#{float})"
1650-
accept(Numeric, /\A(#{real})(?:\/(#{real}))?/io) {|s, d, n|
1657+
accept(Numeric, /\A(#{real})(?:\/(#{real}))?\z/io) {|s, d, n|
16511658
if n
16521659
Rational(d, n)
16531660
elsif s
@@ -1658,22 +1665,40 @@ def environment(env = File.basename($0, '.*'))
16581665
#
16591666
# Decimal integer format, to be converted to Integer.
16601667
#
1661-
DecimalInteger = /\A[-+]?#{decimal}/io
1662-
accept(DecimalInteger) {|s,| s.to_i if s}
1668+
DecimalInteger = /\A[-+]?#{decimal}\z/io
1669+
accept(DecimalInteger, DecimalInteger) {|s,|
1670+
begin
1671+
Integer(s)
1672+
rescue ArgumentError
1673+
raise OptionParser::InvalidArgument, s
1674+
end if s
1675+
}
16631676

16641677
#
16651678
# Ruby/C like octal/hexadecimal/binary integer format, to be converted to
16661679
# Integer.
16671680
#
1668-
OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io
1669-
accept(OctalInteger) {|s,| s.oct if s}
1681+
OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))\z/io
1682+
accept(OctalInteger, OctalInteger) {|s,|
1683+
begin
1684+
Integer(s, 8)
1685+
rescue ArgumentError
1686+
raise OptionParser::InvalidArgument, s
1687+
end if s
1688+
}
16701689

16711690
#
16721691
# Decimal integer/float number format, to be converted to Integer for
16731692
# integer format, Float for float format.
16741693
#
16751694
DecimalNumeric = floatpat # decimal integer is allowed as float also.
1676-
accept(DecimalNumeric) {|s,| eval(s) if s}
1695+
accept(DecimalNumeric, floatpat) {|s,|
1696+
begin
1697+
eval(s)
1698+
rescue SyntaxError
1699+
raise OptionParser::InvalidArgument, s
1700+
end if s
1701+
}
16771702

16781703
#
16791704
# Boolean switch, which means whether it is present or not, whether it is

test/optparse/test_acceptable.rb

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
require_relative 'test_optparse'
2+
3+
class TestOptionParser::Acceptable < TestOptionParser
4+
5+
def setup
6+
super
7+
@opt.def_option("--integer VAL", Integer) { |v| @integer = v }
8+
@opt.def_option("--float VAL", Float) { |v| @float = v }
9+
@opt.def_option("--numeric VAL", Numeric) { |v| @numeric = v }
10+
11+
@opt.def_option("--decimal-integer VAL",
12+
OptionParser::DecimalInteger) { |i| @decimal_integer = i }
13+
@opt.def_option("--octal-integer VAL",
14+
OptionParser::OctalInteger) { |i| @octal_integer = i }
15+
@opt.def_option("--decimal-numeric VAL",
16+
OptionParser::DecimalNumeric) { |i| @decimal_numeric = i }
17+
end
18+
19+
def test_integer
20+
assert_equal(%w"", no_error {@opt.parse!(%w"--integer 0")})
21+
assert_equal(0, @integer)
22+
23+
assert_equal(%w"", no_error {@opt.parse!(%w"--integer 0b10")})
24+
assert_equal(2, @integer)
25+
26+
assert_equal(%w"", no_error {@opt.parse!(%w"--integer 077")})
27+
assert_equal(63, @integer)
28+
29+
assert_equal(%w"", no_error {@opt.parse!(%w"--integer 10")})
30+
assert_equal(10, @integer)
31+
32+
assert_equal(%w"", no_error {@opt.parse!(%w"--integer 0x3")})
33+
assert_equal(3, @integer)
34+
35+
assert_raises(OptionParser::InvalidArgument) do
36+
@opt.parse!(%w"--integer 0b")
37+
end
38+
39+
assert_raises(OptionParser::InvalidArgument) do
40+
@opt.parse!(%w"--integer 09")
41+
end
42+
43+
assert_raises(OptionParser::InvalidArgument) do
44+
@opt.parse!(%w"--integer 0x")
45+
end
46+
47+
assert_raises(OptionParser::InvalidArgument) do
48+
@opt.parse!(%w"--integer 1234xyz")
49+
end
50+
end
51+
52+
def test_float
53+
assert_equal(%w"", no_error {@opt.parse!(%w"--float 0")})
54+
assert_in_epsilon(0.0, @float)
55+
56+
assert_equal(%w"", no_error {@opt.parse!(%w"--float 0.0")})
57+
assert_in_epsilon(0.0, @float)
58+
59+
assert_equal(%w"", no_error {@opt.parse!(%w"--float 1.2")})
60+
assert_in_epsilon(1.2, @float)
61+
62+
assert_equal(%w"", no_error {@opt.parse!(%w"--float 1E2")})
63+
assert_in_epsilon(100, @float)
64+
65+
assert_equal(%w"", no_error {@opt.parse!(%w"--float 1E-2")})
66+
assert_in_epsilon(0.01, @float)
67+
68+
assert_raises(OptionParser::InvalidArgument) do
69+
@opt.parse!(%w"--float 0e")
70+
end
71+
72+
assert_raises(OptionParser::InvalidArgument) do
73+
@opt.parse!(%w"--float 1.234xyz")
74+
end
75+
end
76+
77+
def test_numeric
78+
assert_equal(%w"", no_error {@opt.parse!(%w"--numeric 0")})
79+
assert_equal(0, @numeric)
80+
81+
assert_equal(%w"", no_error {@opt.parse!(%w"--numeric 0/1")})
82+
assert_equal(0, @numeric)
83+
84+
assert_equal(%w"", no_error {@opt.parse!(%w"--numeric 1/2")})
85+
assert_equal(Rational(1, 2), @numeric)
86+
87+
assert_equal(%w"", no_error {@opt.parse!(%w"--numeric 1.2/2.3")})
88+
assert_equal(Rational(12, 23), @numeric)
89+
90+
assert_raises(OptionParser::InvalidArgument) do
91+
@opt.parse!(%w"--numeric 1/")
92+
end
93+
94+
assert_raises(OptionParser::InvalidArgument) do
95+
@opt.parse!(%w"--numeric 12/34xyz")
96+
end
97+
98+
assert_raises(OptionParser::InvalidArgument) do
99+
@opt.parse!(%w"--numeric 12x/34yz")
100+
end
101+
end
102+
103+
def test_decimal_integer
104+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-integer 0")})
105+
assert_equal(0, @decimal_integer)
106+
107+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-integer 10")})
108+
assert_equal(10, @decimal_integer)
109+
110+
assert_raises(OptionParser::InvalidArgument) do
111+
@opt.parse!(%w"--decimal-integer 0b1")
112+
end
113+
114+
e = assert_raises(OptionParser::InvalidArgument) do
115+
@opt.parse!(%w"--decimal-integer 09")
116+
end
117+
118+
assert_equal("invalid argument: --decimal-integer 09", e.message)
119+
120+
assert_raises(OptionParser::InvalidArgument) do
121+
@opt.parse!(%w"--decimal-integer x")
122+
end
123+
124+
assert_raises(OptionParser::InvalidArgument) do
125+
@opt.parse!(%w"--decimal-integer 1234xyz")
126+
end
127+
end
128+
129+
def test_octal_integer
130+
assert_equal(%w"", no_error {@opt.parse!(%w"--octal-integer 0")})
131+
assert_equal(0, @octal_integer)
132+
133+
assert_equal(%w"", no_error {@opt.parse!(%w"--octal-integer 6")})
134+
assert_equal(6, @octal_integer)
135+
136+
assert_equal(%w"", no_error {@opt.parse!(%w"--octal-integer 07")})
137+
assert_equal(7, @octal_integer)
138+
139+
assert_equal(%w"", no_error {@opt.parse!(%w"--octal-integer 10")})
140+
assert_equal(8, @octal_integer)
141+
142+
assert_equal(%w"", no_error {@opt.parse!(%w"--octal-integer 011")})
143+
assert_equal(9, @octal_integer)
144+
145+
assert_raises(OptionParser::InvalidArgument) do
146+
@opt.parse!(%w"--octal-integer 09")
147+
end
148+
149+
assert_raises(OptionParser::InvalidArgument) do
150+
@opt.parse!(%w"--octal-integer 0b1")
151+
end
152+
153+
assert_raises(OptionParser::InvalidArgument) do
154+
@opt.parse!(%w"--octal-integer x")
155+
end
156+
157+
assert_raises(OptionParser::InvalidArgument) do
158+
@opt.parse!(%w"--octal-integer 01234xyz")
159+
end
160+
end
161+
162+
def test_decimal_numeric
163+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-numeric 0")})
164+
assert_equal(0, @decimal_numeric)
165+
166+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-numeric 01")})
167+
assert_equal(1, @decimal_numeric)
168+
169+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-numeric 1.2")})
170+
assert_in_delta(1.2, @decimal_numeric)
171+
172+
assert_equal(%w"", no_error {@opt.parse!(%w"--decimal-numeric 1E2")})
173+
assert_in_delta(100.0, @decimal_numeric)
174+
175+
assert_raises(OptionParser::InvalidArgument) do
176+
@opt.parse!(%w"--decimal-numeric 0b1")
177+
end
178+
179+
e = assert_raises(OptionParser::InvalidArgument) do
180+
@opt.parse!(%w"--decimal-numeric 09")
181+
end
182+
183+
assert_equal("invalid argument: --decimal-numeric 09", e.message)
184+
185+
assert_raises(OptionParser::InvalidArgument) do
186+
@opt.parse!(%w"--decimal-integer 1234xyz")
187+
end
188+
189+
assert_raises(OptionParser::InvalidArgument) do
190+
@opt.parse!(%w"--decimal-integer 12.34xyz")
191+
end
192+
end
193+
194+
end
195+

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#define RUBY_VERSION "1.9.3"
2-
#define RUBY_PATCHLEVEL 518
2+
#define RUBY_PATCHLEVEL 519
33

44
#define RUBY_RELEASE_DATE "2014-02-14"
55
#define RUBY_RELEASE_YEAR 2014

0 commit comments

Comments
 (0)