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
| 38 | 38 | continue | |
| 39 | 39 | if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): | |
| 40 | 40 | 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) | |
| 43 | 42 | except ValueError as err: | |
| 44 | 43 | raise IDNAError( | |
| 45 | 44 | f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}" | |
| 46 | 45 | ) from err | |
| 46 | + | if not contextj_ok: | |
| 47 | + | raise InvalidCodepointContext(f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") | |
| 47 | 48 | elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): | |
| 48 | 49 | if not valid_contexto(label, pos): | |
| 49 | 50 | raise InvalidCodepointContext(f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}") |
The check that tells the two apart
fail→pass·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.