Skip to content

Fix: Return no match for forward searches past the string end - #348

Open
grouville wants to merge 2 commits into
ashvardanian:mainfrom
grouville:fix-forward-search-bounds
Open

grouville wants to merge 2 commits into
ashvardanian:mainfrom
grouville:fix-forward-search-bounds

Conversation

@grouville

@grouville grouville commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Forward searches currently require callers to keep the starting position inside the string. Passing a larger position reaches unchecked pointer and length calculations. The corresponding standard-library search safely returns no match, as requested in issue #275.

Check the starting position before those calculations and return npos, the existing no-match value, when it is past the end. Update the documented behavior. Searches starting exactly at the end keep their existing meaning.

The search unit tests pass in GCC C++11 and C++20. New cases cover valid end positions and positions beyond the string for substring, character, and character-set searches.

A minimal C++ check is:

#include <cassert>
#include <stringzilla/stringzilla.hpp>
namespace sz = ashvardanian::stringzilla;
int main() {
    sz::string_view view("abc");
    assert(view.find("", 4) == sz::string_view::npos);
    assert(view.find('a', 4) == sz::string_view::npos);
    assert(view.find_first_of("a", 4) == sz::string_view::npos);
}

These positions previously fell outside the documented contract and could reach unchecked pointer arithmetic. They now return npos, matching the requested STL bounds policy. No new public interface or exception is introduced.

Please merge #346 first. This branch includes that small prerequisite; GitHub removes it from this PR's diff after it merges. You can review just this fix now at grouville/StringZilla@fix-default-empty-view...fix-forward-search-bounds.

Current CI note: full CI is still red. The C++ search tests pass in the failed jobs reviewed so far, but several Python jobs crash. An isolated build of unchanged main also fails a memory check when reversing an empty collection. A separate signed repair is prepared at main...grouville:fix-empty-reverse-sort; its C++ memory checks and 4,537 Python tests pass locally. Windows, macOS and Arm runtime checks remain pending, and not every CI failure has been traced to this cause.

A default-constructed string view represents an empty string, but
searching it for an empty string reports no match. Constructing the view
from an empty string literal reports a match instead.

Return the matching position directly for an empty search. This makes
find, rfind, and contains agree for both empty representations. The
production change is two early returns.

The search unit tests pass in GCC C++11 and C++20. New cases cover read-
only views, writable views, owning strings, and reverse searches with a
position limit.
Forward searches currently require callers to keep the starting position
inside the string. Passing a larger position reaches unchecked pointer
and length calculations. The corresponding standard-library search
safely returns no match, as requested in issue ashvardanian#275.

Check the starting position before those calculations and return npos,
the existing no-match value, when it is past the end. Update the
documented behavior. Searches starting exactly at the end keep their
existing meaning.

The search unit tests pass in GCC C++11 and C++20. New cases cover valid
end positions and positions beyond the string for substring, character,
and character-set searches.
@grouville
grouville force-pushed the fix-forward-search-bounds branch from 3e1a636 to a61c56c Compare October 8, 2026 09:05
@grouville grouville changed the title Fix: Return npos for forward searches beyond the view Fix: Return no match for forward searches past the string end Oct 8, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant