Skip to content

Commit 84926f5

Browse files
committed
Add support to patch PHP builds
1 parent d1fe750 commit 84926f5

10 files changed

Lines changed: 210 additions & 46 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.patch text eol=lf
2+
*.diff text eol=lf

php/BuildPhp/BuildPhp.psd1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
FunctionsToExport = @(
6464
# Private functions (sorted)
6565
'Add-BuildRequirements',
66+
'Add-PhpSourcePatches',
6667
'Add-Path',
6768
'Add-PhpDeps',
6869
'Add-TestRequirements',
@@ -73,6 +74,7 @@
7374
'Get-PhpBuild',
7475
'Get-PhpSdk',
7576
'Get-PhpSrc',
77+
'Get-PhpSourcePatchFiles',
7678
'Get-PhpTestPack',
7779
'Get-SourcePhpVersion',
7880
'Get-TestSettings',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--- win32/build/mkdist.php
2+
+++ win32/build/mkdist.php
3+
@@ -191,11 +191,11 @@
4+
break;
5+
$checksum = 0;
6+
for ($i = 0; $i < 148; $i++)
7+
- $checksum += ord($hdr_data{$i});
8+
+ $checksum += ord($hdr_data[$i]);
9+
for ($i = 148; $i < 156; $i++)
10+
$checksum += 32;
11+
for ($i = 156; $i < 512; $i++)
12+
- $checksum += ord($hdr_data{$i});
13+
+ $checksum += ord($hdr_data[$i]);
14+
15+
$hdr = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $hdr_data);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--- ext/curl/config.w32
2+
+++ ext/curl/config.w32
3+
@@ -24,7 +24,10 @@
4+
!isNaN(ver_num) &&
5+
(CHECK_LIB("normaliz.lib", "curl", PHP_CURL) &&
6+
CHECK_LIB("libssh2.lib", "curl", PHP_CURL) &&
7+
- CHECK_LIB("nghttp2.lib", "curl", PHP_CURL))
8+
+ CHECK_LIB("nghttp2.lib", "curl", PHP_CURL) &&
9+
+ CHECK_LIB("brotlidec.lib", "curl", PHP_CURL) &&
10+
+ CHECK_LIB("brotlicommon.lib", "curl", PHP_CURL) &&
11+
+ CHECK_LIB("libzstd.lib", "curl", PHP_CURL))
12+
) {
13+
EXTENSION("curl", "interface.c multi.c share.c curl_file.c");
14+
AC_DEFINE('HAVE_CURL', 1, "Define to 1 if the PHP extension 'curl' is available.");
15+
--- ext/curl/tests/check_win_config.phpt
16+
+++ ext/curl/tests/check_win_config.phpt
17+
@@ -47,11 +47,11 @@
18+
PSL => No
19+
HTTPS_PROXY => Yes
20+
MULTI_SSL => %s
21+
-BROTLI => %s
22+
+BROTLI => Yes
23+
ALTSVC => Yes
24+
HTTP3 => No
25+
UNICODE => No
26+
-ZSTD => No
27+
+ZSTD => Yes
28+
HSTS => Yes
29+
GSASL => No
30+
Protocols => dict, file, ftp, ftps, gopher, %r(gophers, )?%rhttp, https, imap, imaps, ldap, ldaps, %r(mqtt, )?%rpop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp%r(, ws)?(, wss)?%r
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--- ext/curl/config.w32
2+
+++ ext/curl/config.w32
3+
@@ -12,7 +12,10 @@
4+
SETUP_ZLIB_LIB("curl", PHP_CURL) &&
5+
(CHECK_LIB("normaliz.lib", "curl", PHP_CURL) &&
6+
CHECK_LIB("libssh2.lib", "curl", PHP_CURL) &&
7+
- CHECK_LIB("nghttp2.lib", "curl", PHP_CURL))
8+
+ CHECK_LIB("nghttp2.lib", "curl", PHP_CURL) &&
9+
+ CHECK_LIB("brotlidec.lib", "curl", PHP_CURL) &&
10+
+ CHECK_LIB("brotlicommon.lib", "curl", PHP_CURL) &&
11+
+ CHECK_LIB("libzstd.lib", "curl", PHP_CURL))
12+
) {
13+
EXTENSION("curl", "interface.c multi.c share.c curl_file.c");
14+
AC_DEFINE('HAVE_CURL', 1, "Define to 1 if the PHP extension 'curl' is available.");
15+
--- ext/curl/tests/check_win_config.phpt
16+
+++ ext/curl/tests/check_win_config.phpt
17+
@@ -47,11 +47,11 @@
18+
PSL => No
19+
HTTPS_PROXY => Yes
20+
MULTI_SSL => %s
21+
-BROTLI => %s
22+
+BROTLI => Yes
23+
ALTSVC => Yes
24+
HTTP3 => No
25+
UNICODE => No
26+
-ZSTD => No
27+
+ZSTD => Yes
28+
HSTS => Yes
29+
GSASL => No
30+
Protocols => dict, file, ftp, ftps, gopher, %r(gophers, )?%rhttp, https, imap, imaps, ldap, ldaps, %r(mqtt, )?%rpop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp%r(, ws)?(, wss)?%r
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
function Add-PhpSourcePatches {
2+
<#
3+
.SYNOPSIS
4+
Apply configured PHP source patches for a version series.
5+
.PARAMETER PhpVersion
6+
PHP version or branch name.
7+
.PARAMETER SourceDirectory
8+
Extracted PHP source directory.
9+
#>
10+
[OutputType([System.IO.FileInfo[]])]
11+
param (
12+
[Parameter(Mandatory = $true, Position=0, HelpMessage='PHP Version')]
13+
[ValidateNotNull()]
14+
[ValidateLength(1, [int]::MaxValue)]
15+
[string] $PhpVersion,
16+
[Parameter(Mandatory = $true, Position=1, HelpMessage='Source directory')]
17+
[ValidateNotNull()]
18+
[ValidateLength(1, [int]::MaxValue)]
19+
[string] $SourceDirectory
20+
)
21+
begin {
22+
}
23+
process {
24+
$patchFiles = @(Get-PhpSourcePatchFiles -PhpVersion $PhpVersion)
25+
if ($patchFiles.Count -eq 0) {
26+
return @()
27+
}
28+
29+
$gitCommand = Get-Command git -ErrorAction SilentlyContinue
30+
if ($null -eq $gitCommand) {
31+
throw "Git is required for PHP source patches."
32+
}
33+
34+
foreach ($patchFile in $patchFiles) {
35+
& $gitCommand.Source -C $SourceDirectory apply -p0 --check $patchFile.FullName *> $null
36+
if ($LASTEXITCODE -eq 0) {
37+
& $gitCommand.Source -C $SourceDirectory apply -p0 $patchFile.FullName *> $null
38+
if ($LASTEXITCODE -ne 0) {
39+
throw "Failed to apply PHP source patch $($patchFile.Name) for PHP $PhpVersion."
40+
}
41+
42+
Write-Host "Applied PHP source patch ($($patchFile.Name)) in $SourceDirectory"
43+
continue
44+
}
45+
46+
& $gitCommand.Source -C $SourceDirectory apply -R -p0 --check $patchFile.FullName *> $null
47+
if ($LASTEXITCODE -eq 0) {
48+
Write-Host "Skipped PHP source patch ($($patchFile.Name)) in $SourceDirectory because it is already applied"
49+
continue
50+
}
51+
52+
throw "Failed to apply PHP source patch $($patchFile.Name) for PHP $PhpVersion."
53+
}
54+
55+
return $patchFiles
56+
}
57+
end {
58+
}
59+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function Get-PhpSourcePatchFiles {
2+
<#
3+
.SYNOPSIS
4+
Get patch files for a PHP version series.
5+
.PARAMETER PhpVersion
6+
PHP version or branch name.
7+
#>
8+
[OutputType([System.IO.FileInfo[]])]
9+
param (
10+
[Parameter(Mandatory = $true, Position=0, HelpMessage='PHP Version')]
11+
[ValidateNotNull()]
12+
[ValidateLength(1, [int]::MaxValue)]
13+
[string] $PhpVersion
14+
)
15+
begin {
16+
}
17+
process {
18+
$patchSeries = [regex]::Match($PhpVersion, '^\d+\.\d+').Value
19+
if ([string]::IsNullOrWhiteSpace($patchSeries)) {
20+
$patchSeries = $PhpVersion
21+
}
22+
23+
$patchDirectory = Join-Path $PSScriptRoot "..\config\patches\$patchSeries"
24+
25+
if (-not (Test-Path -Path $patchDirectory -PathType Container)) {
26+
return @()
27+
}
28+
29+
return @(
30+
Get-ChildItem -Path $patchDirectory -File |
31+
Where-Object { $_.Extension -in '.patch', '.diff' } |
32+
Sort-Object Name
33+
)
34+
}
35+
end {
36+
}
37+
}

php/BuildPhp/private/Get-PhpSrc.ps1

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ function Get-PhpSrc {
3939
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipFilePath, $currentDirectory)
4040
Rename-Item -Path "php-src-$ref" -NewName $directory
4141

42-
if ($PhpVersion -match '^7\.2\.\d+$') {
43-
Set-Content -Path (Join-Path $directoryPath 'win32/build/mkdist.php') -Value ((Get-Content -Raw -Path (Join-Path $directoryPath 'win32/build/mkdist.php')).Replace('$hdr_data{$i}', '$hdr_data[$i]')) -NoNewline
44-
}
42+
Add-PhpSourcePatches -PhpVersion $PhpVersion -SourceDirectory $directoryPath > $null
4543

4644
[System.IO.Compression.ZipFile]::CreateFromDirectory($directoryPath, $srcZipFilePath)
4745
}

php/BuildPhp/private/Invoke-CompatRunTestsPatch.ps1

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,16 @@ function Invoke-CompatRunTestsPatch {
1717
[string] $PatchPath
1818
)
1919
begin {
20-
function Get-PatchExecutable {
21-
$gitCommand = Get-Command git -ErrorAction SilentlyContinue
22-
if ($null -eq $gitCommand) {
23-
return $null
24-
}
25-
26-
$gitDirectory = Split-Path -Path $gitCommand.Source -Parent
27-
$candidateRoots = @(
28-
(Split-Path -Path $gitDirectory -Parent),
29-
(Split-Path -Path (Split-Path -Path $gitDirectory -Parent) -Parent)
30-
)
31-
32-
foreach ($gitRoot in $candidateRoots) {
33-
if ([string]::IsNullOrWhiteSpace($gitRoot)) {
34-
continue
35-
}
36-
37-
$gitPatch = Join-Path $gitRoot 'usr\bin\patch.exe'
38-
if (Test-Path -Path $gitPatch) {
39-
return $gitPatch
40-
}
41-
}
42-
43-
return $null
44-
}
4520
}
4621
process {
47-
$patchExecutable = Get-PatchExecutable
48-
if ($null -eq $patchExecutable) {
22+
$gitCommand = Get-Command git -ErrorAction SilentlyContinue
23+
if ($null -eq $gitCommand) {
4924
return $false
5025
}
5126

5227
$targetDirectory = Split-Path -Path $Path -Parent
53-
$targetFileName = Split-Path -Path $Path -Leaf
54-
55-
& $patchExecutable -N -s -d $targetDirectory -i $PatchPath
56-
$exitCode = $LASTEXITCODE
57-
58-
$rejectFile = Join-Path $targetDirectory "$targetFileName.rej"
59-
$originalFile = Join-Path $targetDirectory "$targetFileName.orig"
60-
if (Test-Path -Path $rejectFile) {
61-
Remove-Item -Path $rejectFile -Force
62-
}
63-
if (Test-Path -Path $originalFile) {
64-
Remove-Item -Path $originalFile -Force
65-
}
66-
67-
return $exitCode -eq 0
28+
& $gitCommand.Source -C $targetDirectory apply -p0 $PatchPath *> $null
29+
return $LASTEXITCODE -eq 0
6830
}
6931
end {
7032
}

php/BuildPhp/tests/BuildPhp.Tests.ps1

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,33 @@ Describe "$ModuleName Module - Testing Manifest File (.psd1)" {
5050
}
5151
}
5252

53-
Get-Module -Name $ModuleName | Remove-Module
53+
Describe "$ModuleName Module - PHP source patches" {
54+
Context "Patch file discovery" {
55+
It "Finds configured series patches for patch releases" {
56+
$patches = @(Get-PhpSourcePatchFiles -PhpVersion '7.2.34')
57+
58+
$patches.Count | Should Be 1
59+
$patches[0].Name | Should Be '0001-fix-mkdist-string-offsets.patch'
60+
}
61+
62+
It "Finds configured curl patch for PHP 8.4" {
63+
$patches = @(Get-PhpSourcePatchFiles -PhpVersion '8.4.11')
64+
65+
$patches.Count | Should Be 1
66+
$patches[0].Name | Should Be '0001-curl-add-brotli-and-zstd-on-windows.patch'
67+
}
68+
69+
It "Finds configured curl patch for PHP 8.5" {
70+
$patches = @(Get-PhpSourcePatchFiles -PhpVersion '8.5.5')
71+
72+
$patches.Count | Should Be 1
73+
$patches[0].Name | Should Be '0001-curl-add-brotli-and-zstd-on-windows.patch'
74+
}
75+
76+
It "Returns no patch files when a series has no configured patches" {
77+
@(Get-PhpSourcePatchFiles -PhpVersion '8.3.23').Count | Should Be 0
78+
}
79+
}
80+
}
81+
82+
Get-Module -Name $ModuleName | Remove-Module

0 commit comments

Comments
 (0)