deno_lint
deno_lint copied to clipboard
UB in js_regex::Reader due to constructing invalid char
Hi, I run Miri on a lot of published crates to look for UB. It looks to me like there is a bug related to this code: https://github.com/denoland/deno_lint/blob/dfe78729850680b68e1659c64ea69bdee447e38c/src/js_regex/reader.rs#L125-L129
To reproduce, you can run
MIRIFLAGS=-Zmiri-disable-stacked-borrows cargo +nightly miri test
and you should eventually see this, plus a backtrace:
test js_regex::reader::tests::at_test_es_compliance ... error: Undefined Behavior: type validation failed: encountered 0x0000dbc0, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Note that you do need to disable stacked borrows checking to get to this test, there's probably aliasing problems elsewhere in this codebase.
The standard library also has a debug assertion for misuse of char::from_u32_unchecked
which can detect this. All standard library debug assertions are compiled out by default though, so you'll need to run something like this:
cargo +nightly test -Zbuild-std --target=x86_64-unknown-linux-gnu
and you should see something like this:
failures:
---- js_regex::reader::tests::at_test_es_compliance stdout ----
thread 'js_regex::reader::tests::at_test_es_compliance' panicked at 'called `Option::unwrap()` on a `None` value', /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/char/convert.rs:26:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- js_regex::tests::basic_invalid stdout ----
thread 'js_regex::tests::basic_invalid' panicked at 'called `Option::unwrap()` on a `None` value', /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/char/convert.rs:26:51
---- js_regex::tests::basic_valid stdout ----
thread 'js_regex::tests::basic_valid' panicked at 'called `Option::unwrap()` on a `None` value', /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/char/convert.rs:26:51
---- js_regex::tests::basic_invalid_2015 stdout ----
thread 'js_regex::tests::basic_invalid_2015' panicked at 'called `Option::unwrap()` on a `None` value', /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/char/convert.rs:26:51
---- js_regex::tests::unicode_group_names_invalid_2020 stdout ----
thread 'js_regex::tests::unicode_group_names_invalid_2020' panicked at 'called `Option::unwrap()` on a `None` value', /home/ben/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/char/convert.rs:26:51
failures:
js_regex::reader::tests::at_test_es_compliance
js_regex::tests::basic_invalid
js_regex::tests::basic_invalid_2015
js_regex::tests::basic_valid
js_regex::tests::unicode_group_names_invalid_2020
test result: FAILED. 302 passed; 5 failed; 9 ignored; 0 measured; 0 filtered out; finished in 0.17s
error: test failed, to rerun pass '--lib'
Ah, this bug actually originates in the js-regex
crate which seems to have been copy-pasted into this crate with https://github.com/denoland/deno_lint/pull/252