FIX isValidTinForES() rejects almost every Spanish NIE starting with T (#39384)

The "Check NIE T" branch compared the control character of the TIN to the
return value of preg_match() instead of using preg_match() as the condition:

    if ($num[8] == preg_match('/^[T]{1}[A-Z0-9]{8}$/', $str)) {

Since execution only reaches that branch when the string already matched the
format, preg_match() always returns 1, so the test collapsed to
$num[8] == 1. A NIE of type T therefore validated only when its last
character was literally "1", and every other one was reported as -3
(invalid control key). Out of the 36 possible control characters, 35 were
wrongly rejected.

A NIE starting with T has no control key algorithm, so matching the
documented syntax is the only check to perform.

Also fill in and enable the testIsValidTinForES() unit test that was left
commented out with empty input strings.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
TowyTowy 2026-08-04 22:48:15 +02:00 committed by GitHub
parent 4116c251da
commit 9d10392d66
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 12 deletions

View file

@ -227,7 +227,8 @@ function isValidTinForES($str)
//Check NIE T
if (preg_match('/^[T]{1}/', $str)) {
if ($num[8] == preg_match('/^[T]{1}[A-Z0-9]{8}$/', $str)) {
// A NIE starting with T has no control key to check, so the syntax check is enough.
if (preg_match('/^[T]{1}[A-Z0-9]{8}$/', $str)) {
return 3;
} else {
return -3;

View file

@ -176,26 +176,30 @@ class ProfidLibTest extends CommonClassTest
$this->assertFalse(isValidTinForBE("ABCD.123.123")); // not digits only
}
// TODO
/**
* testIsValidTinForES
*
* @return void
*/
/*
public function testIsValidTinForES()
{
// Tests for NIF
$this->assertEquals(1, isValidTinForES("")); // valid NIF
$this->assertEquals(-1, isValidTinForES("")); // valid regex, but invalid control key
$this->assertEquals(1, isValidTinForES("12345678Z")); // valid NIF
$this->assertEquals(-1, isValidTinForES("12345678A")); // valid regex, but invalid control key
// Tests for CIF
$this->assertEquals(2, isValidTinForES("")); // valid CIF
$this->assertEquals(-2, isValidTinForES("")); // valid regex, but invalid control key
// Tests for NIE
$this->assertEquals(3, isValidTinForES("")); // valid NIE
$this->assertEquals(-3, isValidTinForES("")); // valid regex, but invalid control key
$this->assertEquals(2, isValidTinForES("A58818501")); // valid CIF
$this->assertEquals(-2, isValidTinForES("A58818502")); // valid regex, but invalid control key
// Tests for NIE starting with X, Y or Z (they have a control key)
$this->assertEquals(3, isValidTinForES("X1234567L")); // valid NIE
$this->assertEquals(3, isValidTinForES(" x 1234567 l ")); // valid NIE, formatted with spaces and lowercase
$this->assertEquals(-3, isValidTinForES("X1234567A")); // valid regex, but invalid control key
// Tests for NIE starting with T (they have no control key, so the syntax check is enough)
$this->assertEquals(3, isValidTinForES("T1234567A")); // valid NIE
$this->assertEquals(3, isValidTinForES("T1234567Z")); // valid NIE
$this->assertEquals(3, isValidTinForES("T12345671")); // valid NIE
// Tests for unknown error
$this->assertEquals(-4, isValidTinForES("")); // invalid regex for both NIF, CIF and NIE
$this->assertEquals(-4, isValidTinForES("I1234567A")); // valid regex, but first letter is not a known NIF, CIF or NIE prefix
// Tests for bad syntax
$this->assertEquals(0, isValidTinForES("12345")); // invalid regex for both NIF, CIF and NIE
}
*/
}