mirror of
https://github.com/php-win-ext/php-rar.git
synced 2026-03-24 04:52:07 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19bcaf064c |
27
.github/workflows/ci.yml
vendored
27
.github/workflows/ci.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: ['*']
|
||||
jobs:
|
||||
test-linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
php-rel: ['8.2', '8.3', '8.4', '8.5']
|
||||
ts-state: [ts, nts]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup PHP
|
||||
id: setup-php
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '${{ matrix.php-rel }}'
|
||||
env:
|
||||
phpts: '${{ matrix.ts-state }}'
|
||||
|
||||
- name: build extension
|
||||
run: phpize && ./configure --enable-rar && make
|
||||
- name: run tests
|
||||
run: rm run-tests.php && cp run-tests8.php run-tests.php && make test
|
||||
49
.github/workflows/windows.yml
vendored
49
.github/workflows/windows.yml
vendored
@@ -1,49 +0,0 @@
|
||||
name: Publish Windows Releases
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
push:
|
||||
branches: ['*']
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
get-extension-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.extension-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Get the extension matrix
|
||||
id: extension-matrix
|
||||
uses: php/php-windows-builder/extension-matrix@v1
|
||||
build:
|
||||
needs: get-extension-matrix
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: false
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix: ${{fromJson(needs.get-extension-matrix.outputs.matrix)}}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Build the extension
|
||||
uses: php/php-windows-builder/extension@v1
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
arch: ${{ matrix.arch }}
|
||||
ts: ${{ matrix.ts }}
|
||||
args: '--enable-rar'
|
||||
test-runner: 'run-tests8.php'
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
steps:
|
||||
- name: Upload artifact to the release
|
||||
uses: php/php-windows-builder/release@v1
|
||||
with:
|
||||
release: ${{ github.event.release.tag_name }}
|
||||
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -11,7 +11,6 @@
|
||||
/modules
|
||||
/missing
|
||||
/.deps
|
||||
*.dep
|
||||
/.libs
|
||||
/Makefile
|
||||
/Makefile.fragments
|
||||
@@ -24,14 +23,12 @@
|
||||
/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
|
||||
@@ -44,7 +41,3 @@
|
||||
/rar.la
|
||||
*.autosave
|
||||
/unrar/.libs
|
||||
/tmp-php.ini
|
||||
/php-rar.creator.user
|
||||
/compile_commands.json
|
||||
/.clangd
|
||||
|
||||
33
.travis.yml
Normal file
33
.travis.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
language: c
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- valgrind
|
||||
|
||||
env:
|
||||
#- PHP_VERSION=5.2.17 ZTS=yes MIRROR=http://museum.php.net/php5/
|
||||
- PHP_VERSION=5.3.29 ZTS=yes
|
||||
- PHP_VERSION=5.4.45 ZTS=yes
|
||||
- PHP_VERSION=5.5.37 ZTS=yes
|
||||
- PHP_VERSION=5.6.30 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||
- PHP_VERSION=5.6.30 ZTS=no
|
||||
- PHP_VERSION=7.0.21 ZTS=yes COVERAGE=yes
|
||||
- PHP_VERSION=7.1.7 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/php_builds
|
||||
|
||||
before_install:
|
||||
- source travis.sh
|
||||
- maybe_install_php $PHP_VERSION $ZTS
|
||||
|
||||
install:
|
||||
- build $PHP_VERSION $ZTS "$COVERAGE"
|
||||
|
||||
script:
|
||||
- run_tests $PHP_VERSION $ZTS
|
||||
|
||||
after_success:
|
||||
- 'test "$COVERAGE" != "yes" || bash <(curl -s https://codecov.io/bash)'
|
||||
@@ -1,6 +0,0 @@
|
||||
replace-run-tests:
|
||||
@if ! grep -q 'Minimum required PHP version: 5\.3\.0' run-tests.php; then \
|
||||
cp run-tests8.php run-tests.php; \
|
||||
fi
|
||||
|
||||
test: replace-run-tests
|
||||
15
README
Normal file
15
README
Normal file
@@ -0,0 +1,15 @@
|
||||
PHP extension for reading RAR archives using the bundled UnRAR library.
|
||||
|
||||
This extension uses a modified version of the UnRAR library. The UnRAR library
|
||||
is an official open-source library by RARLabs, an auto generated subset of the
|
||||
RAR codebase. It is available from http://www.rarlab.com/rar_add.htm
|
||||
Please note that it has a more restrictive license than the PHP bindings,
|
||||
barring using it to re-create the RAR compression algorithm. See
|
||||
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)
|
||||
42
README.md
42
README.md
@@ -1,42 +0,0 @@
|
||||
PHP extension for reading RAR archives using the bundled UnRAR library.
|
||||
|
||||
This extension uses a modified version of the UnRAR library. The UnRAR library
|
||||
is an official open-source library by RARLabs, an auto generated subset of the
|
||||
RAR codebase. It is available from http://www.rarlab.com/rar_add.htm
|
||||
Please note that it has a more restrictive license than the PHP bindings,
|
||||
barring using it to re-create the RAR compression algorithm. See
|
||||
unrar/LICENSE.txt for details.
|
||||
|
||||
Some modifications have been applied to the UnRAR library, mainly to allow
|
||||
streaming extraction of files without using threads.
|
||||
|
||||
| Version | Status |
|
||||
|---------|------------------------------|
|
||||
| master | unmaintened :x: |
|
||||
| v4.x | maintened :white_check_mark: |
|
||||
|
||||
Maintained PHP Versions compatibility:
|
||||
|
||||
| PHP Version | Status |
|
||||
|-------------|------------------------|
|
||||
| 5.x | no :x: |
|
||||
| 7.x | no :x: |
|
||||
| 8.0 | yes :white_check_mark: |
|
||||
| 8.1 | yes :white_check_mark: |
|
||||
| 8.2 | yes :white_check_mark: |
|
||||
| 8.3 | yes :white_check_mark: |
|
||||
| 8.4 | yes :white_check_mark: |
|
||||
| 8.5 | yes :white_check_mark: |
|
||||
|
||||
Installation system support:
|
||||
|
||||
| Platform | Status |
|
||||
|----------|------------------------|
|
||||
| PECL | no :x: |
|
||||
| PIE | yes :white_check_mark: |
|
||||
|
||||
To install the extension, use PIE (PHP Installer Extension) with a command like:
|
||||
|
||||
```bash
|
||||
pie install php-win-ext/rar
|
||||
```
|
||||
29
appveyor.bat
Normal file
29
appveyor.bat
Normal file
@@ -0,0 +1,29 @@
|
||||
echo Running appveyor.bat
|
||||
echo on
|
||||
|
||||
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
|
||||
|
||||
IF NOT EXIST "C:\projects\php-sdk" (
|
||||
wget -nv http://windows.php.net/downloads/php-sdk/php-sdk-binary-tools-20110915.zip
|
||||
7z x -y php-sdk-binary-tools-20110915.zip -oC:\projects\php-sdk
|
||||
)
|
||||
IF NOT EXIST "C:\projects\php-src\Release_TS\php7ts.lib" (
|
||||
git clone --depth=1 --branch=PHP-7.1 https://github.com/php/php-src C:\projects\php-src
|
||||
wget -nv http://windows.php.net/downloads/php-sdk/deps-7.1-vc14-x86.7z
|
||||
7z x -y deps-7.1-vc14-x86.7z -oC:\projects\php-src
|
||||
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||
cd C:\projects\php-src
|
||||
CALL buildconf.bat
|
||||
CALL configure.bat --disable-all --enable-cli --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||
nmake
|
||||
) ELSE (
|
||||
echo php7ts.lib already exists
|
||||
cd C:\projects\php-src
|
||||
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||
)
|
||||
|
||||
CALL buildconf.bat --force --add-modules-dir=%APPVEYOR_BUILD_FOLDER%\..
|
||||
CALL configure.bat --disable-all --enable-cli --enable-rar=shared --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||
nmake || exit /b
|
||||
rmdir Release_TS\php-rar /S /Q
|
||||
del /S /Q "Release_TS\*.sbr"
|
||||
26
appveyor.yml
Normal file
26
appveyor.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
# Based on igbinary's appveyor config.
|
||||
|
||||
version: '{branch}.{build}'
|
||||
install:
|
||||
- cmd: choco feature enable -n=allowGlobalConfirmation
|
||||
- cmd: cinst wget
|
||||
- cmd: mkdir %APPVEYOR_BUILD_FOLDER%\bin
|
||||
|
||||
build_script:
|
||||
- cmd: "%APPVEYOR_BUILD_FOLDER%\\appveyor.bat"
|
||||
|
||||
test_script:
|
||||
- cmd: cd C:\projects\php-src
|
||||
- cmd: set NO_INTERACTION=1
|
||||
- cmd: set REPORT_EXIT_STATUS=1
|
||||
- cmd: set TZ=UTC
|
||||
- cmd: 'nmake test TESTS="--show-diff --set-timeout 30 -d extension=C:\projects\php-src\Release_TS\php_rar.dll %APPVEYOR_BUILD_FOLDER%\tests"'
|
||||
|
||||
after_test:
|
||||
# - cmd: dir /S C:\projects\php-src\Release_TS
|
||||
- cmd: 'del C:\projects\php-src\Release_TS\php_rar.*'
|
||||
|
||||
cache:
|
||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||
- C:\projects\php-src
|
||||
- C:\projects\php-sdk
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "php-win-ext/rar",
|
||||
"type": "php-ext",
|
||||
"license": [
|
||||
"PHP-3.01"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gustavo Lopes",
|
||||
"email": "cataphract@php.net"
|
||||
},
|
||||
{
|
||||
"name": "Antony Dovgal",
|
||||
"email": "tony@daylessday.org"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">= 8.0.0"
|
||||
},
|
||||
"description": "rar extension"
|
||||
}
|
||||
33
config.m4
33
config.m4
@@ -31,43 +31,12 @@ unrar_sources="unrar/sha256.cpp unrar/qopen.cpp \
|
||||
unrar/encname.cpp unrar/file.cpp \
|
||||
unrar/secpassword.cpp unrar/options.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])
|
||||
PHP_SUBST(RAR_SHARED_LIBADD)
|
||||
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 -fvisibility=hidden -I@ext_srcdir@/unrar)
|
||||
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -Wno-write-strings -Wall -I@ext_srcdir@/unrar)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||
fi
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
ARG_ENABLE("rar", "Rar support", "no");
|
||||
|
||||
if (PHP_RAR != "no") {
|
||||
EXTENSION("rar", "rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c rar_time.c", PHP_RAR_SHARED, "/DRARDLL /DSILENT /EHsc /D_WSTDIO_DEFINED");
|
||||
EXTENSION("rar", "rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c", PHP_RAR_SHARED, "/DRARDLL /DSILENT /EHsc /D_WSTDIO_DEFINED");
|
||||
ADD_SOURCES(configure_module_dirname + "/unrar",
|
||||
"sha256.cpp qopen.cpp \
|
||||
blake2s.cpp recvol.cpp \
|
||||
@@ -31,7 +31,7 @@ if (PHP_RAR != "no") {
|
||||
arcread.cpp filefn.cpp \
|
||||
global.cpp list.cpp \
|
||||
encname.cpp file.cpp \
|
||||
secpassword.cpp options.cpp", "rar", "unrar_obj");
|
||||
secpassword.cpp options.cpp", "rar");
|
||||
|
||||
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
||||
}
|
||||
|
||||
140
package.xml
140
package.xml
@@ -23,11 +23,11 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<active>no</active>
|
||||
</developer>
|
||||
|
||||
<date>2020-12-06</date>
|
||||
<time>20:00:00</time>
|
||||
<date>2013-10-11</date>
|
||||
<time>13:00:00</time>
|
||||
<version>
|
||||
<release>4.2.0</release>
|
||||
<api>4.2.0</api>
|
||||
<release>3.0.2</release>
|
||||
<api>3.0.0</api>
|
||||
</version>
|
||||
|
||||
<stability>
|
||||
@@ -36,9 +36,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
</stability>
|
||||
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<notes>- Support PHP 8.
|
||||
- Merge unrar 6.0.2.
|
||||
- RarArchive implements IteratorAggregate (PHP 8 only).
|
||||
<notes>- Fixed build with PHP 5.5.
|
||||
- Upgraded bundled unrar to version 4.2.4.
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
@@ -143,22 +142,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="097.phpt"/>
|
||||
<file role="test" name="098.phpt"/>
|
||||
<file role="test" name="099.phpt"/>
|
||||
<file role="test" name="100.phpt"/>
|
||||
<file role="test" name="101.phpt"/>
|
||||
<file role="test" name="102.phpt"/>
|
||||
<file role="test" name="103.phpt"/>
|
||||
<file role="test" name="104.phpt"/>
|
||||
<file role="test" name="105.phpt"/>
|
||||
<file role="test" name="106.phpt"/>
|
||||
<file role="test" name="107.phpt"/>
|
||||
<file role="test" name="108.phpt"/>
|
||||
<file role="test" name="109.phpt"/>
|
||||
<file role="test" name="110.phpt"/>
|
||||
<file role="test" name="111.phpt"/>
|
||||
<file role="test" name="112.phpt"/>
|
||||
<file role="test" name="113.phpt"/>
|
||||
<file role="test" name="114.phpt"/>
|
||||
<file role="test" name="115.phpt"/>
|
||||
<file role="test" name="commented.rar"/>
|
||||
<file role="test" name="corrupted.rar"/>
|
||||
<file role="test" name="directories.rar"/>
|
||||
@@ -174,7 +157,6 @@ 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"/>
|
||||
@@ -183,9 +165,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="solid.rar"/>
|
||||
<file role="test" name="sparsefiles_rar.rar"/>
|
||||
<file role="test" name="store_method.rar"/>
|
||||
<file role="test" name="rar5-links.rar"/>
|
||||
<file role="test" name="rar5_multi.part1.rar"/>
|
||||
<file role="test" name="rar5_multi.part2.rar"/>
|
||||
</dir> <!-- /tests -->
|
||||
<dir name="unrar">
|
||||
<file name="acknow.txt" role="doc" />
|
||||
@@ -194,14 +173,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<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="beosea.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" />
|
||||
@@ -211,10 +185,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="crc.hpp" role="src" />
|
||||
<file name="crypt.cpp" role="src" />
|
||||
<file name="crypt.hpp" role="src" />
|
||||
<file name="crypt1.cpp" role="src" />
|
||||
<file name="crypt2.cpp" role="src" />
|
||||
<file name="crypt3.cpp" role="src" />
|
||||
<file name="crypt5.cpp" role="src" />
|
||||
<file name="dll.cpp" role="src" />
|
||||
<file name="dll.hpp" role="src" />
|
||||
<file name="encname.cpp" role="src" />
|
||||
@@ -240,12 +210,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="getbits.hpp" role="src" />
|
||||
<file name="global.cpp" role="src" />
|
||||
<file name="global.hpp" role="src" />
|
||||
<file name="hardlinks.cpp" role="src" />
|
||||
<file name="hash.cpp" role="src" />
|
||||
<file name="hash.hpp" role="src" />
|
||||
<file name="headers.cpp" role="src" />
|
||||
<file name="headers.hpp" role="src" />
|
||||
<file name="headers5.hpp" role="src" />
|
||||
<file name="isnt.cpp" role="src" />
|
||||
<file name="isnt.hpp" role="src" />
|
||||
<file name="LICENSE.txt" role="doc" />
|
||||
@@ -261,10 +226,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="options.cpp" role="src" />
|
||||
<file name="options.hpp" role="src" />
|
||||
<file name="os.hpp" role="src" />
|
||||
<file name="os2ea.cpp" role="src" />
|
||||
<file name="pathfn.cpp" role="src" />
|
||||
<file name="pathfn.hpp" role="src" />
|
||||
<file name="qopen.cpp" role="src" />
|
||||
<file name="qopen.hpp" role="src" />
|
||||
<file name="rar.cpp" role="src" />
|
||||
<file name="rar.hpp" role="src" />
|
||||
<file name="rardefs.hpp" role="src" />
|
||||
@@ -273,31 +237,11 @@ 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="rawint.hpp" role="src" />
|
||||
<file name="rarvmtbl.cpp" role="src" />
|
||||
<file name="rawread.cpp" role="src" />
|
||||
<file name="rawread.hpp" role="src" />
|
||||
<file name="rdwrfn.cpp" role="src" />
|
||||
<file name="rdwrfn.hpp" role="src" />
|
||||
<file name="recvol3.cpp" role="src" />
|
||||
<file name="recvol5.cpp" role="src" />
|
||||
<file name="rs16.cpp" role="src" />
|
||||
<file name="rs16.hpp" role="src" />
|
||||
<file name="sha256.cpp" role="src" />
|
||||
<file name="sha256.hpp" role="src" />
|
||||
<file name="threadmisc.cpp" role="src" />
|
||||
<file name="threadpool.cpp" role="src" />
|
||||
<file name="threadpool.hpp" role="src" />
|
||||
<file name="ui.cpp" role="src" />
|
||||
<file name="ui.hpp" role="src" />
|
||||
<file name="uicommon.cpp" role="src" />
|
||||
<file name="uiconsole.cpp" role="src" />
|
||||
<file name="uisilent.cpp" role="src" />
|
||||
<file name="unpack30.cpp" role="src" />
|
||||
<file name="unpack50.cpp" role="src" />
|
||||
<file name="unpack50frag.cpp" role="src" />
|
||||
<file name="unpack50mt.cpp" role="src" />
|
||||
<file name="unpackinline.cpp" role="src" />
|
||||
<file name="win32lnk.cpp" role="src" />
|
||||
<file name="README.txt" role="doc" />
|
||||
<file name="recvol.cpp" role="src" />
|
||||
<file name="recvol.hpp" role="src" />
|
||||
@@ -307,6 +251,7 @@ 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.cpp" role="src" />
|
||||
<file name="savepos.hpp" role="src" />
|
||||
<file name="scantree.cpp" role="src" />
|
||||
<file name="scantree.hpp" role="src" />
|
||||
@@ -327,8 +272,10 @@ 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="unios2.cpp" role="src" />
|
||||
<file name="unpack.cpp" role="src" />
|
||||
<file name="unpack.hpp" role="src" />
|
||||
<file name="unpack15.cpp" role="src" />
|
||||
@@ -340,23 +287,18 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="win32acl.cpp" role="src" />
|
||||
<file name="win32stm.cpp" role="src" />
|
||||
</dir> <!-- /unrar -->
|
||||
<file name="config.m4" role="src" />
|
||||
<file name="config.m4" role="src" />
|
||||
<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="README" 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" />
|
||||
<file name="rararch.c" role="src" />
|
||||
<file name="rarentry.c" role="src" />
|
||||
<file name="rar_error.c" role="src" />
|
||||
<file name="rar_time.c" role="src" />
|
||||
<file name="run-tests8.php" role="test" />
|
||||
<file role="src" name="rar_navigation.c"/>
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
@@ -364,7 +306,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>5.3.0</min>
|
||||
<min>5.2.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0</min>
|
||||
@@ -375,58 +317,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<providesextension>rar</providesextension>
|
||||
|
||||
<extsrcrelease />
|
||||
|
||||
<changelog>
|
||||
<release>
|
||||
<version>
|
||||
<release>4.1.0</release>
|
||||
<api>4.0.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2020-10-11</date>
|
||||
<notes>Changes in this version:
|
||||
- Merge changes made to unrar up to version 5.5.6.
|
||||
- Support PHP 7.2, PHP 7.3 and PHP 7.4.
|
||||
- Update to unrar 5.9.4.
|
||||
- Fix bug #76592: streaming unpacking of uncompressed files incomplete.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>4.0.0</release>
|
||||
<api>4.0.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2017-07-22</date>
|
||||
<notes>Changes in this version:
|
||||
- Added functions RarEntry::getRedirType(), RarEntry::isRedirectToDirectory() and RarEntry::getRedirTarget(), as well as the following constants on RarEntry: FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION, FSREDIR_HARDLINK and FSREDIR_FILECOPY.
|
||||
- Changed stat handler to return UTC time for creation, modification and access time (does not work reliably on Windows).
|
||||
- Fix cloning of RarArchive being allowed.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>3.0.2</release>
|
||||
<api>3.0.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2013-10-11</date>
|
||||
<notes>Changes in this version:
|
||||
- Fixed build with PHP 5.5.
|
||||
- Upgraded bundled unrar to version 4.2.4.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>3.0.1</release>
|
||||
@@ -514,7 +406,7 @@ Other changes:
|
||||
- A lot of refactoring and compilation as C, not C++.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>1.0.0</release>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Add predefined macros for your project here. For example:
|
||||
// #define THE_ANSWER 42
|
||||
#define RARDLL 1
|
||||
#define HAVE_CONFIG_H 1
|
||||
#define _Float32 float
|
||||
#define _Float32x float
|
||||
#define _Float64 double
|
||||
#define _Float64x double
|
||||
#define _Float128 long double
|
||||
#define _Float128x long double
|
||||
#define _BITS_FLOATN_H
|
||||
@@ -1 +0,0 @@
|
||||
[General]
|
||||
161
php-rar.files
161
php-rar.files
@@ -1,161 +0,0 @@
|
||||
config.h
|
||||
php_compat.h
|
||||
php_compat.h
|
||||
php_rar.h
|
||||
rar.c
|
||||
rar_error.c
|
||||
rar_navigation.c
|
||||
rar_stream.c
|
||||
rar_time.c
|
||||
rararch.c
|
||||
rarentry.c
|
||||
unrar/arccmt.cpp
|
||||
unrar/archive.cpp
|
||||
unrar/archive.hpp
|
||||
unrar/arcread.cpp
|
||||
unrar/array.hpp
|
||||
unrar/blake2s.cpp
|
||||
unrar/blake2s.hpp
|
||||
unrar/blake2s_sse.cpp
|
||||
unrar/blake2sp.cpp
|
||||
unrar/cmddata.cpp
|
||||
unrar/cmddata.hpp
|
||||
unrar/cmdfilter.cpp
|
||||
unrar/cmdmix.cpp
|
||||
unrar/coder.cpp
|
||||
unrar/coder.hpp
|
||||
unrar/compress.hpp
|
||||
unrar/consio.cpp
|
||||
unrar/consio.hpp
|
||||
unrar/crc.cpp
|
||||
unrar/crc.hpp
|
||||
unrar/crypt.cpp
|
||||
unrar/crypt.hpp
|
||||
unrar/crypt1.cpp
|
||||
unrar/crypt2.cpp
|
||||
unrar/crypt3.cpp
|
||||
unrar/crypt5.cpp
|
||||
unrar/dll.cpp
|
||||
unrar/dll.hpp
|
||||
unrar/encname.cpp
|
||||
unrar/encname.hpp
|
||||
unrar/errhnd.cpp
|
||||
unrar/errhnd.hpp
|
||||
unrar/extinfo.cpp
|
||||
unrar/extinfo.hpp
|
||||
unrar/extract.cpp
|
||||
unrar/extract.hpp
|
||||
unrar/extractchunk.cpp
|
||||
unrar/filcreat.cpp
|
||||
unrar/filcreat.hpp
|
||||
unrar/file.cpp
|
||||
unrar/file.hpp
|
||||
unrar/filefn.cpp
|
||||
unrar/filefn.hpp
|
||||
unrar/filestr.cpp
|
||||
unrar/filestr.hpp
|
||||
unrar/find.cpp
|
||||
unrar/find.hpp
|
||||
unrar/getbits.cpp
|
||||
unrar/getbits.hpp
|
||||
unrar/global.cpp
|
||||
unrar/global.hpp
|
||||
unrar/hardlinks.cpp
|
||||
unrar/hash.cpp
|
||||
unrar/hash.hpp
|
||||
unrar/headers.cpp
|
||||
unrar/headers.hpp
|
||||
unrar/headers5.hpp
|
||||
unrar/isnt.cpp
|
||||
unrar/isnt.hpp
|
||||
unrar/list.cpp
|
||||
unrar/list.hpp
|
||||
unrar/loclang.hpp
|
||||
unrar/log.cpp
|
||||
unrar/log.hpp
|
||||
unrar/match.cpp
|
||||
unrar/match.hpp
|
||||
unrar/model.cpp
|
||||
unrar/model.hpp
|
||||
unrar/options.cpp
|
||||
unrar/options.hpp
|
||||
unrar/os.hpp
|
||||
unrar/pathfn.cpp
|
||||
unrar/pathfn.hpp
|
||||
unrar/qopen.cpp
|
||||
unrar/qopen.hpp
|
||||
unrar/rar.cpp
|
||||
unrar/rar.hpp
|
||||
unrar/rardefs.hpp
|
||||
unrar/rarlang.hpp
|
||||
unrar/raros.hpp
|
||||
unrar/rartypes.hpp
|
||||
unrar/rarvm.cpp
|
||||
unrar/rarvm.hpp
|
||||
unrar/rarvmtbl.cpp
|
||||
unrar/rawint.hpp
|
||||
unrar/rawread.cpp
|
||||
unrar/rawread.hpp
|
||||
unrar/rdwrfn.cpp
|
||||
unrar/rdwrfn.hpp
|
||||
unrar/recvol.cpp
|
||||
unrar/recvol.hpp
|
||||
unrar/recvol3.cpp
|
||||
unrar/recvol5.cpp
|
||||
unrar/resource.cpp
|
||||
unrar/resource.hpp
|
||||
unrar/rijndael.cpp
|
||||
unrar/rijndael.hpp
|
||||
unrar/rs.cpp
|
||||
unrar/rs.hpp
|
||||
unrar/rs16.cpp
|
||||
unrar/rs16.hpp
|
||||
unrar/savepos.hpp
|
||||
unrar/scantree.cpp
|
||||
unrar/scantree.hpp
|
||||
unrar/secpassword.cpp
|
||||
unrar/secpassword.hpp
|
||||
unrar/sha1.cpp
|
||||
unrar/sha1.hpp
|
||||
unrar/sha256.cpp
|
||||
unrar/sha256.hpp
|
||||
unrar/smallfn.cpp
|
||||
unrar/smallfn.hpp
|
||||
unrar/strfn.cpp
|
||||
unrar/strfn.hpp
|
||||
unrar/strlist.cpp
|
||||
unrar/strlist.hpp
|
||||
unrar/suballoc.cpp
|
||||
unrar/suballoc.hpp
|
||||
unrar/system.cpp
|
||||
unrar/system.hpp
|
||||
unrar/threadmisc.cpp
|
||||
unrar/threadpool.cpp
|
||||
unrar/threadpool.hpp
|
||||
unrar/timefn.cpp
|
||||
unrar/timefn.hpp
|
||||
unrar/ui.cpp
|
||||
unrar/ui.hpp
|
||||
unrar/uicommon.cpp
|
||||
unrar/uiconsole.cpp
|
||||
unrar/uisilent.cpp
|
||||
unrar/ulinks.cpp
|
||||
unrar/ulinks.hpp
|
||||
unrar/unicode.cpp
|
||||
unrar/unicode.hpp
|
||||
unrar/unpack.cpp
|
||||
unrar/unpack.hpp
|
||||
unrar/unpack15.cpp
|
||||
unrar/unpack20.cpp
|
||||
unrar/unpack30.cpp
|
||||
unrar/unpack50.cpp
|
||||
unrar/unpack50frag.cpp
|
||||
unrar/unpack50mt.cpp
|
||||
unrar/unpackinline.cpp
|
||||
unrar/uowners.cpp
|
||||
unrar/version.hpp
|
||||
unrar/volume.cpp
|
||||
unrar/volume.hpp
|
||||
unrar/win32acl.cpp
|
||||
unrar/win32lnk.cpp
|
||||
unrar/win32stm.cpp
|
||||
@@ -1,4 +0,0 @@
|
||||
/home/glopes/repos/php-src/Zend
|
||||
/home/glopes/repos/php-src/TSRM
|
||||
/home/glopes/repos/php-src/main
|
||||
/home/glopes/repos/php-src
|
||||
72
php_compat.h
72
php_compat.h
@@ -1,72 +0,0 @@
|
||||
#include <php.h>
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
# define TSRMLS_DC
|
||||
# define TSRMLS_D
|
||||
# define TSRMLS_CC
|
||||
# define TSRMLS_C
|
||||
# define TSRMLS_FETCH()
|
||||
# define IS_CALLABLE_STRICT 0
|
||||
# define zend_qsort zend_sort
|
||||
# define ZV_TO_THIS_FOR_HANDLER(zv) (Z_OBJ_P(zv))
|
||||
typedef zend_object handler_this_t;
|
||||
#else
|
||||
# define ZV_TO_THIS_FOR_HANDLER(zv) (zv)
|
||||
typedef zval handler_this_t;
|
||||
#endif
|
||||
|
||||
#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
|
||||
72
php_rar.h
72
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.2.1"
|
||||
#define PHP_RAR_VERSION "4.0.0"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_RAR_API __declspec(dllexport)
|
||||
@@ -63,8 +63,6 @@ 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 */
|
||||
@@ -89,6 +87,63 @@ enum FILE_SYSTEM_REDIRECT {
|
||||
/* 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
|
||||
|
||||
typedef struct _rar_cb_user_data {
|
||||
char *password; /* can be NULL */
|
||||
zval *callable; /* can be NULL */
|
||||
@@ -278,9 +333,8 @@ void _rar_close_file_resource(rar_file_t *rar);
|
||||
/* Fetches the rar_file_t part of the RarArchive object in order to use the
|
||||
* 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_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);
|
||||
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);
|
||||
void minit_rararch(TSRMLS_D);
|
||||
|
||||
PHP_FUNCTION(rar_open);
|
||||
@@ -308,12 +362,6 @@ php_stream *php_stream_rar_open(char *arc_name,
|
||||
STREAMS_DC TSRMLS_DC);
|
||||
extern php_stream_wrapper php_stream_rar_wrapper;
|
||||
|
||||
/* rar_time.c */
|
||||
void rar_time_convert(unsigned low, unsigned high, time_t *to);
|
||||
int rar_dos_time_convert(unsigned dos_time, time_t *to);
|
||||
#ifdef PHP_WIN32
|
||||
#define timegm _mkgmtime
|
||||
#endif
|
||||
#endif /* PHP_RAR_H */
|
||||
|
||||
|
||||
|
||||
@@ -247,12 +247,12 @@ void minit_rarerror(TSRMLS_D) /* {{{ */
|
||||
zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
||||
#else
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||
zend_ce_exception);
|
||||
zend_exception_get_default(TSRMLS_C));
|
||||
#endif
|
||||
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
||||
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
||||
ZEND_ACC_STATIC TSRMLS_CC);
|
||||
ZEND_ACC_PRIVATE | ZEND_ACC_STATIC TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -313,9 +313,6 @@ void _rar_delete_entries(rar_file_t *rar TSRMLS_DC)
|
||||
if (rar->entries->entries_array != NULL) {
|
||||
size_t i;
|
||||
for (i = 0; i < rar->entries->num_entries; i++) {
|
||||
if (rar->entries->entries_array[i]->entry.RedirName != NULL) {
|
||||
efree(rar->entries->entries_array[i]->entry.RedirName);
|
||||
}
|
||||
efree(rar->entries->entries_array[i]);
|
||||
}
|
||||
efree(rar->entries->entries_array);
|
||||
@@ -356,11 +353,7 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
ents->last_accessed = NULL;
|
||||
|
||||
while (result == 0) {
|
||||
struct _rar_unique_entry *ue;
|
||||
struct RARHeaderDataEx entry = {0};
|
||||
wchar_t redir_name[1024] = L"";
|
||||
entry.RedirName = redir_name;
|
||||
entry.RedirNameSize = sizeof(redir_name) / sizeof(redir_name[0]);
|
||||
result = RARReadHeaderEx(rar->arch_handle, &entry);
|
||||
/* value of 2nd argument is irrelevant in RAR_OM_LIST_[SPLIT] mode */
|
||||
if (result == 0) {
|
||||
@@ -408,22 +401,16 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
assert(capacity > ents->num_entries);
|
||||
|
||||
ents->entries_array[ents->num_entries] = ue =
|
||||
ents->entries_array[ents->num_entries] =
|
||||
emalloc(sizeof *ents->entries_array[0]);
|
||||
memcpy(&ue->entry, &entry, sizeof ents->entries_array[0]->entry);
|
||||
ue->id = ents->num_entries;
|
||||
ue->packed_size = packed_size;
|
||||
memcpy(&ents->entries_array[ents->num_entries]->entry, &entry,
|
||||
sizeof ents->entries_array[0]->entry);
|
||||
ents->entries_array[ents->num_entries]->id = ents->num_entries;
|
||||
ents->entries_array[ents->num_entries]->packed_size = packed_size;
|
||||
_rar_nav_get_depth_and_length(entry.FileNameW,
|
||||
sizeof(entry.FileNameW) / sizeof(entry.FileNameW[0]), /* = 1024 */
|
||||
&ue->depth, &ue->name_wlen TSRMLS_CC);
|
||||
if (redir_name[0] != L'\0') {
|
||||
size_t size = (wcslen(redir_name) + 1) * sizeof(redir_name[0]);
|
||||
ue->entry.RedirName = emalloc(size);
|
||||
memcpy(ue->entry.RedirName, redir_name, size);
|
||||
} else {
|
||||
ue->entry.RedirName = NULL;
|
||||
ue->entry.RedirNameSize = 0;
|
||||
}
|
||||
&ents->entries_array[ents->num_entries]->depth,
|
||||
&ents->entries_array[ents->num_entries]->name_wlen TSRMLS_CC);
|
||||
ents->num_entries++;
|
||||
}
|
||||
|
||||
|
||||
163
rar_stream.c
163
rar_stream.c
@@ -41,6 +41,7 @@ extern "C" {
|
||||
#include <wchar.h>
|
||||
|
||||
#include "php_rar.h"
|
||||
#include "unrar/rartypes.hpp"
|
||||
|
||||
#include <php_streams.h>
|
||||
#include <ext/standard/url.h>
|
||||
@@ -51,11 +52,10 @@ 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_read_size; /* content size */
|
||||
size_t buffer_cont_size; /* content size */
|
||||
size_t buffer_pos;
|
||||
uint64 cursor;
|
||||
int no_more_data;
|
||||
@@ -99,11 +99,7 @@ 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
|
||||
@@ -118,12 +114,12 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
while (left > 0) {
|
||||
size_t this_read_size;
|
||||
/* if nothing in the buffer or buffer already read, fill buffer */
|
||||
if (/*self->buffer_read_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_read_size)
|
||||
if (/*self->buffer_cont_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_cont_size)
|
||||
{
|
||||
int res;
|
||||
self->buffer_pos = 0;
|
||||
self->buffer_read_size = 0;
|
||||
self->buffer_cont_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
|
||||
@@ -133,25 +129,25 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
if (self->no_more_data)
|
||||
break;
|
||||
res = RARProcessFileChunk(self->rar_handle, self->buffer,
|
||||
self->buffer_size, &self->buffer_read_size,
|
||||
self->buffer_size, &self->buffer_cont_size,
|
||||
&self->no_more_data);
|
||||
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
||||
break; /* finish in case of failure */
|
||||
}
|
||||
assert(self->buffer_read_size <= self->buffer_size);
|
||||
assert(self->buffer_cont_size <= self->buffer_size);
|
||||
/* we did not read anything. no need to continue */
|
||||
if (self->buffer_read_size == 0)
|
||||
if (self->buffer_cont_size == 0)
|
||||
break;
|
||||
}
|
||||
/* if we get here we have data to be read in the buffer */
|
||||
this_read_size = MIN(left,
|
||||
self->buffer_read_size - self->buffer_pos);
|
||||
self->buffer_cont_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);
|
||||
}
|
||||
|
||||
@@ -160,16 +156,9 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
|
||||
/* no more data upstream (for sure), buffer already read and
|
||||
* caller asked for more data than we're giving */
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_read_size &&
|
||||
n < count && stream->eof != 1) {
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_cont_size &&
|
||||
((size_t) n) < count)
|
||||
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: %lu 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) {
|
||||
@@ -179,29 +168,17 @@ static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
stream->eof = 1;
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 50400
|
||||
return n;
|
||||
#else
|
||||
return (ssize_t) n;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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;
|
||||
@@ -303,6 +280,43 @@ static mode_t _rar_convert_file_attrs(unsigned os_attrs,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _rar_time_convert(unsigned low, unsigned high, time_t *to) /* {{{ */
|
||||
{
|
||||
time_t default_ = (time_t) 0,
|
||||
local_time;
|
||||
struct tm tm = {0};
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (high == 0U && low == 0U) {
|
||||
*to = default_;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970. */
|
||||
uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
|
||||
|
||||
/* value is in 10^-7 seconds since 01-01-1601 */
|
||||
/* convert to nanoseconds, shift to 01-01-1970 and convert to seconds */
|
||||
local_time = (time_t) ((INT32TO64(high, low) * 100 - ushift) / 1000000000);
|
||||
|
||||
/* now we have the time in... I don't know what. It gives UTC - tz offset */
|
||||
/* we need to try and convert it to UTC */
|
||||
/* abuse gmtime, which is supposed to work with UTC */
|
||||
#ifndef PHP_WIN32
|
||||
if (gmtime_r(&local_time, &tm) == NULL) {
|
||||
#else
|
||||
if (gmtime_s(&tm, &local_time) != 0) {
|
||||
#endif
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not convert time to UTC, using local time");
|
||||
*to = local_time;
|
||||
}
|
||||
|
||||
tm.tm_isdst = -1;
|
||||
*to = local_time + (local_time - mktime(&tm));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
php_stream_statbuf *ssb) /* {{{ */
|
||||
{
|
||||
@@ -317,7 +331,7 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
* SUBHEAD_TYPE_UOWNER), but it is not exposed in unRAR */
|
||||
ssb->sb.st_uid = 0;
|
||||
ssb->sb.st_gid = 0;
|
||||
#if defined(HAVE_ST_RDEV) || defined(HAVE_STRUCT_STAT_ST_RDEV)
|
||||
#ifdef HAVE_ST_RDEV
|
||||
ssb->sb.st_rdev = 0;
|
||||
#endif
|
||||
/* never mind signedness, we'll never get sizes big enough for that to
|
||||
@@ -332,26 +346,34 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
ssb->sb.st_size = (long) (unsigned long) (int64) unp_size;
|
||||
}
|
||||
|
||||
rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
||||
rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
||||
_rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
||||
_rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
||||
|
||||
if (header->MtimeLow == 0 && header->MtimeHigh == 0) {
|
||||
/* high precision mod time undefined */
|
||||
struct tm time_s = {0};
|
||||
time_t time;
|
||||
if (rar_dos_time_convert(header->FileTime, &time) == FAILURE) {
|
||||
unsigned dos_time = header->FileTime;
|
||||
|
||||
time_s.tm_sec = (dos_time & 0x1f)*2;
|
||||
time_s.tm_min = (dos_time>>5) & 0x3f;
|
||||
time_s.tm_hour = (dos_time>>11) & 0x1f;
|
||||
time_s.tm_mday = (dos_time>>16) & 0x1f;
|
||||
time_s.tm_mon = ((dos_time>>21) & 0x0f) - 1;
|
||||
time_s.tm_year = (dos_time>>25) + 80;
|
||||
if ((time = mktime(&time_s)) == -1)
|
||||
return FAILURE;
|
||||
}
|
||||
ssb->sb.st_mtime = time;
|
||||
}
|
||||
else {
|
||||
rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
||||
_rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
||||
&ssb->sb.st_mtime);
|
||||
}
|
||||
|
||||
#if defined(HAVE_ST_BLKSIZE) || defined(HAVE_STRUCT_STAT_ST_BLKSIZE)
|
||||
#ifdef HAVE_ST_BLKSIZE
|
||||
ssb->sb.st_blksize = 0;
|
||||
#endif
|
||||
#if defined(HAVE_ST_BLOCKS) || defined (HAVE_STRUCT_STAT_ST_BLOCKS)
|
||||
#ifdef HAVE_ST_BLOCKS
|
||||
ssb->sb.st_blocks = 0;
|
||||
#endif
|
||||
/* php_stat in filestat.c doesn't check this one, so don't touch it */
|
||||
@@ -387,32 +409,19 @@ static php_stream_ops php_stream_rario_ops = {
|
||||
/* {{{ RAR directory streams */
|
||||
|
||||
/* {{{ 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;
|
||||
size_t offset;
|
||||
int offset;
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
if (count != sizeof(entry)) {
|
||||
#if PHP_VERSION_ID < 70400
|
||||
if (count != sizeof(entry))
|
||||
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 */
|
||||
@@ -468,11 +477,7 @@ 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
|
||||
|
||||
@@ -549,18 +554,16 @@ 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 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);
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
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");
|
||||
@@ -784,13 +787,7 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
|
||||
#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 {
|
||||
@@ -958,23 +955,21 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
|
||||
{
|
||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||
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);
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
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);
|
||||
@@ -1078,7 +1073,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
int res;
|
||||
const char *err_str;
|
||||
|
||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
@@ -1102,7 +1097,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_zv_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_ex(rar_obj, rar, 1 TSRMLS_CC) == FAILURE) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
goto cleanup;
|
||||
|
||||
63
rar_time.c
63
rar_time.c
@@ -1,63 +0,0 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <php.h>
|
||||
#include "php_rar.h"
|
||||
|
||||
void rar_time_convert(unsigned low, unsigned high, time_t *to) /* {{{ */
|
||||
{
|
||||
time_t default_ = (time_t) 0,
|
||||
local_time;
|
||||
struct tm tm = {0};
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (high == 0U && low == 0U) {
|
||||
*to = default_;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970. */
|
||||
uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
|
||||
|
||||
/* value is in 10^-7 seconds since 01-01-1601 */
|
||||
/* convert to nanoseconds, shift to 01-01-1970 and convert to seconds */
|
||||
local_time = (time_t) ((INT32TO64(high, low) * 100 - ushift) / 1000000000);
|
||||
|
||||
/* now we have the time in... I don't know what. It gives UTC - tz offset */
|
||||
/* we need to try and convert it to UTC */
|
||||
/* abuse gmtime, which is supposed to work with UTC */
|
||||
if (php_gmtime_r(&local_time, &tm) == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not convert time to UTC, using local time");
|
||||
*to = local_time;
|
||||
}
|
||||
|
||||
tm.tm_isdst = -1;
|
||||
*to = local_time + (local_time - mktime(&tm));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
int rar_dos_time_convert(unsigned dos_time, time_t *to) /* {{{ */
|
||||
{
|
||||
struct tm time_s = {0};
|
||||
|
||||
time_s.tm_sec = (dos_time & 0x1f)*2;
|
||||
time_s.tm_min = (dos_time>>5) & 0x3f;
|
||||
time_s.tm_hour = (dos_time>>11) & 0x1f;
|
||||
time_s.tm_mday = (dos_time>>16) & 0x1f;
|
||||
time_s.tm_mon = ((dos_time>>21) & 0x0f) - 1;
|
||||
time_s.tm_year = (dos_time>>25) + 80;
|
||||
/* the dos times that unrar gives out seem to be already in UTC.
|
||||
* Or at least they don't depend on TZ */
|
||||
if ((*to = timegm(&time_s)) == (time_t) -1) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
287
rararch.c
287
rararch.c
@@ -27,22 +27,17 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "zend_types.h"
|
||||
#include <zend_API.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
#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 */
|
||||
typedef struct _ze_rararch_object {
|
||||
@@ -92,53 +87,35 @@ static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC);
|
||||
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
|
||||
#define rararch_object_from_ref(ref) zend_object_store_get_object_by_handle((ref) TSRMLS_CC)
|
||||
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(handler_this_t *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, long *index, int quiet TSRMLS_DC);
|
||||
static int rararch_count_elements(handler_this_t *object, long *count 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(handler_this_t *object, zval *offset, int type, zval *rv);
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv);
|
||||
#endif
|
||||
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);
|
||||
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
|
||||
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Function definitions with external linkage */
|
||||
int _rar_get_file_resource_zv(zval *zv, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
||||
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);
|
||||
return _rar_get_file_resource_ex(zval_file, rar_file, FALSE 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,
|
||||
@@ -204,21 +181,20 @@ 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_zv. */
|
||||
* to NULL. This is checked by _rar_get_file_resource. */
|
||||
RARCloseArchive(rar->arch_handle);
|
||||
rar->arch_handle = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Receives archive zval, returns object struct.
|
||||
* If allow_closed is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* If silent is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* is, an exception/error is raised and FAILURE is returned
|
||||
*/
|
||||
int _rar_get_file_resource_ex(rar_obj_ref zobjref_file, rar_file_t **rar_file,
|
||||
int allow_closed TSRMLS_DC) /* {{{ */
|
||||
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_rararch_object *zobj;
|
||||
zobj = rararch_object_from_ref(zobjref_file);
|
||||
zobj = rararch_object_from_zv(zval_file TSRMLS_CC);
|
||||
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.");
|
||||
@@ -226,7 +202,7 @@ int _rar_get_file_resource_ex(rar_obj_ref zobjref_file, rar_file_t **rar_file,
|
||||
}
|
||||
|
||||
*rar_file = zobj->rar_file;
|
||||
if ((*rar_file)->arch_handle == NULL && !allow_closed) { /* rar_close was called */
|
||||
if ((*rar_file)->arch_handle == NULL && !silent) { /* rar_close was called */
|
||||
_rar_handle_ext_error("The archive is already closed" TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -313,10 +289,6 @@ static ze_rararch_object *rararch_object_from_zv(const zval *zv)
|
||||
{
|
||||
return rararch_object_fetch(Z_OBJ_P(zv));
|
||||
}
|
||||
static ze_rararch_object *rararch_object_from_ref(const rar_obj_ref ref)
|
||||
{
|
||||
return rararch_object_fetch(ref);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* {{{ */
|
||||
@@ -401,12 +373,11 @@ static void rararch_ce_free_object_storage(zend_object *zobj)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive handlers */
|
||||
static int rararch_handlers_preamble(handler_this_t *object,
|
||||
rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
/* don't call zend_objects_get_address or zend_object_store_get directly;
|
||||
* _rar_get_file_resource_zv checks if the archive was closed */
|
||||
if (_rar_get_file_resource_handler(object, rar TSRMLS_CC) == FAILURE) {
|
||||
* _rar_get_file_resource checks if the archive was closed */
|
||||
if (_rar_get_file_resource(object, rar TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -444,7 +415,7 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
return FAILURE;
|
||||
}
|
||||
else if (type == IS_DOUBLE) {
|
||||
if (d > (double) LONG_MAX || d < (double) LONG_MIN) {
|
||||
if (d > LONG_MAX || d < LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
@@ -454,8 +425,7 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
}
|
||||
}
|
||||
else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
if (Z_DVAL_P(offset) > (double) LONG_MAX ||
|
||||
Z_DVAL_P(offset) < (double) LONG_MIN) {
|
||||
if (Z_DVAL_P(offset) > LONG_MAX || Z_DVAL_P(offset) < LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
@@ -463,17 +433,16 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
*index = (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
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset TSRMLS_CC);
|
||||
# else
|
||||
#else
|
||||
zval zv_holder;
|
||||
ZVAL_NULL(&zv_holder);
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset, &zv_holder);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* get handler cannot return NULL */
|
||||
assert(newoffset != NULL);
|
||||
@@ -486,32 +455,12 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
|
||||
ret = rararch_dimensions_preamble(rar, newoffset, index, quiet
|
||||
TSRMLS_CC);
|
||||
# if PHP_MAJOR_VERSION < 7
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&newoffset);
|
||||
# else
|
||||
#else
|
||||
zval_ptr_dtor(newoffset);
|
||||
# endif
|
||||
#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,
|
||||
@@ -544,8 +493,7 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive count_elements handler */
|
||||
|
||||
static int rararch_count_elements(zend_object *object, zend_long *count TSRMLS_DC)
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||
{
|
||||
rar_file_t *rar = NULL;
|
||||
size_t entry_count;
|
||||
@@ -556,10 +504,10 @@ static int rararch_count_elements(zend_object *object, zend_long *count TSRMLS_D
|
||||
}
|
||||
|
||||
entry_count = _rar_entry_count(rar);
|
||||
if (entry_count > ZEND_LONG_MAX)
|
||||
entry_count = ZEND_LONG_MAX;
|
||||
if (entry_count > LONG_MAX)
|
||||
entry_count = (size_t) LONG_MAX;
|
||||
|
||||
*count = (zend_long) entry_count;
|
||||
*count = (long) entry_count;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -569,7 +517,7 @@ static int rararch_count_elements(zend_object *object, zend_long *count TSRMLS_D
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
#else
|
||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv)
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv)
|
||||
#endif
|
||||
{
|
||||
long index;
|
||||
@@ -598,16 +546,8 @@ static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int ty
|
||||
#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);
|
||||
#endif
|
||||
_rar_entry_search_end(out);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_DELREF_P(ret); /* set refcount to 0 */
|
||||
@@ -617,7 +557,7 @@ static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int ty
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive write_dimension handler */
|
||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC)
|
||||
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -625,7 +565,7 @@ static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive has_dimension handler */
|
||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
{
|
||||
long index;
|
||||
rar_file_t *rar = NULL;
|
||||
@@ -642,7 +582,7 @@ static int rararch_has_dimension(handler_this_t *object, zval *offset, int check
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive unset_dimension handler */
|
||||
static void rararch_unset_dimension(handler_this_t *object, zval *offset TSRMLS_DC)
|
||||
static void rararch_unset_dimension(zval *object, zval *offset TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -721,7 +661,7 @@ PHP_FUNCTION(rar_list)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -756,7 +696,7 @@ PHP_FUNCTION(rar_entry_get)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -793,7 +733,7 @@ PHP_FUNCTION(rar_solid_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -811,7 +751,7 @@ PHP_FUNCTION(rar_comment_get)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -842,7 +782,7 @@ PHP_FUNCTION(rar_broken_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -873,7 +813,7 @@ PHP_FUNCTION(rar_allow_broken_set)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -891,7 +831,7 @@ PHP_FUNCTION(rar_close)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -915,8 +855,7 @@ PHP_METHOD(rararch, __toString)
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
if (_rar_get_file_resource_zv_ex(arch_obj, &rar, TRUE TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
if (_rar_get_file_resource_ex(arch_obj, &rar, TRUE TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE; /* should never happen */
|
||||
}
|
||||
|
||||
@@ -937,18 +876,6 @@ PHP_METHOD(rararch, __toString)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string RarEntry::getIterator() */
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
PHP_METHOD(rararch, getIterator)
|
||||
{
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
zend_create_internal_iterator_zval(return_value, getThis());
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ arginfo */
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_open, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, filename)
|
||||
@@ -964,20 +891,8 @@ 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
|
||||
/* }}} */
|
||||
|
||||
static zend_function_entry php_rararch_class_functions[] = {
|
||||
@@ -992,11 +907,8 @@ 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_tostring, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rararch, __toString, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rararchive_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
PHP_ME(rararch, getIterator, arginfo_rararchive_getiterator, ZEND_ACC_PUBLIC)
|
||||
#endif
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -1020,6 +932,55 @@ 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)
|
||||
{
|
||||
@@ -1085,7 +1046,7 @@ static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC)
|
||||
robj = &it->parent.data;
|
||||
#endif
|
||||
|
||||
res = _rar_get_file_resource_zv_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||
res = _rar_get_file_resource_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||
if (res == FAILURE)
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"Cannot fetch RarArchive object");
|
||||
@@ -1138,8 +1099,13 @@ static void rararch_it_current_data(zend_object_iterator *iter,
|
||||
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
|
||||
@@ -1181,61 +1147,6 @@ static zend_object_iterator_funcs rararch_it_funcs = {
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_get_iterator */
|
||||
static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
zval *object,
|
||||
int by_ref TSRMLS_DC)
|
||||
{
|
||||
rar_file_t *rar;
|
||||
int res;
|
||||
|
||||
if (by_ref) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"An iterator cannot be used with foreach by reference");
|
||||
}
|
||||
|
||||
res = _rar_get_file_resource_zv_ex(object, &rar, 1 TSRMLS_CC);
|
||||
if (res == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"Cannot fetch RarArchive object");
|
||||
}
|
||||
if (rar->arch_handle == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"The archive is already closed, cannot give an iterator");
|
||||
}
|
||||
|
||||
rararch_iterator *it = emalloc(sizeof *it);
|
||||
|
||||
#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
|
||||
|
||||
#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;
|
||||
@@ -1259,14 +1170,8 @@ 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;
|
||||
#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
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
127
rarentry.c
127
rarentry.c
@@ -27,10 +27,11 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <zend_types.h>
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
#include <php.h>
|
||||
@@ -45,7 +46,7 @@ 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);
|
||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC);
|
||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string);
|
||||
static void _rar_dos_date_to_text(int dos_time, char *date_string);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Functions with external linkage */
|
||||
@@ -57,19 +58,14 @@ void _rar_entry_to_zval(zval *parent,
|
||||
struct RARHeaderDataEx *entry,
|
||||
unsigned long 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;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zend_long unp_size; /* zval stores PHP ints as zend_long, so use that here */
|
||||
#else
|
||||
long unp_size; /* zval stores PHP ints as long, so use that here */
|
||||
#endif
|
||||
zval *parent_copy = parent;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
/* allocate zval on the heap */
|
||||
@@ -80,18 +76,10 @@ void _rar_entry_to_zval(zval *parent,
|
||||
#endif
|
||||
|
||||
object_init_ex(object, rar_class_entry_ptr);
|
||||
#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",
|
||||
zend_update_property(rar_class_entry_ptr, object, "rarfile",
|
||||
sizeof("rararch") - 1, parent_copy TSRMLS_CC);
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7 && ZEND_ENABLE_ZVAL_LONG64
|
||||
unp_size = ((zend_long) entry->UnpSize) + (((zend_long) entry->UnpSizeHigh) << 32);
|
||||
#elif PHP_MAJOR_VERSION < 7 && ULONG_MAX > 0xffffffffUL
|
||||
#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 */
|
||||
@@ -114,42 +102,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, obj, "position",
|
||||
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, obj, "name",
|
||||
zend_update_property_stringl(rar_class_entry_ptr, object, "name",
|
||||
sizeof("name") - 1, filename, filename_len TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "unpacked_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "unpacked_size",
|
||||
sizeof("unpacked_size") - 1, unp_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "packed_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "packed_size",
|
||||
sizeof("packed_size") - 1, packed_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "host_os",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "host_os",
|
||||
sizeof("host_os") - 1, entry->HostOS TSRMLS_CC);
|
||||
|
||||
_rar_dos_date_to_text(entry->FileTime, time);
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "file_time",
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "file_time",
|
||||
sizeof("file_time") - 1, time TSRMLS_CC);
|
||||
|
||||
sprintf(tmp_s, "%x", entry->FileCRC);
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "crc",
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "crc",
|
||||
sizeof("crc") - 1, tmp_s TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "attr",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "attr",
|
||||
sizeof("attr") - 1, entry->FileAttr TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "version",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "version",
|
||||
sizeof("version") - 1, entry->UnpVer TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "method",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "method",
|
||||
sizeof("method") - 1, entry->Method TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "flags",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "flags",
|
||||
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "redir_type",
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "redir_type",
|
||||
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
||||
|
||||
if (entry->RedirName) {
|
||||
char *redir_target = NULL;
|
||||
size_t redir_target_size;
|
||||
|
||||
zend_update_property_bool(rar_class_entry_ptr, obj,
|
||||
zend_update_property_long(rar_class_entry_ptr, object,
|
||||
"redir_to_directory", sizeof("redir_to_directory") - 1,
|
||||
!!entry->DirTarget TSRMLS_CC);
|
||||
|
||||
@@ -158,7 +146,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, obj, "redir_target",
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "redir_target",
|
||||
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
||||
|
||||
efree(redir_target);
|
||||
@@ -207,14 +195,8 @@ 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;
|
||||
@@ -234,12 +216,10 @@ static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TS
|
||||
EG(scope) = rar_class_entry_ptr;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), Z_OBJ_P(entry_obj), name, namelen, 1, &zv);
|
||||
#elif PHP_MAJOR_VERSION >= 7
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
||||
#else
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1 TSRMLS_CC);
|
||||
#else
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
||||
#endif
|
||||
if (tmp == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
@@ -254,29 +234,24 @@ static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TS
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string) /* {{{ */
|
||||
static void _rar_dos_date_to_text(int dos_time, char *date_string) /* {{{ */
|
||||
{
|
||||
time_t time = 0;
|
||||
struct tm tm = {0};
|
||||
int res;
|
||||
|
||||
res = rar_dos_time_convert(dos_time, &time) != FAILURE &&
|
||||
php_gmtime_r(&time, &tm) != NULL;
|
||||
|
||||
if (!res) {
|
||||
sprintf(date_string, "%s", "time conversion failure");
|
||||
}
|
||||
|
||||
sprintf(date_string, "%u-%02u-%02u %02u:%02u:%02u",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
|
||||
tm.tm_sec);
|
||||
int second, minute, hour, day, month, year;
|
||||
/* following lines were taken from timefn.cpp */
|
||||
second = (dos_time & 0x1f)*2;
|
||||
minute = (dos_time>>5) & 0x3f;
|
||||
hour = (dos_time>>11) & 0x1f;
|
||||
day = (dos_time>>16) & 0x1f;
|
||||
month = (dos_time>>21) & 0x0f;
|
||||
year = (dos_time>>25)+1980;
|
||||
sprintf(date_string, "%u-%02u-%02u %02u:%02u:%02u", year, month, day, hour, minute, second);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Methods */
|
||||
/* {{{ public function extract(?string $dir, ?string $filepath = '',
|
||||
?string $password = null, bool $extended_data = false): void {}
|
||||
/* {{{ proto bool RarEntry::extract(string dir [, string filepath = ''
|
||||
[, string password = NULL [, bool extended_data = FALSE]])
|
||||
Extract file from the archive */
|
||||
PHP_METHOD(rarentry, extract)
|
||||
{ /* lots of variables, but no need to be intimidated */
|
||||
@@ -303,14 +278,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!|s!s!b", &dir,
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss!b", &dir,
|
||||
&dir_len, &filepath, &filepath_len, &password, &password_len,
|
||||
&process_ed) == FAILURE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -564,7 +539,7 @@ PHP_METHOD(rarentry, getStream)
|
||||
|
||||
RAR_GET_PROPERTY(position, "position");
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -719,21 +694,12 @@ 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)
|
||||
@@ -741,13 +707,6 @@ 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
|
||||
/* }}} */
|
||||
|
||||
static zend_function_entry php_rar_class_functions[] = {
|
||||
@@ -768,7 +727,7 @@ 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_tostring, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, __toString, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
@@ -850,3 +809,7 @@ void minit_rarentry(TSRMLS_D)
|
||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SYM_LINK", 0x0A000L);
|
||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SOCKET", 0x0C000L);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
3811
run-tests8.php
3811
run-tests8.php
File diff suppressed because it is too large
Load Diff
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
JOBS=3
|
||||
|
||||
function package_name {
|
||||
local readonly version=$1 zts=$2
|
||||
local zts_suffix=''
|
||||
if [[ $zts = 'true' ]]; then
|
||||
zts_suffix='-zts'
|
||||
fi
|
||||
|
||||
echo "php-${version}${zts_suffix}-bare-dbg"
|
||||
}
|
||||
|
||||
function prefix {
|
||||
local readonly version=$1 zts=$2
|
||||
|
||||
echo "/opt/$(package_name $version $zts)"
|
||||
}
|
||||
|
||||
function build_ext {
|
||||
local readonly version=$1 zts=$2 coverage=$3
|
||||
local readonly prefix=$(prefix $1 $2)
|
||||
local cflags= cxxflags= ldflags=
|
||||
"$prefix"/bin/phpize
|
||||
if [[ $coverage == true ]]; then
|
||||
cflags=--coverage
|
||||
cxxflags=--coverage
|
||||
ldflags=--coverage
|
||||
fi
|
||||
CFLAGS="$cflags" CXXFLAGS="$cxxflags" LDFLAGS="$ldflags" \
|
||||
./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)"
|
||||
local ret=0
|
||||
sed -i s/-@if/@if/ Makefile
|
||||
TEST_PHP_EXECUTABLE="$prefix/bin/php" \
|
||||
TEST_PHP_JUNIT=report.xml \
|
||||
REPORT_EXIT_STATUS=1 \
|
||||
NO_INTERACTION=1 \
|
||||
TESTS="--set-timeout 300 --show-diff $RUN_TESTS_FLAGS" make test \
|
||||
|| ret=$?
|
||||
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 {} \;
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
function install_php {
|
||||
local readonly version=$1 zts=$2
|
||||
local readonly url="$MIRROR/php-$version.tar.gz"
|
||||
|
||||
sudo apt-get install -y gnupg
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 5D98E7264E3F3D89463B314B12229434A9F003C9
|
||||
echo deb [arch=amd64] http://artefacto-test.s3.amazonaws.com/php-bare-dbg bionic main | sudo tee -a /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y $(package_name $version $zts)
|
||||
}
|
||||
|
||||
function run_tests {
|
||||
set -e
|
||||
set -o pipefail
|
||||
do_tests "$(prefix $1 $2)"
|
||||
}
|
||||
@@ -5,7 +5,6 @@ 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);
|
||||
@@ -15,7 +14,8 @@ $list2 = rar_list($rar_file2);
|
||||
var_dump($list2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
argerr(function() use ($rar_file3) { rar_list($rar_file3); });
|
||||
$list3 = rar_list($rar_file3);
|
||||
var_dump($list3);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -163,5 +163,6 @@ 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, %s given in %s on line %d
|
||||
Warning: rar_list() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
Done
|
||||
|
||||
@@ -5,7 +5,6 @@ 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);
|
||||
@@ -15,9 +14,8 @@ $entry2 = rar_entry_get($rar_file2, '2.txt');
|
||||
var_dump($entry2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
argerr(function() use ($rar_file3) {
|
||||
rar_entry_get($rar_file3, '2.txt');
|
||||
});
|
||||
$entry3 = rar_entry_get($rar_file3, '2.txt');
|
||||
var_dump($entry3);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -91,5 +89,6 @@ object(RarEntry)#%d (%d) {
|
||||
|
||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
Done
|
||||
|
||||
@@ -5,8 +5,6 @@ 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";
|
||||
@@ -15,9 +13,8 @@ var_dump($entry);
|
||||
echo "\n";
|
||||
|
||||
$rar_file2 = rar_open(dirname(__FILE__).'/nonexistent.rar');
|
||||
argerr(function() use ($rar_file2) {
|
||||
rar_entry_get($rar_file2, "file1.txt");
|
||||
});
|
||||
$entry = rar_entry_get($rar_file2, "file1.txt");
|
||||
var_dump($entry);
|
||||
echo "\n";
|
||||
|
||||
echo "Done\n";
|
||||
@@ -31,6 +28,7 @@ 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, %s given in %s on line %d
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
|
||||
Done
|
||||
|
||||
@@ -9,6 +9,10 @@ $rar_file1 = rar_open(dirname(__FILE__).'/multi.part1.rar');
|
||||
$entries = rar_list($rar_file1);
|
||||
echo count($entries)." files:\n\n";
|
||||
//var_dump($entries);
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
foreach ($entries as $e) {
|
||||
$stream = $e->getStream();
|
||||
if ($stream === false) {
|
||||
@@ -21,7 +25,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -9,6 +9,10 @@ $rar_file1 = rar_open(dirname(__FILE__).'/store_method.rar');
|
||||
$entries = rar_list($rar_file1);
|
||||
echo count($entries)." files:\n\n";
|
||||
//var_dump($entries);
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
foreach ($entries as $e) {
|
||||
$stream = $e->getStream();
|
||||
echo $e->getName().": ";
|
||||
@@ -17,7 +21,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 512);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -9,6 +9,10 @@ $rar_file1 = rar_open(dirname(__FILE__).'/solid.rar');
|
||||
$entries = rar_list($rar_file1);
|
||||
echo count($entries)." files:\n\n";
|
||||
//var_dump($entries);
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
foreach ($entries as $e) {
|
||||
$stream = $e->getStream();
|
||||
echo $e->getName().": ";
|
||||
@@ -17,7 +21,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -4,9 +4,6 @@ RarArchive get iterator on closed file
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
$rarF = RarArchive::open(dirname(__FILE__) . '/latest_winrar.rar');
|
||||
$rarF->close();
|
||||
foreach ($rarF as $k => $rarE) {
|
||||
|
||||
@@ -7,9 +7,9 @@ if(!extension_loaded("rar")) die("skip");
|
||||
<?php
|
||||
chdir(dirname(__FILE__));
|
||||
function volume_callback($vol) {
|
||||
if (strpos($vol, '_fail') !== false)
|
||||
if (preg_match('/_fail/', $vol))
|
||||
$ret = basename(str_replace('_fail', '', $vol));
|
||||
elseif (strpos($vol, '_broken') !== false)
|
||||
elseif (preg_match('/_broken/', $vol))
|
||||
$ret = basename(str_replace('_broken', '_fail', $vol));
|
||||
else
|
||||
$ret = null;
|
||||
|
||||
@@ -5,7 +5,6 @@ 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) {
|
||||
@@ -31,15 +30,11 @@ var_dump($rar);
|
||||
|
||||
echo "\nGiven callback that takes more arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'strpos');
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
$rar->getEntries();
|
||||
|
||||
echo "\nGiven callback that takes another kind of arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'array_keys');
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
$rar->getEntries();
|
||||
|
||||
echo "\nGiven callback that returns another kind of arguments:\n";
|
||||
function testA($vol) { return true; }
|
||||
@@ -57,7 +52,7 @@ try {
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF_DYNAMIC--
|
||||
--EXPECTF--
|
||||
Not given a callback:
|
||||
|
||||
Warning: RarArchive::open(): Expected the third argument, if provided, to be a valid callback in %s on line %d
|
||||
@@ -69,33 +64,15 @@ 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:
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ function resolve($vol) {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar', null, 'resolve');
|
||||
foreach ($rar_file1 as $e) {
|
||||
$stream = $e->getStream();
|
||||
@@ -19,7 +23,7 @@ foreach ($rar_file1 as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -10,6 +10,10 @@ function resolve($vol) {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
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');
|
||||
$entry = $rar_file1->getEntry('file2.txt');
|
||||
@@ -18,7 +22,7 @@ echo "\nSuccess:\n";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar', null, 'resolve');
|
||||
$entry = $rar_file1->getEntry('file2.txt');
|
||||
$entry->extract(null, dirname(__FILE__) . "/temp_file2.txt");
|
||||
echo strtoupper(hash("crc32b", file_get_contents(dirname(__FILE__) . "/temp_file2.txt")));
|
||||
echo int32_to_hex(crc32(file_get_contents(dirname(__FILE__) . "/temp_file2.txt")));
|
||||
echo "\n";
|
||||
echo "Done\n";
|
||||
?>
|
||||
|
||||
@@ -50,11 +50,11 @@ string(5) "11111"
|
||||
Test with include path:
|
||||
Should fail (not in include):
|
||||
|
||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Should fail (include unused):
|
||||
|
||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Should succeed:
|
||||
string(5) "11111"
|
||||
|
||||
@@ -20,9 +20,9 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Archive not found :
|
||||
|
||||
Warning: fopen(rar://%snot_found.rar#1.txt): %cailed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://%snot_found.rar#1.txt): failed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
File not found :
|
||||
|
||||
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.
|
||||
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.
|
||||
@@ -27,21 +27,21 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Test empty:
|
||||
|
||||
Warning: fopen(rar://): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no fragment:
|
||||
|
||||
Warning: fopen(rar://file.rar): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://file.rar): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test empty fragment:
|
||||
|
||||
Warning: fopen(rar://file.rar#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://file.rar#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no path:
|
||||
|
||||
Warning: fopen(rar://#frag): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://#frag): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no path and empty fragment:
|
||||
|
||||
Warning: fopen(rar://#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Done.
|
||||
|
||||
@@ -55,11 +55,11 @@ echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
Headers: should not work (no password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Headers: should not work (password given was file_password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Headers: should work (password given was open_password):
|
||||
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): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Files: should not work (password given was open_password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Files: should work (password given was file_password):
|
||||
string(26) "Encrypted file 1 contents."
|
||||
|
||||
@@ -11,13 +11,17 @@ function resolve($vol) {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
function int32_to_hex($value) {
|
||||
$value &= 0xffffffff;
|
||||
return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
|
||||
}
|
||||
$stream = fopen("rar://" .
|
||||
dirname(__FILE__) . '/multi_broken.part1.rar' .
|
||||
"#file2.txt", "r", false,
|
||||
stream_context_create(array('rar'=>array('volume_callback'=>'resolve'))));
|
||||
$a = stream_get_contents($stream);
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
17704 bytes, CRC F2C79881
|
||||
|
||||
@@ -12,6 +12,6 @@ var_dump(opendir($u));
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
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
|
||||
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
|
||||
bool(false)
|
||||
Done.
|
||||
|
||||
@@ -4,7 +4,6 @@ RarArchive direct instantiation does not crash (PHP 5.x)
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID >= 70000) die("skip for PHP 5.x");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7');
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ 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");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7');
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -48,12 +48,12 @@ Count: 13
|
||||
|
||||
* Closed file test (1):
|
||||
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
Warning: count(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (2):
|
||||
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
Warning: count(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (3, exceptions):
|
||||
|
||||
@@ -15,12 +15,10 @@ echo "string (\"0.001\"). {$a['0.001']}\n";
|
||||
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF_DYNAMIC--
|
||||
--EXPECTF--
|
||||
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_DYNAMIC--
|
||||
--EXPECTF--
|
||||
* -1 (int):
|
||||
|
||||
Warning: main(): Dimension index must be non-negative, given -1 in %s on line %d
|
||||
@@ -81,11 +81,6 @@ Warning: main(): Attempt to use a non-numeric dimension to access a RarArchive o
|
||||
|
||||
* new stdClass():
|
||||
|
||||
<?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
|
||||
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 } 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,15 +1,9 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?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');
|
||||
?>
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -4,9 +4,6 @@ RarArchive read_property gives a fatal error on a write context
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?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')
|
||||
?>
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -4,9 +4,6 @@ RarArchive unset_property gives a fatal error
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -5,18 +5,13 @@ 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);
|
||||
argerr(function() use ($a) {
|
||||
$a->isBroken("jjj");
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_broken_is($a, "jjj");
|
||||
});
|
||||
var_dump($a->isBroken("jjj"));
|
||||
var_dump(rar_broken_is($a, "jjj"));
|
||||
|
||||
echo "\n* unbroken file; as first call\n";
|
||||
var_dump($a->isBroken());
|
||||
@@ -51,8 +46,10 @@ 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,18 +5,13 @@ 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');
|
||||
argerr(function() use ($a) {
|
||||
$a->setAllowBroken();
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_allow_broken_set($a);
|
||||
});
|
||||
$a->setAllowBroken();
|
||||
rar_allow_broken_set($a);
|
||||
|
||||
echo "\n* broken file; do not allow broken (default)\n";
|
||||
$a = RarArchive::open($b, null, 'retnull');
|
||||
@@ -59,7 +54,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: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; do not allow broken (explicit)
|
||||
@@ -67,7 +62,7 @@ int(0)
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; allow broken
|
||||
|
||||
@@ -4,9 +4,6 @@ Traversal of RarArchive with foreach by reference gives error
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -5,7 +5,6 @@ Wrapper cache exaustion test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$f = array();
|
||||
$f[] = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$f[] = dirname(__FILE__) . "/directories.rar";
|
||||
@@ -19,9 +18,7 @@ function printstats() {
|
||||
}
|
||||
|
||||
echo "* Invalid call to rar_wrapper_cache_stats():\n";
|
||||
argerr(function() {
|
||||
rar_wrapper_cache_stats("sfddf");
|
||||
});
|
||||
var_dump(rar_wrapper_cache_stats("sfddf"));
|
||||
|
||||
echo "\n* Initial stats:\n";
|
||||
printstats();
|
||||
@@ -78,6 +75,7 @@ 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,9 +10,7 @@ phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
//normalize line endings
|
||||
$phpinfo = str_replace("\r\n", "\n", $phpinfo);
|
||||
$phpinfo = str_replace("\r", "\n", $phpinfo);
|
||||
$phpinfo = preg_replace('/\r\n?/', "\n", $phpinfo); //normalize line endings
|
||||
|
||||
$phpinfo = explode("\n", $phpinfo);
|
||||
|
||||
|
||||
@@ -16,10 +16,7 @@ foreach ($rar as $rar_file) {
|
||||
|
||||
echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
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)
|
||||
int(2279)
|
||||
int(1316)
|
||||
|
||||
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.
|
||||
Done.
|
||||
@@ -32,6 +32,6 @@ opened
|
||||
|
||||
Testing 'r+'
|
||||
|
||||
Warning: fopen(%s): %cailed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
Warning: fopen(%s): failed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
|
||||
Done.
|
||||
|
||||
@@ -3,7 +3,6 @@ Supports version 5 RAR files
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
if (isset($_ENV['APPVEYOR'])) die("skip failing on appveyor");
|
||||
if ($_ENV['RUNNER_OS'] === 'Windows') die("skip failing on Windows runner on GitHub Action");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
@@ -39,7 +38,7 @@ object(RarEntry)#%d (%d) {
|
||||
["attr%sprivate%s=>
|
||||
int(33261)
|
||||
["version%sprivate%s=>
|
||||
int(50)
|
||||
int(200)
|
||||
["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 %s in %s:%d
|
||||
Fatal error: Uncaught Error: Call to private RarArchive::__construct() from invalid context 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 %s in %s:%d
|
||||
Fatal error: Uncaught Error: Call to private RarEntry::__construct() from invalid context in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
Redirection functions
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$m = array(
|
||||
RarEntry::FSREDIR_UNIXSYMLINK => 'FSREDIR_UNIXSYMLINK',
|
||||
RarEntry::FSREDIR_WINSYMLINK => 'FSREDIR_WINSYMLINK',
|
||||
RarEntry::FSREDIR_JUNCTION => 'FSREDIR_JUNCTION',
|
||||
RarEntry::FSREDIR_HARDLINK => 'FSREDIR_HARDLINK',
|
||||
RarEntry::FSREDIR_FILECOPY => 'FSREDIR_FILECOPY',
|
||||
);
|
||||
$a = rar_open(dirname(__FILE__) . '/rar5-links.rar');
|
||||
$i = 0;
|
||||
foreach ($a as $e) {
|
||||
if ($i++ != 0) echo "\n";
|
||||
echo "$i. ", $e->getName(), "\n";
|
||||
$type = $e->getRedirType();
|
||||
$type = $type ? $m[$type] : $type;
|
||||
echo "redir type: ", var_export($type, true), "\n";
|
||||
echo "redir to dir: ", var_export($e->isRedirectToDirectory(), true), "\n";
|
||||
echo "redir target: ", var_export($e->getRedirTarget(), true), "\n";
|
||||
// break;
|
||||
}
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
1. file1-hardlink.txt
|
||||
redir type: NULL
|
||||
redir to dir: NULL
|
||||
redir target: NULL
|
||||
|
||||
2. file1.txt
|
||||
redir type: 'FSREDIR_HARDLINK'
|
||||
redir to dir: false
|
||||
redir target: 'file1-hardlink.txt'
|
||||
|
||||
3. dir-link
|
||||
redir type: 'FSREDIR_UNIXSYMLINK'
|
||||
redir to dir: true
|
||||
redir target: 'dir'
|
||||
|
||||
4. file1-link.txt
|
||||
redir type: 'FSREDIR_UNIXSYMLINK'
|
||||
redir to dir: false
|
||||
redir target: 'file1.txt'
|
||||
|
||||
5. dir
|
||||
redir type: NULL
|
||||
redir to dir: NULL
|
||||
redir target: NULL
|
||||
Done.
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::getPackedSize()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/4mb.rar');
|
||||
$e = $a->getEntry('4mb.txt');
|
||||
var_dump($e->getPackedSize());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
int(2444)
|
||||
Done.
|
||||
@@ -1,16 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::getHostOs()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/4mb.rar');
|
||||
$e = $a->getEntry('4mb.txt');
|
||||
var_dump($e->getHostOs());
|
||||
var_dump(RarEntry::HOST_WIN32);
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
int(2)
|
||||
int(2)
|
||||
Done.
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::getFileTime()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/4mb.rar');
|
||||
$e = $a->getEntry('4mb.txt');
|
||||
var_dump($e->getFileTime());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
string(19) "2010-05-30 01:22:00"
|
||||
Done.
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::getVersion()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/rar5-links.rar');
|
||||
$e = $a->getEntry('file1.txt');
|
||||
var_dump($e->getVersion());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
int(50)
|
||||
Done.
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::getMethod()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/rar5-links.rar');
|
||||
$e = $a->getEntry('file1.txt');
|
||||
var_dump($e->getMethod());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
int(48)
|
||||
Done.
|
||||
@@ -1,19 +0,0 @@
|
||||
--TEST--
|
||||
RarEntry::isEncrypted()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
$a = rar_open(dirname(__FILE__) . '/rar5-links.rar');
|
||||
$e = $a->getEntry('file1.txt');
|
||||
var_dump($e->isEncrypted());
|
||||
|
||||
$a = rar_open(dirname(__FILE__) . '/encrypted_only_files.rar');
|
||||
$e = $a->getEntry('encfile1.txt');
|
||||
var_dump($e->isEncrypted());
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(true)
|
||||
Done.
|
||||
@@ -1,50 +0,0 @@
|
||||
--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==
|
||||
@@ -1,25 +0,0 @@
|
||||
--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
|
||||
@@ -1,17 +0,0 @@
|
||||
<?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";
|
||||
}
|
||||
}
|
||||
Binary file not shown.
86
travis.sh
Executable file
86
travis.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/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)"
|
||||
}
|
||||
876
unrar/UnRARDll.vcproj
Normal file
876
unrar/UnRARDll.vcproj
Normal file
@@ -0,0 +1,876 @@
|
||||
<?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>
|
||||
@@ -4,17 +4,10 @@ bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
{
|
||||
if (!MainComment)
|
||||
return false;
|
||||
int64 SavePos=Tell();
|
||||
bool Success=DoGetComment(CmtData);
|
||||
Seek(SavePos,SEEK_SET);
|
||||
return Success;
|
||||
}
|
||||
SaveFilePos SavePos(*this);
|
||||
|
||||
|
||||
bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
uint CmtLength;
|
||||
ushort CmtLength;
|
||||
if (Format==RARFMT14)
|
||||
{
|
||||
Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
|
||||
@@ -29,8 +22,7 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
// Old style (RAR 2.9) archive comment embedded into the main
|
||||
// archive header.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
|
||||
if (!ReadHeader() || GetHeaderType()!=HEAD3_CMT)
|
||||
return false;
|
||||
ReadHeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -41,7 +33,7 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
#ifndef SFX_MODULE
|
||||
// Old style (RAR 2.9) comment header embedded into the main
|
||||
// archive header.
|
||||
if (BrokenHeader || CommHead.HeadSize<SIZEOF_COMMHEAD)
|
||||
if (BrokenHeader)
|
||||
{
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
@@ -60,12 +52,10 @@ bool Archive::DoGetComment(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;
|
||||
@@ -77,7 +67,6 @@ bool Archive::DoGetComment(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);
|
||||
@@ -94,8 +83,6 @@ bool Archive::DoGetComment(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.
|
||||
@@ -107,19 +94,11 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CmtLength==0)
|
||||
return false;
|
||||
Array<byte> CmtRaw(CmtLength);
|
||||
int ReadSize=Read(&CmtRaw[0],CmtLength);
|
||||
if (ReadSize>=0 && (uint)ReadSize<CmtLength) // Comment is shorter than declared.
|
||||
{
|
||||
CmtLength=ReadSize;
|
||||
CmtRaw.Alloc(CmtLength);
|
||||
}
|
||||
|
||||
Read(&CmtRaw[0],CmtLength);
|
||||
|
||||
if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
|
||||
{
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
@@ -132,9 +111,9 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
// 4x memory for OEM to UTF-8 output here.
|
||||
OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
|
||||
#endif
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtLength);
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return CmtData->Size() > 0;
|
||||
}
|
||||
@@ -143,7 +122,7 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
bool Archive::ReadCommentData(Array<wchar> *CmtData)
|
||||
{
|
||||
Array<byte> CmtRaw;
|
||||
if (!ReadSubData(&CmtRaw,NULL,false))
|
||||
if (!ReadSubData(&CmtRaw,NULL))
|
||||
return false;
|
||||
size_t CmtSize=CmtRaw.Size();
|
||||
CmtRaw.Push(0);
|
||||
@@ -152,12 +131,12 @@ bool Archive::ReadCommentData(Array<wchar> *CmtData)
|
||||
UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
else
|
||||
if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0)
|
||||
{
|
||||
{
|
||||
RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2);
|
||||
(*CmtData)[CmtSize/2]=0;
|
||||
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ Archive::Archive(RAROptions *InitCmd)
|
||||
CurBlockPos=0;
|
||||
NextBlockPos=0;
|
||||
|
||||
RecoverySize=-1;
|
||||
RecoveryPercent=-1;
|
||||
|
||||
memset(&MainHead,0,sizeof(MainHead));
|
||||
memset(&CryptHead,0,sizeof(CryptHead));
|
||||
@@ -46,10 +48,6 @@ Archive::Archive(RAROptions *InitCmd)
|
||||
|
||||
SilentOpen=false;
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
ProhibitQOpen=false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +114,7 @@ RARFORMAT Archive::IsSignature(const byte *D,size_t Size)
|
||||
if (D[6]==1)
|
||||
Type=RARFMT50;
|
||||
else
|
||||
if (D[6]>1 && D[6]<5)
|
||||
if (D[6]==2)
|
||||
Type=RARFMT_FUTURE;
|
||||
}
|
||||
return Type;
|
||||
@@ -177,7 +175,8 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
}
|
||||
if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
|
||||
{
|
||||
if (Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1)!=1 || MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
|
||||
Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
|
||||
if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
|
||||
return false;
|
||||
MarkHead.HeadSize=SIZEOF_MARKHEAD5;
|
||||
}
|
||||
@@ -193,31 +192,27 @@ 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 ((HeadersLeft=(ReadHeader()!=0))==true) // Additional parentheses to silence Clang.
|
||||
while (ReadHeader()!=0)
|
||||
{
|
||||
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.
|
||||
StartFound=Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT;
|
||||
if (StartFound)
|
||||
if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT)
|
||||
break;
|
||||
SeekToNext();
|
||||
}
|
||||
|
||||
|
||||
// We should not do it for EnableBroken or we'll get 'not RAR archive'
|
||||
// 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'
|
||||
// messages when extracting encrypted archives with wrong password.
|
||||
if (FailedHeaderDecryption && !EnableBroken)
|
||||
return false;
|
||||
|
||||
if (BrokenHeader || !StartFound) // Main archive header is corrupt or missing.
|
||||
SeekToNext();
|
||||
if (BrokenHeader) // Main archive header is corrupt.
|
||||
{
|
||||
if (!FailedHeaderDecryption) // If not reported a wrong password already.
|
||||
uiMsg(UIERROR_MHEADERBROKEN,FileName);
|
||||
uiMsg(UIERROR_MHEADERBROKEN,FileName);
|
||||
if (!EnableBroken)
|
||||
return false;
|
||||
}
|
||||
@@ -231,9 +226,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 (HeadersLeft && (!SilentOpen || !Encrypted))
|
||||
if (!SilentOpen || !Encrypted)
|
||||
{
|
||||
int64 SavePos=Tell();
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||
HEADER_TYPE SaveCurHeaderType=CurHeaderType;
|
||||
|
||||
@@ -262,10 +257,9 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
CurHeaderType=SaveCurHeaderType;
|
||||
Seek(SavePos,SEEK_SET);
|
||||
}
|
||||
if (!Volume || FirstVolume)
|
||||
wcsncpyz(FirstVolumeName,FileName,ASIZE(FirstVolumeName));
|
||||
wcscpy(FirstVolumeName,FileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -20,15 +20,13 @@ 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 ConvertFileHeader(FileHeader *hd);
|
||||
void WriteBlock50(HEADER_TYPE HeaderType,BaseBlock *wb,bool OnlySetSize,bool NonFinalWrite);
|
||||
size_t ReadHeader14();
|
||||
size_t ReadHeader15();
|
||||
size_t ReadHeader50();
|
||||
@@ -36,8 +34,8 @@ class Archive:public File
|
||||
void RequestArcPassword();
|
||||
void UnexpEndArcMsg();
|
||||
void BrokenHeaderMsg();
|
||||
void UnkEncVerMsg(const wchar *Name,const wchar *Info);
|
||||
bool DoGetComment(Array<wchar> *CmtData);
|
||||
void UnkEncVerMsg(const wchar *Name);
|
||||
void UnkEncVerMsg();
|
||||
bool ReadCommentData(Array<wchar> *CmtData);
|
||||
|
||||
#if !defined(RAR_NOCRYPT)
|
||||
@@ -47,6 +45,8 @@ class Archive:public File
|
||||
bool DummyCmd;
|
||||
RAROptions *Cmd;
|
||||
|
||||
int64 RecoverySize;
|
||||
int RecoveryPercent;
|
||||
|
||||
RarTime LatestTime;
|
||||
int LastReadBlock;
|
||||
@@ -55,7 +55,6 @@ class Archive:public File
|
||||
bool SilentOpen;
|
||||
#ifdef USE_QOPEN
|
||||
QuickOpen QOpen;
|
||||
bool ProhibitQOpen;
|
||||
#endif
|
||||
public:
|
||||
Archive(RAROptions *InitCmd=NULL);
|
||||
@@ -65,6 +64,8 @@ class Archive:public File
|
||||
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);}
|
||||
size_t ReadHeader();
|
||||
void CheckArc(bool EnableBroken);
|
||||
void CheckOpen(const wchar *Name);
|
||||
@@ -81,8 +82,8 @@ class Archive:public File
|
||||
int64 GetStartPos();
|
||||
void AddSubData(byte *SrcData,uint64 DataSize,File *SrcFile,
|
||||
const wchar *Name,uint Flags);
|
||||
bool ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode);
|
||||
HEADER_TYPE GetHeaderType() {return CurHeaderType;}
|
||||
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
|
||||
HEADER_TYPE GetHeaderType() {return CurHeaderType;};
|
||||
RAROptions* GetRAROptions() {return Cmd;}
|
||||
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
|
||||
#if 0
|
||||
@@ -94,7 +95,6 @@ class Archive:public File
|
||||
void Seek(int64 Offset,int Method);
|
||||
int64 Tell();
|
||||
void QOpenUnload() {QOpen.Unload();}
|
||||
void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;}
|
||||
#endif
|
||||
|
||||
BaseBlock ShortBlock;
|
||||
@@ -107,7 +107,10 @@ class Archive:public File
|
||||
FileHeader SubHead;
|
||||
CommentHeader CommHead;
|
||||
ProtectHeader ProtectHead;
|
||||
AVHeader AVHead;
|
||||
SignHeader SignHead;
|
||||
UnixOwnersHeader UOHead;
|
||||
MacFInfoHeader MACHead;
|
||||
EAHeader EAHead;
|
||||
StreamHeader StreamHead;
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@ size_t Archive::ReadHeader()
|
||||
|
||||
CurBlockPos=Tell();
|
||||
|
||||
// Other developers asked us to initialize it to suppress "may be used
|
||||
// uninitialized" warning in code below in some compilers.
|
||||
size_t ReadSize=0;
|
||||
|
||||
size_t ReadSize;
|
||||
switch(Format)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
@@ -29,18 +26,11 @@ size_t Archive::ReadHeader()
|
||||
break;
|
||||
}
|
||||
|
||||
// It is important to check ReadSize>0 here, because it is normal
|
||||
// for RAR2 and RAR3 archives without end of archive block to have
|
||||
// NextBlockPos==CurBlockPos after the end of archive has reached.
|
||||
if (ReadSize>0 && NextBlockPos<=CurBlockPos)
|
||||
{
|
||||
BrokenHeaderMsg();
|
||||
ReadSize=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ReadSize==0)
|
||||
CurHeaderType=HEAD_UNKNOWN;
|
||||
|
||||
return ReadSize;
|
||||
}
|
||||
|
||||
@@ -116,24 +106,13 @@ void Archive::BrokenHeaderMsg()
|
||||
}
|
||||
|
||||
|
||||
void Archive::UnkEncVerMsg(const wchar *Name,const wchar *Info)
|
||||
void Archive::UnkEncVerMsg(const wchar *Name)
|
||||
{
|
||||
uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name,Info);
|
||||
uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
}
|
||||
|
||||
|
||||
// Return f in case of signed integer overflow or negative parameters
|
||||
// or v1+v2 otherwise. We use it for file offsets, which are signed
|
||||
// for compatibility with off_t in POSIX file functions and third party code.
|
||||
// Signed integer overflow is the undefined behavior according to
|
||||
// C++ standard and it causes fuzzers to complain.
|
||||
inline int64 SafeAdd(int64 v1,int64 v2,int64 f)
|
||||
{
|
||||
return v1>=0 && v2>=0 && v1<=MAX_INT64-v2 ? v1+v2 : f;
|
||||
}
|
||||
|
||||
|
||||
size_t Archive::ReadHeader15()
|
||||
{
|
||||
RawRead Raw(this);
|
||||
@@ -267,15 +246,10 @@ size_t Archive::ReadHeader15()
|
||||
|
||||
uint FileTime=Raw.Get4();
|
||||
hd->UnpVer=Raw.Get1();
|
||||
|
||||
hd->Method=Raw.Get1()-0x30;
|
||||
size_t NameSize=Raw.Get2();
|
||||
hd->FileAttr=Raw.Get4();
|
||||
|
||||
// RAR15 did not use the special dictionary size to mark dirs.
|
||||
if (hd->UnpVer<20 && (hd->FileAttr & 0x10)!=0)
|
||||
hd->Dir=true;
|
||||
|
||||
hd->CryptMethod=CRYPT_NONE;
|
||||
if (hd->Encrypted)
|
||||
switch(hd->UnpVer)
|
||||
@@ -334,17 +308,17 @@ size_t Archive::ReadHeader15()
|
||||
|
||||
if (FileBlock)
|
||||
{
|
||||
*hd->FileName=0;
|
||||
if ((hd->Flags & LHD_UNICODE)!=0)
|
||||
{
|
||||
EncodeFileName NameCoder;
|
||||
size_t Length=strlen(FileName);
|
||||
Length++;
|
||||
if (ReadNameSize>Length)
|
||||
NameCoder.Decode(FileName,ReadNameSize,(byte *)FileName+Length,
|
||||
ReadNameSize-Length,hd->FileName,
|
||||
NameCoder.Decode(FileName,(byte *)FileName+Length,
|
||||
NameSize-Length,hd->FileName,
|
||||
ASIZE(hd->FileName));
|
||||
}
|
||||
else
|
||||
*hd->FileName=0;
|
||||
|
||||
if (*hd->FileName==0)
|
||||
ArcCharToWide(FileName,hd->FileName,ASIZE(hd->FileName),ACTW_OEM);
|
||||
@@ -369,8 +343,18 @@ size_t Archive::ReadHeader15()
|
||||
// They are stored after the file name and before salt.
|
||||
hd->SubData.Alloc(DataSize);
|
||||
Raw.GetB(&hd->SubData[0],DataSize);
|
||||
|
||||
if (hd->CmpName(SUBHEAD_TYPE_RR))
|
||||
{
|
||||
byte *D=&hd->SubData[8];
|
||||
RecoverySize=D[0]+((uint)D[1]<<8)+((uint)D[2]<<16)+((uint)D[3]<<24);
|
||||
RecoverySize*=512; // Sectors to size.
|
||||
int64 CurPos=Tell();
|
||||
RecoveryPercent=ToPercent(RecoverySize,CurPos);
|
||||
// Round fractional percent exceeding .5 to upper value.
|
||||
if (ToPercent(RecoverySize+CurPos/200,CurPos)>RecoveryPercent)
|
||||
RecoveryPercent++;
|
||||
}
|
||||
}
|
||||
|
||||
if (hd->CmpName(SUBHEAD_TYPE_CMT))
|
||||
MainComment=true;
|
||||
@@ -402,8 +386,8 @@ size_t Archive::ReadHeader15()
|
||||
if (rmode & 4)
|
||||
rlt.Second++;
|
||||
rlt.Reminder=0;
|
||||
uint count=rmode&3;
|
||||
for (uint J=0;J<count;J++)
|
||||
int count=rmode&3;
|
||||
for (int J=0;J<count;J++)
|
||||
{
|
||||
byte CurByte=Raw.Get1();
|
||||
rlt.Reminder|=(((uint)CurByte)<<((J+3-count)*8));
|
||||
@@ -413,9 +397,7 @@ size_t Archive::ReadHeader15()
|
||||
CurTime->SetLocal(&rlt);
|
||||
}
|
||||
}
|
||||
// Set to 0 in case of overflow, so end of ReadHeader cares about it.
|
||||
NextBlockPos=SafeAdd(NextBlockPos,hd->PackSize,0);
|
||||
|
||||
NextBlockPos+=hd->PackSize;
|
||||
bool CRCProcessedOnly=hd->CommentInHeader;
|
||||
ushort HeaderCRC=Raw.GetCRC15(CRCProcessedOnly);
|
||||
if (hd->HeadCRC!=HeaderCRC)
|
||||
@@ -452,6 +434,19 @@ size_t Archive::ReadHeader15()
|
||||
CommHead.Method=Raw.Get1();
|
||||
CommHead.CommCRC=Raw.Get2();
|
||||
break;
|
||||
case HEAD3_SIGN:
|
||||
*(BaseBlock *)&SignHead=ShortBlock;
|
||||
SignHead.CreationTime=Raw.Get4();
|
||||
SignHead.ArcNameSize=Raw.Get2();
|
||||
SignHead.UserNameSize=Raw.Get2();
|
||||
break;
|
||||
case HEAD3_AV:
|
||||
*(BaseBlock *)&AVHead=ShortBlock;
|
||||
AVHead.UnpVer=Raw.Get1();
|
||||
AVHead.Method=Raw.Get1();
|
||||
AVHead.AVVer=Raw.Get1();
|
||||
AVHead.AVInfoCRC=Raw.Get4();
|
||||
break;
|
||||
case HEAD3_PROTECT:
|
||||
*(BaseBlock *)&ProtectHead=ShortBlock;
|
||||
ProtectHead.DataSize=Raw.Get4();
|
||||
@@ -460,8 +455,9 @@ size_t Archive::ReadHeader15()
|
||||
ProtectHead.TotalBlocks=Raw.Get4();
|
||||
Raw.GetB(ProtectHead.Mark,8);
|
||||
NextBlockPos+=ProtectHead.DataSize;
|
||||
RecoverySize=ProtectHead.RecSectors*512;
|
||||
break;
|
||||
case HEAD3_OLDSERVICE: // RAR 2.9 and earlier.
|
||||
case HEAD3_OLDSERVICE:
|
||||
*(BaseBlock *)&SubBlockHead=ShortBlock;
|
||||
SubBlockHead.DataSize=Raw.Get4();
|
||||
NextBlockPos+=SubBlockHead.DataSize;
|
||||
@@ -482,6 +478,13 @@ size_t Archive::ReadHeader15()
|
||||
UOHead.OwnerName[UOHead.OwnerNameSize]=0;
|
||||
UOHead.GroupName[UOHead.GroupNameSize]=0;
|
||||
break;
|
||||
case MAC_HEAD:
|
||||
*(SubBlockHeader *)&MACHead=SubBlockHead;
|
||||
MACHead.fileType=Raw.Get4();
|
||||
MACHead.fileCreator=Raw.Get4();
|
||||
break;
|
||||
case EA_HEAD:
|
||||
case BEEA_HEAD:
|
||||
case NTACL_HEAD:
|
||||
*(SubBlockHeader *)&EAHead=SubBlockHead;
|
||||
EAHead.UnpSize=Raw.Get4();
|
||||
@@ -521,6 +524,7 @@ size_t Archive::ReadHeader15()
|
||||
{
|
||||
// Last 7 bytes of recovered volume can contain zeroes, because
|
||||
// REV files store its own information (volume number, etc.) here.
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 Length=Tell();
|
||||
Seek(Length-7,SEEK_SET);
|
||||
Recovered=true;
|
||||
@@ -542,6 +546,12 @@ size_t Archive::ReadHeader15()
|
||||
}
|
||||
}
|
||||
|
||||
if (NextBlockPos<=CurBlockPos)
|
||||
{
|
||||
BrokenHeaderMsg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Raw.Size();
|
||||
}
|
||||
|
||||
@@ -557,6 +567,7 @@ size_t Archive::ReadHeader50()
|
||||
#if defined(RAR_NOCRYPT)
|
||||
return 0;
|
||||
#else
|
||||
RequestArcPassword();
|
||||
|
||||
byte HeadersInitV[SIZE_INITV];
|
||||
if (Read(HeadersInitV,SIZE_INITV)!=SIZE_INITV)
|
||||
@@ -565,57 +576,24 @@ size_t Archive::ReadHeader50()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We repeat the password request only for manually entered passwords
|
||||
// and not for -p<pwd>. Wrong password can be intentionally provided
|
||||
// in -p<pwd> to not stop batch processing for encrypted archives.
|
||||
bool GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
|
||||
|
||||
while (true) // Repeat the password prompt for wrong passwords.
|
||||
{
|
||||
RequestArcPassword();
|
||||
|
||||
byte PswCheck[SIZE_PSWCHECK];
|
||||
HeadersCrypt.SetCryptKeys(false,CRYPT_RAR50,&Cmd->Password,CryptHead.Salt,HeadersInitV,CryptHead.Lg2Count,NULL,PswCheck);
|
||||
// Verify password validity.
|
||||
if (CryptHead.UsePswCheck && memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
|
||||
{
|
||||
if (GlobalPassword) // For -p<pwd> or Ctrl+P.
|
||||
{
|
||||
// This message is used by Android GUI to reset cached passwords.
|
||||
// Update appropriate code if changed.
|
||||
uiMsg(UIERROR_BADPSW,FileName,FileName);
|
||||
uiMsg(UIERROR_BADPSW,FileName);
|
||||
FailedHeaderDecryption=true;
|
||||
ErrHandler.SetErrorCode(RARX_BADPWD);
|
||||
return 0;
|
||||
}
|
||||
else // For passwords entered manually.
|
||||
{
|
||||
// This message is used by Android GUI and Windows GUI and SFX to
|
||||
// reset cached passwords. Update appropriate code if changed.
|
||||
uiMsg(UIWAIT_BADPSW,FileName,FileName);
|
||||
Cmd->Password.Clean();
|
||||
}
|
||||
|
||||
#ifdef RARDLL
|
||||
// Avoid new requests for unrar.dll to prevent the infinite loop
|
||||
// if app always returns the same password.
|
||||
ErrHandler.SetErrorCode(RARX_BADPWD);
|
||||
Cmd->DllError=ERAR_BAD_PASSWORD;
|
||||
ErrHandler.Exit(RARX_BADPWD);
|
||||
#else
|
||||
continue; // Request a password again.
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Raw.SetCrypt(&HeadersCrypt);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Header size must not occupy more than 3 variable length integer bytes
|
||||
// resulting in 2 MB maximum header size (MAX_HEADER_SIZE_RAR5),
|
||||
// so here we read 4 byte CRC32 followed by 3 bytes or less of header size.
|
||||
// resulting in 2 MB maximum header size, so here we read 4 byte CRC32
|
||||
// followed by 3 bytes or less of header size.
|
||||
const size_t FirstReadSize=7; // Smallest possible block size.
|
||||
if (Raw.Read(FirstReadSize)<FirstReadSize)
|
||||
{
|
||||
@@ -692,9 +670,7 @@ size_t Archive::ReadHeader50()
|
||||
if ((ShortBlock.Flags & HFL_DATA)!=0)
|
||||
DataSize=Raw.GetV();
|
||||
|
||||
NextBlockPos=CurBlockPos+FullHeaderSize(ShortBlock.HeadSize);
|
||||
// Set to 0 in case of overflow, so end of ReadHeader cares about it.
|
||||
NextBlockPos=SafeAdd(NextBlockPos,DataSize,0);
|
||||
NextBlockPos=CurBlockPos+FullHeaderSize(ShortBlock.HeadSize)+DataSize;
|
||||
|
||||
switch(ShortBlock.HeaderType)
|
||||
{
|
||||
@@ -704,9 +680,7 @@ size_t Archive::ReadHeader50()
|
||||
uint CryptVersion=(uint)Raw.GetV();
|
||||
if (CryptVersion>CRYPT_VERSION)
|
||||
{
|
||||
wchar Info[20];
|
||||
swprintf(Info,ASIZE(Info),L"h%u",CryptVersion);
|
||||
UnkEncVerMsg(FileName,Info);
|
||||
UnkEncVerMsg(FileName);
|
||||
return 0;
|
||||
}
|
||||
uint EncFlags=(uint)Raw.GetV();
|
||||
@@ -714,12 +688,9 @@ size_t Archive::ReadHeader50()
|
||||
CryptHead.Lg2Count=Raw.Get1();
|
||||
if (CryptHead.Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX)
|
||||
{
|
||||
wchar Info[20];
|
||||
swprintf(Info,ASIZE(Info),L"hc%u",CryptHead.Lg2Count);
|
||||
UnkEncVerMsg(FileName,Info);
|
||||
UnkEncVerMsg(FileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Raw.GetB(CryptHead.Salt,SIZE_SALT50);
|
||||
if (CryptHead.UsePswCheck)
|
||||
{
|
||||
@@ -763,7 +734,7 @@ size_t Archive::ReadHeader50()
|
||||
ProcessExtra50(&Raw,(size_t)ExtraSize,&MainHead);
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
if (!ProhibitQOpen && MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
|
||||
if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
|
||||
{
|
||||
// We seek to QO block in the end of archive when processing
|
||||
// QOpen.Load, so we need to preserve current block positions
|
||||
@@ -822,8 +793,6 @@ size_t Archive::ReadHeader50()
|
||||
// but it was already used in RAR 1.5 and Unpack needs to distinguish
|
||||
// them.
|
||||
hd->UnpVer=(CompInfo & 0x3f) + 50;
|
||||
if (hd->UnpVer!=50) // Only 5.0 compression is known now.
|
||||
hd->UnpVer=VER_UNKNOWN;
|
||||
|
||||
hd->HostOS=(byte)Raw.GetV();
|
||||
size_t NameSize=(size_t)Raw.GetV();
|
||||
@@ -899,6 +868,11 @@ size_t Archive::ReadHeader50()
|
||||
break;
|
||||
}
|
||||
|
||||
if (NextBlockPos<=CurBlockPos)
|
||||
{
|
||||
BrokenHeaderMsg();
|
||||
return 0;
|
||||
}
|
||||
return Raw.Size();
|
||||
}
|
||||
|
||||
@@ -934,10 +908,11 @@ void Archive::RequestArcPassword()
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
#else
|
||||
if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password))
|
||||
if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password) ||
|
||||
!Cmd->Password.IsSet())
|
||||
{
|
||||
Close();
|
||||
uiMsg(UIERROR_INCERRCOUNT); // Prevent archive deleting if delete after extraction is on.
|
||||
uiMsg(UIERROR_INCERRCOUNT);
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
#endif
|
||||
@@ -956,17 +931,14 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
Raw->SetPos(ExtraStart);
|
||||
while (Raw->DataLeft()>=2)
|
||||
{
|
||||
int64 FieldSize=Raw->GetV(); // Needs to be signed for check below and can be negative.
|
||||
if (FieldSize<=0 || Raw->DataLeft()==0 || FieldSize>(int64)Raw->DataLeft())
|
||||
int64 FieldSize=Raw->GetV();
|
||||
if (FieldSize==0 || Raw->DataLeft()==0 || FieldSize>(int64)Raw->DataLeft())
|
||||
break;
|
||||
size_t NextPos=size_t(Raw->GetPos()+FieldSize);
|
||||
uint64 FieldType=Raw->GetV();
|
||||
|
||||
FieldSize=int64(NextPos-Raw->GetPos()); // Field size without size and type fields.
|
||||
|
||||
if (FieldSize<0) // FieldType is longer than expected extra field size.
|
||||
break;
|
||||
|
||||
if (bb->HeaderType==HEAD_MAIN)
|
||||
{
|
||||
MainHeader *hd=(MainHeader *)bb;
|
||||
@@ -999,11 +971,7 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
FileHeader *hd=(FileHeader *)bb;
|
||||
uint EncVersion=(uint)Raw->GetV();
|
||||
if (EncVersion > CRYPT_VERSION)
|
||||
{
|
||||
wchar Info[20];
|
||||
swprintf(Info,ASIZE(Info),L"x%u",EncVersion);
|
||||
UnkEncVerMsg(hd->FileName,Info);
|
||||
}
|
||||
UnkEncVerMsg(hd->FileName);
|
||||
else
|
||||
{
|
||||
uint Flags=(uint)Raw->GetV();
|
||||
@@ -1011,11 +979,7 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
hd->UseHashKey=(Flags & FHEXTRA_CRYPT_HASHMAC)!=0;
|
||||
hd->Lg2Count=Raw->Get1();
|
||||
if (hd->Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX)
|
||||
{
|
||||
wchar Info[20];
|
||||
swprintf(Info,ASIZE(Info),L"xc%u",hd->Lg2Count);
|
||||
UnkEncVerMsg(hd->FileName,Info);
|
||||
}
|
||||
UnkEncVerMsg(hd->FileName);
|
||||
Raw->GetB(hd->Salt,SIZE_SALT50);
|
||||
Raw->GetB(hd->InitV,SIZE_INITV);
|
||||
if (hd->UsePswCheck)
|
||||
@@ -1106,7 +1070,7 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
|
||||
wchar VerText[20];
|
||||
swprintf(VerText,ASIZE(VerText),L";%u",Version);
|
||||
wcsncatz(hd->FileName,VerText,ASIZE(hd->FileName));
|
||||
wcsncatz(FileHead.FileName,VerText,ASIZE(FileHead.FileName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1172,7 +1136,7 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
// required. It did not hurt extraction, because UnRAR 5.21
|
||||
// and earlier ignored this field and set FieldSize as data left
|
||||
// in entire extra area. But now we set the correct field size
|
||||
// and set FieldSize based on the actual extra record size,
|
||||
// and set FieldSize based on actual extra record size,
|
||||
// so we need to adjust it for those older archives here.
|
||||
// FHEXTRA_SUBDATA in those archives always belongs to HEAD_SERVICE
|
||||
// and always is last in extra area. So since its size is by 1
|
||||
@@ -1181,9 +1145,6 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
|
||||
if (bb->HeaderType==HEAD_SERVICE && Raw->Size()-NextPos==1)
|
||||
FieldSize++;
|
||||
|
||||
// We cannot allocate too much memory here, because above
|
||||
// we check FieldSize againt Raw size and we control that Raw size
|
||||
// is sensible when reading headers.
|
||||
hd->SubData.Alloc((size_t)FieldSize);
|
||||
Raw->GetB(hd->SubData.Addr(0),(size_t)FieldSize);
|
||||
}
|
||||
@@ -1207,8 +1168,6 @@ size_t Archive::ReadHeader14()
|
||||
byte Mark[4];
|
||||
Raw.GetB(Mark,4);
|
||||
uint HeadSize=Raw.Get2();
|
||||
if (HeadSize<7)
|
||||
return false;
|
||||
byte Flags=Raw.Get1();
|
||||
NextBlockPos=CurBlockPos+HeadSize;
|
||||
CurHeaderType=HEAD_MAIN;
|
||||
@@ -1230,8 +1189,6 @@ size_t Archive::ReadHeader14()
|
||||
FileHead.FileHash.Type=HASH_RAR14;
|
||||
FileHead.FileHash.CRC32=Raw.Get2();
|
||||
FileHead.HeadSize=Raw.Get2();
|
||||
if (FileHead.HeadSize<21)
|
||||
return false;
|
||||
uint FileTime=Raw.Get4();
|
||||
FileHead.FileAttr=Raw.Get1();
|
||||
FileHead.Flags=Raw.Get1()|LONG_BLOCK;
|
||||
@@ -1246,23 +1203,17 @@ size_t Archive::ReadHeader14()
|
||||
|
||||
FileHead.PackSize=FileHead.DataSize;
|
||||
FileHead.WinSize=0x10000;
|
||||
FileHead.Dir=(FileHead.FileAttr & 0x10)!=0;
|
||||
|
||||
FileHead.HostOS=HOST_MSDOS;
|
||||
FileHead.HSType=HSYS_WINDOWS;
|
||||
|
||||
FileHead.mtime.SetDos(FileTime);
|
||||
|
||||
Raw.Read(NameSize);
|
||||
|
||||
char FileName[NM];
|
||||
size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
|
||||
Raw.GetB((byte *)FileName,ReadNameSize);
|
||||
FileName[ReadNameSize]=0;
|
||||
Raw.GetB((byte *)FileName,Min(NameSize,ASIZE(FileName)));
|
||||
FileName[NameSize]=0;
|
||||
IntToExt(FileName,FileName,ASIZE(FileName));
|
||||
CharToWide(FileName,FileHead.FileName,ASIZE(FileHead.FileName));
|
||||
ConvertNameCase(FileHead.FileName);
|
||||
ConvertFileHeader(&FileHead);
|
||||
|
||||
if (Raw.Size()!=0)
|
||||
NextBlockPos=CurBlockPos+FileHead.HeadSize+FileHead.PackSize;
|
||||
@@ -1357,6 +1308,8 @@ void Archive::ConvertAttributes()
|
||||
|
||||
void Archive::ConvertFileHeader(FileHeader *hd)
|
||||
{
|
||||
if (Format==RARFMT15 && hd->UnpVer<20 && (hd->FileAttr & 0x10))
|
||||
hd->Dir=true;
|
||||
if (hd->HSType==HSYS_UNKNOWN)
|
||||
if (hd->Dir)
|
||||
hd->FileAttr=0x10;
|
||||
@@ -1416,7 +1369,7 @@ int64 Archive::GetStartPos()
|
||||
}
|
||||
|
||||
|
||||
bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode)
|
||||
bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile)
|
||||
{
|
||||
if (BrokenHeader)
|
||||
{
|
||||
@@ -1449,9 +1402,9 @@ bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode)
|
||||
SubDataIO.SetTestMode(true);
|
||||
else
|
||||
{
|
||||
UnpData->Alloc((size_t)SubHead.UnpSize);
|
||||
SubDataIO.SetUnpackToMemory(&(*UnpData)[0],(uint)SubHead.UnpSize);
|
||||
}
|
||||
UnpData->Alloc((size_t)SubHead.UnpSize);
|
||||
SubDataIO.SetUnpackToMemory(&(*UnpData)[0],(uint)SubHead.UnpSize);
|
||||
}
|
||||
}
|
||||
if (SubHead.Encrypted)
|
||||
if (Cmd->Password.IsSet())
|
||||
@@ -1464,7 +1417,6 @@ bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode)
|
||||
SubDataIO.SetPackedSizeToRead(SubHead.PackSize);
|
||||
SubDataIO.EnableShowProgress(false);
|
||||
SubDataIO.SetFiles(this,DestFile);
|
||||
SubDataIO.SetTestMode(TestMode);
|
||||
SubDataIO.UnpVolume=SubHead.SplitAfter;
|
||||
SubDataIO.SetSubHeader(&SubHead,NULL);
|
||||
Unpack.SetDestSize(SubHead.UnpSize);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#define _RAR_BLAKE2_
|
||||
|
||||
#define BLAKE2_DIGEST_SIZE 32
|
||||
#define BLAKE2_THREADS_NUMBER 8
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#include "cmdfilter.cpp"
|
||||
#include "cmdmix.cpp"
|
||||
|
||||
CommandData::CommandData()
|
||||
{
|
||||
Init();
|
||||
@@ -16,7 +13,6 @@ void CommandData::Init()
|
||||
*Command=0;
|
||||
*ArcName=0;
|
||||
FileLists=false;
|
||||
NoMoreSwitches=false;
|
||||
|
||||
ListMode=RCLM_AUTO;
|
||||
|
||||
@@ -56,6 +52,7 @@ void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
|
||||
// In Windows we may prefer to implement our own command line parser
|
||||
// to avoid replacing \" by " in standard parser. Such replacing corrupts
|
||||
// destination paths like "dest path\" in extraction commands.
|
||||
// Also our own parser is Unicode compatible.
|
||||
const wchar *CmdLine=GetCommandLine();
|
||||
|
||||
wchar *Par;
|
||||
@@ -99,7 +96,7 @@ void CommandData::ParseArg(wchar *Arg)
|
||||
else
|
||||
if (*Command==0)
|
||||
{
|
||||
wcsncpyz(Command,Arg,ASIZE(Command));
|
||||
wcsncpy(Command,Arg,ASIZE(Command));
|
||||
|
||||
|
||||
*Command=toupperw(*Command);
|
||||
@@ -122,7 +119,6 @@ void CommandData::ParseArg(wchar *Arg)
|
||||
wchar CmdChar=toupperw(*Command);
|
||||
bool Add=wcschr(L"AFUM",CmdChar)!=NULL;
|
||||
bool Extract=CmdChar=='X' || CmdChar=='E';
|
||||
bool Repair=CmdChar=='R' && Command[1]==0;
|
||||
if (EndSeparator && !Add)
|
||||
wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
|
||||
else
|
||||
@@ -133,15 +129,25 @@ void CommandData::ParseArg(wchar *Arg)
|
||||
FindData FileData;
|
||||
bool Found=FindFile::FastFind(Arg,&FileData);
|
||||
if ((!Found || ListMode==RCLM_ACCEPT_LISTS) &&
|
||||
ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg+1))
|
||||
ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg))
|
||||
{
|
||||
FileLists=true;
|
||||
|
||||
ReadTextFile(Arg+1,&FileArgs,false,true,FilelistCharset,true,true,true);
|
||||
RAR_CHARSET Charset=FilelistCharset;
|
||||
|
||||
#if defined(_WIN_ALL)
|
||||
// for compatibility reasons we use OEM encoding
|
||||
// in Win32 console version by default
|
||||
|
||||
// if (Charset==RCH_DEFAULT)
|
||||
// Charset=RCH_OEM;
|
||||
#endif
|
||||
|
||||
ReadTextFile(Arg+1,&FileArgs,false,true,Charset,true,true,true);
|
||||
|
||||
}
|
||||
else // We use 'destpath\' when extracting and reparing.
|
||||
if (Found && FileData.IsDir && (Extract || Repair) && *ExtrPath==0)
|
||||
else
|
||||
if (Found && FileData.IsDir && Extract && *ExtrPath==0)
|
||||
{
|
||||
wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
|
||||
AddEndSlash(ExtrPath,ASIZE(ExtrPath));
|
||||
@@ -242,7 +248,7 @@ void CommandData::ReadConfig()
|
||||
if (C0=='R' && (C1=='R' || C1=='V'))
|
||||
Cmd[2]=0;
|
||||
wchar SwName[16+ASIZE(Cmd)];
|
||||
swprintf(SwName,ASIZE(SwName),L"switches_%ls=",Cmd);
|
||||
swprintf(SwName,ASIZE(SwName),L"switches_%s=",Cmd);
|
||||
size_t Length=wcslen(SwName);
|
||||
if (wcsnicomp(Str,SwName,Length)==0)
|
||||
ProcessSwitchesString(Str+Length);
|
||||
@@ -283,23 +289,13 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
ClearArc=true;
|
||||
break;
|
||||
case 'D':
|
||||
if (Switch[2]==0)
|
||||
AppendArcNameToPath=APPENDARCNAME_DESTPATH;
|
||||
else
|
||||
if (Switch[2]=='1')
|
||||
AppendArcNameToPath=APPENDARCNAME_OWNSUBDIR;
|
||||
else
|
||||
if (Switch[2]=='2')
|
||||
AppendArcNameToPath=APPENDARCNAME_OWNDIR;
|
||||
AppendArcNameToPath=true;
|
||||
break;
|
||||
#ifndef SFX_MODULE
|
||||
case 'G':
|
||||
if (Switch[2]=='-' && Switch[3]==0)
|
||||
GenerateArcName=0;
|
||||
else
|
||||
if (toupperw(Switch[2])=='F')
|
||||
wcsncpyz(DefGenerateMask,Switch+3,ASIZE(DefGenerateMask));
|
||||
else
|
||||
{
|
||||
GenerateArcName=true;
|
||||
wcsncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask));
|
||||
@@ -315,7 +311,7 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
AddArcOnly=true;
|
||||
break;
|
||||
case 'P':
|
||||
wcsncpyz(ArcPath,Switch+2,ASIZE(ArcPath));
|
||||
wcscpy(ArcPath,Switch+2);
|
||||
break;
|
||||
case 'S':
|
||||
SyncFiles=true;
|
||||
@@ -378,11 +374,11 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
default:
|
||||
if (Switch[1]=='+')
|
||||
{
|
||||
InclFileAttr|=GetExclAttr(Switch+2,InclDir);
|
||||
InclFileAttr|=GetExclAttr(Switch+2);
|
||||
InclAttrSet=true;
|
||||
}
|
||||
else
|
||||
ExclFileAttr|=GetExclAttr(Switch+1,ExclDir);
|
||||
ExclFileAttr|=GetExclAttr(Switch+1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -420,17 +416,14 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
wcsncpyz(LogName,Switch[4]!=0 ? Switch+4:DefLogName,ASIZE(LogName));
|
||||
break;
|
||||
}
|
||||
if (wcsnicomp(Switch+1,L"SND",3)==0)
|
||||
if (wcsicomp(Switch+1,L"SND")==0)
|
||||
{
|
||||
Sound=Switch[4]=='-' ? SOUND_NOTIFY_OFF : SOUND_NOTIFY_ON;
|
||||
Sound=true;
|
||||
break;
|
||||
}
|
||||
if (wcsicomp(Switch+1,L"ERR")==0)
|
||||
{
|
||||
MsgStream=MSG_STDERR;
|
||||
// Set it immediately when parsing the command line, so it also
|
||||
// affects messages issued while parsing the command line.
|
||||
SetConsoleMsgStream(MSG_STDERR);
|
||||
break;
|
||||
}
|
||||
if (wcsnicomp(Switch+1,L"EML",3)==0)
|
||||
@@ -438,15 +431,9 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
wcsncpyz(EmailTo,Switch[4]!=0 ? Switch+4:L"@",ASIZE(EmailTo));
|
||||
break;
|
||||
}
|
||||
if (wcsicomp(Switch+1,L"M")==0) // For compatibility with pre-WinRAR 6.0 -im syntax. Replaced with -idv.
|
||||
{
|
||||
VerboseOutput=true;
|
||||
break;
|
||||
}
|
||||
if (wcsicomp(Switch+1,L"NUL")==0)
|
||||
{
|
||||
MsgStream=MSG_NULL;
|
||||
SetConsoleMsgStream(MSG_NULL);
|
||||
break;
|
||||
}
|
||||
if (toupperw(Switch[1])=='D')
|
||||
@@ -456,7 +443,6 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
{
|
||||
case 'Q':
|
||||
MsgStream=MSG_ERRONLY;
|
||||
SetConsoleMsgStream(MSG_ERRONLY);
|
||||
break;
|
||||
case 'C':
|
||||
DisableCopyright=true;
|
||||
@@ -467,33 +453,12 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
case 'P':
|
||||
DisablePercentage=true;
|
||||
break;
|
||||
case 'N':
|
||||
DisableNames=true;
|
||||
break;
|
||||
case 'V':
|
||||
VerboseOutput=true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (wcsnicomp(Switch+1,L"OFF",3)==0)
|
||||
if (wcsicomp(Switch+1,L"OFF")==0)
|
||||
{
|
||||
switch(Switch[4])
|
||||
{
|
||||
case 0:
|
||||
case '1':
|
||||
Shutdown=POWERMODE_OFF;
|
||||
break;
|
||||
case '2':
|
||||
Shutdown=POWERMODE_HIBERNATE;
|
||||
break;
|
||||
case '3':
|
||||
Shutdown=POWERMODE_SLEEP;
|
||||
break;
|
||||
case '4':
|
||||
Shutdown=POWERMODE_RESTART;
|
||||
break;
|
||||
}
|
||||
Shutdown=true;
|
||||
break;
|
||||
}
|
||||
if (wcsicomp(Switch+1,L"VER")==0)
|
||||
@@ -547,6 +512,7 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
case 'D': Type=FILTER_DELTA; break;
|
||||
case 'A': Type=FILTER_AUDIO; break;
|
||||
case 'C': Type=FILTER_RGB; break;
|
||||
case 'I': Type=FILTER_ITANIUM; break;
|
||||
case 'R': Type=FILTER_ARM; break;
|
||||
}
|
||||
if (*Str=='+' || *Str=='-')
|
||||
@@ -608,7 +574,19 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
{
|
||||
StringList *Args=toupperw(Switch[0])=='N' ? &InclArgs:&ExclArgs;
|
||||
if (Switch[1]=='@' && !IsWildcard(Switch))
|
||||
ReadTextFile(Switch+2,Args,false,true,FilelistCharset,true,true,true);
|
||||
{
|
||||
RAR_CHARSET Charset=FilelistCharset;
|
||||
|
||||
#if defined(_WIN_ALL)
|
||||
// for compatibility reasons we use OEM encoding
|
||||
// in Win32 console version by default
|
||||
|
||||
// if (Charset==RCH_DEFAULT)
|
||||
// Charset=RCH_OEM;
|
||||
#endif
|
||||
|
||||
ReadTextFile(Switch+2,Args,false,true,Charset,true,true,true);
|
||||
}
|
||||
else
|
||||
Args->AddString(Switch+1);
|
||||
}
|
||||
@@ -805,9 +783,6 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
AlreadyBad=true;
|
||||
break;
|
||||
}
|
||||
// Set it immediately when parsing the command line, so it also
|
||||
// affects messages issued while parsing the command line.
|
||||
SetConsoleRedirectCharset(RedirectCharset);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -823,20 +798,52 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
ArcTime=ARCTIME_LATEST;
|
||||
break;
|
||||
case 'O':
|
||||
SetTimeFilters(Switch+2,true,true);
|
||||
FileTimeBefore.SetAgeText(Switch+2);
|
||||
break;
|
||||
case 'N':
|
||||
SetTimeFilters(Switch+2,false,true);
|
||||
FileTimeAfter.SetAgeText(Switch+2);
|
||||
break;
|
||||
case 'B':
|
||||
SetTimeFilters(Switch+2,true,false);
|
||||
FileTimeBefore.SetIsoText(Switch+2);
|
||||
break;
|
||||
case 'A':
|
||||
SetTimeFilters(Switch+2,false,false);
|
||||
FileTimeAfter.SetIsoText(Switch+2);
|
||||
break;
|
||||
case 'S':
|
||||
SetStoreTimeMode(Switch+2);
|
||||
{
|
||||
EXTTIME_MODE Mode=EXTTIME_HIGH3;
|
||||
bool CommonMode=Switch[2]>='0' && Switch[2]<='4';
|
||||
if (CommonMode)
|
||||
Mode=(EXTTIME_MODE)(Switch[2]-'0');
|
||||
if (Mode==EXTTIME_HIGH1 || Mode==EXTTIME_HIGH2) // '2' and '3' not supported anymore.
|
||||
Mode=EXTTIME_HIGH3;
|
||||
if (Switch[2]=='-')
|
||||
Mode=EXTTIME_NONE;
|
||||
if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0)
|
||||
xmtime=xctime=xatime=Mode;
|
||||
else
|
||||
{
|
||||
if (Switch[3]>='0' && Switch[3]<='4')
|
||||
Mode=(EXTTIME_MODE)(Switch[3]-'0');
|
||||
if (Mode==EXTTIME_HIGH1 || Mode==EXTTIME_HIGH2) // '2' and '3' not supported anymore.
|
||||
Mode=EXTTIME_HIGH3;
|
||||
if (Switch[3]=='-')
|
||||
Mode=EXTTIME_NONE;
|
||||
switch(toupperw(Switch[2]))
|
||||
{
|
||||
case 'M':
|
||||
xmtime=Mode;
|
||||
break;
|
||||
case 'C':
|
||||
xctime=Mode;
|
||||
break;
|
||||
case 'A':
|
||||
xatime=Mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
Test=false;
|
||||
break;
|
||||
@@ -883,7 +890,7 @@ void CommandData::ProcessSwitch(const wchar *Switch)
|
||||
if (Switch[1]==0)
|
||||
{
|
||||
// If comment file is not specified, we read data from stdin.
|
||||
wcsncpyz(CommentFile,L"stdin",ASIZE(CommentFile));
|
||||
wcscpy(CommentFile,L"stdin");
|
||||
}
|
||||
else
|
||||
wcsncpyz(CommentFile,Switch+1,ASIZE(CommentFile));
|
||||
@@ -908,6 +915,311 @@ void CommandData::BadSwitch(const wchar *Switch)
|
||||
#endif
|
||||
|
||||
|
||||
void CommandData::OutTitle()
|
||||
{
|
||||
if (BareOutput || DisableCopyright)
|
||||
return;
|
||||
#if defined(__GNUC__) && defined(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,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
|
||||
MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
|
||||
MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
|
||||
MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSL,MCHelpSwSM,
|
||||
MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,
|
||||
MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,
|
||||
MCHelpSwY
|
||||
// RAR switches definition.
|
||||
//removed in 3.9.7
|
||||
#endif
|
||||
};
|
||||
|
||||
for (uint I=0;I<ASIZE(Help);I++)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
if (CmpMSGID(Help[I],MCHelpSwV))
|
||||
continue;
|
||||
#ifndef _WIN_ALL
|
||||
static MSGID Win32Only[]={
|
||||
MCHelpSwIEML,MCHelpSwVD,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
|
||||
MCHelpSwEP2,MCHelpSwOC,MCHelpSwONI,MCHelpSwDR,MCHelpSwRI
|
||||
};
|
||||
bool Found=false;
|
||||
for (int J=0;J<sizeof(Win32Only)/sizeof(Win32Only[0]);J++)
|
||||
if (CmpMSGID(Help[I],Win32Only[J]))
|
||||
{
|
||||
Found=true;
|
||||
break;
|
||||
}
|
||||
if (Found)
|
||||
continue;
|
||||
#endif
|
||||
#if !defined(_UNIX) && !defined(_WIN_ALL)
|
||||
if (CmpMSGID(Help[I],MCHelpSwOW))
|
||||
continue;
|
||||
#endif
|
||||
#if !defined(_WIN_ALL) && !defined(_EMX)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
// 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 wchar *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 wchar *CheckName,bool CheckFullPath,int MatchMode)
|
||||
{
|
||||
wchar *Name=ConvertPath(CheckName,NULL);
|
||||
wchar FullName[NM];
|
||||
wchar CurMask[NM];
|
||||
*FullName=0;
|
||||
Args->Rewind();
|
||||
while (Args->GetString(CurMask,ASIZE(CurMask)))
|
||||
{
|
||||
wchar *LastMaskChar=PointToLastChar(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.
|
||||
|
||||
*LastMaskChar=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// REMOVED, we want -npath\* to match empty folders too.
|
||||
// If mask has wildcards in name part and does not have the trailing
|
||||
// '\' character, we cannot use it for directories.
|
||||
|
||||
// if (IsWildcard(PointToName(CurMask)))
|
||||
// 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)
|
||||
wcsncatz(CurMask,L"*",ASIZE(CurMask));
|
||||
}
|
||||
|
||||
#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==0)
|
||||
ConvertNameToFull(CheckName,FullName,ASIZE(FullName));
|
||||
if (CmpName(CurMask,FullName,MatchMode))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
wchar NewName[NM+2],*CurName=Name;
|
||||
|
||||
// Important to convert before "*\" check below, so masks like
|
||||
// d:*\something are processed properly.
|
||||
wchar *CmpMask=ConvertPath(CurMask,NULL);
|
||||
|
||||
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.
|
||||
NewName[0]='.';
|
||||
NewName[1]=CPATHDIVIDER;
|
||||
wcsncpyz(NewName+2,Name,ASIZE(NewName)-2);
|
||||
CurName=NewName;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Return 'true' if we need to exclude the file from processing.
|
||||
bool CommandData::TimeCheck(RarTime &ft)
|
||||
{
|
||||
if (FileTimeBefore.IsSet() && ft>=FileTimeBefore)
|
||||
return true;
|
||||
if (FileTimeAfter.IsSet() && ft<=FileTimeAfter)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Return 'true' if we need to exclude the file from processing.
|
||||
bool CommandData::SizeCheck(int64 Size)
|
||||
{
|
||||
if (FileSizeLess!=INT64NDF && Size>=FileSizeLess)
|
||||
return(true);
|
||||
if (FileSizeMore!=INT64NDF && Size<=FileSizeMore)
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
|
||||
wchar *MatchedArg,uint MatchedArgSize)
|
||||
{
|
||||
if (MatchedArg!=NULL && MatchedArgSize>0)
|
||||
*MatchedArg=0;
|
||||
if (wcslen(FileHead.FileName)>=NM)
|
||||
return 0;
|
||||
bool Dir=FileHead.Dir;
|
||||
if (ExclCheck(FileHead.FileName,Dir,false,true))
|
||||
return 0;
|
||||
#ifndef SFX_MODULE
|
||||
if (TimeCheck(FileHead.mtime))
|
||||
return 0;
|
||||
if ((FileHead.FileAttr & ExclFileAttr)!=0 || InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0)
|
||||
return 0;
|
||||
if (!Dir && SizeCheck(FileHead.UnpSize))
|
||||
return 0;
|
||||
#endif
|
||||
wchar *ArgName;
|
||||
FileArgs.Rewind();
|
||||
for (int StringCount=1;(ArgName=FileArgs.GetString())!=NULL;StringCount++)
|
||||
if (CmpName(ArgName,FileHead.FileName,MatchType))
|
||||
{
|
||||
if (ExactMatch!=NULL)
|
||||
*ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
|
||||
if (MatchedArg!=NULL)
|
||||
wcsncpyz(MatchedArg,ArgName,MatchedArgSize);
|
||||
return StringCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CommandData::ProcessCommand()
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
@@ -938,10 +1250,7 @@ void CommandData::ProcessCommand()
|
||||
if (wcschr(L"AFUMD",*Command)==NULL)
|
||||
{
|
||||
if (GenerateArcName)
|
||||
{
|
||||
const wchar *Mask=*GenerateMask!=0 ? GenerateMask:DefGenerateMask;
|
||||
GenerateArchiveName(ArcName,ASIZE(ArcName),Mask,false);
|
||||
}
|
||||
GenerateArchiveName(ArcName,ASIZE(ArcName),GenerateMask,false);
|
||||
|
||||
StringList ArcMasks;
|
||||
ArcMasks.AddString(ArcName);
|
||||
@@ -960,6 +1269,7 @@ void CommandData::ProcessCommand()
|
||||
case 'X':
|
||||
case 'E':
|
||||
case 'T':
|
||||
case 'I':
|
||||
{
|
||||
CmdExtract Extract(this);
|
||||
Extract.DoExtract();
|
||||
@@ -1002,7 +1312,7 @@ bool CommandData::IsSwitch(int Ch)
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
uint CommandData::GetExclAttr(const wchar *Str,bool &Dir)
|
||||
uint CommandData::GetExclAttr(const wchar *Str)
|
||||
{
|
||||
if (IsDigit(*Str))
|
||||
return wcstol(Str,NULL,0);
|
||||
@@ -1012,10 +1322,10 @@ uint CommandData::GetExclAttr(const wchar *Str,bool &Dir)
|
||||
{
|
||||
switch(toupperw(*Str))
|
||||
{
|
||||
case 'D':
|
||||
Dir=true;
|
||||
break;
|
||||
#ifdef _UNIX
|
||||
case 'D':
|
||||
Attr|=S_IFDIR;
|
||||
break;
|
||||
case 'V':
|
||||
Attr|=S_IFCHR;
|
||||
break;
|
||||
@@ -1029,6 +1339,9 @@ uint CommandData::GetExclAttr(const wchar *Str,bool &Dir)
|
||||
case 'S':
|
||||
Attr|=0x4;
|
||||
break;
|
||||
case 'D':
|
||||
Attr|=0x10;
|
||||
break;
|
||||
case 'A':
|
||||
Attr|=0x20;
|
||||
break;
|
||||
|
||||
@@ -6,18 +6,13 @@
|
||||
|
||||
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,bool &Dir);
|
||||
#if !defined(SFX_MODULE)
|
||||
void SetTimeFilters(const wchar *Mod,bool Before,bool Age);
|
||||
void SetStoreTimeMode(const wchar *S);
|
||||
#endif
|
||||
uint GetExclAttr(const wchar *Str);
|
||||
|
||||
bool FileLists;
|
||||
bool NoMoreSwitches;
|
||||
@@ -33,18 +28,17 @@ class CommandData:public RAROptions
|
||||
void ParseEnvVar();
|
||||
void ReadConfig();
|
||||
void PreprocessArg(const wchar *Arg);
|
||||
void ProcessSwitchesString(const wchar *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 ExclDirByAttr(uint FileAttr);
|
||||
bool TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta);
|
||||
bool TimeCheck(RarTime &ft);
|
||||
bool SizeCheck(int64 Size);
|
||||
bool AnyFiltersActive();
|
||||
int IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType,
|
||||
bool Flags,wchar *MatchedArg,uint MatchedArgSize);
|
||||
int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH,
|
||||
wchar *MatchedArg=NULL,uint MatchedArgSize=0);
|
||||
void ProcessCommand();
|
||||
void AddArcName(const wchar *Name);
|
||||
bool GetArcName(wchar *Name,int MaxSize);
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
// 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 wchar *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 wchar *CheckName,bool CheckFullPath,int MatchMode)
|
||||
{
|
||||
wchar *Name=ConvertPath(CheckName,NULL,0);
|
||||
wchar FullName[NM];
|
||||
wchar CurMask[NM];
|
||||
*FullName=0;
|
||||
Args->Rewind();
|
||||
while (Args->GetString(CurMask,ASIZE(CurMask)))
|
||||
{
|
||||
wchar *LastMaskChar=PointToLastChar(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.
|
||||
|
||||
*LastMaskChar=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// REMOVED, we want -npath\* to match empty folders too.
|
||||
// If mask has wildcards in name part and does not have the trailing
|
||||
// '\' character, we cannot use it for directories.
|
||||
|
||||
// if (IsWildcard(PointToName(CurMask)))
|
||||
// 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)
|
||||
wcsncatz(CurMask,L"*",ASIZE(CurMask));
|
||||
}
|
||||
|
||||
#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==0)
|
||||
ConvertNameToFull(CheckName,FullName,ASIZE(FullName));
|
||||
if (CmpName(CurMask,FullName,MatchMode))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
wchar NewName[NM+2],*CurName=Name;
|
||||
|
||||
// Important to convert before "*\" check below, so masks like
|
||||
// d:*\something are processed properly.
|
||||
wchar *CmpMask=ConvertPath(CurMask,NULL,0);
|
||||
|
||||
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.
|
||||
NewName[0]='.';
|
||||
NewName[1]=CPATHDIVIDER;
|
||||
wcsncpyz(NewName+2,Name,ASIZE(NewName)-2);
|
||||
CurName=NewName;
|
||||
}
|
||||
|
||||
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 (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,wchar *MatchedArg,uint MatchedArgSize)
|
||||
{
|
||||
if (MatchedArg!=NULL && MatchedArgSize>0)
|
||||
*MatchedArg=0;
|
||||
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.Dir && (FileHead.FileAttr & InclFileAttr)==0 ||
|
||||
FileHead.Dir && !InclDir))
|
||||
return 0;
|
||||
if (!Dir && SizeCheck(FileHead.UnpSize))
|
||||
return 0;
|
||||
#endif
|
||||
wchar *ArgName;
|
||||
FileArgs.Rewind();
|
||||
for (int StringCount=1;(ArgName=FileArgs.GetString())!=NULL;StringCount++)
|
||||
if (CmpName(ArgName,FileHead.FileName,MatchType))
|
||||
{
|
||||
if (ExactMatch!=NULL)
|
||||
*ExactMatch=wcsicompc(ArgName,FileHead.FileName)==0;
|
||||
if (MatchedArg!=NULL)
|
||||
wcsncpyz(MatchedArg,ArgName,MatchedArgSize);
|
||||
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
|
||||
118
unrar/cmdmix.cpp
118
unrar/cmdmix.cpp
@@ -1,118 +0,0 @@
|
||||
void CommandData::OutTitle()
|
||||
{
|
||||
if (BareOutput || DisableCopyright)
|
||||
return;
|
||||
#if defined(__GNUC__) && defined(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,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
|
||||
MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
|
||||
MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
|
||||
MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSL,MCHelpSwSM,
|
||||
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
|
||||
if (CmpMSGID(Help[I],MCHelpSwV))
|
||||
continue;
|
||||
#ifndef _WIN_ALL
|
||||
static MSGID Win32Only[]={
|
||||
MCHelpSwIEML,MCHelpSwVD,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
|
||||
MCHelpSwEP2,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
|
||||
#if !defined(_UNIX) && !defined(_WIN_ALL)
|
||||
if (CmpMSGID(Help[I],MCHelpSwOW))
|
||||
continue;
|
||||
#endif
|
||||
#if !defined(_WIN_ALL) && !defined(_EMX)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -6,16 +6,7 @@
|
||||
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 LOW_DIST_REP_COUNT = 16;
|
||||
|
||||
|
||||
@@ -49,14 +49,9 @@ void InitConsole()
|
||||
}
|
||||
|
||||
|
||||
void SetConsoleMsgStream(MESSAGE_TYPE MsgStream)
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,RAR_CHARSET RedirectCharset)
|
||||
{
|
||||
::MsgStream=MsgStream;
|
||||
}
|
||||
|
||||
|
||||
void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset)
|
||||
{
|
||||
::RedirectCharset=RedirectCharset;
|
||||
}
|
||||
|
||||
@@ -164,7 +159,7 @@ static void GetPasswordText(wchar *Str,uint MaxLength)
|
||||
SetConsoleMode(hConIn,ConInMode);
|
||||
SetConsoleMode(hConOut,ConOutMode);
|
||||
#else
|
||||
char StrA[MAXPASSWORD*4]; // "*4" for multibyte UTF-8 characters.
|
||||
char StrA[MAXPASSWORD];
|
||||
#if defined(_EMX) || defined (__VMS)
|
||||
fgets(StrA,ASIZE(StrA)-1,stdin);
|
||||
#elif defined(__sun)
|
||||
@@ -248,12 +243,6 @@ bool getwstr(wchar *str,size_t n)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
StrA[ReadSize]=0;
|
||||
|
||||
// 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,n);
|
||||
cleandata(&StrA[0],StrA.Size()); // We can use this function to enter passwords.
|
||||
}
|
||||
@@ -311,7 +300,7 @@ int Ask(const wchar *AskStr)
|
||||
|
||||
for (int I=0;I<NumItems;I++)
|
||||
{
|
||||
eprintf(I==0 ? (NumItems>3 ? L"\n":L" "):L", ");
|
||||
eprintf(I==0 ? (NumItems>4 ? L"\n":L" "):L", ");
|
||||
int KeyPos=ItemKeyPos[I];
|
||||
for (int J=0;J<KeyPos;J++)
|
||||
eprintf(L"%c",Item[I][J]);
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#define _RAR_CONSIO_
|
||||
|
||||
void InitConsole();
|
||||
void SetConsoleMsgStream(MESSAGE_TYPE MsgStream);
|
||||
void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset);
|
||||
void InitConsoleOptions(MESSAGE_TYPE MsgStream,RAR_CHARSET RedirectCharset);
|
||||
void OutComment(const wchar *Comment,size_t Size);
|
||||
|
||||
#ifndef SILENT
|
||||
|
||||
@@ -66,14 +66,14 @@ uint CRC32(uint StartCRC,const void *Addr,size_t Size)
|
||||
uint NextData = Data[4]|(Data[5] << 8)|(Data[6] << 16)|(Data[7] << 24);
|
||||
#else
|
||||
StartCRC ^= *(uint32 *) Data;
|
||||
uint NextData = *(uint32 *) (Data+4);
|
||||
uint NextData = *(uint32 *) (Data +4);
|
||||
#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[2][(byte)(NextData >>8 ) ] ^
|
||||
crc_tables[1][(byte)(NextData >> 16)] ^
|
||||
crc_tables[0][(byte)(NextData >> 24)];
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,co
|
||||
sha1_context c;
|
||||
sha1_init(&c);
|
||||
|
||||
const uint HashRounds=0x40000;
|
||||
for (uint I=0;I<HashRounds;I++)
|
||||
const int HashRounds=0x40000;
|
||||
for (int I=0;I<HashRounds;I++)
|
||||
{
|
||||
sha1_process_rar29( &c, RawPsw, RawLength );
|
||||
byte PswNum[3];
|
||||
@@ -47,8 +47,8 @@ void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,co
|
||||
}
|
||||
uint32 digest[5];
|
||||
sha1_done( &c, digest );
|
||||
for (uint I=0;I<4;I++)
|
||||
for (uint J=0;J<4;J++)
|
||||
for (int I=0;I<4;I++)
|
||||
for (int J=0;J<4;J++)
|
||||
AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
|
||||
|
||||
KDF3Cache[KDF3CachePos].Pwd=*Password;
|
||||
|
||||
@@ -35,14 +35,11 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||
DataSet *Data=NULL;
|
||||
try
|
||||
{
|
||||
ErrHandler.Clean();
|
||||
|
||||
r->OpenResult=0;
|
||||
Data=new DataSet;
|
||||
Data->Cmd.DllError=0;
|
||||
Data->OpenMode=r->OpenMode;
|
||||
Data->Cmd.FileArgs.AddString(L"*");
|
||||
Data->Cmd.KeepBroken=(r->OpFlags&ROADOF_KEEPBROKEN)!=0;
|
||||
|
||||
char AnsiArcName[NM];
|
||||
*AnsiArcName=0;
|
||||
@@ -51,7 +48,7 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||
strncpyz(AnsiArcName,r->ArcName,ASIZE(AnsiArcName));
|
||||
#ifdef _WIN_ALL
|
||||
if (!AreFileApisANSI())
|
||||
{
|
||||
{
|
||||
OemToCharBuffA(r->ArcName,AnsiArcName,ASIZE(AnsiArcName));
|
||||
AnsiArcName[ASIZE(AnsiArcName)-1]=0;
|
||||
}
|
||||
@@ -93,53 +90,39 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||
return NULL;
|
||||
}
|
||||
r->Flags=0;
|
||||
|
||||
|
||||
if (Data->Arc.Volume)
|
||||
r->Flags|=ROADF_VOLUME;
|
||||
if (Data->Arc.MainComment)
|
||||
r->Flags|=ROADF_COMMENT;
|
||||
r->Flags|=0x01;
|
||||
if (Data->Arc.Locked)
|
||||
r->Flags|=ROADF_LOCK;
|
||||
r->Flags|=0x04;
|
||||
if (Data->Arc.Solid)
|
||||
r->Flags|=ROADF_SOLID;
|
||||
r->Flags|=0x08;
|
||||
if (Data->Arc.NewNumbering)
|
||||
r->Flags|=ROADF_NEWNUMBERING;
|
||||
r->Flags|=0x10;
|
||||
if (Data->Arc.Signed)
|
||||
r->Flags|=ROADF_SIGNED;
|
||||
r->Flags|=0x20;
|
||||
if (Data->Arc.Protected)
|
||||
r->Flags|=ROADF_RECOVERY;
|
||||
r->Flags|=0x40;
|
||||
if (Data->Arc.Encrypted)
|
||||
r->Flags|=ROADF_ENCHEADERS;
|
||||
r->Flags|=0x80;
|
||||
if (Data->Arc.FirstVolume)
|
||||
r->Flags|=ROADF_FIRSTVOLUME;
|
||||
r->Flags|=0x100;
|
||||
|
||||
Array<wchar> CmtDataW;
|
||||
if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtDataW))
|
||||
{
|
||||
if (r->CmtBufW!=NULL)
|
||||
{
|
||||
CmtDataW.Push(0);
|
||||
size_t Size=wcslen(&CmtDataW[0])+1;
|
||||
|
||||
r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
|
||||
r->CmtSize=(uint)Min(Size,r->CmtBufSize);
|
||||
memcpy(r->CmtBufW,&CmtDataW[0],(r->CmtSize-1)*sizeof(*r->CmtBufW));
|
||||
r->CmtBufW[r->CmtSize-1]=0;
|
||||
}
|
||||
else
|
||||
if (r->CmtBuf!=NULL)
|
||||
{
|
||||
Array<char> CmtData(CmtDataW.Size()*4+1);
|
||||
memset(&CmtData[0],0,CmtData.Size());
|
||||
WideToChar(&CmtDataW[0],&CmtData[0],CmtData.Size()-1);
|
||||
size_t Size=strlen(&CmtData[0])+1;
|
||||
|
||||
r->Flags|=2;
|
||||
r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
|
||||
r->CmtSize=(uint)Min(Size,r->CmtBufSize);
|
||||
memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
|
||||
if (Size<=r->CmtBufSize)
|
||||
r->CmtBuf[r->CmtSize-1]=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
r->CmtState=r->CmtSize=0;
|
||||
Data->Extract.ExtractArchiveInit(Data->Arc);
|
||||
@@ -168,17 +151,10 @@ HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||
int PASCAL RARCloseArchive(HANDLE hArcData)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
try
|
||||
{
|
||||
bool Success=Data==NULL ? false:Data->Arc.Close();
|
||||
delete Data;
|
||||
return Success ? ERAR_SUCCESS : ERAR_ECLOSE;
|
||||
}
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
return Data->Cmd.DllError!=0 ? Data->Cmd.DllError : RarErrorToDll(ErrCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
|
||||
@@ -267,6 +243,9 @@ int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||
D->UnpSize=uint(hd->UnpSize & 0xffffffff);
|
||||
D->UnpSizeHigh=uint(hd->UnpSize>>32);
|
||||
D->HostOS=hd->HSType==HSYS_WINDOWS ? HOST_WIN32:HOST_UNIX;
|
||||
if (Data->Arc.Format==RARFMT50)
|
||||
D->UnpVer=Data->Arc.FileHead.UnpVer==0 ? 50 : 200; // If it is not 0, just set it to something big.
|
||||
else
|
||||
D->UnpVer=Data->Arc.FileHead.UnpVer;
|
||||
D->FileCRC=hd->FileHash.CRC32;
|
||||
D->FileTime=hd->mtime.GetDos();
|
||||
@@ -312,9 +291,6 @@ int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||
D->RedirNameSize>0 && D->RedirNameSize<100000)
|
||||
wcsncpyz(D->RedirName,hd->RedirName,D->RedirNameSize);
|
||||
D->DirTarget=hd->DirTarget;
|
||||
|
||||
/* added by me */
|
||||
D->WinSize = hd->WinSize;
|
||||
}
|
||||
catch (RAR_EXIT ErrCode)
|
||||
{
|
||||
@@ -403,7 +379,7 @@ int PASCAL ProcessFile(HANDLE hArcData, int Operation, char *DestPath,
|
||||
if (DestNameW!=NULL)
|
||||
wcsncpyz(Data->Cmd.DllDestName,DestNameW,ASIZE(Data->Cmd.DllDestName));
|
||||
|
||||
wcsncpyz(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T",ASIZE(Data->Cmd.Command));
|
||||
wcscpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T");
|
||||
Data->Cmd.Test=Operation!=RAR_EXTRACT;
|
||||
if (Operation == RAR_EXTRACT_CHUNK)
|
||||
{
|
||||
@@ -417,7 +393,7 @@ int PASCAL ProcessFile(HANDLE hArcData, int Operation, char *DestPath,
|
||||
|
||||
bool Repeat=false;
|
||||
if (Operation != RAR_EXTRACT_CHUNK)
|
||||
Data->Extract.ExtractCurrentFile(Data->Arc,Data->HeaderSize,Repeat);
|
||||
Data->Extract.ExtractCurrentFile(Data->Arc,Data->HeaderSize,Repeat);
|
||||
else
|
||||
{
|
||||
if (InitDataIO) //chunk, init
|
||||
@@ -456,7 +432,7 @@ int PASCAL ProcessFile(HANDLE hArcData, int Operation, char *DestPath,
|
||||
}
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
@@ -472,15 +448,15 @@ int PASCAL ProcessFile(HANDLE hArcData, int Operation, char *DestPath,
|
||||
|
||||
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName)
|
||||
{
|
||||
return ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL,NULL,0,
|
||||
NULL,false,NULL);
|
||||
return(ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL,NULL,0,
|
||||
NULL,false,NULL));
|
||||
}
|
||||
|
||||
|
||||
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar *DestPath,wchar *DestName)
|
||||
{
|
||||
return ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName,NULL,0,
|
||||
NULL,false,NULL);
|
||||
return(ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName,NULL,0,
|
||||
NULL,false,NULL));
|
||||
}
|
||||
|
||||
int PASCAL RARProcessFileChunkInit(HANDLE hArcData)
|
||||
@@ -529,16 +505,16 @@ void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataPro
|
||||
}
|
||||
|
||||
|
||||
#ifndef RAR_NOCRYPT
|
||||
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
|
||||
{
|
||||
#ifndef RAR_NOCRYPT
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
wchar PasswordW[MAXPASSWORD];
|
||||
GetWideName(Password,NULL,PasswordW,ASIZE(PasswordW));
|
||||
Data->Cmd.Password.Set(PasswordW);
|
||||
cleandata(PasswordW,sizeof(PasswordW));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int PASCAL RARGetDllVersion()
|
||||
@@ -552,7 +528,6 @@ static int RarErrorToDll(RAR_EXIT ErrCode)
|
||||
switch(ErrCode)
|
||||
{
|
||||
case RARX_FATAL:
|
||||
case RARX_READ:
|
||||
return ERAR_EREAD;
|
||||
case RARX_CRC:
|
||||
return ERAR_BAD_DATA;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _UNRAR_DLL_
|
||||
#define _UNRAR_DLL_
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(1)
|
||||
|
||||
#define ERAR_SUCCESS 0
|
||||
#define ERAR_END_ARCHIVE 10
|
||||
@@ -39,11 +39,9 @@
|
||||
#define RAR_HASH_CRC32 1
|
||||
#define RAR_HASH_BLAKE2 2
|
||||
|
||||
//Must be the same as MAXWINSIZE
|
||||
//not in original
|
||||
// should be a multiple of 16 becasue this buffer is passed
|
||||
// directly to UnpRead (bypassing UnstoreFile) and 16 is the size
|
||||
// of crypt blocks
|
||||
#define RAR_CHUNK_BUFFER_SIZE 0x100000UL
|
||||
#define RAR_CHUNK_BUFFER_SIZE 0x400000
|
||||
|
||||
#ifdef _UNIX
|
||||
#define CALLBACK
|
||||
@@ -133,8 +131,6 @@ struct RARHeaderDataEx
|
||||
/* removed by me: we don't need to retain binary compatibility in case new
|
||||
* fields are added, so we avoid wasting space here */
|
||||
/* unsigned int Reserved[988]; */
|
||||
/* added by me */
|
||||
size_t WinSize; /* window size */
|
||||
};
|
||||
|
||||
|
||||
@@ -161,8 +157,6 @@ typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM
|
||||
#define ROADF_ENCHEADERS 0x0080
|
||||
#define ROADF_FIRSTVOLUME 0x0100
|
||||
|
||||
#define ROADOF_KEEPBROKEN 0x0001
|
||||
|
||||
struct RAROpenArchiveDataEx
|
||||
{
|
||||
char *ArcName;
|
||||
@@ -176,10 +170,8 @@ struct RAROpenArchiveDataEx
|
||||
unsigned int Flags;
|
||||
UNRARCALLBACK Callback;
|
||||
LPARAM UserData;
|
||||
unsigned int OpFlags;
|
||||
wchar_t *CmtBufW;
|
||||
/* removed by me */
|
||||
/* unsigned int Reserved[25]; */
|
||||
/* unsigned int Reserved[28]; */
|
||||
};
|
||||
|
||||
enum UNRARCALLBACK_MESSAGES {
|
||||
@@ -214,6 +206,6 @@ int PASCAL RARGetDllVersion();
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack(pop)
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
10
unrar/dll.rc
10
unrar/dll.rc
@@ -2,8 +2,8 @@
|
||||
#include <commctrl.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6, 0, 2, 3610
|
||||
PRODUCTVERSION 6, 0, 2, 3610
|
||||
FILEVERSION 5, 50, 5, 2378
|
||||
PRODUCTVERSION 5, 50, 5, 2378
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
{
|
||||
@@ -14,9 +14,9 @@ FILETYPE VFT_APP
|
||||
VALUE "CompanyName", "Alexander Roshal\0"
|
||||
VALUE "ProductName", "RAR decompression library\0"
|
||||
VALUE "FileDescription", "RAR decompression library\0"
|
||||
VALUE "FileVersion", "6.0.2\0"
|
||||
VALUE "ProductVersion", "6.0.2\0"
|
||||
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2020\0"
|
||||
VALUE "FileVersion", "5.50.5\0"
|
||||
VALUE "ProductVersion", "5.50.5\0"
|
||||
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2017\0"
|
||||
VALUE "OriginalFilename", "Unrar.dll\0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
EXPORTS
|
||||
RAROpenArchive
|
||||
RAROpenArchiveEx
|
||||
RARCloseArchive
|
||||
RARReadHeader
|
||||
RARReadHeaderEx
|
||||
RARProcessFile
|
||||
RARProcessFileW
|
||||
RARSetCallback
|
||||
RARSetChangeVolProc
|
||||
RARSetProcessDataProc
|
||||
; RARSetPassword
|
||||
RARGetDllVersion
|
||||
@@ -11,53 +11,41 @@ EncodeFileName::EncodeFileName()
|
||||
|
||||
|
||||
|
||||
void EncodeFileName::Decode(char *Name,size_t NameSize,byte *EncName,size_t EncSize,
|
||||
wchar *NameW,size_t MaxDecSize)
|
||||
void EncodeFileName::Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,
|
||||
size_t MaxDecSize)
|
||||
{
|
||||
size_t EncPos=0,DecPos=0;
|
||||
byte HighByte=EncPos<EncSize ? EncName[EncPos++] : 0;
|
||||
byte HighByte=EncName[EncPos++];
|
||||
while (EncPos<EncSize && DecPos<MaxDecSize)
|
||||
{
|
||||
if (FlagBits==0)
|
||||
{
|
||||
if (EncPos>=EncSize)
|
||||
break;
|
||||
Flags=EncName[EncPos++];
|
||||
FlagBits=8;
|
||||
}
|
||||
switch(Flags>>6)
|
||||
{
|
||||
case 0:
|
||||
if (EncPos>=EncSize)
|
||||
break;
|
||||
NameW[DecPos++]=EncName[EncPos++];
|
||||
break;
|
||||
case 1:
|
||||
if (EncPos>=EncSize)
|
||||
break;
|
||||
NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8);
|
||||
break;
|
||||
case 2:
|
||||
if (EncPos+1>=EncSize)
|
||||
break;
|
||||
NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8);
|
||||
EncPos+=2;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
if (EncPos>=EncSize)
|
||||
break;
|
||||
int Length=EncName[EncPos++];
|
||||
if ((Length & 0x80)!=0)
|
||||
if (Length & 0x80)
|
||||
{
|
||||
if (EncPos>=EncSize)
|
||||
break;
|
||||
byte Correction=EncName[EncPos++];
|
||||
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize && DecPos<NameSize;Length--,DecPos++)
|
||||
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||
NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+(HighByte<<8);
|
||||
}
|
||||
else
|
||||
for (Length+=2;Length>0 && DecPos<MaxDecSize && DecPos<NameSize;Length--,DecPos++)
|
||||
for (Length+=2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||
NameW[DecPos]=Name[DecPos];
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,7 @@ class EncodeFileName
|
||||
public:
|
||||
EncodeFileName();
|
||||
size_t Encode(char *Name,wchar *NameW,byte *EncName);
|
||||
void Decode(char *Name,size_t NameSize,byte *EncName,size_t EncSize,wchar *NameW,size_t MaxDecSize);
|
||||
void Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,size_t MaxDecSize);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
113
unrar/errhnd.cpp
113
unrar/errhnd.cpp
@@ -15,7 +15,6 @@ void ErrorHandler::Clean()
|
||||
UserBreak=false;
|
||||
MainExit=false;
|
||||
DisableShutdown=false;
|
||||
ReadErrIgnoreAll=false;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,12 +41,9 @@ void ErrorHandler::CloseError(const wchar *FileName)
|
||||
uiMsg(UIERROR_FILECLOSE,FileName);
|
||||
SysErrMsg();
|
||||
}
|
||||
// We must not call Exit and throw an exception here, because this function
|
||||
// is called from File object destructor and can be invoked when stack
|
||||
// unwinding while handling another exception. Throwing a new exception
|
||||
// when stack unwinding is prohibited and terminates a program.
|
||||
// If necessary, we can check std::uncaught_exception() before throw.
|
||||
SetErrorCode(RARX_FATAL);
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Exit(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -57,34 +53,24 @@ void ErrorHandler::ReadError(const wchar *FileName)
|
||||
ReadErrorMsg(FileName);
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Exit(RARX_READ);
|
||||
Exit(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::AskRepeatRead(const wchar *FileName,bool &Ignore,bool &Retry,bool &Quit)
|
||||
bool ErrorHandler::AskRepeatRead(const wchar *FileName)
|
||||
{
|
||||
SetErrorCode(RARX_READ);
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
if (!Silent)
|
||||
{
|
||||
uiMsg(UIERROR_FILEREAD,UINULL,FileName);
|
||||
SysErrMsg();
|
||||
if (ReadErrIgnoreAll)
|
||||
Ignore=true;
|
||||
else
|
||||
{
|
||||
bool All=false;
|
||||
uiAskRepeatRead(FileName,Ignore,All,Retry,Quit);
|
||||
if (All)
|
||||
ReadErrIgnoreAll=Ignore=true;
|
||||
if (Quit) // Disable shutdown if user select Quit in read error prompt.
|
||||
DisableShutdown=true;
|
||||
}
|
||||
return;
|
||||
bool Repeat=uiAskRepeatRead(FileName);
|
||||
if (!Repeat) // Disable shutdown if user pressed Cancel in error dialog.
|
||||
DisableShutdown=true;
|
||||
return Repeat;
|
||||
}
|
||||
#endif
|
||||
Ignore=true; // Saving the file part for -y or -inul or "Ignore all" choice.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +155,6 @@ void ErrorHandler::OpenErrorMsg(const wchar *FileName)
|
||||
|
||||
void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
|
||||
uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_OPEN);
|
||||
@@ -200,7 +185,7 @@ void ErrorHandler::ReadErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_FILEREAD,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_READ);
|
||||
SetErrorCode(RARX_FATAL);
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +267,6 @@ void _stdfunction ProcessSignal(int SigType)
|
||||
#endif
|
||||
|
||||
ErrHandler.UserBreak=true;
|
||||
ErrHandler.SetDisableShutdown();
|
||||
mprintf(St(MBreak));
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
@@ -306,7 +290,7 @@ void _stdfunction ProcessSignal(int SigType)
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_MSC_VER)
|
||||
// Never reached, just to avoid a compiler warning
|
||||
// never reached, just to avoid a compiler warning
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
@@ -338,15 +322,36 @@ void ErrorHandler::Throw(RAR_EXIT Code)
|
||||
}
|
||||
|
||||
|
||||
bool ErrorHandler::GetSysErrMsg(wchar *Msg,size_t Size)
|
||||
void ErrorHandler::SysErrMsg()
|
||||
{
|
||||
#ifndef SILENT
|
||||
#if !defined(SFX_MODULE) && !defined(SILENT)
|
||||
#ifdef _WIN_ALL
|
||||
wchar *lpMsgBuf=NULL;
|
||||
int ErrType=GetLastError();
|
||||
if (ErrType!=0)
|
||||
return FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,ErrType,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
|
||||
Msg,(DWORD)Size,NULL)!=0;
|
||||
if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,0,NULL))
|
||||
{
|
||||
wchar *CurMsg=lpMsgBuf;
|
||||
while (CurMsg!=NULL)
|
||||
{
|
||||
while (*CurMsg=='\r' || *CurMsg=='\n')
|
||||
CurMsg++;
|
||||
if (*CurMsg==0)
|
||||
break;
|
||||
wchar *EndMsg=wcschr(CurMsg,'\r');
|
||||
if (EndMsg==NULL)
|
||||
EndMsg=wcschr(CurMsg,'\n');
|
||||
if (EndMsg!=NULL)
|
||||
{
|
||||
*EndMsg=0;
|
||||
EndMsg++;
|
||||
}
|
||||
uiMsg(UIERROR_SYSERRMSG,CurMsg);
|
||||
CurMsg=EndMsg;
|
||||
}
|
||||
}
|
||||
LocalFree( lpMsgBuf );
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
@@ -355,46 +360,12 @@ bool ErrorHandler::GetSysErrMsg(wchar *Msg,size_t Size)
|
||||
char *err=strerror(errno);
|
||||
if (err!=NULL)
|
||||
{
|
||||
CharToWide(err,Msg,Size);
|
||||
return true;
|
||||
wchar Msg[1024];
|
||||
CharToWide(err,Msg,ASIZE(Msg));
|
||||
uiMsg(UIERROR_SYSERRMSG,Msg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SysErrMsg()
|
||||
{
|
||||
#if !defined(SFX_MODULE) && !defined(SILENT)
|
||||
wchar Msg[1024];
|
||||
if (!GetSysErrMsg(Msg,ASIZE(Msg)))
|
||||
return;
|
||||
#ifdef _WIN_ALL
|
||||
wchar *CurMsg=Msg;
|
||||
while (CurMsg!=NULL) // Print string with \r\n as several strings to multiple lines.
|
||||
{
|
||||
while (*CurMsg=='\r' || *CurMsg=='\n')
|
||||
CurMsg++;
|
||||
if (*CurMsg==0)
|
||||
break;
|
||||
wchar *EndMsg=wcschr(CurMsg,'\r');
|
||||
if (EndMsg==NULL)
|
||||
EndMsg=wcschr(CurMsg,'\n');
|
||||
if (EndMsg!=NULL)
|
||||
{
|
||||
*EndMsg=0;
|
||||
EndMsg++;
|
||||
}
|
||||
uiMsg(UIERROR_SYSERRMSG,CurMsg);
|
||||
CurMsg=EndMsg;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
uiMsg(UIERROR_SYSERRMSG,Msg);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@ enum RAR_EXIT // RAR exit code.
|
||||
RARX_CREATE = 9,
|
||||
RARX_NOFILES = 10,
|
||||
RARX_BADPWD = 11,
|
||||
RARX_READ = 12,
|
||||
RARX_USERBREAK = 255
|
||||
};
|
||||
|
||||
|
||||
class ErrorHandler
|
||||
{
|
||||
private:
|
||||
@@ -28,7 +26,6 @@ class ErrorHandler
|
||||
bool EnableBreak;
|
||||
bool Silent;
|
||||
bool DisableShutdown; // Shutdown is not suitable after last error.
|
||||
bool ReadErrIgnoreAll;
|
||||
public:
|
||||
ErrorHandler();
|
||||
void Clean();
|
||||
@@ -36,7 +33,7 @@ class ErrorHandler
|
||||
void OpenError(const wchar *FileName);
|
||||
void CloseError(const wchar *FileName);
|
||||
void ReadError(const wchar *FileName);
|
||||
void AskRepeatRead(const wchar *FileName,bool &Ignore,bool &Retry,bool &Quit);
|
||||
bool AskRepeatRead(const wchar *FileName);
|
||||
void WriteError(const wchar *ArcName,const wchar *FileName);
|
||||
void WriteErrorFAT(const wchar *FileName);
|
||||
bool AskRepeatWrite(const wchar *FileName,bool DiskFull);
|
||||
@@ -59,12 +56,10 @@ class ErrorHandler
|
||||
uint GetErrorCount() {return ErrCount;}
|
||||
void SetSignalHandlers(bool Enable);
|
||||
void Throw(RAR_EXIT Code);
|
||||
void SetSilent(bool Mode) {Silent=Mode;}
|
||||
bool GetSysErrMsg(wchar *Msg,size_t Size);
|
||||
void SetSilent(bool Mode) {Silent=Mode;};
|
||||
void SysErrMsg();
|
||||
int GetSystemErrorCode();
|
||||
void SetSystemErrorCode(int Code);
|
||||
void SetDisableShutdown() {DisableShutdown=true;}
|
||||
bool IsShutdownEnabled() {return !DisableShutdown;}
|
||||
|
||||
bool UserBreak; // Ctrl+Break is pressed.
|
||||
|
||||
@@ -93,25 +93,6 @@ static int CalcAllowedDepth(const wchar *Name)
|
||||
}
|
||||
|
||||
|
||||
// Check if all existing path components are directories and not links.
|
||||
static bool LinkInPath(const wchar *Name)
|
||||
{
|
||||
wchar Path[NM];
|
||||
if (wcslen(Name)>=ASIZE(Path))
|
||||
return true; // It should not be that long, skip.
|
||||
wcsncpyz(Path,Name,ASIZE(Path));
|
||||
for (wchar *s=Path+wcslen(Path)-1;s>Path;s--)
|
||||
if (IsPathDiv(*s))
|
||||
{
|
||||
*s=0;
|
||||
FindData FD;
|
||||
if (FindFile::FastFind(Path,&FD,true) && (FD.IsLink || !FD.IsDir))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName)
|
||||
{
|
||||
// Catch root dir based /path/file paths also as stuff like \\?\.
|
||||
@@ -119,25 +100,7 @@ bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *Pr
|
||||
// is a root based.
|
||||
if (IsFullRootPath(SrcName) || IsFullRootPath(TargetName))
|
||||
return false;
|
||||
|
||||
// Number of ".." in link target.
|
||||
int UpLevels=0;
|
||||
for (int Pos=0;*TargetName!=0;Pos++)
|
||||
{
|
||||
bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
|
||||
(IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
|
||||
(Pos==0 || IsPathDiv(*(TargetName-1)));
|
||||
if (Dot2)
|
||||
UpLevels++;
|
||||
TargetName++;
|
||||
}
|
||||
// If link target includes "..", it must not have another links
|
||||
// in the path, because they can bypass our safety check. For example,
|
||||
// suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
|
||||
// or "dir/lnk1" -> ".." first and "dir/lnk1/lnk2" -> ".." next.
|
||||
if (UpLevels>0 && LinkInPath(PrepSrcName))
|
||||
return false;
|
||||
|
||||
|
||||
// We could check just prepared src name, but for extra safety
|
||||
// we check both original (as from archive header) and prepared
|
||||
// (after applying the destination path and -ep switches) names.
|
||||
@@ -156,6 +119,17 @@ bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *Pr
|
||||
}
|
||||
int PrepAllowedDepth=CalcAllowedDepth(PrepSrcName);
|
||||
|
||||
// Number of ".." in link target.
|
||||
int UpLevels=0;
|
||||
for (int Pos=0;*TargetName!=0;Pos++)
|
||||
{
|
||||
bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
|
||||
(IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
|
||||
(Pos==0 || IsPathDiv(*(TargetName-1)));
|
||||
if (Dot2)
|
||||
UpLevels++;
|
||||
TargetName++;
|
||||
}
|
||||
return AllowedDepth>=UpLevels && PrepAllowedDepth>=UpLevels;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user