mirror of
https://github.com/php-win-ext/php-rar.git
synced 2026-03-24 04:52:07 +01:00
Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4d66343e7 | ||
|
|
2ef087bd9e | ||
|
|
d9bc8cd4c5 | ||
|
|
60eaceb6ee | ||
|
|
b6d9dc8eae | ||
|
|
d58737756c | ||
|
|
b79e6491b5 | ||
|
|
1f1baf4fc1 | ||
|
|
4e914be013 | ||
|
|
05c8e5e675 | ||
|
|
b482f2f156 | ||
|
|
4115c69fe2 | ||
|
|
ea74acb27b | ||
|
|
1b6a2a5aa4 | ||
|
|
e5b9669359 | ||
|
|
89ac57cd59 | ||
|
|
440d2a14c8 | ||
|
|
a169ed937e | ||
|
|
10e3e3222a | ||
|
|
055906e455 | ||
|
|
2d3b968d23 | ||
|
|
371536d3a8 | ||
|
|
3f536c9f9d | ||
|
|
ff2aa63dbf | ||
|
|
0cace1db4b | ||
|
|
0c05fac324 | ||
|
|
ae9a4623fe | ||
|
|
88773b47f1 | ||
|
|
5e74ad9803 | ||
|
|
f6650b4abe | ||
|
|
be202cc5b1 | ||
|
|
6a2ec1ccfc | ||
|
|
eb1a919fb9 | ||
|
|
5e063a9626 | ||
|
|
4a4e67ec33 | ||
|
|
3dcba946ab | ||
|
|
77cc02a1db | ||
|
|
0131eef66c | ||
|
|
823315f6d6 | ||
|
|
40a7872954 | ||
|
|
9babd4f983 | ||
|
|
366007b41a | ||
|
|
320f84b6ae | ||
|
|
899eb2cedd | ||
|
|
d21e05b1f7 | ||
|
|
1c76380291 | ||
|
|
55a566364a | ||
|
|
5823bb16b5 | ||
|
|
9a5d712d99 | ||
|
|
95fe328cc2 | ||
|
|
0a08604b53 | ||
|
|
9f17788011 | ||
|
|
a657432560 | ||
|
|
abb9fa4632 | ||
|
|
b810988366 | ||
|
|
294d87a695 | ||
|
|
f57721dbb3 | ||
|
|
094a536987 | ||
|
|
340695bebb | ||
|
|
e63362d16a | ||
|
|
cc7d8e8c40 | ||
|
|
d2b82835c4 | ||
|
|
571deeda60 | ||
|
|
412c7bf024 | ||
|
|
4594bd1cd1 | ||
|
|
3fcd7f12fe | ||
|
|
efddae46a9 | ||
|
|
63a7b8bbbb | ||
|
|
d7a5b2c8f0 | ||
|
|
2f979b4b64 | ||
|
|
0922854405 | ||
|
|
b7ec361367 | ||
|
|
1502c092f0 | ||
|
|
c00e9c1493 | ||
|
|
f367a22fe3 | ||
|
|
ab26d28575 | ||
|
|
488dd3caaa | ||
|
|
1dc896be94 | ||
|
|
36345d004e | ||
|
|
8f070c282f | ||
|
|
91ed5b09a0 | ||
|
|
d95cab037b | ||
|
|
7cff10aa2c | ||
|
|
5b94797037 | ||
|
|
4ff664b2b0 | ||
|
|
2e13165bdb | ||
|
|
d0cd509090 | ||
|
|
bd65eab735 | ||
|
|
45742b94ab | ||
|
|
6545fdd215 | ||
|
|
08f8190e49 | ||
|
|
095b4cdd58 | ||
|
|
da32228c34 | ||
|
|
2788a30227 | ||
|
|
e0c6c97ef0 | ||
|
|
2322542282 | ||
|
|
2b12de7a8f | ||
|
|
23430540f1 | ||
|
|
e3f3ecd1ab | ||
|
|
544f55920a | ||
|
|
24b421e0e6 | ||
|
|
05a48cbbeb | ||
|
|
6d0e583ef9 | ||
|
|
714f15cb06 | ||
|
|
58bb195ae3 | ||
|
|
5293a8f07e | ||
|
|
61edb08973 | ||
|
|
adc9fe7d39 | ||
|
|
5eb1055447 | ||
|
|
7ca7561e09 | ||
|
|
61eca15136 | ||
|
|
dc8ee65999 | ||
|
|
656c3fa69d | ||
|
|
a6bea8fec8 | ||
|
|
3b405bea8e | ||
|
|
18cd0568aa | ||
|
|
dc298847c7 | ||
|
|
246a80fdeb | ||
|
|
4b6fd31d08 | ||
|
|
44e35b8f6a | ||
|
|
fe4a94305b | ||
|
|
0453380858 | ||
|
|
957fc7702d | ||
|
|
5a0cd32191 | ||
|
|
5ca8d78562 | ||
|
|
1225c9240e |
88
.clang-format
Normal file
88
.clang-format
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
# 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
|
||||
27
.github/docker-image-shas.yml
vendored
Normal file
27
.github/docker-image-shas.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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
|
||||
|
||||
datadog/dd-appsec-php-ci:
|
||||
php-7.0-debug: "sha256:0a9aaeaf79bd4c578eac6dedabf6ac131537266f44562158ce67fdb37c794916"
|
||||
php-7.0-release-zts: "sha256:4bb5fac6fbd3124234d062328c68f6c51027aa95f13e4e8b14afd7c8de518ec6"
|
||||
php-7.1-debug: "sha256:500007ad057d9e71b2bb9079a2f8ba3f1ecfbb26d112db69e17d6007b4e857b5"
|
||||
php-7.1-release-zts: "sha256:d997b9f99c28967872bd0949f8572b089daaadb6ceaa1e856ccc76e07e2ba6b7"
|
||||
php-7.2-debug: "sha256:4c5f111f8e84fcb7dcc9e3cc13e1277d0702b04cd33286ce33db885485d1f025"
|
||||
php-7.2-release-zts: "sha256:634b857d74c3d77b88986ceb088be2dd5bc30151bc08c2b536443984e6659d6e"
|
||||
php-7.3-debug: "sha256:efa81f79783097478a434578226fe9a3b8fe84abda33168034aaea60c197c73b"
|
||||
php-7.3-release-zts: "sha256:c713df299596a9615f88cfe73c29b0a1f9faf32e5e6fa62fa07ee839313cd57e"
|
||||
php-7.4-debug: "sha256:b8a9e982179189122d73feb896c1a1e8578a92fc9a023dabc825f45db8299c22"
|
||||
php-7.4-release-zts: "sha256:6492e3334e722b106352180ec9f0cbee8dd81f008e3537d03f4b8da3522f49e1"
|
||||
php-8.0-debug: "sha256:900ceae7487db1e3652de2880c181e572fdf053673bcda8ff47abf664ff74d39"
|
||||
php-8.0-release-zts: "sha256:b6243199f6aea0792a97583c9036f0b191ad9efb96ea337632fbaca76289a4da"
|
||||
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"
|
||||
35
.github/scripts/build-and-test.sh
vendored
Executable file
35
.github/scripts/build-and-test.sh
vendored
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the extension and run the test suite.
|
||||
# Expected to run inside a datadog/dd-appsec-php-ci container from the repo root.
|
||||
set -euo pipefail
|
||||
|
||||
# Clean up artifacts from any previous build so stale objects don't survive a
|
||||
# PHP-version switch (safe in CI where the workspace is always fresh).
|
||||
if [ -f Makefile ]; then
|
||||
make -f Makefile distclean
|
||||
fi
|
||||
|
||||
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"
|
||||
52
.github/scripts/update-docker-shas.sh
vendored
Executable file
52
.github/scripts/update-docker-shas.sh
vendored
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/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="datadog/dd-appsec-php-ci"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOCK_FILE="$SCRIPT_DIR/../docker-image-shas.yml"
|
||||
|
||||
TAGS=(
|
||||
php-7.0-debug php-7.0-release-zts
|
||||
php-7.1-debug php-7.1-release-zts
|
||||
php-7.2-debug php-7.2-release-zts
|
||||
php-7.3-debug php-7.3-release-zts
|
||||
php-7.4-debug php-7.4-release-zts
|
||||
php-8.0-debug php-8.0-release-zts
|
||||
php-8.1-debug php-8.1-release-zts
|
||||
php-8.2-debug php-8.2-release-zts
|
||||
php-8.3-debug php-8.3-release-zts
|
||||
php-8.4-debug php-8.4-release-zts
|
||||
php-8.5-debug php-8.5-release-zts
|
||||
)
|
||||
|
||||
get_index_digest() {
|
||||
# The top-level "digest" field in the Hub tags API is the manifest-list
|
||||
# (OCI index) digest, not a per-platform image digest.
|
||||
curl -fsSL "https://hub.docker.com/v2/repositories/${IMAGE}/tags/$1" \
|
||||
| python3 -c "import sys,json; print(json.load(sys.stdin)['digest'])"
|
||||
}
|
||||
|
||||
# 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
|
||||
123
.github/workflows/release.yml
vendored
Normal file
123
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
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
|
||||
|
||||
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
|
||||
92
.github/workflows/tests.yml
vendored
Normal file
92
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
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 = 'datadog/dd-appsec-php-ci'
|
||||
includes = []
|
||||
for tag, sha in data[image].items():
|
||||
# tag: "php-7.0-debug" or "php-7.0-release-zts"
|
||||
ver, variant = tag[len('php-'):].split('-', 1)
|
||||
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: datadog/dd-appsec-php-ci@${{ 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
|
||||
|
||||
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'
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
*.o
|
||||
*.lo
|
||||
/run-tests.php
|
||||
/tests/*.sh
|
||||
/tests/*.exp
|
||||
/tests/*.diff
|
||||
@@ -7,7 +8,6 @@
|
||||
/tests/*.php
|
||||
/tests/*.out
|
||||
/tests/*.mem
|
||||
/run-tests.php
|
||||
/modules
|
||||
/missing
|
||||
/.deps
|
||||
@@ -23,12 +23,14 @@
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.nice
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/configure.in
|
||||
/configure.ac
|
||||
/install-sh
|
||||
/intl.la
|
||||
/libtool
|
||||
@@ -41,3 +43,12 @@
|
||||
/rar.la
|
||||
*.autosave
|
||||
/unrar/.libs
|
||||
/tmp-php.ini
|
||||
/php-rar.creator.user
|
||||
/compile_commands.json
|
||||
/.clangd
|
||||
/report.xml
|
||||
/.worktrees
|
||||
*.dep
|
||||
/configure~
|
||||
/.cache/
|
||||
|
||||
33
.travis.yml
33
.travis.yml
@@ -1,33 +0,0 @@
|
||||
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)'
|
||||
113
Justfile
Normal file
113
Justfile
Normal file
@@ -0,0 +1,113 @@
|
||||
# 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 := "datadog/dd-appsec-php-ci@"
|
||||
_shas := ".github/docker-image-shas.yml"
|
||||
|
||||
image_7_0_debug := _base + `grep 'php-7.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_0_release_zts := _base + `grep 'php-7.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_1_debug := _base + `grep 'php-7.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_1_release_zts := _base + `grep 'php-7.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_2_debug := _base + `grep 'php-7.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_2_release_zts := _base + `grep 'php-7.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_3_debug := _base + `grep 'php-7.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_3_release_zts := _base + `grep 'php-7.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_4_debug := _base + `grep 'php-7.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_7_4_release_zts := _base + `grep 'php-7.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_0_debug := _base + `grep 'php-8.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_0_release_zts := _base + `grep 'php-8.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_1_debug := _base + `grep 'php-8.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_1_release_zts := _base + `grep 'php-8.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_2_debug := _base + `grep 'php-8.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_2_release_zts := _base + `grep 'php-8.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_3_debug := _base + `grep 'php-8.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_3_release_zts := _base + `grep 'php-8.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_4_debug := _base + `grep 'php-8.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_4_release_zts := _base + `grep 'php-8.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_5_debug := _base + `grep 'php-8.5-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
|
||||
image_8_5_release_zts := _base + `grep 'php-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
|
||||
5
Makefile.frag
Normal file
5
Makefile.frag
Normal file
@@ -0,0 +1,5 @@
|
||||
.PHONY: replace-run-tests
|
||||
replace-run-tests:
|
||||
cp run-tests-rar.php run-tests.php
|
||||
|
||||
test: replace-run-tests
|
||||
22
README.md
22
README.md
@@ -10,6 +10,22 @@ unrar/LICENSE.txt for details.
|
||||
Some modifications have been applied to the UnRAR library, mainly to allow
|
||||
streaming extraction of files without using threads.
|
||||
|
||||
[](https://ci.appveyor.com/project/cataphract/php-rar/branch/master)
|
||||
[](https://travis-ci.org/cataphract/php-rar)
|
||||
[](https://codecov.io/gh/cataphract/php-rar)
|
||||
## Installation
|
||||
|
||||
### With PECL
|
||||
|
||||
```sh
|
||||
pecl install rar
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
29
appveyor.bat
29
appveyor.bat
@@ -1,29 +0,0 @@
|
||||
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"
|
||||
26
appveyor.yml
26
appveyor.yml
@@ -1,26 +0,0 @@
|
||||
# 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,18 +1,31 @@
|
||||
{
|
||||
"name": "rar",
|
||||
"type": "extension",
|
||||
"license": [
|
||||
"PHP License"
|
||||
],
|
||||
"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"
|
||||
"email": "cataphract@php.net",
|
||||
"role": "lead"
|
||||
},
|
||||
{
|
||||
"name": "Antony Dovgal",
|
||||
"email": "tony@daylessday.org"
|
||||
"email": "tony@daylessday.org",
|
||||
"role": "developer"
|
||||
}
|
||||
],
|
||||
"description": "rar extension"
|
||||
}
|
||||
"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"]
|
||||
}
|
||||
}
|
||||
|
||||
36
config.m4
36
config.m4
@@ -29,7 +29,39 @@ unrar_sources="unrar/sha256.cpp unrar/qopen.cpp \
|
||||
unrar/arcread.cpp unrar/filefn.cpp \
|
||||
unrar/global.cpp unrar/list.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([-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="$cxxflags_null"
|
||||
echo "EXTRA_CXXFLAGS := \$(EXTRA_CXXFLAGS) $extra_cxxflags" >> Makefile.fragments
|
||||
cat Makefile.frag >> Makefile.fragments
|
||||
INCLUDES=`echo "$INCLUDES" | sed 's/-I/-isystem /g'`
|
||||
|
||||
if test "$PHP_RAR" != "no"; then
|
||||
AC_DEFINE(HAVE_RAR, 1, [Whether you have rar support])
|
||||
@@ -37,6 +69,6 @@ if test "$PHP_RAR" != "no"; then
|
||||
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 -Wno-write-strings -Wall -I@ext_srcdir@/unrar)
|
||||
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 -Wno-write-strings -Wall -fPIC -fvisibility=hidden -I@ext_srcdir@/unrar)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||
fi
|
||||
|
||||
@@ -18,7 +18,7 @@ if (PHP_RAR != "no") {
|
||||
crc.cpp rijndael.cpp crypt.cpp \
|
||||
rawread.cpp \
|
||||
rs.cpp smallfn.cpp \
|
||||
isnt.cpp rar.cpp consio.cpp \
|
||||
isnt.cpp consio.cpp \
|
||||
scantree.cpp archive.cpp strfn.cpp \
|
||||
strlist.cpp \
|
||||
getbits.cpp hash.cpp \
|
||||
@@ -31,7 +31,8 @@ if (PHP_RAR != "no") {
|
||||
arcread.cpp filefn.cpp \
|
||||
global.cpp list.cpp \
|
||||
encname.cpp file.cpp \
|
||||
secpassword.cpp options.cpp", "rar");
|
||||
secpassword.cpp options.cpp \
|
||||
largepage.cpp motw.cpp", "rar");
|
||||
|
||||
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
||||
}
|
||||
|
||||
110
package.xml
110
package.xml
@@ -23,10 +23,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<active>no</active>
|
||||
</developer>
|
||||
|
||||
<date>2017-07-22</date>
|
||||
<time>03:00:00</time>
|
||||
<date>2026-03-08</date>
|
||||
<time>20:00:00</time>
|
||||
<version>
|
||||
<release>4.0.0</release>
|
||||
<release>4.3.0</release>
|
||||
<api>4.0.0</api>
|
||||
</version>
|
||||
|
||||
@@ -36,11 +36,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
</stability>
|
||||
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<notes>- Merge changes made to unrar up to version 5.5.6.
|
||||
- Support PHP 7.0 and PHP 7.1.
|
||||
- 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>- Add PHP 8.1, 8.2, 8.3, 8.4, 8.5 support.
|
||||
- Drop PHP 5 support; minimum PHP version is now 7.0.
|
||||
- Update bundled unrar to 7.2.4.
|
||||
- Fix Windows bug
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
@@ -113,8 +112,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="065.phpt"/>
|
||||
<file role="test" name="066.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="071.phpt"/>
|
||||
<file role="test" name="072.phpt"/>
|
||||
@@ -150,7 +147,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="102.phpt"/>
|
||||
<file role="test" name="103.phpt"/>
|
||||
<file role="test" name="104.phpt"/>
|
||||
<file role="test" name="105.phpt"/>
|
||||
<file role="test" name="106.phpt"/>
|
||||
<file role="test" name="107.phpt"/>
|
||||
<file role="test" name="108.phpt"/>
|
||||
@@ -159,6 +155,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<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="commented.rar"/>
|
||||
<file role="test" name="corrupted.rar"/>
|
||||
<file role="test" name="directories.rar"/>
|
||||
@@ -174,6 +172,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="multi.part2.rar"/>
|
||||
<file role="test" name="multi.part3.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_unicode.rar"/>
|
||||
<file role="test" name="repeated_name.rar"/>
|
||||
@@ -192,13 +191,14 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="archive.cpp" role="src" />
|
||||
<file name="archive.hpp" role="src" />
|
||||
<file name="arcread.cpp" role="src" />
|
||||
<file name="array.hpp" role="src" />
|
||||
<file name="blake2s.cpp" role="src" />
|
||||
<file name="blake2s.hpp" role="src" />
|
||||
<file name="blake2s_sse.cpp" role="src" />
|
||||
<file name="blake2sp.cpp" role="src" />
|
||||
<file name="cmddata.cpp" 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.hpp" role="src" />
|
||||
<file name="compress.hpp" role="src" />
|
||||
@@ -245,6 +245,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="headers5.hpp" role="src" />
|
||||
<file name="isnt.cpp" 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="list.cpp" role="src" />
|
||||
<file name="list.hpp" role="src" />
|
||||
@@ -255,6 +257,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="match.hpp" role="src" />
|
||||
<file name="model.cpp" 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.hpp" role="src" />
|
||||
<file name="os.hpp" role="src" />
|
||||
@@ -270,7 +274,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="rartypes.hpp" role="src" />
|
||||
<file name="rarvm.cpp" role="src" />
|
||||
<file name="rarvm.hpp" role="src" />
|
||||
<file name="rarvmtbl.cpp" role="src" />
|
||||
<file name="rawint.hpp" role="src" />
|
||||
<file name="rawread.cpp" role="src" />
|
||||
<file name="rawread.hpp" role="src" />
|
||||
@@ -305,7 +308,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="rijndael.hpp" role="src" />
|
||||
<file name="rs.cpp" role="src" />
|
||||
<file name="rs.hpp" role="src" />
|
||||
<file name="savepos.hpp" role="src" />
|
||||
<file name="scantree.cpp" role="src" />
|
||||
<file name="scantree.hpp" role="src" />
|
||||
<file name="secpassword.cpp" role="src" />
|
||||
@@ -325,7 +327,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="timefn.cpp" role="src" />
|
||||
<file name="timefn.hpp" role="src" />
|
||||
<file name="ulinks.cpp" role="src" />
|
||||
<file name="ulinks.hpp" role="src" />
|
||||
<file name="unicode.cpp" role="src" />
|
||||
<file name="unicode.hpp" role="src" />
|
||||
<file name="unpack.cpp" role="src" />
|
||||
@@ -343,8 +344,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="config.w32" role="src" />
|
||||
<file name="CREDITS" role="doc" />
|
||||
<file name="LICENSE" role="doc" />
|
||||
<file name="Makefile.frag" role="src" />
|
||||
<file name="README.md" role="doc" />
|
||||
<file name="example.php" role="doc" />
|
||||
<file name="php_compat.h" role="src" />
|
||||
<file name="php_rar.h" role="src" />
|
||||
<file name="rar.c" role="src" />
|
||||
<file name="rar_stream.c" role="src" />
|
||||
@@ -352,6 +355,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="rarentry.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"/>
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
@@ -359,7 +363,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>5.3.0</min>
|
||||
<min>7.0.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0</min>
|
||||
@@ -370,8 +374,80 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<providesextension>rar</providesextension>
|
||||
|
||||
<extsrcrelease />
|
||||
|
||||
<changelog>
|
||||
<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>
|
||||
|
||||
11
php-rar.config
Normal file
11
php-rar.config
Normal file
@@ -0,0 +1,11 @@
|
||||
// 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
php-rar.creator
Normal file
1
php-rar.creator
Normal file
@@ -0,0 +1 @@
|
||||
[General]
|
||||
161
php-rar.files
Normal file
161
php-rar.files
Normal file
@@ -0,0 +1,161 @@
|
||||
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
|
||||
4
php-rar.includes
Normal file
4
php-rar.includes
Normal file
@@ -0,0 +1,4 @@
|
||||
/home/glopes/repos/php-src/Zend
|
||||
/home/glopes/repos/php-src/TSRM
|
||||
/home/glopes/repos/php-src/main
|
||||
/home/glopes/repos/php-src
|
||||
54
php_compat.h
Normal file
54
php_compat.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#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
|
||||
114
php_rar.h
114
php_rar.h
@@ -51,7 +51,7 @@
|
||||
extern zend_module_entry rar_module_entry;
|
||||
#define phpext_rar_ptr &rar_module_entry
|
||||
|
||||
#define PHP_RAR_VERSION "4.0.0"
|
||||
#define PHP_RAR_VERSION "4.3.1-dev"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_RAR_API __declspec(dllexport)
|
||||
@@ -63,6 +63,8 @@ extern zend_module_entry rar_module_entry;
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#include "php_compat.h"
|
||||
|
||||
/* causes linking errors (multiple definitions) in functions
|
||||
that were requested inlining but were not inlined by the compiler */
|
||||
/* #include "unrar/rar.hpp */
|
||||
@@ -75,6 +77,7 @@ extern zend_module_entry rar_module_entry;
|
||||
#include "unrar/dll.hpp"
|
||||
#include "unrar/version.hpp"
|
||||
/* These are in unrar/headers.hpp, but that header depends on several other */
|
||||
/* clang-format off */
|
||||
enum HOST_SYSTEM {
|
||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||
HOST_BEOS=5,HOST_MAX
|
||||
@@ -83,67 +86,12 @@ enum FILE_SYSTEM_REDIRECT {
|
||||
FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION,
|
||||
FSREDIR_HARDLINK, FSREDIR_FILECOPY
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* maximum comment size if 64KB */
|
||||
#define RAR_MAX_COMMENT_SIZE 65536
|
||||
|
||||
/* 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
|
||||
|
||||
/* clang-format off */
|
||||
typedef struct _rar_cb_user_data {
|
||||
char *password; /* can be NULL */
|
||||
zval *callable; /* can be NULL */
|
||||
@@ -160,13 +108,19 @@ typedef struct rar {
|
||||
rar_cb_user_data cb_userdata;
|
||||
int allow_broken;
|
||||
} rar_file_t;
|
||||
/* clang-format on */
|
||||
|
||||
/* Misc */
|
||||
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||
# define RAR_TSRMLS_TC , void ***
|
||||
#else
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define ARR_SIZE(arr) \
|
||||
(sizeof(arr) / sizeof((arr)[0]) + \
|
||||
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
|
||||
#endif
|
||||
|
||||
#define RAR_RETNULL_ON_ARGS() \
|
||||
if (zend_parse_parameters_none() == FAILURE) { \
|
||||
@@ -213,33 +167,6 @@ ZEND_EXTERN_MODULE_GLOBALS(rar);
|
||||
# define RAR_G(v) (rar_globals.v)
|
||||
#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
|
||||
size_t _rar_strnlen(const char *s, size_t maxlen);
|
||||
@@ -303,7 +230,7 @@ typedef struct _rar_find_output {
|
||||
int found;
|
||||
size_t position;
|
||||
struct RARHeaderDataEx * header;
|
||||
unsigned long packed_size;
|
||||
zend_ulong packed_size;
|
||||
int eof;
|
||||
} rar_find_output;
|
||||
#define RAR_SEARCH_INDEX 0x01U
|
||||
@@ -333,8 +260,9 @@ void _rar_close_file_resource(rar_file_t *rar);
|
||||
/* 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
|
||||
* RarEntry::extract/getStream access extract_open_dat and cb_userdata */
|
||||
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file 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_zv(zval *zv_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(rar_obj_ref objref_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
||||
void minit_rararch(TSRMLS_D);
|
||||
|
||||
PHP_FUNCTION(rar_open);
|
||||
@@ -351,7 +279,7 @@ extern zend_class_entry *rar_class_entry_ptr;
|
||||
void minit_rarentry(TSRMLS_D);
|
||||
void _rar_entry_to_zval(zval *parent,
|
||||
struct RARHeaderDataEx *entry,
|
||||
unsigned long packed_size,
|
||||
zend_ulong packed_size,
|
||||
size_t index,
|
||||
zval *entry_object TSRMLS_DC);
|
||||
|
||||
|
||||
189
php_upgrade.md
Normal file
189
php_upgrade.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# 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: -->
|
||||
115
rar.c
115
rar.c
@@ -28,14 +28,12 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
@@ -50,7 +48,7 @@ extern "C" {
|
||||
#include <ext/standard/info.h>
|
||||
#include <ext/spl/spl_exceptions.h>
|
||||
|
||||
#if HAVE_RAR
|
||||
#include "unrar/rardefs.hpp"
|
||||
|
||||
#include "php_rar.h"
|
||||
|
||||
@@ -161,12 +159,8 @@ void _rar_destroy_userdata(rar_cb_user_data *udata) /* {{{ */
|
||||
}
|
||||
|
||||
if (udata->callable != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&udata->callable);
|
||||
#else
|
||||
zval_ptr_dtor(udata->callable);
|
||||
efree(udata->callable);
|
||||
#endif
|
||||
}
|
||||
|
||||
udata->password = NULL;
|
||||
@@ -240,13 +234,16 @@ int _rar_find_file_w(struct RAROpenArchiveDataEx *open_data, /* IN */
|
||||
|
||||
while ((result = RARReadHeaderEx(*arc_handle, used_header_data)) == 0) {
|
||||
#if WCHAR_MAX > 0xffff
|
||||
_rar_fix_wide(used_header_data->FileNameW, NM);
|
||||
_rar_fix_wide(used_header_data->FileNameW,
|
||||
ARR_SIZE(used_header_data->FileNameW));
|
||||
#endif
|
||||
|
||||
if (wcsncmp(used_header_data->FileNameW, file_name, NM) == 0) {
|
||||
if (wcsncmp(used_header_data->FileNameW, file_name,
|
||||
ARR_SIZE(used_header_data->FileNameW)) == 0) {
|
||||
*found = TRUE;
|
||||
goto cleanup;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
process_result = RARProcessFile(*arc_handle, RAR_SKIP, NULL, NULL);
|
||||
}
|
||||
if (process_result != 0) {
|
||||
@@ -383,6 +380,7 @@ int CALLBACK _rar_unrar_callback(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
// TODO: maybe support UCM_NEEDPASSWORDW and UCM_CHANGEVOLUMEW
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -425,7 +423,7 @@ PHP_FUNCTION(rar_wrapper_cache_stats) /* {{{ */
|
||||
static void _rar_fix_wide(wchar_t *str, size_t max_size) /* {{{ */
|
||||
{
|
||||
wchar_t *write,
|
||||
*read,
|
||||
*read,
|
||||
*max_fin;
|
||||
max_fin = str + max_size;
|
||||
for (write = str, read = str; *read != L'\0' && read != max_fin; read++) {
|
||||
@@ -442,61 +440,37 @@ 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
|
||||
* error code ERAR_EOPEN to be thrown.
|
||||
*/
|
||||
static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||
static int _rar_unrar_volume_user_callback(char* dst_buffer, // MAXPATHSIZE
|
||||
zend_fcall_info *fci,
|
||||
zend_fcall_info_cache *cache
|
||||
TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *failed_vol,
|
||||
*retval_ptr = NULL,
|
||||
**params;
|
||||
#else
|
||||
zval failed_vol,
|
||||
retval,
|
||||
*params,
|
||||
*const retval_ptr = &retval;
|
||||
#endif
|
||||
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_NULL(&retval);
|
||||
params = &failed_vol;
|
||||
fci->retval = &retval;
|
||||
fci->params = params;
|
||||
#endif
|
||||
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)) {
|
||||
#endif
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Failure to call volume find callback");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(*fci->retval_ptr_ptr == retval_ptr);
|
||||
#else
|
||||
assert(fci->retval == &retval);
|
||||
#endif
|
||||
if (Z_TYPE_P(retval_ptr) == IS_NULL) {
|
||||
/* let return -1 */
|
||||
}
|
||||
else if (Z_TYPE_P(retval_ptr) == IS_STRING) {
|
||||
char *filename = Z_STRVAL_P(retval_ptr);
|
||||
char resolved_path[MAXPATHLEN];
|
||||
char resolved_path[MAXPATHSIZE];
|
||||
size_t resolved_len;
|
||||
|
||||
if (OPENBASEDIR_CHECKPATH(filename)) {
|
||||
@@ -508,17 +482,15 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
resolved_len = _rar_strnlen(resolved_path, MAXPATHLEN);
|
||||
/* 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) {
|
||||
resolved_len = _rar_strnlen(resolved_path, MAXPATHSIZE);
|
||||
if (resolved_len > MAXPATHSIZE - 1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Resolved path is too big for the unRAR library");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strncpy(dst_buffer, resolved_path, NM);
|
||||
dst_buffer[NM - 1] = '\0';
|
||||
strncpy(dst_buffer, resolved_path, MAXPATHSIZE);
|
||||
dst_buffer[MAXPATHSIZE - 1] = '\0';
|
||||
ret = 1; /* try this new filename */
|
||||
}
|
||||
else {
|
||||
@@ -529,15 +501,8 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||
}
|
||||
|
||||
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(&retval);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -553,17 +518,6 @@ static int _rar_make_userdata_fcall(zval *callable,
|
||||
|
||||
*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,
|
||||
&error TSRMLS_CC) == SUCCESS) {
|
||||
if (error) {
|
||||
@@ -583,7 +537,6 @@ static int _rar_make_userdata_fcall(zval *callable,
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
@@ -634,6 +587,7 @@ ZEND_END_ARG_INFO()
|
||||
/* {{{ rar_functions[]
|
||||
*
|
||||
*/
|
||||
/* clang-format off */
|
||||
static zend_function_entry rar_functions[] = {
|
||||
PHP_FE(rar_open, arginfo_rar_open)
|
||||
PHP_FE(rar_list, arginfo_rar_void_archmeth)
|
||||
@@ -646,16 +600,13 @@ static zend_function_entry rar_functions[] = {
|
||||
PHP_FE(rar_wrapper_cache_stats, arginfo_rar_wrapper_cache_stats)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* clang-format on */
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Globals' related activities */
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
return (ZEND_HASH_APPLY_STOP | ZEND_HASH_APPLY_REMOVE);
|
||||
}
|
||||
@@ -673,13 +624,7 @@ static void _rar_contents_cache_put(const char *key,
|
||||
assert(zend_hash_num_elements(cc->data) == cur_size - 1);
|
||||
}
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
static zval *_rar_contents_cache_get(const char *key,
|
||||
@@ -688,15 +633,7 @@ static zval *_rar_contents_cache_get(const char *key,
|
||||
{
|
||||
rar_contents_cache *cc = &RAR_G(contents_cache);
|
||||
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);
|
||||
#endif
|
||||
|
||||
if (element != NULL) {
|
||||
cc->hits++;
|
||||
@@ -755,16 +692,14 @@ ZEND_MODULE_STARTUP_D(rar)
|
||||
|
||||
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_OS2", HOST_OS2, 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_MACOS", HOST_MACOS, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("RAR_HOST_BEOS", HOST_BEOS, CONST_CS | CONST_PERSISTENT);
|
||||
/* 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
|
||||
/* clang-format on */
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -829,12 +764,6 @@ zend_module_entry rar_module_entry = {
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#endif /* HAVE_RAR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
||||
47
rar_error.c
47
rar_error.c
@@ -25,10 +25,6 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <php.h>
|
||||
#include <zend_exceptions.h>
|
||||
#include "php_rar.h"
|
||||
@@ -70,11 +66,7 @@ void _rar_handle_ext_error(const char *format TSRMLS_DC, ...) /* {{{ */
|
||||
va_list arg;
|
||||
char *message;
|
||||
|
||||
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||
va_start(arg, TSRMLS_C);
|
||||
#else
|
||||
va_start(arg, format);
|
||||
#endif
|
||||
vspprintf(&message, 0, format, arg);
|
||||
va_end(arg);
|
||||
|
||||
@@ -91,13 +83,8 @@ int _rar_using_exceptions(TSRMLS_D)
|
||||
zval *pval;
|
||||
pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||
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);
|
||||
return Z_TYPE_P(pval) == IS_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* returns a string or NULL if not an error */
|
||||
@@ -186,39 +173,22 @@ PHP_METHOD(rarexception, setUsingExceptions)
|
||||
Return whether exceptions are being used */
|
||||
PHP_METHOD(rarexception, isUsingExceptions)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval **pval;
|
||||
#else
|
||||
zval *pval;
|
||||
#endif
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
|
||||
pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
|
||||
(zend_bool) 0);
|
||||
zend_string_release(prop_name);
|
||||
#endif
|
||||
/* property always exists */
|
||||
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);
|
||||
RETURN_ZVAL(pval, 0, 0);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -231,31 +201,24 @@ ZEND_BEGIN_ARG_INFO(arginfo_rarexception_void, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* clang-format off */
|
||||
static zend_function_entry php_rarexception_class_functions[] = {
|
||||
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)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
void minit_rarerror(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
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
|
||||
/* zend_exception_get_default() was removed in PHP 8.5; use the global directly */
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce, zend_ce_exception);
|
||||
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
||||
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
||||
ZEND_ACC_PRIVATE | ZEND_ACC_STATIC TSRMLS_CC);
|
||||
ZEND_ACC_STATIC TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,21 +25,16 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <php.h>
|
||||
#include <wchar.h>
|
||||
#include "php_rar.h"
|
||||
|
||||
#if HAVE_RAR
|
||||
|
||||
/* {{{ Structure definitions */
|
||||
|
||||
/* clang-format off */
|
||||
typedef struct _rar_find_state {
|
||||
rar_find_output out;
|
||||
rar_file_t *rar;
|
||||
@@ -49,7 +44,7 @@ typedef struct _rar_find_state {
|
||||
struct _rar_unique_entry {
|
||||
size_t id; /* position in the entries_array */
|
||||
struct RARHeaderDataEx entry; /* last entry */
|
||||
unsigned long packed_size;
|
||||
zend_ulong packed_size;
|
||||
int depth; /* number of directory separators */
|
||||
size_t name_wlen; /* excluding L'\0' terminator */
|
||||
};
|
||||
@@ -65,6 +60,7 @@ struct _rar_entries {
|
||||
struct _rar_unique_entry *last_accessed;
|
||||
int list_result; /* tell whether the archive's broken */
|
||||
};
|
||||
/* clang-format on */
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -73,9 +69,7 @@ static void _rar_nav_get_depth_and_length(wchar_t *filenamew, const size_t file_
|
||||
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_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);
|
||||
#endif
|
||||
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,
|
||||
const wchar_t *str2, const int depth2,
|
||||
@@ -116,15 +110,9 @@ void _rar_entry_search_start(rar_file_t *rar,
|
||||
sizeof rar->entries->entries_array_s[0]);
|
||||
memcpy(rar->entries->entries_array_s, rar->entries->entries_array,
|
||||
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,
|
||||
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries,
|
||||
_rar_nav_swap_entries);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -336,7 +324,7 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
int result = 0;
|
||||
size_t capacity = 0;
|
||||
int first_file_check = TRUE;
|
||||
unsigned long packed_size = 0UL;
|
||||
zend_ulong packed_size = 0;
|
||||
struct _rar_entries *ents;
|
||||
|
||||
if (rar->entries != NULL) {
|
||||
@@ -378,22 +366,16 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
|
||||
/* reset packed size if not split before */
|
||||
if ((entry.Flags & RHDF_SPLITBEFORE) == 0)
|
||||
packed_size = 0UL;
|
||||
packed_size = 0;
|
||||
|
||||
/* we would exceed size of ulong. cap at ulong_max
|
||||
* equivalent to packed_size + entry.PackSize > ULONG_MAX,
|
||||
* but without overflowing */
|
||||
if (ULONG_MAX - packed_size < entry.PackSize)
|
||||
packed_size = ULONG_MAX;
|
||||
else {
|
||||
packed_size += entry.PackSize;
|
||||
if (entry.PackSizeHigh != 0) {
|
||||
#if ULONG_MAX > 0xffffffffUL
|
||||
packed_size += ((unsigned long) entry.PackSizeHigh) << 32;
|
||||
#else
|
||||
packed_size = ULONG_MAX; /* cap */
|
||||
#endif
|
||||
}
|
||||
/* accumulate packed size; cap at ZEND_LONG_MAX (the PHP int ceiling) */
|
||||
{
|
||||
zend_ulong entry_packed = ((zend_ulong)entry.PackSizeHigh << 32) | entry.PackSize;
|
||||
if (entry_packed > (zend_ulong)ZEND_LONG_MAX ||
|
||||
packed_size > (zend_ulong)ZEND_LONG_MAX - entry_packed)
|
||||
packed_size = (zend_ulong)ZEND_LONG_MAX;
|
||||
else
|
||||
packed_size += entry_packed;
|
||||
}
|
||||
|
||||
if (entry.Flags & RHDF_SPLITAFTER) /* do not commit */
|
||||
@@ -502,7 +484,6 @@ 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) /* {{{ */
|
||||
{
|
||||
/* just swaps two pointer values */
|
||||
@@ -515,7 +496,6 @@ static void _rar_nav_swap_entries(void *op1, void *op2) /* {{{ */
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
static int _rar_nav_compare_entries_std(const void *op1, const void *op2) /* {{{ */
|
||||
{
|
||||
@@ -620,12 +600,6 @@ static size_t _rar_nav_position_on_dir_start(const wchar_t *dir_name,
|
||||
|
||||
/* end functions with internal linkage */
|
||||
|
||||
#endif /* HAVE_RAR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
@@ -634,5 +608,3 @@ static size_t _rar_nav_position_on_dir_start(const wchar_t *dir_name,
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
|
||||
|
||||
|
||||
296
rar_stream.c
296
rar_stream.c
@@ -27,17 +27,11 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <php.h>
|
||||
|
||||
#if HAVE_RAR
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "php_rar.h"
|
||||
@@ -47,14 +41,16 @@ extern "C" {
|
||||
#include <ext/standard/php_string.h>
|
||||
#include <ext/standard/file.h>
|
||||
|
||||
/* clang-format off */
|
||||
typedef struct php_rar_stream_data_t {
|
||||
struct RAROpenArchiveDataEx open_data;
|
||||
struct RARHeaderDataEx header_data;
|
||||
HANDLE rar_handle;
|
||||
size_t file_size;
|
||||
/* TODO: consider encapsulating a php memory/tmpfile stream */
|
||||
unsigned char *buffer;
|
||||
size_t buffer_size;
|
||||
size_t buffer_cont_size; /* content size */
|
||||
size_t buffer_read_size; /* content size */
|
||||
size_t buffer_pos;
|
||||
uint64 cursor;
|
||||
int no_more_data;
|
||||
@@ -72,12 +68,15 @@ typedef struct php_rar_dir_stream_data_t {
|
||||
int no_encode; /* do not urlencode entry names */
|
||||
php_stream *stream;
|
||||
} php_rar_dir_stream_data, *php_rar_dir_stream_data_P;
|
||||
/* clang-format on */
|
||||
|
||||
/* clang-format off */
|
||||
#define STREAM_DATA_FROM_STREAM \
|
||||
php_rar_stream_data_P self = (php_rar_stream_data_P) stream->abstract;
|
||||
|
||||
#define STREAM_DIR_DATA_FROM_STREAM \
|
||||
php_rar_dir_stream_data_P self = (php_rar_dir_stream_data_P) stream->abstract;
|
||||
/* clang-format on */
|
||||
|
||||
/* len can be -1 (calculate) */
|
||||
static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
||||
@@ -98,7 +97,11 @@ static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
||||
/* {{{ RAR file streams */
|
||||
|
||||
/* {{{ 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)
|
||||
#else
|
||||
static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
size_t n = 0;
|
||||
STREAM_DATA_FROM_STREAM
|
||||
@@ -113,12 +116,12 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
while (left > 0) {
|
||||
size_t this_read_size;
|
||||
/* if nothing in the buffer or buffer already read, fill buffer */
|
||||
if (/*self->buffer_cont_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_cont_size)
|
||||
if (/*self->buffer_read_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_read_size)
|
||||
{
|
||||
int res;
|
||||
self->buffer_pos = 0;
|
||||
self->buffer_cont_size = 0;
|
||||
self->buffer_read_size = 0;
|
||||
/* Note: this condition is important, you cannot rely on
|
||||
* having a call to RARProcessFileChunk return no data and
|
||||
* break on the condition self->buffer_cont_size == 0 because
|
||||
@@ -128,25 +131,25 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
if (self->no_more_data)
|
||||
break;
|
||||
res = RARProcessFileChunk(self->rar_handle, self->buffer,
|
||||
self->buffer_size, &self->buffer_cont_size,
|
||||
self->buffer_size, &self->buffer_read_size,
|
||||
&self->no_more_data);
|
||||
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
||||
break; /* finish in case of failure */
|
||||
}
|
||||
assert(self->buffer_cont_size <= self->buffer_size);
|
||||
assert(self->buffer_read_size <= self->buffer_size);
|
||||
/* we did not read anything. no need to continue */
|
||||
if (self->buffer_cont_size == 0)
|
||||
if (self->buffer_read_size == 0)
|
||||
break;
|
||||
}
|
||||
/* if we get here we have data to be read in the buffer */
|
||||
this_read_size = MIN(left,
|
||||
self->buffer_cont_size - self->buffer_pos);
|
||||
self->buffer_read_size - self->buffer_pos);
|
||||
assert(this_read_size > 0);
|
||||
memcpy(&buf[count-left], &self->buffer[self->buffer_pos],
|
||||
this_read_size);
|
||||
left -= this_read_size;
|
||||
n += this_read_size;
|
||||
self->buffer_pos += this_read_size;
|
||||
self->buffer_pos += this_read_size;
|
||||
assert(left >= 0);
|
||||
}
|
||||
|
||||
@@ -155,9 +158,16 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
|
||||
/* no more data upstream (for sure), buffer already read and
|
||||
* caller asked for more data than we're giving */
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_cont_size &&
|
||||
((size_t) n) < count)
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_read_size &&
|
||||
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 */
|
||||
if (!self->no_more_data && n == 0) {
|
||||
@@ -167,17 +177,25 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
stream->eof = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
return (ssize_t) n;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
#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,
|
||||
"Write operation not supported for RAR streams.");
|
||||
if (!stream) {
|
||||
#if PHP_VERSION_ID < 70400
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -293,7 +311,7 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
* SUBHEAD_TYPE_UOWNER), but it is not exposed in unRAR */
|
||||
ssb->sb.st_uid = 0;
|
||||
ssb->sb.st_gid = 0;
|
||||
#ifdef HAVE_ST_RDEV
|
||||
#if defined(HAVE_ST_RDEV) || defined(HAVE_STRUCT_STAT_ST_RDEV)
|
||||
ssb->sb.st_rdev = 0;
|
||||
#endif
|
||||
/* never mind signedness, we'll never get sizes big enough for that to
|
||||
@@ -324,10 +342,10 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
&ssb->sb.st_mtime);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ST_BLKSIZE
|
||||
#if defined(HAVE_ST_BLKSIZE) || defined(HAVE_STRUCT_STAT_ST_BLKSIZE)
|
||||
ssb->sb.st_blksize = 0;
|
||||
#endif
|
||||
#ifdef HAVE_ST_BLOCKS
|
||||
#if defined(HAVE_ST_BLOCKS) || defined (HAVE_STRUCT_STAT_ST_BLOCKS)
|
||||
ssb->sb.st_blocks = 0;
|
||||
#endif
|
||||
/* php_stat in filestat.c doesn't check this one, so don't touch it */
|
||||
@@ -363,19 +381,32 @@ static php_stream_ops php_stream_rario_ops = {
|
||||
/* {{{ RAR directory streams */
|
||||
|
||||
/* {{{ 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)
|
||||
#else
|
||||
static ssize_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||
#endif
|
||||
{
|
||||
php_stream_dirent entry;
|
||||
int offset;
|
||||
size_t offset;
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
if (count != sizeof(entry))
|
||||
if (count != sizeof(entry)) {
|
||||
#if PHP_VERSION_ID < 70400
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
_rar_entry_search_advance(self->state, self->directory, self->dir_size, 1);
|
||||
if (!self->state->found) {
|
||||
stream->eof = 1;
|
||||
#if PHP_VERSION_ID < 70400
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (self->dir_size == 1) /* root */
|
||||
@@ -387,19 +418,10 @@ static size_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count T
|
||||
entry.d_name, sizeof entry.d_name);
|
||||
|
||||
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 =
|
||||
php_url_encode(entry.d_name, strlen(entry.d_name));
|
||||
strlcpy(entry.d_name, encoded_name->val, sizeof entry.d_name);
|
||||
zend_string_release(encoded_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -415,11 +437,7 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
||||
{
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&self->rar_obj);
|
||||
#else
|
||||
zval_ptr_dtor(&self->rar_obj);
|
||||
#endif
|
||||
efree(self->directory);
|
||||
efree(self->state);
|
||||
efree(self);
|
||||
@@ -431,7 +449,11 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
#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
|
||||
|
||||
@@ -508,16 +530,18 @@ php_stream *php_stream_rar_open(char *arc_name,
|
||||
TSRMLS_CC, position, arc_name);
|
||||
else {
|
||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize);
|
||||
size_t buffer_size = MIN(
|
||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
||||
file_size);
|
||||
int process_result = RARProcessFileChunkInit(self->rar_handle);
|
||||
|
||||
if (_rar_handle_error(process_result TSRMLS_CC) == FAILURE) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
self->file_size = file_size;
|
||||
self->buffer = emalloc(buffer_size);
|
||||
self->buffer_size = buffer_size;
|
||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, "rb");
|
||||
@@ -544,67 +568,6 @@ cleanup:
|
||||
|
||||
/* {{{ 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 */
|
||||
/* memory is to be managed externally */
|
||||
static void php_rar_process_context(php_stream_context *context,
|
||||
@@ -615,9 +578,6 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
zval **volume_cb TSRMLS_DC)
|
||||
{
|
||||
zval *ctx_opt;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval **ctx_opt_p = NULL;
|
||||
#endif
|
||||
|
||||
assert(context != NULL);
|
||||
assert(open_password != NULL);
|
||||
@@ -627,14 +587,8 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
|
||||
/* 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(
|
||||
context, "rar", "open_password"))) {
|
||||
#endif
|
||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"RAR open password was provided, but not a string.");
|
||||
@@ -642,14 +596,8 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
*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(
|
||||
context, "rar", "file_password"))) {
|
||||
#endif
|
||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"RAR file password was provided, but not a string.");
|
||||
@@ -657,19 +605,9 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
*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(
|
||||
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)) {
|
||||
#endif
|
||||
*volume_cb = ctx_opt;
|
||||
}
|
||||
else
|
||||
@@ -738,17 +676,19 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
|
||||
|
||||
if (!(options & STREAM_ASSUME_REALPATH)) {
|
||||
if (options & USE_PATH) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*archive = zend_resolve_path(tmp_archive, tmp_arch_len TSRMLS_CC);
|
||||
#else
|
||||
#if PHP_VERSION_ID < 80100
|
||||
zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
|
||||
#else
|
||||
zend_string *tmp_archive_str = zend_string_init_fast(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) {
|
||||
*archive = estrndup(arc_str->val, arc_str->len);
|
||||
} else {
|
||||
*archive = NULL;
|
||||
}
|
||||
zend_string_release(arc_str);
|
||||
#endif
|
||||
}
|
||||
if (*archive == NULL) {
|
||||
if ((*archive = expand_filepath(tmp_archive, NULL TSRMLS_CC))
|
||||
@@ -816,17 +756,10 @@ cleanup:
|
||||
|
||||
/* {{{ php_stream_rar_opener */
|
||||
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 *mode,
|
||||
int options,
|
||||
zend_string **opened_path,
|
||||
#endif
|
||||
php_stream_context *context
|
||||
STREAMS_DC TSRMLS_DC)
|
||||
{
|
||||
@@ -909,21 +842,23 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
|
||||
{
|
||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize);
|
||||
size_t buffer_size = MIN(
|
||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
||||
file_size);
|
||||
rar_result = RARProcessFileChunkInit(self->rar_handle);
|
||||
|
||||
if ((rar_error = _rar_error_to_string(rar_result)) != NULL) {
|
||||
char *mb_entry = _rar_wide_to_utf_with_alloc(fragment, -1);
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Error opening file %s inside RAR archive %s: %s",
|
||||
mb_entry, tmp_open_path, rar_error);
|
||||
"Error opening file %s inside RAR archive %s: %s",
|
||||
mb_entry, tmp_open_path, rar_error);
|
||||
efree(mb_entry);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
self->file_size = file_size;
|
||||
self->buffer = emalloc(buffer_size);
|
||||
self->buffer_size = buffer_size;
|
||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, mode);
|
||||
@@ -936,12 +871,8 @@ cleanup:
|
||||
|
||||
if (tmp_open_path != NULL) {
|
||||
if (opened_path != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*opened_path = tmp_open_path;
|
||||
#else
|
||||
*opened_path =
|
||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||
#endif
|
||||
} else {
|
||||
efree(tmp_open_path);
|
||||
}
|
||||
@@ -997,11 +928,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
zval *cache_zv;
|
||||
|
||||
assert(rar_obj != NULL);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
INIT_ZVAL(*rar_obj);
|
||||
#else
|
||||
ZVAL_UNDEF(rar_obj);
|
||||
#endif
|
||||
|
||||
_rar_arch_cache_get_key(arch_path, open_passwd, volume_cb, &cache_key,
|
||||
&cache_key_len);
|
||||
@@ -1027,7 +954,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
int res;
|
||||
const char *err_str;
|
||||
|
||||
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
@@ -1051,7 +978,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
else { /* cache hit */
|
||||
/* cache get already put the value in rar_obj and incremented the
|
||||
* refcount of the object */
|
||||
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
goto cleanup;
|
||||
@@ -1064,56 +991,26 @@ cleanup:
|
||||
efree(cache_key);
|
||||
|
||||
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_UNDEF(rar_obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _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
|
||||
/* {{{ _rar_stream_tidy_wrapper_error_log */
|
||||
static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
|
||||
{
|
||||
if (wrapper && FG(wrapper_errors)) {
|
||||
zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_stream_rar_stater */
|
||||
static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
char *url,
|
||||
#else
|
||||
const char *url,
|
||||
#endif
|
||||
int flags,
|
||||
php_stream_statbuf *ssb,
|
||||
php_stream_context *context TSRMLS_DC)
|
||||
@@ -1132,11 +1029,7 @@ static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||
int ret = FAILURE;
|
||||
|
||||
/* {{{ preliminaries */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_TYPE(rararch) = IS_NULL;
|
||||
#else
|
||||
ZVAL_UNDEF(&rararch);
|
||||
#endif
|
||||
|
||||
if (_rar_get_archive_and_fragment(wrapper, url, options, 1,
|
||||
&open_path, &fragment, NULL TSRMLS_CC) == FAILURE) {
|
||||
@@ -1187,11 +1080,7 @@ cleanup:
|
||||
}
|
||||
|
||||
if (Z_TYPE(rararch) == IS_OBJECT) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&rararch);
|
||||
#else
|
||||
zval_ptr_dtor(&rararch);
|
||||
#endif
|
||||
}
|
||||
if (state != NULL) {
|
||||
_rar_entry_search_end(state);
|
||||
@@ -1214,17 +1103,10 @@ cleanup:
|
||||
|
||||
/* {{{ php_stream_rar_dir_opener */
|
||||
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 *mode,
|
||||
int options,
|
||||
zend_string **opened_path,
|
||||
#endif
|
||||
php_stream_context *context
|
||||
STREAMS_DC TSRMLS_DC)
|
||||
{
|
||||
@@ -1323,12 +1205,8 @@ cleanup:
|
||||
|
||||
if (tmp_open_path != NULL) {
|
||||
if (opened_path != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*opened_path = tmp_open_path;
|
||||
#else
|
||||
*opened_path =
|
||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||
#endif
|
||||
} else {
|
||||
efree(tmp_open_path);
|
||||
}
|
||||
@@ -1339,11 +1217,7 @@ cleanup:
|
||||
if (stream == NULL) { /* failed */
|
||||
if (self != NULL) {
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
if (self->directory != NULL) {
|
||||
efree(self->directory);
|
||||
@@ -1380,12 +1254,6 @@ php_stream_wrapper php_stream_rar_wrapper = {
|
||||
|
||||
/* end wrapper stuff }}} */
|
||||
|
||||
#endif /* HAVE_RAR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <php.h>
|
||||
#include "php_rar.h"
|
||||
|
||||
@@ -57,7 +53,3 @@ int rar_dos_time_convert(unsigned dos_time, time_t *to) /* {{{ */
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
467
rararch.c
467
rararch.c
@@ -27,39 +27,34 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "zend_types.h"
|
||||
#include <zend_API.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include <wchar.h>
|
||||
#include <php.h>
|
||||
#include <zend_interfaces.h>
|
||||
#include "php_rar.h"
|
||||
#include "php_compat.h"
|
||||
|
||||
/* {{{ Type definitions reserved for this translation unit */
|
||||
/* clang-format off */
|
||||
typedef struct _ze_rararch_object {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zend_object parent;
|
||||
rar_file_t *rar_file;
|
||||
#else
|
||||
rar_file_t *rar_file;
|
||||
zend_object parent;
|
||||
#endif
|
||||
} ze_rararch_object;
|
||||
|
||||
typedef struct _rararch_iterator {
|
||||
zend_object_iterator parent;
|
||||
rar_find_output *state;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *value;
|
||||
#else
|
||||
zval value;
|
||||
#endif
|
||||
int empty_iterator; /* iterator should give nothing */
|
||||
} rararch_iterator;
|
||||
/* clang-format on */
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Globals with internal linkage */
|
||||
@@ -83,39 +78,46 @@ static zend_object_handlers rararch_object_handlers;
|
||||
/* {{{ Function prototypes for functions with internal linkage */
|
||||
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);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
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_ref(const rar_obj_ref ref);
|
||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce);
|
||||
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 */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, long *index, int quiet TSRMLS_DC);
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC);
|
||||
#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
|
||||
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);
|
||||
static int rararch_handlers_preamble(handler_this_t *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_count_elements(handler_this_t *object, zend_long *count TSRMLS_DC);
|
||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv);
|
||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC);
|
||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Function definitions with external linkage */
|
||||
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
int _rar_get_file_resource_zv(zval *zv, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return _rar_get_file_resource_ex(zval_file, rar_file, FALSE TSRMLS_CC);
|
||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
||||
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 */
|
||||
int _rar_create_rararch_obj(const char* resolved_path,
|
||||
const char* open_password,
|
||||
@@ -181,20 +183,21 @@ void _rar_close_file_resource(rar_file_t *rar) /* {{{ */
|
||||
/* When changed from resource to custom object, instead of fiddling
|
||||
* with the refcount to force object destruction, an indication that
|
||||
* the file is already closed is given by setting rar->arch_handle
|
||||
* to NULL. This is checked by _rar_get_file_resource. */
|
||||
* to NULL. This is checked by _rar_get_file_resource_zv. */
|
||||
RARCloseArchive(rar->arch_handle);
|
||||
rar->arch_handle = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Receives archive zval, returns object struct.
|
||||
* If silent is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* If allow_closed is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* is, an exception/error is raised and FAILURE is returned
|
||||
*/
|
||||
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 zobjref_file, rar_file_t **rar_file,
|
||||
int allow_closed TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_rararch_object *zobj;
|
||||
zobj = rararch_object_from_zv(zval_file TSRMLS_CC);
|
||||
zobj = rararch_object_from_ref(zobjref_file);
|
||||
if (zobj == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not find object in the store. This is a bug, please report it.");
|
||||
@@ -202,7 +205,7 @@ int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent
|
||||
}
|
||||
|
||||
*rar_file = zobj->rar_file;
|
||||
if ((*rar_file)->arch_handle == NULL && !silent) { /* rar_close was called */
|
||||
if ((*rar_file)->arch_handle == NULL && !allow_closed) { /* rar_close was called */
|
||||
_rar_handle_ext_error("The archive is already closed" TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -234,25 +237,17 @@ static void _rar_raw_entries_to_array(rar_file_t *rar, zval *target TSRMLS_DC) /
|
||||
state->position, entry_obj TSRMLS_CC);
|
||||
|
||||
add_next_index_zval(target, entry_obj);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
/* PHP 7 copies the zval (but without increasing the refcount of the
|
||||
* obj), while 5.x simply copies the pointer. Only for PHP 5.x do we
|
||||
* keep the allocation) */
|
||||
* obj). Free the allocation. */
|
||||
efree(entry_obj);
|
||||
#endif
|
||||
}
|
||||
} while (state->eof == 0);
|
||||
_rar_entry_search_end(state);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&rararch_obj);
|
||||
#else
|
||||
zval_ptr_dtor(&rararch_obj);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if PHP_MAJOR_VERSION >=7
|
||||
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
||||
{
|
||||
return Z_OBJ(*zv);
|
||||
@@ -262,24 +257,7 @@ static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC)
|
||||
ZVAL_OBJ(zv, zo);
|
||||
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)
|
||||
{
|
||||
return (ze_rararch_object *)
|
||||
@@ -289,35 +267,12 @@ static ze_rararch_object *rararch_object_from_zv(const zval *zv)
|
||||
{
|
||||
return rararch_object_fetch(Z_OBJ_P(zv));
|
||||
}
|
||||
#endif
|
||||
static ze_rararch_object *rararch_object_from_ref(const rar_obj_ref ref)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ze_rararch_object *zobj =
|
||||
@@ -329,18 +284,12 @@ static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
||||
|
||||
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)
|
||||
{
|
||||
ze_rararch_object *object = rararch_object_fetch(zobj);
|
||||
#endif
|
||||
rar_file_t *rar = object->rar_file;
|
||||
|
||||
/* may be NULL if the user did new RarArchive() */
|
||||
@@ -364,20 +313,18 @@ static void rararch_ce_free_object_storage(zend_object *zobj)
|
||||
/* could call zend_objects_free_object_storage here (not before!), but
|
||||
* instead I'll mimic its behaviour */
|
||||
zend_object_std_dtor(&object->parent TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
efree(object);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive handlers */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
static int rararch_handlers_preamble(handler_this_t *object,
|
||||
rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
/* don't call zend_objects_get_address or zend_object_store_get directly;
|
||||
* _rar_get_file_resource checks if the archive was closed */
|
||||
if (_rar_get_file_resource(object, rar TSRMLS_CC) == FAILURE) {
|
||||
* _rar_get_file_resource_zv checks if the archive was closed */
|
||||
if (_rar_get_file_resource_handler(object, rar TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -391,7 +338,7 @@ static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC) /
|
||||
/* {{{ rararch_dimensions_preamble - semi-strict parsing of int argument */
|
||||
static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
zval *offset,
|
||||
long *index,
|
||||
zend_long *index,
|
||||
int quiet TSRMLS_DC)
|
||||
{
|
||||
if (offset == NULL) {
|
||||
@@ -415,34 +362,32 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
return FAILURE;
|
||||
}
|
||||
else if (type == IS_DOUBLE) {
|
||||
if (d > LONG_MAX || d < LONG_MIN) {
|
||||
if (d > (double) ZEND_LONG_MAX || d < (double) ZEND_LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*index = (long) d;
|
||||
*index = (zend_long) d;
|
||||
}
|
||||
}
|
||||
else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
if (Z_DVAL_P(offset) > LONG_MAX || Z_DVAL_P(offset) < LONG_MIN) {
|
||||
if (Z_DVAL_P(offset) > (double) ZEND_LONG_MAX ||
|
||||
Z_DVAL_P(offset) < (double) ZEND_LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
}
|
||||
*index = (long) Z_DVAL_P(offset);
|
||||
*index = (zend_long) Z_DVAL_P(offset);
|
||||
}
|
||||
else if (Z_TYPE_P(offset) == IS_OBJECT) {
|
||||
#if PHP_MAJOR_VERSION < 8
|
||||
if (Z_OBJ_HT_P(offset)->get) {
|
||||
zval *newoffset = NULL;
|
||||
int ret;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset TSRMLS_CC);
|
||||
#else
|
||||
zval zv_holder;
|
||||
ZVAL_NULL(&zv_holder);
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset, &zv_holder);
|
||||
#endif
|
||||
|
||||
/* get handler cannot return NULL */
|
||||
assert(newoffset != NULL);
|
||||
@@ -455,12 +400,28 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
|
||||
ret = rararch_dimensions_preamble(rar, newoffset, index, quiet
|
||||
TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&newoffset);
|
||||
#else
|
||||
zval_ptr_dtor(newoffset);
|
||||
#endif
|
||||
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 {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
@@ -476,9 +437,9 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (*index < 0L) {
|
||||
if (*index < 0) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index must be non-negative, given %ld", *index);
|
||||
"Dimension index must be non-negative, given " ZEND_LONG_FMT, *index);
|
||||
return FAILURE;
|
||||
}
|
||||
if ((size_t) *index >= _rar_entry_count(rar)) {
|
||||
@@ -493,34 +454,30 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive count_elements handler */
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||
static int rararch_count_elements(handler_this_t *object, zend_long *count TSRMLS_DC)
|
||||
{
|
||||
rar_file_t *rar = NULL;
|
||||
size_t entry_count;
|
||||
|
||||
if (rararch_handlers_preamble(object, &rar TSRMLS_CC) == FAILURE) {
|
||||
*count = 0L;
|
||||
*count = 0;
|
||||
return SUCCESS; /* intentional */
|
||||
}
|
||||
|
||||
entry_count = _rar_entry_count(rar);
|
||||
if (entry_count > LONG_MAX)
|
||||
entry_count = (size_t) LONG_MAX;
|
||||
if (entry_count > ZEND_LONG_MAX)
|
||||
entry_count = (size_t) ZEND_LONG_MAX;
|
||||
|
||||
*count = (long) entry_count;
|
||||
*count = (zend_long) entry_count;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive read_dimension handler */
|
||||
#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
|
||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv)
|
||||
{
|
||||
long index;
|
||||
zend_long index;
|
||||
rar_file_t *rar = NULL;
|
||||
struct _rar_find_output *out;
|
||||
zval *ret = NULL;
|
||||
@@ -541,23 +498,24 @@ static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *
|
||||
_rar_entry_search_seek(out, (size_t) index);
|
||||
_rar_entry_search_advance(out, NULL, 0, 0);
|
||||
assert(out->found);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
ALLOC_INIT_ZVAL(ret);
|
||||
#else
|
||||
ret = rv;
|
||||
#endif
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
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
|
||||
_rar_entry_to_zval(object, out->header, out->packed_size, out->position,
|
||||
ret TSRMLS_CC);
|
||||
_rar_entry_search_end(out);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_DELREF_P(ret); /* set refcount to 0 */
|
||||
#endif
|
||||
_rar_entry_search_end(out);
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive write_dimension handler */
|
||||
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
|
||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -565,9 +523,9 @@ static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRM
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive has_dimension handler */
|
||||
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
{
|
||||
long index;
|
||||
zend_long index;
|
||||
rar_file_t *rar = NULL;
|
||||
|
||||
(void) check_empty; /* don't care */
|
||||
@@ -582,7 +540,7 @@ static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSR
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive unset_dimension handler */
|
||||
static void rararch_unset_dimension(zval *object, zval *offset TSRMLS_DC)
|
||||
static void rararch_unset_dimension(handler_this_t *object, zval *offset TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -622,11 +580,7 @@ PHP_FUNCTION(rar_open)
|
||||
assert(strnlen(resolved_path, MAXPATHLEN) < MAXPATHLEN);
|
||||
|
||||
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)) {
|
||||
#endif
|
||||
_rar_handle_ext_error("%s" TSRMLS_CC, "Expected the third "
|
||||
"argument, if provided, to be a valid callback");
|
||||
RETURN_FALSE;
|
||||
@@ -661,7 +615,7 @@ PHP_FUNCTION(rar_list)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -696,7 +650,7 @@ PHP_FUNCTION(rar_entry_get)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -733,7 +687,7 @@ PHP_FUNCTION(rar_solid_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -751,7 +705,7 @@ PHP_FUNCTION(rar_comment_get)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -782,7 +736,7 @@ PHP_FUNCTION(rar_broken_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -813,7 +767,7 @@ PHP_FUNCTION(rar_allow_broken_set)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -831,7 +785,7 @@ PHP_FUNCTION(rar_close)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -855,7 +809,8 @@ PHP_METHOD(rararch, __toString)
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
if (_rar_get_file_resource_ex(arch_obj, &rar, TRUE TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv_ex(arch_obj, &rar, TRUE TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
RETURN_FALSE; /* should never happen */
|
||||
}
|
||||
|
||||
@@ -876,6 +831,18 @@ 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 */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_open, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, filename)
|
||||
@@ -891,10 +858,23 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_setallowbroken, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, allow_broken)
|
||||
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_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[] = {
|
||||
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)
|
||||
@@ -907,10 +887,14 @@ static zend_function_entry php_rararch_class_functions[] = {
|
||||
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(close, rar_close, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rararch, __toString, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rararch, __toString, arginfo_rararchive_tostring, ZEND_ACC_PUBLIC)
|
||||
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}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
/* {{{ Iteration. Very boring stuff indeed. */
|
||||
|
||||
@@ -922,78 +906,17 @@ 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_fetch(rararch_iterator *it 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);
|
||||
#endif
|
||||
static void rararch_it_move_forward(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 */
|
||||
static void rararch_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
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_UNDEF(&it->value);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1004,16 +927,9 @@ static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC)
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
_rar_entry_search_end(it->state);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
efree(it);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1024,91 +940,47 @@ static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC)
|
||||
int res;
|
||||
zval *robj;
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(it->value == NULL);
|
||||
#else
|
||||
assert(Z_TYPE(it->value) == IS_UNDEF);
|
||||
#endif
|
||||
|
||||
if (it->empty_iterator) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(it->value);
|
||||
ZVAL_FALSE(it->value);
|
||||
#else
|
||||
ZVAL_FALSE(&it->value);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
robj = it->parent.data;
|
||||
#else
|
||||
robj = &it->parent.data;
|
||||
#endif
|
||||
|
||||
res = _rar_get_file_resource_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||
res = _rar_get_file_resource_zv_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||
if (res == FAILURE)
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"Cannot fetch RarArchive object");
|
||||
|
||||
_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)
|
||||
_rar_entry_to_zval(&it->parent.data, it->state->header,
|
||||
it->state->packed_size, it->state->position, &it->value TSRMLS_CC);
|
||||
else {
|
||||
ZVAL_FALSE(&it->value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_valid */
|
||||
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;
|
||||
assert(Z_TYPE_P(value) != IS_UNDEF);
|
||||
return Z_TYPE_P(value) != IS_FALSE ? SUCCESS : FAILURE;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
{
|
||||
zval *ret;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
ret = ((rararch_iterator *) iter)->value;
|
||||
assert(ret != NULL);
|
||||
#else
|
||||
ret = &((rararch_iterator *) iter)->value;
|
||||
assert(Z_TYPE_P(ret) != IS_UNDEF);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_move_forward */
|
||||
@@ -1116,11 +988,7 @@ static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
rararch_iterator *it = (rararch_iterator *) iter;
|
||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
it->value = NULL;
|
||||
#else
|
||||
ZVAL_UNDEF(&it->value);
|
||||
#endif
|
||||
rararch_it_fetch(it TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -1147,6 +1015,55 @@ 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)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
@@ -1159,10 +1076,8 @@ void minit_rararch(TSRMLS_D)
|
||||
rararch_object_handlers.has_dimension = rararch_has_dimension;
|
||||
rararch_object_handlers.unset_dimension = rararch_unset_dimension;
|
||||
rararch_object_handlers.clone_obj = NULL;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
rararch_object_handlers.free_obj = rararch_ce_free_object_storage;
|
||||
rararch_object_handlers.offset = XtOffsetOf(ze_rararch_object, parent);
|
||||
#endif
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarArchive", php_rararch_class_functions);
|
||||
rararch_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
@@ -1170,10 +1085,12 @@ void minit_rararch(TSRMLS_D)
|
||||
rararch_ce_ptr->clone = NULL;
|
||||
rararch_ce_ptr->create_object = &rararch_ce_create_object;
|
||||
rararch_ce_ptr->get_iterator = rararch_it_get_iterator;
|
||||
#if PHP_VERSION_ID < 70300
|
||||
rararch_ce_ptr->iterator_funcs.funcs = &rararch_it_funcs;
|
||||
zend_class_implements(rararch_ce_ptr TSRMLS_CC, 1, zend_ce_traversable);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
|
||||
144
rarentry.c
144
rarentry.c
@@ -27,11 +27,10 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <zend_types.h>
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
#include <php.h>
|
||||
@@ -52,49 +51,44 @@ static void _rar_dos_date_to_text(unsigned dos_time, char *date_string);
|
||||
/* {{{ Functions with external linkage */
|
||||
/* 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 */
|
||||
/* parent is zval to RarArchive object. The object (not the zval, in PHP 5.x)
|
||||
/* parent is zval to RarArchive object. The object
|
||||
* will have its refcount increased */
|
||||
void _rar_entry_to_zval(zval *parent,
|
||||
struct RARHeaderDataEx *entry,
|
||||
unsigned long packed_size,
|
||||
zend_ulong packed_size,
|
||||
size_t position,
|
||||
zval *object TSRMLS_DC) /* {{{ */
|
||||
zval *object TSRMLS_DC)
|
||||
/* {{{ */
|
||||
{
|
||||
char tmp_s [MAX_LENGTH_OF_LONG + 1];
|
||||
char time[50];
|
||||
char *filename;
|
||||
int filename_size,
|
||||
filename_len;
|
||||
long unp_size; /* zval stores PHP ints as long, so use that here */
|
||||
zend_long unp_size;
|
||||
zval *parent_copy = parent;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
/* allocate zval on the heap */
|
||||
zval_addref_p(parent_copy);
|
||||
SEPARATE_ZVAL(&parent_copy);
|
||||
/* set refcount to 0; zend_update_property will increase it */
|
||||
Z_DELREF_P(parent_copy);
|
||||
#endif
|
||||
|
||||
object_init_ex(object, rar_class_entry_ptr);
|
||||
zend_update_property(rar_class_entry_ptr, object, "rarfile",
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
zend_object *obj = Z_OBJ_P(object);
|
||||
#else
|
||||
zval *obj = object;
|
||||
#endif
|
||||
|
||||
zend_update_property(rar_class_entry_ptr, obj, "rarfile",
|
||||
sizeof("rararch") - 1, parent_copy TSRMLS_CC);
|
||||
|
||||
#if ULONG_MAX > 0xffffffffUL
|
||||
unp_size = ((long) entry->UnpSize) + (((long) entry->UnpSizeHigh) << 32);
|
||||
#else
|
||||
/* 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
|
||||
{
|
||||
uint64_t raw_size = (uint64_t)entry->UnpSizeHigh << 32 | entry->UnpSize;
|
||||
unp_size = raw_size > (uint64_t)ZEND_LONG_MAX
|
||||
? ZEND_LONG_MAX : (zend_long)raw_size;
|
||||
}
|
||||
|
||||
filename_size = sizeof(entry->FileNameW) * 4;
|
||||
filename = (char*) emalloc(filename_size);
|
||||
|
||||
if (packed_size > (unsigned long) LONG_MAX)
|
||||
packed_size = LONG_MAX;
|
||||
if (packed_size > (zend_ulong) ZEND_LONG_MAX)
|
||||
packed_size = (zend_ulong) ZEND_LONG_MAX;
|
||||
_rar_wide_to_utf(entry->FileNameW, filename, filename_size);
|
||||
/* OK; safe usage below: */
|
||||
filename_len = _rar_strnlen(filename, filename_size);
|
||||
@@ -102,42 +96,42 @@ void _rar_entry_to_zval(zval *parent,
|
||||
* properties from here with add_property_x, or
|
||||
* direct call to rarentry_object_handlers.write_property
|
||||
* zend_update_property_x updates the scope accordingly */
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "position",
|
||||
sizeof("position") - 1, (long) position TSRMLS_CC);
|
||||
zend_update_property_stringl(rar_class_entry_ptr, object, "name",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "position",
|
||||
sizeof("position") - 1, (zend_long) position TSRMLS_CC);
|
||||
zend_update_property_stringl(rar_class_entry_ptr, obj, "name",
|
||||
sizeof("name") - 1, filename, filename_len TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "unpacked_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "unpacked_size",
|
||||
sizeof("unpacked_size") - 1, unp_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "packed_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "packed_size",
|
||||
sizeof("packed_size") - 1, packed_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "host_os",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "host_os",
|
||||
sizeof("host_os") - 1, entry->HostOS TSRMLS_CC);
|
||||
|
||||
_rar_dos_date_to_text(entry->FileTime, time);
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "file_time",
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "file_time",
|
||||
sizeof("file_time") - 1, time TSRMLS_CC);
|
||||
|
||||
sprintf(tmp_s, "%x", entry->FileCRC);
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "crc",
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "crc",
|
||||
sizeof("crc") - 1, tmp_s TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "attr",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "attr",
|
||||
sizeof("attr") - 1, entry->FileAttr TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "version",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "version",
|
||||
sizeof("version") - 1, entry->UnpVer TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "method",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "method",
|
||||
sizeof("method") - 1, entry->Method TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "flags",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "flags",
|
||||
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "redir_type",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "redir_type",
|
||||
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
||||
|
||||
if (entry->RedirName) {
|
||||
char *redir_target = NULL;
|
||||
size_t redir_target_size;
|
||||
|
||||
zend_update_property_bool(rar_class_entry_ptr, object,
|
||||
zend_update_property_bool(rar_class_entry_ptr, obj,
|
||||
"redir_to_directory", sizeof("redir_to_directory") - 1,
|
||||
!!entry->DirTarget TSRMLS_CC);
|
||||
|
||||
@@ -146,7 +140,7 @@ void _rar_entry_to_zval(zval *parent,
|
||||
assert(redir_target_size > 0);
|
||||
_rar_wide_to_utf(entry->RedirName, redir_target, redir_target_size);
|
||||
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "redir_target",
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "redir_target",
|
||||
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
||||
|
||||
efree(redir_target);
|
||||
@@ -170,7 +164,7 @@ void _rar_entry_to_zval(zval *parent,
|
||||
|
||||
#define REG_RAR_CLASS_CONST_LONG(const_name, value) \
|
||||
zend_declare_class_constant_long(rar_class_entry_ptr, const_name, \
|
||||
sizeof(const_name) - 1, (long) value TSRMLS_CC)
|
||||
sizeof(const_name) - 1, (zend_long) value TSRMLS_CC)
|
||||
|
||||
#define REG_RAR_PROPERTY(name, comment) \
|
||||
_rar_decl_priv_prop_null(rar_class_entry_ptr, name, sizeof(name) -1, \
|
||||
@@ -180,13 +174,6 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
||||
int name_length, char *doc_comment,
|
||||
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;
|
||||
zend_string *name_str,
|
||||
*doc_str;
|
||||
@@ -195,29 +182,32 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
||||
ZVAL_NULL(&property);
|
||||
name_str = zend_string_init(name, (size_t) name_length, 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,
|
||||
doc_str);
|
||||
#endif
|
||||
zend_string_release(name_str);
|
||||
zend_string_release(doc_str);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *tmp;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval zv;
|
||||
#endif
|
||||
#if PHP_VERSION_ID < 70100
|
||||
zend_class_entry *orig_scope = EG(scope);
|
||||
|
||||
EG(scope) = rar_class_entry_ptr;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1 TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), Z_OBJ_P(entry_obj), name, namelen, 1, &zv);
|
||||
#else
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
||||
#endif
|
||||
@@ -255,8 +245,8 @@ static void _rar_dos_date_to_text(unsigned dos_time, char *date_string) /* {{{ *
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Methods */
|
||||
/* {{{ proto bool RarEntry::extract(string dir [, string filepath = ''
|
||||
[, string password = NULL [, bool extended_data = FALSE]])
|
||||
/* {{{ public function extract(?string $dir, ?string $filepath = '',
|
||||
?string $password = null, bool $extended_data = false): void {}
|
||||
Extract file from the archive */
|
||||
PHP_METHOD(rarentry, extract)
|
||||
{ /* lots of variables, but no need to be intimidated */
|
||||
@@ -275,7 +265,7 @@ PHP_METHOD(rarentry, extract)
|
||||
*tmp_position;
|
||||
rar_file_t *rar = NULL;
|
||||
zval *entry_obj = getThis();
|
||||
struct RARHeaderDataEx entry;
|
||||
struct RARHeaderDataEx entry = {0};
|
||||
HANDLE extract_handle = NULL;
|
||||
int result;
|
||||
int found;
|
||||
@@ -283,14 +273,14 @@ PHP_METHOD(rarentry, extract)
|
||||
* password that's different from the one stored in the rar_file_t object*/
|
||||
rar_cb_user_data cb_udata = {NULL};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss!b", &dir,
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!|s!s!b", &dir,
|
||||
&dir_len, &filepath, &filepath_len, &password, &password_len,
|
||||
&process_ed) == FAILURE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -544,7 +534,7 @@ PHP_METHOD(rarentry, getStream)
|
||||
|
||||
RAR_GET_PROPERTY(position, "position");
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -571,7 +561,7 @@ PHP_METHOD(rarentry, isDirectory)
|
||||
{
|
||||
zval *tmp;
|
||||
zval *entry_obj = getThis();
|
||||
long flags;
|
||||
zend_long flags;
|
||||
int is_dir;
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
@@ -590,7 +580,7 @@ PHP_METHOD(rarentry, isEncrypted)
|
||||
{
|
||||
zval *tmp;
|
||||
zval *entry_obj = getThis();
|
||||
long flags;
|
||||
zend_long flags;
|
||||
int is_encrypted;
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
@@ -699,12 +689,21 @@ PHP_METHOD(rarentry, __toString)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo */
|
||||
#if PHP_MAJOR_VERSION < 8
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_extract, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, path)
|
||||
ZEND_ARG_INFO(0, filename)
|
||||
ZEND_ARG_INFO(0, password)
|
||||
ZEND_ARG_INFO(0, extended_data)
|
||||
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_ARG_INFO(0, password)
|
||||
@@ -712,8 +711,16 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_rar_void, 0)
|
||||
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[] = {
|
||||
PHP_ME(rarentry, extract, arginfo_rarentry_extract, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, getPosition, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
@@ -732,10 +739,11 @@ static zend_function_entry php_rar_class_functions[] = {
|
||||
PHP_ME(rarentry, getRedirType, 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, __toString, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, __toString, arginfo_rar_tostring, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
void minit_rarentry(TSRMLS_D)
|
||||
{
|
||||
@@ -762,6 +770,7 @@ void minit_rarentry(TSRMLS_D)
|
||||
REG_RAR_PROPERTY("redir_to_directory", "Whether the redirection target is a directory");
|
||||
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_OS2", HOST_OS2);
|
||||
REG_RAR_CLASS_CONST_LONG("HOST_WIN32", HOST_WIN32);
|
||||
@@ -813,8 +822,5 @@ void minit_rarentry(TSRMLS_D)
|
||||
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_SOCKET", 0x0C000L);
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
3797
run-tests-rar.php
Normal file
3797
run-tests-rar.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ rar_list() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$list1 = rar_list($rar_file1);
|
||||
var_dump($list1);
|
||||
@@ -14,8 +15,7 @@ $list2 = rar_list($rar_file2);
|
||||
var_dump($list2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
$list3 = rar_list($rar_file3);
|
||||
var_dump($list3);
|
||||
argerr(function() use ($rar_file3) { rar_list($rar_file3); });
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -163,6 +163,5 @@ array(2) {
|
||||
|
||||
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, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_list() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
Done
|
||||
|
||||
@@ -5,6 +5,7 @@ rar_entry_get() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$entry1 = rar_entry_get($rar_file1, 'test file with whitespaces.txt');
|
||||
var_dump($entry1);
|
||||
@@ -14,8 +15,9 @@ $entry2 = rar_entry_get($rar_file2, '2.txt');
|
||||
var_dump($entry2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
$entry3 = rar_entry_get($rar_file3, '2.txt');
|
||||
var_dump($entry3);
|
||||
argerr(function() use ($rar_file3) {
|
||||
rar_entry_get($rar_file3, '2.txt');
|
||||
});
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -89,6 +91,5 @@ object(RarEntry)#%d (%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, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
Done
|
||||
|
||||
@@ -5,6 +5,8 @@ rar_entry_get() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part1.rar');
|
||||
$entry = rar_entry_get($rar_file1, "file1.txt");
|
||||
echo "$entry\n";
|
||||
@@ -13,8 +15,9 @@ var_dump($entry);
|
||||
echo "\n";
|
||||
|
||||
$rar_file2 = rar_open(dirname(__FILE__).'/nonexistent.rar');
|
||||
$entry = rar_entry_get($rar_file2, "file1.txt");
|
||||
var_dump($entry);
|
||||
argerr(function() use ($rar_file2) {
|
||||
rar_entry_get($rar_file2, "file1.txt");
|
||||
});
|
||||
echo "\n";
|
||||
|
||||
echo "Done\n";
|
||||
@@ -28,7 +31,6 @@ bool(false)
|
||||
|
||||
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, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
|
||||
Done
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarEntry::getStream() function (good RAR file, several volumes)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarEntry::getStream() function (store method)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarEntry::getStream() function (solid archive)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@ foreach ($rarF as $k => $rarE) {
|
||||
}
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): The archive is already closed, cannot give an iterator in %s on line %d
|
||||
Fatal error: main(): The archive is already closed, cannot give an iterator in %s on line %d%A
|
||||
|
||||
@@ -7,9 +7,9 @@ if(!extension_loaded("rar")) die("skip");
|
||||
<?php
|
||||
chdir(dirname(__FILE__));
|
||||
function volume_callback($vol) {
|
||||
if (preg_match('/_fail/', $vol))
|
||||
if (strpos($vol, '_fail') !== false)
|
||||
$ret = basename(str_replace('_fail', '', $vol));
|
||||
elseif (preg_match('/_broken/', $vol))
|
||||
elseif (strpos($vol, '_broken') !== false)
|
||||
$ret = basename(str_replace('_broken', '_fail', $vol));
|
||||
else
|
||||
$ret = null;
|
||||
|
||||
@@ -5,6 +5,7 @@ rar_open() with invalid volume callback
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
|
||||
class A {
|
||||
public static function resolve($vol) {
|
||||
@@ -30,11 +31,15 @@ var_dump($rar);
|
||||
|
||||
echo "\nGiven callback that takes more arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'strpos');
|
||||
$rar->getEntries();
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
|
||||
echo "\nGiven callback that takes another kind of arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'array_keys');
|
||||
$rar->getEntries();
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
|
||||
echo "\nGiven callback that returns another kind of arguments:\n";
|
||||
function testA($vol) { return true; }
|
||||
@@ -52,7 +57,7 @@ try {
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
Not given a callback:
|
||||
|
||||
Warning: RarArchive::open(): Expected the third argument, if provided, to be a valid callback in %s on line %d
|
||||
@@ -64,15 +69,33 @@ bool(false)
|
||||
|
||||
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: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
<?php } ?>
|
||||
|
||||
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: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
<?php } ?>
|
||||
|
||||
Given callback that returns another kind of arguments:
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarEntry::getStream() function (broken set fixed with volume callback)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function resolve($vol) {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarEntry::extract() function (broken set fixed with volume callback)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
function resolve($vol) {
|
||||
@@ -10,9 +13,9 @@ function resolve($vol) {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
echo "Fail:\n";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar');
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
--TEST--
|
||||
RarArchive::open() volume callback long return (case MAXPATHLEN > NM)
|
||||
RarArchive::open() volume callback long return (case MAXPATHLEN > MAXPATHSIZE)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
define('MAXPATHSIZE', 0x10000);
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (!defined("PHP_MAXPATHLEN"))
|
||||
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
||||
if (!(PHP_MAXPATHLEN > 2048))
|
||||
if (!(PHP_MAXPATHLEN > MAXPATHSIZE))
|
||||
die("skip test is for systems where MAXPATHLEN > 2048");
|
||||
$rp = dirname(__FILE__) . "/" . str_repeat("a", 2048);
|
||||
$rp = dirname(__FILE__) . "/" . str_repeat("a", MAXPATHSIZE);
|
||||
if (strlen(dirname(__FILE__) > PHP_MAXPATHLEN - 1))
|
||||
die("skip current directory is too deep.");
|
||||
--FILE--
|
||||
@@ -18,7 +19,7 @@ if (!defined("PHP_MAXPATHLEN"))
|
||||
chdir(dirname(__FILE__));
|
||||
$fn = dirname(__FILE__) . '/multi_broken.part1.rar';
|
||||
|
||||
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", 2048); }
|
||||
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", MAXPATHSIZE); }
|
||||
$rar = RarArchive::open($fn, null, 'testA');
|
||||
$rar->getEntries();
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ string(5) "11111"
|
||||
Test with include path:
|
||||
Should fail (not in include):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Should fail (include unused):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Should succeed:
|
||||
string(5) "11111"
|
||||
|
||||
@@ -20,9 +20,9 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Archive not found :
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
File not found :
|
||||
|
||||
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.
|
||||
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
|
||||
Done.
|
||||
|
||||
@@ -27,21 +27,21 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Test empty:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Test no fragment:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Test empty fragment:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Test no path:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Test no path and empty fragment:
|
||||
|
||||
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
|
||||
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
|
||||
Done.
|
||||
|
||||
@@ -55,11 +55,11 @@ echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
Headers: should not work (no password):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Headers: should not work (password given was file_password):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Headers: should work (password given was open_password):
|
||||
string(26) "Encrypted file 1 contents."
|
||||
@@ -67,11 +67,11 @@ string(26) "Encrypted file 1 contents."
|
||||
|
||||
Files: should not work (no password):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Files: should not work (password given was open_password):
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
Files: should work (password given was file_password):
|
||||
string(26) "Encrypted file 1 contents."
|
||||
|
||||
@@ -3,6 +3,7 @@ Stream wrapper with volume find callback
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if(PHP_INT_SIZE < 8) die("skip 32-bit PHP not supported");
|
||||
--FILE--
|
||||
<?php
|
||||
function resolve($vol) {
|
||||
|
||||
@@ -12,6 +12,6 @@ var_dump(opendir($u));
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Warning: opendir(rar://%sdirlink_unix.rar#file): failed to open dir: Archive %sdirlink_unix.rar has an entry named file, but it is not a directory in %s on line %d
|
||||
Warning: opendir(rar://%sdirlink_unix.rar#file): %cailed to open dir%S: Archive %sdirlink_unix.rar has an entry named file, but it is not a directory in %s on line %d
|
||||
bool(false)
|
||||
Done.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
RarArchive direct instantiation does not crash (PHP 5.x)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID >= 70000) die("skip for PHP 5.x");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new RarArchive();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Call to private RarArchive::__construct() from invalid context in %s on line %d
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry direct instantiation does not crash (PHP 5.x)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID >= 70000) die("skip for PHP 5.x");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new RarEntry();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Call to private RarEntry::__construct() from invalid context in %s on line %d
|
||||
@@ -48,12 +48,12 @@ Count: 13
|
||||
|
||||
* Closed file test (1):
|
||||
|
||||
Warning: count(): The archive is already closed in %s on line %d
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (2):
|
||||
|
||||
Warning: count(): The archive is already closed in %s on line %d
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (3, exceptions):
|
||||
|
||||
@@ -15,10 +15,12 @@ echo "string (\"0.001\"). {$a['0.001']}\n";
|
||||
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
string ("0"). RarEntry for file "1.txt" (a0de71c0)
|
||||
<?php if (PHP_VERSION_ID < 80000) { ?>
|
||||
|
||||
Notice: A non well formed numeric value encountered in %s on line %d
|
||||
<?php } ?>
|
||||
string ("1abc"). RarEntry for file "2.txt" (45a918de)
|
||||
float (0.001). RarEntry for file "1.txt" (a0de71c0)
|
||||
string ("0.001"). RarEntry for file "1.txt" (a0de71c0)
|
||||
|
||||
@@ -42,7 +42,7 @@ echo $a[new stdClass()];
|
||||
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
* -1 (int):
|
||||
|
||||
Warning: main(): Dimension index must be non-negative, given -1 in %s on line %d
|
||||
@@ -81,6 +81,11 @@ Warning: main(): Attempt to use a non-numeric dimension to access a RarArchive o
|
||||
|
||||
* new stdClass():
|
||||
|
||||
Warning: main(): Attempt to use an object with no get handler as a dimension to access a RarArchive object in %s on line %d
|
||||
<?php if (PHP_VERSION_ID >= 80000) { ?>
|
||||
Warning: main(): Could not convert object given as dimension index into an integer (cast_object failed) in %s on line %d
|
||||
|
||||
<?php } else { ?>
|
||||
Notice: Object of class stdClass could not be converted to int in %s on line %d
|
||||
RarEntry for file "2.txt" (45a918de)
|
||||
<?php } ?>
|
||||
Done.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -13,4 +16,4 @@ $a[0] = "jjj";
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d%A
|
||||
|
||||
@@ -18,4 +18,4 @@ unset($a[0]["jj"]);
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): A RarArchive object is not modifiable in %s on line %d
|
||||
Fatal error: main(): A RarArchive object is not modifiable in %s on line %d%A
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7')
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -13,4 +16,4 @@ $a[0] = "hhh";
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d%A
|
||||
|
||||
@@ -13,4 +13,4 @@ unset($a[0]);
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d
|
||||
Fatal error: main(): A RarArchive object is not writable in %s on line %d%A
|
||||
|
||||
@@ -5,13 +5,18 @@ RarArchive::isBroken/rar_broken_is test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$f = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$b = dirname(__FILE__) . "/multi_broken.part1.rar";
|
||||
|
||||
echo "\n* unbroken file; bad arguments\n";
|
||||
$a = RarArchive::open($f);
|
||||
var_dump($a->isBroken("jjj"));
|
||||
var_dump(rar_broken_is($a, "jjj"));
|
||||
argerr(function() use ($a) {
|
||||
$a->isBroken("jjj");
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_broken_is($a, "jjj");
|
||||
});
|
||||
|
||||
echo "\n* unbroken file; as first call\n";
|
||||
var_dump($a->isBroken());
|
||||
@@ -46,10 +51,8 @@ echo "Done.\n";
|
||||
* unbroken file; bad arguments
|
||||
|
||||
Warning: RarArchive::isBroken() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: rar_broken_is() expects exactly 1 parameter, 2 given in %s on line %d
|
||||
NULL
|
||||
|
||||
* unbroken file; as first call
|
||||
bool(false)
|
||||
|
||||
@@ -5,13 +5,18 @@ RarArchive::setAllowBroken has the desired effect
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
function retnull() { return null; }
|
||||
$b = dirname(__FILE__) . "/multi_broken.part1.rar";
|
||||
|
||||
echo "* broken file; bad arguments\n";
|
||||
$a = RarArchive::open($b, null, 'retnull');
|
||||
$a->setAllowBroken();
|
||||
rar_allow_broken_set($a);
|
||||
argerr(function() use ($a) {
|
||||
$a->setAllowBroken();
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_allow_broken_set($a);
|
||||
});
|
||||
|
||||
echo "\n* broken file; do not allow broken (default)\n";
|
||||
$a = RarArchive::open($b, null, 'retnull');
|
||||
@@ -54,7 +59,7 @@ Warning: rar_allow_broken_set() expects exactly 2 parameters, 1 given in %s on l
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; do not allow broken (explicit)
|
||||
@@ -62,7 +67,7 @@ int(0)
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; allow broken
|
||||
|
||||
@@ -15,4 +15,4 @@ foreach ($a as &$v) {
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Fatal error: main(): An iterator cannot be used with foreach by reference in %s on line %d
|
||||
Fatal error: main(): An iterator cannot be used with foreach by reference in %s on line %d%A
|
||||
|
||||
@@ -5,6 +5,7 @@ Wrapper cache exaustion test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$f = array();
|
||||
$f[] = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$f[] = dirname(__FILE__) . "/directories.rar";
|
||||
@@ -18,7 +19,9 @@ function printstats() {
|
||||
}
|
||||
|
||||
echo "* Invalid call to rar_wrapper_cache_stats():\n";
|
||||
var_dump(rar_wrapper_cache_stats("sfddf"));
|
||||
argerr(function() {
|
||||
rar_wrapper_cache_stats("sfddf");
|
||||
});
|
||||
|
||||
echo "\n* Initial stats:\n";
|
||||
printstats();
|
||||
@@ -75,7 +78,6 @@ echo "Done.\n";
|
||||
* Invalid call to rar_wrapper_cache_stats():
|
||||
|
||||
Warning: rar_wrapper_cache_stats() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
* Initial stats:
|
||||
Stats: 0/0 (hits/misses)
|
||||
|
||||
@@ -10,7 +10,9 @@ phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$phpinfo = preg_replace('/\r\n?/', "\n", $phpinfo); //normalize line endings
|
||||
//normalize line endings
|
||||
$phpinfo = str_replace("\r\n", "\n", $phpinfo);
|
||||
$phpinfo = str_replace("\r", "\n", $phpinfo);
|
||||
|
||||
$phpinfo = explode("\n", $phpinfo);
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@ foreach ($rar as $rar_file) {
|
||||
|
||||
echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
int(2279)
|
||||
int(1316)
|
||||
Warning: stream_get_contents(): The file size is supposed to be 2279 bytes, but we read more: 2288 bytes (corruption/wrong pwd) in %s on line %d
|
||||
int(2288)
|
||||
|
||||
Done.
|
||||
Warning: stream_get_contents(): The file size is supposed to be 1316 bytes, but we read more: 1328 bytes (corruption/wrong pwd) in %s on line %d
|
||||
int(1328)
|
||||
|
||||
Done.
|
||||
|
||||
@@ -32,6 +32,6 @@ opened
|
||||
|
||||
Testing 'r+'
|
||||
|
||||
Warning: fopen(%s): failed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
Warning: fopen(%s): %cailed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
|
||||
Done.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
Supports version 5 RAR files
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
if (isset($_ENV['APPVEYOR'])) die("skip failing on appveyor");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
@@ -38,7 +37,7 @@ object(RarEntry)#%d (%d) {
|
||||
["attr%sprivate%s=>
|
||||
int(33261)
|
||||
["version%sprivate%s=>
|
||||
int(200)
|
||||
int(50)
|
||||
["method%sprivate%s=>
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
|
||||
@@ -11,7 +11,7 @@ new RarArchive();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to private RarArchive::__construct() from invalid context in %s:%d
|
||||
Fatal error: Uncaught Error: Call to private RarArchive::__construct() from %s in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
|
||||
@@ -10,7 +10,7 @@ new RarEntry();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to private RarEntry::__construct() from invalid context in %s:%d
|
||||
Fatal error: Uncaught Error: Call to private RarEntry::__construct() from %s in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
--TEST--
|
||||
Clone of RarArchive is forbidden (PHP 5.x)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip";
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID >= 70000) die("skip for PHP 5.x");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
$file = dirname(__FILE__) . '/rar5_multi.part1.rar';
|
||||
$rar = RarArchive::open($file);
|
||||
$rar2 = clone $rar;
|
||||
$rar2->getEntries();
|
||||
echo "Never reached.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Trying to clone an uncloneable object of class RarArchive in %s on line %d
|
||||
@@ -10,5 +10,5 @@ $e = $a->getEntry('file1.txt');
|
||||
var_dump($e->getVersion());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
int(200)
|
||||
int(50)
|
||||
Done.
|
||||
|
||||
50
tests/114.phpt
Normal file
50
tests/114.phpt
Normal file
@@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
Bug 76592: solid files are partially extracted
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (PHP_OS != 'Linux') die('skip for linux');
|
||||
if (PHP_VERSION_ID < 50400) die("skip for PHP 5.4+");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$before = hex2bin('526172211a07010030f8db480d01050900080101c5808085800093f4589f2e02030b80808085800004808080858000b483020000000080380108746573742e6461740a031389bf735fa302a31c');
|
||||
$after = hex2bin('a6e7161b0e0306be0000be000080000102514fe6dcc40b3900b38080053393f4589f2e02030b80808085800004808080858000b483020000000080380108746573742e6461740a031389bf735fa302a31c1d77565103050400');
|
||||
|
||||
$middle = file_get_contents('/dev/urandom', false, null, 0, 10 * 1024 * 1024) or die('failed file_get_contents');
|
||||
$crc32hexbe = crc32($middle);
|
||||
$crc32le = pack('V', $crc32hexbe);
|
||||
|
||||
$before = substr($before, 0, 50) . $crc32le . substr($before, 54);
|
||||
$after = substr($after, 0, 56) . $crc32le . substr($after, 60);
|
||||
|
||||
$data = $before . $middle . $after;
|
||||
$file = tempnam('/tmp', 'rar');
|
||||
file_put_contents($file, $data) or die('failed file_put contents');
|
||||
|
||||
$rar = \RarArchive::open($file) or die('Unable to open archive');
|
||||
$rar->setAllowBroken(true); // we don't fixup the headers checksum, only the contents. Ignore the error
|
||||
$entry = $rar->getEntry('test.dat') or die('Unable to get entry');
|
||||
|
||||
$contents = stream_get_contents($entry->getStream(), $entry->getUnpackedSize());
|
||||
$crc32_rar = $entry->getCrc();
|
||||
$crc32_cont = dechex(crc32($contents));
|
||||
$crc32_orig_content = dechex(crc32($contents));
|
||||
|
||||
unlink($file);
|
||||
|
||||
echo 'orig content size: ', strlen($middle), "\n";
|
||||
echo 'read content size: ', strlen($contents), "\n";
|
||||
|
||||
if ($crc32_rar !== $crc32_cont) {
|
||||
die("CRC values do not match");
|
||||
}
|
||||
if ($crc32_rar !== $crc32_orig_content) {
|
||||
die("CRC values do not match (2)");
|
||||
}
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
orig content size: 10485760
|
||||
read content size: 10485760
|
||||
==DONE==
|
||||
25
tests/115.phpt
Normal file
25
tests/115.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
getIterator() (PHP 8+)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (PHP_VERSION_ID < 80000) print "skip for PHP 8";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$it = $a->getIterator();
|
||||
var_dump($it);
|
||||
foreach ($it as $e) {
|
||||
echo $e->getName(), "\n";
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
object(InternalIterator)#3 (0) {
|
||||
}
|
||||
plain.txt
|
||||
test file with whitespaces.txt
|
||||
Done
|
||||
17
tests/php8compat.php.inc
Normal file
17
tests/php8compat.php.inc
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
ini_set('pcre.jit', '0'); // avoid some valgrind errors
|
||||
|
||||
function argerr($cl) {
|
||||
try {
|
||||
return $cl();
|
||||
} catch (TypeError $err) {
|
||||
$msg = $err->getMessage();
|
||||
$msg = "Warning: $msg in {$err->getFile()} on line {$err->getLine()}";
|
||||
$msg = preg_replace('/: Argument #(\d) \(\$\S+\) must be of type/',
|
||||
' expects parameter \1 to be', $msg);
|
||||
$msg = preg_replace('/expects (.+) (\d) argument/',
|
||||
'expects \1 \2 parameter', $msg);
|
||||
echo "\n", $msg, "\n";
|
||||
}
|
||||
}
|
||||
86
travis.sh
86
travis.sh
@@ -1,86 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
BUILDS_DIR=$HOME/php_builds
|
||||
MIRROR=${MIRROR:-http://us1.php.net/distributions}
|
||||
JOBS=3
|
||||
|
||||
function prefix {
|
||||
local readonly version=$1 zts=$2
|
||||
local zts_suffix=''
|
||||
if [[ $zts = 'yes' ]]; then
|
||||
zts_suffix='-zts'
|
||||
fi
|
||||
|
||||
echo "$BUILDS_DIR/${version}$zts_suffix"
|
||||
}
|
||||
|
||||
function install_php {
|
||||
local readonly version=$1 zts=$2
|
||||
local readonly url="$MIRROR/php-$version.tar.gz" \
|
||||
extract_dir="/tmp/php-$version" prefix=$(prefix $version $zts)
|
||||
local extra_flags=''
|
||||
|
||||
mkdir -p "$extract_dir"
|
||||
wget -O - "$url" | tar -C "$extract_dir" --strip-components=1 -xzf -
|
||||
|
||||
pushd "$extract_dir"
|
||||
if [[ $zts = 'yes' ]]; then
|
||||
extra_flags="$extra_flags --enable-maintainer-zts"
|
||||
fi
|
||||
./configure --prefix="$prefix" --disable-all --enable-cli \
|
||||
$extra_flags
|
||||
make -j $JOBS install
|
||||
popd
|
||||
}
|
||||
|
||||
function build_ext {
|
||||
local readonly prefix=$1 coverage=$2
|
||||
"$prefix"/bin/phpize
|
||||
if [[ $coverage = 'yes' ]]; then
|
||||
export CPPFLAGS="$CPPFLAGS --coverage"
|
||||
fi
|
||||
./configure --with-php-config="$prefix/bin/php-config"
|
||||
make -j $JOBS
|
||||
}
|
||||
|
||||
function do_tests {
|
||||
local readonly prefix=$1
|
||||
local found_leaks= dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
echo "--suppressions=$dir/valgrind.supp" | tee ~/.valgrindrc
|
||||
TEST_PHP_EXECUTABLE="$prefix/bin/php" REPORT_EXIT_STATUS=1 \
|
||||
"$prefix/bin/php" "$prefix"/lib/php/build/run-tests.php \
|
||||
-q -d extension=modules/rar.so --set-timeout 300 --show-diff \
|
||||
$RUN_TESTS_FLAGS tests
|
||||
found_leaks=$(find tests -name '*.mem' | wc -l)
|
||||
if [[ $found_leaks -gt 0 ]]; then
|
||||
echo "Found $found_leaks leaks. Failing."
|
||||
find tests -name "*.mem" -print -exec cat {} \;
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# public functions below
|
||||
|
||||
function maybe_install_php {
|
||||
set -e
|
||||
set -o pipefail
|
||||
local readonly version=$1 zts=$2
|
||||
local readonly prefix=$(prefix $version $zts)
|
||||
if [[ ! -d $prefix ]]; then
|
||||
install_php $version $zts
|
||||
fi
|
||||
}
|
||||
|
||||
function build {
|
||||
set -e
|
||||
set -o pipefail
|
||||
if [[ ! -f modules/rar.so ]]; then
|
||||
build_ext "$(prefix $1 $2)" "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
function run_tests {
|
||||
set -e
|
||||
set -o pipefail
|
||||
do_tests "$(prefix $1 $2)"
|
||||
}
|
||||
3
unrar/.clang-format
Normal file
3
unrar/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# Disable clang-format for vendored unrar sources.
|
||||
DisableFormat: true
|
||||
@@ -238,8 +238,10 @@
|
||||
<ClCompile Include="hash.cpp" />
|
||||
<ClCompile Include="headers.cpp" />
|
||||
<ClCompile Include="isnt.cpp" />
|
||||
<ClCompile Include="largepage.cpp" />
|
||||
<ClCompile Include="list.cpp" />
|
||||
<ClCompile Include="match.cpp" />
|
||||
<ClCompile Include="motw.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="pathfn.cpp" />
|
||||
<ClCompile Include="qopen.cpp" />
|
||||
|
||||
@@ -1,876 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="UnRAR"
|
||||
ProjectGUID="{E815C46C-36C4-499F-BBC2-E772C6B17971}"
|
||||
RootNamespace="UnRAR"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
StructMemberAlignment="3"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
StructMemberAlignment="3"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="3"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/SAFESEH"
|
||||
OutputFile="$(OutDir)\unrar.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="3"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release_nocrypt|Win32"
|
||||
OutputDirectory="build\unrardll32\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll32\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT;RAR_NOCRYPT"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="3"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
FloatingPointModel="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="0"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/SAFESEH"
|
||||
OutputFile="$(OutDir)\unrar_nocrypt.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll_nocrypt.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="release_nocrypt|x64"
|
||||
OutputDirectory="build\unrardll64\$(ConfigurationName)"
|
||||
IntermediateDirectory="build\unrardll64\$(ConfigurationName)\obj"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="0"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="RARDLL;UNRAR;SILENT;RAR_NOCRYPT"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="3"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="rar.hpp"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CallingConvention="2"
|
||||
DisableSpecificWarnings="4007;4996"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\unrar64_nocrypt.dll"
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="true"
|
||||
ModuleDefinitionFile="dll_nocrypt.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="archive.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="arcread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="blake2s.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="cmddata.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="consio.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="crypt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="dll.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="encname.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="errhnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="extract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filcreat.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="file.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="filestr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="find.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="getbits.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="global.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="hash.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="headers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="isnt.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="match.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="options.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="pathfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="qopen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarpch.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="release_nocrypt|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rarvm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rawread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rdwrfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rijndael.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rs.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rs16.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="scantree.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="secpassword.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sha1.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sha256.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="smallfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strfn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="strlist.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="system.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="threadpool.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="timefn.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="ui.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unicode.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="unpack.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="volume.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="rar.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath="dll.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -138,7 +138,7 @@
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
@@ -168,7 +168,7 @@
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
@@ -198,7 +198,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
@@ -239,7 +239,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@@ -274,7 +274,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
@@ -315,7 +315,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@@ -374,7 +374,9 @@
|
||||
<ClCompile Include="hash.cpp" />
|
||||
<ClCompile Include="headers.cpp" />
|
||||
<ClCompile Include="isnt.cpp" />
|
||||
<ClCompile Include="largepage.cpp" />
|
||||
<ClCompile Include="match.cpp" />
|
||||
<ClCompile Include="motw.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="pathfn.cpp" />
|
||||
<ClCompile Include="qopen.cpp" />
|
||||
|
||||
@@ -7,51 +7,18 @@
|
||||
for samples and ideas allowed to make Reed-Solomon coding
|
||||
more efficient.
|
||||
|
||||
* RAR text compression algorithm is based on Dmitry Shkarin PPMII
|
||||
* RAR4 text compression algorithm is based on Dmitry Shkarin PPMII
|
||||
and Dmitry Subbotin carryless rangecoder public domain source code.
|
||||
You may find it in ftp.elf.stuba.sk/pub/pc/pack.
|
||||
You can find it in ftp.elf.stuba.sk/pub/pc/pack.
|
||||
|
||||
* RAR encryption includes parts of code from Szymon Stefanek
|
||||
and Brian Gladman AES implementations also as Steve Reid SHA-1 source.
|
||||
* RAR encryption includes parts of public domain code
|
||||
from Szymon Stefanek AES and Steve Reid SHA-1 implementations.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK.
|
||||
All rights reserved.
|
||||
* With exception of SFX modules, RAR uses CRC32 function based
|
||||
on Intel Slicing-by-8 algorithm. Original Intel Slicing-by-8 code
|
||||
is available here:
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Source code of this package also as other cryptographic technology
|
||||
and computing project related links are available on Brian Gladman's
|
||||
web site: http://www.gladman.me.uk
|
||||
|
||||
* RAR uses CRC32 function based on Intel Slicing-by-8 algorithm.
|
||||
Original Intel Slicing-by-8 code is available here:
|
||||
|
||||
http://sourceforge.net/projects/slicing-by-8/
|
||||
https://sourceforge.net/projects/slicing-by-8/
|
||||
|
||||
Original Intel Slicing-by-8 code is licensed under BSD License
|
||||
available at http://www.opensource.org/licenses/bsd-license.html
|
||||
|
||||
111
unrar/arccmt.cpp
111
unrar/arccmt.cpp
@@ -1,13 +1,20 @@
|
||||
static bool IsAnsiEscComment(const wchar *Data,size_t Size);
|
||||
|
||||
bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
bool Archive::GetComment(std::wstring &CmtData)
|
||||
{
|
||||
if (!MainComment)
|
||||
return false;
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 SavePos=Tell();
|
||||
bool Success=DoGetComment(CmtData);
|
||||
Seek(SavePos,SEEK_SET);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
bool Archive::DoGetComment(std::wstring &CmtData)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
ushort CmtLength;
|
||||
uint CmtLength;
|
||||
if (Format==RARFMT14)
|
||||
{
|
||||
Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
|
||||
@@ -22,18 +29,24 @@ bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
// Old style (RAR 2.9) archive comment embedded into the main
|
||||
// archive header.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
|
||||
ReadHeader();
|
||||
if (!ReadHeader() || GetHeaderType()!=HEAD3_CMT)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current (RAR 3.0+) version of archive comment.
|
||||
Seek(GetStartPos(),SEEK_SET);
|
||||
return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
|
||||
if (SearchSubBlock(SUBHEAD_TYPE_CMT)!=0)
|
||||
if (ReadCommentData(CmtData))
|
||||
return true;
|
||||
else
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
}
|
||||
#ifndef SFX_MODULE
|
||||
// Old style (RAR 2.9) comment header embedded into the main
|
||||
// archive header.
|
||||
if (BrokenHeader)
|
||||
if (BrokenHeader || CommHead.HeadSize<SIZEOF_COMMHEAD)
|
||||
{
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
@@ -52,10 +65,12 @@ bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
if (Format==RARFMT14)
|
||||
{
|
||||
#ifdef RAR_NOCRYPT
|
||||
return(false);
|
||||
return false;
|
||||
#else
|
||||
UnpCmtLength=GetByte();
|
||||
UnpCmtLength+=(GetByte()<<8);
|
||||
if (CmtLength<2)
|
||||
return false;
|
||||
CmtLength-=2;
|
||||
DataIO.SetCmt13Encryption();
|
||||
CommHead.UnpVer=15;
|
||||
@@ -67,6 +82,7 @@ bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetPackedSizeToRead(CmtLength);
|
||||
DataIO.UnpHash.Init(HASH_CRC32,1);
|
||||
DataIO.SetNoFileHeader(true); // this->FileHead is not filled yet.
|
||||
|
||||
Unpack CmtUnpack(&DataIO);
|
||||
CmtUnpack.Init(0x10000,false);
|
||||
@@ -83,64 +99,70 @@ bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
byte *UnpData;
|
||||
size_t UnpDataSize;
|
||||
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
|
||||
if (UnpDataSize>0)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// If we ever decide to extend it to Android, we'll need to alloc
|
||||
// 4x memory for OEM to UTF-8 output here.
|
||||
OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
|
||||
#endif
|
||||
CmtData->Alloc(UnpDataSize+1);
|
||||
memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
|
||||
CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
std::string UnpStr((char*)UnpData,UnpDataSize);
|
||||
CharToWide(UnpStr,CmtData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<byte> CmtRaw(CmtLength);
|
||||
Read(&CmtRaw[0],CmtLength);
|
||||
|
||||
if (CmtLength==0)
|
||||
return false;
|
||||
std::vector<byte> CmtRaw(CmtLength);
|
||||
int ReadSize=Read(CmtRaw.data(),CmtLength);
|
||||
if (ReadSize>=0 && (uint)ReadSize<CmtLength) // Comment is shorter than declared.
|
||||
{
|
||||
CmtLength=ReadSize;
|
||||
CmtRaw.resize(CmtLength);
|
||||
}
|
||||
|
||||
if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
|
||||
{
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
}
|
||||
CmtData->Alloc(CmtLength+1);
|
||||
CmtRaw.Push(0);
|
||||
// CmtData.resize(CmtLength+1);
|
||||
CmtRaw.push_back(0);
|
||||
#ifdef _WIN_ALL
|
||||
// If we ever decide to extend it to Android, we'll need to alloc
|
||||
// 4x memory for OEM to UTF-8 output here.
|
||||
OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
|
||||
OemToCharA((char *)CmtRaw.data(),(char *)CmtRaw.data());
|
||||
#endif
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtLength);
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
}
|
||||
CharToWide((const char *)CmtRaw.data(),CmtData);
|
||||
// CmtData->resize(wcslen(CmtData->data()));
|
||||
}
|
||||
#endif
|
||||
return CmtData->Size() > 0;
|
||||
return CmtData.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
bool Archive::ReadCommentData(Array<wchar> *CmtData)
|
||||
bool Archive::ReadCommentData(std::wstring &CmtData)
|
||||
{
|
||||
Array<byte> CmtRaw;
|
||||
if (!ReadSubData(&CmtRaw,NULL))
|
||||
std::vector<byte> CmtRaw;
|
||||
if (!ReadSubData(&CmtRaw,NULL,false))
|
||||
return false;
|
||||
size_t CmtSize=CmtRaw.Size();
|
||||
CmtRaw.Push(0);
|
||||
CmtData->Alloc(CmtSize+1);
|
||||
size_t CmtSize=CmtRaw.size();
|
||||
CmtRaw.push_back(0);
|
||||
// CmtData->resize(CmtSize+1);
|
||||
if (Format==RARFMT50)
|
||||
UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
UtfToWide((char *)CmtRaw.data(),CmtData);
|
||||
else
|
||||
if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0)
|
||||
{
|
||||
RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2);
|
||||
(*CmtData)[CmtSize/2]=0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
CmtData=RawToWide(CmtRaw);
|
||||
}
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0))); // Set buffer size to actual comment length.
|
||||
else
|
||||
{
|
||||
CharToWide((const char *)CmtRaw.data(),CmtData);
|
||||
}
|
||||
// CmtData->resize(wcslen(CmtData->data())); // Set buffer size to actual comment length.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -149,15 +171,16 @@ void Archive::ViewComment()
|
||||
{
|
||||
if (Cmd->DisableComment)
|
||||
return;
|
||||
Array<wchar> CmtBuf;
|
||||
if (GetComment(&CmtBuf)) // In GUI too, so "Test" command detects broken comments.
|
||||
std::wstring CmtBuf;
|
||||
if (GetComment(CmtBuf)) // In GUI too, so "Test" command detects broken comments.
|
||||
{
|
||||
size_t CmtSize=CmtBuf.Size();
|
||||
wchar *ChPtr=wcschr(&CmtBuf[0],0x1A);
|
||||
if (ChPtr!=NULL)
|
||||
CmtSize=ChPtr-&CmtBuf[0];
|
||||
mprintf(L"\n");
|
||||
OutComment(&CmtBuf[0],CmtSize);
|
||||
size_t CmtSize=CmtBuf.size();
|
||||
auto EndPos=CmtBuf.find(0x1A);
|
||||
if (EndPos!=std::wstring::npos)
|
||||
CmtSize=EndPos;
|
||||
mprintf(St(MArcComment));
|
||||
mprintf(L":\n");
|
||||
OutComment(CmtBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
#include "arccmt.cpp"
|
||||
|
||||
|
||||
Archive::Archive(RAROptions *InitCmd)
|
||||
Archive::Archive(CommandData *InitCmd)
|
||||
{
|
||||
Cmd=NULL; // Just in case we'll have an exception in 'new' below.
|
||||
|
||||
DummyCmd=(InitCmd==NULL);
|
||||
Cmd=DummyCmd ? (new RAROptions):InitCmd;
|
||||
Cmd=DummyCmd ? (new CommandData):InitCmd;
|
||||
|
||||
OpenShared=Cmd->OpenShared;
|
||||
Format=RARFMT15;
|
||||
Format=RARFMT_NONE;
|
||||
Solid=false;
|
||||
Volume=false;
|
||||
MainComment=false;
|
||||
@@ -26,28 +26,31 @@ Archive::Archive(RAROptions *InitCmd)
|
||||
FailedHeaderDecryption=false;
|
||||
BrokenHeader=false;
|
||||
LastReadBlock=0;
|
||||
CurHeaderType=HEAD_UNKNOWN;
|
||||
|
||||
CurBlockPos=0;
|
||||
NextBlockPos=0;
|
||||
|
||||
RecoverySize=-1;
|
||||
RecoveryPercent=-1;
|
||||
|
||||
memset(&MainHead,0,sizeof(MainHead));
|
||||
memset(&CryptHead,0,sizeof(CryptHead));
|
||||
memset(&EndArcHead,0,sizeof(EndArcHead));
|
||||
MainHead.Reset();
|
||||
CryptHead={};
|
||||
EndArcHead.Reset();
|
||||
|
||||
VolNumber=0;
|
||||
VolWrite=0;
|
||||
AddingFilesSize=0;
|
||||
AddingHeadersSize=0;
|
||||
*FirstVolumeName=0;
|
||||
|
||||
Splitting=false;
|
||||
NewArchive=false;
|
||||
|
||||
SilentOpen=false;
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
ProhibitQOpen=false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -66,13 +69,13 @@ void Archive::CheckArc(bool EnableBroken)
|
||||
// password is incorrect.
|
||||
if (!FailedHeaderDecryption)
|
||||
uiMsg(UIERROR_BADARCHIVE,FileName);
|
||||
ErrHandler.Exit(RARX_FATAL);
|
||||
ErrHandler.Exit(RARX_BADARC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE)
|
||||
void Archive::CheckOpen(const wchar *Name)
|
||||
void Archive::CheckOpen(const std::wstring &Name)
|
||||
{
|
||||
TOpen(Name);
|
||||
CheckArc(false);
|
||||
@@ -80,7 +83,7 @@ void Archive::CheckOpen(const wchar *Name)
|
||||
#endif
|
||||
|
||||
|
||||
bool Archive::WCheckOpen(const wchar *Name)
|
||||
bool Archive::WCheckOpen(const std::wstring &Name)
|
||||
{
|
||||
if (!WOpen(Name))
|
||||
return false;
|
||||
@@ -108,13 +111,15 @@ RARFORMAT Archive::IsSignature(const byte *D,size_t Size)
|
||||
// We check the last signature byte, so we can return a sensible
|
||||
// warning in case we'll want to change the archive format
|
||||
// sometimes in the future.
|
||||
#ifndef SFX_MODULE
|
||||
if (D[6]==0)
|
||||
Type=RARFMT15;
|
||||
else
|
||||
#endif
|
||||
if (D[6]==1)
|
||||
Type=RARFMT50;
|
||||
else
|
||||
if (D[6]==2)
|
||||
if (D[6]>1 && D[6]<5)
|
||||
Type=RARFMT_FUTURE;
|
||||
}
|
||||
return Type;
|
||||
@@ -146,9 +151,9 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<char> Buffer(MAXSFXSIZE);
|
||||
std::vector<char> Buffer(MAXSFXSIZE);
|
||||
long CurPos=(long)Tell();
|
||||
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
|
||||
int ReadSize=Read(Buffer.data(),Buffer.size()-16);
|
||||
for (int I=0;I<ReadSize;I++)
|
||||
if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
|
||||
{
|
||||
@@ -175,8 +180,7 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
}
|
||||
if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
|
||||
{
|
||||
Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
|
||||
if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
|
||||
if (Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1)!=1 || MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
|
||||
return false;
|
||||
MarkHead.HeadSize=SIZEOF_MARKHEAD5;
|
||||
}
|
||||
@@ -192,27 +196,31 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
SilentOpen=true;
|
||||
#endif
|
||||
|
||||
bool HeadersLeft; // Any headers left to read.
|
||||
bool StartFound=false; // Main or encryption headers found.
|
||||
// Skip the archive encryption header if any and read the main header.
|
||||
while (ReadHeader()!=0)
|
||||
while ((HeadersLeft=(ReadHeader()!=0))==true) // Additional parentheses to silence Clang.
|
||||
{
|
||||
SeekToNext();
|
||||
|
||||
HEADER_TYPE Type=GetHeaderType();
|
||||
// In RAR 5.0 we need to quit after reading HEAD_CRYPT if we wish to
|
||||
// avoid the password prompt.
|
||||
if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT)
|
||||
StartFound=Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT;
|
||||
if (StartFound)
|
||||
break;
|
||||
SeekToNext();
|
||||
}
|
||||
|
||||
// This check allows to make RS based recovery even if password is incorrect.
|
||||
// But we should not do it for EnableBroken or we'll get 'not RAR archive'
|
||||
|
||||
// We should not do it for EnableBroken or we'll get 'not RAR archive'
|
||||
// messages when extracting encrypted archives with wrong password.
|
||||
if (FailedHeaderDecryption && !EnableBroken)
|
||||
return false;
|
||||
|
||||
SeekToNext();
|
||||
if (BrokenHeader) // Main archive header is corrupt.
|
||||
if (BrokenHeader || !StartFound) // Main archive header is corrupt or missing.
|
||||
{
|
||||
uiMsg(UIERROR_MHEADERBROKEN,FileName);
|
||||
if (!FailedHeaderDecryption) // If not reported a wrong password already.
|
||||
uiMsg(UIERROR_MHEADERBROKEN,FileName);
|
||||
if (!EnableBroken)
|
||||
return false;
|
||||
}
|
||||
@@ -226,9 +234,9 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
// first file header to set "comment" flag when reading service header.
|
||||
// Unless we are in silent mode, we need to know about presence of comment
|
||||
// immediately after IsArchive call.
|
||||
if (!SilentOpen || !Encrypted)
|
||||
if (HeadersLeft && (!SilentOpen || !Encrypted) && IsSeekable())
|
||||
{
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 SavePos=Tell();
|
||||
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||
HEADER_TYPE SaveCurHeaderType=CurHeaderType;
|
||||
|
||||
@@ -257,9 +265,10 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
CurHeaderType=SaveCurHeaderType;
|
||||
Seek(SavePos,SEEK_SET);
|
||||
}
|
||||
if (!Volume || FirstVolume)
|
||||
wcscpy(FirstVolumeName,FileName);
|
||||
FirstVolumeName=FileName;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -295,7 +304,7 @@ uint Archive::FullHeaderSize(size_t Size)
|
||||
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
bool Archive::Open(const wchar *Name,uint Mode)
|
||||
bool Archive::Open(const std::wstring &Name,uint Mode)
|
||||
{
|
||||
// Important if we reuse Archive object and it has virtual QOpen
|
||||
// file position not matching real. For example, for 'l -v volname'.
|
||||
@@ -330,3 +339,23 @@ int64 Archive::Tell()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Return 0 if dictionary size is invalid. If size is RAR7 only, return
|
||||
// the adjusted nearest bottom value. Return header flags in Flags.
|
||||
uint64 Archive::GetWinSize(uint64 Size,uint &Flags)
|
||||
{
|
||||
Flags=0;
|
||||
// Allow 128 KB - 1 TB range.
|
||||
if (Size<0x20000 || Size>0x10000000000ULL)
|
||||
return 0;
|
||||
uint64 Pow2=0x20000; // Power of 2 dictionary size.
|
||||
for (;2*Pow2<=Size;Pow2*=2)
|
||||
Flags+=FCI_DICT_BIT0;
|
||||
if (Size==Pow2)
|
||||
return Size; // If 'Size' is the power of 2, return it as is.
|
||||
|
||||
// Get the number of Pow2/32 to add to Pow2 for nearest value not exceeding 'Size'.
|
||||
uint64 Fraction=(Size-Pow2)/(Pow2/32);
|
||||
Flags+=(uint)Fraction*FCI_DICT_FRACT0;
|
||||
return Pow2+Fraction*(Pow2/32);
|
||||
}
|
||||
|
||||
@@ -20,32 +20,33 @@ enum ADDSUBDATA_FLAGS
|
||||
ASDF_CRYPTIFHEADERS = 8 // Encrypt data after subheader only in -hp mode.
|
||||
};
|
||||
|
||||
// RAR5 headers must not exceed 2 MB.
|
||||
#define MAX_HEADER_SIZE_RAR5 0x200000
|
||||
|
||||
class Archive:public File
|
||||
{
|
||||
private:
|
||||
void UpdateLatestTime(FileHeader *CurBlock);
|
||||
void ConvertNameCase(wchar *Name);
|
||||
void ConvertNameCase(std::wstring &Name);
|
||||
void ConvertFileHeader(FileHeader *hd);
|
||||
void WriteBlock50(HEADER_TYPE HeaderType,BaseBlock *wb,bool OnlySetSize,bool NonFinalWrite);
|
||||
size_t ReadHeader14();
|
||||
size_t ReadHeader15();
|
||||
size_t ReadHeader50();
|
||||
void ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb);
|
||||
void RequestArcPassword();
|
||||
void ProcessExtra50(RawRead *Raw,size_t ExtraSize,const BaseBlock *bb);
|
||||
void RequestArcPassword(RarCheckPassword *SelPwd);
|
||||
void UnexpEndArcMsg();
|
||||
void BrokenHeaderMsg();
|
||||
void UnkEncVerMsg(const wchar *Name);
|
||||
void UnkEncVerMsg();
|
||||
bool ReadCommentData(Array<wchar> *CmtData);
|
||||
void UnkEncVerMsg(const std::wstring &Name,const std::wstring &Info);
|
||||
bool DoGetComment(std::wstring &CmtData);
|
||||
bool ReadCommentData(std::wstring &CmtData);
|
||||
|
||||
#if !defined(RAR_NOCRYPT)
|
||||
CryptData HeadersCrypt;
|
||||
#endif
|
||||
ComprDataIO SubDataIO;
|
||||
bool DummyCmd;
|
||||
RAROptions *Cmd;
|
||||
CommandData *Cmd;
|
||||
|
||||
int64 RecoverySize;
|
||||
int RecoveryPercent;
|
||||
|
||||
RarTime LatestTime;
|
||||
@@ -55,22 +56,22 @@ class Archive:public File
|
||||
bool SilentOpen;
|
||||
#ifdef USE_QOPEN
|
||||
QuickOpen QOpen;
|
||||
bool ProhibitQOpen;
|
||||
#endif
|
||||
public:
|
||||
Archive(RAROptions *InitCmd=NULL);
|
||||
Archive(CommandData *InitCmd=nullptr);
|
||||
~Archive();
|
||||
static RARFORMAT IsSignature(const byte *D,size_t Size);
|
||||
bool IsArchive(bool EnableBroken);
|
||||
size_t SearchBlock(HEADER_TYPE HeaderType);
|
||||
size_t SearchSubBlock(const wchar *Type);
|
||||
size_t SearchRR();
|
||||
void WriteBlock(HEADER_TYPE HeaderType,BaseBlock *wb=NULL,bool OnlySetSize=false,bool NonFinalWrite=false);
|
||||
void SetBlockSize(HEADER_TYPE HeaderType,BaseBlock *wb=NULL) {WriteBlock(HeaderType,wb,true);}
|
||||
int GetRecoveryPercent() {return RecoveryPercent;}
|
||||
size_t ReadHeader();
|
||||
void CheckArc(bool EnableBroken);
|
||||
void CheckOpen(const wchar *Name);
|
||||
bool WCheckOpen(const wchar *Name);
|
||||
bool GetComment(Array<wchar> *CmtData);
|
||||
void CheckOpen(const std::wstring &Name);
|
||||
bool WCheckOpen(const std::wstring &Name);
|
||||
bool GetComment(std::wstring &CmtData);
|
||||
void ViewComment();
|
||||
void SetLatestTime(RarTime *NewTime);
|
||||
void SeekToNext();
|
||||
@@ -80,22 +81,25 @@ class Archive:public File
|
||||
void VolSubtractHeaderSize(size_t SubSize);
|
||||
uint FullHeaderSize(size_t Size);
|
||||
int64 GetStartPos();
|
||||
void AddSubData(byte *SrcData,uint64 DataSize,File *SrcFile,
|
||||
void AddSubData(const byte *SrcData,uint64 DataSize,File *SrcFile,
|
||||
const wchar *Name,uint Flags);
|
||||
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
|
||||
HEADER_TYPE GetHeaderType() {return CurHeaderType;};
|
||||
RAROptions* GetRAROptions() {return Cmd;}
|
||||
bool ReadSubData(std::vector<byte> *UnpData,File *DestFile,bool TestMode);
|
||||
HEADER_TYPE GetHeaderType() {return CurHeaderType;}
|
||||
CommandData* GetCommandData() {return Cmd;}
|
||||
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
|
||||
#if 0
|
||||
void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
|
||||
#endif
|
||||
#ifdef USE_QOPEN
|
||||
bool Open(const wchar *Name,uint Mode=FMF_READ);
|
||||
int Read(void *Data,size_t Size);
|
||||
void Seek(int64 Offset,int Method);
|
||||
int64 Tell();
|
||||
bool Open(const std::wstring &Name,uint Mode=FMF_READ) override;
|
||||
int Read(void *Data,size_t Size) override;
|
||||
void Seek(int64 Offset,int Method) override;
|
||||
int64 Tell() override;
|
||||
void QOpenUnload() {QOpen.Unload();}
|
||||
void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;}
|
||||
#endif
|
||||
static uint64 GetWinSize(uint64 Size,uint &Flags);
|
||||
|
||||
// Needed to see wstring based Open from File. Otherwise compiler finds
|
||||
// Open in Archive and doesn't check the base class overloads.
|
||||
using File::Open;
|
||||
|
||||
BaseBlock ShortBlock;
|
||||
MarkHeader MarkHead;
|
||||
@@ -107,10 +111,6 @@ class Archive:public File
|
||||
FileHeader SubHead;
|
||||
CommentHeader CommHead;
|
||||
ProtectHeader ProtectHead;
|
||||
AVHeader AVHead;
|
||||
SignHeader SignHead;
|
||||
UnixOwnersHeader UOHead;
|
||||
MacFInfoHeader MACHead;
|
||||
EAHeader EAHead;
|
||||
StreamHeader StreamHead;
|
||||
|
||||
@@ -139,12 +139,19 @@ class Archive:public File
|
||||
|
||||
uint VolNumber;
|
||||
int64 VolWrite;
|
||||
|
||||
// Total size of files adding to archive. Might also include the size of
|
||||
// files repacked in solid archive.
|
||||
uint64 AddingFilesSize;
|
||||
|
||||
uint64 AddingHeadersSize;
|
||||
|
||||
bool NewArchive;
|
||||
|
||||
wchar FirstVolumeName[NM];
|
||||
std::wstring FirstVolumeName;
|
||||
#ifdef PROPAGATE_MOTW
|
||||
MarkOfTheWeb Motw;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
191
unrar/array.hpp
191
unrar/array.hpp
@@ -1,191 +0,0 @@
|
||||
#ifndef _RAR_ARRAY_
|
||||
#define _RAR_ARRAY_
|
||||
|
||||
extern ErrorHandler ErrHandler;
|
||||
|
||||
template <class T> class Array
|
||||
{
|
||||
private:
|
||||
T *Buffer;
|
||||
size_t BufSize;
|
||||
size_t AllocSize;
|
||||
size_t MaxSize;
|
||||
bool Secure; // Clean memory if true.
|
||||
public:
|
||||
Array();
|
||||
Array(size_t Size);
|
||||
Array(const Array &Src); // Copy constructor.
|
||||
~Array();
|
||||
inline void CleanData();
|
||||
inline T& operator [](size_t Item) const;
|
||||
inline T* operator + (size_t Pos);
|
||||
inline size_t Size(); // Returns the size in items, not in bytes.
|
||||
void Add(size_t Items);
|
||||
void Alloc(size_t Items);
|
||||
void Reset();
|
||||
void SoftReset();
|
||||
void operator = (Array<T> &Src);
|
||||
void Push(T Item);
|
||||
void Append(T *Item,size_t Count);
|
||||
T* Addr(size_t Item) {return Buffer+Item;}
|
||||
void SetMaxSize(size_t Size) {MaxSize=Size;}
|
||||
T* Begin() {return Buffer;}
|
||||
T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
|
||||
void SetSecure() {Secure=true;}
|
||||
};
|
||||
|
||||
|
||||
template <class T> void Array<T>::CleanData()
|
||||
{
|
||||
Buffer=NULL;
|
||||
BufSize=0;
|
||||
AllocSize=0;
|
||||
MaxSize=0;
|
||||
Secure=false;
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::Array()
|
||||
{
|
||||
CleanData();
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::Array(size_t Size)
|
||||
{
|
||||
CleanData();
|
||||
Add(Size);
|
||||
}
|
||||
|
||||
|
||||
// Copy constructor in case we need to pass an object as value.
|
||||
template <class T> Array<T>::Array(const Array &Src)
|
||||
{
|
||||
CleanData();
|
||||
Alloc(Src.BufSize);
|
||||
if (Src.BufSize!=0)
|
||||
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::~Array()
|
||||
{
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
if (Secure)
|
||||
cleandata(Buffer,AllocSize*sizeof(T));
|
||||
free(Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T& Array<T>::operator [](size_t Item) const
|
||||
{
|
||||
return Buffer[Item];
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T* Array<T>::operator +(size_t Pos)
|
||||
{
|
||||
return Buffer+Pos;
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline size_t Array<T>::Size()
|
||||
{
|
||||
return BufSize;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Add(size_t Items)
|
||||
{
|
||||
BufSize+=Items;
|
||||
if (BufSize>AllocSize)
|
||||
{
|
||||
if (MaxSize!=0 && BufSize>MaxSize)
|
||||
{
|
||||
ErrHandler.GeneralErrMsg(L"Maximum allowed array size (%u) is exceeded",MaxSize);
|
||||
ErrHandler.MemoryError();
|
||||
}
|
||||
|
||||
size_t Suggested=AllocSize+AllocSize/4+32;
|
||||
size_t NewSize=Max(BufSize,Suggested);
|
||||
|
||||
T *NewBuffer;
|
||||
if (Secure)
|
||||
{
|
||||
NewBuffer=(T *)malloc(NewSize*sizeof(T));
|
||||
if (NewBuffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
memcpy(NewBuffer,Buffer,AllocSize*sizeof(T));
|
||||
cleandata(Buffer,AllocSize*sizeof(T));
|
||||
free(Buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
|
||||
if (NewBuffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
}
|
||||
Buffer=NewBuffer;
|
||||
AllocSize=NewSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Alloc(size_t Items)
|
||||
{
|
||||
if (Items>AllocSize)
|
||||
Add(Items-BufSize);
|
||||
else
|
||||
BufSize=Items;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Reset()
|
||||
{
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
free(Buffer);
|
||||
Buffer=NULL;
|
||||
}
|
||||
BufSize=0;
|
||||
AllocSize=0;
|
||||
}
|
||||
|
||||
|
||||
// Reset buffer size, but preserve already allocated memory if any,
|
||||
// so we can reuse it without wasting time to allocation.
|
||||
template <class T> void Array<T>::SoftReset()
|
||||
{
|
||||
BufSize=0;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::operator =(Array<T> &Src)
|
||||
{
|
||||
Reset();
|
||||
Alloc(Src.BufSize);
|
||||
if (Src.BufSize!=0)
|
||||
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Push(T Item)
|
||||
{
|
||||
Add(1);
|
||||
(*this)[Size()-1]=Item;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Append(T *Items,size_t Count)
|
||||
{
|
||||
size_t CurSize=Size();
|
||||
Add(Count);
|
||||
memcpy(Buffer+CurSize,Items,Count*sizeof(T));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
static const byte blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
#ifdef USE_SSE
|
||||
#include "blake2s_sse.cpp"
|
||||
#endif
|
||||
@@ -18,20 +32,6 @@ static const uint32 blake2s_IV[8] =
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const byte blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
static inline void blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = ~0U;
|
||||
@@ -134,11 +134,7 @@ void blake2s_update( blake2s_state *S, const byte *in, size_t inlen )
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
#ifdef USE_SSE
|
||||
#ifdef _WIN_32 // We use SSSE3 _mm_shuffle_epi8 only in x64 mode.
|
||||
if (_SSE_Version>=SSE_SSE2)
|
||||
#else
|
||||
if (_SSE_Version>=SSE_SSSE3)
|
||||
#endif
|
||||
blake2s_compress_sse( S, S->buf );
|
||||
else
|
||||
blake2s_compress( S, S->buf ); // Compress
|
||||
|
||||
@@ -3,13 +3,11 @@
|
||||
#define _RAR_BLAKE2_
|
||||
|
||||
#define BLAKE2_DIGEST_SIZE 32
|
||||
#define BLAKE2_THREADS_NUMBER 8
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32
|
||||
};
|
||||
|
||||
// Use constexpr instead of enums for -std=c++20 compatibility.
|
||||
constexpr size_t BLAKE2S_BLOCKBYTES = 64;
|
||||
constexpr size_t BLAKE2S_OUTBYTES = 32;
|
||||
|
||||
// Alignment to 64 improves performance of both SSE and non-SSE versions.
|
||||
// Alignment to n*16 is required for SSE version, so we selected 64.
|
||||
@@ -19,10 +17,15 @@ enum blake2s_constant
|
||||
// 'new' operator.
|
||||
struct blake2s_state
|
||||
{
|
||||
enum { BLAKE_ALIGNMENT = 64 };
|
||||
// Use constexpr instead of enums, because otherwise clang -std=c++20
|
||||
// issues a warning about "arithmetic between different enumeration types"
|
||||
// in ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT] declaration.
|
||||
static constexpr size_t BLAKE_ALIGNMENT = 64;
|
||||
|
||||
// buffer and uint32 h[8], t[2], f[2];
|
||||
enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES };
|
||||
// 2 * BLAKE2S_BLOCKBYTES is the buf size in blake2_code_20140114.zip.
|
||||
// It might differ in later versions.
|
||||
static constexpr size_t BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
// Based on public domain code written in 2012 by Samuel Neves
|
||||
|
||||
extern const byte blake2s_sigma[10][16];
|
||||
|
||||
// Initialization vector.
|
||||
static __m128i blake2s_IV_0_3, blake2s_IV_4_7;
|
||||
|
||||
#ifdef _WIN_64
|
||||
// Constants for cyclic rotation. Used in 64-bit mode in mm_rotr_epi32 macro.
|
||||
// Constants for cyclic rotation.
|
||||
static __m128i crotr8, crotr16;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
__attribute__((target("sse2")))
|
||||
#endif
|
||||
static void blake2s_init_sse()
|
||||
{
|
||||
// We cannot initialize these 128 bit variables in place when declaring
|
||||
@@ -24,28 +23,18 @@ static void blake2s_init_sse()
|
||||
blake2s_IV_0_3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
|
||||
blake2s_IV_4_7 = _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 );
|
||||
|
||||
#ifdef _WIN_64
|
||||
crotr8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
|
||||
crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
|
||||
#ifdef _WIN_32
|
||||
// 32-bit mode has less SSE2 registers and in MSVC2008 it is more efficient
|
||||
// to not use _mm_shuffle_epi8 here.
|
||||
#define mm_rotr_epi32(r, c) ( \
|
||||
_mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) )
|
||||
#else
|
||||
#define mm_rotr_epi32(r, c) ( \
|
||||
c==8 ? _mm_shuffle_epi8(r,crotr8) \
|
||||
: c==16 ? _mm_shuffle_epi8(r,crotr16) \
|
||||
: _mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) )
|
||||
#endif
|
||||
|
||||
|
||||
#define G1(row1,row2,row3,row4,buf) \
|
||||
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||
@@ -73,14 +62,6 @@ static void blake2s_init_sse()
|
||||
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) );
|
||||
|
||||
#ifdef _WIN_64
|
||||
// MSVC 2008 in x64 mode expands _mm_set_epi32 to store to stack and load
|
||||
// from stack operations, which are slower than this code.
|
||||
#define _mm_set_epi32(i3,i2,i1,i0) \
|
||||
_mm_unpacklo_epi32(_mm_unpacklo_epi32(_mm_cvtsi32_si128(i0),_mm_cvtsi32_si128(i2)), \
|
||||
_mm_unpacklo_epi32(_mm_cvtsi32_si128(i1),_mm_cvtsi32_si128(i3)))
|
||||
#endif
|
||||
|
||||
// Original BLAKE2 SSE4.1 message loading code was a little slower in x86 mode
|
||||
// and about the same in x64 mode in our test. Perhaps depends on compiler.
|
||||
// We also tried _mm_i32gather_epi32 and _mm256_i32gather_epi32 AVX2 gather
|
||||
@@ -101,6 +82,9 @@ static void blake2s_init_sse()
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
__attribute__((target("ssse3")))
|
||||
#endif
|
||||
static int blake2s_compress_sse( blake2s_state *S, const byte block[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
__m128i row[4];
|
||||
|
||||
@@ -20,7 +20,7 @@ void blake2sp_init( blake2sp_state *S )
|
||||
|
||||
blake2s_init_param( &S->R, 0, 1 ); // Init root.
|
||||
|
||||
for( uint i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
for( uint32 i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_init_param( &S->S[i], i, 0 ); // Init leaf.
|
||||
|
||||
S->R.last_node = 1;
|
||||
@@ -49,6 +49,8 @@ void Blake2ThreadData::Update()
|
||||
if (_SSE_Version>=SSE_SSE && inlen__ >= 2 * PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES)
|
||||
_mm_prefetch((char*)(in__ + PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES), _MM_HINT_T0);
|
||||
#endif
|
||||
// We tried to _forceinline blake2s_update and blake2s_compress_sse,
|
||||
// but it didn't improve performance.
|
||||
blake2s_update( S, in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,30 @@
|
||||
#ifndef _RAR_CMDDATA_
|
||||
#define _RAR_CMDDATA_
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
|
||||
// In Windows we implement our own command line parser to avoid replacing
|
||||
// \" by " in standard parser. Such replacing corrupts destination paths
|
||||
// like "dest path\" in extraction commands.
|
||||
#define CUSTOM_CMDLINE_PARSER
|
||||
#endif
|
||||
|
||||
#define DefaultStoreList L"7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lz;lzh;mp3;rar;taz;tgz;xz;z;zip;zipx"
|
||||
#define DefaultStoreList L"7z;arj;bz2;cab;gz;jpeg;jpg;lha;lz;lzh;mp3;rar;taz;tbz;tbz2;tgz;txz;xz;z;zip;zipx;zst;tzst"
|
||||
|
||||
enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS};
|
||||
|
||||
enum IS_PROCESS_FILE_FLAGS {IPFF_EXCLUDE_PARENT=1};
|
||||
|
||||
class CommandData:public RAROptions
|
||||
{
|
||||
private:
|
||||
void ProcessSwitchesString(const wchar *Str);
|
||||
void ProcessSwitch(const wchar *Switch);
|
||||
void BadSwitch(const wchar *Switch);
|
||||
uint GetExclAttr(const wchar *Str);
|
||||
uint GetExclAttr(const wchar *Str,bool &Dir);
|
||||
#if !defined(SFX_MODULE)
|
||||
void SetTimeFilters(const wchar *Mod,bool Before,bool Age);
|
||||
void SetStoreTimeMode(const wchar *S);
|
||||
#endif
|
||||
int64 GetModSize(const wchar *S,uint DefMultiplier);
|
||||
|
||||
bool FileLists;
|
||||
bool NoMoreSwitches;
|
||||
@@ -23,42 +35,69 @@ class CommandData:public RAROptions
|
||||
void Init();
|
||||
|
||||
void ParseCommandLine(bool Preprocess,int argc, char *argv[]);
|
||||
void ParseArg(wchar *ArgW);
|
||||
void ParseArg(const wchar *ArgW);
|
||||
void ParseDone();
|
||||
void ParseEnvVar();
|
||||
void ReadConfig();
|
||||
void PreprocessArg(const wchar *Arg);
|
||||
void ProcessSwitchesString(const std::wstring &Str);
|
||||
void OutTitle();
|
||||
void OutHelp(RAR_EXIT ExitCode);
|
||||
bool IsSwitch(int Ch);
|
||||
bool ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList);
|
||||
static bool CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode);
|
||||
bool ExclCheck(const std::wstring &CheckName,bool Dir,bool CheckFullPath,bool CheckInclList);
|
||||
static bool CheckArgs(StringList *Args,bool Dir,const std::wstring &CheckName,bool CheckFullPath,int MatchMode);
|
||||
bool ExclDirByAttr(uint FileAttr);
|
||||
bool TimeCheck(RarTime &ft);
|
||||
bool TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta);
|
||||
bool SizeCheck(int64 Size);
|
||||
bool AnyFiltersActive();
|
||||
int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH,
|
||||
wchar *MatchedArg=NULL,uint MatchedArgSize=0);
|
||||
int IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
|
||||
bool Flags,std::wstring *MatchedArg);
|
||||
void ProcessCommand();
|
||||
void AddArcName(const wchar *Name);
|
||||
void AddArcName(const std::wstring &Name);
|
||||
bool GetArcName(wchar *Name,int MaxSize);
|
||||
bool CheckWinSize();
|
||||
bool GetArcName(std::wstring &Name);
|
||||
|
||||
int GetRecoverySize(const wchar *Str,int DefSize);
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
void ReportWrongSwitches(RARFORMAT Format);
|
||||
#endif
|
||||
|
||||
wchar Command[NM+16];
|
||||
void GetBriefMaskList(const std::wstring &Masks,StringList &Args);
|
||||
|
||||
wchar ArcName[NM];
|
||||
|
||||
std::wstring Command;
|
||||
std::wstring ArcName;
|
||||
std::wstring ExtrPath;
|
||||
std::wstring TempPath;
|
||||
std::wstring SFXModule;
|
||||
std::wstring CommentFile;
|
||||
std::wstring ArcPath; // For -ap<path>.
|
||||
std::wstring ExclArcPath; // For -ep4<path> switch.
|
||||
std::wstring LogName;
|
||||
std::wstring EmailTo;
|
||||
|
||||
// Read data from stdin and store in archive under a name specified here
|
||||
// when archiving. Read an archive from stdin if any non-empty string
|
||||
// is specified here when extracting.
|
||||
std::wstring UseStdin;
|
||||
|
||||
StringList FileArgs;
|
||||
StringList ExclArgs;
|
||||
StringList InclArgs;
|
||||
StringList ArcNames;
|
||||
StringList StoreArgs;
|
||||
#ifdef PROPAGATE_MOTW
|
||||
StringList MotwList; // Extensions to assign the mark of the web.
|
||||
#endif
|
||||
|
||||
SecPassword Password;
|
||||
|
||||
std::vector<int64> NextVolSizes;
|
||||
|
||||
|
||||
#ifdef RARDLL
|
||||
std::wstring DllDestName;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
380
unrar/cmdfilter.cpp
Normal file
380
unrar/cmdfilter.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
// Return 'true' if we need to exclude the file from processing as result
|
||||
// of -x switch. If CheckInclList is true, we also check the file against
|
||||
// the include list created with -n switch.
|
||||
bool CommandData::ExclCheck(const std::wstring &CheckName,bool Dir,bool CheckFullPath,bool CheckInclList)
|
||||
{
|
||||
if (CheckArgs(&ExclArgs,Dir,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
|
||||
return true;
|
||||
if (!CheckInclList || InclArgs.ItemsCount()==0)
|
||||
return false;
|
||||
if (CheckArgs(&InclArgs,Dir,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CommandData::CheckArgs(StringList *Args,bool Dir,const std::wstring &CheckName,bool CheckFullPath,int MatchMode)
|
||||
{
|
||||
std::wstring Name,FullName,CurMask;
|
||||
ConvertPath(&CheckName,&Name);
|
||||
Args->Rewind();
|
||||
while (Args->GetString(CurMask))
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// 2025.09.11: Unix allows DOS slashes as a part of file name, so we do not
|
||||
// convert it for Unix. In Windows we wish -xdir\file and -xdir/file both
|
||||
// to exclude the file.
|
||||
UnixSlashToDos(CurMask,CurMask);
|
||||
#endif
|
||||
wchar LastMaskChar=GetLastChar(CurMask);
|
||||
bool DirMask=IsPathDiv(LastMaskChar); // Mask for directories only.
|
||||
|
||||
if (Dir)
|
||||
{
|
||||
// CheckName is a directory.
|
||||
if (DirMask)
|
||||
{
|
||||
// We process the directory and have the directory exclusion mask.
|
||||
// So let's convert "mask\" to "mask" and process it normally.
|
||||
|
||||
CurMask.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This code doesn't allow to apply -n and -x wildcard masks without
|
||||
// trailing slash to folders unless these masks are * and *.*.
|
||||
// See the changes history below.
|
||||
// 2023.03.26: Previously we removed this code completely to let
|
||||
// 'rar a arc dir -ndir\path\*' include empty folders in 'path' too.
|
||||
// But then we received an email from user not willing -x*.avi to
|
||||
// exclude folders like dir.avi with non-avi files. Also rar.txt
|
||||
// mentions that masks like *.avi exclude only files. Initially
|
||||
// we wanted masks like -npath\* or -xpath\* to match the entire
|
||||
// contents of path including empty folders and added the special
|
||||
// check for "*" and "*.*". But this is not very straightforward,
|
||||
// when *.* and *.avi are processed differently, especially taking
|
||||
// into account that we can specify the exact folder name without
|
||||
// wildcards to process it and masks like 'dir*\' can be used to
|
||||
// exclude folders. So we decided to skip all usual wildcard masks
|
||||
// for folders.
|
||||
// 2023.11.22: We returned the special check for "*" and "*.*",
|
||||
// because users expected 'rar a arc dir -xdir\*' to exclude
|
||||
// everything including subfolders in 'dir'. For now we returned it
|
||||
// both for -n and -x, but we can limit it to -x only if needed.
|
||||
std::wstring Name=PointToName(CurMask);
|
||||
if (IsWildcard(Name) && Name!=L"*" && Name!=L"*.*")
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we process a file inside of directory excluded by "dirmask\".
|
||||
// we want to exclude such file too. So we convert "dirmask\" to
|
||||
// "dirmask\*". It is important for operations other than archiving
|
||||
// with -x. When archiving with -x, directory matched by "dirmask\"
|
||||
// is excluded from further scanning.
|
||||
|
||||
if (DirMask)
|
||||
CurMask+=L"*";
|
||||
}
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
if (CheckFullPath && IsFullPath(CurMask))
|
||||
{
|
||||
// We do not need to do the special "*\" processing here, because
|
||||
// unlike the "else" part of this "if", now we convert names to full
|
||||
// format, so they all include the path, which is matched by "*\"
|
||||
// correctly. Moreover, removing "*\" from mask would break
|
||||
// the comparison, because now all names have the path.
|
||||
|
||||
if (FullName.empty())
|
||||
ConvertNameToFull(CheckName,FullName);
|
||||
if (CmpName(CurMask,FullName,MatchMode))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
std::wstring CurName=Name;
|
||||
|
||||
// Important to convert before "*\" check below, so masks like
|
||||
// d:*\something are processed properly.
|
||||
size_t MaskOffset=ConvertPath(&CurMask,nullptr);
|
||||
std::wstring CmpMask=CurMask.substr(MaskOffset);
|
||||
|
||||
if (CmpMask[0]=='*' && IsPathDiv(CmpMask[1]))
|
||||
{
|
||||
// We want "*\name" to match 'name' not only in subdirectories,
|
||||
// but also in the current directory. We convert the name
|
||||
// from 'name' to '.\name' to be matched by "*\" part even if it is
|
||||
// in current directory.
|
||||
CurName=L'.';
|
||||
CurName+=CPATHDIVIDER;
|
||||
CurName+=Name;
|
||||
}
|
||||
|
||||
if (CmpName(CmpMask,CurName,MatchMode))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Now this function performs only one task and only in Windows version:
|
||||
// it skips symlinks to directories if -e1024 switch is specified.
|
||||
// Symlinks are skipped in ScanTree class, so their entire contents
|
||||
// is skipped too. Without this function we would check the attribute
|
||||
// only directly before archiving, so we would skip the symlink record,
|
||||
// but not the contents of symlinked directory.
|
||||
bool CommandData::ExclDirByAttr(uint FileAttr)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0 &&
|
||||
(ExclFileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE)
|
||||
void CommandData::SetTimeFilters(const wchar *Mod,bool Before,bool Age)
|
||||
{
|
||||
bool ModeOR=false,TimeMods=false;
|
||||
const wchar *S=Mod;
|
||||
// Check if any 'mca' modifiers are present, set OR mode if 'o' is present,
|
||||
// skip modifiers and set S to beginning of time string. Be sure to check
|
||||
// *S!=0, because termination 0 is a part of string for wcschr.
|
||||
for (;*S!=0 && wcschr(L"MCAOmcao",*S)!=NULL;S++)
|
||||
if (*S=='o' || *S=='O')
|
||||
ModeOR=true;
|
||||
else
|
||||
TimeMods=true;
|
||||
|
||||
if (!TimeMods) // Assume 'm' if no modifiers are specified.
|
||||
Mod=L"m";
|
||||
|
||||
// Set the specified time for every modifier. Be sure to check *Mod!=0,
|
||||
// because termination 0 is a part of string for wcschr. This check is
|
||||
// important when we set Mod to "m" above.
|
||||
for (;*Mod!=0 && wcschr(L"MCAOmcao",*Mod)!=NULL;Mod++)
|
||||
switch(toupperw(*Mod))
|
||||
{
|
||||
case 'M':
|
||||
if (Before)
|
||||
{
|
||||
Age ? FileMtimeBefore.SetAgeText(S):FileMtimeBefore.SetIsoText(S);
|
||||
FileMtimeBeforeOR=ModeOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
Age ? FileMtimeAfter.SetAgeText(S):FileMtimeAfter.SetIsoText(S);
|
||||
FileMtimeAfterOR=ModeOR;
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
if (Before)
|
||||
{
|
||||
Age ? FileCtimeBefore.SetAgeText(S):FileCtimeBefore.SetIsoText(S);
|
||||
FileCtimeBeforeOR=ModeOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
Age ? FileCtimeAfter.SetAgeText(S):FileCtimeAfter.SetIsoText(S);
|
||||
FileCtimeAfterOR=ModeOR;
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
if (Before)
|
||||
{
|
||||
Age ? FileAtimeBefore.SetAgeText(S):FileAtimeBefore.SetIsoText(S);
|
||||
FileAtimeBeforeOR=ModeOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
Age ? FileAtimeAfter.SetAgeText(S):FileAtimeAfter.SetIsoText(S);
|
||||
FileAtimeAfterOR=ModeOR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Return 'true' if we need to exclude the file from processing.
|
||||
bool CommandData::TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta)
|
||||
{
|
||||
bool FilterOR=false;
|
||||
|
||||
if (FileMtimeBefore.IsSet()) // Filter present.
|
||||
if (ftm>=FileMtimeBefore) // Condition not matched.
|
||||
if (FileMtimeBeforeOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileMtimeBeforeOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
if (FileMtimeAfter.IsSet()) // Filter present.
|
||||
if (ftm<FileMtimeAfter) // Condition not matched.
|
||||
if (FileMtimeAfterOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileMtimeAfterOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
if (FileCtimeBefore.IsSet()) // Filter present.
|
||||
if (ftc>=FileCtimeBefore) // Condition not matched.
|
||||
if (FileCtimeBeforeOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileCtimeBeforeOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
if (FileCtimeAfter.IsSet()) // Filter present.
|
||||
if (ftc<FileCtimeAfter) // Condition not matched.
|
||||
if (FileCtimeAfterOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileCtimeAfterOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
if (FileAtimeBefore.IsSet()) // Filter present.
|
||||
if (fta>=FileAtimeBefore) // Condition not matched.
|
||||
if (FileAtimeBeforeOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileAtimeBeforeOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
if (FileAtimeAfter.IsSet()) // Filter present.
|
||||
if (fta<FileAtimeAfter) // Condition not matched.
|
||||
if (FileAtimeAfterOR)
|
||||
FilterOR=true; // Not matched OR filter is present.
|
||||
else
|
||||
return true; // Exclude file in AND mode.
|
||||
else // Condition matched.
|
||||
if (FileAtimeAfterOR)
|
||||
return false; // Include file in OR mode.
|
||||
|
||||
return FilterOR; // Exclude if all OR filters are not matched.
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Return 'true' if we need to exclude the file from processing.
|
||||
bool CommandData::SizeCheck(int64 Size)
|
||||
{
|
||||
if (Size==INT64NDF) // If called from archive formats like bzip2, not storing the file size.
|
||||
return false;
|
||||
if (FileSizeLess!=INT64NDF && Size>=FileSizeLess)
|
||||
return true;
|
||||
if (FileSizeMore!=INT64NDF && Size<=FileSizeMore)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// Return 0 if file must not be processed or a number of matched parameter otherwise.
|
||||
int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
|
||||
bool Flags,std::wstring *MatchedArg)
|
||||
{
|
||||
if (MatchedArg!=NULL)
|
||||
MatchedArg->clear();
|
||||
bool Dir=FileHead.Dir;
|
||||
if (ExclCheck(FileHead.FileName,Dir,false,true))
|
||||
return 0;
|
||||
#ifndef SFX_MODULE
|
||||
if (TimeCheck(FileHead.mtime,FileHead.ctime,FileHead.atime))
|
||||
return 0;
|
||||
if ((FileHead.FileAttr & ExclFileAttr)!=0 || FileHead.Dir && ExclDir)
|
||||
return 0;
|
||||
if (InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0 &&
|
||||
(!FileHead.Dir || !InclDir))
|
||||
return 0;
|
||||
if (!Dir && SizeCheck(FileHead.UnpSize))
|
||||
return 0;
|
||||
#endif
|
||||
std::wstring ArgName;
|
||||
FileArgs.Rewind();
|
||||
for (int StringCount=1;FileArgs.GetString(ArgName);StringCount++)
|
||||
{
|
||||
// Ensure that both parameters of CmpName are either C++ strings or
|
||||
// pointers, so we avoid time consuming string construction for one of
|
||||
// parameters in this expensive loop.
|
||||
if (CmpName(ArgName,FileHead.FileName,MatchType))
|
||||
{
|
||||
if (ExactMatch!=NULL)
|
||||
*ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
|
||||
if (MatchedArg!=NULL)
|
||||
*MatchedArg=ArgName;
|
||||
return StringCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE)
|
||||
void CommandData::SetStoreTimeMode(const wchar *S)
|
||||
{
|
||||
if (*S==0 || IsDigit(*S) || *S=='-' || *S=='+')
|
||||
{
|
||||
// Apply -ts, -ts1, -ts-, -ts+ to all 3 times.
|
||||
// Handle obsolete -ts[2,3,4] as ts+.
|
||||
EXTTIME_MODE Mode=EXTTIME_MAX;
|
||||
if (*S=='-')
|
||||
Mode=EXTTIME_NONE;
|
||||
if (*S=='1')
|
||||
Mode=EXTTIME_1S;
|
||||
xmtime=xctime=xatime=Mode;
|
||||
S++;
|
||||
}
|
||||
|
||||
while (*S!=0)
|
||||
{
|
||||
EXTTIME_MODE Mode=EXTTIME_MAX;
|
||||
if (S[1]=='-')
|
||||
Mode=EXTTIME_NONE;
|
||||
if (S[1]=='1')
|
||||
Mode=EXTTIME_1S;
|
||||
switch(toupperw(*S))
|
||||
{
|
||||
case 'M':
|
||||
xmtime=Mode;
|
||||
break;
|
||||
case 'C':
|
||||
xctime=Mode;
|
||||
break;
|
||||
case 'A':
|
||||
xatime=Mode;
|
||||
break;
|
||||
case 'P':
|
||||
PreserveAtime=true;
|
||||
break;
|
||||
}
|
||||
S++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
123
unrar/cmdmix.cpp
Normal file
123
unrar/cmdmix.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
void CommandData::OutTitle()
|
||||
{
|
||||
if (BareOutput || DisableCopyright)
|
||||
return;
|
||||
#ifdef SFX_MODULE
|
||||
mprintf(St(MCopyrightS));
|
||||
#else
|
||||
#ifndef SILENT
|
||||
static bool TitleShown=false;
|
||||
if (TitleShown)
|
||||
return;
|
||||
TitleShown=true;
|
||||
|
||||
wchar Version[80];
|
||||
if (RARVER_BETA!=0)
|
||||
swprintf(Version,ASIZE(Version),L"%d.%02d %ls %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA);
|
||||
else
|
||||
swprintf(Version,ASIZE(Version),L"%d.%02d",RARVER_MAJOR,RARVER_MINOR);
|
||||
#if defined(_WIN_32) || defined(_WIN_64)
|
||||
wcsncatz(Version,L" ",ASIZE(Version));
|
||||
#endif
|
||||
#ifdef _WIN_32
|
||||
wcsncatz(Version,St(Mx86),ASIZE(Version));
|
||||
#endif
|
||||
#ifdef _WIN_64
|
||||
wcsncatz(Version,St(Mx64),ASIZE(Version));
|
||||
#endif
|
||||
if (PrintVersion)
|
||||
{
|
||||
mprintf(L"%s",Version);
|
||||
exit(0);
|
||||
}
|
||||
mprintf(St(MUCopyright),Version,RARVER_YEAR);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline bool CmpMSGID(MSGID i1,MSGID i2)
|
||||
{
|
||||
#ifdef MSGID_INT
|
||||
return i1==i2;
|
||||
#else
|
||||
// If MSGID is const char*, we cannot compare pointers only.
|
||||
// Pointers to different instances of same string can differ,
|
||||
// so we need to compare complete strings.
|
||||
return wcscmp(i1,i2)==0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommandData::OutHelp(RAR_EXIT ExitCode)
|
||||
{
|
||||
#if !defined(SILENT)
|
||||
OutTitle();
|
||||
static MSGID Help[]={
|
||||
#ifdef SFX_MODULE
|
||||
// Console SFX switches definition.
|
||||
MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV
|
||||
#else
|
||||
// UnRAR switches definition.
|
||||
MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL,
|
||||
MCHelpCmdP,MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm,
|
||||
MCHelpSwAT,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,MCHelpSwAI,MCHelpSwAP,
|
||||
MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDH,MCHelpSwEP,
|
||||
MCHelpSwEP3,MCHelpSwEP4,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
|
||||
MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwME,MCHelpSwMLP,
|
||||
MCHelpSwN,MCHelpSwNa,MCHelpSwNal,MCHelpSwO,MCHelpSwOC,MCHelpSwOL,
|
||||
MCHelpSwOM,MCHelpSwOP,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,MCHelpSwR,
|
||||
MCHelpSwRI,MCHelpSwSC,MCHelpSwSI,MCHelpSwSL,MCHelpSwTA,
|
||||
MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwVUnr,
|
||||
MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,MCHelpSwY
|
||||
#endif
|
||||
};
|
||||
|
||||
for (uint I=0;I<ASIZE(Help);I++)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
#ifndef _WIN_ALL
|
||||
static MSGID Win32Only[]={
|
||||
MCHelpSwIEML,MCHelpSwVD,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
|
||||
MCHelpSwEP2,MCHelpSwMLP,MCHelpSwOC,MCHelpSwONI,MCHelpSwDR,MCHelpSwRI
|
||||
};
|
||||
bool Found=false;
|
||||
for (uint J=0;J<ASIZE(Win32Only);J++)
|
||||
if (CmpMSGID(Help[I],Win32Only[J]))
|
||||
{
|
||||
Found=true;
|
||||
break;
|
||||
}
|
||||
if (Found)
|
||||
continue;
|
||||
#endif
|
||||
#ifdef _UNIX
|
||||
if (CmpMSGID(Help[I],MRARTitle2))
|
||||
{
|
||||
mprintf(St(MFwrSlTitle2));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if !defined(_UNIX) && !defined(_WIN_ALL)
|
||||
if (CmpMSGID(Help[I],MCHelpSwOW))
|
||||
continue;
|
||||
#endif
|
||||
#ifndef _WIN_ALL
|
||||
if (CmpMSGID(Help[I],MCHelpSwAC))
|
||||
continue;
|
||||
#endif
|
||||
#ifndef SAVE_LINKS
|
||||
if (CmpMSGID(Help[I],MCHelpSwOL))
|
||||
continue;
|
||||
#endif
|
||||
#ifndef RAR_SMP
|
||||
if (CmpMSGID(Help[I],MCHelpSwMT))
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
mprintf(St(Help[I]));
|
||||
}
|
||||
mprintf(L"\n");
|
||||
ErrHandler.Exit(ExitCode);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
|
||||
inline unsigned int RangeCoder::GetChar()
|
||||
inline byte RangeCoder::GetChar()
|
||||
{
|
||||
return(UnpackRead->GetChar());
|
||||
return UnpackRead->GetChar();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ void RangeCoder::InitDecoder(Unpack *UnpackRead)
|
||||
RangeCoder::UnpackRead=UnpackRead;
|
||||
|
||||
low=code=0;
|
||||
range=uint(-1);
|
||||
for (int i=0;i < 4;i++)
|
||||
range=0xffffffff;
|
||||
for (uint i = 0; i < 4; i++)
|
||||
code=(code << 8) | GetChar();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class RangeCoder
|
||||
inline uint GetCurrentShiftCount(uint SHIFT);
|
||||
inline void Decode();
|
||||
inline void PutChar(unsigned int c);
|
||||
inline unsigned int GetChar();
|
||||
inline byte GetChar();
|
||||
|
||||
uint low, code, range;
|
||||
struct SUBRANGE
|
||||
|
||||
@@ -6,15 +6,27 @@
|
||||
class PackDef
|
||||
{
|
||||
public:
|
||||
// Maximum LZ match length we can encode even for short distances.
|
||||
static const uint MAX_LZ_MATCH = 0x1001;
|
||||
|
||||
// We increment LZ match length for longer distances, because shortest
|
||||
// matches are not allowed for them. Maximum length increment is 3
|
||||
// for distances larger than 256KB (0x40000). Here we define the maximum
|
||||
// incremented LZ match. Normally packer does not use it, but we must be
|
||||
// ready to process it in corrupt archives.
|
||||
static const uint MAX_INC_LZ_MATCH = MAX_LZ_MATCH + 3;
|
||||
|
||||
static const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
|
||||
static const uint MAX3_INC_LZ_MATCH = MAX3_LZ_MATCH + 3;
|
||||
static const uint LOW_DIST_REP_COUNT = 16;
|
||||
|
||||
static const uint NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
static const uint DC = 64;
|
||||
static const uint DCB = 64; // Base distance codes up to 4 GB.
|
||||
static const uint DCX = 80; // Extended distance codes up to 1 TB.
|
||||
static const uint LDC = 16;
|
||||
static const uint RC = 44;
|
||||
static const uint HUFF_TABLE_SIZE = NC + DC + RC + LDC;
|
||||
static const uint HUFF_TABLE_SIZEB = NC + DCB + RC + LDC;
|
||||
static const uint HUFF_TABLE_SIZEX = NC + DCX + RC + LDC;
|
||||
static const uint BC = 20;
|
||||
|
||||
static const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||
@@ -33,10 +45,6 @@ class PackDef
|
||||
// Largest alphabet size among all values listed above.
|
||||
static const uint LARGEST_TABLE_SIZE = 306;
|
||||
|
||||
enum {
|
||||
CODE_HUFFMAN, CODE_LZ, CODE_REPEATLZ, CODE_CACHELZ, CODE_STARTFILE,
|
||||
CODE_ENDFILE, CODE_FILTER, CODE_FILTERDATA
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +52,10 @@ enum FilterType {
|
||||
// These values must not be changed, because we use them directly
|
||||
// in RAR5 compression and decompression code.
|
||||
FILTER_DELTA=0, FILTER_E8, FILTER_E8E9, FILTER_ARM,
|
||||
FILTER_AUDIO, FILTER_RGB, FILTER_ITANIUM, FILTER_PPM, FILTER_NONE
|
||||
FILTER_AUDIO, FILTER_RGB, FILTER_ITANIUM, FILTER_TEXT,
|
||||
|
||||
// These values can be changed.
|
||||
FILTER_LONGRANGE,FILTER_EXHAUSTIVE,FILTER_NONE
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
246
unrar/consio.cpp
246
unrar/consio.cpp
@@ -3,8 +3,8 @@
|
||||
|
||||
static MESSAGE_TYPE MsgStream=MSG_STDOUT;
|
||||
static RAR_CHARSET RedirectCharset=RCH_DEFAULT;
|
||||
|
||||
const int MaxMsgSize=2*NM+2048;
|
||||
static bool ProhibitInput=false;
|
||||
static bool ConsoleOutputPresent=false;
|
||||
|
||||
static bool StdoutRedirected=false,StderrRedirected=false,StdinRedirected=false;
|
||||
|
||||
@@ -49,54 +49,65 @@ void InitConsole()
|
||||
}
|
||||
|
||||
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,RAR_CHARSET RedirectCharset)
|
||||
void SetConsoleMsgStream(MESSAGE_TYPE MsgStream)
|
||||
{
|
||||
::MsgStream=MsgStream;
|
||||
}
|
||||
|
||||
|
||||
void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset)
|
||||
{
|
||||
::RedirectCharset=RedirectCharset;
|
||||
}
|
||||
|
||||
|
||||
void ProhibitConsoleInput()
|
||||
{
|
||||
ProhibitInput=true;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
static void cvt_wprintf(FILE *dest,const wchar *fmt,va_list arglist)
|
||||
{
|
||||
// This buffer is for format string only, not for entire output,
|
||||
// so it can be short enough.
|
||||
wchar fmtw[1024];
|
||||
PrintfPrepareFmt(fmt,fmtw,ASIZE(fmtw));
|
||||
ConsoleOutputPresent=true;
|
||||
|
||||
// No need for PrintfPrepareFmt here, vwstrprintf calls it.
|
||||
std::wstring s=vwstrprintf(fmt,arglist);
|
||||
|
||||
ReplaceEsc(s);
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
safebuf wchar Msg[MaxMsgSize];
|
||||
if (dest==stdout && StdoutRedirected || dest==stderr && StderrRedirected)
|
||||
{
|
||||
HANDLE hOut=GetStdHandle(dest==stdout ? STD_OUTPUT_HANDLE:STD_ERROR_HANDLE);
|
||||
vswprintf(Msg,ASIZE(Msg),fmtw,arglist);
|
||||
DWORD Written;
|
||||
if (RedirectCharset==RCH_UNICODE)
|
||||
WriteFile(hOut,Msg,(DWORD)wcslen(Msg)*sizeof(*Msg),&Written,NULL);
|
||||
WriteFile(hOut,s.data(),(DWORD)s.size()*sizeof(s[0]),&Written,NULL);
|
||||
else
|
||||
{
|
||||
// Avoid Unicode for redirect in Windows, it does not work with pipes.
|
||||
safebuf char MsgA[MaxMsgSize];
|
||||
std::string MsgA;
|
||||
if (RedirectCharset==RCH_UTF8)
|
||||
WideToUtf(Msg,MsgA,ASIZE(MsgA));
|
||||
WideToUtf(s,MsgA);
|
||||
else
|
||||
WideToChar(Msg,MsgA,ASIZE(MsgA));
|
||||
WideToChar(s,MsgA);
|
||||
if (RedirectCharset==RCH_DEFAULT || RedirectCharset==RCH_OEM)
|
||||
CharToOemA(MsgA,MsgA); // Console tools like 'more' expect OEM encoding.
|
||||
CharToOemA(&MsgA[0],&MsgA[0]); // Console tools like 'more' expect OEM encoding.
|
||||
|
||||
// We already converted \n to \r\n above, so we use WriteFile instead
|
||||
// of C library to avoid unnecessary additional conversion.
|
||||
WriteFile(hOut,MsgA,(DWORD)strlen(MsgA),&Written,NULL);
|
||||
WriteFile(hOut,MsgA.data(),(DWORD)MsgA.size(),&Written,NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// MSVC2008 vfwprintf writes every character to console separately
|
||||
// and it is too slow. We use direct WriteConsole call instead.
|
||||
vswprintf(Msg,ASIZE(Msg),fmtw,arglist);
|
||||
HANDLE hOut=GetStdHandle(dest==stderr ? STD_ERROR_HANDLE:STD_OUTPUT_HANDLE);
|
||||
DWORD Written;
|
||||
WriteConsole(hOut,Msg,(DWORD)wcslen(Msg),&Written,NULL);
|
||||
WriteConsole(hOut,s.data(),(DWORD)s.size(),&Written,NULL);
|
||||
#else
|
||||
vfwprintf(dest,fmtw,arglist);
|
||||
fputws(s.c_str(),dest);
|
||||
// We do not use setbuf(NULL) in Unix (see comments in InitConsole).
|
||||
fflush(dest);
|
||||
#endif
|
||||
@@ -136,81 +147,109 @@ void eprintf(const wchar *fmt,...)
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
static void GetPasswordText(wchar *Str,uint MaxLength)
|
||||
static void QuitIfInputProhibited()
|
||||
{
|
||||
if (MaxLength==0)
|
||||
return;
|
||||
// We cannot handle user prompts if -si is used to read file or archive data
|
||||
// from stdin.
|
||||
if (ProhibitInput)
|
||||
{
|
||||
mprintf(St(MStdinNoInput));
|
||||
ErrHandler.Exit(RARX_FATAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void GetPasswordText(std::wstring &Str)
|
||||
{
|
||||
QuitIfInputProhibited();
|
||||
if (StdinRedirected)
|
||||
getwstr(Str,MaxLength); // Read from pipe or redirected file.
|
||||
getwstr(Str); // Read from pipe or redirected file.
|
||||
else
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD ConInMode,ConOutMode;
|
||||
DWORD Read=0;
|
||||
DWORD ConInMode;
|
||||
GetConsoleMode(hConIn,&ConInMode);
|
||||
GetConsoleMode(hConOut,&ConOutMode);
|
||||
SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
|
||||
SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||
SetConsoleMode(hConIn,ENABLE_LINE_INPUT); // Remove ENABLE_ECHO_INPUT.
|
||||
|
||||
std::vector<wchar> Buf(MAXPASSWORD);
|
||||
|
||||
// We prefer ReadConsole to ReadFile, so we can read Unicode input.
|
||||
DWORD Read=0;
|
||||
ReadConsole(hConIn,Buf.data(),(DWORD)Buf.size()-1,&Read,NULL);
|
||||
Buf[Read]=0;
|
||||
Str=Buf.data();
|
||||
cleandata(Buf.data(),Buf.size()*sizeof(Buf[0]));
|
||||
|
||||
ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
|
||||
Str[Read]=0;
|
||||
SetConsoleMode(hConIn,ConInMode);
|
||||
SetConsoleMode(hConOut,ConOutMode);
|
||||
|
||||
// 2023.03.12: Previously we checked for presence of "\n" in entered
|
||||
// passwords, supposing that truncated strings do not include it.
|
||||
// We did it to read the rest of excessively long string, so it is not
|
||||
// read later as the second password for -p switch. But this "\n" check
|
||||
// doesn't seem to work in Windows 10 anymore and "\r" is present even
|
||||
// in truncated strings. Also we increased MAXPASSWORD, so it is larger
|
||||
// than MAXPASSWORD_RAR. Thus we removed this check as not working
|
||||
// and not that necessary. Low level FlushConsoleInputBuffer doesn't help
|
||||
// for high level ReadConsole, which in line input mode seems to store
|
||||
// the rest of string in its own internal buffer.
|
||||
#else
|
||||
char StrA[MAXPASSWORD];
|
||||
#if defined(_EMX) || defined (__VMS)
|
||||
fgets(StrA,ASIZE(StrA)-1,stdin);
|
||||
std::vector<char> StrA(MAXPASSWORD*4); // "*4" for multibyte UTF-8 characters.
|
||||
#ifdef __VMS
|
||||
fgets(StrA.data(),StrA.size()-1,stdin);
|
||||
#elif defined(__sun)
|
||||
strncpyz(StrA,getpassphrase(""),ASIZE(StrA));
|
||||
strncpyz(StrA.data(),getpassphrase(""),StrA.size());
|
||||
#else
|
||||
strncpyz(StrA,getpass(""),ASIZE(StrA));
|
||||
strncpyz(StrA.data(),getpass(""),StrA.size());
|
||||
#endif
|
||||
CharToWide(StrA,Str,MaxLength);
|
||||
cleandata(StrA,sizeof(StrA));
|
||||
CharToWide(StrA.data(),Str);
|
||||
cleandata(StrA.data(),StrA.size()*sizeof(StrA[0]));
|
||||
#endif
|
||||
}
|
||||
Str[MaxLength-1]=0;
|
||||
RemoveLF(Str);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
|
||||
bool GetConsolePassword(UIPASSWORD_TYPE Type,const std::wstring &FileName,SecPassword *Password)
|
||||
{
|
||||
if (!StdinRedirected)
|
||||
uiAlarm(UIALARM_QUESTION);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!StdinRedirected)
|
||||
// if (!StdinRedirected)
|
||||
if (Type==UIPASSWORD_GLOBAL)
|
||||
eprintf(L"\n%s: ",St(MAskPsw));
|
||||
else
|
||||
eprintf(St(MAskPswFor),FileName);
|
||||
eprintf(St(MAskPswFor),FileName.c_str());
|
||||
|
||||
wchar PlainPsw[MAXPASSWORD];
|
||||
GetPasswordText(PlainPsw,ASIZE(PlainPsw));
|
||||
if (*PlainPsw==0 && Type==UIPASSWORD_GLOBAL)
|
||||
std::wstring PlainPsw;
|
||||
GetPasswordText(PlainPsw);
|
||||
if (PlainPsw.empty() && Type==UIPASSWORD_GLOBAL)
|
||||
return false;
|
||||
if (PlainPsw.size()>=MAXPASSWORD)
|
||||
{
|
||||
PlainPsw.erase(MAXPASSWORD-1);
|
||||
uiMsg(UIERROR_TRUNCPSW,MAXPASSWORD-1);
|
||||
}
|
||||
if (!StdinRedirected && Type==UIPASSWORD_GLOBAL)
|
||||
{
|
||||
eprintf(St(MReAskPsw));
|
||||
wchar CmpStr[MAXPASSWORD];
|
||||
GetPasswordText(CmpStr,ASIZE(CmpStr));
|
||||
if (*CmpStr==0 || wcscmp(PlainPsw,CmpStr)!=0)
|
||||
std::wstring CmpStr;
|
||||
GetPasswordText(CmpStr);
|
||||
if (CmpStr.empty() || PlainPsw!=CmpStr)
|
||||
{
|
||||
eprintf(St(MNotMatchPsw));
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
cleandata(CmpStr,sizeof(CmpStr));
|
||||
cleandata(&PlainPsw[0],PlainPsw.size()*sizeof(PlainPsw[0]));
|
||||
cleandata(&CmpStr[0],CmpStr.size()*sizeof(CmpStr[0]));
|
||||
continue;
|
||||
}
|
||||
cleandata(CmpStr,sizeof(CmpStr));
|
||||
cleandata(&CmpStr[0],CmpStr.size()*sizeof(CmpStr[0]));
|
||||
}
|
||||
Password->Set(PlainPsw);
|
||||
cleandata(PlainPsw,sizeof(PlainPsw));
|
||||
Password->Set(PlainPsw.c_str());
|
||||
cleandata(&PlainPsw[0],PlainPsw.size()*sizeof(PlainPsw[0]));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@@ -219,12 +258,17 @@ bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *
|
||||
|
||||
|
||||
#ifndef SILENT
|
||||
bool getwstr(wchar *str,size_t n)
|
||||
void getwstr(std::wstring &str)
|
||||
{
|
||||
// Print buffered prompt title function before waiting for input.
|
||||
fflush(stderr);
|
||||
|
||||
*str=0;
|
||||
QuitIfInputProhibited();
|
||||
|
||||
str.clear();
|
||||
|
||||
const size_t MaxRead=MAXPATHSIZE; // Large enough to read a file name.
|
||||
|
||||
#if defined(_WIN_ALL)
|
||||
// fgetws does not work well with non-English text in Windows,
|
||||
// so we do not use it.
|
||||
@@ -232,33 +276,50 @@ bool getwstr(wchar *str,size_t n)
|
||||
{
|
||||
// fgets does not work well with pipes in Windows in our test.
|
||||
// Let's use files.
|
||||
Array<char> StrA(n*4); // Up to 4 UTF-8 characters per wchar_t.
|
||||
std::vector<char> StrA(MaxRead*4); // Up to 4 UTF-8 characters per wchar_t.
|
||||
File SrcFile;
|
||||
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||
int ReadSize=SrcFile.Read(&StrA[0],StrA.Size()-1);
|
||||
SrcFile.SetLineInputMode(true);
|
||||
int ReadSize=SrcFile.Read(&StrA[0],StrA.size()-1);
|
||||
if (ReadSize<=0)
|
||||
{
|
||||
// Looks like stdin is a null device. We can enter to infinite loop
|
||||
// calling Ask(), so let's better exit.
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
// calling Ask() or set an empty password, so let's better exit.
|
||||
ErrHandler.ReadError(L"stdin");
|
||||
}
|
||||
StrA[ReadSize]=0;
|
||||
CharToWide(&StrA[0],str,n);
|
||||
cleandata(&StrA[0],StrA.Size()); // We can use this function to enter passwords.
|
||||
|
||||
// We expect ANSI encoding here, but "echo text|rar ..." to pipe to RAR,
|
||||
// such as send passwords, we get OEM encoding by default, unless we
|
||||
// use "chcp" in console. But we avoid OEM to ANSI conversion,
|
||||
// because we also want to handle ANSI files redirection correctly,
|
||||
// like "rar ... < ansifile.txt".
|
||||
CharToWide(&StrA[0],str);
|
||||
cleandata(&StrA[0],StrA.size()); // We can use this function to enter passwords.
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<wchar> Buf(MaxRead); // Up to 4 UTF-8 characters per wchar_t.
|
||||
DWORD SizeToRead=(DWORD)Buf.size()-1;
|
||||
|
||||
// ReadConsole fails in Windows 7 for requested input exceeding 30 KB.
|
||||
// Not certain about Windows 8, so check for Windows 10 here.
|
||||
if (WinNT()<=WNT_W10)
|
||||
SizeToRead=Min(SizeToRead,0x4000);
|
||||
|
||||
DWORD ReadSize=0;
|
||||
if (ReadConsole(GetStdHandle(STD_INPUT_HANDLE),str,DWORD(n-1),&ReadSize,NULL)==0)
|
||||
return false;
|
||||
str[ReadSize]=0;
|
||||
if (ReadConsole(GetStdHandle(STD_INPUT_HANDLE),&Buf[0],SizeToRead,&ReadSize,NULL)==0)
|
||||
ErrHandler.ReadError(L"stdin"); // Unknown user input, safer to abort.
|
||||
Buf[ReadSize]=0;
|
||||
str=Buf.data();
|
||||
}
|
||||
#else
|
||||
if (fgetws(str,n,stdin)==NULL)
|
||||
ErrHandler.Exit(RARX_USERBREAK); // Avoid infinite Ask() loop.
|
||||
std::vector<wchar> Buf(MaxRead); // Up to 4 UTF-8 characters per wchar_t.
|
||||
if (fgetws(&Buf[0],Buf.size(),stdin)==NULL)
|
||||
ErrHandler.ReadError(L"stdin"); // Avoid infinite Ask() loop.
|
||||
str=Buf.data();
|
||||
#endif
|
||||
RemoveLF(str);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -272,22 +333,22 @@ int Ask(const wchar *AskStr)
|
||||
{
|
||||
uiAlarm(UIALARM_QUESTION);
|
||||
|
||||
const int MaxItems=10;
|
||||
const uint MaxItems=10;
|
||||
wchar Item[MaxItems][40];
|
||||
int ItemKeyPos[MaxItems],NumItems=0;
|
||||
uint ItemKeyPos[MaxItems],NumItems=0;
|
||||
|
||||
for (const wchar *NextItem=AskStr;NextItem!=NULL;NextItem=wcschr(NextItem+1,'_'))
|
||||
for (const wchar *NextItem=AskStr;NextItem!=nullptr;NextItem=wcschr(NextItem+1,'_'))
|
||||
{
|
||||
wchar *CurItem=Item[NumItems];
|
||||
wcsncpyz(CurItem,NextItem+1,ASIZE(Item[0]));
|
||||
wchar *EndItem=wcschr(CurItem,'_');
|
||||
if (EndItem!=NULL)
|
||||
if (EndItem!=nullptr)
|
||||
*EndItem=0;
|
||||
int KeyPos=0,CurKey;
|
||||
uint KeyPos=0,CurKey;
|
||||
while ((CurKey=CurItem[KeyPos])!=0)
|
||||
{
|
||||
bool Found=false;
|
||||
for (int I=0;I<NumItems && !Found;I++)
|
||||
for (uint I=0;I<NumItems && !Found;I++)
|
||||
if (toupperw(Item[I][ItemKeyPos[I]])==toupperw(CurKey))
|
||||
Found=true;
|
||||
if (!Found && CurKey!=' ')
|
||||
@@ -298,19 +359,19 @@ int Ask(const wchar *AskStr)
|
||||
NumItems++;
|
||||
}
|
||||
|
||||
for (int I=0;I<NumItems;I++)
|
||||
for (uint I=0;I<NumItems;I++)
|
||||
{
|
||||
eprintf(I==0 ? (NumItems>4 ? L"\n":L" "):L", ");
|
||||
int KeyPos=ItemKeyPos[I];
|
||||
for (int J=0;J<KeyPos;J++)
|
||||
eprintf(I==0 ? (NumItems>3 ? L"\n":L" "):L", ");
|
||||
uint KeyPos=ItemKeyPos[I];
|
||||
for (uint J=0;J<KeyPos;J++)
|
||||
eprintf(L"%c",Item[I][J]);
|
||||
eprintf(L"[%c]%ls",Item[I][KeyPos],&Item[I][KeyPos+1]);
|
||||
}
|
||||
eprintf(L" ");
|
||||
wchar Str[50];
|
||||
getwstr(Str,ASIZE(Str));
|
||||
std::wstring Str;
|
||||
getwstr(Str);
|
||||
wchar Ch=toupperw(Str[0]);
|
||||
for (int I=0;I<NumItems;I++)
|
||||
for (uint I=0;I<NumItems;I++)
|
||||
if (Ch==Item[I][ItemKeyPos[I]])
|
||||
return I+1;
|
||||
return 0;
|
||||
@@ -318,11 +379,11 @@ int Ask(const wchar *AskStr)
|
||||
#endif
|
||||
|
||||
|
||||
static bool IsCommentUnsafe(const wchar *Data,size_t Size)
|
||||
static bool IsCommentUnsafe(const std::wstring &Data)
|
||||
{
|
||||
for (size_t I=0;I<Size;I++)
|
||||
for (size_t I=0;I<Data.size();I++)
|
||||
if (Data[I]==27 && Data[I+1]=='[')
|
||||
for (size_t J=I+2;J<Size;J++)
|
||||
for (size_t J=I+2;J<Data.size();J++)
|
||||
{
|
||||
// Return true for <ESC>[{key};"{string}"p used to redefine
|
||||
// a keyboard key on some terminals.
|
||||
@@ -335,18 +396,21 @@ static bool IsCommentUnsafe(const wchar *Data,size_t Size)
|
||||
}
|
||||
|
||||
|
||||
void OutComment(const wchar *Comment,size_t Size)
|
||||
void OutComment(const std::wstring &Comment)
|
||||
{
|
||||
if (IsCommentUnsafe(Comment,Size))
|
||||
if (IsCommentUnsafe(Comment))
|
||||
return;
|
||||
const size_t MaxOutSize=0x400;
|
||||
for (size_t I=0;I<Size;I+=MaxOutSize)
|
||||
for (size_t I=0;I<Comment.size();I+=MaxOutSize)
|
||||
{
|
||||
wchar Msg[MaxOutSize+1];
|
||||
size_t CopySize=Min(MaxOutSize,Size-I);
|
||||
wcsncpy(Msg,Comment+I,CopySize);
|
||||
Msg[CopySize]=0;
|
||||
mprintf(L"%s",Msg);
|
||||
size_t CopySize=Min(MaxOutSize,Comment.size()-I);
|
||||
mprintf(L"%s",Comment.substr(I,CopySize).c_str());
|
||||
}
|
||||
mprintf(L"\n");
|
||||
}
|
||||
|
||||
|
||||
bool IsConsoleOutputPresent()
|
||||
{
|
||||
return ConsoleOutputPresent;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
#define _RAR_CONSIO_
|
||||
|
||||
void InitConsole();
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,RAR_CHARSET RedirectCharset);
|
||||
void OutComment(const wchar *Comment,size_t Size);
|
||||
void SetConsoleMsgStream(MESSAGE_TYPE MsgStream);
|
||||
void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset);
|
||||
void ProhibitConsoleInput();
|
||||
void OutComment(const std::wstring &Comment);
|
||||
bool IsConsoleOutputPresent();
|
||||
|
||||
#ifndef SILENT
|
||||
bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password);
|
||||
bool GetConsolePassword(UIPASSWORD_TYPE Type,const std::wstring &FileName,SecPassword *Password);
|
||||
#endif
|
||||
|
||||
#ifdef SILENT
|
||||
@@ -14,13 +17,13 @@ bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *
|
||||
inline void eprintf(const wchar *fmt,...) {}
|
||||
inline void Alarm() {}
|
||||
inline int Ask(const wchar *AskStr) {return 0;}
|
||||
inline bool getwstr(wchar *str,size_t n) {return false;}
|
||||
inline void getwstr(std::wstring &str) {}
|
||||
#else
|
||||
void mprintf(const wchar *fmt,...);
|
||||
void eprintf(const wchar *fmt,...);
|
||||
void Alarm();
|
||||
int Ask(const wchar *AskStr);
|
||||
bool getwstr(wchar *str,size_t n);
|
||||
void getwstr(std::wstring &str);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
210
unrar/crc.cpp
210
unrar/crc.cpp
@@ -14,7 +14,17 @@
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
static uint crc_tables[8][256]; // Tables for Slicing-by-8.
|
||||
#ifndef SFX_MODULE
|
||||
// User suggested to avoid BSD license in SFX module, so they do not need
|
||||
// to include the license to SFX archive.
|
||||
#define USE_SLICING
|
||||
#endif
|
||||
|
||||
static uint crc_tables[16][256]; // Tables for Slicing-by-16.
|
||||
|
||||
#ifdef USE_NEON_CRC32
|
||||
static bool CRC_Neon;
|
||||
#endif
|
||||
|
||||
|
||||
// Build the classic CRC32 lookup table.
|
||||
@@ -30,6 +40,19 @@ void InitCRC32(uint *CRCTab)
|
||||
C=(C & 1) ? (C>>1)^0xEDB88320 : (C>>1);
|
||||
CRCTab[I]=C;
|
||||
}
|
||||
|
||||
#ifdef USE_NEON_CRC32
|
||||
#ifdef _APPLE
|
||||
// getauxval isn't available in OS X
|
||||
uint Value=0;
|
||||
size_t Size=sizeof(Value);
|
||||
int RetCode=sysctlbyname("hw.optional.armv8_crc32",&Value,&Size,NULL,0);
|
||||
CRC_Neon=RetCode==0 && Value!=0;
|
||||
#else
|
||||
CRC_Neon=(getauxval(AT_HWCAP) & HWCAP_CRC32)!=0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,15 +60,17 @@ static void InitTables()
|
||||
{
|
||||
InitCRC32(crc_tables[0]);
|
||||
|
||||
#ifdef USE_SLICING
|
||||
for (uint I=0;I<256;I++) // Build additional lookup tables.
|
||||
{
|
||||
uint C=crc_tables[0][I];
|
||||
for (uint J=1;J<8;J++)
|
||||
for (uint J=1;J<16;J++)
|
||||
{
|
||||
C=crc_tables[0][(byte)C]^(C>>8);
|
||||
crc_tables[J][I]=C;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -55,28 +80,68 @@ uint CRC32(uint StartCRC,const void *Addr,size_t Size)
|
||||
{
|
||||
byte *Data=(byte *)Addr;
|
||||
|
||||
// Align Data to 8 for better performance.
|
||||
for (;Size>0 && ((size_t)Data & 7);Size--,Data++)
|
||||
#ifdef USE_NEON_CRC32
|
||||
if (CRC_Neon)
|
||||
{
|
||||
for (;Size>=8;Size-=8,Data+=8)
|
||||
#ifdef __clang__
|
||||
StartCRC = __builtin_arm_crc32d(StartCRC, RawGet8(Data));
|
||||
#else
|
||||
StartCRC = __builtin_aarch64_crc32x(StartCRC, RawGet8(Data));
|
||||
#endif
|
||||
for (;Size>0;Size--,Data++) // Process left data.
|
||||
#ifdef __clang__
|
||||
StartCRC = __builtin_arm_crc32b(StartCRC, *Data);
|
||||
#else
|
||||
StartCRC = __builtin_aarch64_crc32b(StartCRC, *Data);
|
||||
#endif
|
||||
return StartCRC;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SLICING
|
||||
// Align Data to 16 for better performance and to avoid ALLOW_MISALIGNED
|
||||
// check below.
|
||||
for (;Size>0 && ((size_t)Data & 15)!=0;Size--,Data++)
|
||||
StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
|
||||
|
||||
for (;Size>=8;Size-=8,Data+=8)
|
||||
// 2023.12.06: We switched to slicing-by-16, which seems to be faster than
|
||||
// slicing-by-8 on modern CPUs. Slicing-by-32 would require 32 KB for tables
|
||||
// and could be limited by L1 cache size on some CPUs.
|
||||
for (;Size>=16;Size-=16,Data+=16)
|
||||
{
|
||||
#ifdef BIG_ENDIAN
|
||||
StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24);
|
||||
uint NextData = Data[4]|(Data[5] << 8)|(Data[6] << 16)|(Data[7] << 24);
|
||||
StartCRC ^= RawGet4(Data);
|
||||
uint D1 = RawGet4(Data+4);
|
||||
uint D2 = RawGet4(Data+8);
|
||||
uint D3 = RawGet4(Data+12);
|
||||
#else
|
||||
// We avoid RawGet4 here for performance reason, to access uint32
|
||||
// directly even if ALLOW_MISALIGNED isn't defined. We can do it,
|
||||
// because we aligned 'Data' above.
|
||||
StartCRC ^= *(uint32 *) Data;
|
||||
uint NextData = *(uint32 *) (Data +4);
|
||||
uint D1 = *(uint32 *) (Data+4);
|
||||
uint D2 = *(uint32 *) (Data+8);
|
||||
uint D3 = *(uint32 *) (Data+12);
|
||||
#endif
|
||||
StartCRC = crc_tables[7][(byte) StartCRC ] ^
|
||||
crc_tables[6][(byte)(StartCRC >> 8) ] ^
|
||||
crc_tables[5][(byte)(StartCRC >> 16)] ^
|
||||
crc_tables[4][(byte)(StartCRC >> 24)] ^
|
||||
crc_tables[3][(byte) NextData ] ^
|
||||
crc_tables[2][(byte)(NextData >>8 ) ] ^
|
||||
crc_tables[1][(byte)(NextData >> 16)] ^
|
||||
crc_tables[0][(byte)(NextData >> 24)];
|
||||
StartCRC = crc_tables[15][(byte) StartCRC ] ^
|
||||
crc_tables[14][(byte)(StartCRC >> 8) ] ^
|
||||
crc_tables[13][(byte)(StartCRC >> 16)] ^
|
||||
crc_tables[12][(byte)(StartCRC >> 24)] ^
|
||||
crc_tables[11][(byte) D1 ] ^
|
||||
crc_tables[10][(byte)(D1 >> 8) ] ^
|
||||
crc_tables[ 9][(byte)(D1 >> 16)] ^
|
||||
crc_tables[ 8][(byte)(D1 >> 24)] ^
|
||||
crc_tables[ 7][(byte) D2 ] ^
|
||||
crc_tables[ 6][(byte)(D2 >> 8)] ^
|
||||
crc_tables[ 5][(byte)(D2 >> 16)] ^
|
||||
crc_tables[ 4][(byte)(D2 >> 24)] ^
|
||||
crc_tables[ 3][(byte) D3 ] ^
|
||||
crc_tables[ 2][(byte)(D3 >> 8)] ^
|
||||
crc_tables[ 1][(byte)(D3 >> 16)] ^
|
||||
crc_tables[ 0][(byte)(D3 >> 24)];
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;Size>0;Size--,Data++) // Process left data.
|
||||
StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
|
||||
@@ -100,3 +165,116 @@ ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static void TestCRC();
|
||||
struct TestCRCStruct {TestCRCStruct() {TestCRC();exit(0);}} GlobalTesCRC;
|
||||
|
||||
void TestCRC()
|
||||
{
|
||||
// This function is invoked from global object and _SSE_Version is global
|
||||
// and can be initialized after this function. So we explicitly initialize
|
||||
// it here to enable SSE support in Blake2sp.
|
||||
_SSE_Version=GetSSEVersion();
|
||||
|
||||
const uint FirstSize=300;
|
||||
byte b[FirstSize];
|
||||
|
||||
if ((CRC32(0xffffffff,(byte*)"testtesttest",12)^0xffffffff)==0x44608e84)
|
||||
mprintf(L"\nCRC32 test1 OK");
|
||||
else
|
||||
mprintf(L"\nCRC32 test1 FAILED");
|
||||
|
||||
if (CRC32(0,(byte*)"te\x80st",5)==0xB2E5C5AE)
|
||||
mprintf(L"\nCRC32 test2 OK");
|
||||
else
|
||||
mprintf(L"\nCRC32 test2 FAILED");
|
||||
|
||||
for (uint I=0;I<14;I++) // Check for possible int sign extension.
|
||||
b[I]=(byte)0x7f+I;
|
||||
if ((CRC32(0xffffffff,b,14)^0xffffffff)==0x1DFA75DA)
|
||||
mprintf(L"\nCRC32 test3 OK");
|
||||
else
|
||||
mprintf(L"\nCRC32 test3 FAILED");
|
||||
|
||||
for (uint I=0;I<FirstSize;I++)
|
||||
b[I]=(byte)I;
|
||||
uint r32=CRC32(0xffffffff,b,FirstSize);
|
||||
for (uint I=FirstSize;I<1024;I++)
|
||||
{
|
||||
b[0]=(byte)I;
|
||||
r32=CRC32(r32,b,1);
|
||||
}
|
||||
if ((r32^0xffffffff)==0xB70B4C26)
|
||||
mprintf(L"\nCRC32 test4 OK");
|
||||
else
|
||||
mprintf(L"\nCRC32 test4 FAILED");
|
||||
|
||||
if ((CRC64(0xffffffffffffffff,(byte*)"testtesttest",12)^0xffffffffffffffff)==0x7B1C2D230EDEB436)
|
||||
mprintf(L"\nCRC64 test1 OK");
|
||||
else
|
||||
mprintf(L"\nCRC64 test1 FAILED");
|
||||
|
||||
if (CRC64(0,(byte*)"te\x80st",5)==0xB5DBF9583A6EED4A)
|
||||
mprintf(L"\nCRC64 test2 OK");
|
||||
else
|
||||
mprintf(L"\nCRC64 test2 FAILED");
|
||||
|
||||
for (uint I=0;I<14;I++) // Check for possible int sign extension.
|
||||
b[I]=(byte)0x7f+I;
|
||||
if ((CRC64(0xffffffffffffffff,b,14)^0xffffffffffffffff)==0xE019941C05B2820C)
|
||||
mprintf(L"\nCRC64 test3 OK");
|
||||
else
|
||||
mprintf(L"\nCRC64 test3 FAILED");
|
||||
|
||||
for (uint I=0;I<FirstSize;I++)
|
||||
b[I]=(byte)I;
|
||||
uint64 r64=CRC64(0xffffffffffffffff,b,FirstSize);
|
||||
for (uint I=FirstSize;I<1024;I++)
|
||||
{
|
||||
b[0]=(byte)I;
|
||||
r64=CRC64(r64,b,1);
|
||||
}
|
||||
if ((r64^0xffffffffffffffff)==0xD51FB58DC789C400)
|
||||
mprintf(L"\nCRC64 test4 OK");
|
||||
else
|
||||
mprintf(L"\nCRC64 test4 FAILED");
|
||||
|
||||
const size_t BufSize=0x100000;
|
||||
byte *Buf=new byte[BufSize];
|
||||
GetRnd(Buf,BufSize);
|
||||
|
||||
clock_t StartTime=clock();
|
||||
r32=0xffffffff;
|
||||
const uint64 BufCount=5000;
|
||||
for (uint I=0;I<BufCount;I++)
|
||||
r32=CRC32(r32,Buf,BufSize);
|
||||
if (r32!=0) // Otherwise compiler optimizer removes CRC calculation.
|
||||
mprintf(L"\nCRC32 speed: %llu MB/s",BufCount*CLOCKS_PER_SEC/(clock()-StartTime));
|
||||
|
||||
StartTime=clock();
|
||||
DataHash Hash;
|
||||
Hash.Init(HASH_CRC32,MaxPoolThreads);
|
||||
const uint64 BufCountMT=20000;
|
||||
for (uint I=0;I<BufCountMT;I++)
|
||||
Hash.Update(Buf,BufSize);
|
||||
HashValue Result;
|
||||
Hash.Result(&Result);
|
||||
mprintf(L"\nCRC32 MT speed: %llu MB/s",BufCountMT*CLOCKS_PER_SEC/(clock()-StartTime));
|
||||
|
||||
StartTime=clock();
|
||||
Hash.Init(HASH_BLAKE2,MaxPoolThreads);
|
||||
for (uint I=0;I<BufCount;I++)
|
||||
Hash.Update(Buf,BufSize);
|
||||
Hash.Result(&Result);
|
||||
mprintf(L"\nBlake2sp speed: %llu MB/s",BufCount*CLOCKS_PER_SEC/(clock()-StartTime));
|
||||
|
||||
StartTime=clock();
|
||||
r64=0xffffffffffffffff;
|
||||
for (uint I=0;I<BufCount;I++)
|
||||
r64=CRC64(r64,Buf,BufSize);
|
||||
if (r64!=0) // Otherwise compiler optimizer removes CRC calculation.
|
||||
mprintf(L"\nCRC64 speed: %llu MB/s",BufCount*CLOCKS_PER_SEC/(clock()-StartTime));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11,21 +11,12 @@
|
||||
CryptData::CryptData()
|
||||
{
|
||||
Method=CRYPT_NONE;
|
||||
memset(KDF3Cache,0,sizeof(KDF3Cache));
|
||||
memset(KDF5Cache,0,sizeof(KDF5Cache));
|
||||
KDF3CachePos=0;
|
||||
KDF5CachePos=0;
|
||||
memset(CRCTab,0,sizeof(CRCTab));
|
||||
}
|
||||
|
||||
|
||||
CryptData::~CryptData()
|
||||
{
|
||||
cleandata(KDF3Cache,sizeof(KDF3Cache));
|
||||
cleandata(KDF5Cache,sizeof(KDF5Cache));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CryptData::DecryptBlock(byte *Buf,size_t Size)
|
||||
@@ -56,16 +47,28 @@ bool CryptData::SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,
|
||||
SecPassword *Password,const byte *Salt,
|
||||
const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
|
||||
{
|
||||
if (!Password->IsSet() || Method==CRYPT_NONE)
|
||||
if (Method==CRYPT_NONE || !Password->IsSet())
|
||||
return false;
|
||||
|
||||
CryptData::Method=Method;
|
||||
|
||||
wchar PwdW[MAXPASSWORD];
|
||||
Password->Get(PwdW,ASIZE(PwdW));
|
||||
|
||||
// Display this warning only when encrypting. Users complained that
|
||||
// it is distracting when decrypting. It still can be useful when encrypting,
|
||||
// so users do not waste time to excessively long passwords.
|
||||
if (Encrypt && wcslen(PwdW)>=MAXPASSWORD_RAR)
|
||||
uiMsg(UIERROR_TRUNCPSW,MAXPASSWORD_RAR-1);
|
||||
|
||||
PwdW[Min(MAXPASSWORD_RAR,MAXPASSWORD)-1]=0; // For compatibility with existing archives.
|
||||
|
||||
char PwdA[MAXPASSWORD];
|
||||
WideToChar(PwdW,PwdA,ASIZE(PwdA));
|
||||
PwdA[Min(MAXPASSWORD_RAR,MAXPASSWORD)-1]=0; // For compatibility with existing archives.
|
||||
|
||||
bool Success=true;
|
||||
|
||||
switch(Method)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
@@ -83,12 +86,12 @@ bool CryptData::SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,
|
||||
SetKey30(Encrypt,Password,PwdW,Salt);
|
||||
break;
|
||||
case CRYPT_RAR50:
|
||||
SetKey50(Encrypt,Password,PwdW,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
|
||||
Success=SetKey50(Encrypt,Password,PwdW,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
|
||||
break;
|
||||
}
|
||||
cleandata(PwdA,sizeof(PwdA));
|
||||
cleandata(PwdW,sizeof(PwdW));
|
||||
return true;
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +120,7 @@ void GetRnd(byte *RndBuf,size_t BufSize)
|
||||
HCRYPTPROV hProvider = 0;
|
||||
if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
{
|
||||
Success=CryptGenRandom(hProvider, (DWORD)BufSize, RndBuf) == TRUE;
|
||||
Success=CryptGenRandom(hProvider, (DWORD)BufSize, RndBuf) != FALSE;
|
||||
CryptReleaseContext(hProvider, 0);
|
||||
}
|
||||
#elif defined(_UNIX)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user