Skip to content

test(segment): cover override bounds, a pending byte and an empty piece - #285

Merged
siracozmen01 merged 1 commit into
mainfrom
test/segment-gaps
Nov 8, 2026
Merged

siracozmen01 merged 1 commit into
mainfrom
test/segment-gaps

Conversation

@siracozmen01

Copy link
Copy Markdown
Contributor

Problem

Source coverage of the suites at 0c2c23a found three refusals in src/segment.c that a host reaches through the public API with no test behind them. A mutant that weakens each one still passes every suite:

  • ValidOverrides never sees an override above U+DFFF, so codePoint >= 0xD800 alone, which would refuse every override from U+E000 up, survives. The edges U+DFFF and U+10FFFF are untested too.
  • muniSegmentIterator_FindBreaksAround is never called with a byte pending from an earlier piece while the cursor is still at offset 0, so dropping pendingCount != 0 survives and the call would read the last piece as the whole text.
  • muniSegmentIterator_Feed is never called with a NULL iterator, nor with an empty last piece (NULL and 0), so refusing every NULL piece survives.

Change

Tests only, in test/test_segment.c:

  • Overrides at U+DFFF are refused, and overrides at U+E000 and U+10FFFF are taken.
  • Feed refuses a NULL iterator, and an empty last piece ends the text with the break at its end.
  • A lead byte fed alone with more to follow, then the rest of its sequence as the last piece, makes FindBreaksAround return muni_errorState and leave its outputs alone.

Verification

  • Each of the three mutants survives on main and is killed with these tests (each mutant built and run against every suite).
  • tools/check.sh pr passes.

Closes #283

Work in progress: not built or run yet. Mutants for each gap are in
out/drafts/mutants-gaps.sh and have not run.
@siracozmen01 siracozmen01 added the test A missing or weak test label Nov 8, 2026

@siracozmen01 siracozmen01 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at e7ea8ba: ready, once CI goes green. I read the tests against include/maul-unicode/segment.h; I did not run the mutants.

Each new check expects the documented result, not just a failure:

  • Override bounds. SetBreakClassOverrides documents muni_errorInvalid for "a code point past U+10FFFF or a surrogate". U+DFFF expects exactly that. U+E000 and U+10FFFF, in strictly increasing order with a valid Sentence_Break class, expect muni_success. The codePoint >= 0xD800 mutant fails the second.
  • Feed. Feed(nullptr, ...) expects muni_errorInvalid ("a NULL argument"). The empty last piece (NULL, 0, false, which the header allows: "May be NULL when length is 0") expects muni_success, then NextBreak gives muni_success with offset == 2, the end of "ab". The first NextBreak returned muni_needMoreText, so no boundary came before it. That checks the value, not just that the call works.
  • The pending byte. The text so far is \xE0 with more to follow, then \xA0\x80 as the last piece. The iterator does not hold its whole text, so FindBreaksAround must answer muni_errorState and leave both outputs "as it was unless the call returns muni_success". before and after are 7 from the earlier refusal and are checked to still be 7. A mutant that reads the last piece as the whole text would return success there and fail.

The body has Problem, Change and Verification, and no column-0 name( line.

No findings.

@siracozmen01
siracozmen01 merged commit 06815a7 into main Nov 8, 2026
24 checks passed
@siracozmen01
siracozmen01 deleted the test/segment-gaps branch November 8, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test A missing or weak test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Three refusals in src/segment.c have no test behind them

1 participant