From c809789a67ce6c1df6c51d403c6b86d192c255c6 Mon Sep 17 00:00:00 2001 From: MohamedAklamaash Date: Mon, 6 Jul 2026 22:36:41 +0530 Subject: [PATCH] Fix EsNieRecognizer.validate_result raising instead of returning False isdigit was referenced without being called, so the digit guard was always truthy and never actually checked anything. Under the recognizer's default pattern this stays hidden since the middle characters are already constrained to digits, but a custom patterns argument (which the constructor explicitly supports) can let non-digit text reach the checksum line further down and raise a ValueError instead of returning False. Fixes #2145 --- .../country_specific/spain/es_nie_recognizer.py | 2 +- presidio-analyzer/tests/test_es_nie_recognizer.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/presidio-analyzer/presidio_analyzer/predefined_recognizers/country_specific/spain/es_nie_recognizer.py b/presidio-analyzer/presidio_analyzer/predefined_recognizers/country_specific/spain/es_nie_recognizer.py index cc8a9601a3..a88cb15ea0 100644 --- a/presidio-analyzer/presidio_analyzer/predefined_recognizers/country_specific/spain/es_nie_recognizer.py +++ b/presidio-analyzer/presidio_analyzer/predefined_recognizers/country_specific/spain/es_nie_recognizer.py @@ -66,7 +66,7 @@ def validate_result(self, pattern_text: str) -> bool: letter = pattern_text[-1] # check last is a letter, and first is in X,Y,Z - if not pattern_text[1:-1].isdigit or pattern_text[:1] not in "XYZ": + if not pattern_text[1:-1].isdigit() or pattern_text[:1] not in "XYZ": return False # check size is 8 or 9 if len(pattern_text) < 8 or len(pattern_text) > 9: diff --git a/presidio-analyzer/tests/test_es_nie_recognizer.py b/presidio-analyzer/tests/test_es_nie_recognizer.py index 0b91d1b98e..070d83fbeb 100644 --- a/presidio-analyzer/tests/test_es_nie_recognizer.py +++ b/presidio-analyzer/tests/test_es_nie_recognizer.py @@ -1,7 +1,8 @@ import pytest +from presidio_analyzer import Pattern +from presidio_analyzer.predefined_recognizers import EsNieRecognizer from tests import assert_result -from presidio_analyzer.predefined_recognizers import EsNieRecognizer @pytest.fixture(scope="module") @@ -51,3 +52,11 @@ def test_when_all_es_nie_then_succeed( assert len(results) == expected_len for res, (st_pos, fn_pos) in zip(results, expected_positions): assert_result(res, entities[0], st_pos, fn_pos, max_score) + + +def test_when_custom_pattern_allows_non_digit_middle_then_no_crash(entities): + """A non-digit middle segment should be rejected, not raise.""" + loose_pattern = Pattern("NIE_LOOSE", r"\b[X-Z][0-9A-Za-z]{6}[A-Z]\b", 0.5) + recognizer = EsNieRecognizer(patterns=[loose_pattern]) + results = recognizer.analyze("XABCDEFG", entities) + assert results == []