mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-15 22:44:01 +00:00
tinyexpr: Check for wcstod errors
This would otherwise unwrap() an Err and crash.
This commit is contained in:
parent
b3ff982ad7
commit
06b89083d5
2 changed files with 32 additions and 3 deletions
|
@ -35,7 +35,7 @@ use std::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
wchar::prelude::*,
|
wchar::prelude::*,
|
||||||
wutil::{wcstod::wcstod_underscores, wgettext},
|
wutil::{wcstod::wcstod_underscores, wgettext, Error as wcstodError},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -95,6 +95,7 @@ pub enum ErrorKind {
|
||||||
UnexpectedToken,
|
UnexpectedToken,
|
||||||
LogicalOperator,
|
LogicalOperator,
|
||||||
DivByZero,
|
DivByZero,
|
||||||
|
NumberTooLarge,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ impl ErrorKind {
|
||||||
wgettext!("Logical operations are not supported, use `test` instead")
|
wgettext!("Logical operations are not supported, use `test` instead")
|
||||||
}
|
}
|
||||||
ErrorKind::DivByZero => wgettext!("Division by zero"),
|
ErrorKind::DivByZero => wgettext!("Division by zero"),
|
||||||
|
ErrorKind::NumberTooLarge => wgettext!("Number is too large"),
|
||||||
ErrorKind::Unknown => wgettext!("Expression is bogus"),
|
ErrorKind::Unknown => wgettext!("Expression is bogus"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,8 +398,21 @@ impl<'s> State<'s> {
|
||||||
// Try reading a number.
|
// Try reading a number.
|
||||||
if matches!(next.first(), Some('0'..='9') | Some('.')) {
|
if matches!(next.first(), Some('0'..='9') | Some('.')) {
|
||||||
let mut consumed = 0;
|
let mut consumed = 0;
|
||||||
let num = wcstod_underscores(*next, &mut consumed).unwrap();
|
match wcstod_underscores(*next, &mut consumed) {
|
||||||
Some((consumed, Some(Token::Number(num))))
|
Ok(num) => Some((consumed, Some(Token::Number(num)))),
|
||||||
|
Err(wcstodError::InvalidChar) => {
|
||||||
|
self.set_error(ErrorKind::Unknown, Some((self.pos + consumed, 1)));
|
||||||
|
return Some((consumed, Some(Token::Error)));
|
||||||
|
},
|
||||||
|
Err(wcstodError::Overflow) => {
|
||||||
|
self.set_error(ErrorKind::NumberTooLarge, Some((self.pos, consumed)));
|
||||||
|
return Some((consumed, Some(Token::Error)));
|
||||||
|
},
|
||||||
|
Err(wcstodError::Empty) => {
|
||||||
|
// We have a matches! above, this can't be?
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Look for a function call.
|
// Look for a function call.
|
||||||
// But not when it's an "x" followed by whitespace
|
// But not when it's an "x" followed by whitespace
|
||||||
|
|
|
@ -358,3 +358,17 @@ echo 7 + 6 | math 2 + 2
|
||||||
# It isn't checked at all.
|
# It isn't checked at all.
|
||||||
echo 7 + 8 | math not an expression
|
echo 7 + 8 | math not an expression
|
||||||
# CHECK: 15
|
# CHECK: 15
|
||||||
|
|
||||||
|
math (string repeat -n 1000 1) 2>| string shorten -m50 --char=""
|
||||||
|
# CHECK: math: Error: Number is too large
|
||||||
|
# CHECK: '1111111111111111111111111111111111111111111111111
|
||||||
|
# CHECK: ^
|
||||||
|
|
||||||
|
math 0x0_2.0P-0x3
|
||||||
|
# CHECKERR: math: Error: Unknown function
|
||||||
|
# CHECKERR: '0x0_2.0P-0x3'
|
||||||
|
# CHECKERR: ^^
|
||||||
|
math 0x0_2.0P-f
|
||||||
|
# CHECKERR: math: Error: Unexpected token
|
||||||
|
# CHECKERR: '0x0_2.0P-f'
|
||||||
|
# CHECKERR: ^
|
||||||
|
|
Loading…
Reference in a new issue