mirror of
https://github.com/php-win-ext/php-rar.git
synced 2026-04-24 12:58:06 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19bcaf064c |
@@ -1,88 +0,0 @@
|
|||||||
---
|
|
||||||
# Formatting style for php-rar C source files.
|
|
||||||
# Does NOT apply to unrar/ (see unrar/.clang-format).
|
|
||||||
Language: Cpp
|
|
||||||
BasedOnStyle: LLVM
|
|
||||||
|
|
||||||
# Indentation: real tabs, width 4 (matches vim modeline: noet sw=4 ts=4)
|
|
||||||
UseTab: Always
|
|
||||||
TabWidth: 4
|
|
||||||
IndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
|
|
||||||
# Disable line-length wrapping to preserve hand-formatted long lines
|
|
||||||
ColumnLimit: 0
|
|
||||||
|
|
||||||
# Brace style:
|
|
||||||
# - Functions: brace on its own line (Allman)
|
|
||||||
# - Structs/unions/enums/extern "C": brace attached (K&R)
|
|
||||||
# - Control statements: brace attached (K&R)
|
|
||||||
# - else/else if: on its own line (after closing })
|
|
||||||
BreakBeforeBraces: Custom
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: Never
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: true
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
AfterExternBlock: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: true
|
|
||||||
BeforeLambdaBody: false
|
|
||||||
BeforeWhile: false
|
|
||||||
IndentBraces: false
|
|
||||||
SplitEmptyFunction: false
|
|
||||||
SplitEmptyRecord: false
|
|
||||||
SplitEmptyNamespace: false
|
|
||||||
|
|
||||||
# Preserve indentation of preprocessor directives (# include, # define inside #ifdef)
|
|
||||||
IndentPPDirectives: AfterHash
|
|
||||||
PPIndentWidth: 1
|
|
||||||
|
|
||||||
# Pointer star attached to variable name: char *ptr
|
|
||||||
PointerAlignment: Right
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
|
|
||||||
# Spaces
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
|
|
||||||
# Don't align backslashes in multi-line macros (just 1 space before \)
|
|
||||||
AlignEscapedNewlines: DontAlign
|
|
||||||
|
|
||||||
# ZEND_BEGIN/END_ARG_INFO_EX act as block delimiters so ZEND_ARG_INFO lines
|
|
||||||
# inside them keep their indentation.
|
|
||||||
MacroBlockBegin: "^ZEND_BEGIN_ARG_INFO"
|
|
||||||
MacroBlockEnd: "^ZEND_END_ARG_INFO"
|
|
||||||
|
|
||||||
# Align continuation arguments after opening paren; when ( is last on the line,
|
|
||||||
# fall back to a block indent (ContinuationIndentWidth).
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
|
|
||||||
# Preserve existing include order
|
|
||||||
SortIncludes: Never
|
|
||||||
|
|
||||||
# case labels are indented one level inside switch
|
|
||||||
IndentCaseLabels: true
|
|
||||||
|
|
||||||
# Don't collapse or expand short constructs
|
|
||||||
AllowShortBlocksOnASingleLine: Never
|
|
||||||
AllowShortFunctionsOnASingleLine: None
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
|
|
||||||
# Alignment: leave hand-aligned blocks alone
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignTrailingComments: false
|
|
||||||
|
|
||||||
# Blank lines
|
|
||||||
MaxEmptyLinesToKeep: 2
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Docker image SHA lock file.
|
|
||||||
# Maps image tags to their multi-arch OCI index digests (amd64 + arm64).
|
|
||||||
# Regenerate with: .github/scripts/update-docker-shas.sh
|
|
||||||
|
|
||||||
ghcr.io/cataphract/php-minimal:
|
|
||||||
7.0-debug: "sha256:c1a08b9c71b30c3ed4c31bb6ca9f4c81f82f4351c5e6e0c423a8f980ce3c89ee"
|
|
||||||
7.0-release-zts: "sha256:9d9f1b1337822e1c069cf49c22f5f6b55ba806547cccbb4836e847fe8e32819a"
|
|
||||||
7.1-debug: "sha256:b670b5de5dd8d0791a86b29e336b5a7d801fbdeaeadf9148e616cf5357b9035e"
|
|
||||||
7.1-release-zts: "sha256:1f3164d4cdd57faa0911de43c4c77b7d18fdf84971db97ff2889f1a5ed8a0e5a"
|
|
||||||
7.2-debug: "sha256:7c1d2b2248a64339d8b0ae7bcbe4156fc8e3903653ce1d86347bfeacb9679c0d"
|
|
||||||
7.2-release-zts: "sha256:5e1f47179d730c22c8eada20f9cbedb034f3b97c89174ce4e6108e7d76bf7da5"
|
|
||||||
7.3-debug: "sha256:b0b4c0a57e52011469c7999b330020d4ef27628eb8ac745e7e74796c8ff8601a"
|
|
||||||
7.3-release-zts: "sha256:fe021f3979bc4c69be0d73ec74a30085915939a62f457557be91e003938d6e0a"
|
|
||||||
7.4-debug: "sha256:d2d827524eae4a7d391b5f71b33477a1affabc74f674f9680b7838c3a5154d7f"
|
|
||||||
7.4-release-zts: "sha256:6c5eacd2f493c1c07a68f451b72a62ed67ddb2406dab8e3dc82f20adc7e72bf7"
|
|
||||||
8.0-debug: "sha256:d46c15e648497cf55bb6b4806c726c58714f5b63fcb1096e4a8ec433ec17c835"
|
|
||||||
8.0-release-zts: "sha256:bcbaab72e7c0e704d7bdef01e8f91e1bc0636e6e98c0ab68cc2fc417e7a98a66"
|
|
||||||
8.1-debug: "sha256:dbdb437df0a4acbbd11e020461f7cef2f0e949f46f9ca841c5f058012ec7cc98"
|
|
||||||
8.1-release: "sha256:f401dba3b4249dc16acb90909951b88e3146dcd2e622203d95e80219258932c9"
|
|
||||||
8.1-release-zts: "sha256:2b330ce54679f29e09ea77c984cd409618142cc20cab48b5a114cc1e5b09257c"
|
|
||||||
8.2-debug: "sha256:efecf1cdbd09511aec12897a03682934243498c5bb2ba37874ae2100c1498011"
|
|
||||||
8.2-release: "sha256:e09be007096a29d64427afa99ea4d10f7e1a91a8e2129aeaa854daf045986d8f"
|
|
||||||
8.2-release-zts: "sha256:d67d1c370abdc5e629a2bec1ff4d308f0ccb7d3cbc7ecc3c7eee851cd6c2efaa"
|
|
||||||
8.3-debug: "sha256:1b8e6ba17c837a4035f6981dd38f9f447be57a3d558ca8f18071c8390a62ce6c"
|
|
||||||
8.3-release: "sha256:23abac21af8c95ccd6cd6a8b5fbb2d1dd67e122fc7630bbbfcc7b75e6a6fcc96"
|
|
||||||
8.3-release-zts: "sha256:158060357f81b495a5420b1f9d488abd61d59306946b352e4fbfc4011b7a2d89"
|
|
||||||
8.4-debug: "sha256:c863e2a60f144856f56d50ed1080bbe0377ca99760195f170c762ad46f0466e5"
|
|
||||||
8.4-release: "sha256:571251d31267c6960846727f0788f1d9a593a02adf6a68899a0582c5635d5c50"
|
|
||||||
8.4-release-zts: "sha256:6451c7104d874f8c4f7e0305e5baaecebbd74672a036c02de2cbb9d1a10c8906"
|
|
||||||
8.5-debug: "sha256:014a16949dd0da0581cda6768bd7751f66b6ada3becdc949aeb5b8e1efb3c5cf"
|
|
||||||
8.5-release: "sha256:bc58405b860c17ea5f36cbd466dc5c93b97283c148e3489ec78171d73727859c"
|
|
||||||
8.5-release-zts: "sha256:dadd96c4740bc9606f2985be51fb0b85d768132f93786c4ae52940552f3cbdc6"
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Build the extension and run the test suite.
|
|
||||||
# Expected to run inside a php-minimal container from the repo root.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Clean up all generated files so stale objects from a previous PHP version or
|
|
||||||
# build variant don't silently survive into this build.
|
|
||||||
if [ -f Makefile ]; then
|
|
||||||
make -f Makefile distclean
|
|
||||||
fi
|
|
||||||
# Remove any leftover object files even if Makefile is gone (e.g. after a
|
|
||||||
# partial prior build that ended before distclean could run).
|
|
||||||
find . -name '*.lo' -o -name '*.o' | xargs rm -f 2>/dev/null || true
|
|
||||||
find . -name '.libs' -type d | xargs rm -rf 2>/dev/null || true
|
|
||||||
|
|
||||||
phpize
|
|
||||||
./configure --with-php-config="$(which php-config)"
|
|
||||||
make -f Makefile -j"$(nproc)"
|
|
||||||
|
|
||||||
# The generated Makefile silences and ignores errors on the `if` commands;
|
|
||||||
# undo that so test failures surface properly.
|
|
||||||
sed -i 's/-@if/@if/' Makefile
|
|
||||||
|
|
||||||
ret=0
|
|
||||||
TEST_PHP_EXECUTABLE="$(which php)" \
|
|
||||||
TEST_PHP_JUNIT=report.xml \
|
|
||||||
REPORT_EXIT_STATUS=1 \
|
|
||||||
NO_INTERACTION=1 \
|
|
||||||
TESTS="--set-timeout 300 --show-diff" \
|
|
||||||
make -f Makefile test || ret=$?
|
|
||||||
|
|
||||||
found=$(find tests -name '*.mem' | wc -l)
|
|
||||||
if [ "$found" -gt 0 ]; then
|
|
||||||
echo "Found $found memory leak(s):"
|
|
||||||
find tests -name '*.mem' -print -exec cat {} \;
|
|
||||||
ret=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit "$ret"
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Refresh docker-image-shas.yml with current OCI index digests.
|
|
||||||
# The index digest covers all platforms (amd64 + arm64); Docker resolves the
|
|
||||||
# right platform image from it at pull time.
|
|
||||||
# Justfile and tests.yml read from docker-image-shas.yml directly — no patching needed.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
IMAGE="ghcr.io/cataphract/php-minimal"
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
LOCK_FILE="$SCRIPT_DIR/../docker-image-shas.yml"
|
|
||||||
|
|
||||||
TAGS=(
|
|
||||||
7.0-debug 7.0-release-zts
|
|
||||||
7.1-debug 7.1-release-zts
|
|
||||||
7.2-debug 7.2-release-zts
|
|
||||||
7.3-debug 7.3-release-zts
|
|
||||||
7.4-debug 7.4-release-zts
|
|
||||||
8.0-debug 8.0-release-zts
|
|
||||||
8.1-debug 8.1-release 8.1-release-zts
|
|
||||||
8.2-debug 8.2-release 8.2-release-zts
|
|
||||||
8.3-debug 8.3-release 8.3-release-zts
|
|
||||||
8.4-debug 8.4-release 8.4-release-zts
|
|
||||||
8.5-debug 8.5-release 8.5-release-zts
|
|
||||||
)
|
|
||||||
|
|
||||||
get_index_digest() {
|
|
||||||
local tag="$1" digest attempt
|
|
||||||
for attempt in 1 2 3; do
|
|
||||||
digest=$(docker buildx imagetools inspect "${IMAGE}:${tag}" \
|
|
||||||
| awk '/^Digest:/ { print $2; exit }')
|
|
||||||
if [[ -n "$digest" ]]; then
|
|
||||||
echo "$digest"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
echo "Attempt $attempt failed for $tag, retrying..." >&2
|
|
||||||
sleep $((attempt * 5))
|
|
||||||
done
|
|
||||||
echo "ERROR: could not fetch digest for $tag after 3 attempts" >&2
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Collect all digests first so we fail fast before touching any file.
|
|
||||||
declare -A DIGESTS
|
|
||||||
for tag in "${TAGS[@]}"; do
|
|
||||||
echo "Fetching $tag ..." >&2
|
|
||||||
DIGESTS[$tag]=$(get_index_digest "$tag")
|
|
||||||
done
|
|
||||||
|
|
||||||
# ── Update docker-image-shas.yml ─────────────────────────────────────────────
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "# Docker image SHA lock file."
|
|
||||||
echo "# Maps image tags to their multi-arch OCI index digests (amd64 + arm64)."
|
|
||||||
echo "# Regenerate with: .github/scripts/update-docker-shas.sh"
|
|
||||||
echo ""
|
|
||||||
echo "${IMAGE}:"
|
|
||||||
for tag in "${TAGS[@]}"; do
|
|
||||||
printf " %-20s \"%s\"\n" "${tag}:" "${DIGESTS[$tag]}"
|
|
||||||
done
|
|
||||||
} > "$LOCK_FILE"
|
|
||||||
echo "Updated $LOCK_FILE" >&2
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
name: Build Docker images
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [docker]
|
|
||||||
|
|
||||||
env:
|
|
||||||
MUSL_ENV_IMAGE: ghcr.io/cataphract/musl-build-env
|
|
||||||
PHP_IMAGE: ghcr.io/cataphract/php-minimal
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# ── Push: build musl-build-env for both arches ───────────────────────────
|
|
||||||
musl-build-env:
|
|
||||||
name: musl-build-env / ${{ matrix.arch }}
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- arch: x86_64
|
|
||||||
platform: linux/amd64
|
|
||||||
runner: ubuntu-latest
|
|
||||||
- arch: aarch64
|
|
||||||
platform: linux/arm64
|
|
||||||
runner: ubuntu-24.04-arm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: docker/musl-build-env
|
|
||||||
platforms: ${{ matrix.platform }}
|
|
||||||
push: true
|
|
||||||
tags: ${{ env.MUSL_ENV_IMAGE }}:latest-${{ matrix.arch }}
|
|
||||||
build-args: ARCH=${{ matrix.arch }}
|
|
||||||
cache-from: type=gha,scope=musl-build-env-${{ matrix.arch }}
|
|
||||||
cache-to: type=gha,mode=max,scope=musl-build-env-${{ matrix.arch }}
|
|
||||||
|
|
||||||
# ── Push: build php-minimal for all PHP versions and variants ─────────────
|
|
||||||
php-minimal:
|
|
||||||
name: php-minimal ${{ matrix.php }}-${{ matrix.variant }} / ${{ matrix.arch }}
|
|
||||||
needs: musl-build-env
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php:
|
|
||||||
- "7.0"
|
|
||||||
- "7.1"
|
|
||||||
- "7.2"
|
|
||||||
- "7.3"
|
|
||||||
- "7.4"
|
|
||||||
- "8.0"
|
|
||||||
- "8.1"
|
|
||||||
- "8.2"
|
|
||||||
- "8.3"
|
|
||||||
- "8.4"
|
|
||||||
- "8.5"
|
|
||||||
variant:
|
|
||||||
- debug
|
|
||||||
- release
|
|
||||||
- release-zts
|
|
||||||
arch:
|
|
||||||
- x86_64
|
|
||||||
- aarch64
|
|
||||||
include:
|
|
||||||
- arch: x86_64
|
|
||||||
platform: linux/amd64
|
|
||||||
runner: ubuntu-latest
|
|
||||||
- arch: aarch64
|
|
||||||
platform: linux/arm64
|
|
||||||
runner: ubuntu-24.04-arm
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Resolve PHP patch version and build flags
|
|
||||||
id: cfg
|
|
||||||
run: |
|
|
||||||
declare -A PHP_VERSIONS=(
|
|
||||||
[7.0]=7.0.33 [7.1]=7.1.33 [7.2]=7.2.34 [7.3]=7.3.33 [7.4]=7.4.33
|
|
||||||
[8.0]=8.0.30 [8.1]=8.1.32 [8.2]=8.2.28 [8.3]=8.3.19 [8.4]=8.4.6
|
|
||||||
[8.5]=8.5.0
|
|
||||||
)
|
|
||||||
patch="${PHP_VERSIONS[${{ matrix.php }}]}"
|
|
||||||
case "${{ matrix.variant }}" in
|
|
||||||
debug) debug=yes; zts=no ;;
|
|
||||||
release) debug=no; zts=no ;;
|
|
||||||
release-zts) debug=no; zts=yes ;;
|
|
||||||
esac
|
|
||||||
echo "patch=${patch}" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "debug=${debug}" >> "$GITHUB_OUTPUT"
|
|
||||||
echo "zts=${zts}" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: docker/php-minimal
|
|
||||||
platforms: ${{ matrix.platform }}
|
|
||||||
push: true
|
|
||||||
tags: ${{ env.PHP_IMAGE }}:${{ matrix.php }}-${{ matrix.variant }}-${{ matrix.arch }}
|
|
||||||
build-args: |
|
|
||||||
BUILD_ENV_IMAGE=${{ env.MUSL_ENV_IMAGE }}:latest-${{ matrix.arch }}
|
|
||||||
PHP_VERSION=${{ steps.cfg.outputs.patch }}
|
|
||||||
ARCH=${{ matrix.arch }}
|
|
||||||
PHP_ENABLE_DEBUG=${{ steps.cfg.outputs.debug }}
|
|
||||||
PHP_ENABLE_ZTS=${{ steps.cfg.outputs.zts }}
|
|
||||||
cache-from: type=gha,scope=php-${{ matrix.php }}-${{ matrix.variant }}-${{ matrix.arch }}
|
|
||||||
cache-to: type=gha,mode=max,scope=php-${{ matrix.php }}-${{ matrix.variant }}-${{ matrix.arch }}
|
|
||||||
|
|
||||||
# ── Push: create multi-arch manifests ────────────────────────────────────
|
|
||||||
merge-manifests:
|
|
||||||
name: Create multi-arch manifests
|
|
||||||
needs: php-minimal
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Merge musl-build-env manifest
|
|
||||||
run: |
|
|
||||||
docker buildx imagetools create \
|
|
||||||
-t ${{ env.MUSL_ENV_IMAGE }}:latest \
|
|
||||||
${{ env.MUSL_ENV_IMAGE }}:latest-x86_64 \
|
|
||||||
${{ env.MUSL_ENV_IMAGE }}:latest-aarch64
|
|
||||||
|
|
||||||
- name: Merge php-minimal manifests
|
|
||||||
run: |
|
|
||||||
for minor in 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5; do
|
|
||||||
for variant in debug release release-zts; do
|
|
||||||
docker buildx imagetools create \
|
|
||||||
-t ${{ env.PHP_IMAGE }}:${minor}-${variant} \
|
|
||||||
${{ env.PHP_IMAGE }}:${minor}-${variant}-x86_64 \
|
|
||||||
${{ env.PHP_IMAGE }}:${minor}-${variant}-aarch64
|
|
||||||
done
|
|
||||||
done
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
name: Release binaries
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v[0-9]*.[0-9]*.[0-9]*'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-version:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Check version consistency
|
|
||||||
run: |
|
|
||||||
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
||||||
HEADER_VERSION=$(grep -oP '(?<=#define PHP_RAR_VERSION ")[^"]+' php_rar.h)
|
|
||||||
PACKAGE_VERSION=$(python3 -c "
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
t = ET.parse('package.xml')
|
|
||||||
ns = {'p': 'http://pear.php.net/dtd/package-2.0'}
|
|
||||||
print(t.find('p:version/p:release', ns).text)
|
|
||||||
")
|
|
||||||
|
|
||||||
echo "Tag version: $TAG_VERSION"
|
|
||||||
echo "Header version: $HEADER_VERSION"
|
|
||||||
echo "Package version: $PACKAGE_VERSION"
|
|
||||||
|
|
||||||
if [ "$TAG_VERSION" != "$HEADER_VERSION" ]; then
|
|
||||||
echo "ERROR: Tag version ($TAG_VERSION) does not match PHP_RAR_VERSION in php_rar.h ($HEADER_VERSION)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
|
|
||||||
echo "ERROR: Tag version ($TAG_VERSION) does not match version in package.xml ($PACKAGE_VERSION)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "All versions match: $TAG_VERSION"
|
|
||||||
|
|
||||||
create-draft-release:
|
|
||||||
needs: [check-version]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-tags: 'true'
|
|
||||||
ref: ${{ github.ref }}
|
|
||||||
|
|
||||||
- name: Create draft release from tag
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: gh release create "${{ github.ref_name }}" --title "${{ github.ref_name }}" --draft --notes-from-tag
|
|
||||||
|
|
||||||
linux-extension-matrix:
|
|
||||||
needs: [create-draft-release]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- id: set-matrix
|
|
||||||
run: |
|
|
||||||
python3 <<'EOF'
|
|
||||||
import yaml, json, os
|
|
||||||
with open('.github/docker-image-shas.yml') as f:
|
|
||||||
data = yaml.safe_load(f)
|
|
||||||
image = 'ghcr.io/cataphract/php-minimal'
|
|
||||||
includes = []
|
|
||||||
for tag, sha in data[image].items():
|
|
||||||
ver, variant = tag.split('-', 1)
|
|
||||||
if variant not in ('release', 'release-zts'):
|
|
||||||
continue
|
|
||||||
if float(ver) < 8.1:
|
|
||||||
continue
|
|
||||||
for arch, runner in [('x86_64', 'ubuntu-latest'), ('aarch64', 'ubuntu-24.04-arm')]:
|
|
||||||
includes.append({'php': ver, 'variant': variant, 'image_sha': sha,
|
|
||||||
'arch': arch, 'runner': runner})
|
|
||||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
||||||
f.write('matrix=' + json.dumps({'include': includes}) + '\n')
|
|
||||||
EOF
|
|
||||||
|
|
||||||
linux-build:
|
|
||||||
name: Linux PHP ${{ matrix.php }} (${{ matrix.variant }}, ${{ matrix.arch }})
|
|
||||||
needs: [linux-extension-matrix]
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{ fromJson(needs.linux-extension-matrix.outputs.matrix) }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install patchelf
|
|
||||||
run: sudo apt-get install -y patchelf
|
|
||||||
|
|
||||||
- name: Build rar.so in musl container
|
|
||||||
run: |
|
|
||||||
docker run --rm \
|
|
||||||
--user "$(id -u):$(id -g)" \
|
|
||||||
-v "$GITHUB_WORKSPACE:/workspace" \
|
|
||||||
-w /workspace \
|
|
||||||
"ghcr.io/cataphract/php-minimal@${{ matrix.image_sha }}" \
|
|
||||||
sh -c 'phpize && ./configure --with-php-config=$(which php-config) && make -j$(nproc)'
|
|
||||||
|
|
||||||
- name: Remove musl DT_NEEDED from rar.so
|
|
||||||
run: patchelf --remove-needed "libc.musl-$(uname -m).so.1" modules/rar.so
|
|
||||||
|
|
||||||
- name: Package and upload to release
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
VERSION="${GITHUB_REF_NAME#v}"
|
|
||||||
ARCH="${{ matrix.arch }}"
|
|
||||||
[ "$ARCH" = "aarch64" ] && ARCH="arm64"
|
|
||||||
ZTS_SUFFIX=""
|
|
||||||
[[ "${{ matrix.variant }}" == "release-zts" ]] && ZTS_SUFFIX="-zts"
|
|
||||||
ARTIFACT="php_rar-${VERSION}_php${{ matrix.php }}-${ARCH}-linux${ZTS_SUFFIX}.zip"
|
|
||||||
zip -j "$ARTIFACT" modules/rar.so
|
|
||||||
gh release upload "${{ github.ref_name }}" "$ARTIFACT" --clobber
|
|
||||||
|
|
||||||
windows-extension-matrix:
|
|
||||||
needs: [create-draft-release]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
matrix: ${{ steps.extension-matrix.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Get the extension matrix
|
|
||||||
id: extension-matrix
|
|
||||||
uses: php/php-windows-builder/extension-matrix@v1
|
|
||||||
with:
|
|
||||||
php-version-list: '8.0, 8.1, 8.2, 8.3, 8.4, 8.5'
|
|
||||||
|
|
||||||
windows-build:
|
|
||||||
needs: [windows-extension-matrix]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{ fromJson(needs.windows-extension-matrix.outputs.matrix) }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build the extension for Windows
|
|
||||||
uses: php/php-windows-builder/extension@v1
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-version }}
|
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
ts: ${{ matrix.ts }}
|
|
||||||
args: --enable-rar=shared
|
|
||||||
test-runner: run-tests-rar.php
|
|
||||||
|
|
||||||
windows-release:
|
|
||||||
needs: [windows-build]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: Upload artifacts to the release
|
|
||||||
uses: php/php-windows-builder/release@v1
|
|
||||||
with:
|
|
||||||
release: ${{ github.ref_name }}
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
draft: 'true'
|
|
||||||
|
|
||||||
pecl-package:
|
|
||||||
needs: [create-draft-release]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: '8.3'
|
|
||||||
tools: pecl
|
|
||||||
|
|
||||||
- name: Build PECL package
|
|
||||||
run: pecl package
|
|
||||||
|
|
||||||
- name: Upload PECL package to release
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
run: gh release upload "${{ github.ref_name }}" rar-*.tgz
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
name: Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-dev-version:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Check PHP_RAR_VERSION ends in -dev
|
|
||||||
run: |
|
|
||||||
HEADER_VERSION=$(grep -oP '(?<=#define PHP_RAR_VERSION ")[^"]+' php_rar.h)
|
|
||||||
echo "Header version: $HEADER_VERSION"
|
|
||||||
if [[ "$HEADER_VERSION" != *-dev ]]; then
|
|
||||||
echo "ERROR: PHP_RAR_VERSION ($HEADER_VERSION) does not end in -dev on master"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
generate-matrix:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- id: set-matrix
|
|
||||||
run: |
|
|
||||||
python3 <<'EOF'
|
|
||||||
import yaml, json, os
|
|
||||||
with open('.github/docker-image-shas.yml') as f:
|
|
||||||
data = yaml.safe_load(f)
|
|
||||||
image = 'ghcr.io/cataphract/php-minimal'
|
|
||||||
includes = []
|
|
||||||
for tag, sha in data[image].items():
|
|
||||||
# tag: "7.0-debug" or "7.0-release-zts"; skip glibc-only entries
|
|
||||||
ver, variant = tag.split('-', 1)
|
|
||||||
if variant not in ('debug', 'release-zts'):
|
|
||||||
continue
|
|
||||||
includes.append({'php': ver, 'variant': variant, 'image_sha': sha})
|
|
||||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
||||||
f.write('matrix=' + json.dumps({'include': includes}) + '\n')
|
|
||||||
EOF
|
|
||||||
|
|
||||||
linux:
|
|
||||||
name: PHP ${{ matrix.php }} (${{ matrix.variant }})
|
|
||||||
needs: generate-matrix
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: ghcr.io/cataphract/php-minimal@${{ matrix.image_sha }}
|
|
||||||
options: --user root
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build and test
|
|
||||||
run: bash .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
- name: Upload test results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: test-results-php${{ matrix.php }}-${{ matrix.variant }}
|
|
||||||
path: report.xml
|
|
||||||
|
|
||||||
glibc:
|
|
||||||
name: glibc (PHP 8.3 release, ${{ matrix.arch }})
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- arch: x86_64
|
|
||||||
runner: ubuntu-latest
|
|
||||||
- arch: aarch64
|
|
||||||
runner: ubuntu-24.04-arm
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Read build image SHA
|
|
||||||
id: image-sha
|
|
||||||
run: |
|
|
||||||
python3 -c "
|
|
||||||
import yaml, os
|
|
||||||
with open('.github/docker-image-shas.yml') as f:
|
|
||||||
d = yaml.safe_load(f)
|
|
||||||
sha = d['ghcr.io/cataphract/php-minimal']['8.3-release']
|
|
||||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
|
||||||
f.write('sha=' + sha + '\n')
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Install PHP 8.3 and patchelf
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -q
|
|
||||||
sudo apt-get install -y php8.3 php8.3-dev patchelf
|
|
||||||
|
|
||||||
- name: Build rar.so in musl container
|
|
||||||
run: |
|
|
||||||
docker run --rm \
|
|
||||||
--user "$(id -u):$(id -g)" \
|
|
||||||
-v "$GITHUB_WORKSPACE:/workspace" \
|
|
||||||
-w /workspace \
|
|
||||||
"ghcr.io/cataphract/php-minimal@${{ steps.image-sha.outputs.sha }}" \
|
|
||||||
sh -c 'phpize && ./configure --with-php-config=$(which php-config) && make -j$(nproc)'
|
|
||||||
|
|
||||||
- name: Remove musl DT_NEEDED from rar.so
|
|
||||||
run: patchelf --remove-needed "libc.musl-$(uname -m).so.1" modules/rar.so
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
TEST_PHP_EXECUTABLE=$(which php8.3) \
|
|
||||||
TEST_PHP_JUNIT=report.xml \
|
|
||||||
REPORT_EXIT_STATUS=1 \
|
|
||||||
NO_INTERACTION=1 \
|
|
||||||
php8.3 run-tests-rar.php \
|
|
||||||
-n -d extension_dir=modules/ -d extension=rar.so \
|
|
||||||
--set-timeout 300 --show-diff \
|
|
||||||
tests/
|
|
||||||
|
|
||||||
- name: Upload test results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: test-results-glibc-php8.3-release-${{ matrix.arch }}
|
|
||||||
path: report.xml
|
|
||||||
|
|
||||||
windows:
|
|
||||||
name: Windows PHP 8.1 TS
|
|
||||||
runs-on: windows-2022
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build and test
|
|
||||||
uses: php/php-windows-builder/extension@v1
|
|
||||||
with:
|
|
||||||
php-version: '8.1'
|
|
||||||
arch: x64
|
|
||||||
ts: ts
|
|
||||||
args: --enable-rar=shared
|
|
||||||
test-runner: ${{ github.workspace }}/run-tests-rar.php
|
|
||||||
test-workers: 1
|
|
||||||
|
|
||||||
- name: Upload test results
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: test-results-windows-php8.1-ts
|
|
||||||
path: '*.xml'
|
|
||||||
+1
-12
@@ -1,6 +1,5 @@
|
|||||||
*.o
|
*.o
|
||||||
*.lo
|
*.lo
|
||||||
/run-tests.php
|
|
||||||
/tests/*.sh
|
/tests/*.sh
|
||||||
/tests/*.exp
|
/tests/*.exp
|
||||||
/tests/*.diff
|
/tests/*.diff
|
||||||
@@ -8,6 +7,7 @@
|
|||||||
/tests/*.php
|
/tests/*.php
|
||||||
/tests/*.out
|
/tests/*.out
|
||||||
/tests/*.mem
|
/tests/*.mem
|
||||||
|
/run-tests.php
|
||||||
/modules
|
/modules
|
||||||
/missing
|
/missing
|
||||||
/.deps
|
/.deps
|
||||||
@@ -23,14 +23,12 @@
|
|||||||
/config.guess
|
/config.guess
|
||||||
/config.h
|
/config.h
|
||||||
/config.h.in
|
/config.h.in
|
||||||
/config.h.in~
|
|
||||||
/config.log
|
/config.log
|
||||||
/config.nice
|
/config.nice
|
||||||
/config.status
|
/config.status
|
||||||
/config.sub
|
/config.sub
|
||||||
/configure
|
/configure
|
||||||
/configure.in
|
/configure.in
|
||||||
/configure.ac
|
|
||||||
/install-sh
|
/install-sh
|
||||||
/intl.la
|
/intl.la
|
||||||
/libtool
|
/libtool
|
||||||
@@ -43,12 +41,3 @@
|
|||||||
/rar.la
|
/rar.la
|
||||||
*.autosave
|
*.autosave
|
||||||
/unrar/.libs
|
/unrar/.libs
|
||||||
/tmp-php.ini
|
|
||||||
/php-rar.creator.user
|
|
||||||
/compile_commands.json
|
|
||||||
/.clangd
|
|
||||||
/report.xml
|
|
||||||
/.worktrees
|
|
||||||
*.dep
|
|
||||||
/configure~
|
|
||||||
/.cache/
|
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
language: c
|
||||||
|
dist: trusty
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- valgrind
|
||||||
|
|
||||||
|
env:
|
||||||
|
#- PHP_VERSION=5.2.17 ZTS=yes MIRROR=http://museum.php.net/php5/
|
||||||
|
- PHP_VERSION=5.3.29 ZTS=yes
|
||||||
|
- PHP_VERSION=5.4.45 ZTS=yes
|
||||||
|
- PHP_VERSION=5.5.37 ZTS=yes
|
||||||
|
- PHP_VERSION=5.6.30 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||||
|
- PHP_VERSION=5.6.30 ZTS=no
|
||||||
|
- PHP_VERSION=7.0.21 ZTS=yes COVERAGE=yes
|
||||||
|
- PHP_VERSION=7.1.7 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/php_builds
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- source travis.sh
|
||||||
|
- maybe_install_php $PHP_VERSION $ZTS
|
||||||
|
|
||||||
|
install:
|
||||||
|
- build $PHP_VERSION $ZTS "$COVERAGE"
|
||||||
|
|
||||||
|
script:
|
||||||
|
- run_tests $PHP_VERSION $ZTS
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- 'test "$COVERAGE" != "yes" || bash <(curl -s https://codecov.io/bash)'
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
# Build and test inside the matching CI Docker image.
|
|
||||||
# Image SHAs are read from .github/docker-image-shas.yml (multi-arch OCI index digests).
|
|
||||||
# To refresh SHAs: .github/scripts/update-docker-shas.sh
|
|
||||||
|
|
||||||
# ── Images ────────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
_base := "ghcr.io/cataphract/php-minimal@"
|
|
||||||
_shas := ".github/docker-image-shas.yml"
|
|
||||||
|
|
||||||
image_7_0_debug := _base + `grep '7.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_0_release_zts := _base + `grep '7.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_1_debug := _base + `grep '7.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_1_release_zts := _base + `grep '7.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_2_debug := _base + `grep '7.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_2_release_zts := _base + `grep '7.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_3_debug := _base + `grep '7.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_3_release_zts := _base + `grep '7.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_4_debug := _base + `grep '7.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_7_4_release_zts := _base + `grep '7.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_0_debug := _base + `grep '8.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_0_release_zts := _base + `grep '8.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_1_debug := _base + `grep '8.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_1_release_zts := _base + `grep '8.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_2_debug := _base + `grep '8.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_2_release_zts := _base + `grep '8.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_3_debug := _base + `grep '8.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_3_release_zts := _base + `grep '8.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_4_debug := _base + `grep '8.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_4_release_zts := _base + `grep '8.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_5_debug := _base + `grep '8.5-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_8_5_release_zts := _base + `grep '8.5-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
|
|
||||||
_run := "docker run --rm --entrypoint bash -v \"$PWD:/workspace\" -w /workspace --user root"
|
|
||||||
|
|
||||||
# ── Default ───────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
default:
|
|
||||||
@just --list
|
|
||||||
|
|
||||||
# ── Individual targets ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
test-7_0-debug:
|
|
||||||
{{_run}} {{image_7_0_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-7_0-release-zts:
|
|
||||||
{{_run}} {{image_7_0_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-7_1-debug:
|
|
||||||
{{_run}} {{image_7_1_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-7_1-release-zts:
|
|
||||||
{{_run}} {{image_7_1_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-7_2-debug:
|
|
||||||
{{_run}} {{image_7_2_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-7_2-release-zts:
|
|
||||||
{{_run}} {{image_7_2_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-7_3-debug:
|
|
||||||
{{_run}} {{image_7_3_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-7_3-release-zts:
|
|
||||||
{{_run}} {{image_7_3_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-7_4-debug:
|
|
||||||
{{_run}} {{image_7_4_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-7_4-release-zts:
|
|
||||||
{{_run}} {{image_7_4_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_0-debug:
|
|
||||||
{{_run}} {{image_8_0_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_0-release-zts:
|
|
||||||
{{_run}} {{image_8_0_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_1-debug:
|
|
||||||
{{_run}} {{image_8_1_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_1-release-zts:
|
|
||||||
{{_run}} {{image_8_1_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_2-debug:
|
|
||||||
{{_run}} {{image_8_2_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_2-release-zts:
|
|
||||||
{{_run}} {{image_8_2_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_3-debug:
|
|
||||||
{{_run}} {{image_8_3_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_3-release-zts:
|
|
||||||
{{_run}} {{image_8_3_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_4-debug:
|
|
||||||
{{_run}} {{image_8_4_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_4-release-zts:
|
|
||||||
{{_run}} {{image_8_4_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-8_5-debug:
|
|
||||||
{{_run}} {{image_8_5_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-8_5-release-zts:
|
|
||||||
{{_run}} {{image_8_5_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
# ── Per-version aggregates (sequential to avoid workspace conflicts) ───────────
|
|
||||||
|
|
||||||
test-7_0: test-7_0-debug test-7_0-release-zts
|
|
||||||
test-7_1: test-7_1-debug test-7_1-release-zts
|
|
||||||
test-7_2: test-7_2-debug test-7_2-release-zts
|
|
||||||
test-7_3: test-7_3-debug test-7_3-release-zts
|
|
||||||
test-7_4: test-7_4-debug test-7_4-release-zts
|
|
||||||
test-8_0: test-8_0-debug test-8_0-release-zts
|
|
||||||
test-8_1: test-8_1-debug test-8_1-release-zts
|
|
||||||
test-8_2: test-8_2-debug test-8_2-release-zts
|
|
||||||
test-8_3: test-8_3-debug test-8_3-release-zts
|
|
||||||
test-8_4: test-8_4-debug test-8_4-release-zts
|
|
||||||
test-8_5: test-8_5-debug test-8_5-release-zts
|
|
||||||
|
|
||||||
# ── All Linux targets ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
test-linux: test-7_0 test-7_1 test-7_2 test-7_3 test-7_4 test-8_0 test-8_1 test-8_2 test-8_3 test-8_4 test-8_5
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
EXTRA_CFLAGS := $(EXTRA_CFLAGS) -Wall
|
|
||||||
|
|
||||||
.PHONY: replace-run-tests
|
|
||||||
replace-run-tests:
|
|
||||||
cp run-tests-rar.php run-tests.php
|
|
||||||
|
|
||||||
test: replace-run-tests
|
|
||||||
+3
-23
@@ -10,26 +10,6 @@ unrar/LICENSE.txt for details.
|
|||||||
Some modifications have been applied to the UnRAR library, mainly to allow
|
Some modifications have been applied to the UnRAR library, mainly to allow
|
||||||
streaming extraction of files without using threads.
|
streaming extraction of files without using threads.
|
||||||
|
|
||||||
## Installation
|
[](https://ci.appveyor.com/project/cataphract/php-rar/branch/master)
|
||||||
|
[](https://travis-ci.org/cataphract/php-rar)
|
||||||
### With PECL
|
[](https://codecov.io/gh/cataphract/php-rar)
|
||||||
|
|
||||||
To install a specific version directly from GitHub, use the `.tgz` release
|
|
||||||
asset — not the auto-generated tag archive, which has an incompatible directory
|
|
||||||
structure:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
pecl install https://github.com/cataphract/php-rar/releases/download/v4.3.1/rar-4.3.1.tgz
|
|
||||||
```
|
|
||||||
|
|
||||||
Then add `extension=rar` to your `php.ini`.
|
|
||||||
|
|
||||||
### With PIE
|
|
||||||
|
|
||||||
[PIE](https://github.com/php/pie) is the modern replacement for PECL, available from PHP 8.1+.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
pie install rar
|
|
||||||
```
|
|
||||||
|
|
||||||
PIE automatically adds the extension to your `php.ini`.
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
echo Running appveyor.bat
|
||||||
|
echo on
|
||||||
|
|
||||||
|
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
|
||||||
|
|
||||||
|
IF NOT EXIST "C:\projects\php-sdk" (
|
||||||
|
wget -nv http://windows.php.net/downloads/php-sdk/php-sdk-binary-tools-20110915.zip
|
||||||
|
7z x -y php-sdk-binary-tools-20110915.zip -oC:\projects\php-sdk
|
||||||
|
)
|
||||||
|
IF NOT EXIST "C:\projects\php-src\Release_TS\php7ts.lib" (
|
||||||
|
git clone --depth=1 --branch=PHP-7.1 https://github.com/php/php-src C:\projects\php-src
|
||||||
|
wget -nv http://windows.php.net/downloads/php-sdk/deps-7.1-vc14-x86.7z
|
||||||
|
7z x -y deps-7.1-vc14-x86.7z -oC:\projects\php-src
|
||||||
|
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||||
|
cd C:\projects\php-src
|
||||||
|
CALL buildconf.bat
|
||||||
|
CALL configure.bat --disable-all --enable-cli --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||||
|
nmake
|
||||||
|
) ELSE (
|
||||||
|
echo php7ts.lib already exists
|
||||||
|
cd C:\projects\php-src
|
||||||
|
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||||
|
)
|
||||||
|
|
||||||
|
CALL buildconf.bat --force --add-modules-dir=%APPVEYOR_BUILD_FOLDER%\..
|
||||||
|
CALL configure.bat --disable-all --enable-cli --enable-rar=shared --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||||
|
nmake || exit /b
|
||||||
|
rmdir Release_TS\php-rar /S /Q
|
||||||
|
del /S /Q "Release_TS\*.sbr"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# Based on igbinary's appveyor config.
|
||||||
|
|
||||||
|
version: '{branch}.{build}'
|
||||||
|
install:
|
||||||
|
- cmd: choco feature enable -n=allowGlobalConfirmation
|
||||||
|
- cmd: cinst wget
|
||||||
|
- cmd: mkdir %APPVEYOR_BUILD_FOLDER%\bin
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cmd: "%APPVEYOR_BUILD_FOLDER%\\appveyor.bat"
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- cmd: cd C:\projects\php-src
|
||||||
|
- cmd: set NO_INTERACTION=1
|
||||||
|
- cmd: set REPORT_EXIT_STATUS=1
|
||||||
|
- cmd: set TZ=UTC
|
||||||
|
- cmd: 'nmake test TESTS="--show-diff --set-timeout 30 -d extension=C:\projects\php-src\Release_TS\php_rar.dll %APPVEYOR_BUILD_FOLDER%\tests"'
|
||||||
|
|
||||||
|
after_test:
|
||||||
|
# - cmd: dir /S C:\projects\php-src\Release_TS
|
||||||
|
- cmd: 'del C:\projects\php-src\Release_TS\php_rar.*'
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||||
|
- C:\projects\php-src
|
||||||
|
- C:\projects\php-sdk
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "cataphract/rar",
|
|
||||||
"type": "php-ext",
|
|
||||||
"description": "PHP extension for reading RAR archives using bundled unRAR library",
|
|
||||||
"license": "PHP-3.01",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Gustavo Lopes",
|
|
||||||
"email": "cataphract@php.net",
|
|
||||||
"role": "lead"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Antony Dovgal",
|
|
||||||
"email": "tony@daylessday.org",
|
|
||||||
"role": "developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": "^7.0 || ^8.0"
|
|
||||||
},
|
|
||||||
"replace": {
|
|
||||||
"ext-rar": "*"
|
|
||||||
},
|
|
||||||
"support": {
|
|
||||||
"source": "https://github.com/cataphract/php-rar"
|
|
||||||
},
|
|
||||||
"php-ext": {
|
|
||||||
"extension-name": "rar",
|
|
||||||
"download-url-method": ["pre-packaged-binary", "composer-default"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,63 +29,14 @@ unrar_sources="unrar/sha256.cpp unrar/qopen.cpp \
|
|||||||
unrar/arcread.cpp unrar/filefn.cpp \
|
unrar/arcread.cpp unrar/filefn.cpp \
|
||||||
unrar/global.cpp unrar/list.cpp \
|
unrar/global.cpp unrar/list.cpp \
|
||||||
unrar/encname.cpp unrar/file.cpp \
|
unrar/encname.cpp unrar/file.cpp \
|
||||||
unrar/secpassword.cpp unrar/options.cpp \
|
unrar/secpassword.cpp unrar/options.cpp"
|
||||||
unrar/largepage.cpp"
|
|
||||||
|
|
||||||
|
|
||||||
AC_LANG_PUSH([C++])
|
|
||||||
cxxflags_null=""
|
|
||||||
AC_DEFUN([CXXC_FLAG_CHECK],
|
|
||||||
[
|
|
||||||
ac_saved_cxxflags="$CXXFLAGS"
|
|
||||||
CXXFLAGS="$1 -Werror"
|
|
||||||
flag_to_add=m4_default([$2],[$1])
|
|
||||||
AC_MSG_CHECKING([whether the C++ compiler supports $1])
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM([])],
|
|
||||||
[AC_MSG_RESULT([yes])]
|
|
||||||
[cxxflags_null="$cxxflags_null $flag_to_add"],
|
|
||||||
[AC_MSG_RESULT([no])]
|
|
||||||
)
|
|
||||||
CXXFLAGS="$ac_saved_cxxflags"
|
|
||||||
])
|
|
||||||
CXXC_FLAG_CHECK([-Wparentheses], [-Wno-parentheses])
|
|
||||||
CXXC_FLAG_CHECK([-Wswitch], [-Wno-switch])
|
|
||||||
CXXC_FLAG_CHECK([-Wdangling-else], [-Wno-dangling-else])
|
|
||||||
CXXC_FLAG_CHECK([-Wlogical-op-parentheses], [-Wno-logical-op-parentheses])
|
|
||||||
CXXC_FLAG_CHECK([-Wmissing-braces], [-Wno-missing-braces])
|
|
||||||
CXXC_FLAG_CHECK([-Wunused-function], [-Wno-unused-function])
|
|
||||||
CXXC_FLAG_CHECK([-Wunused-variable], [-Wno-unused-variable])
|
|
||||||
CXXC_FLAG_CHECK([-Wsign-compare], [-Wno-sign-compare])
|
|
||||||
CXXC_FLAG_CHECK([-Wmisleading-indentation], [-Wno-misleading-indentation])
|
|
||||||
AC_LANG_POP([C++])
|
|
||||||
|
|
||||||
extra_cxxflags="-Wall $cxxflags_null"
|
|
||||||
echo "EXTRA_CXXFLAGS := \$(EXTRA_CXXFLAGS) $extra_cxxflags" >> Makefile.fragments
|
|
||||||
cat Makefile.frag >> Makefile.fragments
|
|
||||||
INCLUDES=`echo "$INCLUDES" | sed 's/-I/-isystem /g'`
|
|
||||||
dnl Move -Wall into CFLAGS/CXXFLAGS so it precedes EXTRA_CXXFLAGS in compile
|
|
||||||
dnl commands; the -Wno-* suppression flags in EXTRA_CXXFLAGS must come last.
|
|
||||||
CFLAGS="$CFLAGS -Wall"
|
|
||||||
CXXFLAGS="$CXXFLAGS -Wall"
|
|
||||||
|
|
||||||
if test "$PHP_RAR" != "no"; then
|
if test "$PHP_RAR" != "no"; then
|
||||||
AC_DEFINE(HAVE_RAR, 1, [Whether you have rar support])
|
AC_DEFINE(HAVE_RAR, 1, [Whether you have rar support])
|
||||||
PHP_SUBST(RAR_SHARED_LIBADD)
|
PHP_SUBST(RAR_SHARED_LIBADD)
|
||||||
PHP_REQUIRE_CXX()
|
PHP_REQUIRE_CXX()
|
||||||
|
PHP_ADD_LIBRARY_WITH_PATH(stdc++, "", RAR_SHARED_LIBADD)
|
||||||
|
|
||||||
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c rar_time.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -fPIC -fvisibility=hidden -I@ext_srcdir@/unrar, yes)
|
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -Wno-write-strings -Wall -I@ext_srcdir@/unrar)
|
||||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether linker supports version scripts])
|
|
||||||
rar_save_ldflags="$LDFLAGS"
|
|
||||||
LDFLAGS="$LDFLAGS -Wl,--version-script=$ext_srcdir/rar.map"
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM([[void get_module(void) {}]], [])],
|
|
||||||
[AC_MSG_RESULT([yes])
|
|
||||||
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--version-script=$ext_srcdir/rar.map"],
|
|
||||||
[AC_MSG_RESULT([no])]
|
|
||||||
)
|
|
||||||
LDFLAGS="$rar_save_ldflags"
|
|
||||||
PHP_SUBST(EXTRA_LDFLAGS)
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
+3
-4
@@ -4,7 +4,7 @@
|
|||||||
ARG_ENABLE("rar", "Rar support", "no");
|
ARG_ENABLE("rar", "Rar support", "no");
|
||||||
|
|
||||||
if (PHP_RAR != "no") {
|
if (PHP_RAR != "no") {
|
||||||
EXTENSION("rar", "rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c rar_time.c", PHP_RAR_SHARED, "/DRARDLL /DSILENT /EHsc /D_WSTDIO_DEFINED");
|
EXTENSION("rar", "rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c", PHP_RAR_SHARED, "/DRARDLL /DSILENT /EHsc /D_WSTDIO_DEFINED");
|
||||||
ADD_SOURCES(configure_module_dirname + "/unrar",
|
ADD_SOURCES(configure_module_dirname + "/unrar",
|
||||||
"sha256.cpp qopen.cpp \
|
"sha256.cpp qopen.cpp \
|
||||||
blake2s.cpp recvol.cpp \
|
blake2s.cpp recvol.cpp \
|
||||||
@@ -18,7 +18,7 @@ if (PHP_RAR != "no") {
|
|||||||
crc.cpp rijndael.cpp crypt.cpp \
|
crc.cpp rijndael.cpp crypt.cpp \
|
||||||
rawread.cpp \
|
rawread.cpp \
|
||||||
rs.cpp smallfn.cpp \
|
rs.cpp smallfn.cpp \
|
||||||
isnt.cpp consio.cpp \
|
isnt.cpp rar.cpp consio.cpp \
|
||||||
scantree.cpp archive.cpp strfn.cpp \
|
scantree.cpp archive.cpp strfn.cpp \
|
||||||
strlist.cpp \
|
strlist.cpp \
|
||||||
getbits.cpp hash.cpp \
|
getbits.cpp hash.cpp \
|
||||||
@@ -31,8 +31,7 @@ if (PHP_RAR != "no") {
|
|||||||
arcread.cpp filefn.cpp \
|
arcread.cpp filefn.cpp \
|
||||||
global.cpp list.cpp \
|
global.cpp list.cpp \
|
||||||
encname.cpp file.cpp \
|
encname.cpp file.cpp \
|
||||||
secpassword.cpp options.cpp \
|
secpassword.cpp options.cpp", "rar");
|
||||||
largepage.cpp motw.cpp", "rar");
|
|
||||||
|
|
||||||
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
# Build environment using Alpine 3.23 with LLVM runtimes built from source.
|
|
||||||
# Provides a musl-based toolchain for building portable Linux binaries
|
|
||||||
# that work on both musl and glibc systems (via glibc_compat.a).
|
|
||||||
#
|
|
||||||
# Build:
|
|
||||||
# docker build --build-arg ARCH=aarch64 -t musl-build-env:latest .
|
|
||||||
# docker build --build-arg ARCH=x86_64 -t musl-build-env:latest .
|
|
||||||
|
|
||||||
FROM alpine:3.23
|
|
||||||
|
|
||||||
ARG ARCH
|
|
||||||
|
|
||||||
RUN test -n "${ARCH}" || (echo "ARCH build arg is required (aarch64 or x86_64)" && false)
|
|
||||||
|
|
||||||
# Install build tools and dependencies
|
|
||||||
RUN apk --no-cache add \
|
|
||||||
alpine-sdk bash binutils clang cmake compiler-rt \
|
|
||||||
coreutils git linux-headers lld llvm make \
|
|
||||||
musl-dev patchelf python3 wget xz
|
|
||||||
|
|
||||||
# Apply musl patches for glibc ABI compatibility
|
|
||||||
COPY locale.h.diff /locale.h.diff
|
|
||||||
RUN cd /usr/include && patch -p0 < /locale.h.diff
|
|
||||||
|
|
||||||
COPY alltypes.h.diff /alltypes.h.diff
|
|
||||||
RUN cd /usr/include && patch -p0 < /alltypes.h.diff
|
|
||||||
|
|
||||||
# Download and build LLVM runtimes (libunwind, libc++abi, libc++) matching
|
|
||||||
# the system clang version so headers, ABIs and compiler-rt all align.
|
|
||||||
# Detect the full version string (e.g. 21.1.2) from the installed clang.
|
|
||||||
# Only the runtimes are built from source — the system clang is the bootstrap.
|
|
||||||
RUN set -e && \
|
|
||||||
LLVM_VER=$(clang --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) && \
|
|
||||||
echo "Building LLVM ${LLVM_VER} runtimes to match system clang" && \
|
|
||||||
wget -q "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VER}/llvm-project-${LLVM_VER}.src.tar.xz" && \
|
|
||||||
tar -xf "llvm-project-${LLVM_VER}.src.tar.xz" && \
|
|
||||||
rm "llvm-project-${LLVM_VER}.src.tar.xz" && \
|
|
||||||
cd "llvm-project-${LLVM_VER}.src" && mkdir build && cd build && \
|
|
||||||
cmake \
|
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
|
||||||
-DCMAKE_C_COMPILER=clang \
|
|
||||||
-DCMAKE_C_FLAGS="-fno-omit-frame-pointer" \
|
|
||||||
-DCMAKE_CXX_COMPILER=clang++ \
|
|
||||||
-DCMAKE_CXX_FLAGS="-fno-omit-frame-pointer" \
|
|
||||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
|
||||||
-DLIBUNWIND_ENABLE_SHARED=OFF \
|
|
||||||
-DLIBUNWIND_ENABLE_STATIC=ON \
|
|
||||||
-DLIBUNWIND_USE_COMPILER_RT=ON \
|
|
||||||
-DLIBCXXABI_ENABLE_SHARED=OFF \
|
|
||||||
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \
|
|
||||||
-DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
|
|
||||||
-DLIBCXXABI_USE_COMPILER_RT=ON \
|
|
||||||
-DLIBCXX_ENABLE_SHARED=OFF \
|
|
||||||
-DLIBCXX_HAS_MUSL_LIBC=ON \
|
|
||||||
-DLIBCXX_USE_COMPILER_RT=ON \
|
|
||||||
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
|
|
||||||
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
|
|
||||||
../runtimes && \
|
|
||||||
make -j$(nproc) install-unwind install-cxxabi install-cxx && \
|
|
||||||
cd / && rm -rf "/llvm-project-${LLVM_VER}.src"
|
|
||||||
|
|
||||||
# Set up symlinks using the system LLVM and GCC versions detected at build time.
|
|
||||||
# Use grep -oE (not -oP) since busybox grep lacks Perl regex support.
|
|
||||||
RUN set -e && \
|
|
||||||
SYS_LLVM_VER=$(clang --version | grep -oE '[0-9]+' | head -1) && \
|
|
||||||
GCC_VER=$(ls /usr/lib/gcc/${ARCH}-alpine-linux-musl/) && \
|
|
||||||
echo "System LLVM: ${SYS_LLVM_VER}, GCC: ${GCC_VER}" && \
|
|
||||||
GCC_DIR=/usr/lib/gcc/${ARCH}-alpine-linux-musl/${GCC_VER} && \
|
|
||||||
CLANG_DIR=/usr/lib/llvm${SYS_LLVM_VER}/lib/clang/${SYS_LLVM_VER} && \
|
|
||||||
ln -s ${GCC_DIR} /usr/lib/resource_dir && \
|
|
||||||
ln -s ${CLANG_DIR}/lib /usr/lib/resource_dir/lib && \
|
|
||||||
ln -s ${CLANG_DIR}/lib/${ARCH}-alpine-linux-musl/libclang_rt.builtins-${ARCH}.a \
|
|
||||||
/usr/lib/libclang_rt.builtins.a && \
|
|
||||||
GCC_STDATOMIC=${GCC_DIR}/include/stdatomic.h && \
|
|
||||||
if [ -f "${GCC_STDATOMIC}" ]; then \
|
|
||||||
mv "${GCC_STDATOMIC}" "${GCC_STDATOMIC}_" && \
|
|
||||||
cp ${CLANG_DIR}/include/stdatomic.h "${GCC_STDATOMIC}"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set up sysroot directory structure.
|
|
||||||
# Programs compiled with --sysroot=/sysroot/ARCH-none-linux-musl will find
|
|
||||||
# headers and libraries via these symlinks.
|
|
||||||
RUN mkdir -p /sysroot/${ARCH}-none-linux-musl/usr && \
|
|
||||||
ln -s /usr/lib /sysroot/${ARCH}-none-linux-musl/usr/lib && \
|
|
||||||
ln -s /usr/include /sysroot/${ARCH}-none-linux-musl/usr/include && \
|
|
||||||
ln -s /lib /sysroot/${ARCH}-none-linux-musl/lib
|
|
||||||
|
|
||||||
# Build glibc_compat.c into a static archive.
|
|
||||||
# This library ensures binaries work on both musl and glibc:
|
|
||||||
# - On musl: musl exports __xstat and other glibc compat symbols, so the
|
|
||||||
# wrappers in glibc_compat resolve correctly.
|
|
||||||
# - On glibc: glibc_compat bridges the musl-compiled ABI to glibc internals.
|
|
||||||
# Always link against -lglibc_compat; the musl-clang wrapper does this by default.
|
|
||||||
COPY glibc_compat.c /sysroot/glibc_compat.c
|
|
||||||
RUN clang \
|
|
||||||
--target=${ARCH}-none-linux-musl \
|
|
||||||
--sysroot=/sysroot/${ARCH}-none-linux-musl \
|
|
||||||
-rtlib=compiler-rt \
|
|
||||||
-fpie -O2 -fno-omit-frame-pointer -ggdb3 \
|
|
||||||
-c /sysroot/glibc_compat.c -o /tmp/glibc_compat.o && \
|
|
||||||
ar rcs /sysroot/${ARCH}-none-linux-musl/usr/lib/libglibc_compat.a /tmp/glibc_compat.o && \
|
|
||||||
rm /tmp/glibc_compat.o
|
|
||||||
|
|
||||||
# Install CMake toolchain file for this architecture
|
|
||||||
COPY Toolchain.cmake.${ARCH} /sysroot/${ARCH}-none-linux-musl/Toolchain.cmake
|
|
||||||
|
|
||||||
# Install musl-clang / musl-clang++ wrapper scripts.
|
|
||||||
# These encode the target triple, sysroot, required compiler flags, and always
|
|
||||||
# link -lglibc_compat so every binary works on both musl and glibc systems.
|
|
||||||
COPY musl-clang.sh /usr/local/bin/musl-clang
|
|
||||||
COPY musl-clang++.sh /usr/local/bin/musl-clang++
|
|
||||||
RUN chmod +x /usr/local/bin/musl-clang /usr/local/bin/musl-clang++
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# vim: set ft=cmake:
|
|
||||||
set(sysroot /sysroot/aarch64-none-linux-musl)
|
|
||||||
set(arch aarch64)
|
|
||||||
set(interpreter ld-musl-aarch64.so.1)
|
|
||||||
set(CMAKE_SYSTEM_NAME Linux)
|
|
||||||
set(CMAKE_SYSTEM_PROCESSOR ${arch})
|
|
||||||
set(CMAKE_SYSROOT ${sysroot})
|
|
||||||
set(CMAKE_AR /usr/bin/llvm-ar)
|
|
||||||
set(triple ${arch}-none-linux-musl)
|
|
||||||
set(CMAKE_ASM_COMPILER_TARGET ${triple})
|
|
||||||
set(CMAKE_C_COMPILER /usr/bin/clang)
|
|
||||||
set(CMAKE_C_COMPILER_TARGET ${triple})
|
|
||||||
|
|
||||||
set(c_cxx_flags "-Qunused-arguments -rtlib=compiler-rt -unwindlib=libunwind -static-libgcc -fno-omit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS_INIT ${c_cxx_flags})
|
|
||||||
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
|
|
||||||
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
|
||||||
set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++ ${c_cxx_flags}")
|
|
||||||
|
|
||||||
set(linker_flags "-fuse-ld=lld -nodefaultlibs -Wl,-Bstatic -lc++ -lc++abi ${sysroot}/usr/lib/libclang_rt.builtins.a -lunwind -lglibc_compat -Wl,-Bdynamic ${sysroot}/usr/lib/libclang_rt.builtins.a -Wl,--dynamic-linker,${sysroot}/lib/${interpreter} -Wl,-rpath=${sysroot} -resource-dir ${sysroot}/usr/lib/resource_dir")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "${linker_flags} -Wl,--dynamic-linker,${sysroot}/lib/${interpreter}")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT ${linker_flags})
|
|
||||||
set(CMAKE_C_STANDARD_LIBRARIES "-Wl,-Bdynamic -lc")
|
|
||||||
set(CMAKE_CXX_STANDARD_LIBRARIES "-Wl,-Bdynamic -lc")
|
|
||||||
|
|
||||||
set(CMAKE_NM /usr/bin/llvm-nm)
|
|
||||||
set(CMAKE_RANLIB /usr/bin/llvm-ranlib)
|
|
||||||
set(CMAKE_STRIP /usr/bin/strip)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# vim: set ft=cmake:
|
|
||||||
set(sysroot /sysroot/x86_64-none-linux-musl)
|
|
||||||
set(arch x86_64)
|
|
||||||
set(interpreter ld-musl-x86_64.so.1)
|
|
||||||
set(CMAKE_SYSTEM_NAME Linux)
|
|
||||||
set(CMAKE_SYSTEM_PROCESSOR ${arch})
|
|
||||||
set(CMAKE_SYSROOT ${sysroot})
|
|
||||||
set(CMAKE_AR /usr/bin/llvm-ar)
|
|
||||||
set(triple ${arch}-none-linux-musl)
|
|
||||||
set(CMAKE_ASM_COMPILER_TARGET ${triple})
|
|
||||||
set(CMAKE_C_COMPILER /usr/bin/clang)
|
|
||||||
set(CMAKE_C_COMPILER_TARGET ${triple})
|
|
||||||
|
|
||||||
set(c_cxx_flags "-Qunused-arguments -rtlib=compiler-rt -unwindlib=libunwind -static-libgcc -fno-omit-frame-pointer")
|
|
||||||
set(CMAKE_C_FLAGS_INIT ${c_cxx_flags})
|
|
||||||
set(CMAKE_CXX_COMPILER /usr/bin/clang++)
|
|
||||||
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
|
||||||
set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++ ${c_cxx_flags}")
|
|
||||||
|
|
||||||
set(linker_flags "-fuse-ld=lld -nodefaultlibs -Wl,-Bstatic -lc++ -lc++abi ${sysroot}/usr/lib/libclang_rt.builtins.a -lunwind -lglibc_compat -Wl,-Bdynamic ${sysroot}/usr/lib/libclang_rt.builtins.a -Wl,--dynamic-linker,${sysroot}/lib/${interpreter} -Wl,-rpath=${sysroot} -resource-dir ${sysroot}/usr/lib/resource_dir")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "${linker_flags} -Wl,--dynamic-linker,${sysroot}/lib/${interpreter}")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_INIT ${linker_flags})
|
|
||||||
set(CMAKE_C_STANDARD_LIBRARIES "-Wl,-Bdynamic -lc")
|
|
||||||
set(CMAKE_CXX_STANDARD_LIBRARIES "-Wl,-Bdynamic -lc")
|
|
||||||
|
|
||||||
set(CMAKE_NM /usr/bin/llvm-nm)
|
|
||||||
set(CMAKE_RANLIB /usr/bin/llvm-ranlib)
|
|
||||||
set(CMAKE_STRIP /usr/bin/strip)
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
--- bits/alltypes.h
|
|
||||||
+++ bits/alltypes.h
|
|
||||||
@@ -299,17 +299,32 @@
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
|
|
||||||
-typedef struct { unsigned __attr; } pthread_mutexattr_t;
|
|
||||||
+typedef struct { union { unsigned __attr;
|
|
||||||
+#ifdef __aarch64__
|
|
||||||
+ long __glibc_compat;
|
|
||||||
+#endif
|
|
||||||
+};
|
|
||||||
+} pthread_mutexattr_t;
|
|
||||||
#define __DEFINED_pthread_mutexattr_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
|
|
||||||
-typedef struct { unsigned __attr; } pthread_condattr_t;
|
|
||||||
+typedef struct { union { unsigned __attr;
|
|
||||||
+#ifdef __aarch64__
|
|
||||||
+ long __glibc_compat;
|
|
||||||
+#endif
|
|
||||||
+};
|
|
||||||
+} pthread_condattr_t;
|
|
||||||
#define __DEFINED_pthread_condattr_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
|
|
||||||
-typedef struct { unsigned __attr; } pthread_barrierattr_t;
|
|
||||||
+typedef struct { union { unsigned __attr;
|
|
||||||
+#ifdef __aarch64__
|
|
||||||
+ long __glibc_compat;
|
|
||||||
+#endif
|
|
||||||
+};
|
|
||||||
+} pthread_barrierattr_t;
|
|
||||||
#define __DEFINED_pthread_barrierattr_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -383,12 +398,20 @@
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
|
|
||||||
-typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t;
|
|
||||||
+typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9];
|
|
||||||
+#ifdef __aarch64__
|
|
||||||
+ char __glibc_compat[64];
|
|
||||||
+#endif
|
|
||||||
+} __u; } pthread_attr_t;
|
|
||||||
#define __DEFINED_pthread_attr_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
|
|
||||||
-typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } pthread_mutex_t;
|
|
||||||
+typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6];
|
|
||||||
+#ifdef __aarch64__
|
|
||||||
+ char __glibc_compat[48];
|
|
||||||
+#endif
|
|
||||||
+} __u; } pthread_mutex_t;
|
|
||||||
#define __DEFINED_pthread_mutex_t
|
|
||||||
#endif
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
#include <dlfcn.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <fenv.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if defined(__linux__) && !defined(__GLIBC__)
|
|
||||||
|
|
||||||
# ifdef __x86_64__
|
|
||||||
float ceilf(float x)
|
|
||||||
{
|
|
||||||
float result;
|
|
||||||
// NOLINTNEXTLINE(hicpp-no-assembler)
|
|
||||||
__asm__("roundss $0x0A, %[x], %[result]"
|
|
||||||
: [result] "=x"(result)
|
|
||||||
: [x] "x"(x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
double ceil(double x)
|
|
||||||
{
|
|
||||||
double result;
|
|
||||||
// NOLINTNEXTLINE(hicpp-no-assembler)
|
|
||||||
__asm__("roundsd $0x0A, %[x], %[result]"
|
|
||||||
: [result] "=x"(result)
|
|
||||||
: [x] "x"(x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef __aarch64__
|
|
||||||
float ceilf(float x)
|
|
||||||
{
|
|
||||||
float result;
|
|
||||||
__asm__("frintp %s0, %s1\n" : "=w"(result) : "w"(x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
double ceil(double x)
|
|
||||||
{
|
|
||||||
double result;
|
|
||||||
__asm__("frintp %d0, %d1\n" : "=w"(result) : "w"(x));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef __aarch64__
|
|
||||||
# define _STAT_VER 0
|
|
||||||
# else
|
|
||||||
# define _STAT_VER 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// glibc before 2.33 (2021) doesn't have these
|
|
||||||
int stat(const char *restrict path, void *restrict buf)
|
|
||||||
{
|
|
||||||
int __xstat(int, const char *restrict, void *restrict);
|
|
||||||
return __xstat(_STAT_VER, path, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fstat(int fd, void *buf)
|
|
||||||
{
|
|
||||||
int __fxstat(int, int, void *);
|
|
||||||
return __fxstat(_STAT_VER, fd, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int lstat(const char *restrict path, void *restrict buf)
|
|
||||||
{
|
|
||||||
int __lxstat(int, const char *restrict, void *restrict);
|
|
||||||
return __lxstat(_STAT_VER, path, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fstatat(int dirfd, const char *restrict pathname, void *restrict statbuf, int flags)
|
|
||||||
{
|
|
||||||
int __fxstatat(int, int, const char *restrict, void *restrict, int);
|
|
||||||
return __fxstatat(_STAT_VER, dirfd, pathname, statbuf, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// glibc doesn't define pthread_atfork on aarch64. We need to delegate to
|
|
||||||
// glibc's __register_atfork() instead. __register_atfork() takes an extra
|
|
||||||
// argument, __dso_handle, which is a pointer to the DSO that is registering the
|
|
||||||
// fork handlers. This is used to ensure that the handlers are not called after
|
|
||||||
// the DSO is unloaded. glibc on amd64 also implements pthread_atfork() in terms
|
|
||||||
// of __register_atfork(). (musl never unloads modules so that potential
|
|
||||||
// problem doesn't exist)
|
|
||||||
|
|
||||||
// On amd64, even though pthread_atfork is exported by glibc, it should not be
|
|
||||||
// used. Code that uses pthread_atfork will compile to an import to
|
|
||||||
// __register_atfork(), but here we're compiling against musl, resulting in an
|
|
||||||
// an import to pthread_atfork. This will cause a runtime error when unloading
|
|
||||||
// a shared module. The reason is that when we call pthread_atfork in glibc,
|
|
||||||
// __register_atfork() is called with the __dso_handle of libc6.so, not the
|
|
||||||
// __dso_handle of our module. So the fork handler is not unregistered when our
|
|
||||||
// module is unloaded.
|
|
||||||
|
|
||||||
extern void *__dso_handle __attribute__((weak));
|
|
||||||
int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
|
||||||
void (*child)(void), void *__dso_handle) __attribute__((weak));
|
|
||||||
|
|
||||||
int pthread_atfork(
|
|
||||||
void (*prepare)(void), void (*parent)(void), void (*child)(void))
|
|
||||||
{
|
|
||||||
// glibc
|
|
||||||
if (__dso_handle && __register_atfork) {
|
|
||||||
return __register_atfork(prepare, parent, child, __dso_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int (*real_atfork)(void (*)(void), void (*)(void), void (*)(void));
|
|
||||||
|
|
||||||
if (!real_atfork) {
|
|
||||||
// dlopen musl
|
|
||||||
# ifdef __aarch64__
|
|
||||||
void *handle = dlopen("ld-musl-aarch64.so.1", RTLD_LAZY);
|
|
||||||
if (!handle) {
|
|
||||||
(void)fprintf(
|
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
|
||||||
stderr, "dlopen of ld-musl-aarch64.so.1 failed: %s\n",
|
|
||||||
dlerror());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
void *handle = dlopen("libc.musl-x86_64.so.1", RTLD_LAZY);
|
|
||||||
if (!handle) {
|
|
||||||
(void)fprintf(
|
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
|
||||||
stderr, "dlopen of libc.musl-x86_64.so.1 failed: %s\n",
|
|
||||||
dlerror());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
real_atfork = dlsym(handle, "pthread_atfork");
|
|
||||||
if (!real_atfork) {
|
|
||||||
(void)fprintf(
|
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
|
||||||
stderr, "dlsym of pthread_atfork failed: %s\n", dlerror());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return real_atfork(prepare, parent, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifdef __x86_64__
|
|
||||||
struct pthread_cond;
|
|
||||||
struct pthread_condattr;
|
|
||||||
typedef struct pthread_cond pthread_cond_t;
|
|
||||||
typedef struct pthread_condattr pthread_condattr_t;
|
|
||||||
|
|
||||||
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr)
|
|
||||||
{
|
|
||||||
static int (*real_pthread_cond_init)(pthread_cond_t *cond, const pthread_condattr_t *cond_attr);
|
|
||||||
|
|
||||||
if (!real_pthread_cond_init) {
|
|
||||||
void *handle = dlopen("libc.so.6", RTLD_LAZY);
|
|
||||||
if (!handle) {
|
|
||||||
void *handle = dlopen("libc.musl-x86_64.so.1", RTLD_LAZY);
|
|
||||||
if (!handle) {
|
|
||||||
(void)fprintf(
|
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
|
||||||
stderr, "dlopen of libc.so.6 and libc.musl-x86_64.so.1 failed: %s\n",
|
|
||||||
dlerror());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
real_pthread_cond_init = dlsym(handle, "pthread_cond_init");
|
|
||||||
if (!real_pthread_cond_init) {
|
|
||||||
(void)fprintf(
|
|
||||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
|
||||||
stderr, "dlsym of pthread_cond_init failed: %s\n", dlerror());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return real_pthread_cond_init(cond, cond_attr);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// the symbol strerror_r in glibc is not the POSIX version; it returns char *
|
|
||||||
// __xpg_sterror_r is exported by both glibc and musl
|
|
||||||
int strerror_r(int errnum, char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
int __xpg_strerror_r(int, char *, size_t);
|
|
||||||
return __xpg_strerror_r(errnum, buf, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
// when compiling with --coverage, some references to atexit show up.
|
|
||||||
// glibc doesn't provide atexit for similar reasons as pthread_atfork presumably
|
|
||||||
int __cxa_atexit(void (*func)(void *), void *arg, void *dso_handle);
|
|
||||||
int atexit(void (*function)(void))
|
|
||||||
{
|
|
||||||
if (!__dso_handle) {
|
|
||||||
(void)fprintf(stderr, "Aborting because __dso_handle is NULL\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// the cast is harmless on amd64 and aarch64. Passing an extra argument to a
|
|
||||||
// function that expects none causes no problems
|
|
||||||
return __cxa_atexit((void (*)(void *))function, 0, __dso_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// introduced in glibc 2.25
|
|
||||||
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
|
|
||||||
int fd;
|
|
||||||
size_t bytes_read = 0;
|
|
||||||
|
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bytes_read < buflen) {
|
|
||||||
ssize_t result = read(fd, (char*)buf + bytes_read, buflen - bytes_read);
|
|
||||||
if (result < 0) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
bytes_read += result;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return (ssize_t)bytes_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
#define MEMFD_CREATE_SYSCALL 319
|
|
||||||
#elif __aarch64__
|
|
||||||
#define MEMFD_CREATE_SYSCALL 279
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// introduced in glibc 2.27
|
|
||||||
int memfd_create(const char *name, unsigned flags) {
|
|
||||||
return syscall(MEMFD_CREATE_SYSCALL, name, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// __flt_rounds is the backing function behind musl's FLT_ROUNDS macro: musl's
|
|
||||||
// <float.h> defines FLT_ROUNDS as (__flt_rounds()), making it dynamic — it
|
|
||||||
// reflects the current rounding mode after fesetround(). glibc/GCC does not
|
|
||||||
// export __flt_rounds; GCC's <float.h> defines FLT_ROUNDS as the compile-time
|
|
||||||
// constant 1 (round-to-nearest), so it never tracks fesetround() at all (GCC
|
|
||||||
// bug #59046 — GCC's own float.h has the comment "??? This is supposed to
|
|
||||||
// change with calls to fesetround in <fenv.h>"). fegetround() provides the
|
|
||||||
// actual hardware rounding mode on both.
|
|
||||||
int __flt_rounds(void)
|
|
||||||
{
|
|
||||||
switch (fegetround()) {
|
|
||||||
case FE_TONEAREST: return 1;
|
|
||||||
case FE_UPWARD: return 2;
|
|
||||||
case FE_DOWNWARD: return 3;
|
|
||||||
case FE_TOWARDZERO: return 0;
|
|
||||||
default: return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// glibc has never exported sigsetjmp as a dynamic symbol — it is defined in
|
|
||||||
// <setjmp.h> as a macro expanding to __sigsetjmp, so only __sigsetjmp appears
|
|
||||||
// in the DSO. Musl exports both sigsetjmp ajd __sigsetjmp as real symbols.
|
|
||||||
// sigsetjmp is referenced directly in compiled code, so we provide this
|
|
||||||
// bridge.
|
|
||||||
int sigsetjmp(sigjmp_buf env, int savemask)
|
|
||||||
{
|
|
||||||
int __sigsetjmp(sigjmp_buf, int);
|
|
||||||
return __sigsetjmp(env, savemask);
|
|
||||||
}
|
|
||||||
|
|
||||||
// glibc no longer exports res_init as a dynamic symbol (it never did for amd64
|
|
||||||
// or aarch64, only for older archs). Only __res_init is exported.
|
|
||||||
// Musl-compiled code references res_init directly. __res_init is declared weak
|
|
||||||
// so linking succeeds on musl (where it doesn't exist). At runtime: on glibc
|
|
||||||
// it's non-NULL and called directly; on musl it's NULL and we fall through to
|
|
||||||
// dlopen musl's own res_init.
|
|
||||||
extern int __res_init(void) __attribute__((weak));
|
|
||||||
|
|
||||||
int res_init(void)
|
|
||||||
{
|
|
||||||
if (__res_init)
|
|
||||||
return __res_init();
|
|
||||||
|
|
||||||
// musl path: find res_init in musl's libc via dlopen
|
|
||||||
static int (*musl_res_init)(void);
|
|
||||||
if (!musl_res_init) {
|
|
||||||
# ifdef __aarch64__
|
|
||||||
void *handle = dlopen("ld-musl-aarch64.so.1", RTLD_LAZY);
|
|
||||||
# else
|
|
||||||
void *handle = dlopen("libc.musl-x86_64.so.1", RTLD_LAZY);
|
|
||||||
# endif
|
|
||||||
if (handle) {
|
|
||||||
musl_res_init = dlsym(handle, "res_init");
|
|
||||||
} else {
|
|
||||||
(void)fprintf(stderr, "Aborting because dlopen() of musl failed\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (musl_res_init) {
|
|
||||||
return musl_res_init();
|
|
||||||
} else {
|
|
||||||
(void)fprintf(stderr, "Aborting because res_init/__res_init could not "
|
|
||||||
"be found");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
-- locale.h
|
|
||||||
+++ locale.h
|
|
||||||
@@ -71,7 +71,7 @@
|
|
||||||
#define LC_COLLATE_MASK (1<<LC_COLLATE)
|
|
||||||
#define LC_MONETARY_MASK (1<<LC_MONETARY)
|
|
||||||
#define LC_MESSAGES_MASK (1<<LC_MESSAGES)
|
|
||||||
-#define LC_ALL_MASK 0x7fffffff
|
|
||||||
+#define LC_ALL_MASK 0x1fbf
|
|
||||||
|
|
||||||
locale_t duplocale(locale_t);
|
|
||||||
void freelocale(locale_t);
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Wrapper for clang++ targeting musl libc with the correct sysroot and flags.
|
|
||||||
# Use this as CXX= for autoconf-based builds.
|
|
||||||
# -lglibc_compat is always appended so every binary works on both musl and glibc.
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
SYSROOT="/sysroot/${ARCH}-none-linux-musl"
|
|
||||||
LLVM_MAJOR=$(clang --version | grep -oE '[0-9]+' | head -1)
|
|
||||||
BUILTINS_DIR="/usr/lib/llvm${LLVM_MAJOR}/lib/clang/${LLVM_MAJOR}/lib/linux"
|
|
||||||
|
|
||||||
exec clang++ \
|
|
||||||
--target="${ARCH}-none-linux-musl" \
|
|
||||||
--sysroot="${SYSROOT}" \
|
|
||||||
-stdlib=libc++ \
|
|
||||||
-rtlib=compiler-rt \
|
|
||||||
-unwindlib=libunwind \
|
|
||||||
-fno-omit-frame-pointer \
|
|
||||||
-Qunused-arguments \
|
|
||||||
-fuse-ld=lld \
|
|
||||||
"$@" \
|
|
||||||
-L"${SYSROOT}/usr/lib" \
|
|
||||||
-L"${BUILTINS_DIR}" \
|
|
||||||
-lglibc_compat \
|
|
||||||
-lclang_rt.builtins-${ARCH}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Wrapper for clang targeting musl libc with the correct sysroot and flags.
|
|
||||||
# Use this as CC= for autoconf-based builds (e.g. PHP, php-rar).
|
|
||||||
# -lglibc_compat is always appended so every binary works on both musl and glibc.
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
SYSROOT="/sysroot/${ARCH}-none-linux-musl"
|
|
||||||
LLVM_MAJOR=$(clang --version | grep -oE '[0-9]+' | head -1)
|
|
||||||
BUILTINS_DIR="/usr/lib/llvm${LLVM_MAJOR}/lib/clang/${LLVM_MAJOR}/lib/linux"
|
|
||||||
|
|
||||||
exec clang \
|
|
||||||
--target="${ARCH}-none-linux-musl" \
|
|
||||||
--sysroot="${SYSROOT}" \
|
|
||||||
-rtlib=compiler-rt \
|
|
||||||
-unwindlib=libunwind \
|
|
||||||
-fno-omit-frame-pointer \
|
|
||||||
-Qunused-arguments \
|
|
||||||
-fuse-ld=lld \
|
|
||||||
"$@" \
|
|
||||||
-L"${SYSROOT}/usr/lib" \
|
|
||||||
-L"${BUILTINS_DIR}" \
|
|
||||||
-lglibc_compat \
|
|
||||||
-lclang_rt.builtins-${ARCH}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
# Minimal PHP build using the musl-build-env toolchain.
|
|
||||||
# PHP is compiled with --disable-all so only the CLI binary is built,
|
|
||||||
# with minimal dependencies (only musl libc + glibc_compat shim).
|
|
||||||
#
|
|
||||||
# The resulting image is used to build and test PHP extensions like php-rar.
|
|
||||||
# glibc_compat is always linked (via the musl-clang wrapper) so the binary
|
|
||||||
# and any extensions built here work on both musl and glibc systems.
|
|
||||||
#
|
|
||||||
# Build:
|
|
||||||
# # First build musl-build-env:
|
|
||||||
# docker build --build-arg ARCH=aarch64 -t musl-build-env:latest ../musl-build-env
|
|
||||||
#
|
|
||||||
# # Then build this image:
|
|
||||||
# docker build \
|
|
||||||
# --build-arg BUILD_ENV_IMAGE=musl-build-env:latest \
|
|
||||||
# --build-arg PHP_VERSION=8.4.6 \
|
|
||||||
# --build-arg ARCH=aarch64 \
|
|
||||||
# -t php-minimal:8.4-aarch64 .
|
|
||||||
|
|
||||||
ARG BUILD_ENV_IMAGE=musl-build-env:latest
|
|
||||||
FROM ${BUILD_ENV_IMAGE}
|
|
||||||
|
|
||||||
ARG PHP_VERSION=8.4.6
|
|
||||||
ARG ARCH
|
|
||||||
# PHP build variants: set these for debug/ZTS builds
|
|
||||||
ARG PHP_ENABLE_DEBUG=no
|
|
||||||
ARG PHP_ENABLE_ZTS=no
|
|
||||||
|
|
||||||
RUN test -n "${ARCH}" || (echo "ARCH build arg is required (aarch64 or x86_64)" && false)
|
|
||||||
|
|
||||||
# PHP build-time dependencies (re2c for lexer, autoconf for configure regeneration)
|
|
||||||
RUN apk --no-cache add \
|
|
||||||
autoconf bison re2c \
|
|
||||||
libxml2-dev openssl-dev
|
|
||||||
|
|
||||||
# Download PHP source
|
|
||||||
RUN wget -q "https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz" && \
|
|
||||||
tar -xf "php-${PHP_VERSION}.tar.gz" && \
|
|
||||||
rm "php-${PHP_VERSION}.tar.gz"
|
|
||||||
|
|
||||||
# Apply version-specific source patches for compatibility with modern clang.
|
|
||||||
#
|
|
||||||
# PHP 7.x patches:
|
|
||||||
# - reentrancy.c: configure wrongly detects HAVE_OLD_READDIR_R on musl,
|
|
||||||
# resulting in a 2-argument readdir_r call. Patch to the standard 3-arg form.
|
|
||||||
# - streams/cast.c: COOKIE_SEEKER_USES_OFF64_T is not detected by configure,
|
|
||||||
# so the by-value seek variant is compiled instead of the by-pointer variant
|
|
||||||
# that fopencookie requires on Linux. Fixed by passing -DCOOKIE_SEEKER_USES_OFF64_T.
|
|
||||||
#
|
|
||||||
# PHP 8.0 and 8.1 patches:
|
|
||||||
# - streams/cast.c: same COOKIE_SEEKER_USES_OFF64_T issue as PHP 7.x.
|
|
||||||
RUN \
|
|
||||||
VER_MAJOR=$(echo "${PHP_VERSION}" | cut -d. -f1) && \
|
|
||||||
if [ "${VER_MAJOR}" = "7" ]; then \
|
|
||||||
sed -i \
|
|
||||||
's/readdir_r(dirp, entry);/struct dirent *_rdr; (void)readdir_r(dirp, entry, \&_rdr);/' \
|
|
||||||
"php-${PHP_VERSION}/main/reentrancy.c"; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build PHP with clang targeting musl.
|
|
||||||
# --disable-all: disable all optional extensions (minimal build).
|
|
||||||
# musl-clang wrapper encodes the target triple, sysroot, clang flags, and
|
|
||||||
# always links -lglibc_compat so the binary works on both musl and glibc.
|
|
||||||
RUN \
|
|
||||||
DEBUG_FLAG=$([ "${PHP_ENABLE_DEBUG}" = "yes" ] && echo "--enable-debug" || echo "") && \
|
|
||||||
ZTS_FLAG=$([ "${PHP_ENABLE_ZTS}" = "yes" ] && echo "--enable-zts" || echo "") && \
|
|
||||||
VER_MAJOR=$(echo "${PHP_VERSION}" | cut -d. -f1) && \
|
|
||||||
VER_MINOR=$(echo "${PHP_VERSION}" | cut -d. -f2) && \
|
|
||||||
COMPAT_FLAGS=$([ "${VER_MAJOR}" = "7" ] || { [ "${VER_MAJOR}" = "8" ] && [ "${VER_MINOR}" -le 1 ]; } && echo "-DCOOKIE_SEEKER_USES_OFF64_T -D__off64_t=long -Doff64_t=long" || echo "") && \
|
|
||||||
ASAN_CFLAGS=$([ "${PHP_ENABLE_DEBUG}" = "yes" ] && echo "-fsanitize=address" || echo "") && \
|
|
||||||
ASAN_LDFLAGS=$([ "${PHP_ENABLE_DEBUG}" = "yes" ] && echo "-fsanitize=address" || echo "") && \
|
|
||||||
OPT_FLAG=$([ "${PHP_ENABLE_DEBUG}" = "yes" ] && echo "-O0" || echo "-O2") && \
|
|
||||||
cd "php-${PHP_VERSION}" && \
|
|
||||||
CC=musl-clang \
|
|
||||||
CXX=musl-clang++ \
|
|
||||||
CFLAGS="-g ${OPT_FLAG} ${COMPAT_FLAGS} ${ASAN_CFLAGS}" \
|
|
||||||
LDFLAGS="-fuse-ld=lld ${ASAN_LDFLAGS}" \
|
|
||||||
./configure \
|
|
||||||
--disable-all \
|
|
||||||
--disable-cgi \
|
|
||||||
--disable-fpm \
|
|
||||||
--without-pear \
|
|
||||||
--enable-cli \
|
|
||||||
${DEBUG_FLAG} \
|
|
||||||
${ZTS_FLAG} && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install
|
|
||||||
|
|
||||||
RUN rm -rf "/php-${PHP_VERSION}"
|
|
||||||
|
|
||||||
# Ensure extension builds (phpize + configure) use our musl toolchain.
|
|
||||||
ENV CC=musl-clang CXX=musl-clang++
|
|
||||||
|
|
||||||
# For debug builds: patch the musl-clang wrappers to add -fsanitize=address
|
|
||||||
# so that extensions compiled inside this image (e.g. by build-and-test.sh)
|
|
||||||
# are also ASAN-instrumented. This prevents the ASAN __cxa_throw interceptor
|
|
||||||
# crash that occurs when a non-instrumented extension (with statically-linked
|
|
||||||
# libc++) is loaded into an ASAN-instrumented PHP process.
|
|
||||||
RUN if [ "${PHP_ENABLE_DEBUG}" = "yes" ]; then \
|
|
||||||
for f in /usr/local/bin/musl-clang /usr/local/bin/musl-clang++; do \
|
|
||||||
sed -i 's|"$@"|"-fsanitize=address" "$@"|' "$f"; \
|
|
||||||
done; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify: PHP binary should depend only on musl libc
|
|
||||||
RUN php --version
|
|
||||||
RUN echo "Dynamic dependencies of PHP binary:" && \
|
|
||||||
ldd /usr/local/bin/php && \
|
|
||||||
echo "" && \
|
|
||||||
NON_MUSL=$(ldd /usr/local/bin/php | grep -v 'musl\|linux-vdso\|ld-musl\|statically' || true) && \
|
|
||||||
if [ -n "$NON_MUSL" ]; then \
|
|
||||||
echo "WARNING: unexpected non-musl dependencies: $NON_MUSL"; \
|
|
||||||
else \
|
|
||||||
echo "OK: PHP depends only on musl libc"; \
|
|
||||||
fi
|
|
||||||
+20
-181
@@ -23,11 +23,11 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<active>no</active>
|
<active>no</active>
|
||||||
</developer>
|
</developer>
|
||||||
|
|
||||||
<date>2026-03-15</date>
|
<date>2013-10-11</date>
|
||||||
<time>20:00:00</time>
|
<time>13:00:00</time>
|
||||||
<version>
|
<version>
|
||||||
<release>4.3.1</release>
|
<release>3.0.2</release>
|
||||||
<api>4.0.0</api>
|
<api>3.0.0</api>
|
||||||
</version>
|
</version>
|
||||||
|
|
||||||
<stability>
|
<stability>
|
||||||
@@ -36,8 +36,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
</stability>
|
</stability>
|
||||||
|
|
||||||
<license uri="http://www.php.net/license">PHP License</license>
|
<license uri="http://www.php.net/license">PHP License</license>
|
||||||
<notes>- Fix bug #75557: error opening archive with non-English characters in path on Windows.
|
<notes>- Fixed build with PHP 5.5.
|
||||||
- Do not build unconditionally against listdc++.
|
- Upgraded bundled unrar to version 4.2.4.
|
||||||
</notes>
|
</notes>
|
||||||
<contents>
|
<contents>
|
||||||
<dir name="/">
|
<dir name="/">
|
||||||
@@ -110,6 +110,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file role="test" name="065.phpt"/>
|
<file role="test" name="065.phpt"/>
|
||||||
<file role="test" name="066.phpt"/>
|
<file role="test" name="066.phpt"/>
|
||||||
<file role="test" name="067.phpt"/>
|
<file role="test" name="067.phpt"/>
|
||||||
|
<file role="test" name="068.phpt"/>
|
||||||
|
<file role="test" name="069.phpt"/>
|
||||||
<file role="test" name="070.phpt"/>
|
<file role="test" name="070.phpt"/>
|
||||||
<file role="test" name="071.phpt"/>
|
<file role="test" name="071.phpt"/>
|
||||||
<file role="test" name="072.phpt"/>
|
<file role="test" name="072.phpt"/>
|
||||||
@@ -140,23 +142,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file role="test" name="097.phpt"/>
|
<file role="test" name="097.phpt"/>
|
||||||
<file role="test" name="098.phpt"/>
|
<file role="test" name="098.phpt"/>
|
||||||
<file role="test" name="099.phpt"/>
|
<file role="test" name="099.phpt"/>
|
||||||
<file role="test" name="100.phpt"/>
|
|
||||||
<file role="test" name="101.phpt"/>
|
|
||||||
<file role="test" name="102.phpt"/>
|
|
||||||
<file role="test" name="103.phpt"/>
|
|
||||||
<file role="test" name="104.phpt"/>
|
|
||||||
<file role="test" name="106.phpt"/>
|
|
||||||
<file role="test" name="107.phpt"/>
|
|
||||||
<file role="test" name="108.phpt"/>
|
|
||||||
<file role="test" name="109.phpt"/>
|
|
||||||
<file role="test" name="110.phpt"/>
|
|
||||||
<file role="test" name="111.phpt"/>
|
|
||||||
<file role="test" name="112.phpt"/>
|
|
||||||
<file role="test" name="113.phpt"/>
|
|
||||||
<file role="test" name="114.phpt"/>
|
|
||||||
<file role="test" name="115.phpt"/>
|
|
||||||
<file role="test" name="bug75557.phpt"/>
|
|
||||||
<file role="test" name="75557тест.rar"/>
|
|
||||||
<file role="test" name="commented.rar"/>
|
<file role="test" name="commented.rar"/>
|
||||||
<file role="test" name="corrupted.rar"/>
|
<file role="test" name="corrupted.rar"/>
|
||||||
<file role="test" name="directories.rar"/>
|
<file role="test" name="directories.rar"/>
|
||||||
@@ -172,7 +157,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file role="test" name="multi.part2.rar"/>
|
<file role="test" name="multi.part2.rar"/>
|
||||||
<file role="test" name="multi.part3.rar"/>
|
<file role="test" name="multi.part3.rar"/>
|
||||||
<file role="test" name="multi_broken.part1.rar"/>
|
<file role="test" name="multi_broken.part1.rar"/>
|
||||||
<file role="test" name="php8compat.php.inc"/>
|
|
||||||
<file role="test" name="rar_notrar.rar"/>
|
<file role="test" name="rar_notrar.rar"/>
|
||||||
<file role="test" name="rar_unicode.rar"/>
|
<file role="test" name="rar_unicode.rar"/>
|
||||||
<file role="test" name="repeated_name.rar"/>
|
<file role="test" name="repeated_name.rar"/>
|
||||||
@@ -181,9 +165,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file role="test" name="solid.rar"/>
|
<file role="test" name="solid.rar"/>
|
||||||
<file role="test" name="sparsefiles_rar.rar"/>
|
<file role="test" name="sparsefiles_rar.rar"/>
|
||||||
<file role="test" name="store_method.rar"/>
|
<file role="test" name="store_method.rar"/>
|
||||||
<file role="test" name="rar5-links.rar"/>
|
|
||||||
<file role="test" name="rar5_multi.part1.rar"/>
|
|
||||||
<file role="test" name="rar5_multi.part2.rar"/>
|
|
||||||
</dir> <!-- /tests -->
|
</dir> <!-- /tests -->
|
||||||
<dir name="unrar">
|
<dir name="unrar">
|
||||||
<file name="acknow.txt" role="doc" />
|
<file name="acknow.txt" role="doc" />
|
||||||
@@ -191,14 +172,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="archive.cpp" role="src" />
|
<file name="archive.cpp" role="src" />
|
||||||
<file name="archive.hpp" role="src" />
|
<file name="archive.hpp" role="src" />
|
||||||
<file name="arcread.cpp" role="src" />
|
<file name="arcread.cpp" role="src" />
|
||||||
<file name="blake2s.cpp" role="src" />
|
<file name="array.hpp" role="src" />
|
||||||
<file name="blake2s.hpp" role="src" />
|
<file name="beosea.cpp" role="src" />
|
||||||
<file name="blake2s_sse.cpp" role="src" />
|
|
||||||
<file name="blake2sp.cpp" role="src" />
|
|
||||||
<file name="cmddata.cpp" role="src" />
|
<file name="cmddata.cpp" role="src" />
|
||||||
<file name="cmddata.hpp" role="src" />
|
<file name="cmddata.hpp" role="src" />
|
||||||
<file name="cmdfilter.cpp" role="src" />
|
|
||||||
<file name="cmdmix.cpp" role="src" />
|
|
||||||
<file name="coder.cpp" role="src" />
|
<file name="coder.cpp" role="src" />
|
||||||
<file name="coder.hpp" role="src" />
|
<file name="coder.hpp" role="src" />
|
||||||
<file name="compress.hpp" role="src" />
|
<file name="compress.hpp" role="src" />
|
||||||
@@ -208,10 +185,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="crc.hpp" role="src" />
|
<file name="crc.hpp" role="src" />
|
||||||
<file name="crypt.cpp" role="src" />
|
<file name="crypt.cpp" role="src" />
|
||||||
<file name="crypt.hpp" role="src" />
|
<file name="crypt.hpp" role="src" />
|
||||||
<file name="crypt1.cpp" role="src" />
|
|
||||||
<file name="crypt2.cpp" role="src" />
|
|
||||||
<file name="crypt3.cpp" role="src" />
|
|
||||||
<file name="crypt5.cpp" role="src" />
|
|
||||||
<file name="dll.cpp" role="src" />
|
<file name="dll.cpp" role="src" />
|
||||||
<file name="dll.hpp" role="src" />
|
<file name="dll.hpp" role="src" />
|
||||||
<file name="encname.cpp" role="src" />
|
<file name="encname.cpp" role="src" />
|
||||||
@@ -237,16 +210,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="getbits.hpp" role="src" />
|
<file name="getbits.hpp" role="src" />
|
||||||
<file name="global.cpp" role="src" />
|
<file name="global.cpp" role="src" />
|
||||||
<file name="global.hpp" role="src" />
|
<file name="global.hpp" role="src" />
|
||||||
<file name="hardlinks.cpp" role="src" />
|
|
||||||
<file name="hash.cpp" role="src" />
|
|
||||||
<file name="hash.hpp" role="src" />
|
|
||||||
<file name="headers.cpp" role="src" />
|
|
||||||
<file name="headers.hpp" role="src" />
|
<file name="headers.hpp" role="src" />
|
||||||
<file name="headers5.hpp" role="src" />
|
|
||||||
<file name="isnt.cpp" role="src" />
|
<file name="isnt.cpp" role="src" />
|
||||||
<file name="isnt.hpp" role="src" />
|
<file name="isnt.hpp" role="src" />
|
||||||
<file name="largepage.cpp" role="src" />
|
|
||||||
<file name="largepage.hpp" role="src" />
|
|
||||||
<file name="LICENSE.txt" role="doc" />
|
<file name="LICENSE.txt" role="doc" />
|
||||||
<file name="list.cpp" role="src" />
|
<file name="list.cpp" role="src" />
|
||||||
<file name="list.hpp" role="src" />
|
<file name="list.hpp" role="src" />
|
||||||
@@ -257,15 +223,12 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="match.hpp" role="src" />
|
<file name="match.hpp" role="src" />
|
||||||
<file name="model.cpp" role="src" />
|
<file name="model.cpp" role="src" />
|
||||||
<file name="model.hpp" role="src" />
|
<file name="model.hpp" role="src" />
|
||||||
<file name="motw.cpp" role="src" />
|
|
||||||
<file name="motw.hpp" role="src" />
|
|
||||||
<file name="options.cpp" role="src" />
|
<file name="options.cpp" role="src" />
|
||||||
<file name="options.hpp" role="src" />
|
<file name="options.hpp" role="src" />
|
||||||
<file name="os.hpp" role="src" />
|
<file name="os.hpp" role="src" />
|
||||||
|
<file name="os2ea.cpp" role="src" />
|
||||||
<file name="pathfn.cpp" role="src" />
|
<file name="pathfn.cpp" role="src" />
|
||||||
<file name="pathfn.hpp" role="src" />
|
<file name="pathfn.hpp" role="src" />
|
||||||
<file name="qopen.cpp" role="src" />
|
|
||||||
<file name="qopen.hpp" role="src" />
|
|
||||||
<file name="rar.cpp" role="src" />
|
<file name="rar.cpp" role="src" />
|
||||||
<file name="rar.hpp" role="src" />
|
<file name="rar.hpp" role="src" />
|
||||||
<file name="rardefs.hpp" role="src" />
|
<file name="rardefs.hpp" role="src" />
|
||||||
@@ -274,31 +237,11 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="rartypes.hpp" role="src" />
|
<file name="rartypes.hpp" role="src" />
|
||||||
<file name="rarvm.cpp" role="src" />
|
<file name="rarvm.cpp" role="src" />
|
||||||
<file name="rarvm.hpp" role="src" />
|
<file name="rarvm.hpp" role="src" />
|
||||||
<file name="rawint.hpp" role="src" />
|
<file name="rarvmtbl.cpp" role="src" />
|
||||||
<file name="rawread.cpp" role="src" />
|
<file name="rawread.cpp" role="src" />
|
||||||
<file name="rawread.hpp" role="src" />
|
<file name="rawread.hpp" role="src" />
|
||||||
<file name="rdwrfn.cpp" role="src" />
|
<file name="rdwrfn.cpp" role="src" />
|
||||||
<file name="rdwrfn.hpp" role="src" />
|
<file name="rdwrfn.hpp" role="src" />
|
||||||
<file name="recvol3.cpp" role="src" />
|
|
||||||
<file name="recvol5.cpp" role="src" />
|
|
||||||
<file name="rs16.cpp" role="src" />
|
|
||||||
<file name="rs16.hpp" role="src" />
|
|
||||||
<file name="sha256.cpp" role="src" />
|
|
||||||
<file name="sha256.hpp" role="src" />
|
|
||||||
<file name="threadmisc.cpp" role="src" />
|
|
||||||
<file name="threadpool.cpp" role="src" />
|
|
||||||
<file name="threadpool.hpp" role="src" />
|
|
||||||
<file name="ui.cpp" role="src" />
|
|
||||||
<file name="ui.hpp" role="src" />
|
|
||||||
<file name="uicommon.cpp" role="src" />
|
|
||||||
<file name="uiconsole.cpp" role="src" />
|
|
||||||
<file name="uisilent.cpp" role="src" />
|
|
||||||
<file name="unpack30.cpp" role="src" />
|
|
||||||
<file name="unpack50.cpp" role="src" />
|
|
||||||
<file name="unpack50frag.cpp" role="src" />
|
|
||||||
<file name="unpack50mt.cpp" role="src" />
|
|
||||||
<file name="unpackinline.cpp" role="src" />
|
|
||||||
<file name="win32lnk.cpp" role="src" />
|
|
||||||
<file name="README.txt" role="doc" />
|
<file name="README.txt" role="doc" />
|
||||||
<file name="recvol.cpp" role="src" />
|
<file name="recvol.cpp" role="src" />
|
||||||
<file name="recvol.hpp" role="src" />
|
<file name="recvol.hpp" role="src" />
|
||||||
@@ -308,6 +251,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="rijndael.hpp" role="src" />
|
<file name="rijndael.hpp" role="src" />
|
||||||
<file name="rs.cpp" role="src" />
|
<file name="rs.cpp" role="src" />
|
||||||
<file name="rs.hpp" role="src" />
|
<file name="rs.hpp" role="src" />
|
||||||
|
<file name="savepos.cpp" role="src" />
|
||||||
|
<file name="savepos.hpp" role="src" />
|
||||||
<file name="scantree.cpp" role="src" />
|
<file name="scantree.cpp" role="src" />
|
||||||
<file name="scantree.hpp" role="src" />
|
<file name="scantree.hpp" role="src" />
|
||||||
<file name="secpassword.cpp" role="src" />
|
<file name="secpassword.cpp" role="src" />
|
||||||
@@ -327,8 +272,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="timefn.cpp" role="src" />
|
<file name="timefn.cpp" role="src" />
|
||||||
<file name="timefn.hpp" role="src" />
|
<file name="timefn.hpp" role="src" />
|
||||||
<file name="ulinks.cpp" role="src" />
|
<file name="ulinks.cpp" role="src" />
|
||||||
|
<file name="ulinks.hpp" role="src" />
|
||||||
<file name="unicode.cpp" role="src" />
|
<file name="unicode.cpp" role="src" />
|
||||||
<file name="unicode.hpp" role="src" />
|
<file name="unicode.hpp" role="src" />
|
||||||
|
<file name="unios2.cpp" role="src" />
|
||||||
<file name="unpack.cpp" role="src" />
|
<file name="unpack.cpp" role="src" />
|
||||||
<file name="unpack.hpp" role="src" />
|
<file name="unpack.hpp" role="src" />
|
||||||
<file name="unpack15.cpp" role="src" />
|
<file name="unpack15.cpp" role="src" />
|
||||||
@@ -344,18 +291,14 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<file name="config.w32" role="src" />
|
<file name="config.w32" role="src" />
|
||||||
<file name="CREDITS" role="doc" />
|
<file name="CREDITS" role="doc" />
|
||||||
<file name="LICENSE" role="doc" />
|
<file name="LICENSE" role="doc" />
|
||||||
<file name="Makefile.frag" role="src" />
|
<file name="README" role="doc" />
|
||||||
<file name="README.md" role="doc" />
|
|
||||||
<file name="example.php" role="doc" />
|
<file name="example.php" role="doc" />
|
||||||
<file name="php_compat.h" role="src" />
|
|
||||||
<file name="php_rar.h" role="src" />
|
<file name="php_rar.h" role="src" />
|
||||||
<file name="rar.c" role="src" />
|
<file name="rar.c" role="src" />
|
||||||
<file name="rar_stream.c" role="src" />
|
<file name="rar_stream.c" role="src" />
|
||||||
<file name="rararch.c" role="src" />
|
<file name="rararch.c" role="src" />
|
||||||
<file name="rarentry.c" role="src" />
|
<file name="rarentry.c" role="src" />
|
||||||
<file name="rar_error.c" role="src" />
|
<file name="rar_error.c" role="src" />
|
||||||
<file name="rar_time.c" role="src" />
|
|
||||||
<file name="run-tests-rar.php" role="test" />
|
|
||||||
<file role="src" name="rar_navigation.c"/>
|
<file role="src" name="rar_navigation.c"/>
|
||||||
</dir> <!-- / -->
|
</dir> <!-- / -->
|
||||||
</contents>
|
</contents>
|
||||||
@@ -363,7 +306,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<required>
|
<required>
|
||||||
<php>
|
<php>
|
||||||
<min>7.0.0</min>
|
<min>5.2.0</min>
|
||||||
</php>
|
</php>
|
||||||
<pearinstaller>
|
<pearinstaller>
|
||||||
<min>1.4.0</min>
|
<min>1.4.0</min>
|
||||||
@@ -374,112 +317,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
|||||||
<providesextension>rar</providesextension>
|
<providesextension>rar</providesextension>
|
||||||
|
|
||||||
<extsrcrelease />
|
<extsrcrelease />
|
||||||
|
|
||||||
<changelog>
|
<changelog>
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>4.3.1</release>
|
|
||||||
<api>4.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2026-03-15</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Fix bug #75557: error opening archive with non-English characters in path on Windows.
|
|
||||||
- Do not build unconditionally against listdc++.
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>4.3.0</release>
|
|
||||||
<api>4.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2026-03-08</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Add PHP 8.1, 8.2, 8.3 support.
|
|
||||||
- Drop PHP 5 support; minimum PHP version is now 7.0.
|
|
||||||
- Update bundled unrar to 7.2.4.
|
|
||||||
- Fix segfault caused by uninitialized RARHeaderDataEx.
|
|
||||||
- Fix dll.cpp: don't propagate non-fatal ErrHandler errors as failures.
|
|
||||||
- Fix RAR5 chunk extraction spurious warning on Windows with multi-core CPUs.
|
|
||||||
- Migrate CI from Azure Pipelines/Appveyor to GitHub Actions.
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>4.2.0</release>
|
|
||||||
<api>4.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2020-12-06</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Support PHP 8.
|
|
||||||
- Merge unrar 6.0.2.
|
|
||||||
- RarArchive implements IteratorAggregate (PHP 8 only).
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>4.1.0</release>
|
|
||||||
<api>4.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2020-10-11</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Merge changes made to unrar up to version 5.5.6.
|
|
||||||
- Support PHP 7.2, PHP 7.3 and PHP 7.4.
|
|
||||||
- Update to unrar 5.9.4.
|
|
||||||
- Fix bug #76592: streaming unpacking of uncompressed files incomplete.
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>4.0.0</release>
|
|
||||||
<api>4.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2017-07-22</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Added functions RarEntry::getRedirType(), RarEntry::isRedirectToDirectory() and RarEntry::getRedirTarget(), as well as the following constants on RarEntry: FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION, FSREDIR_HARDLINK and FSREDIR_FILECOPY.
|
|
||||||
- Changed stat handler to return UTC time for creation, modification and access time (does not work reliably on Windows).
|
|
||||||
- Fix cloning of RarArchive being allowed.
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
|
||||||
<version>
|
|
||||||
<release>3.0.2</release>
|
|
||||||
<api>3.0.0</api>
|
|
||||||
</version>
|
|
||||||
<stability>
|
|
||||||
<release>stable</release>
|
|
||||||
<api>stable</api>
|
|
||||||
</stability>
|
|
||||||
<date>2013-10-11</date>
|
|
||||||
<notes>Changes in this version:
|
|
||||||
- Fixed build with PHP 5.5.
|
|
||||||
- Upgraded bundled unrar to version 4.2.4.
|
|
||||||
</notes>
|
|
||||||
</release>
|
|
||||||
|
|
||||||
<release>
|
<release>
|
||||||
<version>
|
<version>
|
||||||
<release>3.0.1</release>
|
<release>3.0.1</release>
|
||||||
@@ -567,7 +406,7 @@ Other changes:
|
|||||||
- A lot of refactoring and compilation as C, not C++.
|
- A lot of refactoring and compilation as C, not C++.
|
||||||
</notes>
|
</notes>
|
||||||
</release>
|
</release>
|
||||||
|
|
||||||
<release>
|
<release>
|
||||||
<version>
|
<version>
|
||||||
<release>1.0.0</release>
|
<release>1.0.0</release>
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
// Add predefined macros for your project here. For example:
|
|
||||||
// #define THE_ANSWER 42
|
|
||||||
#define RARDLL 1
|
|
||||||
#define HAVE_CONFIG_H 1
|
|
||||||
#define _Float32 float
|
|
||||||
#define _Float32x float
|
|
||||||
#define _Float64 double
|
|
||||||
#define _Float64x double
|
|
||||||
#define _Float128 long double
|
|
||||||
#define _Float128x long double
|
|
||||||
#define _BITS_FLOATN_H
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[General]
|
|
||||||
-161
@@ -1,161 +0,0 @@
|
|||||||
config.h
|
|
||||||
php_compat.h
|
|
||||||
php_compat.h
|
|
||||||
php_rar.h
|
|
||||||
rar.c
|
|
||||||
rar_error.c
|
|
||||||
rar_navigation.c
|
|
||||||
rar_stream.c
|
|
||||||
rar_time.c
|
|
||||||
rararch.c
|
|
||||||
rarentry.c
|
|
||||||
unrar/arccmt.cpp
|
|
||||||
unrar/archive.cpp
|
|
||||||
unrar/archive.hpp
|
|
||||||
unrar/arcread.cpp
|
|
||||||
unrar/array.hpp
|
|
||||||
unrar/blake2s.cpp
|
|
||||||
unrar/blake2s.hpp
|
|
||||||
unrar/blake2s_sse.cpp
|
|
||||||
unrar/blake2sp.cpp
|
|
||||||
unrar/cmddata.cpp
|
|
||||||
unrar/cmddata.hpp
|
|
||||||
unrar/cmdfilter.cpp
|
|
||||||
unrar/cmdmix.cpp
|
|
||||||
unrar/coder.cpp
|
|
||||||
unrar/coder.hpp
|
|
||||||
unrar/compress.hpp
|
|
||||||
unrar/consio.cpp
|
|
||||||
unrar/consio.hpp
|
|
||||||
unrar/crc.cpp
|
|
||||||
unrar/crc.hpp
|
|
||||||
unrar/crypt.cpp
|
|
||||||
unrar/crypt.hpp
|
|
||||||
unrar/crypt1.cpp
|
|
||||||
unrar/crypt2.cpp
|
|
||||||
unrar/crypt3.cpp
|
|
||||||
unrar/crypt5.cpp
|
|
||||||
unrar/dll.cpp
|
|
||||||
unrar/dll.hpp
|
|
||||||
unrar/encname.cpp
|
|
||||||
unrar/encname.hpp
|
|
||||||
unrar/errhnd.cpp
|
|
||||||
unrar/errhnd.hpp
|
|
||||||
unrar/extinfo.cpp
|
|
||||||
unrar/extinfo.hpp
|
|
||||||
unrar/extract.cpp
|
|
||||||
unrar/extract.hpp
|
|
||||||
unrar/extractchunk.cpp
|
|
||||||
unrar/filcreat.cpp
|
|
||||||
unrar/filcreat.hpp
|
|
||||||
unrar/file.cpp
|
|
||||||
unrar/file.hpp
|
|
||||||
unrar/filefn.cpp
|
|
||||||
unrar/filefn.hpp
|
|
||||||
unrar/filestr.cpp
|
|
||||||
unrar/filestr.hpp
|
|
||||||
unrar/find.cpp
|
|
||||||
unrar/find.hpp
|
|
||||||
unrar/getbits.cpp
|
|
||||||
unrar/getbits.hpp
|
|
||||||
unrar/global.cpp
|
|
||||||
unrar/global.hpp
|
|
||||||
unrar/hardlinks.cpp
|
|
||||||
unrar/hash.cpp
|
|
||||||
unrar/hash.hpp
|
|
||||||
unrar/headers.cpp
|
|
||||||
unrar/headers.hpp
|
|
||||||
unrar/headers5.hpp
|
|
||||||
unrar/isnt.cpp
|
|
||||||
unrar/isnt.hpp
|
|
||||||
unrar/list.cpp
|
|
||||||
unrar/list.hpp
|
|
||||||
unrar/loclang.hpp
|
|
||||||
unrar/log.cpp
|
|
||||||
unrar/log.hpp
|
|
||||||
unrar/match.cpp
|
|
||||||
unrar/match.hpp
|
|
||||||
unrar/model.cpp
|
|
||||||
unrar/model.hpp
|
|
||||||
unrar/options.cpp
|
|
||||||
unrar/options.hpp
|
|
||||||
unrar/os.hpp
|
|
||||||
unrar/pathfn.cpp
|
|
||||||
unrar/pathfn.hpp
|
|
||||||
unrar/qopen.cpp
|
|
||||||
unrar/qopen.hpp
|
|
||||||
unrar/rar.cpp
|
|
||||||
unrar/rar.hpp
|
|
||||||
unrar/rardefs.hpp
|
|
||||||
unrar/rarlang.hpp
|
|
||||||
unrar/raros.hpp
|
|
||||||
unrar/rartypes.hpp
|
|
||||||
unrar/rarvm.cpp
|
|
||||||
unrar/rarvm.hpp
|
|
||||||
unrar/rarvmtbl.cpp
|
|
||||||
unrar/rawint.hpp
|
|
||||||
unrar/rawread.cpp
|
|
||||||
unrar/rawread.hpp
|
|
||||||
unrar/rdwrfn.cpp
|
|
||||||
unrar/rdwrfn.hpp
|
|
||||||
unrar/recvol.cpp
|
|
||||||
unrar/recvol.hpp
|
|
||||||
unrar/recvol3.cpp
|
|
||||||
unrar/recvol5.cpp
|
|
||||||
unrar/resource.cpp
|
|
||||||
unrar/resource.hpp
|
|
||||||
unrar/rijndael.cpp
|
|
||||||
unrar/rijndael.hpp
|
|
||||||
unrar/rs.cpp
|
|
||||||
unrar/rs.hpp
|
|
||||||
unrar/rs16.cpp
|
|
||||||
unrar/rs16.hpp
|
|
||||||
unrar/savepos.hpp
|
|
||||||
unrar/scantree.cpp
|
|
||||||
unrar/scantree.hpp
|
|
||||||
unrar/secpassword.cpp
|
|
||||||
unrar/secpassword.hpp
|
|
||||||
unrar/sha1.cpp
|
|
||||||
unrar/sha1.hpp
|
|
||||||
unrar/sha256.cpp
|
|
||||||
unrar/sha256.hpp
|
|
||||||
unrar/smallfn.cpp
|
|
||||||
unrar/smallfn.hpp
|
|
||||||
unrar/strfn.cpp
|
|
||||||
unrar/strfn.hpp
|
|
||||||
unrar/strlist.cpp
|
|
||||||
unrar/strlist.hpp
|
|
||||||
unrar/suballoc.cpp
|
|
||||||
unrar/suballoc.hpp
|
|
||||||
unrar/system.cpp
|
|
||||||
unrar/system.hpp
|
|
||||||
unrar/threadmisc.cpp
|
|
||||||
unrar/threadpool.cpp
|
|
||||||
unrar/threadpool.hpp
|
|
||||||
unrar/timefn.cpp
|
|
||||||
unrar/timefn.hpp
|
|
||||||
unrar/ui.cpp
|
|
||||||
unrar/ui.hpp
|
|
||||||
unrar/uicommon.cpp
|
|
||||||
unrar/uiconsole.cpp
|
|
||||||
unrar/uisilent.cpp
|
|
||||||
unrar/ulinks.cpp
|
|
||||||
unrar/ulinks.hpp
|
|
||||||
unrar/unicode.cpp
|
|
||||||
unrar/unicode.hpp
|
|
||||||
unrar/unpack.cpp
|
|
||||||
unrar/unpack.hpp
|
|
||||||
unrar/unpack15.cpp
|
|
||||||
unrar/unpack20.cpp
|
|
||||||
unrar/unpack30.cpp
|
|
||||||
unrar/unpack50.cpp
|
|
||||||
unrar/unpack50frag.cpp
|
|
||||||
unrar/unpack50mt.cpp
|
|
||||||
unrar/unpackinline.cpp
|
|
||||||
unrar/uowners.cpp
|
|
||||||
unrar/version.hpp
|
|
||||||
unrar/volume.cpp
|
|
||||||
unrar/volume.hpp
|
|
||||||
unrar/win32acl.cpp
|
|
||||||
unrar/win32lnk.cpp
|
|
||||||
unrar/win32stm.cpp
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/home/glopes/repos/php-src/Zend
|
|
||||||
/home/glopes/repos/php-src/TSRM
|
|
||||||
/home/glopes/repos/php-src/main
|
|
||||||
/home/glopes/repos/php-src
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#include <php.h>
|
|
||||||
|
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
|
||||||
# define TSRMLS_DC
|
|
||||||
# define TSRMLS_D
|
|
||||||
# define TSRMLS_CC
|
|
||||||
# define TSRMLS_C
|
|
||||||
# define TSRMLS_FETCH()
|
|
||||||
# define IS_CALLABLE_STRICT 0
|
|
||||||
# define zend_qsort zend_sort
|
|
||||||
# define ZV_TO_THIS_FOR_HANDLER(zv) (Z_OBJ_P(zv))
|
|
||||||
typedef zend_object handler_this_t;
|
|
||||||
#else
|
|
||||||
# define ZV_TO_THIS_FOR_HANDLER(zv) (zv)
|
|
||||||
typedef zval handler_this_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef zend_object* rar_obj_ref;
|
|
||||||
|
|
||||||
#define rar_zval_add_ref(ppzv) zval_add_ref(*ppzv)
|
|
||||||
|
|
||||||
#define ZVAL_ALLOC_DUP(dst, src) \
|
|
||||||
do { \
|
|
||||||
dst = (zval*) emalloc(sizeof(zval)); \
|
|
||||||
ZVAL_DUP(dst, src); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define RAR_RETURN_STRINGL(s, l, duplicate) \
|
|
||||||
do { \
|
|
||||||
RETVAL_STRINGL(s, l); \
|
|
||||||
if (duplicate == 0) { \
|
|
||||||
efree(s); \
|
|
||||||
} \
|
|
||||||
return; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define RAR_ZVAL_STRING(z, s, duplicate) \
|
|
||||||
do { \
|
|
||||||
ZVAL_STRING(z, s); \
|
|
||||||
if (duplicate == 0) { \
|
|
||||||
efree(s); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
typedef size_t zpp_s_size_t;
|
|
||||||
|
|
||||||
#define MAKE_STD_ZVAL(zv_p) \
|
|
||||||
do { \
|
|
||||||
(zv_p) = emalloc(sizeof(zval)); \
|
|
||||||
ZVAL_NULL(zv_p); \
|
|
||||||
} while (0)
|
|
||||||
#define INIT_ZVAL(zv) ZVAL_UNDEF(&zv)
|
|
||||||
|
|
||||||
#define ZEND_ACC_FINAL_CLASS ZEND_ACC_FINAL
|
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
extern zend_module_entry rar_module_entry;
|
extern zend_module_entry rar_module_entry;
|
||||||
#define phpext_rar_ptr &rar_module_entry
|
#define phpext_rar_ptr &rar_module_entry
|
||||||
|
|
||||||
#define PHP_RAR_VERSION "4.3.2-dev"
|
#define PHP_RAR_VERSION "4.0.0"
|
||||||
|
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
#define PHP_RAR_API __declspec(dllexport)
|
#define PHP_RAR_API __declspec(dllexport)
|
||||||
@@ -63,8 +63,6 @@ extern zend_module_entry rar_module_entry;
|
|||||||
#include "TSRM.h"
|
#include "TSRM.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "php_compat.h"
|
|
||||||
|
|
||||||
/* causes linking errors (multiple definitions) in functions
|
/* causes linking errors (multiple definitions) in functions
|
||||||
that were requested inlining but were not inlined by the compiler */
|
that were requested inlining but were not inlined by the compiler */
|
||||||
/* #include "unrar/rar.hpp */
|
/* #include "unrar/rar.hpp */
|
||||||
@@ -77,7 +75,6 @@ extern zend_module_entry rar_module_entry;
|
|||||||
#include "unrar/dll.hpp"
|
#include "unrar/dll.hpp"
|
||||||
#include "unrar/version.hpp"
|
#include "unrar/version.hpp"
|
||||||
/* These are in unrar/headers.hpp, but that header depends on several other */
|
/* These are in unrar/headers.hpp, but that header depends on several other */
|
||||||
/* clang-format off */
|
|
||||||
enum HOST_SYSTEM {
|
enum HOST_SYSTEM {
|
||||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||||
HOST_BEOS=5,HOST_MAX
|
HOST_BEOS=5,HOST_MAX
|
||||||
@@ -86,12 +83,67 @@ enum FILE_SYSTEM_REDIRECT {
|
|||||||
FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION,
|
FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION,
|
||||||
FSREDIR_HARDLINK, FSREDIR_FILECOPY
|
FSREDIR_HARDLINK, FSREDIR_FILECOPY
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/* maximum comment size if 64KB */
|
/* maximum comment size if 64KB */
|
||||||
#define RAR_MAX_COMMENT_SIZE 65536
|
#define RAR_MAX_COMMENT_SIZE 65536
|
||||||
|
|
||||||
/* clang-format off */
|
/* PHP 7+ abstraction */
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
|
typedef zend_object* rar_obj_ref;
|
||||||
|
|
||||||
|
#define rar_zval_add_ref(ppzv) zval_add_ref(*ppzv)
|
||||||
|
|
||||||
|
#define ZVAL_ALLOC_DUP(dst, src) \
|
||||||
|
do { \
|
||||||
|
dst = (zval*) emalloc(sizeof(zval)); \
|
||||||
|
ZVAL_DUP(dst, src); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define RAR_RETURN_STRINGL(s, l, duplicate) \
|
||||||
|
do { \
|
||||||
|
RETVAL_STRINGL(s, l); \
|
||||||
|
if (duplicate == 0) { \
|
||||||
|
efree(s); \
|
||||||
|
} \
|
||||||
|
return; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define RAR_ZVAL_STRING(z, s, duplicate) \
|
||||||
|
do { \
|
||||||
|
ZVAL_STRING(z, s); \
|
||||||
|
if (duplicate == 0) { \
|
||||||
|
efree(s); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
typedef size_t zpp_s_size_t;
|
||||||
|
|
||||||
|
#define MAKE_STD_ZVAL(zv_p) \
|
||||||
|
do { \
|
||||||
|
(zv_p) = emalloc(sizeof(zval)); \
|
||||||
|
ZVAL_NULL(zv_p); \
|
||||||
|
} while (0)
|
||||||
|
#define INIT_ZVAL(zv) ZVAL_UNDEF(&zv)
|
||||||
|
|
||||||
|
#define ZEND_ACC_FINAL_CLASS ZEND_ACC_FINAL
|
||||||
|
|
||||||
|
#else /* PHP 5.x */
|
||||||
|
typedef zend_object_handle rar_obj_ref;
|
||||||
|
|
||||||
|
#define rar_zval_add_ref zval_add_ref
|
||||||
|
#define ZVAL_ALLOC_DUP(dst, src) \
|
||||||
|
do { \
|
||||||
|
zval *z_src = src; \
|
||||||
|
dst = z_src; \
|
||||||
|
zval_add_ref(&dst); \
|
||||||
|
SEPARATE_ZVAL(&dst); \
|
||||||
|
} while (0)
|
||||||
|
#define RAR_ZVAL_STRING ZVAL_STRING
|
||||||
|
#define RAR_RETURN_STRINGL(s, l, duplicate) RETURN_STRINGL(s, l, duplicate)
|
||||||
|
typedef int zpp_s_size_t;
|
||||||
|
#define zend_hash_str_del zend_hash_del
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _rar_cb_user_data {
|
typedef struct _rar_cb_user_data {
|
||||||
char *password; /* can be NULL */
|
char *password; /* can be NULL */
|
||||||
zval *callable; /* can be NULL */
|
zval *callable; /* can be NULL */
|
||||||
@@ -108,19 +160,13 @@ typedef struct rar {
|
|||||||
rar_cb_user_data cb_userdata;
|
rar_cb_user_data cb_userdata;
|
||||||
int allow_broken;
|
int allow_broken;
|
||||||
} rar_file_t;
|
} rar_file_t;
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
# if defined(__GNUC__) || defined(__clang__)
|
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||||
# define ARR_SIZE(arr) \
|
# define RAR_TSRMLS_TC , void ***
|
||||||
(sizeof(arr) / sizeof((arr)[0]) + \
|
#else
|
||||||
0 * sizeof(char[1 - 2 * __builtin_types_compatible_p( \
|
|
||||||
__typeof__(arr), __typeof__(&(arr)[0]))]))
|
|
||||||
# else
|
|
||||||
# define ARR_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define RAR_TSRMLS_TC
|
# define RAR_TSRMLS_TC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RAR_RETNULL_ON_ARGS() \
|
#define RAR_RETNULL_ON_ARGS() \
|
||||||
if (zend_parse_parameters_none() == FAILURE) { \
|
if (zend_parse_parameters_none() == FAILURE) { \
|
||||||
@@ -167,6 +213,33 @@ ZEND_EXTERN_MODULE_GLOBALS(rar);
|
|||||||
# define RAR_G(v) (rar_globals.v)
|
# define RAR_G(v) (rar_globals.v)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* PHP 5.2 compatibility */
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3
|
||||||
|
#define zend_parse_parameters_none() \
|
||||||
|
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")
|
||||||
|
#define Z_DELREF_P ZVAL_DELREF
|
||||||
|
# define STREAM_ASSUME_REALPATH 0
|
||||||
|
# define ALLOC_PERMANENT_ZVAL(z) \
|
||||||
|
(z) = (zval*) malloc(sizeof(zval));
|
||||||
|
# define OPENBASEDIR_CHECKPATH(filename) \
|
||||||
|
(PG(safe_mode) && \
|
||||||
|
(!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) \
|
||||||
|
|| php_check_open_basedir(filename TSRMLS_CC)
|
||||||
|
# undef ZEND_BEGIN_ARG_INFO_EX
|
||||||
|
# define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
|
||||||
|
static const zend_arg_info name[] = { \
|
||||||
|
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Other compatibility quirks */
|
||||||
|
/* PHP 5.3 doesn't have ZVAL_COPY_VALUE */
|
||||||
|
#if !defined(ZEND_COPY_VALUE) && PHP_MAJOR_VERSION == 5
|
||||||
|
#define ZVAL_COPY_VALUE(z, v) \
|
||||||
|
do { \
|
||||||
|
(z)->value = (v)->value; \
|
||||||
|
Z_TYPE_P(z) = Z_TYPE_P(v); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_STRNLEN) || !HAVE_STRNLEN
|
#if !defined(HAVE_STRNLEN) || !HAVE_STRNLEN
|
||||||
size_t _rar_strnlen(const char *s, size_t maxlen);
|
size_t _rar_strnlen(const char *s, size_t maxlen);
|
||||||
@@ -230,7 +303,7 @@ typedef struct _rar_find_output {
|
|||||||
int found;
|
int found;
|
||||||
size_t position;
|
size_t position;
|
||||||
struct RARHeaderDataEx * header;
|
struct RARHeaderDataEx * header;
|
||||||
zend_ulong packed_size;
|
unsigned long packed_size;
|
||||||
int eof;
|
int eof;
|
||||||
} rar_find_output;
|
} rar_find_output;
|
||||||
#define RAR_SEARCH_INDEX 0x01U
|
#define RAR_SEARCH_INDEX 0x01U
|
||||||
@@ -260,9 +333,8 @@ void _rar_close_file_resource(rar_file_t *rar);
|
|||||||
/* Fetches the rar_file_t part of the RarArchive object in order to use the
|
/* Fetches the rar_file_t part of the RarArchive object in order to use the
|
||||||
* operations above and (discouraged) to have direct access to the fields
|
* operations above and (discouraged) to have direct access to the fields
|
||||||
* RarEntry::extract/getStream access extract_open_dat and cb_userdata */
|
* RarEntry::extract/getStream access extract_open_dat and cb_userdata */
|
||||||
int _rar_get_file_resource_zv(zval *zv_file, rar_file_t **rar_file TSRMLS_DC);
|
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC);
|
||||||
int _rar_get_file_resource_zv_ex(zval *zv_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
||||||
int _rar_get_file_resource_ex(rar_obj_ref objref_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
|
||||||
void minit_rararch(TSRMLS_D);
|
void minit_rararch(TSRMLS_D);
|
||||||
|
|
||||||
PHP_FUNCTION(rar_open);
|
PHP_FUNCTION(rar_open);
|
||||||
@@ -279,7 +351,7 @@ extern zend_class_entry *rar_class_entry_ptr;
|
|||||||
void minit_rarentry(TSRMLS_D);
|
void minit_rarentry(TSRMLS_D);
|
||||||
void _rar_entry_to_zval(zval *parent,
|
void _rar_entry_to_zval(zval *parent,
|
||||||
struct RARHeaderDataEx *entry,
|
struct RARHeaderDataEx *entry,
|
||||||
zend_ulong packed_size,
|
unsigned long packed_size,
|
||||||
size_t index,
|
size_t index,
|
||||||
zval *entry_object TSRMLS_DC);
|
zval *entry_object TSRMLS_DC);
|
||||||
|
|
||||||
@@ -290,12 +362,6 @@ php_stream *php_stream_rar_open(char *arc_name,
|
|||||||
STREAMS_DC TSRMLS_DC);
|
STREAMS_DC TSRMLS_DC);
|
||||||
extern php_stream_wrapper php_stream_rar_wrapper;
|
extern php_stream_wrapper php_stream_rar_wrapper;
|
||||||
|
|
||||||
/* rar_time.c */
|
|
||||||
void rar_time_convert(unsigned low, unsigned high, time_t *to);
|
|
||||||
int rar_dos_time_convert(unsigned dos_time, time_t *to);
|
|
||||||
#ifdef PHP_WIN32
|
|
||||||
#define timegm _mkgmtime
|
|
||||||
#endif
|
|
||||||
#endif /* PHP_RAR_H */
|
#endif /* PHP_RAR_H */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-189
@@ -1,189 +0,0 @@
|
|||||||
# PHP 8.1–8.5 Upgrade Procedure for php-rar
|
|
||||||
|
|
||||||
This document describes the step-by-step procedure to extend php-rar support
|
|
||||||
from PHP 8.0 to PHP 8.5. Each minor version is handled independently: CI is
|
|
||||||
wired up, the extension is compiled and tested inside the matching Docker image,
|
|
||||||
code changes are applied to fix any failures, and only then is the next version
|
|
||||||
tackled.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Overview of files touched per version
|
|
||||||
|
|
||||||
| File | Change |
|
|
||||||
|---|---|
|
|
||||||
| `.github/docker-image-shas.yml` | Add new tag → SHA entries |
|
|
||||||
| `.github/scripts/update-docker-shas.sh` | Add new tags to the `TAGS` array |
|
|
||||||
| `Justfile` | Add image variables and `test-X_Y-*` targets |
|
|
||||||
| `*.c` / `*.h` | C source changes for API compatibility |
|
|
||||||
| `.github/workflows/tests.yml` | Windows job — update `php-version` (once per bump) |
|
|
||||||
|
|
||||||
The Linux CI matrix is generated automatically from `docker-image-shas.yml`, so
|
|
||||||
no manual edit to `tests.yml` is needed for Linux jobs.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Repeatable procedure for each version
|
|
||||||
|
|
||||||
Follow these numbered steps for **each** minor version in order. Example:
|
|
||||||
8.0 → 8.1 → 8.2 → 8.3 → 8.4 → 8.5.
|
|
||||||
|
|
||||||
### Step 1 — Read the upgrade guides in php-src
|
|
||||||
|
|
||||||
Clone or browse php-src on the target branch, e.g. `PHP-8.1`:
|
|
||||||
|
|
||||||
```
|
|
||||||
https://github.com/php/php-src/blob/PHP-8.X/UPGRADING
|
|
||||||
https://github.com/php/php-src/blob/PHP-8.X/UPGRADING.INTERNALS
|
|
||||||
```
|
|
||||||
|
|
||||||
Focus on sections relevant to C extensions:
|
|
||||||
- Removed or renamed macros / functions
|
|
||||||
- Changed return types (`int` → `zend_result`)
|
|
||||||
- Changed struct member types
|
|
||||||
- New mandatory includes
|
|
||||||
- Any other backwards-incompatible changes
|
|
||||||
|
|
||||||
The per-version notes below summarise the items relevant to php-rar.
|
|
||||||
|
|
||||||
### Step 2 — Add the Docker image SHA
|
|
||||||
|
|
||||||
Fetch the OCI index digest from Docker Hub for the two new tags:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Quick one-liner — prints the index digest for a given tag
|
|
||||||
curl -fsSL "https://hub.docker.com/v2/repositories/datadog/dd-appsec-php-ci/tags/php-X.Y-debug" \
|
|
||||||
| python3 -c "import sys,json; print(json.load(sys.stdin)['digest'])"
|
|
||||||
```
|
|
||||||
|
|
||||||
Or regenerate everything at once with the provided script after adding the new
|
|
||||||
tags to it (see Step 3):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.github/scripts/update-docker-shas.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Append the two lines to `.github/docker-image-shas.yml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
php-X.Y-debug: "sha256:<INDEX-DIGEST>"
|
|
||||||
php-X.Y-release-zts: "sha256:<INDEX-DIGEST>"
|
|
||||||
```
|
|
||||||
|
|
||||||
Also add both tags to the `TAGS` array in `.github/scripts/update-docker-shas.sh`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
TAGS=(
|
|
||||||
...existing tags...
|
|
||||||
php-X.Y-debug php-X.Y-release-zts
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3 — Add Justfile targets
|
|
||||||
|
|
||||||
Add image variables and `test-X_Y-*` targets following the existing pattern:
|
|
||||||
|
|
||||||
```just
|
|
||||||
image_X_Y_debug := _base + `grep 'php-X.Y-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
image_X_Y_release_zts := _base + `grep 'php-X.Y-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
|
||||||
|
|
||||||
test-X_Y-debug:
|
|
||||||
{{_run}} {{image_X_Y_debug}} .github/scripts/build-and-test.sh
|
|
||||||
test-X_Y-release-zts:
|
|
||||||
{{_run}} {{image_X_Y_release_zts}} .github/scripts/build-and-test.sh
|
|
||||||
|
|
||||||
test-X_Y: test-X_Y-debug test-X_Y-release-zts
|
|
||||||
```
|
|
||||||
|
|
||||||
Add `test-X_Y` to the `test-linux` aggregate at the bottom.
|
|
||||||
|
|
||||||
### Step 4 — Compile and test
|
|
||||||
|
|
||||||
Run both variants locally before pushing:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
just test-X_Y-debug
|
|
||||||
just test-X_Y-release-zts
|
|
||||||
```
|
|
||||||
|
|
||||||
Or both together:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
just test-X_Y
|
|
||||||
```
|
|
||||||
|
|
||||||
Examine the output for compiler warnings, errors, and test failures.
|
|
||||||
|
|
||||||
### Step 5 — Apply C source changes
|
|
||||||
|
|
||||||
Based on the compilation output and the per-version notes below, make the
|
|
||||||
minimum necessary changes to `.c`/`.h` files. Guard every change with `#if
|
|
||||||
PHP_VERSION_ID >= XXYY00` so that older PHP versions continue to work.
|
|
||||||
|
|
||||||
### Step 6 — Re-run tests until green
|
|
||||||
|
|
||||||
Repeat Step 4 after each change. When both `debug` and `release-zts` pass,
|
|
||||||
commit.
|
|
||||||
|
|
||||||
### Step 7 — Push and verify CI
|
|
||||||
|
|
||||||
Push the branch. The `linux` CI job matrix is auto-built from
|
|
||||||
`docker-image-shas.yml` — the new versions appear automatically. Verify the
|
|
||||||
GitHub Actions run is green for all new jobs.
|
|
||||||
|
|
||||||
### Step 8 — Update Windows CI (optional, once per bump)
|
|
||||||
|
|
||||||
The Windows job in `.github/workflows/tests.yml` pins a specific PHP version.
|
|
||||||
Update it when the Linux jobs for the matching version are confirmed green:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: Build and test
|
|
||||||
uses: php/php-windows-builder/extension@v1
|
|
||||||
with:
|
|
||||||
php-version: 'X.Y' # ← change here
|
|
||||||
```
|
|
||||||
|
|
||||||
Also update the `name:` and artifact `name:` strings in the same Windows job
|
|
||||||
block.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Current Docker image SHAs (as of 2026-03-01)
|
|
||||||
|
|
||||||
These are the OCI index digests (multi-arch: amd64 + arm64) to use in
|
|
||||||
`docker-image-shas.yml`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
php-8.1-debug: "sha256:1a1e5b44cf043e59768c65fd7c94aaefdacde5fa96d83102d35db11ad86f24c6"
|
|
||||||
php-8.1-release-zts: "sha256:5b8a269b4228d9191420059daef820b660110be0aca6776557924172fd1ff0c8"
|
|
||||||
php-8.2-debug: "sha256:52ad14560672fc8c5130f5758bbee3fa401bc1d35b412f4a230c6258143291a5"
|
|
||||||
php-8.2-release-zts: "sha256:cb143d915b394f16a2d78018765705460f3d1b788fdd2a90ef50fad5f8f5918c"
|
|
||||||
php-8.3-debug: "sha256:bb6df08160126374d3d9247428928aa19a9c2b2429c98356650199b85ae20212"
|
|
||||||
php-8.3-release-zts: "sha256:e58e25a017f75df82691d408b8cb70453875ff36718e295ee8c6653a0f117331"
|
|
||||||
php-8.4-debug: "sha256:15045688f6986f4625b1507a7f4be6104e7bbb88caf877f1611463b929f2bca2"
|
|
||||||
php-8.4-release-zts: "sha256:8e0ac25a3306b4b9f692c593b8a509cc789c2e001ce52682928065a92c880136"
|
|
||||||
php-8.5-debug: "sha256:bd0170331b34fb469e29d00b19b20fb88b726160f76df274a1bdc3a27ac18d30"
|
|
||||||
php-8.5-release-zts: "sha256:e071b2095da55bd24686209422f43a01c65acfc6021f04156d9fb43fd3d4d426"
|
|
||||||
```
|
|
||||||
|
|
||||||
Refresh at any time with `.github/scripts/update-docker-shas.sh` after adding
|
|
||||||
the new tags.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Summary checklist
|
|
||||||
|
|
||||||
For each version X.Y in order (8.1, 8.2, 8.3, 8.4, 8.5):
|
|
||||||
|
|
||||||
- [ ] Read `PHP-X.Y/UPGRADING.INTERNALS` on GitHub
|
|
||||||
- [ ] Add two SHA entries to `.github/docker-image-shas.yml`
|
|
||||||
- [ ] Add both tags to `TAGS` array in `.github/scripts/update-docker-shas.sh`
|
|
||||||
- [ ] Add `image_X_Y_*` variables and `test-X_Y-*` targets to `Justfile`
|
|
||||||
- [ ] Add `test-X_Y` to `test-linux` aggregate in `Justfile`
|
|
||||||
- [ ] Run `just test-X_Y` and fix all compilation errors
|
|
||||||
- [ ] Run `just test-X_Y` again; confirm all tests pass
|
|
||||||
- [ ] Commit infrastructure + code changes together
|
|
||||||
- [ ] Push; confirm GitHub Actions CI is green for the new matrix entries
|
|
||||||
- [ ] (Optional) Update Windows `php-version` in `.github/workflows/tests.yml` to X.Y
|
|
||||||
|
|
||||||
<!-- vim: set tw=80: -->
|
|
||||||
@@ -28,12 +28,14 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
#ifdef __cplusplus
|
||||||
# define _GNU_SOURCE
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
@@ -48,7 +50,7 @@
|
|||||||
#include <ext/standard/info.h>
|
#include <ext/standard/info.h>
|
||||||
#include <ext/spl/spl_exceptions.h>
|
#include <ext/spl/spl_exceptions.h>
|
||||||
|
|
||||||
#include "unrar/rardefs.hpp"
|
#if HAVE_RAR
|
||||||
|
|
||||||
#include "php_rar.h"
|
#include "php_rar.h"
|
||||||
|
|
||||||
@@ -159,8 +161,12 @@ void _rar_destroy_userdata(rar_cb_user_data *udata) /* {{{ */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (udata->callable != NULL) {
|
if (udata->callable != NULL) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_ptr_dtor(&udata->callable);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(udata->callable);
|
zval_ptr_dtor(udata->callable);
|
||||||
efree(udata->callable);
|
efree(udata->callable);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
udata->password = NULL;
|
udata->password = NULL;
|
||||||
@@ -234,16 +240,13 @@ int _rar_find_file_w(struct RAROpenArchiveDataEx *open_data, /* IN */
|
|||||||
|
|
||||||
while ((result = RARReadHeaderEx(*arc_handle, used_header_data)) == 0) {
|
while ((result = RARReadHeaderEx(*arc_handle, used_header_data)) == 0) {
|
||||||
#if WCHAR_MAX > 0xffff
|
#if WCHAR_MAX > 0xffff
|
||||||
_rar_fix_wide(used_header_data->FileNameW,
|
_rar_fix_wide(used_header_data->FileNameW, NM);
|
||||||
ARR_SIZE(used_header_data->FileNameW));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (wcsncmp(used_header_data->FileNameW, file_name,
|
if (wcsncmp(used_header_data->FileNameW, file_name, NM) == 0) {
|
||||||
ARR_SIZE(used_header_data->FileNameW)) == 0) {
|
|
||||||
*found = TRUE;
|
*found = TRUE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
process_result = RARProcessFile(*arc_handle, RAR_SKIP, NULL, NULL);
|
process_result = RARProcessFile(*arc_handle, RAR_SKIP, NULL, NULL);
|
||||||
}
|
}
|
||||||
if (process_result != 0) {
|
if (process_result != 0) {
|
||||||
@@ -380,7 +383,6 @@ int CALLBACK _rar_unrar_callback(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: maybe support UCM_NEEDPASSWORDW and UCM_CHANGEVOLUMEW
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -423,7 +425,7 @@ PHP_FUNCTION(rar_wrapper_cache_stats) /* {{{ */
|
|||||||
static void _rar_fix_wide(wchar_t *str, size_t max_size) /* {{{ */
|
static void _rar_fix_wide(wchar_t *str, size_t max_size) /* {{{ */
|
||||||
{
|
{
|
||||||
wchar_t *write,
|
wchar_t *write,
|
||||||
*read,
|
*read,
|
||||||
*max_fin;
|
*max_fin;
|
||||||
max_fin = str + max_size;
|
max_fin = str + max_size;
|
||||||
for (write = str, read = str; *read != L'\0' && read != max_fin; read++) {
|
for (write = str, read = str; *read != L'\0' && read != max_fin; read++) {
|
||||||
@@ -440,37 +442,61 @@ static void _rar_fix_wide(wchar_t *str, size_t max_size) /* {{{ */
|
|||||||
* because, in case we're using exceptions, we want to let an exception with
|
* because, in case we're using exceptions, we want to let an exception with
|
||||||
* error code ERAR_EOPEN to be thrown.
|
* error code ERAR_EOPEN to be thrown.
|
||||||
*/
|
*/
|
||||||
static int _rar_unrar_volume_user_callback(char* dst_buffer, // MAXPATHSIZE
|
static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||||
zend_fcall_info *fci,
|
zend_fcall_info *fci,
|
||||||
zend_fcall_info_cache *cache
|
zend_fcall_info_cache *cache
|
||||||
TSRMLS_DC) /* {{{ */
|
TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval *failed_vol,
|
||||||
|
*retval_ptr = NULL,
|
||||||
|
**params;
|
||||||
|
#else
|
||||||
zval failed_vol,
|
zval failed_vol,
|
||||||
retval,
|
retval,
|
||||||
*params,
|
*params,
|
||||||
*const retval_ptr = &retval;
|
*const retval_ptr = &retval;
|
||||||
|
#endif
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
MAKE_STD_ZVAL(failed_vol);
|
||||||
|
RAR_ZVAL_STRING(failed_vol, dst_buffer, 1);
|
||||||
|
params = &failed_vol;
|
||||||
|
fci->retval_ptr_ptr = &retval_ptr;
|
||||||
|
fci->params = ¶ms;
|
||||||
|
#else
|
||||||
ZVAL_STRING(&failed_vol, dst_buffer);
|
ZVAL_STRING(&failed_vol, dst_buffer);
|
||||||
ZVAL_NULL(&retval);
|
ZVAL_NULL(&retval);
|
||||||
params = &failed_vol;
|
params = &failed_vol;
|
||||||
fci->retval = &retval;
|
fci->retval = &retval;
|
||||||
fci->params = params;
|
fci->params = params;
|
||||||
|
#endif
|
||||||
fci->param_count = 1;
|
fci->param_count = 1;
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
if (zend_call_function(fci, cache TSRMLS_CC) != SUCCESS ||
|
||||||
|
fci->retval_ptr_ptr == NULL ||
|
||||||
|
*fci->retval_ptr_ptr == NULL) {
|
||||||
|
#else
|
||||||
if (zend_call_function(fci, cache TSRMLS_CC) != SUCCESS || EG(exception)) {
|
if (zend_call_function(fci, cache TSRMLS_CC) != SUCCESS || EG(exception)) {
|
||||||
|
#endif
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Failure to call volume find callback");
|
"Failure to call volume find callback");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
assert(*fci->retval_ptr_ptr == retval_ptr);
|
||||||
|
#else
|
||||||
assert(fci->retval == &retval);
|
assert(fci->retval == &retval);
|
||||||
|
#endif
|
||||||
if (Z_TYPE_P(retval_ptr) == IS_NULL) {
|
if (Z_TYPE_P(retval_ptr) == IS_NULL) {
|
||||||
/* let return -1 */
|
/* let return -1 */
|
||||||
}
|
}
|
||||||
else if (Z_TYPE_P(retval_ptr) == IS_STRING) {
|
else if (Z_TYPE_P(retval_ptr) == IS_STRING) {
|
||||||
char *filename = Z_STRVAL_P(retval_ptr);
|
char *filename = Z_STRVAL_P(retval_ptr);
|
||||||
char resolved_path[MAXPATHSIZE];
|
char resolved_path[MAXPATHLEN];
|
||||||
size_t resolved_len;
|
size_t resolved_len;
|
||||||
|
|
||||||
if (OPENBASEDIR_CHECKPATH(filename)) {
|
if (OPENBASEDIR_CHECKPATH(filename)) {
|
||||||
@@ -482,15 +508,17 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer, // MAXPATHSIZE
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved_len = _rar_strnlen(resolved_path, MAXPATHSIZE);
|
resolved_len = _rar_strnlen(resolved_path, MAXPATHLEN);
|
||||||
if (resolved_len > MAXPATHSIZE - 1) {
|
/* dst_buffer size is NM; first condition won't happen short of a bug
|
||||||
|
* in expand_filepath */
|
||||||
|
if (resolved_len == MAXPATHLEN || resolved_len > NM - 1) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Resolved path is too big for the unRAR library");
|
"Resolved path is too big for the unRAR library");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(dst_buffer, resolved_path, MAXPATHSIZE);
|
strncpy(dst_buffer, resolved_path, NM);
|
||||||
dst_buffer[MAXPATHSIZE - 1] = '\0';
|
dst_buffer[NM - 1] = '\0';
|
||||||
ret = 1; /* try this new filename */
|
ret = 1; /* try this new filename */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -501,8 +529,15 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer, // MAXPATHSIZE
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_ptr_dtor(&failed_vol);
|
||||||
|
if (retval_ptr != NULL) {
|
||||||
|
zval_ptr_dtor(&retval_ptr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&failed_vol);
|
zval_ptr_dtor(&failed_vol);
|
||||||
zval_ptr_dtor(&retval);
|
zval_ptr_dtor(&retval);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -518,6 +553,17 @@ static int _rar_make_userdata_fcall(zval *callable,
|
|||||||
|
|
||||||
*cache = empty_fcall_info_cache;
|
*cache = empty_fcall_info_cache;
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 2
|
||||||
|
if (zend_fcall_info_init(callable, fci, cache TSRMLS_CC) != SUCCESS) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
|
"The RAR file was not opened in rar_open/RarArchive::open with a "
|
||||||
|
"valid callback.", error);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (zend_fcall_info_init(callable, IS_CALLABLE_STRICT, fci, cache, NULL,
|
if (zend_fcall_info_init(callable, IS_CALLABLE_STRICT, fci, cache, NULL,
|
||||||
&error TSRMLS_CC) == SUCCESS) {
|
&error TSRMLS_CC) == SUCCESS) {
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -537,6 +583,7 @@ static int _rar_make_userdata_fcall(zval *callable,
|
|||||||
}
|
}
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -587,7 +634,6 @@ ZEND_END_ARG_INFO()
|
|||||||
/* {{{ rar_functions[]
|
/* {{{ rar_functions[]
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* clang-format off */
|
|
||||||
static zend_function_entry rar_functions[] = {
|
static zend_function_entry rar_functions[] = {
|
||||||
PHP_FE(rar_open, arginfo_rar_open)
|
PHP_FE(rar_open, arginfo_rar_open)
|
||||||
PHP_FE(rar_list, arginfo_rar_void_archmeth)
|
PHP_FE(rar_list, arginfo_rar_void_archmeth)
|
||||||
@@ -600,13 +646,16 @@ static zend_function_entry rar_functions[] = {
|
|||||||
PHP_FE(rar_wrapper_cache_stats, arginfo_rar_wrapper_cache_stats)
|
PHP_FE(rar_wrapper_cache_stats, arginfo_rar_wrapper_cache_stats)
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Globals' related activities */
|
/* {{{ Globals' related activities */
|
||||||
ZEND_DECLARE_MODULE_GLOBALS(rar);
|
ZEND_DECLARE_MODULE_GLOBALS(rar);
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static int _rar_array_apply_remove_first(void *pDest TSRMLS_DC)
|
||||||
|
#else
|
||||||
static int _rar_array_apply_remove_first(zval *pDest TSRMLS_DC)
|
static int _rar_array_apply_remove_first(zval *pDest TSRMLS_DC)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return (ZEND_HASH_APPLY_STOP | ZEND_HASH_APPLY_REMOVE);
|
return (ZEND_HASH_APPLY_STOP | ZEND_HASH_APPLY_REMOVE);
|
||||||
}
|
}
|
||||||
@@ -624,7 +673,13 @@ static void _rar_contents_cache_put(const char *key,
|
|||||||
assert(zend_hash_num_elements(cc->data) == cur_size - 1);
|
assert(zend_hash_num_elements(cc->data) == cur_size - 1);
|
||||||
}
|
}
|
||||||
rar_zval_add_ref(&zv);
|
rar_zval_add_ref(&zv);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
assert(Z_REFCOUNT_P(zv) > 1);
|
||||||
|
SEPARATE_ZVAL(&zv); /* ensure we store a heap allocated copy */
|
||||||
|
zend_hash_update(cc->data, key, key_len, &zv, sizeof(zv), NULL);
|
||||||
|
#else
|
||||||
zend_hash_str_update(cc->data, key, key_len, zv);
|
zend_hash_str_update(cc->data, key, key_len, zv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static zval *_rar_contents_cache_get(const char *key,
|
static zval *_rar_contents_cache_get(const char *key,
|
||||||
@@ -633,7 +688,15 @@ static zval *_rar_contents_cache_get(const char *key,
|
|||||||
{
|
{
|
||||||
rar_contents_cache *cc = &RAR_G(contents_cache);
|
rar_contents_cache *cc = &RAR_G(contents_cache);
|
||||||
zval *element = NULL;
|
zval *element = NULL;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval **element_p = NULL;
|
||||||
|
zend_hash_find(cc->data, key, key_len, (void **) &element_p);
|
||||||
|
if (element_p) {
|
||||||
|
element = *element_p;
|
||||||
|
}
|
||||||
|
#else
|
||||||
element = zend_hash_str_find(cc->data, key, key_len);
|
element = zend_hash_str_find(cc->data, key, key_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
cc->hits++;
|
cc->hits++;
|
||||||
@@ -692,14 +755,16 @@ ZEND_MODULE_STARTUP_D(rar)
|
|||||||
|
|
||||||
php_register_url_stream_wrapper("rar", &php_stream_rar_wrapper TSRMLS_CC);
|
php_register_url_stream_wrapper("rar", &php_stream_rar_wrapper TSRMLS_CC);
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_MSDOS", HOST_MSDOS, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_MSDOS", HOST_MSDOS, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_OS2", HOST_OS2, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_OS2", HOST_OS2, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_WIN32", HOST_WIN32, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_WIN32", HOST_WIN32, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_UNIX", HOST_UNIX, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_UNIX", HOST_UNIX, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_MACOS", HOST_MACOS, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_MACOS", HOST_MACOS, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("RAR_HOST_BEOS", HOST_BEOS, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("RAR_HOST_BEOS", HOST_BEOS, CONST_CS | CONST_PERSISTENT);
|
||||||
/* clang-format on */
|
/* PHP < 5.3 doesn't have the PHP_MAXPATHLEN constant */
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3
|
||||||
|
REGISTER_LONG_CONSTANT("RAR_MAXPATHLEN", MAXPATHLEN, CONST_CS | CONST_PERSISTENT);
|
||||||
|
#endif
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -764,6 +829,12 @@ zend_module_entry rar_module_entry = {
|
|||||||
};
|
};
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#endif /* HAVE_RAR */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* tab-width: 4
|
* tab-width: 4
|
||||||
|
|||||||
+42
-5
@@ -25,6 +25,10 @@
|
|||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
#include <zend_exceptions.h>
|
#include <zend_exceptions.h>
|
||||||
#include "php_rar.h"
|
#include "php_rar.h"
|
||||||
@@ -66,7 +70,11 @@ void _rar_handle_ext_error(const char *format TSRMLS_DC, ...) /* {{{ */
|
|||||||
va_list arg;
|
va_list arg;
|
||||||
char *message;
|
char *message;
|
||||||
|
|
||||||
|
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||||
|
va_start(arg, TSRMLS_C);
|
||||||
|
#else
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
#endif
|
||||||
vspprintf(&message, 0, format, arg);
|
vspprintf(&message, 0, format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
@@ -83,8 +91,13 @@ int _rar_using_exceptions(TSRMLS_D)
|
|||||||
zval *pval;
|
zval *pval;
|
||||||
pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
|
pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||||
sizeof("usingExceptions") -1, (zend_bool) 1 TSRMLS_CC);
|
sizeof("usingExceptions") -1, (zend_bool) 1 TSRMLS_CC);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
assert(Z_TYPE_P(pval) == IS_BOOL);
|
||||||
|
return Z_BVAL_P(pval);
|
||||||
|
#else
|
||||||
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
||||||
return Z_TYPE_P(pval) == IS_TRUE;
|
return Z_TYPE_P(pval) == IS_TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns a string or NULL if not an error */
|
/* returns a string or NULL if not an error */
|
||||||
@@ -173,22 +186,39 @@ PHP_METHOD(rarexception, setUsingExceptions)
|
|||||||
Return whether exceptions are being used */
|
Return whether exceptions are being used */
|
||||||
PHP_METHOD(rarexception, isUsingExceptions)
|
PHP_METHOD(rarexception, isUsingExceptions)
|
||||||
{
|
{
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval **pval;
|
||||||
|
#else
|
||||||
zval *pval;
|
zval *pval;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* or zend_read_static_property, which calls zend_std_get... after chg scope */
|
/* or zend_read_static_property, which calls zend_std_get... after chg scope */
|
||||||
|
#if PHP_VERSION_ID < 50399
|
||||||
|
pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||||
|
sizeof("usingExceptions") -1, (zend_bool) 0 TSRMLS_CC);
|
||||||
|
#elif PHP_MAJOR_VERSION < 7
|
||||||
|
pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||||
|
sizeof("usingExceptions") -1, (zend_bool) 0, NULL TSRMLS_CC);
|
||||||
|
#else
|
||||||
zend_string *prop_name =
|
zend_string *prop_name =
|
||||||
zend_string_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
|
zend_string_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
|
||||||
pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
|
pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
|
||||||
(zend_bool) 0);
|
(zend_bool) 0);
|
||||||
zend_string_release(prop_name);
|
zend_string_release(prop_name);
|
||||||
|
#endif
|
||||||
/* property always exists */
|
/* property always exists */
|
||||||
assert(pval != NULL);
|
assert(pval != NULL);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
assert(Z_TYPE_PP(pval) == IS_BOOL);
|
||||||
|
RETURN_ZVAL(*pval, 0, 0);
|
||||||
|
#else
|
||||||
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
||||||
RETURN_ZVAL(pval, 0, 0);
|
RETURN_ZVAL(pval, 0, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -201,24 +231,31 @@ ZEND_BEGIN_ARG_INFO(arginfo_rarexception_void, 0)
|
|||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
static zend_function_entry php_rarexception_class_functions[] = {
|
static zend_function_entry php_rarexception_class_functions[] = {
|
||||||
PHP_ME(rarexception, setUsingExceptions, arginfo_rarexception_sue, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
PHP_ME(rarexception, setUsingExceptions, arginfo_rarexception_sue, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||||
PHP_ME(rarexception, isUsingExceptions, arginfo_rarexception_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
PHP_ME(rarexception, isUsingExceptions, arginfo_rarexception_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void minit_rarerror(TSRMLS_D) /* {{{ */
|
void minit_rarerror(TSRMLS_D) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_class_entry ce;
|
zend_class_entry ce;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
|
INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
|
||||||
/* zend_exception_get_default() was removed in PHP 8.5; use the global directly */
|
#if PHP_MAJOR_VERSION < 7
|
||||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||||
|
zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
||||||
|
#else
|
||||||
|
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||||
|
zend_exception_get_default(TSRMLS_C));
|
||||||
|
#endif
|
||||||
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
||||||
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
||||||
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
||||||
ZEND_ACC_STATIC TSRMLS_CC);
|
ZEND_ACC_PRIVATE | ZEND_ACC_STATIC TSRMLS_CC);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
+49
-34
@@ -25,16 +25,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include "php_rar.h"
|
#include "php_rar.h"
|
||||||
|
|
||||||
|
#if HAVE_RAR
|
||||||
|
|
||||||
/* {{{ Structure definitions */
|
/* {{{ Structure definitions */
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
typedef struct _rar_find_state {
|
typedef struct _rar_find_state {
|
||||||
rar_find_output out;
|
rar_find_output out;
|
||||||
rar_file_t *rar;
|
rar_file_t *rar;
|
||||||
@@ -44,7 +49,7 @@ typedef struct _rar_find_state {
|
|||||||
struct _rar_unique_entry {
|
struct _rar_unique_entry {
|
||||||
size_t id; /* position in the entries_array */
|
size_t id; /* position in the entries_array */
|
||||||
struct RARHeaderDataEx entry; /* last entry */
|
struct RARHeaderDataEx entry; /* last entry */
|
||||||
zend_ulong packed_size;
|
unsigned long packed_size;
|
||||||
int depth; /* number of directory separators */
|
int depth; /* number of directory separators */
|
||||||
size_t name_wlen; /* excluding L'\0' terminator */
|
size_t name_wlen; /* excluding L'\0' terminator */
|
||||||
};
|
};
|
||||||
@@ -60,7 +65,6 @@ struct _rar_entries {
|
|||||||
struct _rar_unique_entry *last_accessed;
|
struct _rar_unique_entry *last_accessed;
|
||||||
int list_result; /* tell whether the archive's broken */
|
int list_result; /* tell whether the archive's broken */
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
@@ -69,7 +73,9 @@ static void _rar_nav_get_depth_and_length(wchar_t *filenamew, const size_t file_
|
|||||||
int *depth_out, size_t *wlen_out TSRMLS_DC);
|
int *depth_out, size_t *wlen_out TSRMLS_DC);
|
||||||
static int _rar_nav_get_depth(const wchar_t *filenamew, const size_t file_size);
|
static int _rar_nav_get_depth(const wchar_t *filenamew, const size_t file_size);
|
||||||
static int _rar_nav_compare_entries(const void *op1, const void *op2 TSRMLS_DC);
|
static int _rar_nav_compare_entries(const void *op1, const void *op2 TSRMLS_DC);
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
static void _rar_nav_swap_entries(void *op1, void *op2);
|
static void _rar_nav_swap_entries(void *op1, void *op2);
|
||||||
|
#endif
|
||||||
static int _rar_nav_compare_entries_std(const void *op1, const void *op2);
|
static int _rar_nav_compare_entries_std(const void *op1, const void *op2);
|
||||||
static inline int _rar_nav_compare_values(const wchar_t *str1, const int depth1,
|
static inline int _rar_nav_compare_values(const wchar_t *str1, const int depth1,
|
||||||
const wchar_t *str2, const int depth2,
|
const wchar_t *str2, const int depth2,
|
||||||
@@ -110,9 +116,15 @@ void _rar_entry_search_start(rar_file_t *rar,
|
|||||||
sizeof rar->entries->entries_array_s[0]);
|
sizeof rar->entries->entries_array_s[0]);
|
||||||
memcpy(rar->entries->entries_array_s, rar->entries->entries_array,
|
memcpy(rar->entries->entries_array_s, rar->entries->entries_array,
|
||||||
rar->entries->num_entries * sizeof rar->entries->entries_array[0]);
|
rar->entries->num_entries * sizeof rar->entries->entries_array[0]);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zend_qsort(rar->entries->entries_array_s, rar->entries->num_entries,
|
||||||
|
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries
|
||||||
|
TSRMLS_CC);
|
||||||
|
#else
|
||||||
zend_qsort(rar->entries->entries_array_s, rar->entries->num_entries,
|
zend_qsort(rar->entries->entries_array_s, rar->entries->num_entries,
|
||||||
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries,
|
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries,
|
||||||
_rar_nav_swap_entries);
|
_rar_nav_swap_entries);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -301,9 +313,6 @@ void _rar_delete_entries(rar_file_t *rar TSRMLS_DC)
|
|||||||
if (rar->entries->entries_array != NULL) {
|
if (rar->entries->entries_array != NULL) {
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < rar->entries->num_entries; i++) {
|
for (i = 0; i < rar->entries->num_entries; i++) {
|
||||||
if (rar->entries->entries_array[i]->entry.RedirName != NULL) {
|
|
||||||
efree(rar->entries->entries_array[i]->entry.RedirName);
|
|
||||||
}
|
|
||||||
efree(rar->entries->entries_array[i]);
|
efree(rar->entries->entries_array[i]);
|
||||||
}
|
}
|
||||||
efree(rar->entries->entries_array);
|
efree(rar->entries->entries_array);
|
||||||
@@ -324,7 +333,7 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
size_t capacity = 0;
|
size_t capacity = 0;
|
||||||
int first_file_check = TRUE;
|
int first_file_check = TRUE;
|
||||||
zend_ulong packed_size = 0;
|
unsigned long packed_size = 0UL;
|
||||||
struct _rar_entries *ents;
|
struct _rar_entries *ents;
|
||||||
|
|
||||||
if (rar->entries != NULL) {
|
if (rar->entries != NULL) {
|
||||||
@@ -344,11 +353,7 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
|||||||
ents->last_accessed = NULL;
|
ents->last_accessed = NULL;
|
||||||
|
|
||||||
while (result == 0) {
|
while (result == 0) {
|
||||||
struct _rar_unique_entry *ue;
|
|
||||||
struct RARHeaderDataEx entry = {0};
|
struct RARHeaderDataEx entry = {0};
|
||||||
wchar_t redir_name[1024] = L"";
|
|
||||||
entry.RedirName = redir_name;
|
|
||||||
entry.RedirNameSize = sizeof(redir_name) / sizeof(redir_name[0]);
|
|
||||||
result = RARReadHeaderEx(rar->arch_handle, &entry);
|
result = RARReadHeaderEx(rar->arch_handle, &entry);
|
||||||
/* value of 2nd argument is irrelevant in RAR_OM_LIST_[SPLIT] mode */
|
/* value of 2nd argument is irrelevant in RAR_OM_LIST_[SPLIT] mode */
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
@@ -366,16 +371,22 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
|||||||
|
|
||||||
/* reset packed size if not split before */
|
/* reset packed size if not split before */
|
||||||
if ((entry.Flags & RHDF_SPLITBEFORE) == 0)
|
if ((entry.Flags & RHDF_SPLITBEFORE) == 0)
|
||||||
packed_size = 0;
|
packed_size = 0UL;
|
||||||
|
|
||||||
/* accumulate packed size; cap at ZEND_LONG_MAX (the PHP int ceiling) */
|
/* we would exceed size of ulong. cap at ulong_max
|
||||||
{
|
* equivalent to packed_size + entry.PackSize > ULONG_MAX,
|
||||||
zend_ulong entry_packed = ((zend_ulong)entry.PackSizeHigh << 32) | entry.PackSize;
|
* but without overflowing */
|
||||||
if (entry_packed > (zend_ulong)ZEND_LONG_MAX ||
|
if (ULONG_MAX - packed_size < entry.PackSize)
|
||||||
packed_size > (zend_ulong)ZEND_LONG_MAX - entry_packed)
|
packed_size = ULONG_MAX;
|
||||||
packed_size = (zend_ulong)ZEND_LONG_MAX;
|
else {
|
||||||
else
|
packed_size += entry.PackSize;
|
||||||
packed_size += entry_packed;
|
if (entry.PackSizeHigh != 0) {
|
||||||
|
#if ULONG_MAX > 0xffffffffUL
|
||||||
|
packed_size += ((unsigned long) entry.PackSizeHigh) << 32;
|
||||||
|
#else
|
||||||
|
packed_size = ULONG_MAX; /* cap */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.Flags & RHDF_SPLITAFTER) /* do not commit */
|
if (entry.Flags & RHDF_SPLITAFTER) /* do not commit */
|
||||||
@@ -390,22 +401,16 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
|||||||
}
|
}
|
||||||
assert(capacity > ents->num_entries);
|
assert(capacity > ents->num_entries);
|
||||||
|
|
||||||
ents->entries_array[ents->num_entries] = ue =
|
ents->entries_array[ents->num_entries] =
|
||||||
emalloc(sizeof *ents->entries_array[0]);
|
emalloc(sizeof *ents->entries_array[0]);
|
||||||
memcpy(&ue->entry, &entry, sizeof ents->entries_array[0]->entry);
|
memcpy(&ents->entries_array[ents->num_entries]->entry, &entry,
|
||||||
ue->id = ents->num_entries;
|
sizeof ents->entries_array[0]->entry);
|
||||||
ue->packed_size = packed_size;
|
ents->entries_array[ents->num_entries]->id = ents->num_entries;
|
||||||
|
ents->entries_array[ents->num_entries]->packed_size = packed_size;
|
||||||
_rar_nav_get_depth_and_length(entry.FileNameW,
|
_rar_nav_get_depth_and_length(entry.FileNameW,
|
||||||
sizeof(entry.FileNameW) / sizeof(entry.FileNameW[0]), /* = 1024 */
|
sizeof(entry.FileNameW) / sizeof(entry.FileNameW[0]), /* = 1024 */
|
||||||
&ue->depth, &ue->name_wlen TSRMLS_CC);
|
&ents->entries_array[ents->num_entries]->depth,
|
||||||
if (redir_name[0] != L'\0') {
|
&ents->entries_array[ents->num_entries]->name_wlen TSRMLS_CC);
|
||||||
size_t size = (wcslen(redir_name) + 1) * sizeof(redir_name[0]);
|
|
||||||
ue->entry.RedirName = emalloc(size);
|
|
||||||
memcpy(ue->entry.RedirName, redir_name, size);
|
|
||||||
} else {
|
|
||||||
ue->entry.RedirName = NULL;
|
|
||||||
ue->entry.RedirNameSize = 0;
|
|
||||||
}
|
|
||||||
ents->num_entries++;
|
ents->num_entries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,6 +489,7 @@ static int _rar_nav_compare_entries(const void *op1, const void *op2 TSRMLS_DC)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
static void _rar_nav_swap_entries(void *op1, void *op2) /* {{{ */
|
static void _rar_nav_swap_entries(void *op1, void *op2) /* {{{ */
|
||||||
{
|
{
|
||||||
/* just swaps two pointer values */
|
/* just swaps two pointer values */
|
||||||
@@ -496,6 +502,7 @@ static void _rar_nav_swap_entries(void *op1, void *op2) /* {{{ */
|
|||||||
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
#endif
|
||||||
|
|
||||||
static int _rar_nav_compare_entries_std(const void *op1, const void *op2) /* {{{ */
|
static int _rar_nav_compare_entries_std(const void *op1, const void *op2) /* {{{ */
|
||||||
{
|
{
|
||||||
@@ -600,6 +607,12 @@ static size_t _rar_nav_position_on_dir_start(const wchar_t *dir_name,
|
|||||||
|
|
||||||
/* end functions with internal linkage */
|
/* end functions with internal linkage */
|
||||||
|
|
||||||
|
#endif /* HAVE_RAR */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* tab-width: 4
|
* tab-width: 4
|
||||||
@@ -608,3 +621,5 @@ static size_t _rar_nav_position_on_dir_start(const wchar_t *dir_name,
|
|||||||
* vim600: noet sw=4 ts=4 fdm=marker
|
* vim600: noet sw=4 ts=4 fdm=marker
|
||||||
* vim<600: noet sw=4 ts=4
|
* vim<600: noet sw=4 ts=4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+265
-115
@@ -27,30 +27,35 @@
|
|||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
|
|
||||||
|
#if HAVE_RAR
|
||||||
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "php_rar.h"
|
#include "php_rar.h"
|
||||||
|
#include "unrar/rartypes.hpp"
|
||||||
|
|
||||||
#include <php_streams.h>
|
#include <php_streams.h>
|
||||||
#include <ext/standard/url.h>
|
#include <ext/standard/url.h>
|
||||||
#include <ext/standard/php_string.h>
|
#include <ext/standard/php_string.h>
|
||||||
#include <ext/standard/file.h>
|
#include <ext/standard/file.h>
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
typedef struct php_rar_stream_data_t {
|
typedef struct php_rar_stream_data_t {
|
||||||
struct RAROpenArchiveDataEx open_data;
|
struct RAROpenArchiveDataEx open_data;
|
||||||
struct RARHeaderDataEx header_data;
|
struct RARHeaderDataEx header_data;
|
||||||
HANDLE rar_handle;
|
HANDLE rar_handle;
|
||||||
size_t file_size;
|
|
||||||
/* TODO: consider encapsulating a php memory/tmpfile stream */
|
/* TODO: consider encapsulating a php memory/tmpfile stream */
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
size_t buffer_read_size; /* content size */
|
size_t buffer_cont_size; /* content size */
|
||||||
size_t buffer_pos;
|
size_t buffer_pos;
|
||||||
uint64 cursor;
|
uint64 cursor;
|
||||||
int no_more_data;
|
int no_more_data;
|
||||||
@@ -68,15 +73,12 @@ typedef struct php_rar_dir_stream_data_t {
|
|||||||
int no_encode; /* do not urlencode entry names */
|
int no_encode; /* do not urlencode entry names */
|
||||||
php_stream *stream;
|
php_stream *stream;
|
||||||
} php_rar_dir_stream_data, *php_rar_dir_stream_data_P;
|
} php_rar_dir_stream_data, *php_rar_dir_stream_data_P;
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
#define STREAM_DATA_FROM_STREAM \
|
#define STREAM_DATA_FROM_STREAM \
|
||||||
php_rar_stream_data_P self = (php_rar_stream_data_P) stream->abstract;
|
php_rar_stream_data_P self = (php_rar_stream_data_P) stream->abstract;
|
||||||
|
|
||||||
#define STREAM_DIR_DATA_FROM_STREAM \
|
#define STREAM_DIR_DATA_FROM_STREAM \
|
||||||
php_rar_dir_stream_data_P self = (php_rar_dir_stream_data_P) stream->abstract;
|
php_rar_dir_stream_data_P self = (php_rar_dir_stream_data_P) stream->abstract;
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/* len can be -1 (calculate) */
|
/* len can be -1 (calculate) */
|
||||||
static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
||||||
@@ -97,11 +99,7 @@ static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
|||||||
/* {{{ RAR file streams */
|
/* {{{ RAR file streams */
|
||||||
|
|
||||||
/* {{{ php_rar_ops_read */
|
/* {{{ php_rar_ops_read */
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||||
#else
|
|
||||||
static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
STREAM_DATA_FROM_STREAM
|
STREAM_DATA_FROM_STREAM
|
||||||
@@ -116,12 +114,12 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
|||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
size_t this_read_size;
|
size_t this_read_size;
|
||||||
/* if nothing in the buffer or buffer already read, fill buffer */
|
/* if nothing in the buffer or buffer already read, fill buffer */
|
||||||
if (/*self->buffer_read_size == 0 || > condition not necessary */
|
if (/*self->buffer_cont_size == 0 || > condition not necessary */
|
||||||
self->buffer_pos == self->buffer_read_size)
|
self->buffer_pos == self->buffer_cont_size)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
self->buffer_pos = 0;
|
self->buffer_pos = 0;
|
||||||
self->buffer_read_size = 0;
|
self->buffer_cont_size = 0;
|
||||||
/* Note: this condition is important, you cannot rely on
|
/* Note: this condition is important, you cannot rely on
|
||||||
* having a call to RARProcessFileChunk return no data and
|
* having a call to RARProcessFileChunk return no data and
|
||||||
* break on the condition self->buffer_cont_size == 0 because
|
* break on the condition self->buffer_cont_size == 0 because
|
||||||
@@ -131,25 +129,25 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
|||||||
if (self->no_more_data)
|
if (self->no_more_data)
|
||||||
break;
|
break;
|
||||||
res = RARProcessFileChunk(self->rar_handle, self->buffer,
|
res = RARProcessFileChunk(self->rar_handle, self->buffer,
|
||||||
self->buffer_size, &self->buffer_read_size,
|
self->buffer_size, &self->buffer_cont_size,
|
||||||
&self->no_more_data);
|
&self->no_more_data);
|
||||||
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
||||||
break; /* finish in case of failure */
|
break; /* finish in case of failure */
|
||||||
}
|
}
|
||||||
assert(self->buffer_read_size <= self->buffer_size);
|
assert(self->buffer_cont_size <= self->buffer_size);
|
||||||
/* we did not read anything. no need to continue */
|
/* we did not read anything. no need to continue */
|
||||||
if (self->buffer_read_size == 0)
|
if (self->buffer_cont_size == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* if we get here we have data to be read in the buffer */
|
/* if we get here we have data to be read in the buffer */
|
||||||
this_read_size = MIN(left,
|
this_read_size = MIN(left,
|
||||||
self->buffer_read_size - self->buffer_pos);
|
self->buffer_cont_size - self->buffer_pos);
|
||||||
assert(this_read_size > 0);
|
assert(this_read_size > 0);
|
||||||
memcpy(&buf[count-left], &self->buffer[self->buffer_pos],
|
memcpy(&buf[count-left], &self->buffer[self->buffer_pos],
|
||||||
this_read_size);
|
this_read_size);
|
||||||
left -= this_read_size;
|
left -= this_read_size;
|
||||||
n += this_read_size;
|
n += this_read_size;
|
||||||
self->buffer_pos += this_read_size;
|
self->buffer_pos += this_read_size;
|
||||||
assert(left >= 0);
|
assert(left >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,16 +156,9 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
|||||||
|
|
||||||
/* no more data upstream (for sure), buffer already read and
|
/* no more data upstream (for sure), buffer already read and
|
||||||
* caller asked for more data than we're giving */
|
* caller asked for more data than we're giving */
|
||||||
if (self->no_more_data && self->buffer_pos == self->buffer_read_size &&
|
if (self->no_more_data && self->buffer_pos == self->buffer_cont_size &&
|
||||||
n < count && stream->eof != 1) {
|
((size_t) n) < count)
|
||||||
stream->eof = 1;
|
stream->eof = 1;
|
||||||
if (self->cursor > self->file_size) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
|
||||||
"The file size is supposed to be %lu bytes, but "
|
|
||||||
"we read more: %" PRIu64 " bytes (corruption/wrong pwd)",
|
|
||||||
self->file_size, self->cursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we should only give no data if we have no more */
|
/* we should only give no data if we have no more */
|
||||||
if (!self->no_more_data && n == 0) {
|
if (!self->no_more_data && n == 0) {
|
||||||
@@ -177,25 +168,17 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
|||||||
stream->eof = 1;
|
stream->eof = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ssize_t) n;
|
return n;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ php_rar_ops_write */
|
/* {{{ php_rar_ops_write */
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
static size_t php_rar_ops_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
|
static size_t php_rar_ops_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
|
||||||
#else
|
|
||||||
static ssize_t php_rar_ops_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Write operation not supported for RAR streams.");
|
"Write operation not supported for RAR streams.");
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@@ -211,12 +194,6 @@ static int php_rar_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
|||||||
efree(self->open_data.ArcName);
|
efree(self->open_data.ArcName);
|
||||||
self->open_data.ArcName = NULL;
|
self->open_data.ArcName = NULL;
|
||||||
}
|
}
|
||||||
#ifdef PHP_WIN32
|
|
||||||
if (self->open_data.ArcNameW != NULL) {
|
|
||||||
efree(self->open_data.ArcNameW);
|
|
||||||
self->open_data.ArcNameW = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_rar_destroy_userdata(&self->cb_userdata);
|
_rar_destroy_userdata(&self->cb_userdata);
|
||||||
if (self->buffer != NULL) {
|
if (self->buffer != NULL) {
|
||||||
efree(self->buffer);
|
efree(self->buffer);
|
||||||
@@ -303,6 +280,43 @@ static mode_t _rar_convert_file_attrs(unsigned os_attrs,
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static void _rar_time_convert(unsigned low, unsigned high, time_t *to) /* {{{ */
|
||||||
|
{
|
||||||
|
time_t default_ = (time_t) 0,
|
||||||
|
local_time;
|
||||||
|
struct tm tm = {0};
|
||||||
|
TSRMLS_FETCH();
|
||||||
|
|
||||||
|
if (high == 0U && low == 0U) {
|
||||||
|
*to = default_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970. */
|
||||||
|
uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
|
||||||
|
|
||||||
|
/* value is in 10^-7 seconds since 01-01-1601 */
|
||||||
|
/* convert to nanoseconds, shift to 01-01-1970 and convert to seconds */
|
||||||
|
local_time = (time_t) ((INT32TO64(high, low) * 100 - ushift) / 1000000000);
|
||||||
|
|
||||||
|
/* now we have the time in... I don't know what. It gives UTC - tz offset */
|
||||||
|
/* we need to try and convert it to UTC */
|
||||||
|
/* abuse gmtime, which is supposed to work with UTC */
|
||||||
|
#ifndef PHP_WIN32
|
||||||
|
if (gmtime_r(&local_time, &tm) == NULL) {
|
||||||
|
#else
|
||||||
|
if (gmtime_s(&tm, &local_time) != 0) {
|
||||||
|
#endif
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
|
"Could not convert time to UTC, using local time");
|
||||||
|
*to = local_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
*to = local_time + (local_time - mktime(&tm));
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||||
php_stream_statbuf *ssb) /* {{{ */
|
php_stream_statbuf *ssb) /* {{{ */
|
||||||
{
|
{
|
||||||
@@ -317,7 +331,7 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
|||||||
* SUBHEAD_TYPE_UOWNER), but it is not exposed in unRAR */
|
* SUBHEAD_TYPE_UOWNER), but it is not exposed in unRAR */
|
||||||
ssb->sb.st_uid = 0;
|
ssb->sb.st_uid = 0;
|
||||||
ssb->sb.st_gid = 0;
|
ssb->sb.st_gid = 0;
|
||||||
#if defined(HAVE_ST_RDEV) || defined(HAVE_STRUCT_STAT_ST_RDEV)
|
#ifdef HAVE_ST_RDEV
|
||||||
ssb->sb.st_rdev = 0;
|
ssb->sb.st_rdev = 0;
|
||||||
#endif
|
#endif
|
||||||
/* never mind signedness, we'll never get sizes big enough for that to
|
/* never mind signedness, we'll never get sizes big enough for that to
|
||||||
@@ -332,26 +346,34 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
|||||||
ssb->sb.st_size = (long) (unsigned long) (int64) unp_size;
|
ssb->sb.st_size = (long) (unsigned long) (int64) unp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
_rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
||||||
rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
_rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
||||||
|
|
||||||
if (header->MtimeLow == 0 && header->MtimeHigh == 0) {
|
if (header->MtimeLow == 0 && header->MtimeHigh == 0) {
|
||||||
/* high precision mod time undefined */
|
/* high precision mod time undefined */
|
||||||
|
struct tm time_s = {0};
|
||||||
time_t time;
|
time_t time;
|
||||||
if (rar_dos_time_convert(header->FileTime, &time) == FAILURE) {
|
unsigned dos_time = header->FileTime;
|
||||||
|
|
||||||
|
time_s.tm_sec = (dos_time & 0x1f)*2;
|
||||||
|
time_s.tm_min = (dos_time>>5) & 0x3f;
|
||||||
|
time_s.tm_hour = (dos_time>>11) & 0x1f;
|
||||||
|
time_s.tm_mday = (dos_time>>16) & 0x1f;
|
||||||
|
time_s.tm_mon = ((dos_time>>21) & 0x0f) - 1;
|
||||||
|
time_s.tm_year = (dos_time>>25) + 80;
|
||||||
|
if ((time = mktime(&time_s)) == -1)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
|
||||||
ssb->sb.st_mtime = time;
|
ssb->sb.st_mtime = time;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
_rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
||||||
&ssb->sb.st_mtime);
|
&ssb->sb.st_mtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_ST_BLKSIZE) || defined(HAVE_STRUCT_STAT_ST_BLKSIZE)
|
#ifdef HAVE_ST_BLKSIZE
|
||||||
ssb->sb.st_blksize = 0;
|
ssb->sb.st_blksize = 0;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_ST_BLOCKS) || defined (HAVE_STRUCT_STAT_ST_BLOCKS)
|
#ifdef HAVE_ST_BLOCKS
|
||||||
ssb->sb.st_blocks = 0;
|
ssb->sb.st_blocks = 0;
|
||||||
#endif
|
#endif
|
||||||
/* php_stat in filestat.c doesn't check this one, so don't touch it */
|
/* php_stat in filestat.c doesn't check this one, so don't touch it */
|
||||||
@@ -387,32 +409,19 @@ static php_stream_ops php_stream_rario_ops = {
|
|||||||
/* {{{ RAR directory streams */
|
/* {{{ RAR directory streams */
|
||||||
|
|
||||||
/* {{{ php_rar_dir_ops_read */
|
/* {{{ php_rar_dir_ops_read */
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
static size_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
static size_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||||
#else
|
|
||||||
static ssize_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
php_stream_dirent entry;
|
php_stream_dirent entry;
|
||||||
size_t offset;
|
int offset;
|
||||||
STREAM_DIR_DATA_FROM_STREAM
|
STREAM_DIR_DATA_FROM_STREAM
|
||||||
|
|
||||||
if (count != sizeof(entry)) {
|
if (count != sizeof(entry))
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
_rar_entry_search_advance(self->state, self->directory, self->dir_size, 1);
|
_rar_entry_search_advance(self->state, self->directory, self->dir_size, 1);
|
||||||
if (!self->state->found) {
|
if (!self->state->found) {
|
||||||
stream->eof = 1;
|
stream->eof = 1;
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->dir_size == 1) /* root */
|
if (self->dir_size == 1) /* root */
|
||||||
@@ -424,10 +433,19 @@ static ssize_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count
|
|||||||
entry.d_name, sizeof entry.d_name);
|
entry.d_name, sizeof entry.d_name);
|
||||||
|
|
||||||
if (!self->no_encode) { /* urlencode entry */
|
if (!self->no_encode) { /* urlencode entry */
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
int new_len;
|
||||||
|
char *encoded_name;
|
||||||
|
encoded_name = php_url_encode(entry.d_name, strlen(entry.d_name),
|
||||||
|
&new_len);
|
||||||
|
strlcpy(entry.d_name, encoded_name, sizeof entry.d_name);
|
||||||
|
efree(encoded_name);
|
||||||
|
#else
|
||||||
zend_string *encoded_name =
|
zend_string *encoded_name =
|
||||||
php_url_encode(entry.d_name, strlen(entry.d_name));
|
php_url_encode(entry.d_name, strlen(entry.d_name));
|
||||||
strlcpy(entry.d_name, encoded_name->val, sizeof entry.d_name);
|
strlcpy(entry.d_name, encoded_name->val, sizeof entry.d_name);
|
||||||
zend_string_release(encoded_name);
|
zend_string_release(encoded_name);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -443,7 +461,11 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
|||||||
{
|
{
|
||||||
STREAM_DIR_DATA_FROM_STREAM
|
STREAM_DIR_DATA_FROM_STREAM
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_dtor(&self->rar_obj);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&self->rar_obj);
|
zval_ptr_dtor(&self->rar_obj);
|
||||||
|
#endif
|
||||||
efree(self->directory);
|
efree(self->directory);
|
||||||
efree(self->state);
|
efree(self->state);
|
||||||
efree(self);
|
efree(self);
|
||||||
@@ -455,11 +477,7 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ php_rar_dir_ops_rewind */
|
/* {{{ php_rar_dir_ops_rewind */
|
||||||
#if PHP_VERSION_ID < 70400
|
|
||||||
static int php_rar_dir_ops_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC)
|
static int php_rar_dir_ops_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC)
|
||||||
#else
|
|
||||||
static int php_rar_dir_ops_rewind(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
STREAM_DIR_DATA_FROM_STREAM
|
STREAM_DIR_DATA_FROM_STREAM
|
||||||
|
|
||||||
@@ -517,13 +535,6 @@ php_stream *php_stream_rar_open(char *arc_name,
|
|||||||
self = ecalloc(1, sizeof *self);
|
self = ecalloc(1, sizeof *self);
|
||||||
self->open_data.ArcName = estrdup(arc_name);
|
self->open_data.ArcName = estrdup(arc_name);
|
||||||
self->open_data.OpenMode = RAR_OM_EXTRACT;
|
self->open_data.OpenMode = RAR_OM_EXTRACT;
|
||||||
#ifdef PHP_WIN32
|
|
||||||
{
|
|
||||||
size_t arcnamew_len = strlen(arc_name);
|
|
||||||
self->open_data.ArcNameW = safe_emalloc(arcnamew_len, sizeof(wchar_t), sizeof(wchar_t));
|
|
||||||
_rar_utf_to_wide(arc_name, self->open_data.ArcNameW, arcnamew_len + 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* deep copy the callback userdata */
|
/* deep copy the callback userdata */
|
||||||
if (cb_udata_ptr->password != NULL)
|
if (cb_udata_ptr->password != NULL)
|
||||||
self->cb_userdata.password = estrdup(cb_udata_ptr->password);
|
self->cb_userdata.password = estrdup(cb_udata_ptr->password);
|
||||||
@@ -543,18 +554,16 @@ php_stream *php_stream_rar_open(char *arc_name,
|
|||||||
TSRMLS_CC, position, arc_name);
|
TSRMLS_CC, position, arc_name);
|
||||||
else {
|
else {
|
||||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
size_t buffer_size = (size_t)
|
||||||
self->header_data.UnpSize);
|
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||||
size_t buffer_size = MIN(
|
INT32TO64(self->header_data.UnpSizeHigh,
|
||||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
self->header_data.UnpSize));
|
||||||
file_size);
|
|
||||||
int process_result = RARProcessFileChunkInit(self->rar_handle);
|
int process_result = RARProcessFileChunkInit(self->rar_handle);
|
||||||
|
|
||||||
if (_rar_handle_error(process_result TSRMLS_CC) == FAILURE) {
|
if (_rar_handle_error(process_result TSRMLS_CC) == FAILURE) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->file_size = file_size;
|
|
||||||
self->buffer = emalloc(buffer_size);
|
self->buffer = emalloc(buffer_size);
|
||||||
self->buffer_size = buffer_size;
|
self->buffer_size = buffer_size;
|
||||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, "rb");
|
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, "rb");
|
||||||
@@ -566,10 +575,6 @@ cleanup:
|
|||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
if (self->open_data.ArcName != NULL)
|
if (self->open_data.ArcName != NULL)
|
||||||
efree(self->open_data.ArcName);
|
efree(self->open_data.ArcName);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
if (self->open_data.ArcNameW != NULL)
|
|
||||||
efree(self->open_data.ArcNameW);
|
|
||||||
#endif
|
|
||||||
_rar_destroy_userdata(&self->cb_userdata);
|
_rar_destroy_userdata(&self->cb_userdata);
|
||||||
if (self->buffer != NULL)
|
if (self->buffer != NULL)
|
||||||
efree(self->buffer);
|
efree(self->buffer);
|
||||||
@@ -585,6 +590,67 @@ cleanup:
|
|||||||
|
|
||||||
/* {{{ Wrapper stuff */
|
/* {{{ Wrapper stuff */
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3
|
||||||
|
/* PHP 5.2 has no zend_resolve_path. Adapted from 5.3's php_resolve_path */
|
||||||
|
static char *zend_resolve_path(const char *filename,
|
||||||
|
int filename_length TSRMLS_DC) /* {{{ */
|
||||||
|
{
|
||||||
|
const char *path = PG(include_path);
|
||||||
|
char resolved_path[MAXPATHLEN];
|
||||||
|
char trypath[MAXPATHLEN];
|
||||||
|
const char *ptr, *end;
|
||||||
|
char *actual_path;
|
||||||
|
|
||||||
|
if (filename == NULL || filename[0] == '\0') {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not use the include path in these circumstances */
|
||||||
|
if ((*filename == '.' && (IS_SLASH(filename[1]) ||
|
||||||
|
((filename[1] == '.') && IS_SLASH(filename[2])))) ||
|
||||||
|
IS_ABSOLUTE_PATH(filename, filename_length) ||
|
||||||
|
path == NULL || path[0] == '\0') {
|
||||||
|
if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) {
|
||||||
|
return estrdup(resolved_path);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = path;
|
||||||
|
while (ptr && *ptr) {
|
||||||
|
end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
|
||||||
|
if (end) {
|
||||||
|
if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) {
|
||||||
|
ptr = end + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(trypath, ptr, end-ptr);
|
||||||
|
trypath[end-ptr] = '/';
|
||||||
|
memcpy(trypath+(end-ptr)+1, filename, filename_length+1);
|
||||||
|
ptr = end+1;
|
||||||
|
} else {
|
||||||
|
int len = strlen(ptr);
|
||||||
|
|
||||||
|
if (len + 1 + filename_length + 1 >= MAXPATHLEN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(trypath, ptr, len);
|
||||||
|
trypath[len] = '/';
|
||||||
|
memcpy(trypath+len+1, filename, filename_length+1);
|
||||||
|
ptr = NULL;
|
||||||
|
}
|
||||||
|
actual_path = trypath;
|
||||||
|
if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) {
|
||||||
|
return estrdup(resolved_path);
|
||||||
|
}
|
||||||
|
} /* end provided path */
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* {{{ php_rar_process_context */
|
/* {{{ php_rar_process_context */
|
||||||
/* memory is to be managed externally */
|
/* memory is to be managed externally */
|
||||||
static void php_rar_process_context(php_stream_context *context,
|
static void php_rar_process_context(php_stream_context *context,
|
||||||
@@ -595,6 +661,9 @@ static void php_rar_process_context(php_stream_context *context,
|
|||||||
zval **volume_cb TSRMLS_DC)
|
zval **volume_cb TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zval *ctx_opt;
|
zval *ctx_opt;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval **ctx_opt_p = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(context != NULL);
|
assert(context != NULL);
|
||||||
assert(open_password != NULL);
|
assert(open_password != NULL);
|
||||||
@@ -604,8 +673,14 @@ static void php_rar_process_context(php_stream_context *context,
|
|||||||
|
|
||||||
/* TODO: don't know if I can log errors and not fail. check that */
|
/* TODO: don't know if I can log errors and not fail. check that */
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
if (php_stream_context_get_option(
|
||||||
|
context, "rar", "open_password", &ctx_opt_p) == SUCCESS) {
|
||||||
|
ctx_opt = *ctx_opt_p;
|
||||||
|
#else
|
||||||
if ((ctx_opt = php_stream_context_get_option(
|
if ((ctx_opt = php_stream_context_get_option(
|
||||||
context, "rar", "open_password"))) {
|
context, "rar", "open_password"))) {
|
||||||
|
#endif
|
||||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||||
"RAR open password was provided, but not a string.");
|
"RAR open password was provided, but not a string.");
|
||||||
@@ -613,8 +688,14 @@ static void php_rar_process_context(php_stream_context *context,
|
|||||||
*open_password = Z_STRVAL_P(ctx_opt);
|
*open_password = Z_STRVAL_P(ctx_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
if (file_password != NULL && php_stream_context_get_option(context, "rar",
|
||||||
|
"file_password", &ctx_opt_p) == SUCCESS) {
|
||||||
|
ctx_opt = *ctx_opt_p;
|
||||||
|
#else
|
||||||
if (file_password != NULL && (ctx_opt = php_stream_context_get_option(
|
if (file_password != NULL && (ctx_opt = php_stream_context_get_option(
|
||||||
context, "rar", "file_password"))) {
|
context, "rar", "file_password"))) {
|
||||||
|
#endif
|
||||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||||
"RAR file password was provided, but not a string.");
|
"RAR file password was provided, but not a string.");
|
||||||
@@ -622,9 +703,19 @@ static void php_rar_process_context(php_stream_context *context,
|
|||||||
*file_password = Z_STRVAL_P(ctx_opt);
|
*file_password = Z_STRVAL_P(ctx_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
if (php_stream_context_get_option(context, "rar", "volume_callback",
|
||||||
|
&ctx_opt_p) == SUCCESS) {
|
||||||
|
ctx_opt = *ctx_opt_p;
|
||||||
|
#else
|
||||||
if ((ctx_opt = php_stream_context_get_option(
|
if ((ctx_opt = php_stream_context_get_option(
|
||||||
context, "rar", "volume_callback"))) {
|
context, "rar", "volume_callback"))) {
|
||||||
|
#endif
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 2
|
||||||
|
if (zend_is_callable(ctx_opt, IS_CALLABLE_STRICT, NULL)) {
|
||||||
|
#else
|
||||||
if (zend_is_callable(ctx_opt, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
if (zend_is_callable(ctx_opt, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
||||||
|
#endif
|
||||||
*volume_cb = ctx_opt;
|
*volume_cb = ctx_opt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -693,19 +784,17 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
|
|||||||
|
|
||||||
if (!(options & STREAM_ASSUME_REALPATH)) {
|
if (!(options & STREAM_ASSUME_REALPATH)) {
|
||||||
if (options & USE_PATH) {
|
if (options & USE_PATH) {
|
||||||
#if PHP_VERSION_ID < 80100
|
#if PHP_MAJOR_VERSION < 7
|
||||||
zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
|
*archive = zend_resolve_path(tmp_archive, tmp_arch_len TSRMLS_CC);
|
||||||
#else
|
#else
|
||||||
zend_string *tmp_archive_str = zend_string_init_fast(tmp_archive, tmp_arch_len);
|
zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
|
||||||
zend_string *arc_str = zend_resolve_path(tmp_archive_str);
|
|
||||||
zend_string_free(tmp_archive_str);
|
|
||||||
#endif
|
|
||||||
if (arc_str != NULL) {
|
if (arc_str != NULL) {
|
||||||
*archive = estrndup(arc_str->val, arc_str->len);
|
*archive = estrndup(arc_str->val, arc_str->len);
|
||||||
} else {
|
} else {
|
||||||
*archive = NULL;
|
*archive = NULL;
|
||||||
}
|
}
|
||||||
zend_string_release(arc_str);
|
zend_string_release(arc_str);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (*archive == NULL) {
|
if (*archive == NULL) {
|
||||||
if ((*archive = expand_filepath(tmp_archive, NULL TSRMLS_CC))
|
if ((*archive = expand_filepath(tmp_archive, NULL TSRMLS_CC))
|
||||||
@@ -773,10 +862,17 @@ cleanup:
|
|||||||
|
|
||||||
/* {{{ php_stream_rar_opener */
|
/* {{{ php_stream_rar_opener */
|
||||||
static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
char *filename,
|
||||||
|
char *mode,
|
||||||
|
int options,
|
||||||
|
char **opened_path,
|
||||||
|
#else
|
||||||
const char *filename,
|
const char *filename,
|
||||||
const char *mode,
|
const char *mode,
|
||||||
int options,
|
int options,
|
||||||
zend_string **opened_path,
|
zend_string **opened_path,
|
||||||
|
#endif
|
||||||
php_stream_context *context
|
php_stream_context *context
|
||||||
STREAMS_DC TSRMLS_DC)
|
STREAMS_DC TSRMLS_DC)
|
||||||
{
|
{
|
||||||
@@ -820,13 +916,6 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
|||||||
self = ecalloc(1, sizeof *self);
|
self = ecalloc(1, sizeof *self);
|
||||||
self->open_data.ArcName = estrdup(tmp_open_path);
|
self->open_data.ArcName = estrdup(tmp_open_path);
|
||||||
self->open_data.OpenMode = RAR_OM_EXTRACT;
|
self->open_data.OpenMode = RAR_OM_EXTRACT;
|
||||||
#ifdef PHP_WIN32
|
|
||||||
{
|
|
||||||
size_t arcnamew_len = strlen(tmp_open_path);
|
|
||||||
self->open_data.ArcNameW = safe_emalloc(arcnamew_len, sizeof(wchar_t), sizeof(wchar_t));
|
|
||||||
_rar_utf_to_wide(tmp_open_path, self->open_data.ArcNameW, arcnamew_len + 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (open_passwd != NULL)
|
if (open_passwd != NULL)
|
||||||
self->cb_userdata.password = estrdup(open_passwd);
|
self->cb_userdata.password = estrdup(open_passwd);
|
||||||
if (volume_cb != NULL) {
|
if (volume_cb != NULL) {
|
||||||
@@ -866,23 +955,21 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
size_t buffer_size = (size_t)
|
||||||
self->header_data.UnpSize);
|
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||||
size_t buffer_size = MIN(
|
INT32TO64(self->header_data.UnpSizeHigh,
|
||||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
self->header_data.UnpSize));
|
||||||
file_size);
|
|
||||||
rar_result = RARProcessFileChunkInit(self->rar_handle);
|
rar_result = RARProcessFileChunkInit(self->rar_handle);
|
||||||
|
|
||||||
if ((rar_error = _rar_error_to_string(rar_result)) != NULL) {
|
if ((rar_error = _rar_error_to_string(rar_result)) != NULL) {
|
||||||
char *mb_entry = _rar_wide_to_utf_with_alloc(fragment, -1);
|
char *mb_entry = _rar_wide_to_utf_with_alloc(fragment, -1);
|
||||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||||
"Error opening file %s inside RAR archive %s: %s",
|
"Error opening file %s inside RAR archive %s: %s",
|
||||||
mb_entry, tmp_open_path, rar_error);
|
mb_entry, tmp_open_path, rar_error);
|
||||||
efree(mb_entry);
|
efree(mb_entry);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->file_size = file_size;
|
|
||||||
self->buffer = emalloc(buffer_size);
|
self->buffer = emalloc(buffer_size);
|
||||||
self->buffer_size = buffer_size;
|
self->buffer_size = buffer_size;
|
||||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, mode);
|
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, mode);
|
||||||
@@ -895,8 +982,12 @@ cleanup:
|
|||||||
|
|
||||||
if (tmp_open_path != NULL) {
|
if (tmp_open_path != NULL) {
|
||||||
if (opened_path != NULL) {
|
if (opened_path != NULL) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
*opened_path = tmp_open_path;
|
||||||
|
#else
|
||||||
*opened_path =
|
*opened_path =
|
||||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
efree(tmp_open_path);
|
efree(tmp_open_path);
|
||||||
}
|
}
|
||||||
@@ -908,10 +999,6 @@ cleanup:
|
|||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
if (self->open_data.ArcName != NULL)
|
if (self->open_data.ArcName != NULL)
|
||||||
efree(self->open_data.ArcName);
|
efree(self->open_data.ArcName);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
if (self->open_data.ArcNameW != NULL)
|
|
||||||
efree(self->open_data.ArcNameW);
|
|
||||||
#endif
|
|
||||||
_rar_destroy_userdata(&self->cb_userdata);
|
_rar_destroy_userdata(&self->cb_userdata);
|
||||||
if (self->buffer != NULL)
|
if (self->buffer != NULL)
|
||||||
efree(self->buffer);
|
efree(self->buffer);
|
||||||
@@ -956,7 +1043,11 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
|||||||
zval *cache_zv;
|
zval *cache_zv;
|
||||||
|
|
||||||
assert(rar_obj != NULL);
|
assert(rar_obj != NULL);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
INIT_ZVAL(*rar_obj);
|
||||||
|
#else
|
||||||
ZVAL_UNDEF(rar_obj);
|
ZVAL_UNDEF(rar_obj);
|
||||||
|
#endif
|
||||||
|
|
||||||
_rar_arch_cache_get_key(arch_path, open_passwd, volume_cb, &cache_key,
|
_rar_arch_cache_get_key(arch_path, open_passwd, volume_cb, &cache_key,
|
||||||
&cache_key_len);
|
&cache_key_len);
|
||||||
@@ -982,7 +1073,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
|||||||
int res;
|
int res;
|
||||||
const char *err_str;
|
const char *err_str;
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC)
|
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||||
== FAILURE) {
|
== FAILURE) {
|
||||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||||
"Bug: could not retrieve RarArchive object from zval");
|
"Bug: could not retrieve RarArchive object from zval");
|
||||||
@@ -1006,7 +1097,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
|||||||
else { /* cache hit */
|
else { /* cache hit */
|
||||||
/* cache get already put the value in rar_obj and incremented the
|
/* cache get already put the value in rar_obj and incremented the
|
||||||
* refcount of the object */
|
* refcount of the object */
|
||||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
||||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||||
"Bug: could not retrieve RarArchive object from zval");
|
"Bug: could not retrieve RarArchive object from zval");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -1019,26 +1110,56 @@ cleanup:
|
|||||||
efree(cache_key);
|
efree(cache_key);
|
||||||
|
|
||||||
if (ret != SUCCESS && Z_TYPE_P(rar_obj) == IS_OBJECT) {
|
if (ret != SUCCESS && Z_TYPE_P(rar_obj) == IS_OBJECT) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_dtor(rar_obj);
|
||||||
|
Z_TYPE_P(rar_obj) = IS_NULL;
|
||||||
|
#else
|
||||||
zval_ptr_dtor(rar_obj);
|
zval_ptr_dtor(rar_obj);
|
||||||
ZVAL_UNDEF(rar_obj);
|
ZVAL_UNDEF(rar_obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ _rar_stream_tidy_wrapper_error_log */
|
/* {{{ _rar_stream_tidy_wrapper_error_log
|
||||||
|
* These two different versions are because of PHP commit 7166298 */
|
||||||
|
#if PHP_VERSION_ID <= 50310 || PHP_VERSION_ID == 50400
|
||||||
|
/* copied from main/streams/streams.c because it's an internal function */
|
||||||
|
static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
|
||||||
|
{
|
||||||
|
if (wrapper) {
|
||||||
|
/* tidy up the error stack */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < wrapper->err_count; i++) {
|
||||||
|
efree(wrapper->err_stack[i]);
|
||||||
|
}
|
||||||
|
if (wrapper->err_stack) {
|
||||||
|
efree(wrapper->err_stack);
|
||||||
|
}
|
||||||
|
wrapper->err_stack = NULL;
|
||||||
|
wrapper->err_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
|
static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
|
||||||
{
|
{
|
||||||
if (wrapper && FG(wrapper_errors)) {
|
if (wrapper && FG(wrapper_errors)) {
|
||||||
zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper);
|
zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ php_stream_rar_stater */
|
/* {{{ php_stream_rar_stater */
|
||||||
static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
char *url,
|
||||||
|
#else
|
||||||
const char *url,
|
const char *url,
|
||||||
|
#endif
|
||||||
int flags,
|
int flags,
|
||||||
php_stream_statbuf *ssb,
|
php_stream_statbuf *ssb,
|
||||||
php_stream_context *context TSRMLS_DC)
|
php_stream_context *context TSRMLS_DC)
|
||||||
@@ -1057,7 +1178,11 @@ static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
|||||||
int ret = FAILURE;
|
int ret = FAILURE;
|
||||||
|
|
||||||
/* {{{ preliminaries */
|
/* {{{ preliminaries */
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
Z_TYPE(rararch) = IS_NULL;
|
||||||
|
#else
|
||||||
ZVAL_UNDEF(&rararch);
|
ZVAL_UNDEF(&rararch);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_rar_get_archive_and_fragment(wrapper, url, options, 1,
|
if (_rar_get_archive_and_fragment(wrapper, url, options, 1,
|
||||||
&open_path, &fragment, NULL TSRMLS_CC) == FAILURE) {
|
&open_path, &fragment, NULL TSRMLS_CC) == FAILURE) {
|
||||||
@@ -1108,7 +1233,11 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Z_TYPE(rararch) == IS_OBJECT) {
|
if (Z_TYPE(rararch) == IS_OBJECT) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_dtor(&rararch);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&rararch);
|
zval_ptr_dtor(&rararch);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
_rar_entry_search_end(state);
|
_rar_entry_search_end(state);
|
||||||
@@ -1131,10 +1260,17 @@ cleanup:
|
|||||||
|
|
||||||
/* {{{ php_stream_rar_dir_opener */
|
/* {{{ php_stream_rar_dir_opener */
|
||||||
static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
char *filename,
|
||||||
|
char *mode,
|
||||||
|
int options,
|
||||||
|
char **opened_path,
|
||||||
|
#else
|
||||||
const char *filename,
|
const char *filename,
|
||||||
const char *mode,
|
const char *mode,
|
||||||
int options,
|
int options,
|
||||||
zend_string **opened_path,
|
zend_string **opened_path,
|
||||||
|
#endif
|
||||||
php_stream_context *context
|
php_stream_context *context
|
||||||
STREAMS_DC TSRMLS_DC)
|
STREAMS_DC TSRMLS_DC)
|
||||||
{
|
{
|
||||||
@@ -1233,8 +1369,12 @@ cleanup:
|
|||||||
|
|
||||||
if (tmp_open_path != NULL) {
|
if (tmp_open_path != NULL) {
|
||||||
if (opened_path != NULL) {
|
if (opened_path != NULL) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
*opened_path = tmp_open_path;
|
||||||
|
#else
|
||||||
*opened_path =
|
*opened_path =
|
||||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
efree(tmp_open_path);
|
efree(tmp_open_path);
|
||||||
}
|
}
|
||||||
@@ -1245,7 +1385,11 @@ cleanup:
|
|||||||
if (stream == NULL) { /* failed */
|
if (stream == NULL) { /* failed */
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
if (Z_TYPE(self->rar_obj) == IS_OBJECT) {
|
if (Z_TYPE(self->rar_obj) == IS_OBJECT) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_dtor(&self->rar_obj);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&self->rar_obj);
|
zval_ptr_dtor(&self->rar_obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (self->directory != NULL) {
|
if (self->directory != NULL) {
|
||||||
efree(self->directory);
|
efree(self->directory);
|
||||||
@@ -1282,6 +1426,12 @@ php_stream_wrapper php_stream_rar_wrapper = {
|
|||||||
|
|
||||||
/* end wrapper stuff }}} */
|
/* end wrapper stuff }}} */
|
||||||
|
|
||||||
|
#endif /* HAVE_RAR */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* tab-width: 4
|
* tab-width: 4
|
||||||
|
|||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
#include <php.h>
|
|
||||||
#include "php_rar.h"
|
|
||||||
|
|
||||||
void rar_time_convert(unsigned low, unsigned high, time_t *to) /* {{{ */
|
|
||||||
{
|
|
||||||
time_t default_ = (time_t) 0,
|
|
||||||
local_time;
|
|
||||||
struct tm tm = {0};
|
|
||||||
TSRMLS_FETCH();
|
|
||||||
|
|
||||||
if (high == 0U && low == 0U) {
|
|
||||||
*to = default_;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970. */
|
|
||||||
uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
|
|
||||||
|
|
||||||
/* value is in 10^-7 seconds since 01-01-1601 */
|
|
||||||
/* convert to nanoseconds, shift to 01-01-1970 and convert to seconds */
|
|
||||||
local_time = (time_t) ((INT32TO64(high, low) * 100 - ushift) / 1000000000);
|
|
||||||
|
|
||||||
/* now we have the time in... I don't know what. It gives UTC - tz offset */
|
|
||||||
/* we need to try and convert it to UTC */
|
|
||||||
/* abuse gmtime, which is supposed to work with UTC */
|
|
||||||
if (php_gmtime_r(&local_time, &tm) == NULL) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
|
||||||
"Could not convert time to UTC, using local time");
|
|
||||||
*to = local_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
tm.tm_isdst = -1;
|
|
||||||
*to = local_time + (local_time - mktime(&tm));
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
int rar_dos_time_convert(unsigned dos_time, time_t *to) /* {{{ */
|
|
||||||
{
|
|
||||||
struct tm time_s = {0};
|
|
||||||
|
|
||||||
time_s.tm_sec = (dos_time & 0x1f)*2;
|
|
||||||
time_s.tm_min = (dos_time>>5) & 0x3f;
|
|
||||||
time_s.tm_hour = (dos_time>>11) & 0x1f;
|
|
||||||
time_s.tm_mday = (dos_time>>16) & 0x1f;
|
|
||||||
time_s.tm_mon = ((dos_time>>21) & 0x0f) - 1;
|
|
||||||
time_s.tm_year = (dos_time>>25) + 80;
|
|
||||||
/* the dos times that unrar gives out seem to be already in UTC.
|
|
||||||
* Or at least they don't depend on TZ */
|
|
||||||
if ((*to = timegm(&time_s)) == (time_t) -1) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
@@ -27,34 +27,39 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include "zend_types.h"
|
#ifdef __cplusplus
|
||||||
#include <zend_API.h>
|
extern "C" {
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
# define _GNU_SOURCE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
#include <zend_interfaces.h>
|
#include <zend_interfaces.h>
|
||||||
#include "php_rar.h"
|
#include "php_rar.h"
|
||||||
#include "php_compat.h"
|
|
||||||
|
|
||||||
/* {{{ Type definitions reserved for this translation unit */
|
/* {{{ Type definitions reserved for this translation unit */
|
||||||
/* clang-format off */
|
|
||||||
typedef struct _ze_rararch_object {
|
typedef struct _ze_rararch_object {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zend_object parent;
|
||||||
|
rar_file_t *rar_file;
|
||||||
|
#else
|
||||||
rar_file_t *rar_file;
|
rar_file_t *rar_file;
|
||||||
zend_object parent;
|
zend_object parent;
|
||||||
|
#endif
|
||||||
} ze_rararch_object;
|
} ze_rararch_object;
|
||||||
|
|
||||||
typedef struct _rararch_iterator {
|
typedef struct _rararch_iterator {
|
||||||
zend_object_iterator parent;
|
zend_object_iterator parent;
|
||||||
rar_find_output *state;
|
rar_find_output *state;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval *value;
|
||||||
|
#else
|
||||||
zval value;
|
zval value;
|
||||||
|
#endif
|
||||||
int empty_iterator; /* iterator should give nothing */
|
int empty_iterator; /* iterator should give nothing */
|
||||||
} rararch_iterator;
|
} rararch_iterator;
|
||||||
/* clang-format on */
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Globals with internal linkage */
|
/* {{{ Globals with internal linkage */
|
||||||
@@ -78,46 +83,39 @@ static zend_object_handlers rararch_object_handlers;
|
|||||||
/* {{{ Function prototypes for functions with internal linkage */
|
/* {{{ Function prototypes for functions with internal linkage */
|
||||||
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv);
|
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv);
|
||||||
static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC);
|
static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC);
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj);
|
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj);
|
||||||
|
|
||||||
static ze_rararch_object *rararch_object_from_zv(const zval *zv);
|
static ze_rararch_object *rararch_object_from_zv(const zval *zv);
|
||||||
static ze_rararch_object *rararch_object_from_ref(const rar_obj_ref ref);
|
|
||||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce);
|
static zend_object *rararch_ce_create_object(zend_class_entry *ce);
|
||||||
static void rararch_ce_free_object_storage(zend_object *zobj);
|
static void rararch_ce_free_object_storage(zend_object *zobj);
|
||||||
|
#else
|
||||||
|
#define rararch_object_from_zv zend_object_store_get_object
|
||||||
|
static zend_object_value rararch_ce_create_object(zend_class_entry *class_type TSRMLS_DC);
|
||||||
|
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC);
|
||||||
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive handlers */
|
/* {{{ RarArchive handlers */
|
||||||
static int rararch_handlers_preamble(handler_this_t *object, rar_file_t **rar TSRMLS_DC);
|
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC);
|
||||||
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, zend_long *index, int quiet TSRMLS_DC);
|
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, long *index, int quiet TSRMLS_DC);
|
||||||
static int rararch_count_elements(handler_this_t *object, zend_long *count TSRMLS_DC);
|
static int rararch_count_elements(zval *object, long *count TSRMLS_DC);
|
||||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv);
|
#if PHP_MAJOR_VERSION < 7
|
||||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC);
|
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
|
||||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC);
|
#else
|
||||||
|
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv);
|
||||||
|
#endif
|
||||||
|
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
|
||||||
|
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Function definitions with external linkage */
|
/* {{{ Function definitions with external linkage */
|
||||||
int _rar_get_file_resource_zv(zval *zv, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
return _rar_get_file_resource_ex(zval_file, rar_file, FALSE TSRMLS_CC);
|
||||||
rar_file, FALSE TSRMLS_CC);
|
|
||||||
}
|
|
||||||
int _rar_get_file_resource_zv_ex(zval *zv, rar_file_t **rar_file, int allow_closed TSRMLS_DC)
|
|
||||||
{
|
|
||||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
|
||||||
rar_file, allow_closed TSRMLS_CC);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static int _rar_get_file_resource_handler(handler_this_t *thiz,
|
|
||||||
rar_file_t **rar_file TSRMLS_DC)
|
|
||||||
{
|
|
||||||
#if PHP_MAJOR_VERSION < 8
|
|
||||||
return _rar_get_file_resource_zv(thiz, rar_file TSRMLS_CC);
|
|
||||||
#else
|
|
||||||
return _rar_get_file_resource_ex(thiz, rar_file, FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Creates a RarArchive object, all three in args will be dupped */
|
/* Creates a RarArchive object, all three in args will be dupped */
|
||||||
int _rar_create_rararch_obj(const char* resolved_path,
|
int _rar_create_rararch_obj(const char* resolved_path,
|
||||||
const char* open_password,
|
const char* open_password,
|
||||||
@@ -135,15 +133,6 @@ int _rar_create_rararch_obj(const char* resolved_path,
|
|||||||
rar->list_open_data->CmtBufSize = RAR_MAX_COMMENT_SIZE;
|
rar->list_open_data->CmtBufSize = RAR_MAX_COMMENT_SIZE;
|
||||||
rar->extract_open_data = ecalloc(1, sizeof *rar->extract_open_data);
|
rar->extract_open_data = ecalloc(1, sizeof *rar->extract_open_data);
|
||||||
rar->extract_open_data->ArcName = estrdup(resolved_path);
|
rar->extract_open_data->ArcName = estrdup(resolved_path);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
{
|
|
||||||
size_t arcnamew_len = strlen(resolved_path);
|
|
||||||
rar->list_open_data->ArcNameW = safe_emalloc(arcnamew_len, sizeof(wchar_t), sizeof(wchar));
|
|
||||||
_rar_utf_to_wide(resolved_path, rar->list_open_data->ArcNameW, arcnamew_len + 1);
|
|
||||||
rar->extract_open_data->ArcNameW = safe_emalloc(arcnamew_len, sizeof(wchar_t), sizeof(wchar));
|
|
||||||
_rar_utf_to_wide(resolved_path, rar->extract_open_data->ArcNameW, arcnamew_len + 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rar->extract_open_data->OpenMode = RAR_OM_EXTRACT;
|
rar->extract_open_data->OpenMode = RAR_OM_EXTRACT;
|
||||||
rar->extract_open_data->CmtBuf = NULL; /* not interested in it again */
|
rar->extract_open_data->CmtBuf = NULL; /* not interested in it again */
|
||||||
rar->cb_userdata.password = NULL;
|
rar->cb_userdata.password = NULL;
|
||||||
@@ -176,14 +165,8 @@ int _rar_create_rararch_obj(const char* resolved_path,
|
|||||||
|
|
||||||
efree(rar->list_open_data->ArcName);
|
efree(rar->list_open_data->ArcName);
|
||||||
efree(rar->list_open_data->CmtBuf);
|
efree(rar->list_open_data->CmtBuf);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
efree(rar->list_open_data->ArcNameW);
|
|
||||||
#endif
|
|
||||||
efree(rar->list_open_data);
|
efree(rar->list_open_data);
|
||||||
efree(rar->extract_open_data->ArcName);
|
efree(rar->extract_open_data->ArcName);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
efree(rar->extract_open_data->ArcNameW);
|
|
||||||
#endif
|
|
||||||
efree(rar->extract_open_data);
|
efree(rar->extract_open_data);
|
||||||
efree(rar);
|
efree(rar);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
@@ -198,21 +181,20 @@ void _rar_close_file_resource(rar_file_t *rar) /* {{{ */
|
|||||||
/* When changed from resource to custom object, instead of fiddling
|
/* When changed from resource to custom object, instead of fiddling
|
||||||
* with the refcount to force object destruction, an indication that
|
* with the refcount to force object destruction, an indication that
|
||||||
* the file is already closed is given by setting rar->arch_handle
|
* the file is already closed is given by setting rar->arch_handle
|
||||||
* to NULL. This is checked by _rar_get_file_resource_zv. */
|
* to NULL. This is checked by _rar_get_file_resource. */
|
||||||
RARCloseArchive(rar->arch_handle);
|
RARCloseArchive(rar->arch_handle);
|
||||||
rar->arch_handle = NULL;
|
rar->arch_handle = NULL;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* Receives archive zval, returns object struct.
|
/* Receives archive zval, returns object struct.
|
||||||
* If allow_closed is FALSE, it checks whether the archive is alredy closed, and if it
|
* If silent is FALSE, it checks whether the archive is alredy closed, and if it
|
||||||
* is, an exception/error is raised and FAILURE is returned
|
* is, an exception/error is raised and FAILURE is returned
|
||||||
*/
|
*/
|
||||||
int _rar_get_file_resource_ex(rar_obj_ref zobjref_file, rar_file_t **rar_file,
|
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC) /* {{{ */
|
||||||
int allow_closed TSRMLS_DC) /* {{{ */
|
|
||||||
{
|
{
|
||||||
ze_rararch_object *zobj;
|
ze_rararch_object *zobj;
|
||||||
zobj = rararch_object_from_ref(zobjref_file);
|
zobj = rararch_object_from_zv(zval_file TSRMLS_CC);
|
||||||
if (zobj == NULL) {
|
if (zobj == NULL) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Could not find object in the store. This is a bug, please report it.");
|
"Could not find object in the store. This is a bug, please report it.");
|
||||||
@@ -220,7 +202,7 @@ int _rar_get_file_resource_ex(rar_obj_ref zobjref_file, rar_file_t **rar_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*rar_file = zobj->rar_file;
|
*rar_file = zobj->rar_file;
|
||||||
if ((*rar_file)->arch_handle == NULL && !allow_closed) { /* rar_close was called */
|
if ((*rar_file)->arch_handle == NULL && !silent) { /* rar_close was called */
|
||||||
_rar_handle_ext_error("The archive is already closed" TSRMLS_CC);
|
_rar_handle_ext_error("The archive is already closed" TSRMLS_CC);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
@@ -252,17 +234,25 @@ static void _rar_raw_entries_to_array(rar_file_t *rar, zval *target TSRMLS_DC) /
|
|||||||
state->position, entry_obj TSRMLS_CC);
|
state->position, entry_obj TSRMLS_CC);
|
||||||
|
|
||||||
add_next_index_zval(target, entry_obj);
|
add_next_index_zval(target, entry_obj);
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
/* PHP 7 copies the zval (but without increasing the refcount of the
|
/* PHP 7 copies the zval (but without increasing the refcount of the
|
||||||
* obj). Free the allocation. */
|
* obj), while 5.x simply copies the pointer. Only for PHP 5.x do we
|
||||||
|
* keep the allocation) */
|
||||||
efree(entry_obj);
|
efree(entry_obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} while (state->eof == 0);
|
} while (state->eof == 0);
|
||||||
_rar_entry_search_end(state);
|
_rar_entry_search_end(state);
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_dtor(&rararch_obj);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&rararch_obj);
|
zval_ptr_dtor(&rararch_obj);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION >=7
|
||||||
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
||||||
{
|
{
|
||||||
return Z_OBJ(*zv);
|
return Z_OBJ(*zv);
|
||||||
@@ -272,7 +262,24 @@ static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC)
|
|||||||
ZVAL_OBJ(zv, zo);
|
ZVAL_OBJ(zv, zo);
|
||||||
zval_addref_p(zv);
|
zval_addref_p(zv);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
||||||
|
{
|
||||||
|
return Z_OBJ_HANDLE_P(zv);
|
||||||
|
}
|
||||||
|
inline void rar_obj_ref_make_zv(rar_obj_ref zoh, zval *zv TSRMLS_DC)
|
||||||
|
{
|
||||||
|
INIT_ZVAL(*zv);
|
||||||
|
Z_TYPE_P(zv) = IS_OBJECT;
|
||||||
|
Z_OBJ_HANDLE_P(zv) = zoh;
|
||||||
|
Z_OBJ_HT_P(zv) = &rararch_object_handlers;
|
||||||
|
/* object has a new reference; if not incremented, the object would be
|
||||||
|
* be destroyed when this new zval we created was destroyed */
|
||||||
|
zend_objects_store_add_ref_by_handle(zoh TSRMLS_CC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION >=7
|
||||||
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj)
|
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj)
|
||||||
{
|
{
|
||||||
return (ze_rararch_object *)
|
return (ze_rararch_object *)
|
||||||
@@ -282,12 +289,35 @@ static ze_rararch_object *rararch_object_from_zv(const zval *zv)
|
|||||||
{
|
{
|
||||||
return rararch_object_fetch(Z_OBJ_P(zv));
|
return rararch_object_fetch(Z_OBJ_P(zv));
|
||||||
}
|
}
|
||||||
static ze_rararch_object *rararch_object_from_ref(const rar_obj_ref ref)
|
#endif
|
||||||
{
|
|
||||||
return rararch_object_fetch(ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* {{{ */
|
/* {{{ */
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static zend_object_value rararch_ce_create_object(zend_class_entry *class_type TSRMLS_DC)
|
||||||
|
{
|
||||||
|
zend_object_value zov;
|
||||||
|
ze_rararch_object *zobj;
|
||||||
|
|
||||||
|
zobj = emalloc(sizeof *zobj);
|
||||||
|
/* rararch_ce_free_object_storage will attempt to access it otherwise */
|
||||||
|
zobj->rar_file = NULL;
|
||||||
|
zend_object_std_init((zend_object*) zobj, class_type TSRMLS_CC);
|
||||||
|
|
||||||
|
#if PHP_VERSION_ID < 50399
|
||||||
|
zend_hash_copy(((zend_object*)zobj)->properties,
|
||||||
|
&(class_type->default_properties),
|
||||||
|
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
|
||||||
|
#else
|
||||||
|
object_properties_init((zend_object*)zobj, class_type);
|
||||||
|
#endif
|
||||||
|
zov.handle = zend_objects_store_put(zobj,
|
||||||
|
(zend_objects_store_dtor_t) zend_objects_destroy_object,
|
||||||
|
(zend_objects_free_object_storage_t) rararch_ce_free_object_storage,
|
||||||
|
NULL TSRMLS_CC);
|
||||||
|
zov.handlers = &rararch_object_handlers;
|
||||||
|
return zov;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
||||||
{
|
{
|
||||||
ze_rararch_object *zobj =
|
ze_rararch_object *zobj =
|
||||||
@@ -299,12 +329,18 @@ static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
|||||||
|
|
||||||
return &zobj->parent;
|
return &zobj->parent;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ */
|
/* {{{ */
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC)
|
||||||
|
{
|
||||||
|
#else
|
||||||
static void rararch_ce_free_object_storage(zend_object *zobj)
|
static void rararch_ce_free_object_storage(zend_object *zobj)
|
||||||
{
|
{
|
||||||
ze_rararch_object *object = rararch_object_fetch(zobj);
|
ze_rararch_object *object = rararch_object_fetch(zobj);
|
||||||
|
#endif
|
||||||
rar_file_t *rar = object->rar_file;
|
rar_file_t *rar = object->rar_file;
|
||||||
|
|
||||||
/* may be NULL if the user did new RarArchive() */
|
/* may be NULL if the user did new RarArchive() */
|
||||||
@@ -319,14 +355,8 @@ static void rararch_ce_free_object_storage(zend_object *zobj)
|
|||||||
|
|
||||||
efree(rar->list_open_data->ArcName);
|
efree(rar->list_open_data->ArcName);
|
||||||
efree(rar->list_open_data->CmtBuf);
|
efree(rar->list_open_data->CmtBuf);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
efree(rar->list_open_data->ArcNameW);
|
|
||||||
#endif
|
|
||||||
efree(rar->list_open_data);
|
efree(rar->list_open_data);
|
||||||
efree(rar->extract_open_data->ArcName);
|
efree(rar->extract_open_data->ArcName);
|
||||||
#ifdef PHP_WIN32
|
|
||||||
efree(rar->extract_open_data->ArcNameW);
|
|
||||||
#endif
|
|
||||||
efree(rar->extract_open_data);
|
efree(rar->extract_open_data);
|
||||||
efree(rar);
|
efree(rar);
|
||||||
}
|
}
|
||||||
@@ -334,18 +364,20 @@ static void rararch_ce_free_object_storage(zend_object *zobj)
|
|||||||
/* could call zend_objects_free_object_storage here (not before!), but
|
/* could call zend_objects_free_object_storage here (not before!), but
|
||||||
* instead I'll mimic its behaviour */
|
* instead I'll mimic its behaviour */
|
||||||
zend_object_std_dtor(&object->parent TSRMLS_CC);
|
zend_object_std_dtor(&object->parent TSRMLS_CC);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
efree(object);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive handlers */
|
/* {{{ RarArchive handlers */
|
||||||
static int rararch_handlers_preamble(handler_this_t *object,
|
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||||
rar_file_t **rar TSRMLS_DC) /* {{{ */
|
|
||||||
{
|
{
|
||||||
/* don't call zend_objects_get_address or zend_object_store_get directly;
|
/* don't call zend_objects_get_address or zend_object_store_get directly;
|
||||||
* _rar_get_file_resource_zv checks if the archive was closed */
|
* _rar_get_file_resource checks if the archive was closed */
|
||||||
if (_rar_get_file_resource_handler(object, rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(object, rar TSRMLS_CC) == FAILURE) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +391,7 @@ static int rararch_handlers_preamble(handler_this_t *object,
|
|||||||
/* {{{ rararch_dimensions_preamble - semi-strict parsing of int argument */
|
/* {{{ rararch_dimensions_preamble - semi-strict parsing of int argument */
|
||||||
static int rararch_dimensions_preamble(rar_file_t *rar,
|
static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||||
zval *offset,
|
zval *offset,
|
||||||
zend_long *index,
|
long *index,
|
||||||
int quiet TSRMLS_DC)
|
int quiet TSRMLS_DC)
|
||||||
{
|
{
|
||||||
if (offset == NULL) {
|
if (offset == NULL) {
|
||||||
@@ -383,32 +415,34 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
else if (type == IS_DOUBLE) {
|
else if (type == IS_DOUBLE) {
|
||||||
if (d > (double) ZEND_LONG_MAX || d < (double) ZEND_LONG_MIN) {
|
if (d > LONG_MAX || d < LONG_MIN) {
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Dimension index is out of integer bounds");
|
"Dimension index is out of integer bounds");
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*index = (zend_long) d;
|
*index = (long) d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||||
if (Z_DVAL_P(offset) > (double) ZEND_LONG_MAX ||
|
if (Z_DVAL_P(offset) > LONG_MAX || Z_DVAL_P(offset) < LONG_MIN) {
|
||||||
Z_DVAL_P(offset) < (double) ZEND_LONG_MIN) {
|
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Dimension index is out of integer bounds");
|
"Dimension index is out of integer bounds");
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
*index = (zend_long) Z_DVAL_P(offset);
|
*index = (long) Z_DVAL_P(offset);
|
||||||
}
|
}
|
||||||
else if (Z_TYPE_P(offset) == IS_OBJECT) {
|
else if (Z_TYPE_P(offset) == IS_OBJECT) {
|
||||||
#if PHP_MAJOR_VERSION < 8
|
|
||||||
if (Z_OBJ_HT_P(offset)->get) {
|
if (Z_OBJ_HT_P(offset)->get) {
|
||||||
zval *newoffset = NULL;
|
zval *newoffset = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
newoffset = Z_OBJ_HT_P(offset)->get(offset TSRMLS_CC);
|
||||||
|
#else
|
||||||
zval zv_holder;
|
zval zv_holder;
|
||||||
ZVAL_NULL(&zv_holder);
|
ZVAL_NULL(&zv_holder);
|
||||||
newoffset = Z_OBJ_HT_P(offset)->get(offset, &zv_holder);
|
newoffset = Z_OBJ_HT_P(offset)->get(offset, &zv_holder);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get handler cannot return NULL */
|
/* get handler cannot return NULL */
|
||||||
assert(newoffset != NULL);
|
assert(newoffset != NULL);
|
||||||
@@ -421,28 +455,12 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
|||||||
|
|
||||||
ret = rararch_dimensions_preamble(rar, newoffset, index, quiet
|
ret = rararch_dimensions_preamble(rar, newoffset, index, quiet
|
||||||
TSRMLS_CC);
|
TSRMLS_CC);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_ptr_dtor(&newoffset);
|
||||||
|
#else
|
||||||
zval_ptr_dtor(newoffset);
|
zval_ptr_dtor(newoffset);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
} else
|
|
||||||
#endif // PHP < 8
|
|
||||||
if (Z_OBJ_HT_P(offset)->cast_object) {
|
|
||||||
zval newoffset;
|
|
||||||
int res = Z_OBJ_HT_P(offset)->cast_object(
|
|
||||||
ZV_TO_THIS_FOR_HANDLER(offset), &newoffset, IS_LONG TSRMLS_CC);
|
|
||||||
if (res == FAILURE) {
|
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
|
||||||
"Could not convert object given as dimension index into "
|
|
||||||
"an integer (cast_object failed)");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
if (Z_TYPE(newoffset) != IS_LONG) {
|
|
||||||
zval_dtor(&newoffset);
|
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
|
||||||
"Could not convert object given as dimension index into "
|
|
||||||
"an integer (cast_object did not return int as asked)");
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
*index = Z_LVAL(newoffset);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||||
@@ -458,9 +476,9 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*index < 0) {
|
if (*index < 0L) {
|
||||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||||
"Dimension index must be non-negative, given " ZEND_LONG_FMT, *index);
|
"Dimension index must be non-negative, given %ld", *index);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
if ((size_t) *index >= _rar_entry_count(rar)) {
|
if ((size_t) *index >= _rar_entry_count(rar)) {
|
||||||
@@ -475,30 +493,34 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive count_elements handler */
|
/* {{{ RarArchive count_elements handler */
|
||||||
static int rararch_count_elements(handler_this_t *object, zend_long *count TSRMLS_DC)
|
static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||||
{
|
{
|
||||||
rar_file_t *rar = NULL;
|
rar_file_t *rar = NULL;
|
||||||
size_t entry_count;
|
size_t entry_count;
|
||||||
|
|
||||||
if (rararch_handlers_preamble(object, &rar TSRMLS_CC) == FAILURE) {
|
if (rararch_handlers_preamble(object, &rar TSRMLS_CC) == FAILURE) {
|
||||||
*count = 0;
|
*count = 0L;
|
||||||
return SUCCESS; /* intentional */
|
return SUCCESS; /* intentional */
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_count = _rar_entry_count(rar);
|
entry_count = _rar_entry_count(rar);
|
||||||
if (entry_count > ZEND_LONG_MAX)
|
if (entry_count > LONG_MAX)
|
||||||
entry_count = (size_t) ZEND_LONG_MAX;
|
entry_count = (size_t) LONG_MAX;
|
||||||
|
|
||||||
*count = (zend_long) entry_count;
|
*count = (long) entry_count;
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive read_dimension handler */
|
/* {{{ RarArchive read_dimension handler */
|
||||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv)
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||||
|
#else
|
||||||
|
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
zend_long index;
|
long index;
|
||||||
rar_file_t *rar = NULL;
|
rar_file_t *rar = NULL;
|
||||||
struct _rar_find_output *out;
|
struct _rar_find_output *out;
|
||||||
zval *ret = NULL;
|
zval *ret = NULL;
|
||||||
@@ -519,24 +541,23 @@ static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int ty
|
|||||||
_rar_entry_search_seek(out, (size_t) index);
|
_rar_entry_search_seek(out, (size_t) index);
|
||||||
_rar_entry_search_advance(out, NULL, 0, 0);
|
_rar_entry_search_advance(out, NULL, 0, 0);
|
||||||
assert(out->found);
|
assert(out->found);
|
||||||
ret = rv;
|
#if PHP_MAJOR_VERSION < 7
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
ALLOC_INIT_ZVAL(ret);
|
||||||
zval object_zv;
|
|
||||||
ZVAL_OBJ(&object_zv, object);
|
|
||||||
|
|
||||||
_rar_entry_to_zval(&object_zv, out->header, out->packed_size, out->position,
|
|
||||||
ret TSRMLS_CC);
|
|
||||||
#else
|
#else
|
||||||
|
ret = rv;
|
||||||
|
#endif
|
||||||
_rar_entry_to_zval(object, out->header, out->packed_size, out->position,
|
_rar_entry_to_zval(object, out->header, out->packed_size, out->position,
|
||||||
ret TSRMLS_CC);
|
ret TSRMLS_CC);
|
||||||
#endif
|
|
||||||
_rar_entry_search_end(out);
|
_rar_entry_search_end(out);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
Z_DELREF_P(ret); /* set refcount to 0 */
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive write_dimension handler */
|
/* {{{ RarArchive write_dimension handler */
|
||||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC)
|
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
"A RarArchive object is not writable");
|
"A RarArchive object is not writable");
|
||||||
@@ -544,9 +565,9 @@ static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive has_dimension handler */
|
/* {{{ RarArchive has_dimension handler */
|
||||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC)
|
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zend_long index;
|
long index;
|
||||||
rar_file_t *rar = NULL;
|
rar_file_t *rar = NULL;
|
||||||
|
|
||||||
(void) check_empty; /* don't care */
|
(void) check_empty; /* don't care */
|
||||||
@@ -561,7 +582,7 @@ static int rararch_has_dimension(handler_this_t *object, zval *offset, int check
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ RarArchive unset_dimension handler */
|
/* {{{ RarArchive unset_dimension handler */
|
||||||
static void rararch_unset_dimension(handler_this_t *object, zval *offset TSRMLS_DC)
|
static void rararch_unset_dimension(zval *object, zval *offset TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
"A RarArchive object is not writable");
|
"A RarArchive object is not writable");
|
||||||
@@ -601,7 +622,11 @@ PHP_FUNCTION(rar_open)
|
|||||||
assert(strnlen(resolved_path, MAXPATHLEN) < MAXPATHLEN);
|
assert(strnlen(resolved_path, MAXPATHLEN) < MAXPATHLEN);
|
||||||
|
|
||||||
if (callable != NULL) { /* given volume resolver callback */
|
if (callable != NULL) { /* given volume resolver callback */
|
||||||
|
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 2
|
||||||
|
if (!zend_is_callable(callable, IS_CALLABLE_STRICT, NULL)) {
|
||||||
|
#else
|
||||||
if (!zend_is_callable(callable, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
if (!zend_is_callable(callable, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
||||||
|
#endif
|
||||||
_rar_handle_ext_error("%s" TSRMLS_CC, "Expected the third "
|
_rar_handle_ext_error("%s" TSRMLS_CC, "Expected the third "
|
||||||
"argument, if provided, to be a valid callback");
|
"argument, if provided, to be a valid callback");
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
@@ -636,7 +661,7 @@ PHP_FUNCTION(rar_list)
|
|||||||
|
|
||||||
RAR_THIS_OR_NO_ARGS(file);
|
RAR_THIS_OR_NO_ARGS(file);
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,7 +696,7 @@ PHP_FUNCTION(rar_entry_get)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,7 +733,7 @@ PHP_FUNCTION(rar_solid_is)
|
|||||||
|
|
||||||
RAR_THIS_OR_NO_ARGS(file);
|
RAR_THIS_OR_NO_ARGS(file);
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +751,7 @@ PHP_FUNCTION(rar_comment_get)
|
|||||||
|
|
||||||
RAR_THIS_OR_NO_ARGS(file);
|
RAR_THIS_OR_NO_ARGS(file);
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,7 +782,7 @@ PHP_FUNCTION(rar_broken_is)
|
|||||||
|
|
||||||
RAR_THIS_OR_NO_ARGS(file);
|
RAR_THIS_OR_NO_ARGS(file);
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,7 +813,7 @@ PHP_FUNCTION(rar_allow_broken_set)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,7 +831,7 @@ PHP_FUNCTION(rar_close)
|
|||||||
|
|
||||||
RAR_THIS_OR_NO_ARGS(file);
|
RAR_THIS_OR_NO_ARGS(file);
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,8 +855,7 @@ PHP_METHOD(rararch, __toString)
|
|||||||
|
|
||||||
RAR_RETNULL_ON_ARGS();
|
RAR_RETNULL_ON_ARGS();
|
||||||
|
|
||||||
if (_rar_get_file_resource_zv_ex(arch_obj, &rar, TRUE TSRMLS_CC)
|
if (_rar_get_file_resource_ex(arch_obj, &rar, TRUE TSRMLS_CC) == FAILURE) {
|
||||||
== FAILURE) {
|
|
||||||
RETURN_FALSE; /* should never happen */
|
RETURN_FALSE; /* should never happen */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,18 +876,6 @@ PHP_METHOD(rararch, __toString)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto string RarEntry::getIterator() */
|
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
|
||||||
PHP_METHOD(rararch, getIterator)
|
|
||||||
{
|
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
zend_create_internal_iterator_zval(return_value, getThis());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ arginfo */
|
/* {{{ arginfo */
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_open, 0, 0, 1)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_open, 0, 0, 1)
|
||||||
ZEND_ARG_INFO(0, filename)
|
ZEND_ARG_INFO(0, filename)
|
||||||
@@ -879,23 +891,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_setallowbroken, 0, 0, 1)
|
|||||||
ZEND_ARG_INFO(0, allow_broken)
|
ZEND_ARG_INFO(0, allow_broken)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
|
||||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_rararchive_getiterator, 0, 0, Traversable, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(arginfo_rararchive_void, 0)
|
ZEND_BEGIN_ARG_INFO(arginfo_rararchive_void, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
#if PHP_VERSION_ID >= 80200
|
|
||||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rararchive_tostring, 0, 0, IS_STRING, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
#else
|
|
||||||
#define arginfo_rararchive_tostring arginfo_rararchive_void
|
|
||||||
#endif
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
static zend_function_entry php_rararch_class_functions[] = {
|
static zend_function_entry php_rararch_class_functions[] = {
|
||||||
PHP_ME_MAPPING(open, rar_open, arginfo_rararchive_open, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
|
PHP_ME_MAPPING(open, rar_open, arginfo_rararchive_open, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
|
||||||
PHP_ME_MAPPING(getEntries, rar_list, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
PHP_ME_MAPPING(getEntries, rar_list, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||||
@@ -908,14 +907,10 @@ static zend_function_entry php_rararch_class_functions[] = {
|
|||||||
PHP_ME_MAPPING(isBroken, rar_broken_is, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
PHP_ME_MAPPING(isBroken, rar_broken_is, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME_MAPPING(setAllowBroken, rar_allow_broken_set, arginfo_rararchive_setallowbroken, ZEND_ACC_PUBLIC)
|
PHP_ME_MAPPING(setAllowBroken, rar_allow_broken_set, arginfo_rararchive_setallowbroken, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME_MAPPING(close, rar_close, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
PHP_ME_MAPPING(close, rar_close, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(rararch, __toString, arginfo_rararchive_tostring, ZEND_ACC_PUBLIC)
|
PHP_ME(rararch, __toString, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rararchive_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rararchive_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
|
||||||
PHP_ME(rararch, getIterator, arginfo_rararchive_getiterator, ZEND_ACC_PUBLIC)
|
|
||||||
#endif
|
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/* {{{ Iteration. Very boring stuff indeed. */
|
/* {{{ Iteration. Very boring stuff indeed. */
|
||||||
|
|
||||||
@@ -927,17 +922,78 @@ static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
|||||||
static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC);
|
static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC);
|
||||||
static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC);
|
static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC);
|
||||||
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC);
|
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static void rararch_it_current_data(zend_object_iterator *iter,
|
||||||
|
zval ***data TSRMLS_DC);
|
||||||
|
#else
|
||||||
static zval *rararch_it_current_data(zend_object_iterator *iter);
|
static zval *rararch_it_current_data(zend_object_iterator *iter);
|
||||||
|
#endif
|
||||||
static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
|
static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
|
||||||
static void rararch_it_rewind(zend_object_iterator *iter TSRMLS_DC);
|
static void rararch_it_rewind(zend_object_iterator *iter TSRMLS_DC);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ rararch_it_get_iterator */
|
||||||
|
static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||||
|
zval *object,
|
||||||
|
int by_ref TSRMLS_DC)
|
||||||
|
{
|
||||||
|
rararch_iterator *it;
|
||||||
|
rar_file_t *rar;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (by_ref) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
|
"An iterator cannot be used with foreach by reference");
|
||||||
|
}
|
||||||
|
|
||||||
|
it = emalloc(sizeof *it);
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_add_ref(&object);
|
||||||
|
it->parent.data = object;
|
||||||
|
it->value = NULL;
|
||||||
|
#else
|
||||||
|
zend_iterator_init((zend_object_iterator *) it);
|
||||||
|
ZVAL_COPY(&it->parent.data, object);
|
||||||
|
ZVAL_UNDEF(&it->value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
it->parent.funcs = ce->iterator_funcs.funcs;
|
||||||
|
it->state = NULL;
|
||||||
|
|
||||||
|
res = _rar_get_file_resource_ex(object, &rar, 1 TSRMLS_CC);
|
||||||
|
if (res == FAILURE)
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
|
"Cannot fetch RarArchive object");
|
||||||
|
if (rar->arch_handle == NULL)
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
|
"The archive is already closed, cannot give an iterator");
|
||||||
|
res = _rar_list_files(rar TSRMLS_CC);
|
||||||
|
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
||||||
|
/* if it failed, do not expose the possibly incomplete entry list */
|
||||||
|
it->empty_iterator = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it->empty_iterator = 0;
|
||||||
|
|
||||||
|
_rar_entry_search_start(rar, RAR_SEARCH_TRAVERSE, &it->state TSRMLS_CC);
|
||||||
|
return (zend_object_iterator*) it;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ rararch_it_invalidate_current */
|
/* {{{ rararch_it_invalidate_current */
|
||||||
static void rararch_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
|
static void rararch_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
|
||||||
{
|
{
|
||||||
rararch_iterator *it = (rararch_iterator *) iter;
|
rararch_iterator *it = (rararch_iterator *) iter;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
if (it->value != NULL) {
|
||||||
|
zval_ptr_dtor(&it->value);
|
||||||
|
it->value = NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&it->value);
|
zval_ptr_dtor(&it->value);
|
||||||
ZVAL_UNDEF(&it->value);
|
ZVAL_UNDEF(&it->value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -948,9 +1004,16 @@ static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC)
|
|||||||
|
|
||||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval_ptr_dtor((zval**) &it->parent.data); /* decrease refcount on zval object */
|
||||||
|
#else
|
||||||
zval_ptr_dtor(&it->parent.data);
|
zval_ptr_dtor(&it->parent.data);
|
||||||
|
#endif
|
||||||
|
|
||||||
_rar_entry_search_end(it->state);
|
_rar_entry_search_end(it->state);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
efree(it);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -961,47 +1024,91 @@ static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC)
|
|||||||
int res;
|
int res;
|
||||||
zval *robj;
|
zval *robj;
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
assert(it->value == NULL);
|
||||||
|
#else
|
||||||
assert(Z_TYPE(it->value) == IS_UNDEF);
|
assert(Z_TYPE(it->value) == IS_UNDEF);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (it->empty_iterator) {
|
if (it->empty_iterator) {
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
MAKE_STD_ZVAL(it->value);
|
||||||
|
ZVAL_FALSE(it->value);
|
||||||
|
#else
|
||||||
ZVAL_FALSE(&it->value);
|
ZVAL_FALSE(&it->value);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
robj = it->parent.data;
|
||||||
|
#else
|
||||||
robj = &it->parent.data;
|
robj = &it->parent.data;
|
||||||
|
#endif
|
||||||
|
|
||||||
res = _rar_get_file_resource_zv_ex(robj, &rar_file, 1 TSRMLS_CC);
|
res = _rar_get_file_resource_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||||
if (res == FAILURE)
|
if (res == FAILURE)
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||||
"Cannot fetch RarArchive object");
|
"Cannot fetch RarArchive object");
|
||||||
|
|
||||||
_rar_entry_search_advance(it->state, NULL, 0, 0);
|
_rar_entry_search_advance(it->state, NULL, 0, 0);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
MAKE_STD_ZVAL(it->value);
|
||||||
|
if (it->state->found)
|
||||||
|
_rar_entry_to_zval(robj, it->state->header, it->state->packed_size,
|
||||||
|
it->state->position, it->value TSRMLS_CC);
|
||||||
|
else {
|
||||||
|
ZVAL_FALSE(it->value);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (it->state->found)
|
if (it->state->found)
|
||||||
_rar_entry_to_zval(&it->parent.data, it->state->header,
|
_rar_entry_to_zval(&it->parent.data, it->state->header,
|
||||||
it->state->packed_size, it->state->position, &it->value TSRMLS_CC);
|
it->state->packed_size, it->state->position, &it->value TSRMLS_CC);
|
||||||
else {
|
else {
|
||||||
ZVAL_FALSE(&it->value);
|
ZVAL_FALSE(&it->value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ rararch_it_valid */
|
/* {{{ rararch_it_valid */
|
||||||
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC)
|
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC)
|
||||||
{
|
{
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval *value = ((rararch_iterator *) iter)->value;
|
||||||
|
assert(value != NULL);
|
||||||
|
return (Z_TYPE_P(value) != IS_BOOL)?SUCCESS:FAILURE;
|
||||||
|
#else
|
||||||
zval *value = &((rararch_iterator *) iter)->value;
|
zval *value = &((rararch_iterator *) iter)->value;
|
||||||
assert(Z_TYPE_P(value) != IS_UNDEF);
|
assert(Z_TYPE_P(value) != IS_UNDEF);
|
||||||
return Z_TYPE_P(value) != IS_FALSE ? SUCCESS : FAILURE;
|
return Z_TYPE_P(value) != IS_FALSE ? SUCCESS : FAILURE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ rararch_it_current_data */
|
/* {{{ rararch_it_current_data */
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
static void rararch_it_current_data(zend_object_iterator *iter,
|
||||||
|
zval ***data TSRMLS_DC)
|
||||||
|
{
|
||||||
|
zval **value = &(((rararch_iterator *) iter)->value);
|
||||||
|
assert(*value != NULL);
|
||||||
|
*data = value;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static zval *rararch_it_current_data(zend_object_iterator *iter)
|
static zval *rararch_it_current_data(zend_object_iterator *iter)
|
||||||
{
|
{
|
||||||
zval *ret;
|
zval *ret;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
ret = ((rararch_iterator *) iter)->value;
|
||||||
|
assert(ret != NULL);
|
||||||
|
#else
|
||||||
ret = &((rararch_iterator *) iter)->value;
|
ret = &((rararch_iterator *) iter)->value;
|
||||||
assert(Z_TYPE_P(ret) != IS_UNDEF);
|
assert(Z_TYPE_P(ret) != IS_UNDEF);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ rararch_it_move_forward */
|
/* {{{ rararch_it_move_forward */
|
||||||
@@ -1009,7 +1116,11 @@ static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
|||||||
{
|
{
|
||||||
rararch_iterator *it = (rararch_iterator *) iter;
|
rararch_iterator *it = (rararch_iterator *) iter;
|
||||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
it->value = NULL;
|
||||||
|
#else
|
||||||
ZVAL_UNDEF(&it->value);
|
ZVAL_UNDEF(&it->value);
|
||||||
|
#endif
|
||||||
rararch_it_fetch(it TSRMLS_CC);
|
rararch_it_fetch(it TSRMLS_CC);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -1036,55 +1147,6 @@ static zend_object_iterator_funcs rararch_it_funcs = {
|
|||||||
};
|
};
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ rararch_it_get_iterator */
|
|
||||||
static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
|
||||||
zval *object,
|
|
||||||
int by_ref TSRMLS_DC)
|
|
||||||
{
|
|
||||||
rar_file_t *rar;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (by_ref) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
|
||||||
"An iterator cannot be used with foreach by reference");
|
|
||||||
}
|
|
||||||
|
|
||||||
res = _rar_get_file_resource_zv_ex(object, &rar, 1 TSRMLS_CC);
|
|
||||||
if (res == FAILURE) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
|
||||||
"Cannot fetch RarArchive object");
|
|
||||||
}
|
|
||||||
if (rar->arch_handle == NULL) {
|
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
|
||||||
"The archive is already closed, cannot give an iterator");
|
|
||||||
}
|
|
||||||
|
|
||||||
rararch_iterator *it = emalloc(sizeof *it);
|
|
||||||
|
|
||||||
zend_iterator_init((zend_object_iterator *) it);
|
|
||||||
ZVAL_COPY(&it->parent.data, object);
|
|
||||||
ZVAL_UNDEF(&it->value);
|
|
||||||
|
|
||||||
#if PHP_VERSION_ID < 70300
|
|
||||||
it->parent.funcs = ce->iterator_funcs.funcs;
|
|
||||||
#else
|
|
||||||
it->parent.funcs = &rararch_it_funcs;
|
|
||||||
#endif
|
|
||||||
it->state = NULL;
|
|
||||||
|
|
||||||
res = _rar_list_files(rar TSRMLS_CC);
|
|
||||||
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
|
||||||
/* if it failed, do not expose the possibly incomplete entry list */
|
|
||||||
it->empty_iterator = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
it->empty_iterator = 0;
|
|
||||||
|
|
||||||
_rar_entry_search_start(rar, RAR_SEARCH_TRAVERSE, &it->state TSRMLS_CC);
|
|
||||||
return (zend_object_iterator*) it;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
void minit_rararch(TSRMLS_D)
|
void minit_rararch(TSRMLS_D)
|
||||||
{
|
{
|
||||||
zend_class_entry ce;
|
zend_class_entry ce;
|
||||||
@@ -1097,8 +1159,10 @@ void minit_rararch(TSRMLS_D)
|
|||||||
rararch_object_handlers.has_dimension = rararch_has_dimension;
|
rararch_object_handlers.has_dimension = rararch_has_dimension;
|
||||||
rararch_object_handlers.unset_dimension = rararch_unset_dimension;
|
rararch_object_handlers.unset_dimension = rararch_unset_dimension;
|
||||||
rararch_object_handlers.clone_obj = NULL;
|
rararch_object_handlers.clone_obj = NULL;
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
rararch_object_handlers.free_obj = rararch_ce_free_object_storage;
|
rararch_object_handlers.free_obj = rararch_ce_free_object_storage;
|
||||||
rararch_object_handlers.offset = XtOffsetOf(ze_rararch_object, parent);
|
rararch_object_handlers.offset = XtOffsetOf(ze_rararch_object, parent);
|
||||||
|
#endif
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce, "RarArchive", php_rararch_class_functions);
|
INIT_CLASS_ENTRY(ce, "RarArchive", php_rararch_class_functions);
|
||||||
rararch_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
rararch_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||||
@@ -1106,12 +1170,10 @@ void minit_rararch(TSRMLS_D)
|
|||||||
rararch_ce_ptr->clone = NULL;
|
rararch_ce_ptr->clone = NULL;
|
||||||
rararch_ce_ptr->create_object = &rararch_ce_create_object;
|
rararch_ce_ptr->create_object = &rararch_ce_create_object;
|
||||||
rararch_ce_ptr->get_iterator = rararch_it_get_iterator;
|
rararch_ce_ptr->get_iterator = rararch_it_get_iterator;
|
||||||
#if PHP_VERSION_ID < 70300
|
|
||||||
rararch_ce_ptr->iterator_funcs.funcs = &rararch_it_funcs;
|
rararch_ce_ptr->iterator_funcs.funcs = &rararch_it_funcs;
|
||||||
#endif
|
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
|
||||||
zend_class_implements(rararch_ce_ptr TSRMLS_CC, 1, zend_ce_aggregate);
|
|
||||||
#else
|
|
||||||
zend_class_implements(rararch_ce_ptr TSRMLS_CC, 1, zend_ce_traversable);
|
zend_class_implements(rararch_ce_ptr TSRMLS_CC, 1, zend_ce_traversable);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
+80
-104
@@ -27,10 +27,11 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <zend_types.h>
|
#ifdef __cplusplus
|
||||||
#ifndef _GNU_SOURCE
|
extern "C" {
|
||||||
# define _GNU_SOURCE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <php.h>
|
#include <php.h>
|
||||||
@@ -45,50 +46,55 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
|||||||
int name_length, char *doc_comment,
|
int name_length, char *doc_comment,
|
||||||
int doc_comment_len TSRMLS_DC);
|
int doc_comment_len TSRMLS_DC);
|
||||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC);
|
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC);
|
||||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string);
|
static void _rar_dos_date_to_text(int dos_time, char *date_string);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Functions with external linkage */
|
/* {{{ Functions with external linkage */
|
||||||
/* should be passed the last entry that corresponds to a given file
|
/* should be passed the last entry that corresponds to a given file
|
||||||
* only that one has the correct CRC. Still, it may have a wrong packedSize */
|
* only that one has the correct CRC. Still, it may have a wrong packedSize */
|
||||||
/* parent is zval to RarArchive object. The object
|
/* parent is zval to RarArchive object. The object (not the zval, in PHP 5.x)
|
||||||
* will have its refcount increased */
|
* will have its refcount increased */
|
||||||
void _rar_entry_to_zval(zval *parent,
|
void _rar_entry_to_zval(zval *parent,
|
||||||
struct RARHeaderDataEx *entry,
|
struct RARHeaderDataEx *entry,
|
||||||
zend_ulong packed_size,
|
unsigned long packed_size,
|
||||||
size_t position,
|
size_t position,
|
||||||
zval *object TSRMLS_DC)
|
zval *object TSRMLS_DC) /* {{{ */
|
||||||
/* {{{ */
|
|
||||||
{
|
{
|
||||||
char tmp_s [MAX_LENGTH_OF_LONG + 1];
|
char tmp_s [MAX_LENGTH_OF_LONG + 1];
|
||||||
char time[50];
|
char time[50];
|
||||||
char *filename;
|
char *filename;
|
||||||
int filename_size,
|
int filename_size,
|
||||||
filename_len;
|
filename_len;
|
||||||
zend_long unp_size;
|
long unp_size; /* zval stores PHP ints as long, so use that here */
|
||||||
zval *parent_copy = parent;
|
zval *parent_copy = parent;
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
object_init_ex(object, rar_class_entry_ptr);
|
/* allocate zval on the heap */
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
zval_addref_p(parent_copy);
|
||||||
zend_object *obj = Z_OBJ_P(object);
|
SEPARATE_ZVAL(&parent_copy);
|
||||||
#else
|
/* set refcount to 0; zend_update_property will increase it */
|
||||||
zval *obj = object;
|
Z_DELREF_P(parent_copy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
zend_update_property(rar_class_entry_ptr, obj, "rarfile",
|
object_init_ex(object, rar_class_entry_ptr);
|
||||||
|
zend_update_property(rar_class_entry_ptr, object, "rarfile",
|
||||||
sizeof("rararch") - 1, parent_copy TSRMLS_CC);
|
sizeof("rararch") - 1, parent_copy TSRMLS_CC);
|
||||||
|
|
||||||
{
|
#if ULONG_MAX > 0xffffffffUL
|
||||||
uint64_t raw_size = (uint64_t)entry->UnpSizeHigh << 32 | entry->UnpSize;
|
unp_size = ((long) entry->UnpSize) + (((long) entry->UnpSizeHigh) << 32);
|
||||||
unp_size = raw_size > (uint64_t)ZEND_LONG_MAX
|
#else
|
||||||
? ZEND_LONG_MAX : (zend_long)raw_size;
|
/* for 32-bit long, at least don't give negative values */
|
||||||
}
|
if ((unsigned long) entry->UnpSize > (unsigned long) LONG_MAX
|
||||||
|
|| entry->UnpSizeHigh != 0)
|
||||||
|
unp_size = LONG_MAX;
|
||||||
|
else
|
||||||
|
unp_size = (long) entry->UnpSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
filename_size = sizeof(entry->FileNameW) * 4;
|
filename_size = sizeof(entry->FileNameW) * 4;
|
||||||
filename = (char*) emalloc(filename_size);
|
filename = (char*) emalloc(filename_size);
|
||||||
|
|
||||||
if (packed_size > (zend_ulong) ZEND_LONG_MAX)
|
if (packed_size > (unsigned long) LONG_MAX)
|
||||||
packed_size = (zend_ulong) ZEND_LONG_MAX;
|
packed_size = LONG_MAX;
|
||||||
_rar_wide_to_utf(entry->FileNameW, filename, filename_size);
|
_rar_wide_to_utf(entry->FileNameW, filename, filename_size);
|
||||||
/* OK; safe usage below: */
|
/* OK; safe usage below: */
|
||||||
filename_len = _rar_strnlen(filename, filename_size);
|
filename_len = _rar_strnlen(filename, filename_size);
|
||||||
@@ -96,42 +102,42 @@ void _rar_entry_to_zval(zval *parent,
|
|||||||
* properties from here with add_property_x, or
|
* properties from here with add_property_x, or
|
||||||
* direct call to rarentry_object_handlers.write_property
|
* direct call to rarentry_object_handlers.write_property
|
||||||
* zend_update_property_x updates the scope accordingly */
|
* zend_update_property_x updates the scope accordingly */
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "position",
|
zend_update_property_long(rar_class_entry_ptr, object, "position",
|
||||||
sizeof("position") - 1, (zend_long) position TSRMLS_CC);
|
sizeof("position") - 1, (long) position TSRMLS_CC);
|
||||||
zend_update_property_stringl(rar_class_entry_ptr, obj, "name",
|
zend_update_property_stringl(rar_class_entry_ptr, object, "name",
|
||||||
sizeof("name") - 1, filename, filename_len TSRMLS_CC);
|
sizeof("name") - 1, filename, filename_len TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "unpacked_size",
|
zend_update_property_long(rar_class_entry_ptr, object, "unpacked_size",
|
||||||
sizeof("unpacked_size") - 1, unp_size TSRMLS_CC);
|
sizeof("unpacked_size") - 1, unp_size TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "packed_size",
|
zend_update_property_long(rar_class_entry_ptr, object, "packed_size",
|
||||||
sizeof("packed_size") - 1, packed_size TSRMLS_CC);
|
sizeof("packed_size") - 1, packed_size TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "host_os",
|
zend_update_property_long(rar_class_entry_ptr, object, "host_os",
|
||||||
sizeof("host_os") - 1, entry->HostOS TSRMLS_CC);
|
sizeof("host_os") - 1, entry->HostOS TSRMLS_CC);
|
||||||
|
|
||||||
_rar_dos_date_to_text(entry->FileTime, time);
|
_rar_dos_date_to_text(entry->FileTime, time);
|
||||||
zend_update_property_string(rar_class_entry_ptr, obj, "file_time",
|
zend_update_property_string(rar_class_entry_ptr, object, "file_time",
|
||||||
sizeof("file_time") - 1, time TSRMLS_CC);
|
sizeof("file_time") - 1, time TSRMLS_CC);
|
||||||
|
|
||||||
sprintf(tmp_s, "%x", entry->FileCRC);
|
sprintf(tmp_s, "%x", entry->FileCRC);
|
||||||
zend_update_property_string(rar_class_entry_ptr, obj, "crc",
|
zend_update_property_string(rar_class_entry_ptr, object, "crc",
|
||||||
sizeof("crc") - 1, tmp_s TSRMLS_CC);
|
sizeof("crc") - 1, tmp_s TSRMLS_CC);
|
||||||
|
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "attr",
|
zend_update_property_long(rar_class_entry_ptr, object, "attr",
|
||||||
sizeof("attr") - 1, entry->FileAttr TSRMLS_CC);
|
sizeof("attr") - 1, entry->FileAttr TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "version",
|
zend_update_property_long(rar_class_entry_ptr, object, "version",
|
||||||
sizeof("version") - 1, entry->UnpVer TSRMLS_CC);
|
sizeof("version") - 1, entry->UnpVer TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "method",
|
zend_update_property_long(rar_class_entry_ptr, object, "method",
|
||||||
sizeof("method") - 1, entry->Method TSRMLS_CC);
|
sizeof("method") - 1, entry->Method TSRMLS_CC);
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "flags",
|
zend_update_property_long(rar_class_entry_ptr, object, "flags",
|
||||||
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
||||||
|
|
||||||
zend_update_property_long(rar_class_entry_ptr, obj, "redir_type",
|
zend_update_property_long(rar_class_entry_ptr, object, "redir_type",
|
||||||
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
||||||
|
|
||||||
if (entry->RedirName) {
|
if (entry->RedirName) {
|
||||||
char *redir_target = NULL;
|
char *redir_target = NULL;
|
||||||
size_t redir_target_size;
|
size_t redir_target_size;
|
||||||
|
|
||||||
zend_update_property_bool(rar_class_entry_ptr, obj,
|
zend_update_property_long(rar_class_entry_ptr, object,
|
||||||
"redir_to_directory", sizeof("redir_to_directory") - 1,
|
"redir_to_directory", sizeof("redir_to_directory") - 1,
|
||||||
!!entry->DirTarget TSRMLS_CC);
|
!!entry->DirTarget TSRMLS_CC);
|
||||||
|
|
||||||
@@ -140,7 +146,7 @@ void _rar_entry_to_zval(zval *parent,
|
|||||||
assert(redir_target_size > 0);
|
assert(redir_target_size > 0);
|
||||||
_rar_wide_to_utf(entry->RedirName, redir_target, redir_target_size);
|
_rar_wide_to_utf(entry->RedirName, redir_target, redir_target_size);
|
||||||
|
|
||||||
zend_update_property_string(rar_class_entry_ptr, obj, "redir_target",
|
zend_update_property_string(rar_class_entry_ptr, object, "redir_target",
|
||||||
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
||||||
|
|
||||||
efree(redir_target);
|
efree(redir_target);
|
||||||
@@ -164,7 +170,7 @@ void _rar_entry_to_zval(zval *parent,
|
|||||||
|
|
||||||
#define REG_RAR_CLASS_CONST_LONG(const_name, value) \
|
#define REG_RAR_CLASS_CONST_LONG(const_name, value) \
|
||||||
zend_declare_class_constant_long(rar_class_entry_ptr, const_name, \
|
zend_declare_class_constant_long(rar_class_entry_ptr, const_name, \
|
||||||
sizeof(const_name) - 1, (zend_long) value TSRMLS_CC)
|
sizeof(const_name) - 1, (long) value TSRMLS_CC)
|
||||||
|
|
||||||
#define REG_RAR_PROPERTY(name, comment) \
|
#define REG_RAR_PROPERTY(name, comment) \
|
||||||
_rar_decl_priv_prop_null(rar_class_entry_ptr, name, sizeof(name) -1, \
|
_rar_decl_priv_prop_null(rar_class_entry_ptr, name, sizeof(name) -1, \
|
||||||
@@ -174,6 +180,13 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
|||||||
int name_length, char *doc_comment,
|
int name_length, char *doc_comment,
|
||||||
int doc_comment_len TSRMLS_DC) /* {{{ */
|
int doc_comment_len TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
|
#if PHP_MAJOR_VERSION < 7
|
||||||
|
zval *property;
|
||||||
|
ALLOC_PERMANENT_ZVAL(property);
|
||||||
|
INIT_ZVAL(*property);
|
||||||
|
return zend_declare_property_ex(ce, name, name_length, property,
|
||||||
|
ZEND_ACC_PRIVATE, doc_comment, doc_comment_len TSRMLS_CC);
|
||||||
|
#else
|
||||||
zval property;
|
zval property;
|
||||||
zend_string *name_str,
|
zend_string *name_str,
|
||||||
*doc_str;
|
*doc_str;
|
||||||
@@ -182,32 +195,29 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
|||||||
ZVAL_NULL(&property);
|
ZVAL_NULL(&property);
|
||||||
name_str = zend_string_init(name, (size_t) name_length, 1);
|
name_str = zend_string_init(name, (size_t) name_length, 1);
|
||||||
doc_str = zend_string_init(doc_comment, (size_t) doc_comment_len, 1);
|
doc_str = zend_string_init(doc_comment, (size_t) doc_comment_len, 1);
|
||||||
# if PHP_MAJOR_VERSION >= 8
|
|
||||||
zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
|
||||||
doc_str);
|
|
||||||
ret = SUCCESS;
|
|
||||||
# else
|
|
||||||
ret = zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
ret = zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
||||||
doc_str);
|
doc_str);
|
||||||
#endif
|
|
||||||
zend_string_release(name_str);
|
zend_string_release(name_str);
|
||||||
zend_string_release(doc_str);
|
zend_string_release(doc_str);
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC) /* {{{ */
|
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
zval *tmp;
|
zval *tmp;
|
||||||
|
#if PHP_MAJOR_VERSION >= 7
|
||||||
zval zv;
|
zval zv;
|
||||||
|
#endif
|
||||||
#if PHP_VERSION_ID < 70100
|
#if PHP_VERSION_ID < 70100
|
||||||
zend_class_entry *orig_scope = EG(scope);
|
zend_class_entry *orig_scope = EG(scope);
|
||||||
|
|
||||||
EG(scope) = rar_class_entry_ptr;
|
EG(scope) = rar_class_entry_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PHP_MAJOR_VERSION >= 8
|
#if PHP_MAJOR_VERSION < 7
|
||||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), Z_OBJ_P(entry_obj), name, namelen, 1, &zv);
|
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1 TSRMLS_CC);
|
||||||
#else
|
#else
|
||||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
||||||
#endif
|
#endif
|
||||||
@@ -224,29 +234,24 @@ static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TS
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string) /* {{{ */
|
static void _rar_dos_date_to_text(int dos_time, char *date_string) /* {{{ */
|
||||||
{
|
{
|
||||||
time_t time = 0;
|
int second, minute, hour, day, month, year;
|
||||||
struct tm tm = {0};
|
/* following lines were taken from timefn.cpp */
|
||||||
int res;
|
second = (dos_time & 0x1f)*2;
|
||||||
|
minute = (dos_time>>5) & 0x3f;
|
||||||
res = rar_dos_time_convert(dos_time, &time) != FAILURE &&
|
hour = (dos_time>>11) & 0x1f;
|
||||||
php_gmtime_r(&time, &tm) != NULL;
|
day = (dos_time>>16) & 0x1f;
|
||||||
|
month = (dos_time>>21) & 0x0f;
|
||||||
if (!res) {
|
year = (dos_time>>25)+1980;
|
||||||
sprintf(date_string, "%s", "time conversion failure");
|
sprintf(date_string, "%u-%02u-%02u %02u:%02u:%02u", year, month, day, hour, minute, second);
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(date_string, "%u-%02u-%02u %02u:%02u:%02u",
|
|
||||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
|
|
||||||
tm.tm_sec);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Methods */
|
/* {{{ Methods */
|
||||||
/* {{{ public function extract(?string $dir, ?string $filepath = '',
|
/* {{{ proto bool RarEntry::extract(string dir [, string filepath = ''
|
||||||
?string $password = null, bool $extended_data = false): void {}
|
[, string password = NULL [, bool extended_data = FALSE]])
|
||||||
Extract file from the archive */
|
Extract file from the archive */
|
||||||
PHP_METHOD(rarentry, extract)
|
PHP_METHOD(rarentry, extract)
|
||||||
{ /* lots of variables, but no need to be intimidated */
|
{ /* lots of variables, but no need to be intimidated */
|
||||||
@@ -265,7 +270,7 @@ PHP_METHOD(rarentry, extract)
|
|||||||
*tmp_position;
|
*tmp_position;
|
||||||
rar_file_t *rar = NULL;
|
rar_file_t *rar = NULL;
|
||||||
zval *entry_obj = getThis();
|
zval *entry_obj = getThis();
|
||||||
struct RARHeaderDataEx entry = {0};
|
struct RARHeaderDataEx entry;
|
||||||
HANDLE extract_handle = NULL;
|
HANDLE extract_handle = NULL;
|
||||||
int result;
|
int result;
|
||||||
int found;
|
int found;
|
||||||
@@ -273,14 +278,14 @@ PHP_METHOD(rarentry, extract)
|
|||||||
* password that's different from the one stored in the rar_file_t object*/
|
* password that's different from the one stored in the rar_file_t object*/
|
||||||
rar_cb_user_data cb_udata = {NULL};
|
rar_cb_user_data cb_udata = {NULL};
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!|s!s!b", &dir,
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss!b", &dir,
|
||||||
&dir_len, &filepath, &filepath_len, &password, &password_len,
|
&dir_len, &filepath, &filepath_len, &password, &password_len,
|
||||||
&process_ed) == FAILURE ) {
|
&process_ed) == FAILURE ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,25 +346,12 @@ PHP_METHOD(rarentry, extract)
|
|||||||
cb_udata.password = password;
|
cb_udata.password = password;
|
||||||
|
|
||||||
/* Do extraction */
|
/* Do extraction */
|
||||||
#ifdef PHP_WIN32
|
|
||||||
{
|
|
||||||
size_t path_w_len = strlen(considered_path_res);
|
|
||||||
wchar_t *path_w = safe_emalloc(path_w_len, sizeof(wchar_t), sizeof(wchar));
|
|
||||||
_rar_utf_to_wide(considered_path_res, path_w, path_w_len + 1);
|
|
||||||
if (!with_second_arg)
|
|
||||||
result = RARProcessFileW(extract_handle, RAR_EXTRACT, path_w, NULL);
|
|
||||||
else
|
|
||||||
result = RARProcessFileW(extract_handle, RAR_EXTRACT, NULL, path_w);
|
|
||||||
efree(path_w);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (!with_second_arg)
|
if (!with_second_arg)
|
||||||
result = RARProcessFile(extract_handle, RAR_EXTRACT,
|
result = RARProcessFile(extract_handle, RAR_EXTRACT,
|
||||||
considered_path_res, NULL);
|
considered_path_res, NULL);
|
||||||
else
|
else
|
||||||
result = RARProcessFile(extract_handle, RAR_EXTRACT,
|
result = RARProcessFile(extract_handle, RAR_EXTRACT,
|
||||||
NULL, considered_path_res);
|
NULL, considered_path_res);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_rar_handle_error(result TSRMLS_CC) == FAILURE) {
|
if (_rar_handle_error(result TSRMLS_CC) == FAILURE) {
|
||||||
RETVAL_FALSE;
|
RETVAL_FALSE;
|
||||||
@@ -547,7 +539,7 @@ PHP_METHOD(rarentry, getStream)
|
|||||||
|
|
||||||
RAR_GET_PROPERTY(position, "position");
|
RAR_GET_PROPERTY(position, "position");
|
||||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +566,7 @@ PHP_METHOD(rarentry, isDirectory)
|
|||||||
{
|
{
|
||||||
zval *tmp;
|
zval *tmp;
|
||||||
zval *entry_obj = getThis();
|
zval *entry_obj = getThis();
|
||||||
zend_long flags;
|
long flags;
|
||||||
int is_dir;
|
int is_dir;
|
||||||
|
|
||||||
RAR_RETNULL_ON_ARGS();
|
RAR_RETNULL_ON_ARGS();
|
||||||
@@ -593,7 +585,7 @@ PHP_METHOD(rarentry, isEncrypted)
|
|||||||
{
|
{
|
||||||
zval *tmp;
|
zval *tmp;
|
||||||
zval *entry_obj = getThis();
|
zval *entry_obj = getThis();
|
||||||
zend_long flags;
|
long flags;
|
||||||
int is_encrypted;
|
int is_encrypted;
|
||||||
|
|
||||||
RAR_RETNULL_ON_ARGS();
|
RAR_RETNULL_ON_ARGS();
|
||||||
@@ -702,21 +694,12 @@ PHP_METHOD(rarentry, __toString)
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ arginfo */
|
/* {{{ arginfo */
|
||||||
#if PHP_MAJOR_VERSION < 8
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_extract, 0, 0, 1)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_extract, 0, 0, 1)
|
||||||
ZEND_ARG_INFO(0, path)
|
ZEND_ARG_INFO(0, path)
|
||||||
ZEND_ARG_INFO(0, filename)
|
ZEND_ARG_INFO(0, filename)
|
||||||
ZEND_ARG_INFO(0, password)
|
ZEND_ARG_INFO(0, password)
|
||||||
ZEND_ARG_INFO(0, extended_data)
|
ZEND_ARG_INFO(0, extended_data)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
#else
|
|
||||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rarentry_extract, 0, 1, _IS_BOOL, 0)
|
|
||||||
ZEND_ARG_TYPE_INFO(0, dir, IS_STRING, 1)
|
|
||||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filepath, IS_STRING, 1, "\'\'")
|
|
||||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, password, IS_STRING, 1, "null")
|
|
||||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extended_data, _IS_BOOL, 0, "false")
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_getstream, 0, 0, 0)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_getstream, 0, 0, 0)
|
||||||
ZEND_ARG_INFO(0, password)
|
ZEND_ARG_INFO(0, password)
|
||||||
@@ -724,16 +707,8 @@ ZEND_END_ARG_INFO()
|
|||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(arginfo_rar_void, 0)
|
ZEND_BEGIN_ARG_INFO(arginfo_rar_void, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
#if PHP_VERSION_ID >= 80200
|
|
||||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rar_tostring, 0, 0, IS_STRING, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
#else
|
|
||||||
#define arginfo_rar_tostring arginfo_rar_void
|
|
||||||
#endif
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
static zend_function_entry php_rar_class_functions[] = {
|
static zend_function_entry php_rar_class_functions[] = {
|
||||||
PHP_ME(rarentry, extract, arginfo_rarentry_extract, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, extract, arginfo_rarentry_extract, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(rarentry, getPosition, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, getPosition, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||||
@@ -752,11 +727,10 @@ static zend_function_entry php_rar_class_functions[] = {
|
|||||||
PHP_ME(rarentry, getRedirType, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, getRedirType, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(rarentry, isRedirectToDirectory, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, isRedirectToDirectory, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(rarentry, getRedirTarget, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, getRedirTarget, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(rarentry, __toString, arginfo_rar_tostring, ZEND_ACC_PUBLIC)
|
PHP_ME(rarentry, __toString, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
void minit_rarentry(TSRMLS_D)
|
void minit_rarentry(TSRMLS_D)
|
||||||
{
|
{
|
||||||
@@ -783,7 +757,6 @@ void minit_rarentry(TSRMLS_D)
|
|||||||
REG_RAR_PROPERTY("redir_to_directory", "Whether the redirection target is a directory");
|
REG_RAR_PROPERTY("redir_to_directory", "Whether the redirection target is a directory");
|
||||||
REG_RAR_PROPERTY("redir_target", "Target of the redirectory");
|
REG_RAR_PROPERTY("redir_target", "Target of the redirectory");
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
REG_RAR_CLASS_CONST_LONG("HOST_MSDOS", HOST_MSDOS);
|
REG_RAR_CLASS_CONST_LONG("HOST_MSDOS", HOST_MSDOS);
|
||||||
REG_RAR_CLASS_CONST_LONG("HOST_OS2", HOST_OS2);
|
REG_RAR_CLASS_CONST_LONG("HOST_OS2", HOST_OS2);
|
||||||
REG_RAR_CLASS_CONST_LONG("HOST_WIN32", HOST_WIN32);
|
REG_RAR_CLASS_CONST_LONG("HOST_WIN32", HOST_WIN32);
|
||||||
@@ -835,5 +808,8 @@ void minit_rarentry(TSRMLS_D)
|
|||||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_REGULAR_FILE", 0x08000L);
|
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_REGULAR_FILE", 0x08000L);
|
||||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SYM_LINK", 0x0A000L);
|
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SYM_LINK", 0x0A000L);
|
||||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SOCKET", 0x0C000L);
|
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SOCKET", 0x0C000L);
|
||||||
/* clang-format on */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
-3797
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() function
|
rar_open() function
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -1,9 +1,10 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_list() function
|
rar_list() function
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require __DIR__ . "/php8compat.php.inc";
|
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||||
$list1 = rar_list($rar_file1);
|
$list1 = rar_list($rar_file1);
|
||||||
var_dump($list1);
|
var_dump($list1);
|
||||||
@@ -13,7 +14,8 @@ $list2 = rar_list($rar_file2);
|
|||||||
var_dump($list2);
|
var_dump($list2);
|
||||||
|
|
||||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||||
argerr(function() use ($rar_file3) { rar_list($rar_file3); });
|
$list3 = rar_list($rar_file3);
|
||||||
|
var_dump($list3);
|
||||||
|
|
||||||
echo "Done\n";
|
echo "Done\n";
|
||||||
?>
|
?>
|
||||||
@@ -161,5 +163,6 @@ array(2) {
|
|||||||
|
|
||||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
Warning: rar_list() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
Warning: rar_list() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||||
|
NULL
|
||||||
Done
|
Done
|
||||||
|
|||||||
+6
-5
@@ -1,9 +1,10 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_entry_get() function
|
rar_entry_get() function
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require __DIR__ . "/php8compat.php.inc";
|
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||||
$entry1 = rar_entry_get($rar_file1, 'test file with whitespaces.txt');
|
$entry1 = rar_entry_get($rar_file1, 'test file with whitespaces.txt');
|
||||||
var_dump($entry1);
|
var_dump($entry1);
|
||||||
@@ -13,9 +14,8 @@ $entry2 = rar_entry_get($rar_file2, '2.txt');
|
|||||||
var_dump($entry2);
|
var_dump($entry2);
|
||||||
|
|
||||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||||
argerr(function() use ($rar_file3) {
|
$entry3 = rar_entry_get($rar_file3, '2.txt');
|
||||||
rar_entry_get($rar_file3, '2.txt');
|
var_dump($entry3);
|
||||||
});
|
|
||||||
|
|
||||||
echo "Done\n";
|
echo "Done\n";
|
||||||
?>
|
?>
|
||||||
@@ -89,5 +89,6 @@ object(RarEntry)#%d (%d) {
|
|||||||
|
|
||||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||||
|
NULL
|
||||||
Done
|
Done
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::extract() method
|
RarEntry::extract() method
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_comment_get() function
|
rar_comment_get() function
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getCrc() method in multi-volume archives (PECL bug #9470)
|
RarEntry::getCrc() method in multi-volume archives (PECL bug #9470)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() function with a non-RAR
|
rar_open() function with a non-RAR
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -1,10 +1,10 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_entry_get() function
|
rar_entry_get() function
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require __DIR__ . "/php8compat.php.inc";
|
|
||||||
|
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part1.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part1.rar');
|
||||||
$entry = rar_entry_get($rar_file1, "file1.txt");
|
$entry = rar_entry_get($rar_file1, "file1.txt");
|
||||||
echo "$entry\n";
|
echo "$entry\n";
|
||||||
@@ -13,9 +13,8 @@ var_dump($entry);
|
|||||||
echo "\n";
|
echo "\n";
|
||||||
|
|
||||||
$rar_file2 = rar_open(dirname(__FILE__).'/nonexistent.rar');
|
$rar_file2 = rar_open(dirname(__FILE__).'/nonexistent.rar');
|
||||||
argerr(function() use ($rar_file2) {
|
$entry = rar_entry_get($rar_file2, "file1.txt");
|
||||||
rar_entry_get($rar_file2, "file1.txt");
|
var_dump($entry);
|
||||||
});
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
|
|
||||||
echo "Done\n";
|
echo "Done\n";
|
||||||
@@ -29,6 +28,7 @@ bool(false)
|
|||||||
|
|
||||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||||
|
NULL
|
||||||
|
|
||||||
Done
|
Done
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getName() function with unicode filenames
|
RarEntry::getName() function with unicode filenames
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (good RAR file, one volume)
|
RarEntry::getStream() function (good RAR file, one volume)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (good RAR file, several volumes)
|
RarEntry::getStream() function (good RAR file, several volumes)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
|
||||||
?>
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (bad RAR file)
|
RarEntry::getStream() function (bad RAR file)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/corrupted.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/corrupted.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_entry_get() and RarEntry::getName() coherence
|
rar_entry_get() and RarEntry::getName() coherence
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() on unicode entry
|
RarEntry::getStream() on unicode entry
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_close() liberates resource (PECL bug #9649)
|
rar_close() liberates resource (PECL bug #9649)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
copy(dirname(__FILE__).'/latest_winrar.rar', dirname(__FILE__).'/temp.rar');
|
copy(dirname(__FILE__).'/latest_winrar.rar', dirname(__FILE__).'/temp.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::extract() method (corrupt RAR file)
|
RarEntry::extract() method (corrupt RAR file)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/corrupted.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/corrupted.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::extract() with unicode files
|
RarEntry::extract() with unicode files
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/rar_unicode.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/rar_unicode.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_list()/rar_entry_get() with not first volume
|
rar_list()/rar_entry_get() with not first volume
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part2.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part2.rar');
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (store method)
|
RarEntry::getStream() function (store method)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
|
||||||
?>
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (solid archive)
|
RarEntry::getStream() function (solid archive)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
|
||||||
?>
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::isDirectory() basic test
|
RarEntry::isDirectory() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::extract() with directory
|
RarEntry::extract() with directory
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() with directory
|
RarEntry::getStream() with directory
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/directories.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open()/RarEntry::getStream() (headers level password)
|
rar_open()/RarEntry::getStream() (headers level password)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
echo "--> should fail (no password):\n";
|
echo "--> should fail (no password):\n";
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open()/RarEntry::extract() (headers level password)
|
rar_open()/RarEntry::extract() (headers level password)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_file2 = rar_open(dirname(__FILE__).'/encrypted_headers.rar', 'samplepassword');
|
$rar_file2 = rar_open(dirname(__FILE__).'/encrypted_headers.rar', 'samplepassword');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() (file level password)
|
RarEntry::getStream() (file level password)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
echo "--> should fail (no password):\n";
|
echo "--> should fail (no password):\n";
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() with Linux directories and links
|
RarEntry::getStream() with Linux directories and links
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar = rar_open(dirname(__FILE__) . "/dirlink_unix.rar");
|
$rar = rar_open(dirname(__FILE__) . "/dirlink_unix.rar");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive::open() basic test
|
RarArchive::open() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$arch = RarArchive::open(dirname(__FILE__) . "/dirlink_unix.rar");
|
$arch = RarArchive::open(dirname(__FILE__) . "/dirlink_unix.rar");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive::getEntries() basic test
|
RarArchive::getEntries() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$arch = RarArchive::open(dirname(__FILE__) . "/dirlink_unix.rar");
|
$arch = RarArchive::open(dirname(__FILE__) . "/dirlink_unix.rar");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive::getEntry() basic test
|
RarArchive::getEntry() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_arch = RarArchive::open(dirname(__FILE__) . '/solid.rar');
|
$rar_arch = RarArchive::open(dirname(__FILE__) . '/solid.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive::getComment() basic test
|
RarArchive::getComment() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rar_arch = RarArchive::open(dirname(__FILE__) . '/commented.rar');
|
$rar_arch = RarArchive::open(dirname(__FILE__) . '/commented.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive traversal with multi-part archive
|
RarArchive traversal with multi-part archive
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rarF = RarArchive::open(dirname(__FILE__) . '/multi.part1.rar');
|
$rarF = RarArchive::open(dirname(__FILE__) . '/multi.part1.rar');
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_solid_is() basic test
|
rar_solid_is() basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$arch1 = RarArchive::open(dirname(__FILE__) . "/store_method.rar");
|
$arch1 = RarArchive::open(dirname(__FILE__) . "/store_method.rar");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarException::(set/is)UsingExceptions() test
|
RarException::(set/is)UsingExceptions() test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
echo "Initial state: " . (RarException::isUsingExceptions()?'yes':'no').".\n";
|
echo "Initial state: " . (RarException::isUsingExceptions()?'yes':'no').".\n";
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_entry_get() non-existent file with exceptions
|
rar_entry_get() non-existent file with exceptions
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
RarException::setUsingExceptions(true);
|
RarException::setUsingExceptions(true);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() non-existent archive with exceptions
|
rar_open() non-existent archive with exceptions
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
RarException::setUsingExceptions(true);
|
RarException::setUsingExceptions(true);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream(), password not given, with exceptions
|
RarEntry::getStream(), password not given, with exceptions
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
RarException::setUsingExceptions(true);
|
RarException::setUsingExceptions(true);
|
||||||
|
|||||||
+3
-1
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive get iterator on closed file
|
RarArchive get iterator on closed file
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rarF = RarArchive::open(dirname(__FILE__) . '/latest_winrar.rar');
|
$rarF = RarArchive::open(dirname(__FILE__) . '/latest_winrar.rar');
|
||||||
@@ -10,4 +12,4 @@ foreach ($rarF as $k => $rarE) {
|
|||||||
}
|
}
|
||||||
echo "Done.\n";
|
echo "Done.\n";
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: main(): The archive is already closed, cannot give an iterator in %s on line %d%A
|
Fatal error: main(): The archive is already closed, cannot give an iterator in %s on line %d
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Access RAR archive with missing volumes
|
Access RAR archive with missing volumes
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$rarF = RarArchive::open(dirname(__FILE__) . '/multi_broken.part1.rar');
|
$rarF = RarArchive::open(dirname(__FILE__) . '/multi_broken.part1.rar');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
RarEntry::getUnpackedSize() on platforms with 32-bit longs
|
RarEntry::getUnpackedSize() on platforms with 32-bit longs
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platforms only");
|
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platforms only");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
RarEntry::getUnpackedSize() on platforms with 64-bit longs
|
RarEntry::getUnpackedSize() on platforms with 64-bit longs
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platforms only");
|
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platforms only");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
+5
-2
@@ -1,12 +1,15 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() with volume find callback basic test
|
rar_open() with volume find callback basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
chdir(dirname(__FILE__));
|
chdir(dirname(__FILE__));
|
||||||
function volume_callback($vol) {
|
function volume_callback($vol) {
|
||||||
if (strpos($vol, '_fail') !== false)
|
if (preg_match('/_fail/', $vol))
|
||||||
$ret = basename(str_replace('_fail', '', $vol));
|
$ret = basename(str_replace('_fail', '', $vol));
|
||||||
elseif (strpos($vol, '_broken') !== false)
|
elseif (preg_match('/_broken/', $vol))
|
||||||
$ret = basename(str_replace('_broken', '_fail', $vol));
|
$ret = basename(str_replace('_broken', '_fail', $vol));
|
||||||
else
|
else
|
||||||
$ret = null;
|
$ret = null;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() with volume find (callback variants 1)
|
rar_open() with volume find (callback variants 1)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
class A {
|
class A {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
rar_open() with volume find (callback variants 2)
|
rar_open() with volume find (callback variants 2)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
if(!defined('PHP_VERSION_ID') || PHP_VERSION_ID<50300) die("skip");
|
if(!defined('PHP_VERSION_ID') || PHP_VERSION_ID<50300) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
+6
-26
@@ -1,8 +1,10 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
rar_open() with invalid volume callback
|
rar_open() with invalid volume callback
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
require __DIR__ . "/php8compat.php.inc";
|
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
public static function resolve($vol) {
|
public static function resolve($vol) {
|
||||||
@@ -28,15 +30,11 @@ var_dump($rar);
|
|||||||
|
|
||||||
echo "\nGiven callback that takes more arguments:\n";
|
echo "\nGiven callback that takes more arguments:\n";
|
||||||
$rar = RarArchive::open($fn, null, 'strpos');
|
$rar = RarArchive::open($fn, null, 'strpos');
|
||||||
argerr(function() use ($rar) {
|
$rar->getEntries();
|
||||||
$rar->getEntries();
|
|
||||||
});
|
|
||||||
|
|
||||||
echo "\nGiven callback that takes another kind of arguments:\n";
|
echo "\nGiven callback that takes another kind of arguments:\n";
|
||||||
$rar = RarArchive::open($fn, null, 'array_keys');
|
$rar = RarArchive::open($fn, null, 'array_keys');
|
||||||
argerr(function() use ($rar) {
|
$rar->getEntries();
|
||||||
$rar->getEntries();
|
|
||||||
});
|
|
||||||
|
|
||||||
echo "\nGiven callback that returns another kind of arguments:\n";
|
echo "\nGiven callback that returns another kind of arguments:\n";
|
||||||
function testA($vol) { return true; }
|
function testA($vol) { return true; }
|
||||||
@@ -54,7 +52,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
echo "Done.\n";
|
echo "Done.\n";
|
||||||
--EXPECTF_DYNAMIC--
|
--EXPECTF--
|
||||||
Not given a callback:
|
Not given a callback:
|
||||||
|
|
||||||
Warning: RarArchive::open(): Expected the third argument, if provided, to be a valid callback in %s on line %d
|
Warning: RarArchive::open(): Expected the third argument, if provided, to be a valid callback in %s on line %d
|
||||||
@@ -66,33 +64,15 @@ bool(false)
|
|||||||
|
|
||||||
Given callback that takes more arguments:
|
Given callback that takes more arguments:
|
||||||
|
|
||||||
<?php if (PHP_VERSION_ID >= 80000) { ?>
|
|
||||||
Warning: RarArchive::getEntries(): Failure to call volume find callback in %s on line %d
|
|
||||||
<?php } ?>
|
|
||||||
<?php if (PHP_VERSION_ID >= 80000) { ?>
|
|
||||||
|
|
||||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
|
||||||
|
|
||||||
Warning: strpos() expects at least %d parameters, 1 given in %s on line %d
|
|
||||||
<?php } else { ?>
|
|
||||||
Warning: strpos() expects at least %d parameters, 1 given in %s on line %d
|
Warning: strpos() expects at least %d parameters, 1 given in %s on line %d
|
||||||
|
|
||||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
Given callback that takes another kind of arguments:
|
Given callback that takes another kind of arguments:
|
||||||
|
|
||||||
<?php if (PHP_VERSION_ID >= 80000) { ?>
|
|
||||||
Warning: RarArchive::getEntries(): Failure to call volume find callback in %s on line %d
|
|
||||||
|
|
||||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
|
||||||
|
|
||||||
Warning: array_keys() expects parameter 1 to be array, string given in %s on line %d
|
|
||||||
<?php } else { ?>
|
|
||||||
Warning: array_keys() expects parameter 1 to be array, string given in %s on line %d
|
Warning: array_keys() expects parameter 1 to be array, string given in %s on line %d
|
||||||
|
|
||||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
Given callback that returns another kind of arguments:
|
Given callback that returns another kind of arguments:
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::getStream() function (broken set fixed with volume callback)
|
RarEntry::getStream() function (broken set fixed with volume callback)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
|
||||||
?>
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
function resolve($vol) {
|
function resolve($vol) {
|
||||||
|
|||||||
+4
-6
@@ -1,9 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarEntry::extract() function (broken set fixed with volume callback)
|
RarEntry::extract() function (broken set fixed with volume callback)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
|
||||||
?>
|
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
function resolve($vol) {
|
function resolve($vol) {
|
||||||
@@ -12,9 +10,9 @@ function resolve($vol) {
|
|||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
function int32_to_hex($value) {
|
function int32_to_hex($value) {
|
||||||
$value &= 0xffffffff;
|
$value &= 0xffffffff;
|
||||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||||
}
|
}
|
||||||
echo "Fail:\n";
|
echo "Fail:\n";
|
||||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar');
|
$rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
RarArchive::open() volume callback long return (case MAXPATHLEN <= NM)
|
RarArchive::open() volume callback long return (case MAXPATHLEN <= NM)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
if (!defined("PHP_MAXPATHLEN"))
|
if (!defined("PHP_MAXPATHLEN"))
|
||||||
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
||||||
if (!(PHP_MAXPATHLEN <= 1024))
|
if (!(PHP_MAXPATHLEN <= 1024))
|
||||||
|
|||||||
+5
-5
@@ -1,13 +1,13 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RarArchive::open() volume callback long return (case MAXPATHLEN > MAXPATHSIZE)
|
RarArchive::open() volume callback long return (case MAXPATHLEN > NM)
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
define('MAXPATHSIZE', 0x10000);
|
if(!extension_loaded("rar")) die("skip");
|
||||||
if (!defined("PHP_MAXPATHLEN"))
|
if (!defined("PHP_MAXPATHLEN"))
|
||||||
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
||||||
if (!(PHP_MAXPATHLEN > MAXPATHSIZE))
|
if (!(PHP_MAXPATHLEN > 2048))
|
||||||
die("skip test is for systems where MAXPATHLEN > 2048");
|
die("skip test is for systems where MAXPATHLEN > 2048");
|
||||||
$rp = dirname(__FILE__) . "/" . str_repeat("a", MAXPATHSIZE);
|
$rp = dirname(__FILE__) . "/" . str_repeat("a", 2048);
|
||||||
if (strlen(dirname(__FILE__) > PHP_MAXPATHLEN - 1))
|
if (strlen(dirname(__FILE__) > PHP_MAXPATHLEN - 1))
|
||||||
die("skip current directory is too deep.");
|
die("skip current directory is too deep.");
|
||||||
--FILE--
|
--FILE--
|
||||||
@@ -18,7 +18,7 @@ if (!defined("PHP_MAXPATHLEN"))
|
|||||||
chdir(dirname(__FILE__));
|
chdir(dirname(__FILE__));
|
||||||
$fn = dirname(__FILE__) . '/multi_broken.part1.rar';
|
$fn = dirname(__FILE__) . '/multi_broken.part1.rar';
|
||||||
|
|
||||||
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", MAXPATHSIZE); }
|
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", 2048); }
|
||||||
$rar = RarArchive::open($fn, null, 'testA');
|
$rar = RarArchive::open($fn, null, 'testA');
|
||||||
$rar->getEntries();
|
$rar->getEntries();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Stream wrapper basic test
|
Stream wrapper basic test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$stream = fopen("rar://" .
|
$stream = fopen("rar://" .
|
||||||
|
|||||||
+5
-2
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Stream wrapper relative path test
|
Stream wrapper relative path test
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--CLEAN--
|
--CLEAN--
|
||||||
<?php
|
<?php
|
||||||
unlink(dirname(__FILE__) . '/temp/tmp.rar');
|
unlink(dirname(__FILE__) . '/temp/tmp.rar');
|
||||||
@@ -47,11 +50,11 @@ string(5) "11111"
|
|||||||
Test with include path:
|
Test with include path:
|
||||||
Should fail (not in include):
|
Should fail (not in include):
|
||||||
|
|
||||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
Should fail (include unused):
|
Should fail (include unused):
|
||||||
|
|
||||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
Should succeed:
|
Should succeed:
|
||||||
string(5) "11111"
|
string(5) "11111"
|
||||||
|
|||||||
+6
-3
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Stream wrapper archive/file not found
|
Stream wrapper archive/file not found
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -17,9 +20,9 @@ echo "Done.\n";
|
|||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Archive not found :
|
Archive not found :
|
||||||
|
|
||||||
Warning: fopen(rar://%snot_found.rar#1.txt): %cailed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
Warning: fopen(rar://%snot_found.rar#1.txt): failed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||||
|
|
||||||
File not found :
|
File not found :
|
||||||
|
|
||||||
Warning: fopen(rar://%slatest_winrar.rar#not_found.txt): %cailed to open stream: Can't file not_found.txt in RAR archive %s on line %d
|
Warning: fopen(rar://%slatest_winrar.rar#not_found.txt): failed to open stream: Can't file not_found.txt in RAR archive %s on line %d
|
||||||
Done.
|
Done.
|
||||||
+8
-5
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Stream wrapper malformed url
|
Stream wrapper malformed url
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -24,21 +27,21 @@ echo "Done.\n";
|
|||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Test empty:
|
Test empty:
|
||||||
|
|
||||||
Warning: fopen(rar://): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
Warning: fopen(rar://): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||||
|
|
||||||
Test no fragment:
|
Test no fragment:
|
||||||
|
|
||||||
Warning: fopen(rar://file.rar): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
Warning: fopen(rar://file.rar): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||||
|
|
||||||
Test empty fragment:
|
Test empty fragment:
|
||||||
|
|
||||||
Warning: fopen(rar://file.rar#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
Warning: fopen(rar://file.rar#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||||
|
|
||||||
Test no path:
|
Test no path:
|
||||||
|
|
||||||
Warning: fopen(rar://#frag): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
Warning: fopen(rar://#frag): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||||
|
|
||||||
Test no path and empty fragment:
|
Test no path and empty fragment:
|
||||||
|
|
||||||
Warning: fopen(rar://#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
Warning: fopen(rar://#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||||
Done.
|
Done.
|
||||||
|
|||||||
+7
-4
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Stream wrapper with header or file level passwords
|
Stream wrapper with header or file level passwords
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
@@ -52,11 +55,11 @@ echo "\nDone.\n";
|
|||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Headers: should not work (no password):
|
Headers: should not work (no password):
|
||||||
|
|
||||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||||
|
|
||||||
Headers: should not work (password given was file_password):
|
Headers: should not work (password given was file_password):
|
||||||
|
|
||||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||||
|
|
||||||
Headers: should work (password given was open_password):
|
Headers: should work (password given was open_password):
|
||||||
string(26) "Encrypted file 1 contents."
|
string(26) "Encrypted file 1 contents."
|
||||||
@@ -64,11 +67,11 @@ string(26) "Encrypted file 1 contents."
|
|||||||
|
|
||||||
Files: should not work (no password):
|
Files: should not work (no password):
|
||||||
|
|
||||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||||
|
|
||||||
Files: should not work (password given was open_password):
|
Files: should not work (password given was open_password):
|
||||||
|
|
||||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||||
|
|
||||||
Files: should work (password given was file_password):
|
Files: should work (password given was file_password):
|
||||||
string(26) "Encrypted file 1 contents."
|
string(26) "Encrypted file 1 contents."
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
Stream wrapper with volume find callback
|
Stream wrapper with volume find callback
|
||||||
--SKIPIF--
|
--SKIPIF--
|
||||||
<?php
|
<?php
|
||||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
function resolve($vol) {
|
function resolve($vol) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RAR file stream stat
|
RAR file stream stat
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--ENV--
|
--ENV--
|
||||||
TZ=Asia/Tokyo
|
TZ=Asia/Tokyo
|
||||||
--FILE--
|
--FILE--
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
RAR file stream stat consistency with url stat
|
RAR file stream stat consistency with url stat
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!extension_loaded("rar")) die("skip");
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$u = "rar://" .
|
$u = "rar://" .
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user