Monday, August 17, 2009

ruby's sprintf considered harmful

irb(main):001:0> sprintf("%d", "01")
=> "1"
irb(main):002:0> sprintf("%d", "02")
=> "2"
irb(main):003:0> sprintf("%d", "03")
=> "3"
irb(main):004:0> sprintf("%d", "04")
=> "4"
irb(main):005:0> sprintf("%d", "05")
=> "5"
irb(main):006:0> sprintf("%d", "06")
=> "6"
irb(main):007:0> sprintf("%d", "07")
=> "7"
irb(main):008:0> sprintf("%d", "08")
ArgumentError: invalid value for Integer: "08"
from (irb):8:in `sprintf'
from (irb):8
irb(main):009:0> sprintf("%d", "09")
ArgumentError: invalid value for Integer: "09"
from (irb):9:in `sprintf'
from (irb):9

irb(main):010:0> sprintf("%d", "10")
=> "10"
irb(main):011:0> sprintf("%d", "11")
=> "11"
irb(main):012:0> sprintf("%d", "12")
=> "12"

Of course, this bug's been known for years.

2 comments:

Unknown said...

irb(main):001:0> 08
SyntaxError: compile error
(irb):1: Illegal octal digit
from (irb):1
irb(main):002:0>

I think that's a parse error -- decimal-looking values that start with 0 are interpreted as octal, right?

(or am I missing something?)

Unknown said...

Oh!

Oh, I see. It's delaying the interpretation of the numbers in those strings. That /is/ harmful.

How did this manifest? Was this an issue you ran into in the wild?