From 72305212adc7829e8bd54c11b776700098e63621 Mon Sep 17 00:00:00 2001 From: p1geondove Date: Wed, 11 Mar 2026 03:33:53 +0100 Subject: [PATCH 1/2] fix: correct match offset truncation for buffers larger than 4GB --- src/hyperscan/extension.c | 4 ++-- tests/test_hyperscan.py | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/hyperscan/extension.c b/src/hyperscan/extension.c index 57ce975..e072d10 100644 --- a/src/hyperscan/extension.c +++ b/src/hyperscan/extension.c @@ -238,7 +238,7 @@ static int hs_match_handler( PyGILState_STATE gstate; gstate = PyGILState_Ensure(); PyObject *rv = PyObject_CallFunction( - cctx->callback, "IIIIO", id, from, to, flags, cctx->ctx); + cctx->callback, "IKKIO", id, from, to, flags, cctx->ctx); int halt = 1; if (rv == NULL) { cctx->success = 0; @@ -273,7 +273,7 @@ static int ch_match_handler( } PyObject *rv = PyObject_CallFunction( cctx->callback, - "IIIIOO", + "IKKIOO", id, from, to, diff --git a/tests/test_hyperscan.py b/tests/test_hyperscan.py index e762b3b..076c860 100644 --- a/tests/test_hyperscan.py +++ b/tests/test_hyperscan.py @@ -506,3 +506,29 @@ def on_test_match(pattern_id, from_offset, to_offset, flags, context): test_db.scan(b"test", match_event_handler=on_test_match) assert len(test_matches) > 0, "Basic pattern matching should work" + + +def test_vectored_scan_large_offset(database_vector, mocker): + callback = mocker.Mock(return_value=None) + buffers = [ + b"x"*(2**32-1), + b"fo" + ] + database_vector.scan(buffers, match_event_handler=callback) + callback.assert_has_calls( + [ + mocker.call(0,0,2**32+1,0,None), + ], + ) + + +def test_stream_scan_large_offset(database_stream, mocker): + callback = mocker.Mock(return_value=None) + with database_stream.stream(match_event_handler=callback) as stream: + stream.scan(b"x"*(2**32-1)) + stream.scan(b"fo") + callback.assert_has_calls( + [ + mocker.call(0,0,2**32+1,0,None) + ], + ) From 3be9029e2d09393fce93e8d4b107440898e14820 Mon Sep 17 00:00:00 2001 From: p1geondove Date: Sat, 14 Mar 2026 00:35:07 +0100 Subject: [PATCH 2/2] adding slow mark to pytest --- pyproject.toml | 5 +++++ tests/conftest.py | 14 ++++++++++++++ tests/test_hyperscan.py | 2 ++ 3 files changed, 21 insertions(+) create mode 100644 tests/conftest.py diff --git a/pyproject.toml b/pyproject.toml index d62e954..744face 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -185,3 +185,8 @@ docs = [ "mkdocs-material>=9.5", "pymdown-extensions>=10.9", ] + +[tool.pytest.ini_options] +markers = [ + "slow: marks tests as slow", +] diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..5398b7f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,14 @@ +import pytest + +def pytest_addoption(parser): + parser.addoption( + "--run-slow", action="store_true", default=False, + help="Run slow tests" + ) + +def pytest_collection_modifyitems(config, items): + if not config.getoption("--run-slow"): + skip_slow = pytest.mark.skip(reason="Pass --run-slow to run") + for item in items: + if "slow" in item.keywords: + item.add_marker(skip_slow) diff --git a/tests/test_hyperscan.py b/tests/test_hyperscan.py index 076c860..fcfac2d 100644 --- a/tests/test_hyperscan.py +++ b/tests/test_hyperscan.py @@ -508,6 +508,7 @@ def on_test_match(pattern_id, from_offset, to_offset, flags, context): assert len(test_matches) > 0, "Basic pattern matching should work" +@pytest.mark.slow def test_vectored_scan_large_offset(database_vector, mocker): callback = mocker.Mock(return_value=None) buffers = [ @@ -522,6 +523,7 @@ def test_vectored_scan_large_offset(database_vector, mocker): ) +@pytest.mark.slow def test_stream_scan_large_offset(database_stream, mocker): callback = mocker.Mock(return_value=None) with database_stream.stream(match_event_handler=callback) as stream: