From aca7dedf330d833530a5635ba08d4b07af282555 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Mon, 20 Feb 2023 13:41:11 -0600 Subject: [PATCH] Fix Tokenizer::parse_fd() on x86 Upsizing to `usize` from `i32` doesn't work if `usize` is only 32-bits. I changed the code to use the `FromStr` impl on `i32`, but we could have also just used `u64` instead of `i32`. Also, we should get in the habit of using the appropriate type aliases where possible (`i32` should be `RawFd`). --- fish-rust/src/tokenizer.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/fish-rust/src/tokenizer.rs b/fish-rust/src/tokenizer.rs index fc0e094e1..f42868b7a 100644 --- a/fish-rust/src/tokenizer.rs +++ b/fish-rust/src/tokenizer.rs @@ -11,6 +11,7 @@ use cxx::{CxxWString, SharedPtr, UniquePtr}; use libc::{c_int, STDIN_FILENO, STDOUT_FILENO}; use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}; +use std::os::fd::RawFd; use widestring_suffix::widestrs; #[cxx::bridge] @@ -1125,18 +1126,20 @@ fn token_type(&self) -> TokenType { // Parse an fd from the non-empty string [start, end), all of which are digits. // Return the fd, or -1 on overflow. -fn parse_fd(s: &wstr) -> i32 { +fn parse_fd(s: &wstr) -> RawFd { assert!(!s.is_empty()); - let mut big_fd: usize = 0; - for c in s.chars() { - assert!(c.is_ascii_digit()); - big_fd = big_fd * 10 + (c.to_digit(10).unwrap() as usize); - if big_fd > (i32::MAX as usize) { - return -1; - } + let chars: Vec = s + .chars() + .map(|c| { + assert!(c.is_ascii_digit()); + c as u8 + }) + .collect(); + let s = std::str::from_utf8(chars.as_slice()).unwrap(); + match s.parse() { + Ok(val) => val, + Err(_) => -1, } - assert!(big_fd <= (i32::MAX as usize), "big_fd should be in range"); - big_fd as i32 } fn new_move_word_state_machine(syl: MoveWordStyle) -> Box {