mirror of
https://github.com/nushell/nushell.git
synced 2024-11-29 11:54:02 +01:00
[fix] crashing issues when the given timestamp is out of range (#3271)
* add support for timestamp-based time conversion by specifing timezone or 'UTC/Local' * [fix] fix the wrong test sample * code formating * code formating and import missing mod to test * code formating again * [fix] it won't crash when given timestamp is too big. * [fix] code formatting =_=b
This commit is contained in:
parent
dc8a68c98f
commit
ad1c4f5e39
@ -110,13 +110,13 @@ impl WholeStreamCommand for SubCommand {
|
|||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "Convert to datetime using a specified timezone",
|
description: "Convert timestamp (no larger than 8e+12) to datetime using a specified timezone",
|
||||||
example: "echo '1614434140' | str to-datetime -z 'UTC'",
|
example: "echo '1614434140' | str to-datetime -z 'UTC'",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description:
|
description:
|
||||||
"Convert to datetime using a specified timezone offset (between -12 and 12)",
|
"Convert timestamp (no larger than 8e+12) to datetime using a specified timezone offset (between -12 and 12)",
|
||||||
example: "echo '1614434140' | str to-datetime -o '+9'",
|
example: "echo '1614434140' | str to-datetime -o '+9'",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
@ -203,7 +203,17 @@ fn action(
|
|||||||
let ts = s.parse::<i64>();
|
let ts = s.parse::<i64>();
|
||||||
// if timezone if specified, first check if the input is a timestamp.
|
// if timezone if specified, first check if the input is a timestamp.
|
||||||
if let Some(tz) = timezone {
|
if let Some(tz) = timezone {
|
||||||
|
const TIMESTAMP_BOUND: i64 = 8.2e+12 as i64;
|
||||||
|
// Since the timestamp method of chrono itself don't throw an error (it just panicked)
|
||||||
|
// We have to manually guard it.
|
||||||
if let Ok(t) = ts {
|
if let Ok(t) = ts {
|
||||||
|
if t.abs() > TIMESTAMP_BOUND {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"could not parse input as a valid timestamp",
|
||||||
|
"given timestamp is out of range, it should between -8e+12 and 8e+12",
|
||||||
|
tag.into().span,
|
||||||
|
));
|
||||||
|
}
|
||||||
const HOUR: i32 = 3600;
|
const HOUR: i32 = 3600;
|
||||||
let stampout = match tz.item {
|
let stampout = match tz.item {
|
||||||
Zone::Utc => UntaggedValue::date(Utc.timestamp(t, 0)),
|
Zone::Utc => UntaggedValue::date(Utc.timestamp(t, 0)),
|
||||||
@ -347,6 +357,18 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn takes_invalid_timestamp() {
|
||||||
|
let date_str = string("10440970000000");
|
||||||
|
let timezone_option = Some(Tagged {
|
||||||
|
item: Zone::Utc,
|
||||||
|
tag: Tag::unknown(),
|
||||||
|
});
|
||||||
|
let actual = action(&date_str, &timezone_option, &None, Tag::unknown());
|
||||||
|
|
||||||
|
assert!(actual.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn communicates_parsing_error_given_an_invalid_datetimelike_string() {
|
fn communicates_parsing_error_given_an_invalid_datetimelike_string() {
|
||||||
let date_str = string("16.11.1984 8:00 am Oops0000");
|
let date_str = string("16.11.1984 8:00 am Oops0000");
|
||||||
|
Loading…
Reference in New Issue
Block a user