What version of regex are you using?
1.13.1
What's the high level problem?
It seems like there's an off-by-one error related to managing the "surrogate gap", the internal range of u32 values that are surrogate code points and therefore aren't a valid char. This error means that values like U+D7FF match their own negation.
What are the steps to reproduce the behavior?
#[test]
fn regression_negated_class_across_surrogate_hole() {
let re = Regex::new(r"^[^\x{D7FF}\x{E000}\x{000A}]$").unwrap();
// This assertion succeeds, 0A is excluded
assert!(!re.is_match("\u{000A}"), "U+000A is excluded by the class");
// This succeeds, 0B is INcluded
assert!(re.is_match("\u{000B}"), "U+000B is included by the class");
// These two do not
assert!(!re.is_match("\u{D7FF}"), "U+D7FF is excluded by the class");
assert!(!re.is_match("\u{E000}"), "U+E000 is excluded by the class");
}
What is the actual behavior?
The assertion fails
What is the expected behavior?
The assertion passes; D7FF and E000 shouldn't match their own negations.
What version of regex are you using?
1.13.1
What's the high level problem?
It seems like there's an off-by-one error related to managing the "surrogate gap", the internal range of
u32values that are surrogate code points and therefore aren't a validchar. This error means that values likeU+D7FFmatch their own negation.What are the steps to reproduce the behavior?
What is the actual behavior?
The assertion fails
What is the expected behavior?
The assertion passes;
D7FFandE000shouldn't match their own negations.