diff --git a/lib/IO/Stty.pm b/lib/IO/Stty.pm index af61fb0..89f5d74 100644 --- a/lib/IO/Stty.pm +++ b/lib/IO/Stty.pm @@ -460,8 +460,10 @@ sub _parse_char_value { return hex($1); } - # Octal: 0 followed by digits (but not plain "0" which is decimal zero) - if ( $val =~ /^0(\d+)$/ ) { + # Octal: 0 followed by octal digits (0-7). We deliberately exclude + # 8 and 9 so that inputs like "08" or "09" fall through to the decimal + # path instead of being silently truncated by oct(). + if ( $val =~ /^0([0-7]+)$/ ) { return oct($1); } diff --git a/t/01-parse-char-value.t b/t/01-parse-char-value.t index 87e4e1b..f9d455a 100644 --- a/t/01-parse-char-value.t +++ b/t/01-parse-char-value.t @@ -45,6 +45,11 @@ my @tests = ( [ '017', 15, 'octal 017' ], [ '0177', 127, 'octal 0177' ], + # Digits 8/9 after leading zero: NOT octal, treated as decimal + [ '08', 8, '08 is decimal 8, not invalid octal' ], + [ '09', 9, '09 is decimal 9, not invalid octal' ], + [ '019', 19, '019 is decimal 19 (contains non-octal digit)' ], + # undef / ^- (returns _POSIX_VDISABLE, which is 0 on Linux, 255 on macOS) [ 'undef', $VDISABLE, 'undef disables character (returns _POSIX_VDISABLE)' ], [ '^-', $VDISABLE, '^- disables character (returns _POSIX_VDISABLE)' ],