From de60b95850951ec5c71712a82a736e8518cc7bf6 Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Fri, 19 May 2017 00:08:13 +0100 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20core=20dump=20when=20given=20in?= =?UTF-8?q?valid=20UTF-8=20arguments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By parsing OsStrings rather than Strings, it’s the getopts crate that’s doing the UTF-8 checking rather than us, so if one of them isn’t valid, it’ll just fail to parse rather than crash exa. Also, save a few allocations here and there. --- src/bin/main.rs | 6 +++--- src/exa.rs | 4 ++-- src/options/mod.rs | 10 ++++++++-- xtests/run.sh | 4 ++++ 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 49fbfca..bd298fd 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,15 +1,15 @@ extern crate exa; use exa::Exa; -use std::env::args; +use std::env::args_os; use std::io::{stdout, stderr, Write, ErrorKind}; use std::process::exit; fn main() { - let args: Vec = args().skip(1).collect(); + let args = args_os().skip(1); let mut stdout = stdout(); - match Exa::new(&args, &mut stdout) { + match Exa::new(args, &mut stdout) { Ok(mut exa) => { match exa.run() { Ok(exit_status) => exit(exit_status), diff --git a/src/exa.rs b/src/exa.rs index 096389f..de3b4b7 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -53,8 +53,8 @@ pub struct Exa<'w, W: Write + 'w> { } impl<'w, W: Write + 'w> Exa<'w, W> { - pub fn new(args: &[S], writer: &'w mut W) -> Result, Misfire> - where S: AsRef { + pub fn new(args: C, writer: &'w mut W) -> Result, Misfire> + where C: IntoIterator, C::Item: AsRef { Options::getopts(args).map(move |(options, args)| { Exa { options, writer, args } }) diff --git a/src/options/mod.rs b/src/options/mod.rs index daebb3d..522dbb8 100644 --- a/src/options/mod.rs +++ b/src/options/mod.rs @@ -39,10 +39,16 @@ pub struct Options { impl Options { + // Even though the arguments go in as OsStrings, they come out + // as Strings. Invalid UTF-8 won’t be parsed, but it won’t make + // exa core dump either. + // + // https://github.com/rust-lang-nursery/getopts/pull/29 + /// Call getopts on the given slice of command-line strings. #[allow(unused_results)] - pub fn getopts(args: &[S]) -> Result<(Options, Vec), Misfire> - where S: AsRef { + pub fn getopts(args: C) -> Result<(Options, Vec), Misfire> + where C: IntoIterator, C::Item: AsRef { let mut opts = getopts::Options::new(); opts.optflag("v", "version", "show version of exa"); diff --git a/xtests/run.sh b/xtests/run.sh index 770d7a6..b8b1fb5 100755 --- a/xtests/run.sh +++ b/xtests/run.sh @@ -72,6 +72,10 @@ COLUMNS=80 $exa $testcases/file-names -R 2>&1 | diff -q - $results/file_names_R $exa $testcases/file-names -1 2>&1 | diff -q - $results/file_names_1 || exit 1 $exa $testcases/file-names -T 2>&1 | diff -q - $results/file_names_T || exit 1 +# At least make sure it handles invalid UTF-8 arguments without crashing +$exa $testcases/file-names/* 2>/dev/null + + # File types $exa $testcases/file-names-exts -1 2>&1 | diff -q - $results/file-names-exts || exit 1 $exa $testcases/specials -l 2>&1 | diff -q - $results/specials || exit 1 -- GitLab