From efddc8ec0f91b7352a2fcba1293ba711f22d508e Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 11 Aug 2026 17:22:30 +0800 Subject: [PATCH 1/2] ext/intl: apply open_basedir restriction to ResourceBundle bundle paths --- .../resourcebundle/resourcebundle_class.cpp | 19 ++++++++ .../tests/resourcebundle_open_basedir.phpt | 44 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 ext/intl/tests/resourcebundle_open_basedir.phpt diff --git a/ext/intl/resourcebundle/resourcebundle_class.cpp b/ext/intl/resourcebundle/resourcebundle_class.cpp index e5a0fe1eefc7..c0f9b1d34241 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.cpp +++ b/ext/intl/resourcebundle/resourcebundle_class.cpp @@ -20,6 +20,7 @@ extern "C" { #include #include +#include "main/fopen_wrappers.h" } #include @@ -39,6 +40,16 @@ zend_class_entry *ResourceBundle_ce_ptr = NULL; static zend_object_handlers ResourceBundle_object_handlers; +static zend_result resourcebundle_check_open_basedir(const char *bundlename, size_t bundlename_len) +{ + if (bundlename != NULL && bundlename_len != 0 && php_check_open_basedir(bundlename)) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "open_basedir restriction in effect"); + return FAILURE; + } + + return SUCCESS; +} + /* {{{ ResourceBundle_object_free */ static void ResourceBundle_object_free( zend_object *object ) { @@ -113,6 +124,10 @@ static zend_result resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) return FAILURE; } + if (resourcebundle_check_open_basedir(bundlename, bundlename_len) == FAILURE) { + return FAILURE; + } + if (fallback) { rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); } else { @@ -357,6 +372,10 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(resourcebundle_locales) bundlename = NULL; } + if (resourcebundle_check_open_basedir(bundlename, bundlename_len) == FAILURE) { + RETURN_FALSE; + } + icuenum = ures_openAvailableLocales( bundlename, &icuerror ); INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); diff --git a/ext/intl/tests/resourcebundle_open_basedir.phpt b/ext/intl/tests/resourcebundle_open_basedir.phpt new file mode 100644 index 000000000000..6b3a006ca5a0 --- /dev/null +++ b/ext/intl/tests/resourcebundle_open_basedir.phpt @@ -0,0 +1,44 @@ +--TEST-- +ResourceBundle bundle paths respect open_basedir +--EXTENSIONS-- +intl +--INI-- +open_basedir=. +display_errors=1 +log_errors=0 +--FILE-- +getMessage(), PHP_EOL; +} + +var_dump(ResourceBundle::create('root', $outside)); +var_dump(ResourceBundle::getLocales($outside)); +?> +--EXPECTF-- +bool(true) +array(2) { + [0]=> + string(2) "es" + [1]=> + string(4) "root" +} + +Warning: ResourceBundle::__construct(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d +IntlException: ResourceBundle::__construct(): open_basedir restriction in effect + +Warning: ResourceBundle::create(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d +NULL + +Warning: ResourceBundle::getLocales(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d +bool(false) From c6c7c2acf44886fc063fdaaf01e7e4a65bd21767 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Tue, 11 Aug 2026 17:24:55 +0800 Subject: [PATCH 2/2] Update NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 35d78d928995..881f2ab9c0ea 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,7 @@ PHP NEWS after successful calls. (Weilin Du) . Fixed IntlNumberRangeFormatter leaving stale global error state after successful createFromSkeleton() and format() calls. (Weilin Du) + . Fixed ResourceBundle bundle paths to respect open_basedir. (Weilin Du) . Implemented GH-20255 (Add a predefined calendar constant in IntlDateFormatter for the proleptic gregorian calendar). (David Carlier) . Added SpoofChecker::areBidiConfusable(). (David Carlier)