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

std::env::vars() panics on any non-utf8 env var, feels like a footgun #70251

Open
Arnavion opened this issue Mar 21, 2020 · 0 comments
Open

std::env::vars() panics on any non-utf8 env var, feels like a footgun #70251

Arnavion opened this issue Mar 21, 2020 · 0 comments

Comments

@Arnavion
Copy link

@Arnavion Arnavion commented Mar 21, 2020

Consider some code that is looking for an env var that it knows should be valid UTF-8. It would be tempted to use std::env::vars() for this:

let value =
    std::env::vars()
    .find_map(|(key, value)| if cond(key) { Some(value) } else { None })
    .unwrap();

(It doesn't know the exact name of the env var, hence the need to enumerate every env var and test the key with cond, rather than just using std::env::var().)

But this will panic if an unrelated env var that isn't convertible to String happens to be enumerated first, because Vars uses .into_string().unwrap() on both OsStrings that it gets from VarsOs. This behavior is documented on std::env::vars(), so it's by design.

So, to be robust against this failure mode, the code has to use std::env::vars_os() and test for String-iness itself:

let value =
    std::env::vars_os()
    .find_map(|(key, value)| {
        let key = key.into_string().ok()?;
        if cond(key) {
            let value = value.into_string().ok()?;
            Some(value)
        }
        else {
            None
        }
    }).unwrap();

Env vars are almost always out of the hands of one's code, and can come from any number of sources even the user running the program may not account for. So it seems to me that std::env::vars() as it's implemented today is a trivial way to crash unnecessarily and should never be used.

It would be nice if it skipped non-UTF-8 env vars instead. Or, if it's necessary to preserve compatibility with the current behavior (which it has had since 1.0), there was a new function that did (std::env::vars_utf8_only() ?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.