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

Suggest handling case insensitivity on .ends_with(".ext") #6425

Closed
kangalio opened this issue Dec 6, 2020 · 6 comments · Fixed by #6500
Closed

Suggest handling case insensitivity on .ends_with(".ext") #6425

kangalio opened this issue Dec 6, 2020 · 6 comments · Fixed by #6500
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-suggestion Lint: Improving, adding or fixing lint suggestions

Comments

@kangalio
Copy link

kangalio commented Dec 6, 2020

What it does

When .ends_with() is called on a String or &str, and the parameter looks like a file extension (regex \.([a-z0-9]{1,5})|([A-Z0-9]{1,5})), inform the programmer that this code will not handle differently-cased filenames well - potentially a bug. Additionally, a correct replacement is suggested (see below).

Categories

  • Kind: clippy::pedantic or perhaps clippy::correctness

What is the advantage of the recommended code over the original code

It handles file extensions correctly regardless of case. In Windows, this behavior is very much expected since the entire operating system has case-insensitive filenames. In Linux, filenames are usually case-sensitive, but I think even on Linux, it's standard behavior to recognize file extensions regardless of case.

Drawbacks

  • The suggested improvement is harder to read than the naive case-sensitive version
  • The line .ends_with(".ext") might not be a file extension check at all. It could mean something else for which case-sensitivity makes sense

Example

if !filename.ends_with(".abc") {
    panic!("Please provide an ABC file");
}

Could be written as:

if filename.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("abc")) != Some(true) {
    panic!("Please provide an ABC file");
}

Or like this (nightly-only because of Path::eq_ignore_ascii_case):

let filename = Path::new(filename);
if filename.extension().map(|ext| ext.eq_ignore_ascii_case("abc")) != Some(true) {
    panic!("Please provide an ABC file");
}
@kangalio kangalio added the A-lint Area: New lints label Dec 6, 2020
@kangalio kangalio changed the title Suggest handling case insensitivity on .endswith(".ext") Suggest handling case insensitivity on .ends_with(".ext") Dec 6, 2020
@flip1995
Copy link
Member

flip1995 commented Dec 6, 2020

If we should lint this, we should only lint the case, where filename is a Path. If we would also lint strings, this will have too many FPs, I think.

@flip1995 flip1995 added L-suggestion Lint: Improving, adding or fixing lint suggestions good-first-issue These issues are a good way to get started with Clippy labels Dec 6, 2020
@kangalio
Copy link
Author

kangalio commented Dec 6, 2020

So like, the lint should trigger only on this kind of thing?

// filename: Path
filename.ends_with(".ext")

Probably nobody is going to write this code, because ends_with on Path doesn't work with the file extension at all. So the above code would fail to return the expected value for almost all inputs, so the programmer will know by themselves that they did something wrong.

The reason for this is that Path::ends_with only considers whole path components to match.

If it would produce too many false positive's to have the lint trigger on strings, I don't think there's any purpose left for this lint suggestion.

@flip1995
Copy link
Member

flip1995 commented Dec 6, 2020

Oh, yeah you're right. Don't know what I was thinking here 😅 Anyway, I would classify this lint as pedantic then and suggest to use the Path methods instead.

@kangalio
Copy link
Author

kangalio commented Dec 6, 2020

You mean, keep the original proposed behavior of triggering on str::starts_with (as opposed to Path), and classify as pedantic to not annoy regular users with false positives?

@flip1995
Copy link
Member

flip1995 commented Dec 6, 2020

Yes. And if on nightly suggest to convert the string to a path and suggest the path method.

Javier-varez added a commit to Javier-varez/rust-clippy that referenced this issue Dec 23, 2020
Closes rust-lang#6425

Looks for ends_with methods calls with case sensitive extensions.
Javier-varez added a commit to Javier-varez/rust-clippy that referenced this issue Dec 23, 2020
Closes rust-lang#6425

Looks for ends_with methods calls with case sensitive extensions.
Javier-varez added a commit to Javier-varez/rust-clippy that referenced this issue Dec 23, 2020
Closes rust-lang#6425

Looks for ends_with methods calls with case sensitive extensions.
Javier-varez added a commit to Javier-varez/rust-clippy that referenced this issue Jan 5, 2021
Closes rust-lang#6425

Looks for ends_with methods calls with case sensitive extensions.
bors added a commit that referenced this issue Jan 15, 2021
…llogiq

Case sensitive file extensions

Closes #6425

Looks for ends_with methods calls with case sensitive extension comparisons.

changelog: Add new lint that warns about case-sensitive file extension comparisons.
@bors bors closed this as completed in 61f3d9d Jan 15, 2021
@kadiwa4
Copy link
Contributor

kadiwa4 commented Jul 21, 2022

That usage of str::rsplit is misleading, see #9220.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-suggestion Lint: Improving, adding or fixing lint suggestions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants