]> git.ipfire.org Git - thirdparty/vectorscan.git/commit
Fix double-shufti accelerator missing matches across stream chunk boundaries (#402) develop
authoryoavwizstein <yoav.winstein@wiz.io>
Fri, 3 Jul 2026 10:14:22 +0000 (10:14 +0000)
committerGitHub <noreply@github.com>
Fri, 3 Jul 2026 10:14:22 +0000 (13:14 +0300)
commita1c107ed92b6cc811a6fbd6b7dfcc7f181e5ab85
treee9128806d1fbd6747f780f3035ed9f83768d33d1
parent77c9011a293c403215605ebf1af4bd11840a62d5
Fix double-shufti accelerator missing matches across stream chunk boundaries (#402)

* Fix double-shufti accelerator dropping cross-chunk matches in streaming mode

shuftiDoubleExec finds the first position i where byte[i] is in class1 and
byte[i+1] is in class2, so it must look one byte past the position it reports.
shuftiDoubleExecReal excludes the final buffer byte from its main loop and
defers it to check_last_byte, which zero-pads the absent byte[i+1].

check_last_byte only stopped on the last byte when it completed a single-char
(wildcard second char) pattern. When the last byte is merely the first char of
a double it was skipped. That is correct at true end-of-data, but at an
intermediate stream chunk boundary the second char is the first byte of the
next chunk, so the straddling match was silently dropped - a streaming
split-invariance violation.

Also stop on the last byte when it is in the first-char class (last_elem !=
0xff), returning buf_end-1. That is a resume point, not a reported match: the
engine re-examines the byte, carries the pending-first-char state into the next
chunk (fixing the false negative), and at true EOD finds nothing (no false
positive). The change is off the SIMD hot loop.

Add DoubleShuftiStreaming.SplitInvariant (block match set vs every streaming
split) and update the internal shufti tests to the new last-byte contract.

* double shufti accelerator fix for sve too
src/nfa/shufti_simd.hpp
src/nfa/shufti_sve.hpp
unit/hyperscan/identical.cpp
unit/internal/shufti.cpp