Merge pull request #3 from qingshi163/master

fix OpAssert positive lookbehind
This commit is contained in:
Noah
2021-02-03 09:06:37 -06:00
committed by GitHub
4 changed files with 36 additions and 4 deletions

View File

@@ -490,14 +490,24 @@ impl OpcodeDispatcher {
SreOpcode::ASSERT => twice(
|drive| {
let back = drive.peek_code(2) as usize;
let passed = drive.ctx().string_position - drive.state.start;
let passed = drive.ctx().string_position;
if passed < back {
drive.ctx_mut().has_matched = Some(false);
return None;
}
let back_offset = drive
.state
.string
.back_offset(drive.ctx().string_offset, back);
drive.state.string_position = drive.ctx().string_position - back;
drive.push_new_context(3);
drive.state.context_stack.last_mut().unwrap().toplevel = false;
let child_ctx = drive.state.context_stack.last_mut().unwrap();
child_ctx.toplevel = false;
child_ctx.string_position -= back;
child_ctx.string_offset = back_offset;
Some(())
},
|drive| {
@@ -512,14 +522,24 @@ impl OpcodeDispatcher {
SreOpcode::ASSERT_NOT => twice(
|drive| {
let back = drive.peek_code(2) as usize;
let passed = drive.ctx().string_position - drive.state.start;
let passed = drive.ctx().string_position;
if passed < back {
drive.skip_code(drive.peek_code(1) as usize + 1);
return None;
}
let back_offset = drive
.state
.string
.back_offset(drive.ctx().string_offset, back);
drive.state.string_position = drive.ctx().string_position - back;
drive.push_new_context(3);
drive.state.context_stack.last_mut().unwrap().toplevel = false;
let child_ctx = drive.state.context_stack.last_mut().unwrap();
child_ctx.toplevel = false;
child_ctx.string_position -= back;
child_ctx.string_offset = back_offset;
Some(())
},
|drive| {

View File

@@ -0,0 +1 @@
re.compile(r'(?<=abc)def')

View File

@@ -0,0 +1,2 @@
// '(?<=abc)def', flags=re.UNICODE
Pattern { code: &[15, 4, 0, 3, 3, 4, 9, 3, 17, 97, 17, 98, 17, 99, 1, 17, 100, 17, 101, 17, 102, 1], flags: SreFlag::from_bits_truncate(32) }

View File

@@ -24,3 +24,12 @@ fn test_2427() {
state = state.pymatch();
assert!(state.has_matched == Some(true));
}
#[test]
fn test_assert() {
// '(?<=abc)def', flags=re.UNICODE
let pattern = include!("positive_lookbehind.re");
let mut state = pattern.state("abcdef", 0..usize::MAX);
state = state.search();
assert!(state.has_matched == Some(true));
}