@@ -32,7 +32,7 @@ use std::os::unix::fs::OpenOptionsExt;
3232use std:: os:: unix:: io:: { AsRawFd , RawFd } ;
3333use uucore:: error:: { UError , UResult , USimpleError , UUsageError } ;
3434use uucore:: format_usage;
35- use uucore:: parser:: parse_int :: parse_u16_wrapped ;
35+ use uucore:: parser:: num_parser :: ExtendedParser ;
3636use uucore:: translate;
3737
3838#[ cfg( not( any(
@@ -324,7 +324,7 @@ fn stty(opts: &Options) -> UResult<()> {
324324 } ,
325325 "rows" => {
326326 if let Some ( rows) = args_iter. next ( ) {
327- if let Some ( n) = parse_u16_wrapped ( rows) {
327+ if let Some ( n) = parse_rows_cols ( rows) {
328328 valid_args. push ( ArgOptions :: Special ( SpecialSetting :: Rows ( n) ) ) ;
329329 } else {
330330 return invalid_integer_arg ( rows) ;
@@ -335,7 +335,7 @@ fn stty(opts: &Options) -> UResult<()> {
335335 }
336336 "columns" | "cols" => {
337337 if let Some ( cols) = args_iter. next ( ) {
338- if let Some ( n) = parse_u16_wrapped ( cols) {
338+ if let Some ( n) = parse_rows_cols ( cols) {
339339 valid_args. push ( ArgOptions :: Special ( SpecialSetting :: Cols ( n) ) ) ;
340340 } else {
341341 return invalid_integer_arg ( cols) ;
@@ -479,6 +479,17 @@ fn parse_u8_or_err(arg: &str) -> Result<u8, String> {
479479 } )
480480}
481481
482+ /// Parse an integer with hex (0x/0X) and octal (0) prefix support, wrapping to u16.
483+ ///
484+ /// GNU stty uses an unsigned 32-bit integer for row/col sizes, then wraps to 16 bits.
485+ /// Returns `None` if parsing fails or value exceeds u32::MAX.
486+ fn parse_rows_cols ( arg : & str ) -> Option < u16 > {
487+ u64:: extended_parse ( arg)
488+ . ok ( )
489+ . filter ( |& n| u32:: try_from ( n) . is_ok ( ) )
490+ . map ( |n| ( n % ( u16:: MAX as u64 + 1 ) ) as u16 )
491+ }
492+
482493/// Parse a saved terminal state string in stty format.
483494///
484495/// The format is colon-separated hexadecimal values:
0 commit comments