diff --git a/.appveyor/install.ps1 b/.appveyor/install.ps1 index fbcd032..6ee46d7 100644 --- a/.appveyor/install.ps1 +++ b/.appveyor/install.ps1 @@ -1,64 +1,61 @@ $ErrorActionPreference = "Stop" -if (-not (Test-Path 'C:\build-cache')) { - [void](New-Item 'C:\build-cache' -ItemType 'directory') +if (-not (Test-Path 'c:\build-cache')) { + [void](New-Item 'c:\build-cache' -ItemType 'directory') } $bname = "php-sdk-$env:BIN_SDK_VER.zip" -if (-not (Test-Path "C:\build-cache\$bname")) { - Invoke-WebRequest "https://github.com/Microsoft/php-sdk-binary-tools/archive/$bname" -OutFile "C:\build-cache\$bname" +Write-Host $bname +if (-not (Test-Path c:\build-cache\$bname)) { + Invoke-WebRequest "https://github.com/microsoft/php-sdk-binary-tools/archive/$bname" -OutFile "c:\build-cache\$bname" } $dname0 = "php-sdk-binary-tools-php-sdk-$env:BIN_SDK_VER" $dname1 = "php-sdk-$env:BIN_SDK_VER" -if (-not (Test-Path "C:\build-cache\$dname1")) { - Expand-Archive "C:\build-cache\$bname" 'C:\build-cache' - Move-Item "C:\build-cache\$dname0" "C:\build-cache\$dname1" +if (-not (Test-Path 'c:\build-cache\$dname1')) { + Expand-Archive "c:\build-cache\$bname" "c:\build-cache" + Move-Item "c:\build-cache\$dname0" "c:\build-cache\$dname1" } -$gareleases = Invoke-WebRequest "https://windows.php.net/downloads/releases/releases.json" | ConvertFrom-Json -$qareleases = Invoke-WebRequest "https://windows.php.net/downloads/qa/releases.json" | ConvertFrom-Json -$garev = [regex]::split($gareleases.$env:PHP_VER.version, '[^\d]')[2] -$qarev = [regex]::split($qareleases.$env:PHP_VER.version, '[^\d]')[2] -if ($qarev -gt $garev) { - $phpversion = $qareleases.$env:PHP_VER.version - $phprelease = 'QA' +$releases = @{ + '7.0' = '7.0.33'; + '7.1' = '7.1.33'; + '7.2' = '7.2.34'; + '7.3' = '7.3.33'; +} +if ($releases.ContainsKey($env:PHP_VER)) { + $phpversion = $releases.$env:PHP_VER; + $base_url = 'http://windows.php.net/downloads/releases/archives'; } else { - $phpversion = $gareleases.$env:PHP_VER.version - $phprelease = 'GA' + $releases = Invoke-WebRequest https://windows.php.net/downloads/releases/releases.json | ConvertFrom-Json + $phpversion = $releases.$env:PHP_VER.version + $base_url = 'http://windows.php.net/downloads/releases'; } $ts_part = '' if ($env:TS -eq '0') { $ts_part += '-nts' } + $bname = "php-devel-pack-$phpversion$ts_part-Win32-$env:VC-$env:ARCH.zip" -if (-not (Test-Path "C:\build-cache\$bname")) { - if ($phprelease -eq "GA") { - Invoke-WebRequest "https://windows.php.net/downloads/releases/$bname" -OutFile "C:\build-cache\$bname" - } else { - Invoke-WebRequest "https://windows.php.net/downloads/qa/$bname" -OutFile "C:\build-cache\$bname" - } +if (-not (Test-Path "c:\build-cache\$bname")) { + Invoke-WebRequest "$base_url/$bname" -OutFile "c:\build-cache\$bname" } $dname0 = "php-$phpversion-devel-$env:VC-$env:ARCH" $dname1 = "php-$phpversion$ts_part-devel-$env:VC-$env:ARCH" -if (-not (Test-Path "C:\build-cache\$dname1")) { - Expand-Archive "C:\build-cache\$bname" 'C:\build-cache' +if (-not (Test-Path "c:\build-cache\$dname1")) { + Expand-Archive "c:\build-cache\$bname" "c:\build-cache" if ($dname0 -ne $dname1) { - Move-Item "C:\build-cache\$dname0" "C:\build-cache\$dname1" + Move-Item "c:\build-cache\$dname0" "c:\build-cache\$dname1" } } -$env:PATH = "C:\build-cache\$dname1;$env:PATH" +$env:PATH = "c:\build-cache\$dname1;$env:PATH" $bname = "php-$phpversion$ts_part-Win32-$env:VC-$env:ARCH.zip" -if (-not (Test-Path "C:\build-cache\$bname")) { - if ($phprelease -eq "GA") { - Invoke-WebRequest "https://windows.php.net/downloads/releases/$bname" -OutFile "C:\build-cache\$bname" - } else { - Invoke-WebRequest "https://windows.php.net/downloads/qa/$bname" -OutFile "C:\build-cache\$bname" - } +if (-not (Test-Path "c:\build-cache\$bname")) { + Invoke-WebRequest "$base_url/$bname" -OutFile "c:\build-cache\$bname" } $dname = "php-$phpversion$ts_part-$env:VC-$env:ARCH" -if (-not (Test-Path "C:\build-cache\$dname")) { - Expand-Archive "C:\build-cache\$bname" "C:\build-cache\$dname" +if (-not (Test-Path "c:\build-cache\$dname")) { + Expand-Archive "c:\build-cache\$bname" "c:\build-cache\$dname" } $env:PATH = "c:\build-cache\$dname;$env:PATH" diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml new file mode 100644 index 0000000..b446743 --- /dev/null +++ b/.github/workflows/common.yml @@ -0,0 +1,60 @@ +name: Run tests + +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read + +jobs: + tests: + name: Execute tests on ${{ matrix.operating-system }} with PHP ${{ matrix.php-versions }} + runs-on: ${{ matrix.operating-system }} + strategy: + fail-fast: false + matrix: + operating-system: + - "ubuntu-latest" + - "macos-latest" + php-versions: + - "7.0" + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + - "8.1" + - "8.2" + - "8.3" + - "8.4" + - "8.5" + - "nightly" + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + tools: phpize + env: + update: true + + - uses: actions/checkout@v3 + + - name: Setup extension + run: | + phpize + ./configure --enable-scalar-objects + make + sudo make install + + - name: Make test + run: make test + + - name: Run tests + env: + REPORT_EXIT_STATUS: 1 + run: php run-tests.php -p `which php` --show-diff -d extension=`pwd`/modules/scalar_objects.so -q diff --git a/README.md b/README.md index b3929dd..2a5dcdb 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ load these APIs just include the `handlers/bootstrap.php` file. Installation ------------ -The master branch supports PHP version 7.0 to 8.0. Use the [version 0.2][version_0_2] -branch for PHP 5 support. +The master branch supports PHP version 7.0 to 8.1. The extension is incompatible +with the JIT compiler. ### Unix diff --git a/doc/string_api.md b/doc/string_api.md index 6c4e87e..e597934 100644 --- a/doc/string_api.md +++ b/doc/string_api.md @@ -325,6 +325,7 @@ length of the main string is not divisible by the chunk length, then the last ch > * This function corresponds to `str_split`. * It is perfectly valid to have a chunk length that is longer than the main string. + * Chunking an empty string results in an empty array. * The name `chunk()` was chosen, because `split()` seems more appropriate for the `explode` equivalent. Furthermore the corresponding array functionality is also named `chunk()`. diff --git a/handlers/string.php b/handlers/string.php index 7090dcd..3e49d07 100644 --- a/handlers/string.php +++ b/handlers/string.php @@ -125,6 +125,10 @@ public static function split($self, $separator, $limit = PHP_INT_MAX) { public static function chunk($self, $chunkLength = 1) { $self->verifyPositive($chunkLength, 'Chunk length'); + if ($self === '') { + // str_split() prior to PHP 8.2 is buggy and returns [''] instead. + return []; + } return str_split($self, $chunkLength); } diff --git a/scalar_objects.c b/scalar_objects.c index 84cf290..08816a9 100644 --- a/scalar_objects.c +++ b/scalar_objects.c @@ -82,10 +82,7 @@ static zval *get_object_zval_ptr_real( int type ) { if (op_type == IS_UNUSED) { - if (!SO_THIS) { - zend_error(E_ERROR, "Using $this when not in object context"); - } - + ZEND_ASSERT(SO_THIS && "Checked by get_object_zval_ptr_safe() beforehand"); return SO_THIS; } else { return get_zval_ptr_real(opline, op_type, node, execute_data, type); @@ -159,8 +156,15 @@ static zend_function *scalar_objects_get_indirection_func( ind->fn.handler = scalar_objects_indirection_func; ind->fn.scope = ce; ind->fn.fn_flags = ZEND_ACC_CALL_VIA_HANDLER | (fbc->common.fn_flags & keep_flags); + ind->fn.fn_flags |= ZEND_ACC_USER_ARG_INFO; ind->fn.num_args = fbc->common.num_args - 1; ind->fn.required_num_args = fbc->common.required_num_args - 1; +#if PHP_VERSION_ID >= 80000 + ind->fn.attributes = NULL; +#endif +#if PHP_VERSION_ID >= 80200 + ind->fn.T = 0; +#endif ind->fbc = fbc; if (fbc->common.arg_info) { diff --git a/tests/named_params.phpt b/tests/named_params.phpt new file mode 100644 index 0000000..9934392 --- /dev/null +++ b/tests/named_params.phpt @@ -0,0 +1,29 @@ +--TEST-- +Named parameters +--SKIPIF-- += 8.0 only'); +?> +--FILE-- +test(prefix: "P")); +var_dump($string->test(suffix: "S")); +var_dump($string->test(prefix: "P", suffix: "S")); +var_dump($string->test(suffix: "S", prefix: "P")); + +?> +--EXPECT-- +string(5) "PTest" +string(5) "TestS" +string(6) "PTestS" +string(6) "PTestS" diff --git a/tests/string.phpt b/tests/string.phpt index 2cfa1ec..ec61687 100644 --- a/tests/string.phpt +++ b/tests/string.phpt @@ -499,9 +499,7 @@ count(""): int(1) count("", 0): int(1) count("", 0, 0): int(1) repeat(3): string(0) "" -chunk(3): array(1) { - [0]=> - string(0) "" +chunk(3): array(0) { } replace("foo", "bar"): string(0) "" replace("foo", "bar", 1): string(0) ""