Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo run cannot accept non-unicode arguments #2511

Closed
oconnor663 opened this issue Mar 23, 2016 · 6 comments · Fixed by #6849
Closed

cargo run cannot accept non-unicode arguments #2511

oconnor663 opened this issue Mar 23, 2016 · 6 comments · Fixed by #6849
Labels

Comments

@oconnor663
Copy link

Say I write a small program that just prints its args:

fn main() {
    for arg in std::env::args_os() {
        println!("{:?}", arg);
    }
}

Because it uses args_os() instead of args(), this program can handle command line args that aren't valid unicode. However, cargo run chokes:

$ cargo run $(printf '\xff')             
invalid unicode in argument: "\u{fffd}"

I have to invoke the binary directly to test the program:

$ ./target/debug/scratch $(printf '\xff')
"./target/debug/scratch"
"\u{fffd}"

Does Cargo need to inspect the command line args at all? It not, it would be nice if it didn't require them to be utf8.

@jonas-schievink
Copy link
Contributor

You might want to try cargo run -- $(printf '\xff') - without the --, cargo parses the 0xff as an argument for cargo run

@oconnor663
Copy link
Author

Oh I hadn't tried that. But it does look like I get the same result:

$ cargo run -- $(printf '\xff')
invalid unicode in argument: "\u{fffd}"

@alexcrichton
Copy link
Member

cc docopt/docopt.rs#152 and @BurntSushi, unfortunately this is a limitation of the underlying docopt library that Cargo is currently using.

@alexcrichton
Copy link
Member

Now that being said I think we're also storing Vec<String> in a few places instead of Vec<OsString>, so there's also changes to be had on the Cargo side as well

@BurntSushi
Copy link
Member

Yeah, docopt should grow support for this. The arg parser itself is written to work on &str, so there are a fair amount of guts that will have to change, but shouldn't be too bad.

@johnbartholomew
Copy link
Contributor

johnbartholomew commented Sep 8, 2018

This issue still seems valid in September 2018, after cargo switched to a different flag parsing library (clap).

// main.rs
fn main() {
    for input in std::env::args_os().skip(1) {
        println!("input: {}", input.to_str().unwrap_or("<not a UTF-8 path>"));
    }
}
$ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s                                                                                                   

$ ./target/debug/example test $(printf '\xff')
input: "test"
input: "<not a UTF-8 path>"

$ cargo run -- test $(printf '\xff')
thread 'main' panicked at 'unexpected invalid UTF-8 code point', libcore/option.rs:989:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

bors added a commit that referenced this issue Apr 15, 2019
… r=alexcrichton

Pass OsStr/OsString args through to the process spawned by cargo run.

This is intended to fix #2511, allowing non-UTF8 arguments to be passed through from cargo run to the spawned process. I was not sure whether the interface of cargo::ops needs to remain unchanged - I assume it does, so I added cargo::ops::run_os() taking &[OsString], and retained cargo::ops::run() with its current signature. If it's ok to change the internal cargo API then it may be better to just pass &[OsString] to run().

I have not tried to pass through OsStr/OsString to other places that could reasonably use them. Just one test added covering this path. It is restricted to `cfg(unix)` due to use of `std::os::unix::ffi::OsStrExt`.

This is my first pull request so I expect there will be changes needed to make this mergeable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants