diff --git a/.github/scripts/windows/find-target-branch.bat b/.github/scripts/windows/find-target-branch.bat index 89652bc..bac6c8b 100644 --- a/.github/scripts/windows/find-target-branch.bat +++ b/.github/scripts/windows/find-target-branch.bat @@ -1,8 +1,18 @@ @echo off -for /f "usebackq tokens=3" %%i in (`findstr PHP_MAJOR_VERSION main\php_version.h`) do set BRANCH=%%i -for /f "usebackq tokens=3" %%i in (`findstr PHP_MINOR_VERSION main\php_version.h`) do set BRANCH=%BRANCH%.%%i - -if /i "%BRANCH%" equ "8.5" ( - set BRANCH=master -) +rem Pin the PHP SDK dependency series to 8.5 (vs17). +rem +rem We build php-src's dev tip (true-async == 8.6-dev) on the windows-2022 +rem runner, i.e. the vs17 / VS 2022 toolchain. php.net's deps server only +rem publishes the bleeding edge (branches "8.6" and "master") for the vs18 / +rem VS 2026 toolchain -- there is no vs17 build of those. The newest series +rem that ships vs17 dependencies is 8.5, and those libs (openssl, libxml2, +rem ...) build the 8.6 tip fine: the series tracks the toolchain, not the PHP +rem minor. Asking for "8.6"/"master" under --crt vs17 fails with +rem "CRT 'vs17' doesn't match any available for branch ...". +rem +rem Bump this to 8.6 once php.net publishes packages-8.6-vs17-*, or switch the +rem runner+PHP_BUILD_CRT to vs18 to follow the dev-tip deps directly. +rem (Old logic derived "8." and remapped a hardcoded 8.5 -> master; +rem it broke when php-src went 8.6 and the dev deps moved to vs18.) +set BRANCH=8.5 diff --git a/tests/phpt/server/compression/010-h1-buffered-gzip.phpt b/tests/phpt/server/compression/010-h1-buffered-gzip.phpt index 36e7322..817b24f 100644 --- a/tests/phpt/server/compression/010-h1-buffered-gzip.phpt +++ b/tests/phpt/server/compression/010-h1-buffered-gzip.phpt @@ -6,7 +6,8 @@ true_async --SKIPIF-- /dev/null')) === '') die('skip gunzip(1) not in PATH'); ?> --FILE-- /dev/null')) === '') die('skip gunzip(1) not in PATH'); ?> --FILE-- /dev/null')) === '') die('skip gzip(1) not in PATH'); ?> --FILE-- /dev/null')) === '') die('skip gunzip(1) not in PATH'); ?> --FILE-- +--FILE-- +getMessage(), "\n"; + } +} + +/* "/" resolves to the filesystem root → explicit guard. */ +check('ctor:root-slash', fn() => new StaticHandler('/x/', '/')); + +/* Leading slash is absolute on POSIX → a missing one reaches not-found + * (proving it cleared the absolute-path gate, unlike on Windows). */ +check('ctor:root-missing-abs', fn() => new StaticHandler('/x/', '/nonexistent-' . bin2hex(random_bytes(8)))); + +echo "done\n"; +?> +--EXPECTF-- +ctor:root-slash: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory must not be '/' +ctor:root-missing-abs: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory not found: %s +done diff --git a/tests/phpt/server/static/016-static-handler-validation.phpt b/tests/phpt/server/static/016-static-handler-validation.phpt index 87e1d6d..1fec6f2 100644 --- a/tests/phpt/server/static/016-static-handler-validation.phpt +++ b/tests/phpt/server/static/016-static-handler-validation.phpt @@ -45,15 +45,23 @@ check('ctor:prefix-double-slash', fn() => new StaticHandler('/a//b/', $root)); check('ctor:prefix-too-short', fn() => new StaticHandler('/', $root)); // len < 2 /* ---- Constructor: root-directory validation -------------------- */ +/* Cross-platform: feed an absolute-but-missing path under the system + * temp dir so it clears the absolute-path gate and hits the not-found + * branch on every OS (a bare "/..." path is NOT absolute on Windows). + * The POSIX-only root cases ("/" itself) live in 016-...-posix. */ +$absent_root = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'sh-absent-' . bin2hex(random_bytes(8)); check('ctor:root-empty', fn() => new StaticHandler('/x/', '')); check('ctor:root-relative', fn() => new StaticHandler('/x/', 'relative')); -check('ctor:root-missing', fn() => new StaticHandler('/x/', '/nonexistent-' . bin2hex(random_bytes(8)))); +check('ctor:root-missing', fn() => new StaticHandler('/x/', $absent_root)); check('ctor:root-not-a-dir', fn() => new StaticHandler('/x/', __FILE__)); -check('ctor:root-slash', fn() => new StaticHandler('/x/', '/')); /* ---- Happy path ------------------------------------------------ */ $sh = new StaticHandler('/static/', $root); -echo "happy-path: prefix=", $sh->getUrlPrefix(), " root-ok=", str_starts_with($sh->getRootDirectory(), '/') ? 'yes' : 'no', "\n"; +$gr = $sh->getRootDirectory(); +/* "absolute for this OS": leading slash on *nix, drive-letter / UNC on Windows. */ +$root_abs = $gr !== '' && (str_starts_with($gr, '/') || str_starts_with($gr, '\\') + || (strlen($gr) >= 2 && ctype_alpha($gr[0]) && $gr[1] === ':')); +echo "happy-path: prefix=", $sh->getUrlPrefix(), " root-ok=", $root_abs ? 'yes' : 'no', "\n"; echo "isLocked: ", $sh->isLocked() ? 'yes' : 'no', "\n"; /* ---- setIndexFiles: validation arms --------------------------- */ @@ -136,7 +144,6 @@ ctor:root-empty: TrueAsync\HttpServerInvalidArgumentException: StaticHandler roo ctor:root-relative: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory must be an absolute path ctor:root-missing: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory not found: %s ctor:root-not-a-dir: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory is not a directory: %s -ctor:root-slash: TrueAsync\HttpServerInvalidArgumentException: StaticHandler root directory must not be '/' happy-path: prefix=/static/ root-ok=yes isLocked: no idx:non-string: TrueAsync\HttpServerInvalidArgumentException: StaticHandler index files must be strings