Bug #13722


OptionParser::DecimalInteger can be converted as Octal

Added by wmccumstie (William McCumstie) almost 7 years ago. Updated almost 7 years ago.

Target version:
ruby -v:
ruby 2.5.0dev (2017-07-03 trunk 59255) [x86_64-linux]


OptionParser::DecimalInteger will convert in octal format for input values that start with a '0'. In the attached script, an input of '035' will be converted to 29.

Script Output:

$: ./ruby-op-octal-bug.rb 
Input: 035
Parsed: 29


ruby-op-octal-bug.rb (332 Bytes) ruby-op-octal-bug.rb Reproduces the bug wmccumstie (William McCumstie), 07/06/2017 09:58 AM

Updated by shyouhei (Shyouhei Urabe) almost 7 years ago

I wonder if this is a bug or an intended behaviour.

Updated by mjtko (Mark Titorenko) almost 7 years ago

shyouhei (Shyouhei Urabe) wrote:

I wonder if this is a bug or an intended behaviour.

I would argue that this is a bug. The test here -- -- also doesn't feel correct, as it's testing that 09 generates an OptionParser::InvalidArgument exception, though that only happens because 09 is not valid octal.

If the intention is for OptionParser:DecimalInteger to behave the same as Integer but disallow hex and binary values, then perhaps it would be better called OptionParser::OctalOrDecimalInteger. :-) As there is already a specific type OptionParser::OctalInteger, it suggests to me that OptionParser::DecimalInteger should be generating base-10 output only; generating base-8 output is confusing and, for me at least, violates the principle of least surprise.

Updated by wmccumstie (William McCumstie) almost 7 years ago

I don't believe it would be intended behaviour. At very least it would be strange to specifically specify a Decimal only to have it converted as Octal.

Looking into to the unit tests (test/optparse/test_acceptable.rb:115), I would have expected the intended behaviour to raise OptionParser::InvalidArgument if anything.

Updated by wmccumstie (William McCumstie) almost 7 years ago

From optparse.rb:

OptionParser comes with a few ready-to-use kinds of  type
# coercion. They are:
# - Date  -- Anything accepted by +Date.parse+
# - DateTime -- Anything accepted by +DateTime.parse+
# - Time -- Anything accepted by +Time.httpdate+ or +Time.parse+
# - URI  -- Anything accepted by +URI.parse+
# - Shellwords -- Anything accepted by +Shellwords.shellwords+
# - String -- Any non-empty string
# - Integer -- Any integer. Will convert octal. (e.g. 124, -3, 040)
# - Float -- Any float. (e.g. 10, 3.14, -100E+13)
# - Numeric -- Any integer, float, or rational (1, 3.4, 1/3)
# - DecimalInteger -- Like +Integer+, but no octal format.
# - OctalInteger -- Like +Integer+, but no decimal format.
# - DecimalNumeric -- Decimal integer or float.
# - TrueClass --  Accepts '+, yes, true, -, no, false' and
#   defaults as +true+
# - FalseClass -- Same as +TrueClass+, but defaults to +false+
# - Array -- Strings separated by ',' (e.g. 1,2,3)
# - Regexp -- Regular expressions. Also includes options.

DecimalInteger does not support octal format. So either it should convert as a decimal or throw an error.

Actions #6

Updated by nobu (Nobuyoshi Nakada) almost 7 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r59273.

Fix DecimalInteger converting to octal bug

Previously if the input started with a '0' then it will be converted
as octal even though it has been specified as a decimal. This commit
forces the number to be interpreted as a decimal.

[ruby-core:81927] [Bug #13722] [Fix GH-1665]
Author: william

Updated by nobu (Nobuyoshi Nakada) almost 7 years ago

  • Description updated (diff)

Thank you, it's obviously a bug.


Also available in: Atom PDF