mirror of
https://github.com/chialab/docker-php.git
synced 2026-11-06 12:40:34 -04:00
Merge pull request #140 from chialab/secure-old-php-versions
build EOL PHP versions from source
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
name: Build image
|
||||
description: >
|
||||
Builds one image for the runner's architecture and tests it. The image is pushed either to the
|
||||
job's local registry, or by digest to ghcr, recording the digest for the publish workflow.
|
||||
|
||||
inputs:
|
||||
image:
|
||||
description: Image name without registry, e.g. php-dev.
|
||||
required: true
|
||||
tag:
|
||||
description: Image tag, e.g. 7.4-apache.
|
||||
required: true
|
||||
arch:
|
||||
description: Runner architecture (amd64 or arm64).
|
||||
required: true
|
||||
context:
|
||||
description: Build context.
|
||||
required: true
|
||||
file:
|
||||
description: Dockerfile path, relative to the repository root.
|
||||
default: ''
|
||||
build-args:
|
||||
description: Build arguments.
|
||||
default: ''
|
||||
build-contexts:
|
||||
description: Additional named build contexts.
|
||||
default: ''
|
||||
push:
|
||||
description: Where to push the image, "local" or "ghcr".
|
||||
default: local
|
||||
cache-write:
|
||||
description: Export the build cache to ghcr.
|
||||
default: 'false'
|
||||
no-cache:
|
||||
description: Ignore the build cache.
|
||||
default: 'false'
|
||||
test:
|
||||
description: Make directory whose "test" target checks the image; empty to skip testing.
|
||||
default: ''
|
||||
|
||||
outputs:
|
||||
ref:
|
||||
description: Reference to the built image, usable as BASE_IMAGE.
|
||||
value: ${{ steps.ref.outputs.ref }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Build ${{ inputs.image }}
|
||||
id: build
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ${{ inputs.context }}
|
||||
file: ${{ inputs.file }}
|
||||
build-args: ${{ inputs.build-args }}
|
||||
build-contexts: ${{ inputs.build-contexts }}
|
||||
no-cache: ${{ inputs.no-cache == 'true' }}
|
||||
cache-from: type=registry,ref=ghcr.io/chialab/${{ inputs.image }}:cache-${{ inputs.tag }}-${{ inputs.arch }}
|
||||
cache-to: ${{ inputs.cache-write == 'true' && format('type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ignore-error=true,ref=ghcr.io/chialab/{0}:cache-{1}-{2}', inputs.image, inputs.tag, inputs.arch) || '' }}
|
||||
tags: ${{ inputs.push == 'local' && format('localhost:5000/chialab/{0}:{1}', inputs.image, inputs.tag) || '' }}
|
||||
push: ${{ inputs.push == 'local' }}
|
||||
outputs: ${{ inputs.push == 'ghcr' && format('type=image,name=ghcr.io/chialab/{0},push-by-digest=true,name-canonical=true,push=true', inputs.image) || '' }}
|
||||
|
||||
- name: Resolve ${{ inputs.image }} reference
|
||||
id: ref
|
||||
shell: bash
|
||||
env:
|
||||
IMAGE: ${{ inputs.image }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
PUSH: ${{ inputs.push }}
|
||||
run: |
|
||||
if [[ "$PUSH" == 'ghcr' ]]; then
|
||||
echo "ref=ghcr.io/chialab/$IMAGE@$DIGEST" >> "$GITHUB_OUTPUT"
|
||||
mkdir -p "$RUNNER_TEMP/digests/$IMAGE"
|
||||
touch "$RUNNER_TEMP/digests/$IMAGE/${DIGEST#sha256:}"
|
||||
else
|
||||
echo "ref=localhost:5000/chialab/$IMAGE:$TAG" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Test ${{ inputs.image }}
|
||||
if: ${{ inputs.test != '' }}
|
||||
shell: bash
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ inputs.tag }}
|
||||
IMAGE: ${{ inputs.image }}
|
||||
REF: ${{ steps.ref.outputs.ref }}
|
||||
MAKE_DIR: ${{ inputs.test }}
|
||||
run: |
|
||||
docker pull "$REF"
|
||||
# the Makefile looks the image up by tag
|
||||
docker tag "$REF" "localhost:5000/chialab/$IMAGE:$VERSION"
|
||||
make -C "$MAKE_DIR" test
|
||||
@@ -6,6 +6,8 @@ updates:
|
||||
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
directories:
|
||||
- "/"
|
||||
- "/.github/actions/build-image"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
name: Build and test images
|
||||
|
||||
# Builds and tests each version × flavor natively on amd64 and arm64. Pull requests push to a local
|
||||
# registry; runs on main push by digest to ghcr and upload the digests for publish-images.yml.
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
versions:
|
||||
description: JSON list of PHP versions.
|
||||
type: string
|
||||
required: true
|
||||
flavors:
|
||||
description: JSON list of flavors.
|
||||
type: string
|
||||
default: '[""]'
|
||||
exclude:
|
||||
description: JSON list of version/flavor combinations to skip.
|
||||
type: string
|
||||
default: '[]'
|
||||
secrets:
|
||||
pull-username:
|
||||
required: true
|
||||
pull-password:
|
||||
required: true
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.version }}${{ matrix.flavor }} (${{ matrix.arch }})
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ${{ fromJSON(inputs.versions) }}
|
||||
flavor: ${{ fromJSON(inputs.flavors) }}
|
||||
arch: [ 'amd64', 'arm64' ]
|
||||
exclude: ${{ fromJSON(inputs.exclude) }}
|
||||
services:
|
||||
registry:
|
||||
image: ${{ github.event_name == 'pull_request' && 'registry:2' || '' }}
|
||||
ports:
|
||||
- 5000:5000
|
||||
env:
|
||||
PUSH: ${{ github.event_name == 'pull_request' && 'local' || 'ghcr' }}
|
||||
CACHE_WRITE: ${{ github.event_name != 'pull_request' }}
|
||||
# Scheduled runs rebuild the extension layers, so they pick up new extension and OS package
|
||||
# versions; the patched PHP base is only rebuilt when its inputs change.
|
||||
NO_CACHE: ${{ github.event_name == 'schedule' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Plan
|
||||
id: plan
|
||||
env:
|
||||
VERSION: ${{ matrix.version }}
|
||||
FLAVOR: ${{ matrix.flavor }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: |
|
||||
tag="$VERSION$FLAVOR"
|
||||
flavorDir="${FLAVOR#-}"
|
||||
eolDir="eol/$VERSION/${flavorDir:-cli}"
|
||||
[[ -d "$eolDir" ]] && eol=true || eol=false
|
||||
[[ "$tag" == *alpine* ]] && dockerfile=Dockerfile.alpine || dockerfile=Dockerfile
|
||||
[[ "$VERSION" == '5.6' && "$ARCH" == 'arm64' ]] && dev=false || dev=true
|
||||
[[ "$VERSION" == '5.6' || "$VERSION" == '7.0' ]] && pcov=false || pcov=true
|
||||
[[ "$ARCH" == 'amd64' ]] && xhprof=true || xhprof=false
|
||||
[[ "$VERSION" == 8.* || "$VERSION" == 'latest' || "$VERSION" == 'alpine' ]] && otel=true || otel=false
|
||||
{
|
||||
echo "tag=$tag"
|
||||
echo "eol=$eol"
|
||||
echo "eol-dir=$eolDir"
|
||||
echo "dockerfile=$dockerfile"
|
||||
echo "dev=$dev"
|
||||
echo "pcov=$pcov"
|
||||
echo "xhprof=$xhprof"
|
||||
echo "otel=$otel"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.pull-username }}
|
||||
password: ${{ secrets.pull-password }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build patched PHP base image
|
||||
id: base
|
||||
if: ${{ steps.plan.outputs.eol == 'true' }}
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php-base
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: ${{ steps.plan.outputs.eol-dir }}
|
||||
build-contexts: |
|
||||
patches=eol/patches
|
||||
scripts=eol/scripts
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
|
||||
- name: Build PHP image
|
||||
id: php
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: .
|
||||
file: ${{ steps.plan.outputs.dockerfile }}
|
||||
build-args: BASE_IMAGE=${{ steps.plan.outputs.eol == 'true' && steps.base.outputs.ref || format('php:{0}', steps.plan.outputs.tag) }}
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
no-cache: ${{ env.NO_CACHE }}
|
||||
test: .
|
||||
|
||||
- name: Build dev image
|
||||
if: ${{ steps.plan.outputs.dev == 'true' }}
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php-dev
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: ./dev
|
||||
build-args: BASE_IMAGE=${{ steps.php.outputs.ref }}
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
no-cache: ${{ env.NO_CACHE }}
|
||||
test: dev
|
||||
|
||||
- name: Build PCOV image
|
||||
if: ${{ steps.plan.outputs.pcov == 'true' }}
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php-pcov
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: ./pcov
|
||||
build-args: BASE_IMAGE=${{ steps.php.outputs.ref }}
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
no-cache: ${{ env.NO_CACHE }}
|
||||
test: pcov
|
||||
|
||||
- name: Build xhprof image
|
||||
if: ${{ steps.plan.outputs.xhprof == 'true' }}
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php-xhprof
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: ./xhprof
|
||||
build-args: BASE_IMAGE=${{ steps.php.outputs.ref }}
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
no-cache: ${{ env.NO_CACHE }}
|
||||
test: xhprof
|
||||
|
||||
- name: Build OTel image
|
||||
if: ${{ steps.plan.outputs.otel == 'true' }}
|
||||
uses: ./.github/actions/build-image
|
||||
with:
|
||||
image: php-otel
|
||||
tag: ${{ steps.plan.outputs.tag }}
|
||||
arch: ${{ matrix.arch }}
|
||||
context: ./otel
|
||||
build-args: BASE_IMAGE=${{ steps.php.outputs.ref }}
|
||||
push: ${{ env.PUSH }}
|
||||
cache-write: ${{ env.CACHE_WRITE }}
|
||||
no-cache: ${{ env.NO_CACHE }}
|
||||
test: otel
|
||||
|
||||
- name: Upload digests
|
||||
if: ${{ env.PUSH == 'ghcr' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ steps.plan.outputs.tag }}-${{ matrix.arch }}
|
||||
path: ${{ runner.temp }}/digests/
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
@@ -0,0 +1,92 @@
|
||||
name: Publish images
|
||||
|
||||
# Publishes the images built and tested by the triggering build-images.yml run: merges each
|
||||
# image's per-arch digests into a multi-arch tag on ghcr, then copies it to Docker Hub. Nothing is
|
||||
# rebuilt, and nothing is read from Docker Hub, so publishing doesn't count against its pull limits.
|
||||
# Callers must skip runs whose commit is no longer the head of main (github.sha), so an older
|
||||
# commit whose tests finished late can't overwrite the tags of a newer one.
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
versions:
|
||||
description: JSON list of PHP versions.
|
||||
type: string
|
||||
required: true
|
||||
flavors:
|
||||
description: JSON list of flavors.
|
||||
type: string
|
||||
default: '[""]'
|
||||
exclude:
|
||||
description: JSON list of version/flavor combinations to skip.
|
||||
type: string
|
||||
default: '[]'
|
||||
secrets:
|
||||
push-username:
|
||||
required: true
|
||||
push-password:
|
||||
required: true
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: ${{ fromJSON(inputs.versions) }}
|
||||
flavor: ${{ fromJSON(inputs.flavors) }}
|
||||
exclude: ${{ fromJSON(inputs.exclude) }}
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: digests-${{ matrix.version }}${{ matrix.flavor }}-{amd64,arm64}
|
||||
path: ${{ runner.temp }}/digests
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create multi-arch tags
|
||||
env:
|
||||
TAG: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
GHCR_USERNAME: ${{ github.repository_owner }}
|
||||
GHCR_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||
DOCKERHUB_USERNAME: ${{ secrets.push-username }}
|
||||
DOCKERHUB_PASSWORD: ${{ secrets.push-password }}
|
||||
run: |
|
||||
shopt -s nullglob
|
||||
cd "$RUNNER_TEMP/digests"
|
||||
for arch in amd64 arm64; do
|
||||
if [[ ! -d "digests-$TAG-$arch" ]]; then
|
||||
echo "Missing the $arch build of $TAG" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
for image in $(find . -mindepth 2 -maxdepth 2 -type d -printf '%f\n' | sort -u); do
|
||||
sources=()
|
||||
for digest in digests-*/"$image"/*; do
|
||||
sources+=("ghcr.io/chialab/$image@sha256:$(basename "$digest")")
|
||||
done
|
||||
docker buildx imagetools create -t "ghcr.io/chialab/$image:$TAG" "${sources[@]}"
|
||||
# The patched base image is internal and stays on ghcr.
|
||||
if [[ "$image" != 'php-base' ]]; then
|
||||
skopeo copy --all --preserve-digests \
|
||||
--src-creds "$GHCR_USERNAME:$GHCR_PASSWORD" \
|
||||
--dest-creds "$DOCKERHUB_USERNAME:$DOCKERHUB_PASSWORD" \
|
||||
"docker://ghcr.io/chialab/$image:$TAG" "docker://docker.io/chialab/$image:$TAG"
|
||||
fi
|
||||
done
|
||||
@@ -8,90 +8,16 @@ on:
|
||||
|
||||
jobs:
|
||||
publish-5:
|
||||
name: Build and publish PHP 5 images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.event_name != 'pull_request' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '5.6' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
exclude:
|
||||
- version: '5.6'
|
||||
flavor: '-alpine'
|
||||
- version: '5.6'
|
||||
flavor: '-fpm-alpine'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to DockerHub (pull)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_1 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_1 }}
|
||||
|
||||
- name: Pull base image
|
||||
run: docker pull chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
|
||||
- name: Login to DockerHub (push)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build dev image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build xhprof image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
name: Publish PHP 5 images
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/publish-images.yml
|
||||
with:
|
||||
versions: '["5.6"]'
|
||||
flavors: '["", "-apache", "-fpm"]'
|
||||
secrets:
|
||||
push-username: ${{ secrets.DOCKER_USERNAME }}
|
||||
push-password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
+14
-100
@@ -8,103 +8,17 @@ on:
|
||||
|
||||
jobs:
|
||||
publish-7:
|
||||
name: Build and publish PHP 7 images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '7.0', '7.1', '7.2', '7.3', '7.4' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
exclude:
|
||||
- version: '7.0'
|
||||
flavor: '-alpine'
|
||||
- version: '7.0'
|
||||
flavor: '-fpm-alpine'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to DockerHub (pull)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_2 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_2 }}
|
||||
|
||||
- name: Pull base image
|
||||
run: docker pull chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
|
||||
- name: Login to DockerHub (push)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build dev image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build PCOV image and push to registry
|
||||
if: ${{ matrix.version >= 7.1 }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build xhprof image (amd64 only) and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
name: Publish PHP 7 images
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/publish-images.yml
|
||||
with:
|
||||
versions: '["7.0", "7.1", "7.2", "7.3", "7.4"]'
|
||||
flavors: '["", "-apache", "-fpm", "-alpine", "-fpm-alpine"]'
|
||||
exclude: '[{"version": "7.0", "flavor": "-alpine"}, {"version": "7.0", "flavor": "-fpm-alpine"}]'
|
||||
secrets:
|
||||
push-username: ${{ secrets.DOCKER_USERNAME }}
|
||||
push-password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
+13
-107
@@ -8,110 +8,16 @@ on:
|
||||
|
||||
jobs:
|
||||
publish-8:
|
||||
name: Build and publish PHP 8 images
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to DockerHub (pull)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_3 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_3 }}
|
||||
|
||||
- name: Pull base image
|
||||
run: docker pull chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
|
||||
- name: Login to DockerHub (push)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build dev image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build PCOV image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build xhprof image (amd64 only) and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Build OTel image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./otel
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: |
|
||||
chialab/php-otel:${{ matrix.version }}${{ matrix.flavor }}
|
||||
ghcr.io/chialab/php-otel:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
name: Publish PHP 8 images
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/publish-images.yml
|
||||
with:
|
||||
versions: '["8.0", "8.1", "8.2", "8.3", "8.4", "8.5"]'
|
||||
flavors: '["", "-apache", "-fpm", "-alpine", "-fpm-alpine"]'
|
||||
secrets:
|
||||
push-username: ${{ secrets.DOCKER_USERNAME }}
|
||||
push-password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
@@ -6,11 +6,17 @@ on:
|
||||
branches: [main]
|
||||
types: [completed]
|
||||
|
||||
# Every completed test run starts this workflow; runs that won't publish get their own group, so
|
||||
# they can't cancel a publish in progress.
|
||||
concurrency:
|
||||
group: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha && github.workflow || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
publish-compat:
|
||||
name: Build and publish compatibility images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -57,6 +63,7 @@ jobs:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: ./compat
|
||||
build-contexts: patches=eol/patches
|
||||
file: ${{ format('compat/{0}.{1}{2}', 'Dockerfile', matrix.version, matrix.flavor) }}
|
||||
tags: |
|
||||
chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }}
|
||||
|
||||
@@ -7,110 +7,16 @@ on:
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
publish-8:
|
||||
name: Build and publish PHP 8 images
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ 'latest', 'alpine' ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to DockerHub (pull)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_5 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_5 }}
|
||||
|
||||
- name: Pull base image
|
||||
run: docker pull chialab/php:${{ matrix.version }}
|
||||
|
||||
- name: Login to DockerHub (push)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}
|
||||
tags: |
|
||||
chialab/php:${{ matrix.version }}
|
||||
ghcr.io/chialab/php:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Build dev image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
tags: |
|
||||
chialab/php-dev:${{ matrix.version }}
|
||||
ghcr.io/chialab/php-dev:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Build PCOV image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
tags: |
|
||||
chialab/php-pcov:${{ matrix.version }}
|
||||
ghcr.io/chialab/php-pcov:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Build xhprof image (amd64 only) and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
tags: |
|
||||
chialab/php-xhprof:${{ matrix.version }}
|
||||
ghcr.io/chialab/php-xhprof:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Build OTel image and push to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-to: type=inline
|
||||
context: ./otel
|
||||
build-args: |
|
||||
BASE_IMAGE=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
tags: |
|
||||
chialab/php-otel:${{ matrix.version }}
|
||||
ghcr.io/chialab/php-otel:${{ matrix.version }}
|
||||
push: true
|
||||
publish-latest:
|
||||
name: Publish latest PHP images
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request' && github.event.workflow_run.head_sha == github.sha }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/publish-images.yml
|
||||
with:
|
||||
versions: '["latest", "alpine"]'
|
||||
secrets:
|
||||
push-username: ${{ secrets.DOCKER_USERNAME }}
|
||||
push-password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
@@ -12,79 +12,13 @@ on:
|
||||
jobs:
|
||||
test-5:
|
||||
name: Build and test PHP 5 images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '5.6' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
exclude:
|
||||
- version: '5.6'
|
||||
flavor: '-alpine'
|
||||
- version: '5.6'
|
||||
flavor: '-fpm-alpine'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_1 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_1 }}
|
||||
|
||||
- name: Build image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }} && make test'
|
||||
|
||||
- name: Build dev image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test dev image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }} && make -C dev test'
|
||||
|
||||
- name: Build xhprof image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test xhprof image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }} && make -C xhprof test'
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/build-images.yml
|
||||
with:
|
||||
versions: '["5.6"]'
|
||||
flavors: '["", "-apache", "-fpm"]'
|
||||
secrets:
|
||||
pull-username: ${{ secrets.DOCKER_PULL_USER_1 }}
|
||||
pull-password: ${{ secrets.DOCKER_PULL_PASS_1 }}
|
||||
|
||||
@@ -12,97 +12,14 @@ on:
|
||||
jobs:
|
||||
test-7:
|
||||
name: Build and test PHP 7 images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '7.0', '7.1', '7.2', '7.3', '7.4' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
exclude:
|
||||
- version: '7.0'
|
||||
flavor: '-alpine'
|
||||
- version: '7.0'
|
||||
flavor: '-fpm-alpine'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_2 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_2 }}
|
||||
|
||||
- name: Build image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }} && make test'
|
||||
|
||||
- name: Build dev image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test dev image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }} && make -C dev test'
|
||||
|
||||
- name: Build PCOV image for testing
|
||||
if: ${{ matrix.version >= 7.1 }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test PCOV image
|
||||
if: ${{ matrix.version >= 7.1 }}
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }} && make -C pcov test'
|
||||
|
||||
- name: Build xhprof image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test xhprof image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }} && make -C xhprof test'
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/build-images.yml
|
||||
with:
|
||||
versions: '["7.0", "7.1", "7.2", "7.3", "7.4"]'
|
||||
flavors: '["", "-apache", "-fpm", "-alpine", "-fpm-alpine"]'
|
||||
exclude: '[{"version": "7.0", "flavor": "-alpine"}, {"version": "7.0", "flavor": "-fpm-alpine"}]'
|
||||
secrets:
|
||||
pull-username: ${{ secrets.DOCKER_PULL_USER_2 }}
|
||||
pull-password: ${{ secrets.DOCKER_PULL_PASS_2 }}
|
||||
|
||||
+10
-103
@@ -12,106 +12,13 @@ on:
|
||||
jobs:
|
||||
test-8:
|
||||
name: Build and test PHP 8 images
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]
|
||||
flavor: [ '', '-apache', '-fpm', '-alpine', '-fpm-alpine' ]
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_3 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_3 }}
|
||||
|
||||
- name: Build image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }} && make test'
|
||||
|
||||
- name: Build dev image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test dev image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-dev:${{ matrix.version }}${{ matrix.flavor }} && make -C dev test'
|
||||
|
||||
- name: Build PCOV image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test PCOV image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-pcov:${{ matrix.version }}${{ matrix.flavor }} && make -C pcov test'
|
||||
|
||||
- name: Build xhprof image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test xhprof image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-xhprof:${{ matrix.version }}${{ matrix.flavor }} && make -C xhprof test'
|
||||
|
||||
- name: Build OTel image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./otel
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}${{ matrix.flavor }}
|
||||
tags: localhost:5000/chialab/php-otel:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
- name: Test OTel image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}${{ matrix.flavor }}
|
||||
run: 'docker pull localhost:5000/chialab/php-otel:${{ matrix.version }}${{ matrix.flavor }} && make -C otel test'
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/build-images.yml
|
||||
with:
|
||||
versions: '["8.0", "8.1", "8.2", "8.3", "8.4", "8.5"]'
|
||||
flavors: '["", "-apache", "-fpm", "-alpine", "-fpm-alpine"]'
|
||||
secrets:
|
||||
pull-username: ${{ secrets.DOCKER_PULL_USER_3 }}
|
||||
pull-password: ${{ secrets.DOCKER_PULL_PASS_3 }}
|
||||
|
||||
@@ -9,11 +9,14 @@ on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test-compat:
|
||||
name: Build and test compatibility images
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -40,6 +43,7 @@ jobs:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }}
|
||||
cache-to: type=inline
|
||||
context: ./compat
|
||||
build-contexts: patches=eol/patches
|
||||
file: ${{ format('compat/{0}.{1}{2}', 'Dockerfile', matrix.version, matrix.flavor) }}
|
||||
tags: localhost:5000/chialab/php-compat:${{ matrix.version }}${{ matrix.flavor }}
|
||||
push: true
|
||||
|
||||
@@ -12,105 +12,12 @@ on:
|
||||
jobs:
|
||||
test-latest:
|
||||
name: Build and test latest PHP images
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !contains(github.event.commits[0].message, '[skip ci]') && !contains(github.event.commits[0].message, '[ci skip]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version: [ 'latest', 'alpine' ]
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
ports:
|
||||
- 5000:5000
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_PULL_USER_5 }}
|
||||
password: ${{ secrets.DOCKER_PULL_PASS_5 }}
|
||||
|
||||
- name: Build image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
# cache-from: type=registry,ref=ghcr.io/chialab/php:${{ matrix.version }}
|
||||
cache-to: type=inline
|
||||
context: .
|
||||
file: ${{ ((contains(matrix.flavor, 'alpine') || matrix.version == 'alpine') && 'Dockerfile.alpine') || 'Dockerfile' }}
|
||||
build-args: |
|
||||
BASE_IMAGE=php:${{ matrix.version }}
|
||||
tags: localhost:5000/chialab/php:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Test image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}
|
||||
run: 'docker pull localhost:5000/chialab/php:${{ matrix.version }} && make test'
|
||||
|
||||
- name: Build dev image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./dev
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}
|
||||
tags: localhost:5000/chialab/php-dev:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Test dev image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}
|
||||
run: 'docker pull localhost:5000/chialab/php-dev:${{ matrix.version }} && make -C dev test'
|
||||
|
||||
- name: Build PCOV image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./pcov
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}
|
||||
tags: localhost:5000/chialab/php-pcov:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Test PCOV image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}
|
||||
run: 'docker pull localhost:5000/chialab/php-pcov:${{ matrix.version }} && make -C pcov test'
|
||||
|
||||
- name: Build xhprof image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./xhprof
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}
|
||||
tags: localhost:5000/chialab/php-xhprof:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Test xhprof image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}
|
||||
run: 'docker pull localhost:5000/chialab/php-xhprof:${{ matrix.version }} && make -C xhprof test'
|
||||
|
||||
- name: Build OTel image for testing
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
cache-to: type=inline
|
||||
context: ./otel
|
||||
build-args: |
|
||||
BASE_IMAGE=localhost:5000/chialab/php:${{ matrix.version }}
|
||||
tags: localhost:5000/chialab/php-otel:${{ matrix.version }}
|
||||
push: true
|
||||
|
||||
- name: Test OTel image
|
||||
env:
|
||||
REGISTRY: localhost:5000/
|
||||
VERSION: ${{ matrix.version }}
|
||||
run: 'docker pull localhost:5000/chialab/php-otel:${{ matrix.version }} && make -C otel test'
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
uses: ./.github/workflows/build-images.yml
|
||||
with:
|
||||
versions: '["latest", "alpine"]'
|
||||
secrets:
|
||||
pull-username: ${{ secrets.DOCKER_PULL_USER_5 }}
|
||||
pull-password: ${{ secrets.DOCKER_PULL_PASS_5 }}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
SHELL := /bin/bash
|
||||
ALL: build
|
||||
.PHONY: build test push
|
||||
.PHONY: build build-base test push
|
||||
|
||||
PARENT_IMAGE := php
|
||||
BASE_IMAGE_NAME := chialab/php-base
|
||||
IMAGE := chialab/php
|
||||
VERSION ?= latest
|
||||
PHP_VERSION = $(firstword $(subst -, ,$(VERSION)))
|
||||
FLAVOR = $(if $(findstring -,$(VERSION)),$(patsubst $(PHP_VERSION)-%,%,$(VERSION)),cli)
|
||||
# EOL versions are built from eol/ instead of the official images.
|
||||
EOL_DIR = $(wildcard eol/$(PHP_VERSION)/$(FLAVOR))
|
||||
BASE_IMAGE = $(if $(EOL_DIR),$(REGISTRY)$(BASE_IMAGE_NAME):$(VERSION),$(PARENT_IMAGE):$(VERSION))
|
||||
DOCKERFILE = $(if $(findstring alpine,$(VERSION)),Dockerfile.alpine,Dockerfile)
|
||||
|
||||
# Extensions.
|
||||
EXTENSIONS := \
|
||||
@@ -42,13 +48,21 @@ ifeq (,$(findstring $(PHP_VERSION), 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5
|
||||
EXTENSIONS += mysql
|
||||
endif
|
||||
|
||||
build:
|
||||
build: $(if $(EOL_DIR),build-base)
|
||||
@echo " =====> Building $(REGISTRY)$(IMAGE):$(VERSION)..."
|
||||
docker image build --quiet --build-arg 'BASE_IMAGE=$(PARENT_IMAGE):$(VERSION)' -t $(REGISTRY)$(IMAGE):$(VERSION) .
|
||||
docker image build --quiet --build-arg 'BASE_IMAGE=$(BASE_IMAGE)' -f $(DOCKERFILE) -t $(REGISTRY)$(IMAGE):$(VERSION) .
|
||||
|
||||
build-base:
|
||||
@if [[ -z "$(EOL_DIR)" ]]; then \
|
||||
echo 'No eol/ Dockerfile for $(VERSION)'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo " =====> Building $(BASE_IMAGE)..."
|
||||
docker image build --quiet --build-context patches=eol/patches --build-context scripts=eol/scripts -t $(BASE_IMAGE) $(EOL_DIR)
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@@ -71,6 +85,16 @@ test:
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
@if [[ "$(VERSION)" == *'-fpm'* ]]; then \
|
||||
if ! docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) php-fpm -t > /dev/null 2>&1; then \
|
||||
echo 'FAIL [php-fpm]'; \
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
@if [[ -n "$(EOL_DIR)" && -z `docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) sh -c '/bin/echo $$PHP_PATCHES'` ]]; then \
|
||||
echo 'FAIL [PHP_PATCHES]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if [[ -z `docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) composer --version 2> /dev/null | grep '^Composer version 2\.[0-9][0-9]*'` ]]; then \
|
||||
echo 'FAIL [Composer]'; \
|
||||
exit 1; \
|
||||
|
||||
@@ -57,6 +57,11 @@ If you are really desperate and need PHP 5.6 with support for MySQL 8.x, check t
|
||||
|
||||
As you might have guessed, all tags are built on top of the corresponding tag of the official image. Not all tags are supported in order to easen maintenance.
|
||||
|
||||
### Security backports for EOL versions
|
||||
The official images of unsupported PHP versions (5.6 to 8.1) no longer receive security fixes. For those versions we rebuild PHP from the official images' Dockerfiles (see [`eol/`](eol/)), on the same OS release, with security patches applied to the PHP sources. The image layout doesn't change, so `docker-php-ext-*` and `install-php-extensions` keep working.
|
||||
|
||||
The `PHP_PATCHES` environment variable and the `it.chialab.php.patches` label list what has been applied. `PHP_VERSION` and `php -v` still report the upstream version, so vulnerability scanners may keep flagging fixed issues.
|
||||
|
||||
## Installed extensions
|
||||
The following modules and extensions have been enabled,
|
||||
in addition to those you can already find in the [official PHP image](https://hub.docker.com/r/_/php/):
|
||||
|
||||
@@ -107,6 +107,13 @@ RUN set -xe; \
|
||||
|
||||
COPY --from=php:5.6 /usr/local/bin/docker-php-source /usr/local/bin/
|
||||
|
||||
# Security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
|
||||
@@ -167,6 +167,13 @@ RUN set -xe; \
|
||||
|
||||
COPY --from=php:5.6-apache /usr/local/bin/docker-php-source /usr/local/bin/
|
||||
|
||||
# Security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
|
||||
@@ -108,6 +108,13 @@ RUN set -xe; \
|
||||
|
||||
COPY --from=php:5.6-fpm /usr/local/bin/docker-php-source /usr/local/bin/
|
||||
|
||||
# Security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
|
||||
+6
-2
@@ -43,11 +43,11 @@ endif
|
||||
|
||||
build:
|
||||
@echo " =====> Building $(REGISTRY)$(IMAGE):$(VERSION)..."
|
||||
docker image build --quiet -t $(REGISTRY)$(IMAGE):$(VERSION) .
|
||||
docker image build --quiet --build-context patches=../eol/patches -f Dockerfile.$(VERSION) -t $(REGISTRY)$(IMAGE):$(VERSION) .
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@@ -74,6 +74,10 @@ test:
|
||||
echo 'FAIL [Composer]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if [[ -z `docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) sh -c '/bin/echo $$PHP_PATCHES'` ]]; then \
|
||||
echo 'FAIL [PHP_PATCHES]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
@mariadbClientApi=`docker container run --rm $(REGISTRY)$(IMAGE):$(VERSION) php -i | grep -e "Client API.*MariaDB" | wc -l`; \
|
||||
if [[ "$${mariadbClientApi}" -lt 4 ]]; then \
|
||||
echo 'FAIL [MariaDB]'; \
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ build:
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/fab49d4cb1c61e4f74c2dffe06961408212f054c/5.6/stretch/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
ENV PHP_EXTRA_BUILD_DEPS apache2-dev
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 5.6.40
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-5.6.40.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-5.6.40.tar.xz.asc"
|
||||
ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl1.0-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,221 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/fab49d4cb1c61e4f74c2dffe06961408212f054c/5.6/stretch/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 5.6.40
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-5.6.40.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-5.6.40.tar.xz.asc"
|
||||
ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl1.0-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
CMD ["php", "-a"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,261 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/fab49d4cb1c61e4f74c2dffe06961408212f054c/5.6/stretch/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 5.6.40
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-5.6.40.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-5.6.40.tar.xz.asc"
|
||||
ENV PHP_SHA256="1369a51eee3995d7fbd1c5342e5cc917760e276d561595b6052b21ace2656d1c" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=5.6,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl1.0-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -ex \
|
||||
&& cd /usr/local/etc \
|
||||
&& if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi \
|
||||
&& { \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf \
|
||||
&& { \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,280 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/0e5c984e02d9027c25794bfb5002a2f9da26a7ec/7.0/stretch/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN mkdir -p $PHP_INI_DIR/conf.d
|
||||
|
||||
##<autogenerated>##
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
apache2 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
/var/www/html \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
ENV PHP_EXTRA_BUILD_DEPS apache2-dev
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 1A4E8B7277C42E53DBA9C7B9BCAA30EA9C0D5763 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 7.0.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.0.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.0.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="ab8c5be6e32b1f8d032909dedaaaa4bbb1a209e519abb01a52ce3914f9a13d96" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,215 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/0e5c984e02d9027c25794bfb5002a2f9da26a7ec/7.0/stretch/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN mkdir -p $PHP_INI_DIR/conf.d
|
||||
|
||||
##<autogenerated>##
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 1A4E8B7277C42E53DBA9C7B9BCAA30EA9C0D5763 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 7.0.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.0.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.0.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="ab8c5be6e32b1f8d032909dedaaaa4bbb1a209e519abb01a52ce3914f9a13d96" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
CMD ["php", "-a"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,255 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/0e5c984e02d9027c25794bfb5002a2f9da26a7ec/7.0/stretch/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
# chialab: Debian stretch has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apt-get update && apt-get install -y \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
--no-install-recommends && rm -r /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN mkdir -p $PHP_INI_DIR/conf.d
|
||||
|
||||
##<autogenerated>##
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS 1A4E8B7277C42E53DBA9C7B9BCAA30EA9C0D5763 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
|
||||
|
||||
ENV PHP_VERSION 7.0.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.0.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.0.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="ab8c5be6e32b1f8d032909dedaaaa4bbb1a209e519abb01a52ce3914f9a13d96" PHP_MD5=""
|
||||
|
||||
RUN set -xe; \
|
||||
\
|
||||
fetchDeps=' \
|
||||
wget \
|
||||
'; \
|
||||
if ! command -v gpg > /dev/null; then \
|
||||
fetchDeps="$fetchDeps \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
"; \
|
||||
fi; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends $fetchDeps; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
wget -O php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
wget -O php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
command -v gpgconf > /dev/null && gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
php --version; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/5.6 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/5.6 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -ex \
|
||||
&& cd /usr/local/etc \
|
||||
&& if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi \
|
||||
&& { \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf \
|
||||
&& { \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,197 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/2bf33a859340cf4932a7bce5ae7bc935fc778b9d/7.1/alpine3.10/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.10
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
addgroup -g 82 -S www-data; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.9-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS A917B1ECDA84AEC2B568FED6F50ABC807BD5DCD0 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 1729F83938DA44E27BA0F4D3DBDB397470D12172
|
||||
|
||||
ENV PHP_VERSION 7.1.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.1.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.1.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="bd7c0a9bd5433289ee01fd440af3715309faf583f75832b64fe169c100d52968" PHP_MD5=""
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
libedit-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
export CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.1 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
CMD ["php", "-a"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,294 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/2bf33a859340cf4932a7bce5ae7bc935fc778b9d/7.1/buster/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
ENV PHP_EXTRA_BUILD_DEPS apache2-dev
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS A917B1ECDA84AEC2B568FED6F50ABC807BD5DCD0 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 1729F83938DA44E27BA0F4D3DBDB397470D12172
|
||||
|
||||
ENV PHP_VERSION 7.1.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.1.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.1.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="bd7c0a9bd5433289ee01fd440af3715309faf583f75832b64fe169c100d52968" PHP_MD5=""
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.1 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,226 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/2bf33a859340cf4932a7bce5ae7bc935fc778b9d/7.1/buster/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS A917B1ECDA84AEC2B568FED6F50ABC807BD5DCD0 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 1729F83938DA44E27BA0F4D3DBDB397470D12172
|
||||
|
||||
ENV PHP_VERSION 7.1.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.1.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.1.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="bd7c0a9bd5433289ee01fd440af3715309faf583f75832b64fe169c100d52968" PHP_MD5=""
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.1 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
CMD ["php", "-a"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,241 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/2bf33a859340cf4932a7bce5ae7bc935fc778b9d/7.1/alpine3.10/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.10
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
addgroup -g 82 -S www-data; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.9-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS A917B1ECDA84AEC2B568FED6F50ABC807BD5DCD0 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 1729F83938DA44E27BA0F4D3DBDB397470D12172
|
||||
|
||||
ENV PHP_VERSION 7.1.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.1.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.1.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="bd7c0a9bd5433289ee01fd440af3715309faf583f75832b64fe169c100d52968" PHP_MD5=""
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
libedit-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
export CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.1 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,270 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/2bf33a859340cf4932a7bce5ae7bc935fc778b9d/7.1/buster/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
##<autogenerated>##
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
##</autogenerated>##
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
|
||||
|
||||
ENV GPG_KEYS A917B1ECDA84AEC2B568FED6F50ABC807BD5DCD0 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 1729F83938DA44E27BA0F4D3DBDB397470D12172
|
||||
|
||||
ENV PHP_VERSION 7.1.33
|
||||
# chialab: the php.net mirror redirector is gone.
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.1.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.1.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="bd7c0a9bd5433289ee01fd440af3715309faf583f75832b64fe169c100d52968" PHP_MD5=""
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
if [ -n "$PHP_MD5" ]; then \
|
||||
echo "$PHP_MD5 *php.tar.xz" | md5sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors intead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/5.6 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.1 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
##<autogenerated>##
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
##</autogenerated>##
|
||||
@@ -0,0 +1,200 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/20ebff40bb865416f3767540df06ad1df384337d/7.2/alpine3.12/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.12
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
addgroup -g 82 -S www-data; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.9-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F
|
||||
|
||||
ENV PHP_VERSION 7.2.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.2.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.2.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.2,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
libedit-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
export CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.2 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.2 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,298 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/20ebff40bb865416f3767540df06ad1df384337d/7.2/buster/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
ENV PHP_EXTRA_BUILD_DEPS apache2-dev
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F
|
||||
|
||||
ENV PHP_VERSION 7.2.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.2.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.2.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.2,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.2 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.2 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
@@ -0,0 +1,229 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/20ebff40bb865416f3767540df06ad1df384337d/7.2/buster/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F
|
||||
|
||||
ENV PHP_VERSION 7.2.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.2.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.2.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.2,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.2 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.2 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,245 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/20ebff40bb865416f3767540df06ad1df384337d/7.2/alpine3.12/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.12
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
addgroup -g 82 -S www-data; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.9-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.9-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F
|
||||
|
||||
ENV PHP_VERSION 7.2.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.2.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.2.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.2,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
libedit-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
export CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.2 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.2 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,274 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/20ebff40bb865416f3767540df06ad1df384337d/7.2/buster/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
# chialab: Debian buster has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/buster-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F
|
||||
|
||||
ENV PHP_VERSION 7.2.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.2.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.2.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
# chialab: the SKS keyserver pool is gone.
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.2,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libedit-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
${PHP_EXTRA_BUILD_DEPS:-} \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-libedit \
|
||||
--with-openssl \
|
||||
--with-zlib \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
${PHP_EXTRA_CONFIGURE_ARGS:-} \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.2 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.2 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,215 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/35d0a696b273c31f41ae224f189c19e794df91ae/7.3/alpine3.15/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.15
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
|
||||
|
||||
ENV PHP_VERSION 7.3.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.3.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.3.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.3,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
# PHP < 8 doesn't know to look deeper for GNU libiconv: https://github.com/php/php-src/commit/b480e6841ecd5317faa136647a2b8253a4c2d0df
|
||||
ln -sv /usr/include/gnu-libiconv/*.h /usr/include/; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.3 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,307 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/35d0a696b273c31f41ae224f189c19e794df91ae/7.3/bullseye/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
|
||||
|
||||
ENV PHP_VERSION 7.3.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.3.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.3.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.3,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
apache2-dev \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--with-apxs2 \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.3 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
@@ -0,0 +1,240 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/35d0a696b273c31f41ae224f189c19e794df91ae/7.3/bullseye/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
|
||||
|
||||
ENV PHP_VERSION 7.3.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.3.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.3.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.3,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/939#issuecomment-730501748
|
||||
--enable-embed \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.3 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,265 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/35d0a696b273c31f41ae224f189c19e794df91ae/7.3/alpine3.15/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.15
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
|
||||
|
||||
ENV PHP_VERSION 7.3.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.3.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.3.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.3,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
# PHP < 8 doesn't know to look deeper for GNU libiconv: https://github.com/php/php-src/commit/b480e6841ecd5317faa136647a2b8253a4c2d0df
|
||||
ln -sv /usr/include/gnu-libiconv/*.h /usr/include/; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.3 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,287 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/35d0a696b273c31f41ae224f189c19e794df91ae/7.3/bullseye/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D
|
||||
|
||||
ENV PHP_VERSION 7.3.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.3.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.3.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="166eaccde933381da9516a2b70ad0f447d7cec4b603d07b9a916032b215b90cc"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.3,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.3 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
# temporary "freetype-config" workaround for https://github.com/docker-library/php/issues/865 (https://bugs.php.net/bug.php?id=76324)
|
||||
RUN { echo '#!/bin/sh'; echo 'exec pkg-config "$@" freetype2'; } > /usr/local/bin/freetype-config && chmod +x /usr/local/bin/freetype-config
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,220 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/1361ba95d80570e3984f9de9f765948246191557/7.4/alpine3.16/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.16
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
|
||||
|
||||
ENV PHP_VERSION 7.4.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.4.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.4.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="924846abf93bc613815c55dd3f5809377813ac62a9ec4eb3778675b82a27b927"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.4,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
# PHP < 8 doesn't know to look deeper for GNU libiconv: https://github.com/php/php-src/commit/b480e6841ecd5317faa136647a2b8253a4c2d0df
|
||||
ln -sv /usr/include/gnu-libiconv/*.h /usr/include/; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,308 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/1361ba95d80570e3984f9de9f765948246191557/7.4/bullseye/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
|
||||
|
||||
ENV PHP_VERSION 7.4.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.4.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.4.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="924846abf93bc613815c55dd3f5809377813ac62a9ec4eb3778675b82a27b927"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.4,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
apache2-dev \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--with-apxs2 \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
@@ -0,0 +1,241 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/1361ba95d80570e3984f9de9f765948246191557/7.4/bullseye/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
|
||||
|
||||
ENV PHP_VERSION 7.4.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.4.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.4.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="924846abf93bc613815c55dd3f5809377813ac62a9ec4eb3778675b82a27b927"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.4,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/939#issuecomment-730501748
|
||||
--enable-embed \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,270 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/1361ba95d80570e3984f9de9f765948246191557/7.4/alpine3.16/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.16
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
|
||||
|
||||
ENV PHP_VERSION 7.4.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.4.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.4.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="924846abf93bc613815c55dd3f5809377813ac62a9ec4eb3778675b82a27b927"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.4,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
# PHP < 8 doesn't know to look deeper for GNU libiconv: https://github.com/php/php-src/commit/b480e6841ecd5317faa136647a2b8253a4c2d0df
|
||||
ln -sv /usr/include/gnu-libiconv/*.h /usr/include/; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,288 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/1361ba95d80570e3984f9de9f765948246191557/7.4/bullseye/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312
|
||||
|
||||
ENV PHP_VERSION 7.4.33
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-7.4.33.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-7.4.33.tar.xz.asc"
|
||||
ENV PHP_SHA256="924846abf93bc613815c55dd3f5809377813ac62a9ec4eb3778675b82a27b927"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg dirmngr; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=7.4,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { print $(NF-1) }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; if we send this to /proc/self/fd/1, it never appears'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,218 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/df4636cac888ec860ccbf0f200637b88a2fb22ab/8.0/alpine3.16/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.16
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 39B641343D8C104B2B146DC3F9C39DC0B9698544
|
||||
|
||||
ENV PHP_VERSION 8.0.30
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.0.30.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.0.30.tar.xz.asc"
|
||||
ENV PHP_SHA256="216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,308 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/df4636cac888ec860ccbf0f200637b88a2fb22ab/8.0/bullseye/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 1777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 39B641343D8C104B2B146DC3F9C39DC0B9698544
|
||||
|
||||
ENV PHP_VERSION 8.0.30
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.0.30.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.0.30.tar.xz.asc"
|
||||
ENV PHP_SHA256="216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
apache2-dev \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--with-apxs2 \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
@@ -0,0 +1,241 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/df4636cac888ec860ccbf0f200637b88a2fb22ab/8.0/bullseye/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 39B641343D8C104B2B146DC3F9C39DC0B9698544
|
||||
|
||||
ENV PHP_VERSION 8.0.30
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.0.30.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.0.30.tar.xz.asc"
|
||||
ENV PHP_SHA256="216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/939#issuecomment-730501748
|
||||
--enable-embed \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,274 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/df4636cac888ec860ccbf0f200637b88a2fb22ab/8.0/alpine3.16/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.16
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
tar \
|
||||
xz \
|
||||
# https://github.com/docker-library/php/issues/494
|
||||
openssl
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 39B641343D8C104B2B146DC3F9C39DC0B9698544
|
||||
|
||||
ENV PHP_VERSION 8.0.30
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.0.30.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.0.30.tar.xz.asc"
|
||||
ENV PHP_SHA256="216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; php-fpm closes STDOUT on startup, so sending logs to /proc/self/fd/1 does not work.'; \
|
||||
echo '; https://bugs.php.net/bug.php?id=73886'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
{ \
|
||||
echo '; https://github.com/docker-library/php/issues/878#issuecomment-938595965'; \
|
||||
echo 'fastcgi.logging = Off'; \
|
||||
} > "$PHP_INI_DIR/conf.d/docker-fpm.ini"
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,294 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/df4636cac888ec860ccbf0f200637b88a2fb22ab/8.0/bullseye/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# chialab: Debian bullseye has been moved to archive.debian.org.
|
||||
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
|
||||
-e 's/security.debian.org/archive.debian.org/g' \
|
||||
-e '/bullseye-updates/d' /etc/apt/sources.list
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088130F1BC4B9B5F600B55F3B4 39B641343D8C104B2B146DC3F9C39DC0B9698544
|
||||
|
||||
ENV PHP_VERSION 8.0.30
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.0.30.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.0.30.tar.xz.asc"
|
||||
ENV PHP_SHA256="216ab305737a5d392107112d618a755dc5df42058226f1670e9db90e77d777d9"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
if [ -n "$PHP_ASC_URL" ]; then \
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
fi; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.0,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on s390x
|
||||
# https://manpages.debian.org/bullseye/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
|
||||
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \
|
||||
| sort -u \
|
||||
| xargs -r dpkg-query --search \
|
||||
| cut -d: -f1 \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/7.4 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; php-fpm closes STDOUT on startup, so sending logs to /proc/self/fd/1 does not work.'; \
|
||||
echo '; https://bugs.php.net/bug.php?id=73886'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
{ \
|
||||
echo '; https://github.com/docker-library/php/issues/878#issuecomment-938595965'; \
|
||||
echo 'fastcgi.logging = Off'; \
|
||||
} > "$PHP_INI_DIR/conf.d/docker-fpm.ini"
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,242 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/5c037abaf9dc0095e29807c048d9d1b97e6a9716/8.1/alpine3.21/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.21
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
openssl \
|
||||
tar \
|
||||
xz
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD
|
||||
|
||||
ENV PHP_VERSION 8.1.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.1.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="ffa9e0982e82eeaea848f57687b425ed173aa278fe563001310ae2638db5c251"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
patch \
|
||||
patchutils \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511
|
||||
PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \
|
||||
PHP_UNAME='Linux - Docker' \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
# Apply patches; see https://github.com/docker-library/php/pull/1552
|
||||
# https://github.com/php/php-src/issues/11678
|
||||
curl -fL 'https://github.com/php/php-src/commit/577b8ae4226368e66fee7a9b5c58f9e2428372fc.patch?full_index=1' -o 11678.patch; \
|
||||
echo '6edc20c3bb3e7cc13515abce7f2fffa8ebea6cf7469abfbc78fcdc120350b239 *11678.patch' | sha256sum -c -; \
|
||||
patch -p1 < 11678.patch; \
|
||||
rm 11678.patch; \
|
||||
# https://github.com/php/php-src/pull/19131
|
||||
# this backported commit broke our ability to apply 14834, which is the fix we need, so this is applied as a reverse patch to undo it
|
||||
# 19131 was for FreeBSD, so doesn't apply to this alpine build
|
||||
curl -fL 'https://github.com/php/php-src/commit/a5df26691d1b1f71b964b869510473a5d5413999.patch?full_index=1' -o 19131.patch; \
|
||||
echo 'c98c01c74d3a6da197116f8511b16fed361ca6bbb6a8af8df629a933f541c213 *19131.patch' | sha256sum -c -; \
|
||||
patch --reverse -p1 < 19131.patch; \
|
||||
rm 19131.patch; \
|
||||
# https://github.com/php/php-src/issues/14834
|
||||
curl -fL 'https://github.com/php/php-src/commit/67259e451d5d58b4842776c5696a66d74e157609.patch?full_index=1' -o 14834.patch; \
|
||||
echo 'ed10a1b254091ad676ed204e55628ecbd6c8962004d6185a1821cedecd526c0f *14834.patch' | sha256sum -c -; \
|
||||
filterdiff -x '*/NEWS' 14834.patch | patch -p1; \
|
||||
rm 14834.patch; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here for compatibility with existing versions. ftp_ssl_connect() needed ftp to be compiled statically before PHP 7.0 (see https://github.com/docker-library/php/issues/236).
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+)
|
||||
# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c
|
||||
# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib
|
||||
$(test "$gnuArch" = 'riscv64-linux-musl' && echo '--without-pcre-jit') \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/8.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# enable OPcache by default (https://wiki.php.net/rfc/make_opcache_required)
|
||||
RUN docker-php-ext-enable opcache
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,311 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/5c037abaf9dc0095e29807c048d9d1b97e6a9716/8.1/trixie/apache),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:trixie-slim
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
apt-get dist-clean
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
ENV APACHE_CONFDIR /etc/apache2
|
||||
ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars
|
||||
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends apache2; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
# generically convert lines like
|
||||
# export APACHE_RUN_USER=www-data
|
||||
# into
|
||||
# : ${APACHE_RUN_USER:=www-data}
|
||||
# export APACHE_RUN_USER
|
||||
# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...")
|
||||
sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \
|
||||
\
|
||||
# setup directories and permissions
|
||||
. "$APACHE_ENVVARS"; \
|
||||
for dir in \
|
||||
"$APACHE_LOCK_DIR" \
|
||||
"$APACHE_RUN_DIR" \
|
||||
"$APACHE_LOG_DIR" \
|
||||
# https://salsa.debian.org/apache-team/apache2/-/commit/b97ca8714890ead1ba6c095699dde752e8433205
|
||||
"$APACHE_RUN_DIR/socks" \
|
||||
; do \
|
||||
rm -rvf "$dir"; \
|
||||
mkdir -p "$dir"; \
|
||||
chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
chmod 1777 "$dir"; \
|
||||
done; \
|
||||
\
|
||||
# delete the "index.html" that installing Apache drops in here
|
||||
rm -rvf /var/www/html/*; \
|
||||
\
|
||||
# logs should go to stdout / stderr
|
||||
ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \
|
||||
ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \
|
||||
chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"
|
||||
|
||||
# Apache + PHP requires preforking Apache for best results
|
||||
RUN a2dismod mpm_event && a2enmod mpm_prefork
|
||||
|
||||
# PHP files should be handled by PHP, and should be preferred over any other file type
|
||||
RUN { \
|
||||
echo '<FilesMatch \.php$>'; \
|
||||
echo '\tSetHandler application/x-httpd-php'; \
|
||||
echo '</FilesMatch>'; \
|
||||
echo; \
|
||||
echo 'DirectoryIndex disabled'; \
|
||||
echo 'DirectoryIndex index.php index.html'; \
|
||||
echo; \
|
||||
echo '<Directory /var/www/>'; \
|
||||
echo '\tOptions -Indexes'; \
|
||||
echo '\tAllowOverride All'; \
|
||||
echo '</Directory>'; \
|
||||
} | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \
|
||||
&& a2enconf docker-php
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD
|
||||
|
||||
ENV PHP_VERSION 8.1.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.1.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="ffa9e0982e82eeaea848f57687b425ed173aa278fe563001310ae2638db5c251"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
apache2-dev \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511
|
||||
PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \
|
||||
PHP_UNAME='Linux - Docker' \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here for compatibility with existing versions. ftp_ssl_connect() needed ftp to be compiled statically before PHP 7.0 (see https://github.com/docker-library/php/issues/236).
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+)
|
||||
# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c
|
||||
# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib
|
||||
$(test "$gnuArch" = 'riscv64-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--with-apxs2 \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \
|
||||
| sort -u \
|
||||
| xargs -rt dpkg-query --search \
|
||||
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
|
||||
| awk 'sub(":$", "", $1) { print $1 }' \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/8.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/apache /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# enable OPcache by default (https://wiki.php.net/rfc/make_opcache_required)
|
||||
RUN docker-php-ext-enable opcache
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
|
||||
STOPSIGNAL SIGWINCH
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts apache2-foreground /usr/local/bin/
|
||||
WORKDIR /var/www/html
|
||||
|
||||
EXPOSE 80
|
||||
CMD ["apache2-foreground"]
|
||||
@@ -0,0 +1,242 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/5c037abaf9dc0095e29807c048d9d1b97e6a9716/8.1/trixie/cli),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:trixie-slim
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
apt-get dist-clean
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD
|
||||
|
||||
ENV PHP_VERSION 8.1.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.1.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="ffa9e0982e82eeaea848f57687b425ed173aa278fe563001310ae2638db5c251"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511
|
||||
PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \
|
||||
PHP_UNAME='Linux - Docker' \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here for compatibility with existing versions. ftp_ssl_connect() needed ftp to be compiled statically before PHP 7.0 (see https://github.com/docker-library/php/issues/236).
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/1259
|
||||
--enable-phpdbg \
|
||||
--enable-phpdbg-readline \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+)
|
||||
# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c
|
||||
# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib
|
||||
$(test "$gnuArch" = 'riscv64-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
# https://github.com/docker-library/php/pull/939#issuecomment-730501748
|
||||
--enable-embed \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \
|
||||
| sort -u \
|
||||
| xargs -rt dpkg-query --search \
|
||||
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
|
||||
| awk 'sub(":$", "", $1) { print $1 }' \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/8.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/cli /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# enable OPcache by default (https://wiki.php.net/rfc/make_opcache_required)
|
||||
RUN docker-php-ext-enable opcache
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
CMD ["php", "-a"]
|
||||
@@ -0,0 +1,298 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/5c037abaf9dc0095e29807c048d9d1b97e6a9716/8.1/alpine3.21/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM alpine:3.21
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# these get automatically installed and removed by "docker-php-ext-*" (unless they're already installed)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev dpkg \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkgconf \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
openssl \
|
||||
tar \
|
||||
xz
|
||||
|
||||
# ensure www-data user exists
|
||||
RUN set -eux; \
|
||||
adduser -u 82 -D -S -G www-data www-data
|
||||
# 82 is the standard uid/gid for "www-data" in Alpine
|
||||
# https://git.alpinelinux.org/aports/tree/main/apache2/apache2.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/lighttpd/lighttpd.pre-install?h=3.14-stable
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.pre-install?h=3.14-stable
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD
|
||||
|
||||
ENV PHP_VERSION 8.1.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.1.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="ffa9e0982e82eeaea848f57687b425ed173aa278fe563001310ae2638db5c251"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache --virtual .fetch-deps gnupg; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
\
|
||||
apk del --no-network .fetch-deps
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
coreutils \
|
||||
curl-dev \
|
||||
gnu-libiconv-dev \
|
||||
libsodium-dev \
|
||||
libxml2-dev \
|
||||
linux-headers \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
patch \
|
||||
patchutils \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
; \
|
||||
\
|
||||
# make sure musl's iconv doesn't get used (https://www.php.net/manual/en/intro.iconv.php)
|
||||
rm -vf /usr/include/iconv.h; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511
|
||||
PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \
|
||||
PHP_UNAME='Linux - Docker' \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
# Apply patches; see https://github.com/docker-library/php/pull/1552
|
||||
# https://github.com/php/php-src/issues/11678
|
||||
curl -fL 'https://github.com/php/php-src/commit/577b8ae4226368e66fee7a9b5c58f9e2428372fc.patch?full_index=1' -o 11678.patch; \
|
||||
echo '6edc20c3bb3e7cc13515abce7f2fffa8ebea6cf7469abfbc78fcdc120350b239 *11678.patch' | sha256sum -c -; \
|
||||
patch -p1 < 11678.patch; \
|
||||
rm 11678.patch; \
|
||||
# https://github.com/php/php-src/pull/19131
|
||||
# this backported commit broke our ability to apply 14834, which is the fix we need, so this is applied as a reverse patch to undo it
|
||||
# 19131 was for FreeBSD, so doesn't apply to this alpine build
|
||||
curl -fL 'https://github.com/php/php-src/commit/a5df26691d1b1f71b964b869510473a5d5413999.patch?full_index=1' -o 19131.patch; \
|
||||
echo 'c98c01c74d3a6da197116f8511b16fed361ca6bbb6a8af8df629a933f541c213 *19131.patch' | sha256sum -c -; \
|
||||
patch --reverse -p1 < 19131.patch; \
|
||||
rm 19131.patch; \
|
||||
# https://github.com/php/php-src/issues/14834
|
||||
curl -fL 'https://github.com/php/php-src/commit/67259e451d5d58b4842776c5696a66d74e157609.patch?full_index=1' -o 14834.patch; \
|
||||
echo 'ed10a1b254091ad676ed204e55628ecbd6c8962004d6185a1821cedecd526c0f *14834.patch' | sha256sum -c -; \
|
||||
filterdiff -x '*/NEWS' 14834.patch | patch -p1; \
|
||||
rm 14834.patch; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here for compatibility with existing versions. ftp_ssl_connect() needed ftp to be compiled statically before PHP 7.0 (see https://github.com/docker-library/php/issues/236).
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv=/usr \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+)
|
||||
# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c
|
||||
# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib
|
||||
$(test "$gnuArch" = 'riscv64-linux-musl' && echo '--without-pcre-jit') \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
runDeps="$( \
|
||||
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
|
||||
| tr ',' '\n' \
|
||||
| sort -u \
|
||||
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
|
||||
)"; \
|
||||
apk add --no-cache $runDeps; \
|
||||
\
|
||||
apk del --no-network .build-deps; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/8.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# enable OPcache by default (https://wiki.php.net/rfc/make_opcache_required)
|
||||
RUN docker-php-ext-enable opcache
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; php-fpm closes STDOUT on startup, so sending logs to /proc/self/fd/1 does not work.'; \
|
||||
echo '; https://bugs.php.net/bug.php?id=73886'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
{ \
|
||||
echo '; https://github.com/docker-library/php/issues/878#issuecomment-938595965'; \
|
||||
echo 'fastcgi.logging = Off'; \
|
||||
} > "$PHP_INI_DIR/conf.d/docker-fpm.ini"
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,295 @@
|
||||
#
|
||||
# Taken from the official PHP image's Dockerfile
|
||||
# (https://github.com/docker-library/php/tree/5c037abaf9dc0095e29807c048d9d1b97e6a9716/8.1/trixie/fpm),
|
||||
# with the changes marked "chialab:".
|
||||
#
|
||||
|
||||
FROM debian:trixie-slim
|
||||
|
||||
# prevent Debian's PHP packages from being installed
|
||||
# https://github.com/docker-library/php/pull/542
|
||||
RUN set -eux; \
|
||||
{ \
|
||||
echo 'Package: php*'; \
|
||||
echo 'Pin: release *'; \
|
||||
echo 'Pin-Priority: -1'; \
|
||||
} > /etc/apt/preferences.d/no-debian-php
|
||||
|
||||
# dependencies required for running "phpize"
|
||||
# (see persistent deps below)
|
||||
ENV PHPIZE_DEPS \
|
||||
autoconf \
|
||||
dpkg-dev \
|
||||
file \
|
||||
g++ \
|
||||
gcc \
|
||||
libc-dev \
|
||||
make \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# persistent / runtime deps
|
||||
RUN set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
$PHPIZE_DEPS \
|
||||
ca-certificates \
|
||||
curl \
|
||||
xz-utils \
|
||||
; \
|
||||
apt-get dist-clean
|
||||
|
||||
ENV PHP_INI_DIR /usr/local/etc/php
|
||||
RUN set -eux; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
|
||||
[ ! -d /var/www/html ]; \
|
||||
mkdir -p /var/www/html; \
|
||||
chown www-data:www-data /var/www/html; \
|
||||
chmod 1777 /var/www/html
|
||||
|
||||
# Apply stack smash protection to functions using local buffers and alloca()
|
||||
# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
|
||||
# Enable optimization (-O2)
|
||||
# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
|
||||
# https://github.com/docker-library/php/issues/272
|
||||
# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
|
||||
ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
ENV PHP_CPPFLAGS="$PHP_CFLAGS"
|
||||
ENV PHP_LDFLAGS="-Wl,-O1 -pie"
|
||||
|
||||
ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD
|
||||
|
||||
ENV PHP_VERSION 8.1.34
|
||||
ENV PHP_URL="https://www.php.net/distributions/php-8.1.34.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.34.tar.xz.asc"
|
||||
ENV PHP_SHA256="ffa9e0982e82eeaea848f57687b425ed173aa278fe563001310ae2638db5c251"
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends gnupg; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
mkdir -p /usr/src; \
|
||||
cd /usr/src; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz "$PHP_URL"; \
|
||||
\
|
||||
if [ -n "$PHP_SHA256" ]; then \
|
||||
echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \
|
||||
fi; \
|
||||
\
|
||||
curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \
|
||||
export GNUPGHOME="$(mktemp -d)"; \
|
||||
for key in $GPG_KEYS; do \
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \
|
||||
done; \
|
||||
gpg --batch --verify php.tar.xz.asc php.tar.xz; \
|
||||
gpgconf --kill all; \
|
||||
rm -rf "$GNUPGHOME"; \
|
||||
\
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
apt-mark manual $savedAptMark > /dev/null; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false
|
||||
|
||||
# chialab: helper scripts are shared by all eol/ images, see eol/scripts.
|
||||
COPY --from=scripts docker-php-source /usr/local/bin/
|
||||
|
||||
# chialab: security backports for this EOL version (see eol/patches).
|
||||
ENV PHP_PATCHES="CVE-2026-109618 CVE-2026-109619"
|
||||
LABEL it.chialab.php.patches="CVE-2026-109618 CVE-2026-109619"
|
||||
RUN --mount=type=bind,from=patches,source=8.1,target=/usr/src/php-patches \
|
||||
--mount=type=bind,from=patches,source=docker-php-source-patch,target=/usr/local/bin/docker-php-source-patch \
|
||||
docker-php-source-patch /usr/src/php-patches
|
||||
|
||||
RUN set -eux; \
|
||||
\
|
||||
savedAptMark="$(apt-mark showmanual)"; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
libargon2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libonig-dev \
|
||||
libreadline-dev \
|
||||
libsodium-dev \
|
||||
libsqlite3-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
zlib1g-dev \
|
||||
; \
|
||||
\
|
||||
export \
|
||||
CFLAGS="$PHP_CFLAGS" \
|
||||
CPPFLAGS="$PHP_CPPFLAGS" \
|
||||
LDFLAGS="$PHP_LDFLAGS" \
|
||||
# https://github.com/php/php-src/blob/d6299206dd828382753453befd1b915491b741c6/configure.ac#L1496-L1511
|
||||
PHP_BUILD_PROVIDER='https://github.com/docker-library/php' \
|
||||
PHP_UNAME='Linux - Docker' \
|
||||
; \
|
||||
docker-php-source extract; \
|
||||
cd /usr/src/php; \
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
|
||||
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
|
||||
# https://bugs.php.net/bug.php?id=74125
|
||||
if [ ! -d /usr/include/curl ]; then \
|
||||
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
|
||||
fi; \
|
||||
./configure \
|
||||
--build="$gnuArch" \
|
||||
--with-config-file-path="$PHP_INI_DIR" \
|
||||
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
|
||||
\
|
||||
# make sure invalid --configure-flags are fatal errors instead of just warnings
|
||||
--enable-option-checking=fatal \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/439
|
||||
--with-mhash \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/822
|
||||
--with-pic \
|
||||
\
|
||||
# --enable-ftp is included here for compatibility with existing versions. ftp_ssl_connect() needed ftp to be compiled statically before PHP 7.0 (see https://github.com/docker-library/php/issues/236).
|
||||
--enable-ftp \
|
||||
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
|
||||
--enable-mbstring \
|
||||
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
|
||||
--enable-mysqlnd \
|
||||
# https://wiki.php.net/rfc/argon2_password_hash
|
||||
--with-password-argon2 \
|
||||
# https://wiki.php.net/rfc/libsodium
|
||||
--with-sodium=shared \
|
||||
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
|
||||
--with-pdo-sqlite=/usr \
|
||||
--with-sqlite3=/usr \
|
||||
\
|
||||
--with-curl \
|
||||
--with-iconv \
|
||||
--with-openssl \
|
||||
--with-readline \
|
||||
--with-zlib \
|
||||
\
|
||||
# https://github.com/bwoebi/phpdbg-docs/issues/1#issuecomment-163872806 ("phpdbg is primarily a CLI debugger, and is not suitable for debugging an fpm stack.")
|
||||
--disable-phpdbg \
|
||||
\
|
||||
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
|
||||
--with-pear \
|
||||
\
|
||||
# bundled pcre does not support JIT on riscv64 until 10.41 (php 8.3+)
|
||||
# https://github.com/PCRE2Project/pcre2/commits/pcre2-10.41/src/sljit/sljitNativeRISCV_64.c
|
||||
# https://github.com/php/php-src/tree/php-8.3.0/ext/pcre/pcre2lib
|
||||
$(test "$gnuArch" = 'riscv64-linux-gnu' && echo '--without-pcre-jit') \
|
||||
--with-libdir="lib/$debMultiarch" \
|
||||
\
|
||||
--disable-cgi \
|
||||
\
|
||||
--enable-fpm \
|
||||
--with-fpm-user=www-data \
|
||||
--with-fpm-group=www-data \
|
||||
; \
|
||||
make -j "$(nproc)"; \
|
||||
find -type f -name '*.a' -delete; \
|
||||
make install; \
|
||||
find \
|
||||
/usr/local \
|
||||
-type f \
|
||||
-perm '/0111' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || : \
|
||||
' -- '{}' + \
|
||||
; \
|
||||
make clean; \
|
||||
\
|
||||
# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable)
|
||||
cp -v php.ini-* "$PHP_INI_DIR/"; \
|
||||
\
|
||||
cd /; \
|
||||
docker-php-source delete; \
|
||||
\
|
||||
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
|
||||
apt-mark auto '.*' > /dev/null; \
|
||||
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
|
||||
find /usr/local -type f -executable -exec ldd '{}' ';' \
|
||||
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \
|
||||
| sort -u \
|
||||
| xargs -rt dpkg-query --search \
|
||||
# https://manpages.debian.org/trixie/dpkg/dpkg-query.1.en.html#S (we ignore diversions and it'll be really unusual for more than one package to provide any given .so file)
|
||||
| awk 'sub(":$", "", $1) { print $1 }' \
|
||||
| sort -u \
|
||||
| xargs -r apt-mark manual \
|
||||
; \
|
||||
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
||||
apt-get dist-clean; \
|
||||
\
|
||||
# update pecl channel definitions https://github.com/docker-library/php/issues/443
|
||||
pecl update-channels; \
|
||||
rm -rf /tmp/pear ~/.pearrc; \
|
||||
\
|
||||
# smoke test
|
||||
php --version
|
||||
|
||||
# chialab: from eol/scripts.
|
||||
COPY --from=scripts docker-php-ext-configure/7.2 /usr/local/bin/docker-php-ext-configure
|
||||
COPY --from=scripts docker-php-ext-enable/7.3 /usr/local/bin/docker-php-ext-enable
|
||||
COPY --from=scripts docker-php-ext-install/8.1 /usr/local/bin/docker-php-ext-install
|
||||
COPY --from=scripts docker-php-entrypoint/fpm /usr/local/bin/docker-php-entrypoint
|
||||
|
||||
# enable OPcache by default (https://wiki.php.net/rfc/make_opcache_required)
|
||||
RUN docker-php-ext-enable opcache
|
||||
|
||||
# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598)
|
||||
RUN docker-php-ext-enable sodium
|
||||
|
||||
ENTRYPOINT ["docker-php-entrypoint"]
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN set -eux; \
|
||||
cd /usr/local/etc; \
|
||||
if [ -d php-fpm.d ]; then \
|
||||
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
|
||||
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
|
||||
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
|
||||
else \
|
||||
# PHP 5.x doesn't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
|
||||
mkdir php-fpm.d; \
|
||||
cp php-fpm.conf.default php-fpm.d/www.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'include=etc/php-fpm.d/*.conf'; \
|
||||
} | tee php-fpm.conf; \
|
||||
fi; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'error_log = /proc/self/fd/2'; \
|
||||
echo; echo '; https://github.com/docker-library/php/pull/725#issuecomment-443540114'; echo 'log_limit = 8192'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo '; php-fpm closes STDOUT on startup, so sending logs to /proc/self/fd/1 does not work.'; \
|
||||
echo '; https://bugs.php.net/bug.php?id=73886'; \
|
||||
echo 'access.log = /proc/self/fd/2'; \
|
||||
echo; \
|
||||
echo 'clear_env = no'; \
|
||||
echo; \
|
||||
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
|
||||
echo 'catch_workers_output = yes'; \
|
||||
echo 'decorate_workers_output = no'; \
|
||||
} | tee php-fpm.d/docker.conf; \
|
||||
{ \
|
||||
echo '[global]'; \
|
||||
echo 'daemonize = no'; \
|
||||
echo; \
|
||||
echo '[www]'; \
|
||||
echo 'listen = 9000'; \
|
||||
} | tee php-fpm.d/zz-docker.conf; \
|
||||
mkdir -p "$PHP_INI_DIR/conf.d"; \
|
||||
{ \
|
||||
echo '; https://github.com/docker-library/php/issues/878#issuecomment-938595965'; \
|
||||
echo 'fastcgi.logging = Off'; \
|
||||
} > "$PHP_INI_DIR/conf.d/docker-fpm.ini"
|
||||
|
||||
# Override stop signal to stop process gracefully
|
||||
# https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
@@ -0,0 +1,57 @@
|
||||
# EOL PHP versions
|
||||
|
||||
The official images stop receiving updates once a PHP version reaches end of life. For those
|
||||
versions we build PHP ourselves from the official images' Dockerfiles, with security patches
|
||||
applied to the sources, and use the result as the base image instead of `php:<tag>`.
|
||||
|
||||
- `<X.Y>/<flavor>/Dockerfile`: the official Dockerfiles, one per tag suffix (`cli`, `apache`,
|
||||
`fpm`, `alpine`, `fpm-alpine`).
|
||||
- `scripts/`: the helper scripts copied into the images (`docker-php-*`, `apache2-foreground`),
|
||||
passed to the build as the `scripts` named context.
|
||||
- `patches/`: `docker-php-source-patch` and one `<X.Y>/series` of patches per version, passed to
|
||||
the build as the `patches` named context.
|
||||
|
||||
The build picks a directory up on its own: if `eol/<X.Y>/<flavor>` exists, the Makefile and
|
||||
`build-images.yml` build it as the base image. No workflow lists EOL versions.
|
||||
|
||||
## Adding a version
|
||||
|
||||
Add it once there is a security patch to apply: `make test` fails an EOL image whose
|
||||
`PHP_PATCHES` is empty. Until then, keep building on the official image.
|
||||
|
||||
1. **Find the source.** Take the last [docker-library/php](https://github.com/docker-library/php)
|
||||
commit that still has the `<X.Y>/` directory. For each flavor, pick the variant the plain
|
||||
official tag pointed to: `<X.Y>/<debian-suite>/{cli,apache,fpm}` and
|
||||
`<X.Y>/alpine<N>/{cli,fpm}` for `alpine` and `fpm-alpine`.
|
||||
2. **Copy the Dockerfiles** to `eol/<X.Y>/<flavor>/Dockerfile`, with the header used by the
|
||||
other versions linking the exact source path at that commit. Copy only the Dockerfile, not
|
||||
the scripts next to it.
|
||||
3. **Mark every change** with a `# chialab:` comment:
|
||||
- replace the `COPY docker-php-*` and `COPY apache2-foreground` lines with
|
||||
`COPY --from=scripts …` (see [Scripts](#scripts));
|
||||
- add the patch step right after `docker-php-source` is copied, as in the other versions:
|
||||
`ENV PHP_PATCHES`, `LABEL it.chialab.php.patches` and the `RUN` that bind-mounts
|
||||
`patches/<X.Y>` and runs `docker-php-source-patch`;
|
||||
- once the OS release is archived, or a download host or keyserver disappears, fix it the
|
||||
same way the older versions do.
|
||||
4. **Add the patches** to `patches/<X.Y>/` and list them in its `series`, with a comment
|
||||
linking where each one comes from.
|
||||
5. **Update the range** of EOL versions in the main [README](../README.md).
|
||||
|
||||
## Scripts
|
||||
|
||||
Each script in `scripts/` covers a range of PHP versions. Versioned scripts are named after the
|
||||
first version that uses them, and serve every later version until the next file: for example,
|
||||
`docker-php-ext-install/7.4` is used by both 7.4 and 8.0, and 8.1 has its own file.
|
||||
Entrypoints vary by flavor rather than version, so they're named `cli` (also for `alpine`),
|
||||
`fpm` (also for `fpm-alpine`) and `apache`.
|
||||
|
||||
When adding a version, compare each script from the docker-library directory with the newest
|
||||
file in `scripts/`:
|
||||
|
||||
- if it's identical, point the new Dockerfile at that file;
|
||||
- if it differs, add it as `scripts/<script>/<X.Y>` and point the new Dockerfile at it.
|
||||
|
||||
`docker-php-source` and `apache2-foreground` are the same for every version so far, so they
|
||||
have no version directory. If a new version changes one of them, move it into one, like the
|
||||
other scripts.
|
||||
@@ -0,0 +1,529 @@
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Backported from the PHP 7.4 version:
|
||||
- zend_mm_safe_error_ex() keeps the PHP 5.6 way of finding the script
|
||||
file and line (TSRM, EG(in_execution)).
|
||||
- The overflow errors of safe_address() and _safe_emalloc_string(), and
|
||||
the "String size overflow" errors of concat_function() and
|
||||
add_*_to_string() (which back ZEND_CONCAT and ZEND_ADD_* in 5.6) exit
|
||||
the same way.
|
||||
- GPC arrays start with 2 buckets: nTableMask == 0 marks an uninitialized
|
||||
hash table in 5.6, so a single bucket cannot be used.
|
||||
- SG(callback_func) is also reset in sapi_deactivate().
|
||||
- PHP 5.6 already clears the user error/exception handlers before
|
||||
destroying them; EG(error_handling) and EG(exception) are reset after
|
||||
the object store is freed.
|
||||
- "|| 1" instead of "|| true" in the session upload progress callback.
|
||||
- The max_multipart_body_parts hunk of the 7.4 patch is left out, the
|
||||
code is already there.
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.c | 9 ++++
|
||||
Zend/zend_API.h | 2 +
|
||||
Zend/zend_alloc.c | 110 +++++++++++++++++++---------------------
|
||||
Zend/zend_alloc.h | 6 +++
|
||||
Zend/zend_execute_API.c | 4 ++
|
||||
Zend/zend_llist.c | 2 +
|
||||
Zend/zend_operators.c | 8 +--
|
||||
Zend/zend_strtod.c | 2 +-
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 6 +++
|
||||
main/main.c | 5 ++
|
||||
main/php_variables.c | 6 +--
|
||||
main/rfc1867.c | 27 +++++++---
|
||||
13 files changed, 114 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
|
||||
index 0757cc92..89cdca5f 100644
|
||||
--- a/Zend/zend_API.c
|
||||
+++ b/Zend/zend_API.c
|
||||
@@ -1016,6 +1016,15 @@ ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
|
||||
+{
|
||||
+ _array_init(arg, 0 ZEND_FILE_LINE_RELAY_CC);
|
||||
+ /* nTableMask == 0 marks an uninitialized table, so 2 is the smallest usable size */
|
||||
+ Z_ARRVAL_P(arg)->nTableSize = 2;
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
static int zend_merge_property(zval **value TSRMLS_DC, int num_args, va_list args, const zend_hash_key *hash_key) /* {{{ */
|
||||
{
|
||||
/* which name should a numeric property have ? */
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 41aa65f2..c17dacd5 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -363,10 +363,12 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) _array_init((arg), 0 ZEND_FILE_LINE_CC)
|
||||
#define array_init_size(arg, size) _array_init((arg), (size) ZEND_FILE_LINE_CC)
|
||||
+#define array_init_singleton(arg) _array_init_singleton((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC TSRMLS_CC)
|
||||
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC TSRMLS_CC)
|
||||
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC TSRMLS_CC)
|
||||
ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC);
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC);
|
||||
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC);
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index c7babe12..f84d25ae 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -91,7 +91,7 @@ static void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
/*******************/
|
||||
@@ -1740,6 +1740,42 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent
|
||||
}
|
||||
}
|
||||
|
||||
+ZEND_API void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ const char *error_filename;
|
||||
+ uint error_lineno;
|
||||
+ va_list args;
|
||||
+ char buf[1024];
|
||||
+ TSRMLS_FETCH();
|
||||
+
|
||||
+ if (zend_is_compiling(TSRMLS_C)) {
|
||||
+ error_filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
+ error_lineno = zend_get_compiled_lineno(TSRMLS_C);
|
||||
+ } else if (EG(in_execution)) {
|
||||
+ error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
|
||||
+ error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
|
||||
+ } else {
|
||||
+ error_filename = NULL;
|
||||
+ error_lineno = 0;
|
||||
+ }
|
||||
+ if (!error_filename) {
|
||||
+ error_filename = "Unknown";
|
||||
+ }
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr, "\nFatal error: %s in %s on line %d\n", buf, error_filename, error_lineno);
|
||||
+
|
||||
+/* See http://support.microsoft.com/kb/190351 */
|
||||
+#ifdef PHP_WIN32
|
||||
+ fflush(stderr);
|
||||
+#endif
|
||||
+
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
static void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
const char *format,
|
||||
size_t limit,
|
||||
@@ -1749,59 +1785,15 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
- if (heap->reserve) {
|
||||
- _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
|
||||
- heap->reserve = NULL;
|
||||
- }
|
||||
- if (heap->overflow == 0) {
|
||||
- const char *error_filename;
|
||||
- uint error_lineno;
|
||||
- TSRMLS_FETCH();
|
||||
- if (zend_is_compiling(TSRMLS_C)) {
|
||||
- error_filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
- error_lineno = zend_get_compiled_lineno(TSRMLS_C);
|
||||
- } else if (EG(in_execution)) {
|
||||
- error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
|
||||
- error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
|
||||
- } else {
|
||||
- error_filename = NULL;
|
||||
- error_lineno = 0;
|
||||
- }
|
||||
- if (!error_filename) {
|
||||
- error_filename = "Unknown";
|
||||
- }
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ (void) heap;
|
||||
+
|
||||
+ zend_mm_safe_error_ex(format,
|
||||
+ limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- if (heap->overflow == 2) {
|
||||
- fprintf(stderr, "\nFatal error: ");
|
||||
- fprintf(stderr,
|
||||
- format,
|
||||
- limit,
|
||||
-#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
-#endif
|
||||
- size);
|
||||
- fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
|
||||
- }
|
||||
-/* See http://support.microsoft.com/kb/190351 */
|
||||
-#ifdef PHP_WIN32
|
||||
- fflush(stderr);
|
||||
-#endif
|
||||
- } zend_end_try();
|
||||
- } else {
|
||||
- heap->overflow = 2;
|
||||
- }
|
||||
- zend_bailout();
|
||||
+ size);
|
||||
}
|
||||
|
||||
static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size)
|
||||
@@ -2472,7 +2464,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
"rm"(offset));
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -2501,7 +2493,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
|
||||
#undef LP_SUFF
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -2522,7 +2514,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
"1"(0));
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -2542,7 +2534,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
"r"(offset));
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -2555,7 +2547,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
|
||||
|
||||
if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return (size_t) res;
|
||||
@@ -2570,7 +2562,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
|
||||
double _delta = (double)res - _d;
|
||||
|
||||
if (UNEXPECTED((_d + _delta ) != _d)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return res;
|
||||
@@ -2582,7 +2574,7 @@ ZEND_API void *_safe_emalloc_string(size_t nmemb, size_t size, size_t offset ZEN
|
||||
{
|
||||
size_t str_size = safe_address(nmemb, size, offset);
|
||||
if (UNEXPECTED(str_size > INT_MAX)) {
|
||||
- zend_error_noreturn(E_ERROR, "String allocation overflow, max size is %d", INT_MAX);
|
||||
+ zend_mm_safe_error_ex("String allocation overflow, max size is %d", INT_MAX);
|
||||
}
|
||||
return emalloc_rel(str_size);
|
||||
}
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index 719f9c5c..dab0599a 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -57,6 +57,12 @@ ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_M
|
||||
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
|
||||
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API void *_safe_emalloc_string(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
+
|
||||
+#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
|
||||
+ZEND_API void zend_mm_safe_error_ex(const char *format, ...) __attribute__ ((noreturn));
|
||||
+#else
|
||||
+ZEND_API void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+#endif
|
||||
ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(1,2);
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index bf754d25..a7a7b9ba 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -307,6 +307,10 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
zend_try {
|
||||
clean_non_persistent_constants(TSRMLS_C);
|
||||
} zend_end_try();
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index 3d597a37..5be49408 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -115,6 +115,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
|
||||
index 450153ff..192592b0 100644
|
||||
--- a/Zend/zend_operators.c
|
||||
+++ b/Zend/zend_operators.c
|
||||
@@ -1400,7 +1400,7 @@ ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2)
|
||||
char *buf;
|
||||
|
||||
if (UNEXPECTED(length < 0)) {
|
||||
- zend_error(E_ERROR, "String size overflow");
|
||||
+ zend_mm_safe_error_ex("String size overflow");
|
||||
}
|
||||
|
||||
buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
|
||||
@@ -1419,7 +1419,7 @@ ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2
|
||||
char *buf;
|
||||
|
||||
if (UNEXPECTED(length < 0)) {
|
||||
- zend_error(E_ERROR, "String size overflow");
|
||||
+ zend_mm_safe_error_ex("String size overflow");
|
||||
}
|
||||
|
||||
buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
|
||||
@@ -1465,7 +1465,7 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
|
||||
if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
|
||||
efree(Z_STRVAL_P(result));
|
||||
ZVAL_EMPTY_STRING(result);
|
||||
- zend_error(E_ERROR, "String size overflow");
|
||||
+ zend_mm_safe_error_ex("String size overflow");
|
||||
}
|
||||
|
||||
Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
|
||||
@@ -1478,7 +1478,7 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
|
||||
char *buf;
|
||||
|
||||
if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
|
||||
- zend_error(E_ERROR, "String size overflow");
|
||||
+ zend_mm_safe_error_ex("String size overflow");
|
||||
}
|
||||
buf = (char *) safe_emalloc(length, 1, 1);
|
||||
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index 7ec0366e..a035a154 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -501,7 +501,7 @@ static Bigint * Balloc(int k)
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
|
||||
if (!rv) {
|
||||
_THREAD_PRIVATE_MUTEX_UNLOCK(dtoa_mutex);
|
||||
- zend_error(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
rv->k = k;
|
||||
rv->maxwds = x;
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 2fe9651a..650ef174 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -2669,7 +2669,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra TSRMLS_CC);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || 1) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index 49ffc1c9..660012da 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -528,18 +528,23 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate(TSRMLS_C);
|
||||
@@ -557,6 +562,7 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
|
||||
SG(callback_run) = 0;
|
||||
if (SG(callback_func)) {
|
||||
zval_ptr_dtor(&SG(callback_func));
|
||||
+ SG(callback_func) = NULL;
|
||||
}
|
||||
SG(request_info).headers_read = 0;
|
||||
SG(global_request_time) = 0;
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index ab55b5b8..1f6618bd 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1880,6 +1880,8 @@ void php_request_shutdown(void *dummy)
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
if (PG(http_globals)[i]) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(http_globals)[i] = NULL;
|
||||
}
|
||||
}
|
||||
} zend_end_try();
|
||||
@@ -1937,6 +1939,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index fbd9562e..606a4b03 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -191,7 +191,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
|
||||
if (!index) {
|
||||
MAKE_STD_ZVAL(gpc_element);
|
||||
- array_init(gpc_element);
|
||||
+ array_init_singleton(gpc_element);
|
||||
if (zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p) == FAILURE) {
|
||||
zval_ptr_dtor(&gpc_element);
|
||||
zval_dtor(val);
|
||||
@@ -208,7 +208,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
if (zend_symtable_find(symtable1, index, index_len + 1, (void **) &gpc_element_p) == FAILURE
|
||||
|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
|
||||
MAKE_STD_ZVAL(gpc_element);
|
||||
- array_init(gpc_element);
|
||||
+ array_init_singleton(gpc_element);
|
||||
zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
|
||||
}
|
||||
}
|
||||
@@ -406,7 +406,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
- array_init(array_ptr);
|
||||
+ array_init_singleton(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index 2b3e47f9..fdb671d2 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -400,6 +400,14 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC)
|
||||
{
|
||||
@@ -441,10 +449,15 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while(isspace(*value));
|
||||
-
|
||||
- key = estrdup(line);
|
||||
- smart_str_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while(isspace(*value));
|
||||
+ smart_str_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_str_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -517,11 +530,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -556,7 +569,7 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# https://salsa.debian.org/php-team/php/-/tree/7401dd5c10042b6b875370027d775f9c542171b8/debian/patches (Sury 5.6.40-104)
|
||||
0261-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,25 @@
|
||||
From: Remi Collet <remi@remirepo.net>
|
||||
Date: Fri, 22 Nov 2024 15:24:16 +0100
|
||||
Subject: backport ZSTR_MAX_LEN
|
||||
|
||||
(cherry picked from commit 37056ad634d9c44bac0d6c8e730eafaec1344840)
|
||||
(cherry picked from commit ff868946218d6d1661a0c35757e2058cb3ed23ec)
|
||||
(cherry picked from commit 351dee5281697c14712e261f560d671e1661e51a)
|
||||
---
|
||||
Zend/zend_string.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
|
||||
index 113e5ca..e3286e1 100644
|
||||
--- a/Zend/zend_string.h
|
||||
+++ b/Zend/zend_string.h
|
||||
@@ -61,6 +61,9 @@ END_EXTERN_C()
|
||||
|
||||
#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
|
||||
|
||||
+#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
|
||||
+#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
|
||||
+
|
||||
#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
|
||||
(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
|
||||
GC_REFCOUNT(str) = 1; \
|
||||
@@ -0,0 +1,701 @@
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Backported from the PHP 7.4 version:
|
||||
- There is no fast shutdown in shutdown_executor() before PHP 7.2 (the
|
||||
opcache one runs before the error handlers are destroyed), so the user
|
||||
error/exception handlers, EG(error_handling) and EG(exception) are reset
|
||||
after the cleanup blocks, where a bailout cannot skip it.
|
||||
- array_init_singleton() is implemented in zend_API.c, there is no
|
||||
zend_new_array(); HT_HASH_RESET() uses memset(), so the SSE2 change is
|
||||
not needed.
|
||||
- ZEND_FAST_CONCAT has no string fast path, so only ZEND_CONCAT gets the
|
||||
length checks.
|
||||
- "|| 1" instead of "|| true" in the session upload progress callback
|
||||
(no stdbool.h).
|
||||
- The max_multipart_body_parts hunk of the 7.4 patch is left out, the
|
||||
code is already there.
|
||||
- ZEND_CONCAT uses zend_string_realloc(); the estrdup() and hash table
|
||||
overflow messages use the 7.1+ formats (the old ones passed int
|
||||
arguments for %zu, which vsnprintf() cannot take).
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.c | 8 +++++
|
||||
Zend/zend_API.h | 2 ++
|
||||
Zend/zend_alloc.c | 66 +++++++++++++++++++++++++++++------------
|
||||
Zend/zend_alloc.h | 2 ++
|
||||
Zend/zend_execute_API.c | 8 +++++
|
||||
Zend/zend_hash.c | 6 ++--
|
||||
Zend/zend_llist.c | 2 ++
|
||||
Zend/zend_multiply.h | 4 +--
|
||||
Zend/zend_strtod.c | 4 +--
|
||||
Zend/zend_vm_def.h | 6 ++++
|
||||
Zend/zend_vm_execute.h | 54 +++++++++++++++++++++++++++++++++
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 ++++
|
||||
main/main.c | 5 ++++
|
||||
main/php_variables.c | 8 ++---
|
||||
main/rfc1867.c | 29 +++++++++++++-----
|
||||
16 files changed, 172 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
|
||||
index d7b22791..8622ef67 100644
|
||||
--- a/Zend/zend_API.c
|
||||
+++ b/Zend/zend_API.c
|
||||
@@ -1062,6 +1062,14 @@ ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
|
||||
+{
|
||||
+ _array_init(arg, 0 ZEND_FILE_LINE_RELAY_CC);
|
||||
+ Z_ARRVAL_P(arg)->nTableSize = 1;
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
/* This function should be called after the constructor has been called
|
||||
* because it may call __set from the uninitialized object otherwise. */
|
||||
ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 9f2e2c6b..a1cd888b 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -375,10 +375,12 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) _array_init((arg), 0 ZEND_FILE_LINE_CC)
|
||||
#define array_init_size(arg, size) _array_init((arg), (size) ZEND_FILE_LINE_CC)
|
||||
+#define array_init_singleton(arg) _array_init_singleton((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
|
||||
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC)
|
||||
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC);
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index be41aa3e..62c72a33 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "zend_globals.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
+#include "zend_execute.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
@@ -369,7 +370,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -381,22 +417,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1381,7 +1409,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -2567,7 +2595,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2582,7 +2610,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2599,7 +2627,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2874,7 +2902,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index 529bd618..d8fc31a3 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -392,6 +392,8 @@ static void apc_init_heap(void)
|
||||
|
||||
*/
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index ff2d22f1..b083a782 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -299,6 +299,10 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
|
||||
} zend_end_try();
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+
|
||||
zend_try {
|
||||
/* Cleanup static data for functions and arrays.
|
||||
* We need a separate cleanup stage because of the following problem:
|
||||
@@ -378,6 +382,10 @@ void shutdown_executor(void) /* {{{ */
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
zend_try {
|
||||
#if 0&&ZEND_DEBUG
|
||||
signal(SIGSEGV, original_sigsegv_handler);
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index 9a1b10bb..44508684 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -103,7 +103,7 @@ static uint32_t zend_always_inline zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize < HT_MIN_SIZE) {
|
||||
nSize = HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
@@ -189,7 +189,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
@@ -893,7 +893,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
zend_hash_rehash(ht);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index 677b7da4..f9f7abbb 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -114,6 +114,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index c66e1924..e535a1ff 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -272,7 +272,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -285,7 +285,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index d15048b7..d2f73822 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -600,7 +600,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -613,7 +613,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index b2f9bbdf..3832471f 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -290,11 +290,17 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index 1fd66037..9eecd684 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -4602,11 +4602,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8638,11 +8644,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10521,11 +10533,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -30441,11 +30459,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -35757,11 +35781,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -38475,11 +38505,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -41529,11 +41565,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -43947,11 +43989,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -45096,11 +45144,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_realloc(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 48a15b67..0d76b9b0 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -2960,7 +2960,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || 1) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index 018ef23b..e9854aca 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -516,18 +516,23 @@ SAPI_API void sapi_deactivate(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index 91f9ead1..eec25c7c 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1844,6 +1844,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -1897,6 +1899,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index 46de3477..afeb88cb 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -187,7 +187,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zval_ptr_dtor(&gpc_element);
|
||||
zval_dtor(val);
|
||||
@@ -204,7 +204,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -212,7 +212,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,7 +405,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index 5d255ae3..672da20d 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -405,6 +405,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -445,10 +453,15 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
-
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace(*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -522,11 +535,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -554,14 +567,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://salsa.debian.org/php-team/php/-/tree/dbe6804422b175d8542b91699384afe5beebeab2/debian/patches (Sury 7.0.33-92)
|
||||
0211-backport-ZSTR_MAX_LEN.patch
|
||||
0230-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,24 @@
|
||||
From: Remi Collet <remi@remirepo.net>
|
||||
Date: Fri, 22 Nov 2024 15:24:16 +0100
|
||||
Subject: backport ZSTR_MAX_LEN
|
||||
|
||||
(cherry picked from commit 37056ad634d9c44bac0d6c8e730eafaec1344840)
|
||||
(cherry picked from commit ff868946218d6d1661a0c35757e2058cb3ed23ec)
|
||||
---
|
||||
Zend/zend_string.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
|
||||
index dbc3f3b..b15f78c 100644
|
||||
--- a/Zend/zend_string.h
|
||||
+++ b/Zend/zend_string.h
|
||||
@@ -62,6 +62,9 @@ END_EXTERN_C()
|
||||
|
||||
#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
|
||||
|
||||
+#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
|
||||
+#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
|
||||
+
|
||||
#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
|
||||
(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
|
||||
GC_REFCOUNT(str) = 1; \
|
||||
@@ -0,0 +1,698 @@
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Backported from the PHP 7.4 version:
|
||||
- There is no fast shutdown in shutdown_executor() before PHP 7.2 (the
|
||||
opcache one runs before the error handlers are destroyed), so the user
|
||||
error/exception handlers, EG(error_handling) and EG(exception) are reset
|
||||
after the cleanup blocks, where a bailout cannot skip it.
|
||||
- array_init_singleton() is implemented in zend_API.c, there is no
|
||||
zend_new_array(); HT_HASH_RESET() uses memset(), so the SSE2 change is
|
||||
not needed.
|
||||
- ZEND_FAST_CONCAT has no string fast path, so only ZEND_CONCAT gets the
|
||||
length checks.
|
||||
- "|| 1" instead of "|| true" in the session upload progress callback
|
||||
(no stdbool.h).
|
||||
- The max_multipart_body_parts hunk of the 7.4 patch is left out, the
|
||||
code is already there.
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.c | 8 +++++
|
||||
Zend/zend_API.h | 2 ++
|
||||
Zend/zend_alloc.c | 66 +++++++++++++++++++++++++++++------------
|
||||
Zend/zend_alloc.h | 2 ++
|
||||
Zend/zend_execute_API.c | 8 +++++
|
||||
Zend/zend_hash.c | 6 ++--
|
||||
Zend/zend_llist.c | 2 ++
|
||||
Zend/zend_multiply.h | 4 +--
|
||||
Zend/zend_strtod.c | 4 +--
|
||||
Zend/zend_vm_def.h | 6 ++++
|
||||
Zend/zend_vm_execute.h | 54 +++++++++++++++++++++++++++++++++
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 ++++
|
||||
main/main.c | 5 ++++
|
||||
main/php_variables.c | 8 ++---
|
||||
main/rfc1867.c | 29 +++++++++++++-----
|
||||
16 files changed, 172 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
|
||||
index 3dcf0671..bdff6616 100644
|
||||
--- a/Zend/zend_API.c
|
||||
+++ b/Zend/zend_API.c
|
||||
@@ -1063,6 +1063,14 @@ ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
|
||||
+{
|
||||
+ _array_init(arg, 0 ZEND_FILE_LINE_RELAY_CC);
|
||||
+ Z_ARRVAL_P(arg)->nTableSize = 1;
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
/* This function should be called after the constructor has been called
|
||||
* because it may call __set from the uninitialized object otherwise. */
|
||||
ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 79267ac0..b48477c4 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -379,10 +379,12 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) _array_init((arg), 0 ZEND_FILE_LINE_CC)
|
||||
#define array_init_size(arg, size) _array_init((arg), (size) ZEND_FILE_LINE_CC)
|
||||
+#define array_init_singleton(arg) _array_init_singleton((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
|
||||
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC)
|
||||
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC);
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index d87b066f..235fc8d9 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_bitset.h"
|
||||
+#include "zend_execute.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
@@ -362,7 +363,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -374,22 +410,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1336,7 +1364,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -2523,7 +2551,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2538,7 +2566,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2555,7 +2583,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2830,7 +2858,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index b195534a..ae14ab9e 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -399,6 +399,8 @@ static void apc_init_heap(void)
|
||||
|
||||
*/
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index 5cb87df6..bb4ee17d 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -301,6 +301,10 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
|
||||
} zend_end_try();
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+
|
||||
zend_try {
|
||||
/* Cleanup static data for functions and arrays.
|
||||
* We need a separate cleanup stage because of the following problem:
|
||||
@@ -380,6 +384,10 @@ void shutdown_executor(void) /* {{{ */
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
zend_try {
|
||||
#if 0&&ZEND_DEBUG
|
||||
signal(SIGSEGV, original_sigsegv_handler);
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index dc443838..647280d2 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -101,7 +101,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize < HT_MIN_SIZE) {
|
||||
nSize = HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
@@ -187,7 +187,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT));
|
||||
@@ -866,7 +866,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
zend_hash_rehash(ht);
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index f771bd29..030472c7 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -114,6 +114,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index 8bece847..e80cc218 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -272,7 +272,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -285,7 +285,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index 3aa99f8d..01c1779d 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -600,7 +600,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -613,7 +613,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index 27edd6fc..47531760 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -316,11 +316,17 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index af3c1815..287a30e5 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -4428,11 +4428,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8513,11 +8519,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10525,11 +10537,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -36525,11 +36543,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -43623,11 +43647,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -47732,11 +47762,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -52089,11 +52125,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -54663,11 +54705,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -55947,11 +55995,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index d3226ee1..ec3c85b3 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -2851,7 +2851,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || 1) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index 8176561a..63ef3617 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -515,18 +515,23 @@ SAPI_API void sapi_deactivate(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index 037a2202..3fa2de32 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1892,6 +1892,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -1945,6 +1947,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index e8fcaa08..31c4089b 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -207,7 +207,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zval_ptr_dtor(&gpc_element);
|
||||
zval_dtor(val);
|
||||
@@ -224,7 +224,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -232,7 +232,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,7 +425,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index cac8af84..b219c9f2 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -407,6 +407,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -447,10 +455,15 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
-
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace(*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -524,11 +537,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -556,14 +569,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://salsa.debian.org/php-team/php/-/tree/7a33180834a6169b933132f697b9286bc2bc3c3f/debian/patches (Sury 7.1.33-80)
|
||||
0167-backport-ZSTR_MAX_LEN.patch
|
||||
0186-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,23 @@
|
||||
From: Remi Collet <remi@remirepo.net>
|
||||
Date: Fri, 22 Nov 2024 15:24:16 +0100
|
||||
Subject: backport ZSTR_MAX_LEN
|
||||
|
||||
(cherry picked from commit 37056ad634d9c44bac0d6c8e730eafaec1344840)
|
||||
---
|
||||
Zend/zend_string.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
|
||||
index 784b88e..5f7a9ea 100644
|
||||
--- a/Zend/zend_string.h
|
||||
+++ b/Zend/zend_string.h
|
||||
@@ -74,6 +74,9 @@ END_EXTERN_C()
|
||||
|
||||
#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
|
||||
|
||||
+#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
|
||||
+#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
|
||||
+
|
||||
#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
|
||||
(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
|
||||
GC_REFCOUNT(str) = 1; \
|
||||
@@ -0,0 +1,893 @@
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Backported from the PHP 7.4 version:
|
||||
- shutdown_executor() frees the object store before the error handlers,
|
||||
so the fast shutdown resets are done just before
|
||||
zend_objects_store_free_object_storage().
|
||||
- "|| 1" instead of "|| true" in the session upload progress callback
|
||||
(no stdbool.h).
|
||||
- The max_multipart_body_parts hunk of the 7.4 patch is left out, the
|
||||
code is already there.
|
||||
- array_init_singleton() is implemented in zend_API.c, there is no
|
||||
zend_new_array(); HT_HASH_RESET() uses memset(), so the SSE2 change is
|
||||
not needed.
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.c | 8 +++
|
||||
Zend/zend_API.h | 2 +
|
||||
Zend/zend_alloc.c | 68 +++++++++++++++++--------
|
||||
Zend/zend_alloc.h | 2 +
|
||||
Zend/zend_execute_API.c | 15 ++++++
|
||||
Zend/zend_hash.c | 6 +--
|
||||
Zend/zend_llist.c | 2 +
|
||||
Zend/zend_multiply.h | 4 +-
|
||||
Zend/zend_strtod.c | 4 +-
|
||||
Zend/zend_vm_def.h | 12 +++++
|
||||
Zend/zend_vm_execute.h | 108 ++++++++++++++++++++++++++++++++++++++++
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 ++
|
||||
main/main.c | 5 ++
|
||||
main/php_variables.c | 8 +--
|
||||
main/rfc1867.c | 29 ++++++++---
|
||||
16 files changed, 240 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
|
||||
index 604450e9..738266cf 100644
|
||||
--- a/Zend/zend_API.c
|
||||
+++ b/Zend/zend_API.c
|
||||
@@ -1093,6 +1093,14 @@ ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
|
||||
+{
|
||||
+ _array_init(arg, 0 ZEND_FILE_LINE_RELAY_CC);
|
||||
+ Z_ARRVAL_P(arg)->nTableSize = 1;
|
||||
+ return SUCCESS;
|
||||
+}
|
||||
+/* }}} */
|
||||
+
|
||||
/* This function should be called after the constructor has been called
|
||||
* because it may call __set from the uninitialized object otherwise. */
|
||||
ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 38407703..763c64ab 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -392,10 +392,12 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) _array_init((arg), 0 ZEND_FILE_LINE_CC)
|
||||
#define array_init_size(arg, size) _array_init((arg), (size) ZEND_FILE_LINE_CC)
|
||||
+#define array_init_singleton(arg) _array_init_singleton((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
|
||||
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC)
|
||||
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC);
|
||||
+ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index f4a61795..4b914251 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_bitset.h"
|
||||
+#include "zend_execute.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
@@ -360,7 +361,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -372,22 +408,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1338,7 +1366,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -1731,7 +1759,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
||||
void *ptr;
|
||||
|
||||
if (UNEXPECTED(new_size < size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
}
|
||||
|
||||
#if ZEND_MM_LIMIT
|
||||
@@ -2527,7 +2555,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length+1);
|
||||
@@ -2539,7 +2567,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length);
|
||||
@@ -2553,7 +2581,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2827,7 +2855,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index e3ab221e..334004c5 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -399,6 +399,8 @@ static void apc_init_heap(void)
|
||||
|
||||
*/
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index 9f10843b..99d4ffa6 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -263,8 +263,21 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_close_rsrc_list(&EG(regular_list));
|
||||
} zend_end_try();
|
||||
|
||||
+ if (fast_shutdown) {
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting)));
|
||||
+ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers)));
|
||||
+ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers)));
|
||||
+ }
|
||||
+
|
||||
zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
/* All resources and objects are destroyed. */
|
||||
/* No PHP callback functions may be called after this point. */
|
||||
EG(active) = 0;
|
||||
@@ -299,6 +312,8 @@ void shutdown_executor(void) /* {{{ */
|
||||
} ZEND_HASH_FOREACH_END_DEL();
|
||||
|
||||
zend_cleanup_internal_classes();
|
||||
+ EG(objects_store).object_buckets = NULL;
|
||||
+ EG(objects_store).top = 1;
|
||||
} else {
|
||||
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
|
||||
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index f5fba679..d6c022a2 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -103,7 +103,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize < HT_MIN_SIZE) {
|
||||
nSize = HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
@@ -189,7 +189,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT_RC1(ht);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT));
|
||||
@@ -865,7 +865,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
zend_hash_rehash(ht);
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index de93f295..4b0509cb 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -114,6 +114,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index 26853a3c..386f9353 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -309,7 +309,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -322,7 +322,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index 3aa99f8d..01c1779d 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -600,7 +600,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -613,7 +613,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index ed84d17b..ebdb2fdc 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -316,11 +316,17 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -2716,11 +2722,17 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index 3f975dec..b0170aff 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -4406,11 +4406,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -5202,11 +5208,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8524,11 +8536,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -9253,11 +9271,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10580,11 +10604,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -11275,11 +11305,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -35136,11 +35172,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -37690,11 +37732,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -41657,11 +41705,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -44200,11 +44254,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -45369,11 +45429,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -47770,11 +47836,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -49343,11 +49415,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -49957,11 +50035,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -51749,11 +51833,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -52294,11 +52384,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -53079,11 +53175,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -53625,11 +53727,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
break;
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 0f0d9bcb..8be81f6d 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -3071,7 +3071,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || 1) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index 01383357..17afa0e0 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -515,18 +515,23 @@ SAPI_API void sapi_deactivate(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index 0cfdb913..92c19e46 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1895,6 +1895,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -1948,6 +1950,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index 3e0e8d76..a5a9af19 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -213,7 +213,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zval_ptr_dtor(&gpc_element);
|
||||
zval_dtor(val);
|
||||
@@ -230,7 +230,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -238,7 +238,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
} else {
|
||||
SEPARATE_ARRAY(gpc_element_p);
|
||||
}
|
||||
@@ -433,7 +433,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index 43b94c05..b7d1ed2a 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -407,6 +407,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -447,10 +455,15 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
-
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace(*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -524,11 +537,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -556,14 +569,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://salsa.debian.org/php-team/php/-/tree/e0bcd488d9f8da024d9e1a254113539a846cac6d/debian/patches (Sury 7.2.34-66)
|
||||
0135-backport-ZSTR_MAX_LEN.patch
|
||||
0159-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,22 @@
|
||||
From: Remi Collet <remi@remirepo.net>
|
||||
Date: Fri, 22 Nov 2024 15:24:16 +0100
|
||||
Subject: backport ZSTR_MAX_LEN
|
||||
|
||||
---
|
||||
Zend/zend_string.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
|
||||
index 396b63b..8ef979f 100644
|
||||
--- a/Zend/zend_string.h
|
||||
+++ b/Zend/zend_string.h
|
||||
@@ -76,6 +76,9 @@ END_EXTERN_C()
|
||||
|
||||
#define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
|
||||
|
||||
+#define ZSTR_MAX_OVERHEAD (ZEND_MM_ALIGNED_SIZE(_ZSTR_HEADER_SIZE + 1))
|
||||
+#define ZSTR_MAX_LEN (SIZE_MAX - ZSTR_MAX_OVERHEAD)
|
||||
+
|
||||
#define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \
|
||||
(str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \
|
||||
GC_SET_REFCOUNT(str, 1); \
|
||||
@@ -0,0 +1,912 @@
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Backported from the PHP 7.4 version:
|
||||
- shutdown_executor() frees the object store before the error handlers,
|
||||
so the fast shutdown resets are done just before
|
||||
zend_objects_store_free_object_storage().
|
||||
- "|| 1" instead of "|| true" in the session upload progress callback
|
||||
(no stdbool.h).
|
||||
- The max_multipart_body_parts hunk of the 7.4 patch is left out, the
|
||||
code is already there.
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.h | 1 +
|
||||
Zend/zend_alloc.c | 68 +++++++++++++++++++--------
|
||||
Zend/zend_alloc.h | 2 +
|
||||
Zend/zend_execute_API.c | 15 ++++++
|
||||
Zend/zend_hash.c | 13 +++--
|
||||
Zend/zend_hash.h | 1 +
|
||||
Zend/zend_llist.c | 2 +
|
||||
Zend/zend_multiply.h | 4 +-
|
||||
Zend/zend_strtod.c | 4 +-
|
||||
Zend/zend_types.h | 26 +++++-----
|
||||
Zend/zend_vm_def.h | 12 +++++
|
||||
Zend/zend_vm_execute.h | 102 ++++++++++++++++++++++++++++++++++++++++
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 ++
|
||||
main/main.c | 5 ++
|
||||
main/php_variables.c | 8 ++--
|
||||
main/rfc1867.c | 29 ++++++++----
|
||||
17 files changed, 248 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 3c134f44..67942e39 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -376,6 +376,7 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
|
||||
#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
|
||||
+#define array_init_singleton(arg) ZVAL_ARR((arg), zend_new_array_singleton())
|
||||
ZEND_API int object_init(zval *arg);
|
||||
ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
|
||||
ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index 25216898..126aa124 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_bitset.h"
|
||||
+#include "zend_execute.h"
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
@@ -358,7 +359,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -370,22 +406,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1352,7 +1380,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -1800,7 +1828,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
||||
void *ptr;
|
||||
|
||||
if (UNEXPECTED(new_size < size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
}
|
||||
|
||||
#if ZEND_MM_LIMIT
|
||||
@@ -2596,7 +2624,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length+1);
|
||||
@@ -2608,7 +2636,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length);
|
||||
@@ -2622,7 +2650,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2901,7 +2929,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index b3986ab9..992fa225 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -397,6 +397,8 @@ static void apc_init_heap(void)
|
||||
|
||||
*/
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index 6eb9dfac..65e66fc8 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -265,8 +265,21 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_close_rsrc_list(&EG(regular_list));
|
||||
} zend_end_try();
|
||||
|
||||
+ if (fast_shutdown) {
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting)));
|
||||
+ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers)));
|
||||
+ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers)));
|
||||
+ }
|
||||
+
|
||||
zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
|
||||
|
||||
+ /* may be used by zend_error before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
/* All resources and objects are destroyed. */
|
||||
/* No PHP callback functions may be called after this point. */
|
||||
EG(active) = 0;
|
||||
@@ -285,6 +298,8 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_hash_discard(EG(function_table), EG(persistent_functions_count));
|
||||
zend_hash_discard(EG(class_table), EG(persistent_classes_count));
|
||||
zend_cleanup_internal_classes();
|
||||
+ EG(objects_store).object_buckets = NULL;
|
||||
+ EG(objects_store).top = 1;
|
||||
} else {
|
||||
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
|
||||
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index 7ba4f32c..f228f335 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -93,7 +93,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize <= HT_MIN_SIZE) {
|
||||
return HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
@@ -219,6 +219,13 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void)
|
||||
return ht;
|
||||
}
|
||||
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void)
|
||||
+{
|
||||
+ HashTable *ht = _zend_new_array_0();
|
||||
+ ht->nTableSize = 1;
|
||||
+ return ht;
|
||||
+}
|
||||
+
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize)
|
||||
{
|
||||
HashTable *ht = emalloc(sizeof(HashTable));
|
||||
@@ -230,7 +237,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT_RC1(ht);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
||||
@@ -1041,7 +1048,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||
zend_hash_rehash(ht);
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
|
||||
index 2c295adc..51dc4c5e 100644
|
||||
--- a/Zend/zend_hash.h
|
||||
+++ b/Zend/zend_hash.h
|
||||
@@ -276,6 +276,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
|
||||
#endif
|
||||
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void);
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void);
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size);
|
||||
ZEND_API uint32_t zend_array_count(HashTable *ht);
|
||||
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source);
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index ea5e2cae..f45ddda9 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index 1ec1af06..ee2fd8df 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -321,7 +321,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -334,7 +334,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index 3aa99f8d..01c1779d 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -600,7 +600,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -613,7 +613,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
|
||||
index 4250aabd..fd7e5d6a 100644
|
||||
--- a/Zend/zend_types.h
|
||||
+++ b/Zend/zend_types.h
|
||||
@@ -317,17 +317,21 @@ struct _zend_array {
|
||||
# define HT_HASH_RESET(ht) do { \
|
||||
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
|
||||
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
|
||||
- __m128i xmm0 = _mm_setzero_si128(); \
|
||||
- xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
- ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
- do { \
|
||||
- _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
- p += 64; \
|
||||
- size -= 64; \
|
||||
- } while (size != 0); \
|
||||
+ if (UNEXPECTED(size < 64)) { \
|
||||
+ memset(p, HT_INVALID_IDX, size); \
|
||||
+ } else { \
|
||||
+ __m128i xmm0 = _mm_setzero_si128(); \
|
||||
+ xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
+ ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
+ do { \
|
||||
+ _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
+ p += 64; \
|
||||
+ size -= 64; \
|
||||
+ } while (size != 0); \
|
||||
+ } \
|
||||
} while (0)
|
||||
#else
|
||||
# define HT_HASH_RESET(ht) \
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index 1b4eb572..da46a635 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -320,11 +320,17 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
FREE_OP2();
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -2744,11 +2750,17 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
FREE_OP2();
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index be8b2b3a..ce447cb9 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -4968,11 +4968,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -6679,11 +6685,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -7150,11 +7162,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -9774,11 +9792,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10243,11 +10267,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -12967,11 +12997,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -13732,11 +13768,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -14705,11 +14747,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -15346,11 +15394,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -16800,11 +16854,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17227,11 +17287,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -38581,11 +38647,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -41090,11 +41162,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -42559,11 +42637,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -44857,11 +44941,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -48227,11 +48317,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -50659,11 +50755,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 8fad988d..1c328815 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -3160,7 +3160,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || 1) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index afb0c772..6749184e 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -513,18 +513,23 @@ SAPI_API void sapi_deactivate(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index c3939b3c..6e38959a 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1919,6 +1919,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -1972,6 +1974,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index d0ebd50e..9ebad5c8 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -219,7 +219,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zend_array_destroy(Z_ARR(gpc_element));
|
||||
zval_ptr_dtor_nogc(val);
|
||||
@@ -236,7 +236,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -244,7 +244,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor_nogc(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
} else {
|
||||
SEPARATE_ARRAY(gpc_element_p);
|
||||
}
|
||||
@@ -442,7 +442,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index 3415db2f..265ca9e2 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -405,6 +405,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -445,10 +453,15 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
-
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace(*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -522,11 +535,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -554,14 +567,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://salsa.debian.org/php-team/php/-/tree/ecf76f6726bee03657a2c608240685732312fe54/debian/patches (Sury 7.3.33-35)
|
||||
0107-backport-ZSTR_MAX_LEN.patch
|
||||
0139-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,976 @@
|
||||
From 712e60f9edfd03f0960fc4fc3c2c375f42b90aa2 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:09:54 +0200
|
||||
Subject: [PATCH] Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.h | 1 +
|
||||
Zend/zend_alloc.c | 68 ++++++++++++++++++++---------
|
||||
Zend/zend_alloc.h | 2 +
|
||||
Zend/zend_execute_API.c | 13 ++++++
|
||||
Zend/zend_hash.c | 13 ++++--
|
||||
Zend/zend_hash.h | 1 +
|
||||
Zend/zend_llist.c | 2 +
|
||||
Zend/zend_multiply.h | 4 +-
|
||||
Zend/zend_strtod.c | 4 +-
|
||||
Zend/zend_types.h | 26 +++++++-----
|
||||
Zend/zend_vm_def.h | 11 ++++-
|
||||
Zend/zend_vm_execute.h | 94 +++++++++++++++++++++++++++++++++++++----
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 +++
|
||||
main/main.c | 6 +++
|
||||
main/php_variables.c | 8 ++--
|
||||
main/rfc1867.c | 39 ++++++++++++++---
|
||||
17 files changed, 240 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 2a3b582902..26f7726bd8 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -380,6 +380,7 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
|
||||
#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
|
||||
+#define array_init_singleton(arg) ZVAL_ARR((arg), zend_new_array_singleton())
|
||||
ZEND_API int object_init(zval *arg);
|
||||
ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
|
||||
ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index 3a33e5441c..be9b975426 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_bitset.h"
|
||||
+#include "zend_execute.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@@ -363,7 +364,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -375,22 +411,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1318,7 +1346,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -1762,7 +1790,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
||||
void *ptr;
|
||||
|
||||
if (UNEXPECTED(new_size < size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
}
|
||||
|
||||
#if ZEND_MM_LIMIT
|
||||
@@ -2617,7 +2645,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length+1);
|
||||
@@ -2629,7 +2657,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length);
|
||||
@@ -2643,7 +2671,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -2974,7 +3002,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index 8bb854328d..2ed2ed8b3a 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -402,6 +402,8 @@ static void apc_init_heap(void)
|
||||
size_t zend_mm_globals_size(void);
|
||||
#endif
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index f4f0fa14f1..724b6e5cc4 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -337,10 +337,21 @@ void shutdown_executor(void) /* {{{ */
|
||||
gc_collect_cycles();
|
||||
}
|
||||
#endif
|
||||
+ } else {
|
||||
+ /* may be used by zend_error_zstr_at before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting)));
|
||||
+ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers)));
|
||||
+ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers)));
|
||||
}
|
||||
|
||||
zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
|
||||
|
||||
+ /* may be used by zend_error_zstr_at before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
zend_weakrefs_shutdown();
|
||||
|
||||
zend_try {
|
||||
@@ -357,6 +368,8 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_hash_discard(EG(function_table), EG(persistent_functions_count));
|
||||
zend_hash_discard(EG(class_table), EG(persistent_classes_count));
|
||||
zend_cleanup_internal_classes();
|
||||
+ EG(objects_store).object_buckets = NULL;
|
||||
+ EG(objects_store).top = 1;
|
||||
} else {
|
||||
zend_vm_stack_destroy();
|
||||
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index da150bd798..ef3d301db1 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -97,7 +97,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize <= HT_MIN_SIZE) {
|
||||
return HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
@@ -251,6 +251,13 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void)
|
||||
return ht;
|
||||
}
|
||||
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void)
|
||||
+{
|
||||
+ HashTable *ht = _zend_new_array_0();
|
||||
+ ht->nTableSize = 1;
|
||||
+ return ht;
|
||||
+}
|
||||
+
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize)
|
||||
{
|
||||
HashTable *ht = emalloc(sizeof(HashTable));
|
||||
@@ -282,7 +289,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT_RC1(ht);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
||||
@@ -1164,7 +1171,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||
zend_hash_rehash(ht);
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
|
||||
index f1e2d34685..b833479eaa 100644
|
||||
--- a/Zend/zend_hash.h
|
||||
+++ b/Zend/zend_hash.h
|
||||
@@ -296,6 +296,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
|
||||
#endif
|
||||
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void);
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void);
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size);
|
||||
ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2);
|
||||
ZEND_API uint32_t zend_array_count(HashTable *ht);
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index 4a2c22e632..0955e953aa 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index a3827d25d1..a9bbda5538 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -321,7 +321,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -334,7 +334,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index 2228e2262c..ad8df201af 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -603,7 +603,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -616,7 +616,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
|
||||
index 7b8c079c45..f7828eb6d3 100644
|
||||
--- a/Zend/zend_types.h
|
||||
+++ b/Zend/zend_types.h
|
||||
@@ -330,17 +330,21 @@ struct _zend_array {
|
||||
# define HT_HASH_RESET(ht) do { \
|
||||
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
|
||||
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
|
||||
- __m128i xmm0 = _mm_setzero_si128(); \
|
||||
- xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
- ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
- do { \
|
||||
- _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
- p += 64; \
|
||||
- size -= 64; \
|
||||
- } while (size != 0); \
|
||||
+ if (UNEXPECTED(size < 64)) { \
|
||||
+ memset(p, HT_INVALID_IDX, size); \
|
||||
+ } else { \
|
||||
+ __m128i xmm0 = _mm_setzero_si128(); \
|
||||
+ xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
+ ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
+ do { \
|
||||
+ _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
+ p += 64; \
|
||||
+ size -= 64; \
|
||||
+ } while (size != 0); \
|
||||
+ } \
|
||||
} while (0)
|
||||
#else
|
||||
# define HT_HASH_RESET(ht) \
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index d362b01643..3af90d705b 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -417,7 +417,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -426,6 +426,9 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -3210,6 +3213,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -3217,6 +3223,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index 2875fd3740..8701e77ea8 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -5631,6 +5631,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -5638,6 +5641,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -7491,6 +7497,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -7498,6 +7507,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -7900,7 +7912,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -7909,6 +7921,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -9952,6 +9967,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -9959,6 +9977,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10361,7 +10382,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10370,6 +10391,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -13928,6 +13952,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -13935,6 +13962,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -14681,7 +14711,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -14690,6 +14720,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -15353,7 +15386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -15362,6 +15395,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -16107,6 +16143,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -16114,6 +16153,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17040,7 +17082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17049,6 +17091,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17401,6 +17446,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -17408,6 +17456,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -38348,7 +38399,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -38357,6 +38408,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -40727,7 +40781,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -40736,6 +40790,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -41849,6 +41906,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -41856,6 +41916,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -44132,6 +44195,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -44139,6 +44205,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -46857,7 +46926,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -46866,6 +46935,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -49268,6 +49340,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -49275,6 +49350,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 8fb6dd2cd5..89a7400a9c 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -3174,7 +3174,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || true) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index a5a68f8c68..1c320f6e3f 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -509,18 +509,23 @@ SAPI_API void sapi_deactivate(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index 0b33b2b56c..bb8501f973 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -836,6 +836,7 @@ PHP_INI_BEGIN()
|
||||
PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL)
|
||||
PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL)
|
||||
PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL)
|
||||
+ PHP_INI_ENTRY("max_multipart_body_parts", "-1", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL)
|
||||
|
||||
STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals)
|
||||
STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals)
|
||||
@@ -1960,6 +1961,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -2012,6 +2015,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index 18f6b65a6c..c920e4d5e2 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -218,7 +218,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zend_array_destroy(Z_ARR(gpc_element));
|
||||
zval_ptr_dtor_nogc(val);
|
||||
@@ -229,7 +229,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -237,7 +237,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor_nogc(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
} else {
|
||||
SEPARATE_ARRAY(gpc_element_p);
|
||||
}
|
||||
@@ -429,7 +429,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index edef19c16d..4946df0ca2 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -397,6 +397,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -437,10 +445,16 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace((unsigned char)*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -514,11 +528,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -546,14 +560,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,6 +708,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
|
||||
void *event_extra_data = NULL;
|
||||
unsigned int llen = 0;
|
||||
int upload_cnt = INI_INT("max_file_uploads");
|
||||
+ int body_parts_cnt = INI_INT("max_multipart_body_parts");
|
||||
const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding();
|
||||
php_rfc1867_getword_t getword;
|
||||
php_rfc1867_getword_conf_t getword_conf;
|
||||
@@ -715,6 +730,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (body_parts_cnt < 0) {
|
||||
+ body_parts_cnt = PG(max_input_vars) + upload_cnt;
|
||||
+ }
|
||||
+ int body_parts_limit = body_parts_cnt;
|
||||
+
|
||||
/* Get the boundary */
|
||||
boundary = strstr(content_type_dup, "boundary");
|
||||
if (!boundary) {
|
||||
@@ -799,6 +819,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
|
||||
char *pair = NULL;
|
||||
int end = 0;
|
||||
|
||||
+ if (--body_parts_cnt < 0) {
|
||||
+ php_error_docref(NULL, E_WARNING, "Multipart body parts limit exceeded %d. To increase the limit change max_multipart_body_parts in php.ini.", body_parts_limit);
|
||||
+ goto fileupload_done;
|
||||
+ }
|
||||
+
|
||||
while (isspace(*cd)) {
|
||||
++cd;
|
||||
}
|
||||
--
|
||||
2.56.0
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# https://github.com/php/php-src/commit/712e60f9edfd03f0960fc4fc3c2c375f42b90aa2 (branch PHP-7.4-CVE-2026-109618-109619)
|
||||
0001-Avoid-state-corruption-via-bailout.patch
|
||||
@@ -0,0 +1,944 @@
|
||||
From 82f8f31b16a035c1b67cc253e79f7cc288f4cc20 Mon Sep 17 00:00:00 2001
|
||||
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
Date: Sun, 18 Oct 2026 20:11:52 +0200
|
||||
Subject: [PATCH] Avoid state corruption via bailout
|
||||
|
||||
Minimal mitigation for EOL version.
|
||||
|
||||
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
|
||||
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
|
||||
|
||||
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
|
||||
---
|
||||
Zend/zend_API.h | 1 +
|
||||
Zend/zend_alloc.c | 68 ++++++++++++++++++++---------
|
||||
Zend/zend_alloc.h | 2 +
|
||||
Zend/zend_execute_API.c | 13 ++++++
|
||||
Zend/zend_hash.c | 13 ++++--
|
||||
Zend/zend_hash.h | 1 +
|
||||
Zend/zend_llist.c | 2 +
|
||||
Zend/zend_multiply.h | 4 +-
|
||||
Zend/zend_strtod.c | 4 +-
|
||||
Zend/zend_types.h | 26 +++++++-----
|
||||
Zend/zend_vm_def.h | 11 ++++-
|
||||
Zend/zend_vm_execute.h | 94 +++++++++++++++++++++++++++++++++++++----
|
||||
ext/session/session.c | 2 +-
|
||||
main/SAPI.c | 5 +++
|
||||
main/main.c | 6 +++
|
||||
main/php_variables.c | 8 ++--
|
||||
main/rfc1867.c | 28 +++++++++---
|
||||
17 files changed, 229 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
|
||||
index 456ef05d80..0d015bacf3 100644
|
||||
--- a/Zend/zend_API.h
|
||||
+++ b/Zend/zend_API.h
|
||||
@@ -428,6 +428,7 @@ ZEND_API const char *zend_get_type_by_const(int type);
|
||||
|
||||
#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
|
||||
#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
|
||||
+#define array_init_singleton(arg) ZVAL_ARR((arg), zend_new_array_singleton())
|
||||
ZEND_API void object_init(zval *arg);
|
||||
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *ce);
|
||||
ZEND_API zend_result object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties);
|
||||
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
|
||||
index 6e0ce4b651..a21b10f9be 100644
|
||||
--- a/Zend/zend_alloc.c
|
||||
+++ b/Zend/zend_alloc.c
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_bitset.h"
|
||||
+#include "zend_execute.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@@ -363,7 +364,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
|
||||
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
|
||||
kill(getpid(), SIGSEGV);
|
||||
#endif
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
+}
|
||||
+
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...)
|
||||
+{
|
||||
+ zend_string *script_filename = NULL;
|
||||
+ uint32_t script_lineno = 0;
|
||||
+
|
||||
+ if (zend_is_executing()) {
|
||||
+ script_filename = zend_get_executed_filename_ex();
|
||||
+ script_lineno = zend_get_executed_lineno();
|
||||
+ } else if (zend_is_compiling()) {
|
||||
+ script_filename = zend_get_compiled_filename();
|
||||
+ script_lineno = zend_get_compiled_lineno();
|
||||
+ }
|
||||
+
|
||||
+ va_list args;
|
||||
+ va_start(args, format);
|
||||
+
|
||||
+ char buf[1024];
|
||||
+ vsnprintf(buf, sizeof(buf), format, args);
|
||||
+
|
||||
+ va_end(args);
|
||||
+
|
||||
+ fprintf(stderr,
|
||||
+ "\nFatal error: %s in %s on line %d\n",
|
||||
+ buf,
|
||||
+ script_filename ? ZSTR_VAL(script_filename) : "Unknown",
|
||||
+ script_lineno);
|
||||
+
|
||||
+ /* See http://support.microsoft.com/kb/190351 */
|
||||
+# ifdef ZEND_WIN32
|
||||
+ fflush(stderr);
|
||||
+# endif
|
||||
+
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
@@ -375,22 +411,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
|
||||
#endif
|
||||
size_t size)
|
||||
{
|
||||
+ (void) heap;
|
||||
|
||||
- heap->overflow = 1;
|
||||
- zend_try {
|
||||
- zend_error_noreturn(E_ERROR,
|
||||
- format,
|
||||
- limit,
|
||||
+ zend_mm_safe_error_ex(format, limit,
|
||||
#if ZEND_DEBUG
|
||||
- filename,
|
||||
- lineno,
|
||||
+ filename,
|
||||
+ lineno,
|
||||
#endif
|
||||
- size);
|
||||
- } zend_catch {
|
||||
- } zend_end_try();
|
||||
- heap->overflow = 0;
|
||||
- zend_bailout();
|
||||
- exit(1);
|
||||
+ size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1318,7 +1346,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
|
||||
size = MAX(size, 1);
|
||||
size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info));
|
||||
if (UNEXPECTED(size < real_size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -1762,7 +1790,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
||||
void *ptr;
|
||||
|
||||
if (UNEXPECTED(new_size < size)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", size, alignment);
|
||||
}
|
||||
|
||||
#if ZEND_MM_LIMIT
|
||||
@@ -2618,7 +2646,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
|
||||
length = strlen(s);
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length+1);
|
||||
@@ -2630,7 +2658,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
memcpy(p, s, length);
|
||||
@@ -2644,7 +2672,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
|
||||
char *p;
|
||||
|
||||
if (UNEXPECTED(length + 1 == 0)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length);
|
||||
}
|
||||
p = (char *) malloc(length + 1);
|
||||
if (UNEXPECTED(p == NULL)) {
|
||||
@@ -3048,7 +3076,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
||||
static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
- exit(1);
|
||||
+ _exit(1);
|
||||
}
|
||||
|
||||
ZEND_API void * __zend_malloc(size_t len)
|
||||
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
|
||||
index de450bbca2..f6bc82d250 100644
|
||||
--- a/Zend/zend_alloc.h
|
||||
+++ b/Zend/zend_alloc.h
|
||||
@@ -403,6 +403,8 @@ static void apc_init_heap(void)
|
||||
size_t zend_mm_globals_size(void);
|
||||
#endif
|
||||
|
||||
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...);
|
||||
+
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
|
||||
index 18104c2d99..2f19a17c6b 100644
|
||||
--- a/Zend/zend_execute_API.c
|
||||
+++ b/Zend/zend_execute_API.c
|
||||
@@ -334,10 +334,21 @@ void shutdown_executor(void) /* {{{ */
|
||||
gc_collect_cycles();
|
||||
}
|
||||
#endif
|
||||
+ } else {
|
||||
+ /* may be used by zend_error_zstr_at before init_executor */
|
||||
+ ZVAL_UNDEF(&EG(user_error_handler));
|
||||
+ ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
+ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting)));
|
||||
+ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers)));
|
||||
+ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers)));
|
||||
}
|
||||
|
||||
zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
|
||||
|
||||
+ /* may be used by zend_error_zstr_at before init_executor */
|
||||
+ EG(error_handling) = EH_NORMAL;
|
||||
+ EG(exception) = NULL;
|
||||
+
|
||||
zend_weakrefs_shutdown();
|
||||
|
||||
zend_try {
|
||||
@@ -354,6 +365,8 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_hash_discard(EG(function_table), EG(persistent_functions_count));
|
||||
zend_hash_discard(EG(class_table), EG(persistent_classes_count));
|
||||
zend_cleanup_internal_classes();
|
||||
+ EG(objects_store).object_buckets = NULL;
|
||||
+ EG(objects_store).top = 1;
|
||||
} else {
|
||||
zend_vm_stack_destroy();
|
||||
|
||||
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
|
||||
index a3b62160dc..a4c318d123 100644
|
||||
--- a/Zend/zend_hash.c
|
||||
+++ b/Zend/zend_hash.c
|
||||
@@ -119,7 +119,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
|
||||
if (nSize <= HT_MIN_SIZE) {
|
||||
return HT_MIN_SIZE;
|
||||
} else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
@@ -273,6 +273,13 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void)
|
||||
return ht;
|
||||
}
|
||||
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void)
|
||||
+{
|
||||
+ HashTable *ht = _zend_new_array_0();
|
||||
+ ht->nTableSize = 1;
|
||||
+ return ht;
|
||||
+}
|
||||
+
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize)
|
||||
{
|
||||
HashTable *ht = emalloc(sizeof(HashTable));
|
||||
@@ -304,7 +311,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT_RC1(ht);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
||||
@@ -1190,7 +1197,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||
pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||
zend_hash_rehash(ht);
|
||||
} else {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
|
||||
index ced21a2ca1..b697acf587 100644
|
||||
--- a/Zend/zend_hash.h
|
||||
+++ b/Zend/zend_hash.h
|
||||
@@ -296,6 +296,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
|
||||
#endif
|
||||
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void);
|
||||
+ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void);
|
||||
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size);
|
||||
ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2);
|
||||
ZEND_API uint32_t zend_array_count(HashTable *ht);
|
||||
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
|
||||
index 78a3310438..8c42b2494e 100644
|
||||
--- a/Zend/zend_llist.c
|
||||
+++ b/Zend/zend_llist.c
|
||||
@@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
|
||||
current = next;
|
||||
}
|
||||
|
||||
+ l->head = NULL;
|
||||
+ l->tail = NULL;
|
||||
l->count = 0;
|
||||
}
|
||||
|
||||
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
|
||||
index c6cd472a23..bfe1b8e886 100644
|
||||
--- a/Zend/zend_multiply.h
|
||||
+++ b/Zend/zend_multiply.h
|
||||
@@ -321,7 +321,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
@@ -334,7 +334,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
|
||||
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
|
||||
|
||||
if (UNEXPECTED(overflow)) {
|
||||
- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
+ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
|
||||
index e88fbd001f..fd6b23c9cb 100644
|
||||
--- a/Zend/zend_strtod.c
|
||||
+++ b/Zend/zend_strtod.c
|
||||
@@ -603,7 +603,7 @@ Balloc
|
||||
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#else
|
||||
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
|
||||
@@ -616,7 +616,7 @@ Balloc
|
||||
rv = (Bigint*)MALLOC(len*sizeof(double));
|
||||
if (!rv) {
|
||||
FREE_DTOA_LOCK(0);
|
||||
- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory");
|
||||
+ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
|
||||
}
|
||||
#endif
|
||||
rv->k = k;
|
||||
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
|
||||
index 82cf20f1b5..1a10ba718c 100644
|
||||
--- a/Zend/zend_types.h
|
||||
+++ b/Zend/zend_types.h
|
||||
@@ -439,17 +439,21 @@ struct _zend_array {
|
||||
# define HT_HASH_RESET(ht) do { \
|
||||
char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \
|
||||
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
|
||||
- __m128i xmm0 = _mm_setzero_si128(); \
|
||||
- xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
- ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
- do { \
|
||||
- _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
- _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
- p += 64; \
|
||||
- size -= 64; \
|
||||
- } while (size != 0); \
|
||||
+ if (UNEXPECTED(size < 64)) { \
|
||||
+ memset(p, HT_INVALID_IDX, size); \
|
||||
+ } else { \
|
||||
+ __m128i xmm0 = _mm_setzero_si128(); \
|
||||
+ xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
|
||||
+ ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
|
||||
+ do { \
|
||||
+ _mm_storeu_si128((__m128i*)p, xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+16), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+32), xmm0); \
|
||||
+ _mm_storeu_si128((__m128i*)(p+48), xmm0); \
|
||||
+ p += 64; \
|
||||
+ size -= 64; \
|
||||
+ } while (size != 0); \
|
||||
+ } \
|
||||
} while (0)
|
||||
#else
|
||||
# define HT_HASH_RESET(ht) \
|
||||
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
|
||||
index bcb9be8dab..406350ef26 100644
|
||||
--- a/Zend/zend_vm_def.h
|
||||
+++ b/Zend/zend_vm_def.h
|
||||
@@ -408,7 +408,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -417,6 +417,9 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -3157,6 +3160,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -3164,6 +3170,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
|
||||
index 049d0f2126..eeca7ebb75 100644
|
||||
--- a/Zend/zend_vm_execute.h
|
||||
+++ b/Zend/zend_vm_execute.h
|
||||
@@ -6348,6 +6348,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -6355,6 +6358,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8225,7 +8231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8234,6 +8240,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -8641,6 +8650,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -8648,6 +8660,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10613,7 +10628,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -10622,6 +10637,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -11029,6 +11047,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -11036,6 +11057,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -14644,7 +14668,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -14653,6 +14677,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -15374,6 +15401,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -15381,6 +15411,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -16067,7 +16100,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -16076,6 +16109,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -16797,6 +16833,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -16804,6 +16843,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17744,7 +17786,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -17753,6 +17795,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -18112,6 +18157,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -18119,6 +18167,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -39226,7 +39277,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -39235,6 +39286,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -41677,6 +41731,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -41684,6 +41741,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -42951,7 +43011,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -42960,6 +43020,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -45331,6 +45394,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -45338,6 +45404,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -48150,7 +48219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
}
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -48159,6 +48228,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
@@ -50629,6 +50701,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
|
||||
size_t len = ZSTR_LEN(op1_str);
|
||||
|
||||
+ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
|
||||
@@ -50636,6 +50711,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER
|
||||
zend_string_release_ex(op2_str, 0);
|
||||
}
|
||||
} else {
|
||||
+ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
|
||||
+ zend_mm_safe_error_ex("Integer overflow in memory allocation");
|
||||
+ }
|
||||
str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
|
||||
memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
|
||||
memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
|
||||
diff --git a/ext/session/session.c b/ext/session/session.c
|
||||
index 3c875296c3..0c45b1bb41 100644
|
||||
--- a/ext/session/session.c
|
||||
+++ b/ext/session/session.c
|
||||
@@ -3017,7 +3017,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
|
||||
if (php_session_rfc1867_orig_callback) {
|
||||
retval = php_session_rfc1867_orig_callback(event, event_data, extra);
|
||||
}
|
||||
- if (!PS(rfc1867_enabled)) {
|
||||
+ if (!PS(rfc1867_enabled) || true) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
diff --git a/main/SAPI.c b/main/SAPI.c
|
||||
index eea417cedc..85d964d21b 100644
|
||||
--- a/main/SAPI.c
|
||||
+++ b/main/SAPI.c
|
||||
@@ -503,18 +503,23 @@ SAPI_API void sapi_deactivate_module(void)
|
||||
}
|
||||
if (SG(request_info).auth_user) {
|
||||
efree(SG(request_info).auth_user);
|
||||
+ SG(request_info).auth_user = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_password) {
|
||||
efree(SG(request_info).auth_password);
|
||||
+ SG(request_info).auth_password = NULL;
|
||||
}
|
||||
if (SG(request_info).auth_digest) {
|
||||
efree(SG(request_info).auth_digest);
|
||||
+ SG(request_info).auth_digest = NULL;
|
||||
}
|
||||
if (SG(request_info).content_type_dup) {
|
||||
efree(SG(request_info).content_type_dup);
|
||||
+ SG(request_info).content_type_dup = NULL;
|
||||
}
|
||||
if (SG(request_info).current_user) {
|
||||
efree(SG(request_info).current_user);
|
||||
+ SG(request_info).current_user = NULL;
|
||||
}
|
||||
if (sapi_module.deactivate) {
|
||||
sapi_module.deactivate();
|
||||
diff --git a/main/main.c b/main/main.c
|
||||
index c58ea58bf5..48feda4bc7 100644
|
||||
--- a/main/main.c
|
||||
+++ b/main/main.c
|
||||
@@ -1847,6 +1847,8 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ ZVAL_UNDEF(&PG(http_globals)[i]);
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
@@ -1878,6 +1880,7 @@ void php_request_shutdown(void *dummy)
|
||||
|
||||
/* 15. Free Willy (here be crashes) */
|
||||
zend_interned_strings_deactivate();
|
||||
+ clear_last_error();
|
||||
zend_try {
|
||||
shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0);
|
||||
} zend_end_try();
|
||||
@@ -1901,6 +1904,9 @@ void php_request_shutdown(void *dummy)
|
||||
#ifdef HAVE_DTRACE
|
||||
DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
|
||||
#endif /* HAVE_DTRACE */
|
||||
+
|
||||
+ /* May be accessed before php_request_startup() */
|
||||
+ PG(modules_activated) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
diff --git a/main/php_variables.c b/main/php_variables.c
|
||||
index 27a9ad089e..b17673060a 100644
|
||||
--- a/main/php_variables.c
|
||||
+++ b/main/php_variables.c
|
||||
@@ -213,7 +213,7 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
- array_init(&gpc_element);
|
||||
+ array_init_singleton(&gpc_element);
|
||||
if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) {
|
||||
zend_array_destroy(Z_ARR(gpc_element));
|
||||
zval_ptr_dtor_nogc(val);
|
||||
@@ -224,7 +224,7 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac
|
||||
gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
|
||||
if (!gpc_element_p) {
|
||||
zval tmp;
|
||||
- array_init(&tmp);
|
||||
+ array_init_singleton(&tmp);
|
||||
gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
|
||||
} else {
|
||||
if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
|
||||
@@ -232,7 +232,7 @@ PHPAPI void php_register_variable_ex(const char *var_name, zval *val, zval *trac
|
||||
}
|
||||
if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
|
||||
zval_ptr_dtor_nogc(gpc_element_p);
|
||||
- array_init(gpc_element_p);
|
||||
+ array_init_singleton(gpc_element_p);
|
||||
} else {
|
||||
SEPARATE_ARRAY(gpc_element_p);
|
||||
}
|
||||
@@ -424,7 +424,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
|
||||
case PARSE_POST:
|
||||
case PARSE_GET:
|
||||
case PARSE_COOKIE:
|
||||
- array_init(&array);
|
||||
+ array_init_singleton(&array);
|
||||
switch (arg) {
|
||||
case PARSE_POST:
|
||||
zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_POST]);
|
||||
diff --git a/main/rfc1867.c b/main/rfc1867.c
|
||||
index 3086e8da3d..b64574505d 100644
|
||||
--- a/main/rfc1867.c
|
||||
+++ b/main/rfc1867.c
|
||||
@@ -390,6 +390,14 @@ static int find_boundary(multipart_buffer *self, char *boundary)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static zend_bool php_mime_should_save_hdr(const char *name)
|
||||
+{
|
||||
+ return !strcasecmp(name, "Content-Disposition")
|
||||
+ || !strcasecmp(name, "Content-Type");
|
||||
+}
|
||||
+
|
||||
+static char *php_mime_get_hdr_value(zend_llist header, char *key);
|
||||
+
|
||||
/* parse headers */
|
||||
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
{
|
||||
@@ -430,10 +438,16 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
|
||||
}
|
||||
|
||||
*value = '\0';
|
||||
- do { value++; } while (isspace(*value));
|
||||
|
||||
- key = estrdup(line);
|
||||
- smart_string_appends(&buf_value, value);
|
||||
+ /* Keep only headers we use, and ignore duplicates */
|
||||
+ if (!php_mime_should_save_hdr(line)
|
||||
+ || php_mime_get_hdr_value(*header, line)) {
|
||||
+ key = NULL;
|
||||
+ } else {
|
||||
+ key = estrdup(line);
|
||||
+ do { value++; } while (isspace((unsigned char)*value));
|
||||
+ smart_string_appends(&buf_value, value);
|
||||
+ }
|
||||
} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
|
||||
smart_string_appends(&buf_value, line);
|
||||
} else {
|
||||
@@ -507,11 +521,11 @@ static char *php_ap_getword(const zend_encoding *encoding, char **line, char sto
|
||||
return res;
|
||||
}
|
||||
|
||||
-static char *substring_conf(char *start, int len, char quote)
|
||||
+static char *substring_conf(char *start, size_t len, char quote)
|
||||
{
|
||||
char *result = emalloc(len + 1);
|
||||
char *resp = result;
|
||||
- int i;
|
||||
+ size_t i;
|
||||
|
||||
for (i = 0; i < len && start[i] != quote; ++i) {
|
||||
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
|
||||
@@ -539,14 +553,14 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str)
|
||||
char quote = *str;
|
||||
|
||||
str++;
|
||||
- return substring_conf(str, (int)strlen(str), quote);
|
||||
+ return substring_conf(str, strlen(str), quote);
|
||||
} else {
|
||||
char *strend = str;
|
||||
|
||||
while (*strend && !isspace(*strend)) {
|
||||
++strend;
|
||||
}
|
||||
- return substring_conf(str, strend - str, 0);
|
||||
+ return substring_conf(str, (size_t)(strend - str), 0);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.56.0
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# https://github.com/php/php-src/commit/82f8f31b16a035c1b67cc253e79f7cc288f4cc20 (branch PHP-8.0-CVE-2026-109618-109619)
|
||||
0001-Avoid-state-corruption-via-bailout.patch
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
# https://github.com/php/php-src/commit/1d7dec178a094e6e75b229ce22754045f8c6070a (branch PHP-8.1-CVE-2026-109618-109619)
|
||||
0001-Avoid-state-corruption-via-bailout.patch
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Applies the patches listed in "$1/series" to /usr/src/php.tar.xz and repacks it in place, so the
|
||||
# official build and any later "docker-php-ext-install" compile the patched sources.
|
||||
|
||||
patchDir="$1"
|
||||
src=/usr/src/php.tar.xz
|
||||
work="$(mktemp -d)"
|
||||
|
||||
installed=
|
||||
# busybox's patch (old Alpine releases) lacks -d and the long options used below
|
||||
if ! patch --version 2> /dev/null | grep -q GNU; then
|
||||
if command -v apk > /dev/null; then
|
||||
apk add --no-cache --virtual .patch-deps patch
|
||||
else
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends patch
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
fi
|
||||
installed=1
|
||||
fi
|
||||
|
||||
mkdir "$work/php"
|
||||
tar -xJf "$src" -C "$work/php" --strip-components=1
|
||||
|
||||
grep -v -e '^[[:space:]]*#' -e '^[[:space:]]*$' "$patchDir/series" | while read -r p; do
|
||||
echo "Applying $p"
|
||||
patch -d "$work/php" -p1 --forward --no-backup-if-mismatch < "$patchDir/$p"
|
||||
done
|
||||
|
||||
tar -cJf "$src" -C "$work" php
|
||||
# the upstream signature no longer matches the repacked tarball
|
||||
rm -f "$src.asc"
|
||||
rm -rf "$work"
|
||||
|
||||
if [ -n "$installed" ]; then
|
||||
if command -v apk > /dev/null; then
|
||||
apk del --no-network .patch-deps
|
||||
else
|
||||
apt-get purge -y --auto-remove patch
|
||||
fi
|
||||
fi
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Note: we don't just use "apache2ctl" here because it itself is just a shell-script wrapper around apache2 which provides extra functionality like "apache2ctl start" for launching apache2 in the background.
|
||||
# (also, when run as "apache2ctl <apache args>", it does not use "exec", which leaves an undesirable resident shell process)
|
||||
|
||||
: "${APACHE_CONFDIR:=/etc/apache2}"
|
||||
: "${APACHE_ENVVARS:=$APACHE_CONFDIR/envvars}"
|
||||
if test -f "$APACHE_ENVVARS"; then
|
||||
. "$APACHE_ENVVARS"
|
||||
fi
|
||||
|
||||
# Apache gets grumpy about PID files pre-existing
|
||||
: "${APACHE_RUN_DIR:=/var/run/apache2}"
|
||||
: "${APACHE_PID_FILE:=$APACHE_RUN_DIR/apache2.pid}"
|
||||
rm -f "$APACHE_PID_FILE"
|
||||
|
||||
# create missing directories
|
||||
# (especially APACHE_RUN_DIR, APACHE_LOCK_DIR, and APACHE_LOG_DIR)
|
||||
for e in "${!APACHE_@}"; do
|
||||
if [[ "$e" == *_DIR ]] && [[ "${!e}" == /* ]]; then
|
||||
# handle "/var/lock" being a symlink to "/run/lock", but "/run/lock" not existing beforehand, so "/var/lock/something" fails to mkdir
|
||||
# mkdir: cannot create directory '/var/lock': File exists
|
||||
dir="${!e}"
|
||||
while [ "$dir" != "$(dirname "$dir")" ]; do
|
||||
dir="$(dirname "$dir")"
|
||||
if [ -d "$dir" ]; then
|
||||
break
|
||||
fi
|
||||
absDir="$(readlink -f "$dir" 2>/dev/null || :)"
|
||||
if [ -n "$absDir" ]; then
|
||||
mkdir -p "$absDir"
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "${!e}"
|
||||
fi
|
||||
done
|
||||
|
||||
exec apache2 -DFOREGROUND "$@"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# first arg is `-f` or `--some-option`
|
||||
if [ "${1#-}" != "$1" ]; then
|
||||
set -- apache2-foreground "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# first arg is `-f` or `--some-option`
|
||||
if [ "${1#-}" != "$1" ]; then
|
||||
set -- php "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# first arg is `-f` or `--some-option`
|
||||
if [ "${1#-}" != "$1" ]; then
|
||||
set -- php-fpm "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 ext-name [configure flags]"
|
||||
echo " ie: $0 gd --with-jpeg-dir=/usr/local/something"
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
ext="$1"
|
||||
if [ -z "$ext" ] || [ ! -d "$ext" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual .phpize-deps-configure $PHPIZE_DEPS
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v dpkg-architecture > /dev/null; then
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"
|
||||
set -- --build="$gnuArch" "$@"
|
||||
fi
|
||||
|
||||
cd "$ext"
|
||||
phpize
|
||||
./configure "$@"
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 ext-name [configure flags]"
|
||||
echo " ie: $0 gd --with-jpeg-dir=/usr/local/something"
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
ext="$1"
|
||||
if [ -z "$ext" ] || [ ! -d "$ext" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual .phpize-deps-configure $PHPIZE_DEPS
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v dpkg-architecture > /dev/null; then
|
||||
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"
|
||||
set -- --build="$gnuArch" "$@"
|
||||
fi
|
||||
|
||||
cd "$ext"
|
||||
phpize
|
||||
./configure --enable-option-checking=fatal "$@"
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
extDir="$(php -r 'echo ini_get("extension_dir");')"
|
||||
cd "$extDir"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [options] module-name [module-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 --ini-name 0-apc.ini apcu apc"
|
||||
echo
|
||||
echo 'Possible values for module-name:'
|
||||
find -maxdepth 1 \
|
||||
-type f \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
modules=
|
||||
for module; do
|
||||
if [ -z "$module" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -f "$module.so" ] && ! [ -f "$module" ]; then
|
||||
# allow ".so" to be optional
|
||||
module="$module.so"
|
||||
fi
|
||||
if ! [ -f "$module" ]; then
|
||||
echo >&2 "error: '$module' does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
modules="$modules $module"
|
||||
done
|
||||
|
||||
if [ -z "$modules" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual '.docker-php-ext-enable-deps' binutils
|
||||
apkDel='.docker-php-ext-enable-deps'
|
||||
fi
|
||||
fi
|
||||
|
||||
for module in $modules; do
|
||||
if readelf --wide --syms "$module" | grep -q ' zend_extension_entry$'; then
|
||||
# https://wiki.php.net/internals/extensions#loading_zend_extensions
|
||||
absModule="$(readlink -f "$module")"
|
||||
line="zend_extension=$absModule"
|
||||
else
|
||||
line="extension=$module"
|
||||
fi
|
||||
|
||||
ext="$(basename "$module")"
|
||||
ext="${ext%.*}"
|
||||
if php -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then
|
||||
# this isn't perfect, but it's better than nothing
|
||||
# (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache')
|
||||
echo >&2
|
||||
echo >&2 "warning: $ext ($module) is already loaded!"
|
||||
echo >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
ini="$PHP_INI_DIR/conf.d/${iniName:-"docker-php-ext-$ext.ini"}"
|
||||
if ! grep -q "$line" "$ini" 2>/dev/null; then
|
||||
echo "$line" >> "$ini"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del $apkDel
|
||||
fi
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
extDir="$(php -d 'display_errors=stderr' -r 'echo ini_get("extension_dir");')"
|
||||
cd "$extDir"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [options] module-name [module-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 --ini-name 0-apc.ini apcu apc"
|
||||
echo
|
||||
echo 'Possible values for module-name:'
|
||||
find -maxdepth 1 \
|
||||
-type f \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
modules=
|
||||
for module; do
|
||||
if [ -z "$module" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -f "$module.so" ] && ! [ -f "$module" ]; then
|
||||
# allow ".so" to be optional
|
||||
module="$module.so"
|
||||
fi
|
||||
if ! [ -f "$module" ]; then
|
||||
echo >&2 "error: '$module' does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
modules="$modules $module"
|
||||
done
|
||||
|
||||
if [ -z "$modules" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual '.docker-php-ext-enable-deps' binutils
|
||||
apkDel='.docker-php-ext-enable-deps'
|
||||
fi
|
||||
fi
|
||||
|
||||
for module in $modules; do
|
||||
if readelf --wide --syms "$module" | grep -q ' zend_extension_entry$'; then
|
||||
# https://wiki.php.net/internals/extensions#loading_zend_extensions
|
||||
absModule="$(readlink -f "$module")"
|
||||
line="zend_extension=$absModule"
|
||||
else
|
||||
line="extension=$module"
|
||||
fi
|
||||
|
||||
ext="$(basename "$module")"
|
||||
ext="${ext%.*}"
|
||||
if php -d 'display_errors=stderr' -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then
|
||||
# this isn't perfect, but it's better than nothing
|
||||
# (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache')
|
||||
echo >&2
|
||||
echo >&2 "warning: $ext ($module) is already loaded!"
|
||||
echo >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
ini="$PHP_INI_DIR/conf.d/${iniName:-"docker-php-ext-$ext.ini"}"
|
||||
if ! grep -q "$line" "$ini" 2>/dev/null; then
|
||||
echo "$line" >> "$ini"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
extDir="$(php -d 'display_errors=stderr' -r 'echo ini_get("extension_dir");')"
|
||||
cd "$extDir"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [options] module-name [module-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 --ini-name 0-apc.ini apcu apc"
|
||||
echo
|
||||
echo 'Possible values for module-name:'
|
||||
find -maxdepth 1 \
|
||||
-type f \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
modules=
|
||||
for module; do
|
||||
if [ -z "$module" ]; then
|
||||
continue
|
||||
fi
|
||||
if ! [ -f "$module" ] && ! [ -f "$module.so" ]; then
|
||||
echo >&2 "error: '$module' does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
modules="$modules $module"
|
||||
done
|
||||
|
||||
if [ -z "$modules" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual '.docker-php-ext-enable-deps' binutils
|
||||
apkDel='.docker-php-ext-enable-deps'
|
||||
fi
|
||||
fi
|
||||
|
||||
for module in $modules; do
|
||||
moduleFile="$module"
|
||||
if [ -f "$module.so" ] && ! [ -f "$module" ]; then
|
||||
moduleFile="$module.so"
|
||||
fi
|
||||
if readelf --wide --syms "$moduleFile" | grep -q ' zend_extension_entry$'; then
|
||||
# https://wiki.php.net/internals/extensions#loading_zend_extensions
|
||||
line="zend_extension=$module"
|
||||
else
|
||||
line="extension=$module"
|
||||
fi
|
||||
|
||||
ext="$(basename "$module")"
|
||||
ext="${ext%.*}"
|
||||
if php -d 'display_errors=stderr' -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then
|
||||
# this isn't perfect, but it's better than nothing
|
||||
# (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache')
|
||||
echo >&2
|
||||
echo >&2 "warning: $ext ($module) is already loaded!"
|
||||
echo >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$iniName" in
|
||||
/*)
|
||||
# allow an absolute path
|
||||
ini="$iniName"
|
||||
;;
|
||||
*)
|
||||
ini="$PHP_INI_DIR/conf.d/${iniName:-"docker-php-ext-$ext.ini"}"
|
||||
;;
|
||||
esac
|
||||
if ! grep -q "$line" "$ini" 2>/dev/null; then
|
||||
echo "$line" >> "$ini"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
extDir="$(php -d 'display_errors=stderr' -r 'echo ini_get("extension_dir");')"
|
||||
cd "$extDir"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [options] module-name [module-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 --ini-name 0-apc.ini apcu apc"
|
||||
echo
|
||||
echo 'Possible values for module-name:'
|
||||
find -maxdepth 1 \
|
||||
-type f \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
modules=
|
||||
for module; do
|
||||
if [ -z "$module" ]; then
|
||||
continue
|
||||
fi
|
||||
if ! [ -f "$module" ] && ! [ -f "$module.so" ]; then
|
||||
echo >&2 "error: '$module' does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
modules="$modules $module"
|
||||
done
|
||||
|
||||
if [ -z "$modules" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if \
|
||||
[ -n "$PHPIZE_DEPS" ] \
|
||||
&& ! apk info --installed .phpize-deps > /dev/null \
|
||||
&& ! apk info --installed .phpize-deps-configure > /dev/null \
|
||||
; then
|
||||
apk add --no-cache --virtual '.docker-php-ext-enable-deps' binutils
|
||||
apkDel='.docker-php-ext-enable-deps'
|
||||
fi
|
||||
fi
|
||||
|
||||
for module in $modules; do
|
||||
moduleFile="$module"
|
||||
if [ -f "$module.so" ] && ! [ -f "$module" ]; then
|
||||
moduleFile="$module.so"
|
||||
fi
|
||||
if readelf --wide --syms "$moduleFile" | grep -q ' zend_extension_entry$'; then
|
||||
# https://wiki.php.net/internals/extensions#loading_zend_extensions
|
||||
line="zend_extension=$module"
|
||||
else
|
||||
line="extension=$module"
|
||||
fi
|
||||
|
||||
ext="$(basename "$module")"
|
||||
ext="${ext%.*}"
|
||||
if php -d 'display_errors=stderr' -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then
|
||||
# this isn't perfect, but it's better than nothing
|
||||
# (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache')
|
||||
echo >&2
|
||||
echo >&2 "warning: $ext ($module) is already loaded!"
|
||||
echo >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$iniName" in
|
||||
/*)
|
||||
# allow an absolute path
|
||||
ini="$iniName"
|
||||
;;
|
||||
*)
|
||||
ini="$PHP_INI_DIR/conf.d/${iniName:-"docker-php-ext-$ext.ini"}"
|
||||
;;
|
||||
esac
|
||||
if ! grep -qFx -e "$line" -e "$line.so" "$ini" 2>/dev/null; then
|
||||
echo "$line" >> "$ini"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
make -j"$j"
|
||||
make -j"$j" install
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| xargs -r docker-php-ext-enable
|
||||
make -j"$j" clean
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
make -j"$j"
|
||||
make -j"$j" install
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| xargs -r docker-php-ext-enable
|
||||
make -j"$j" clean
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] [--ini-name file.ini] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,ini-name:,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
make -j"$j"
|
||||
make -j"$j" install
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| xargs -r docker-php-ext-enable ${iniName:+--ini-name "$iniName"}
|
||||
make -j"$j" clean
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+130
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] [--ini-name file.ini] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,ini-name:,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
make -j"$j"
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || :
|
||||
' -- '{}' +
|
||||
make -j"$j" install
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| xargs -r docker-php-ext-enable ${iniName:+--ini-name "$iniName"}
|
||||
make -j"$j" clean
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] [--ini-name file.ini] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,ini-name:,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
|
||||
make -j"$j"
|
||||
|
||||
if ! php -n -d 'display_errors=stderr' -r 'exit(ZEND_DEBUG_BUILD ? 0 : 1);' > /dev/null; then
|
||||
# only "strip" modules if we aren't using a debug build of PHP
|
||||
# (none of our builds are debug builds, but PHP might be recompiled with "--enable-debug" configure option)
|
||||
# https://github.com/docker-library/php/issues/1268
|
||||
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || :
|
||||
' -- '{}' +
|
||||
fi
|
||||
|
||||
make -j"$j" install
|
||||
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' ';' \
|
||||
| xargs -r docker-php-ext-enable ${iniName:+--ini-name "$iniName"}
|
||||
|
||||
make -j"$j" clean
|
||||
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
|
||||
: ${CFLAGS:=$PHP_CFLAGS}
|
||||
: ${CPPFLAGS:=$PHP_CPPFLAGS}
|
||||
: ${LDFLAGS:=$PHP_LDFLAGS}
|
||||
export CFLAGS CPPFLAGS LDFLAGS
|
||||
|
||||
srcExists=
|
||||
if [ -d /usr/src/php ]; then
|
||||
srcExists=1
|
||||
fi
|
||||
docker-php-source extract
|
||||
if [ -z "$srcExists" ]; then
|
||||
touch /usr/src/php/.docker-delete-me
|
||||
fi
|
||||
|
||||
cd /usr/src/php/ext
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-jN] [--ini-name file.ini] ext-name [ext-name ...]"
|
||||
echo " ie: $0 gd mysqli"
|
||||
echo " $0 pdo pdo_mysql"
|
||||
echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
|
||||
echo
|
||||
echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
|
||||
echo
|
||||
echo 'Possible values for ext-name:'
|
||||
find . \
|
||||
-mindepth 2 \
|
||||
-maxdepth 2 \
|
||||
-type f \
|
||||
-name 'config.m4' \
|
||||
| xargs -n1 dirname \
|
||||
| xargs -n1 basename \
|
||||
| sort \
|
||||
| xargs
|
||||
echo
|
||||
echo 'Some of the above modules are already compiled into PHP; please check'
|
||||
echo 'the output of "php -i" to see which modules are already loaded.'
|
||||
}
|
||||
|
||||
opts="$(getopt -o 'h?j:' --long 'help,ini-name:,jobs:' -- "$@" || { usage >&2 && false; })"
|
||||
eval set -- "$opts"
|
||||
|
||||
j=1
|
||||
iniName=
|
||||
while true; do
|
||||
flag="$1"
|
||||
shift
|
||||
case "$flag" in
|
||||
--help|-h|'-?') usage && exit 0 ;;
|
||||
--ini-name) iniName="$1" && shift ;;
|
||||
--jobs|-j) j="$1" && shift ;;
|
||||
--) break ;;
|
||||
*)
|
||||
{
|
||||
echo "error: unknown flag: $flag"
|
||||
usage
|
||||
} >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exts=
|
||||
for ext; do
|
||||
if [ -z "$ext" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ ! -d "$ext" ]; then
|
||||
echo >&2 "error: $PWD/$ext does not exist"
|
||||
echo >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
exts="$exts $ext"
|
||||
done
|
||||
|
||||
if [ -z "$exts" ]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pm='unknown'
|
||||
if [ -e /lib/apk/db/installed ]; then
|
||||
pm='apk'
|
||||
fi
|
||||
|
||||
apkDel=
|
||||
if [ "$pm" = 'apk' ]; then
|
||||
if [ -n "$PHPIZE_DEPS" ]; then
|
||||
if apk info --installed .phpize-deps-configure > /dev/null; then
|
||||
apkDel='.phpize-deps-configure'
|
||||
elif ! apk info --installed .phpize-deps > /dev/null; then
|
||||
apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
|
||||
apkDel='.phpize-deps'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
popDir="$PWD"
|
||||
for ext in $exts; do
|
||||
cd "$ext"
|
||||
|
||||
[ -e Makefile ] || docker-php-ext-configure "$ext"
|
||||
|
||||
make -j"$j"
|
||||
|
||||
if ! php -n -d 'display_errors=stderr' -r 'exit(ZEND_DEBUG_BUILD ? 0 : 1);' > /dev/null; then
|
||||
# only "strip" modules if we aren't using a debug build of PHP
|
||||
# (none of our builds are debug builds, but PHP might be recompiled with "--enable-debug" configure option)
|
||||
# https://github.com/docker-library/php/issues/1268
|
||||
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec sh -euxc ' \
|
||||
strip --strip-all "$@" || :
|
||||
' -- '{}' +
|
||||
fi
|
||||
|
||||
make -j"$j" install
|
||||
|
||||
find modules \
|
||||
-maxdepth 1 \
|
||||
-name '*.so' \
|
||||
-exec basename '{}' '.so' ';' \
|
||||
| xargs -r docker-php-ext-enable ${iniName:+--ini-name "$iniName"}
|
||||
|
||||
make -j"$j" clean
|
||||
|
||||
cd "$popDir"
|
||||
done
|
||||
|
||||
if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
|
||||
apk del --no-network $apkDel
|
||||
fi
|
||||
|
||||
if [ -e /usr/src/php/.docker-delete-me ]; then
|
||||
docker-php-source delete
|
||||
fi
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
dir=/usr/src/php
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 COMMAND"
|
||||
echo
|
||||
echo "Manage php source tarball lifecycle."
|
||||
echo
|
||||
echo "Commands:"
|
||||
echo " extract extract php source tarball into directory $dir if not already done."
|
||||
echo " delete delete extracted php source located into $dir if not already done."
|
||||
echo
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
extract)
|
||||
mkdir -p "$dir"
|
||||
if [ ! -f "$dir/.docker-extracted" ]; then
|
||||
tar -Jxf /usr/src/php.tar.xz -C "$dir" --strip-components=1
|
||||
touch "$dir/.docker-extracted"
|
||||
fi
|
||||
;;
|
||||
|
||||
delete)
|
||||
rm -rf "$dir"
|
||||
;;
|
||||
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+1
-1
@@ -47,7 +47,7 @@ build:
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ build:
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ build:
|
||||
|
||||
test:
|
||||
@echo -e "=====> Testing loaded extensions... \c"
|
||||
@if [[ -z `docker image ls $(REGISTRY)$(IMAGE) | grep "\s$(VERSION)\s"` ]]; then \
|
||||
@if ! docker image inspect $(REGISTRY)$(IMAGE):$(VERSION) > /dev/null 2>&1; then \
|
||||
echo 'FAIL [Missing image!!!]'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user