One function

check_label in kjd/idna

The author described this change as Fix CONTEXTJ violations being masked as generic IDNAError (#260). It counts as a record because the check below fails on the code as it stood at 62f30346a and passes on 9067b803a, with nothing else changed between the two runs.

Projectkjd/idna
Fix saved2026-08-08
Sharing licenceBSD-3-Clause · LICENSE.md
Change size+3 2

What the code was meant to do, written into the code itself as a docstring

Run the full set of IDNA 2008 validity checks on a single label. Applies, in order: NFC normalisation (:func:`check_nfc`), hyphen restrictions (:func:`check_hyphen_ok`), the no-leading-combiner rule (:func:`check_initial_combiner`), per-codepoint validity (PVALID, CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule (:func:`check_bidi`). :param label: The label to validate. `bytes` or `bytearray` input is decoded as UTF-8 first. :raises IDNAError: If the label is empty or fails a structural rule. :raises InvalidCodepoint: If the label contains a DISALLOWED or UNASSIGNED codepoint. :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint is not valid in its context. :raises IDNABidiError: If the Bidi Rule is violated.

The change

3838 continue
3939 if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]):
4040 try:
41- if not valid_contextj(label, pos):
42- raise InvalidCodepointContext(f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}")
41+ contextj_ok = valid_contextj(label, pos)
4342 except ValueError as err:
4443 raise IDNAError(
4544 f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}"
4645 ) from err
46+ if not contextj_ok:
47+ raise InvalidCodepointContext(f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}")
4748 elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]):
4849 if not valid_contexto(label, pos):
4950 raise InvalidCodepointContext(f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}")

The check that tells the two apart

failpass·tests/test_idna.py::IDNATests::test_check_label_contextj_violation

Check file tests/test_idna.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.

Origin and history

The code before it62f30346a210028aa37b9002c3e4814a2c06416a
Broken version dated2026-08-01
Moduleidna.core
Units changedcheck_label
Fingerprint25884dc543db1d67
Checked2026-08-18 by goldset/0.1

Every field above is generated by our program. None of it is written by hand.