From 6d4a3746f8afde1a7a24a40af5f9be4f77a56e2a Mon Sep 17 00:00:00 2001 From: lacatoire Date: Tue, 18 Aug 2026 07:42:11 +0200 Subject: [PATCH] fix(frenchtojd): range-check zend_long args before narrowing to int FrenchToSdn() takes C int parameters, so values like month=1+2**32 were silently truncated to their low 32 bits, aliasing into the valid range and bypassing the guard in french.c. Add an explicit range check against the zend_long variables in the PHP_FUNCTION wrapper, mirroring the guard that already exists inside FrenchToSdn(). This ensures out-of-range values always return 0, matching the documented contract. Fixes: #663 --- ext/calendar/calendar.c | 4 +++ ext/calendar/tests/frenchtojd_overflow.phpt | 29 +++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 ext/calendar/tests/frenchtojd_overflow.phpt diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c index f26d611092db..5e0cf1381570 100644 --- a/ext/calendar/calendar.c +++ b/ext/calendar/calendar.c @@ -550,6 +550,10 @@ PHP_FUNCTION(frenchtojd) RETURN_THROWS(); } + if (year < 1 || year > 14 || month < 1 || month > 13 || day < 1 || day > 30) { + RETURN_LONG(0); + } + RETURN_LONG(FrenchToSdn(year, month, day)); } /* }}} */ diff --git a/ext/calendar/tests/frenchtojd_overflow.phpt b/ext/calendar/tests/frenchtojd_overflow.phpt new file mode 100644 index 000000000000..5091f123d2d9 --- /dev/null +++ b/ext/calendar/tests/frenchtojd_overflow.phpt @@ -0,0 +1,29 @@ +--TEST-- +frenchtojd(): out-of-range arguments that alias into valid range via 32-bit narrowing must return 0 +--EXTENSIONS-- +calendar +--SKIPIF-- + +--FILE-- + 0 +// day out of range (aliases to 1) +var_dump(frenchtojd(1, 1 + $bias, 1)); // day 4294967297 -> 0 +// year out of range (aliases to 1) +var_dump(frenchtojd(1, 1, 1 + $bias)); // year 4294967297 -> 0 + +// Valid call still works +var_dump(frenchtojd(1, 1, 1)); // int(2375840) +?> +--EXPECT-- +int(0) +int(0) +int(0) +int(2375840)