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

StrSearcher does not behave correctly with empty strings as needle/haystack #85462

Closed
Luro02 opened this issue May 19, 2021 · 2 comments · Fixed by #87062
Closed

StrSearcher does not behave correctly with empty strings as needle/haystack #85462

Luro02 opened this issue May 19, 2021 · 2 comments · Fixed by #87062
Assignees
Labels
C-bug Category: This is a bug. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@Luro02
Copy link
Contributor

Luro02 commented May 19, 2021

I tried this code:

#![feature(pattern)]
use core::str::pattern::{Pattern, Searcher, SearchStep};

fn main() {
    let mut searcher = "".into_searcher("");

    assert_eq!(searcher.next(), SearchStep::Match(0, 0));
    assert_eq!(searcher.next(), SearchStep::Done);
    assert_eq!(searcher.next(), SearchStep::Done); // <- panics here
    assert_eq!(searcher.next(), SearchStep::Done);
}

I expected to see this happen:

The searcher should not return matches after SearchStep::Done, because the entire haystack has been already covered.

To quote from the documentation:

Returns Done if every byte of the haystack has been visited.

The stream of Match and Reject values up to a Done will contain index ranges that are adjacent, non-overlapping, covering the whole haystack, and laying on utf8 boundaries.

https://doc.rust-lang.org/std/str/pattern/trait.Searcher.html

Instead, this happened:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 2.10s
     Running `target/debug/playground`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Match(0, 0)`,
 right: `Done`', src/main.rs:9:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Meta

rustc --version --verbose:

rustc 1.54.0-nightly (79e50bf77 2021-05-10)
binary: rustc
commit-hash: 79e50bf77928f374921a6bcafee3fcff1915f062
commit-date: 2021-05-10
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.1
Backtrace

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.91s
     Running `target/debug/playground`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Match(0, 0)`,
 right: `Done`', src/main.rs:9:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/panicking.rs:92:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/panicking.rs:117:5
   4: playground::main
             at ./src/main.rs:9:5
   5: core::ops::function::FnOnce::call_once
             at /rustc/4e3e6db011c5b482d2bef8ba02274657f93b5e0d/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@Luro02 Luro02 added the C-bug Category: This is a bug. label May 19, 2021
@jonas-schievink jonas-schievink added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label May 19, 2021
@SkiFire13
Copy link
Contributor

SkiFire13 commented May 19, 2021

This also means that core::str::Matches (and maybe other str iterators too) is breaking the contract of its FusedIterator implementation

fn check_is_really_fused(mut it: impl core::iter::FusedIterator) {
    for _ in &mut it {}
    assert!(it.next().is_none()); // fails
}

fn main() {
    check_is_really_fused("".matches(""));
}

playground link

@poliorcetics
Copy link
Contributor

@rustbot claim

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 27, 2021
Make StrSearcher behave correctly on empty needle

Fix rust-lang#85462.

This will not affect ABI since the other variant of the enum is bigger.
It may break some code, but that would be very strange: usually people
don't continue after the first `Done` (or `None` for a normal iterator).

`@rustbot` label T-libs A-str A-patterns
@bors bors closed this as completed in 101a146 Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants