From bbc7c4c1a81e31e7e35302c78168ed431a81bb0f Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 19 Aug 2026 15:38:07 +0200 Subject: [PATCH 1/4] Add explicit check for both positive and negative integer overflows --- src/XMLSchema/Type/IntegerValue.php | 9 ++++++++- tests/XMLSchema/Type/IntegerOverflowTest.php | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/XMLSchema/Type/IntegerOverflowTest.php diff --git a/src/XMLSchema/Type/IntegerValue.php b/src/XMLSchema/Type/IntegerValue.php index 2ca85a4b..cdc00e7f 100644 --- a/src/XMLSchema/Type/IntegerValue.php +++ b/src/XMLSchema/Type/IntegerValue.php @@ -50,7 +50,14 @@ public function toInteger(): int { $value = $this->getValue(); - if (bccomp($value, strval(PHP_INT_MAX)) === 1) { + try { + $tooHigh = bccomp($value, (string)PHP_INT_MAX, 0) === 1; + $tooLow = bccomp($value, (string)PHP_INT_MIN, 0) === -1; + } catch (\ValueError $e) { + throw new SchemaViolationException("Not a well-formed integer string.", previous: $e); + } + + if ($tooHigh || $tooLow) { throw new RuntimeException("Cannot convert to integer: out of bounds."); } diff --git a/tests/XMLSchema/Type/IntegerOverflowTest.php b/tests/XMLSchema/Type/IntegerOverflowTest.php new file mode 100644 index 00000000..b3d9bbc7 --- /dev/null +++ b/tests/XMLSchema/Type/IntegerOverflowTest.php @@ -0,0 +1 @@ + Date: Wed, 19 Aug 2026 15:38:35 +0200 Subject: [PATCH 2/4] add unittests for int overflows --- tests/XMLSchema/Type/IntegerOverflowTest.php | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/tests/XMLSchema/Type/IntegerOverflowTest.php b/tests/XMLSchema/Type/IntegerOverflowTest.php index b3d9bbc7..a3ac9c40 100644 --- a/tests/XMLSchema/Type/IntegerOverflowTest.php +++ b/tests/XMLSchema/Type/IntegerOverflowTest.php @@ -1 +1,91 @@ $shouldPass + * @param string $integer + * @param string|null $message + */ + #[DataProvider('provideInvalidInteger')] + #[DataProvider('provideValidInteger')] + #[DataProviderExternal(IntegerTest::class, 'provideValidInteger')] + public function testInteger(bool|string $shouldPass, string $integer, ?string $message = null): void + { + try { + IntegerValue::fromString($integer)->toInteger(); + $this->assertTrue($shouldPass); + } catch (RuntimeException | SchemaViolationException $e) { + $this->assertSame($shouldPass, $e::class); + if ($message !== null) { + $this->assertSame($message, $e->getMessage()); + } + } + } + + + /** + * @return array + */ + public static function provideValidInteger(): array + { + return [ + 'valid with whitespace collapse' => [true, " 1234 \n "], + ]; + } + + + /** + * @return array, 1: string, 2?: string}> + */ + public static function provideInvalidInteger(): array + { + return [ + 'empty' => [SchemaViolationException::class, ''], + 'invalid positive signed out-of-bounds' => [ + RuntimeException::class, + '+9223372036854775808', + 'Cannot convert to integer: out of bounds.', + ], + 'invalid negative signed out-of-bounds' => [ + RuntimeException::class, + '-9223372036854775809', + 'Cannot convert to integer: out of bounds.', + ], + 'invalid' => [SchemaViolationException::class, '0x123'], + 'invalid with fractional' => [SchemaViolationException::class, '1234.'], + 'invalid with thousands-delimiter' => [SchemaViolationException::class, '+1,234'], + ]; + } + + public function testToIntegerWithNonWellFormedIntegerStringThrowsException(): void + { + $this->expectException(SchemaViolationException::class); + $this->expectExceptionMessageMatches('/^Not a well-formed integer string\.$/'); + + /* mock the internal rawValue to test the exception handling within IntegerValue::toInteger() */ + $value = $this->createPartialMock(IntegerValue::class, ['getRawValue']); + $value->expects($this->once())->method('getRawValue')->willReturn('0x42'); + $value->toInteger(); + } + +} From 1a86666be9d0a60b829aced5f085b3efae92e3a0 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 19 Aug 2026 15:39:20 +0200 Subject: [PATCH 3/4] Add tests for IntegerValue::toInteger() --- .../XMLSchema/Type/IntegerFromIntegerTest.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/XMLSchema/Type/IntegerFromIntegerTest.php diff --git a/tests/XMLSchema/Type/IntegerFromIntegerTest.php b/tests/XMLSchema/Type/IntegerFromIntegerTest.php new file mode 100644 index 00000000..5b6d8dbc --- /dev/null +++ b/tests/XMLSchema/Type/IntegerFromIntegerTest.php @@ -0,0 +1,46 @@ +assertSame((string) $integer, $value->getValue()); + $this->assertSame($integer, $value->toInteger()); + } + + + /** + * @return array + */ + public static function provideIntegers(): array + { + return [ + 'negative integer' => [-1234], + 'zero' => [0], + 'positive integer' => [1234], + 'minimum integer' => [PHP_INT_MIN], + 'maximum integer' => [PHP_INT_MAX], + ]; + } +} From 4f863d1be6f3d6201a3deca2ae5bf89969fc7602 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Wed, 19 Aug 2026 20:37:24 +0200 Subject: [PATCH 4/4] Fix coding style --- tests/XMLSchema/Type/IntegerOverflowTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/XMLSchema/Type/IntegerOverflowTest.php b/tests/XMLSchema/Type/IntegerOverflowTest.php index a3ac9c40..0424264f 100644 --- a/tests/XMLSchema/Type/IntegerOverflowTest.php +++ b/tests/XMLSchema/Type/IntegerOverflowTest.php @@ -77,6 +77,7 @@ public static function provideInvalidInteger(): array ]; } + public function testToIntegerWithNonWellFormedIntegerStringThrowsException(): void { $this->expectException(SchemaViolationException::class); @@ -87,5 +88,4 @@ public function testToIntegerWithNonWellFormedIntegerStringThrowsException(): vo $value->expects($this->once())->method('getRawValue')->willReturn('0x42'); $value->toInteger(); } - }