Skip to content

Commit 23ad2c3

Browse files
MrmaxmeierBurntSushi
authored andcommitted
automata: fix validation order in dense::DFA::from_bytes
Closes #1295
1 parent 4085a67 commit 23ad2c3

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Bug fixes:
88
Fixes a memory usage regression for large regexes (introduced in `regex 1.9`).
99
* [BUG #1165](https://github.com/rust-lang/regex/issues/1083):
1010
Fixes a panic in the lazy DFA (can only occur for especially large regexes).
11+
* [BUG #1295](https://github.com/rust-lang/regex/pull/1295):
12+
Fixes a panic when deserializing a corrupted dense DFA.
1113

1214

1315
1.11.3 (2025-09-25)

regex-automata/src/dfa/dense.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,10 +2344,17 @@ impl<'a> DFA<&'a [u32]> {
23442344
// table, match states and accelerators below. If any validation fails,
23452345
// then we return an error.
23462346
let (dfa, nread) = unsafe { DFA::from_bytes_unchecked(slice)? };
2347+
// Note that validation order is important here:
2348+
//
2349+
// * `MatchState::validate` can be called with an untrusted DFA.
2350+
// * `TransistionTable::validate` uses `dfa.ms` through `match_len`.
2351+
// * `StartTable::validate` needs a valid transition table.
2352+
//
2353+
// So... validate the match states first.
2354+
dfa.accels.validate()?;
2355+
dfa.ms.validate(&dfa)?;
23472356
dfa.tt.validate(&dfa)?;
23482357
dfa.st.validate(&dfa)?;
2349-
dfa.ms.validate(&dfa)?;
2350-
dfa.accels.validate()?;
23512358
// N.B. dfa.special doesn't have a way to do unchecked deserialization,
23522359
// so it has already been validated.
23532360
for state in dfa.states() {
@@ -5235,7 +5242,10 @@ mod tests {
52355242
assert_eq!(Err(expected), got);
52365243
}
52375244

5238-
// This panics in TransitionTable::validate if the match states are not validated first.
5245+
// This panics in `TransitionTable::validate` if the match states are not
5246+
// validated first.
5247+
//
5248+
// See: https://github.com/rust-lang/regex/pull/1295
52395249
#[test]
52405250
fn regression_validation_order() {
52415251
let mut dfa = DFA::new("abc").unwrap();

0 commit comments

Comments
 (0)