Hi!
We are a team of researchers studying memory safety in Rust. As part of our ongoing research, we tested scraper (version: 0.26.0) and found that the following code snippet is reported as undefined behavior by Miri:
Minimal Problematic Snippet
#![feature(allocator_api)]
extern crate alloc;
use scraper::*;
fn main() {
let v46 = "𮧵\u{1ade5}\u{5f709}";
let v47 = String::from(v46);
let v48: &'_ str = &v47;
let v49 = <Selector as std::convert::TryFrom<&'_ str>>::try_from(v48);
}
Miri Error Excerpt
error: Undefined Behavior: write access through <192023> at alloc80754[0x0] is forbidden
--> /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:535:12
|
535 | if self.inner().count.fetch_sub(1, Release) != 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
= help: the accessed tag <192023> is a child of the conflicting tag <191984>
= help: the conflicting tag <191984> has state Frozen which forbids this child write access
help: the accessed tag <192023> was created here
--> src/main.rs:9:1
|
9 | }
| ^
help: the conflicting tag <191984> was created here, in the initial state Frozen
--> src/main.rs:9:1
|
9 | }
| ^
= note: BACKTRACE (of the first span):
= note: inside `<servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>> as std::ops::Drop>::drop` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:535:12: 535:52
= note: inside `std::ptr::drop_in_place::<servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>> - shim(Some(servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `<servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>> as std::ops::Drop>::drop` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:1133:43: 1133:44
= note: inside `std::ptr::drop_in_place::<servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>>> - shim(Some(servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<selectors::parser::SelectorList<scraper::selector::Simple>> - shim(Some(selectors::parser::SelectorList<scraper::selector::Simple>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<scraper::Selector> - shim(Some(scraper::Selector))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<std::result::Result<scraper::Selector, scraper::error::SelectorErrorKind<'_>>> - shim(Some(std::result::Result<scraper::Selector, scraper::error::SelectorErrorKind<'_>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
note: inside `main`
--> src/main.rs:9:1
|
9 | }
| ^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
Human-Readable Reproduction
#![feature(allocator_api)]
extern crate alloc;
use scraper::*;
fn main() {
let v1 = "𮧵\u{1ade5}\u{5f709}";
let v2 = Selector::try_from(v1);
}
Miri Output of Human-Readable Reproduction
Command used:
MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri run
Result:
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
Running `/home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/Case_human_readable_case4`
warning: unused variable: `v2`
--> src/main.rs:6:9
|
6 | let v2 = Selector::try_from(v1);
| ^^ help: if this is intentional, prefix it with an underscore: `_v2`
|
= note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default
error: Undefined Behavior: attempting a write access using <190872> at alloc80707[0x20], but that tag does not exist in the borrow stack for this location
--> /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:809:21
|
809 | / ptr::write(
810 | | current,
811 | | items
812 | | .next()
813 | | .expect("ExactSizeIterator over-reported length"),
814 | | );
| |_____________________^ this error occurs as part of an access at alloc80707[0x20..0x48]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <190872> would have been created here, but this is a zero-size retag ([0x20..0x20]) so the tag in question does not exist anywhere
--> src/main.rs:6:14
|
6 | let v2 = Selector::try_from(v1);
| ^^^^^^^^^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_alloc::<{closure@servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_with_size<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>::{closure#0}}, selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:809:21: 814:22
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_with_size::<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:859:9: 865:10
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter::<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:876:9: 876:65
= note: inside `selectors::builder::SelectorBuilder::<scraper::selector::Simple>::build_with_specificity_and_flags` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/builder.rs:136:20: 139:14
= note: inside `selectors::builder::SelectorBuilder::<scraper::selector::Simple>::build` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/builder.rs:99:9: 99:66
= note: inside `selectors::parser::parse_selector::<'_, scraper::selector::Parser, scraper::selector::Simple>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:2857:24: 2857:53
= note: inside closure at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:585:36: 585:88
= note: inside `cssparser::parser::Parser::<'_, '_>::parse_entirely::<{closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:701:22: 701:33
= note: inside `cssparser::parser::parse_until_before::<'_, '_, {closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:1071:18: 1071:56
= note: inside `cssparser::parser::Parser::<'_, '_>::parse_until_before::<{closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:809:9: 809:86
= note: inside `selectors::parser::SelectorList::<scraper::selector::Simple>::parse_with_state::<'_, scraper::selector::Parser>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:583:28: 591:15
= note: inside `selectors::parser::SelectorList::<scraper::selector::Simple>::parse::<'_, scraper::selector::Parser>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:525:9: 531:10
= note: inside `scraper::Selector::parse` at /home/rose/projects/lifesonar-tests/scraper-0.26.0/src/selector.rs:35:9: 35:69
= note: inside `<scraper::Selector as std::convert::TryFrom<&str>>::try_from` at /home/rose/projects/lifesonar-tests/scraper-0.26.0/src/selector.rs:248:9: 248:27
note: inside `main`
--> src/main.rs:6:14
|
6 | let v2 = Selector::try_from(v1);
| ^^^^^^^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error; 1 warning emitted
If use the following command cargo miri run, the generated miri report is the following:
error: Undefined Behavior: attempting a write access using <190872> at alloc80707[0x20], but that tag does not exist in the borrow stack for this location
--> /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:809:21
|
809 | / ptr::write(
810 | | current,
811 | | items
812 | | .next()
813 | | .expect("ExactSizeIterator over-reported length"),
814 | | );
| |_____________________^ this error occurs as part of an access at alloc80707[0x20..0x48]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <190872> would have been created here, but this is a zero-size retag ([0x20..0x20]) so the tag in question does not exist anywhere
--> src/main.rs:6:14
|
6 | let v2 = Selector::try_from(v1);
| ^^^^^^^^^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_alloc::<{closure@servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_with_size<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>::{closure#0}}, selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:809:21: 814:22
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter_with_size::<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:859:9: 865:10
= note: inside `servo_arc::Arc::<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>::from_header_and_iter::<selectors::builder::ExactChain<smallvec::Drain<'_, [selectors::parser::Component<scraper::selector::Simple>; 32]>, std::iter::Cloned<std::slice::Iter<'_, selectors::parser::Component<scraper::selector::Simple>>>>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:876:9: 876:65
= note: inside `selectors::builder::SelectorBuilder::<scraper::selector::Simple>::build_with_specificity_and_flags` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/builder.rs:136:20: 139:14
= note: inside `selectors::builder::SelectorBuilder::<scraper::selector::Simple>::build` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/builder.rs:99:9: 99:66
= note: inside `selectors::parser::parse_selector::<'_, scraper::selector::Parser, scraper::selector::Simple>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:2857:24: 2857:53
= note: inside closure at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:585:36: 585:88
= note: inside `cssparser::parser::Parser::<'_, '_>::parse_entirely::<{closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:701:22: 701:33
= note: inside `cssparser::parser::parse_until_before::<'_, '_, {closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:1071:18: 1071:56
= note: inside `cssparser::parser::Parser::<'_, '_>::parse_until_before::<{closure@selectors::parser::SelectorList<scraper::selector::Simple>::parse_with_state<'_, scraper::selector::Parser>::{closure#0}}, selectors::parser::Selector<scraper::selector::Simple>, selectors::parser::SelectorParseErrorKind<'_>>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.36.0/src/parser.rs:809:9: 809:86
= note: inside `selectors::parser::SelectorList::<scraper::selector::Simple>::parse_with_state::<'_, scraper::selector::Parser>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:583:28: 591:15
= note: inside `selectors::parser::SelectorList::<scraper::selector::Simple>::parse::<'_, scraper::selector::Parser>` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.36.1/parser.rs:525:9: 531:10
= note: inside `scraper::Selector::parse` at /home/rose/projects/lifesonar-tests/scraper-0.26.0/src/selector.rs:35:9: 35:69
= note: inside `<scraper::Selector as std::convert::TryFrom<&str>>::try_from` at /home/rose/projects/lifesonar-tests/scraper-0.26.0/src/selector.rs:248:9: 248:27
note: inside `main`
--> src/main.rs:6:14
|
6 | let v2 = Selector::try_from(v1);
| ^^^^^^^^^^^^^^^^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error; 1 warning emitted
Other possible related undefined behaviour
We find that the following case can also trigger undefined behaviour by using miri:
#![feature(allocator_api)]
extern crate alloc;
use scraper::*;
fn main() {
let v8 = "\u{c4a93}\u{fd5ef}\u{b3e5a}";
let v9 = String::from(v8);
let v10: &'_ str = &v9;
let v11 = Selector::parse(v10);
}
The human readable version is:
#![feature(allocator_api)]
extern crate alloc;
use scraper::*;
fn main() {
let v1 = "\u{c4a93}\u{fd5ef}\u{b3e5a}";
let v2 = Selector::parse(v1);
}
The miri report is similar to the one provided earlier(using command MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri run):
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
Running `/home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/Case_human_readable_case21`
error: Undefined Behavior: write access through <191991> at alloc80742[0x0] is forbidden
--> /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:535:12
|
535 | if self.inner().count.fetch_sub(1, Release) != 1 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
= help: the accessed tag <191991> is a child of the conflicting tag <191952>
= help: the conflicting tag <191952> has state Frozen which forbids this child write access
help: the accessed tag <191991> was created here
--> src/main.rs:7:1
|
7 | }
| ^
help: the conflicting tag <191952> was created here, in the initial state Frozen
--> src/main.rs:7:1
|
7 | }
| ^
= note: BACKTRACE (of the first span):
= note: inside `<servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>> as std::ops::Drop>::drop` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:535:12: 535:52
= note: inside `std::ptr::drop_in_place::<servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>> - shim(Some(servo_arc::Arc<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `<servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>> as std::ops::Drop>::drop` at /home/rose/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.4.3/lib.rs:1133:43: 1133:44
= note: inside `std::ptr::drop_in_place::<servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>>> - shim(Some(servo_arc::ArcUnion<servo_arc::HeaderSlice<selectors::builder::SpecificityAndFlags, selectors::parser::Component<scraper::selector::Simple>>, servo_arc::HeaderSlice<(), selectors::parser::Selector<scraper::selector::Simple>>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<selectors::parser::SelectorList<scraper::selector::Simple>> - shim(Some(selectors::parser::SelectorList<scraper::selector::Simple>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<scraper::Selector> - shim(Some(scraper::Selector))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<std::result::Result<scraper::Selector, scraper::error::SelectorErrorKind<'_>>> - shim(Some(std::result::Result<scraper::Selector, scraper::error::SelectorErrorKind<'_>>))` at /home/rose/.rustup/toolchains/nightly-2025-12-06-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
note: inside `main`
--> src/main.rs:7:1
|
7 | }
| ^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error
We would appreciate it if you could take a look and confirm whether this behavior indicates a real issue or two real issues, or if it is a false positive / expected limitation of Miri.
Thank you very much for your time and for maintaining this great project!
Hi!
We are a team of researchers studying memory safety in Rust. As part of our ongoing research, we tested scraper (version: 0.26.0) and found that the following code snippet is reported as undefined behavior by Miri:
Minimal Problematic Snippet
Miri Error Excerpt
Human-Readable Reproduction
Miri Output of Human-Readable Reproduction
Command used:
MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri runResult:
If use the following command
cargo miri run, the generated miri report is the following:Other possible related undefined behaviour
We find that the following case can also trigger undefined behaviour by using miri:
The human readable version is:
The miri report is similar to the one provided earlier(using command
MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-tree-borrows" RUSTFLAGS=-Awarnings RUST_BACKTRACE=1 cargo miri run):We would appreciate it if you could take a look and confirm whether this behavior indicates a real issue or two real issues, or if it is a false positive / expected limitation of Miri.
Thank you very much for your time and for maintaining this great project!