mirror of
https://github.com/php-win-ext/php-rar.git
synced 2026-03-24 04:52:07 +01:00
Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38fe9a67c4 | ||
|
|
1a623543c4 | ||
|
|
cfffb63b5a | ||
|
|
c99b6925ad | ||
|
|
792c622f3e | ||
|
|
3f507ce2db | ||
|
|
7ba9c28e15 | ||
|
|
717d75ec8e | ||
|
|
498286b7af | ||
|
|
d1c7fcd5a1 | ||
|
|
55d30dfa5d | ||
|
|
52f8a34342 | ||
|
|
5a930a03aa | ||
|
|
234a78c2f7 | ||
|
|
19b94313c2 | ||
|
|
7b2749af57 | ||
|
|
ab26d28575 | ||
|
|
488dd3caaa | ||
|
|
1dc896be94 | ||
|
|
36345d004e | ||
|
|
8f070c282f | ||
|
|
91ed5b09a0 | ||
|
|
d95cab037b | ||
|
|
7cff10aa2c | ||
|
|
5b94797037 | ||
|
|
4ff664b2b0 | ||
|
|
2e13165bdb | ||
|
|
d0cd509090 | ||
|
|
bd65eab735 | ||
|
|
45742b94ab | ||
|
|
6545fdd215 | ||
|
|
08f8190e49 | ||
|
|
095b4cdd58 | ||
|
|
da32228c34 | ||
|
|
2788a30227 | ||
|
|
e0c6c97ef0 | ||
|
|
2322542282 | ||
|
|
2b12de7a8f | ||
|
|
23430540f1 | ||
|
|
e3f3ecd1ab | ||
|
|
544f55920a | ||
|
|
24b421e0e6 | ||
|
|
05a48cbbeb | ||
|
|
6d0e583ef9 | ||
|
|
714f15cb06 | ||
|
|
58bb195ae3 | ||
|
|
5293a8f07e | ||
|
|
61edb08973 | ||
|
|
adc9fe7d39 | ||
|
|
5eb1055447 | ||
|
|
7ca7561e09 | ||
|
|
61eca15136 | ||
|
|
dc8ee65999 | ||
|
|
656c3fa69d | ||
|
|
a6bea8fec8 | ||
|
|
3b405bea8e | ||
|
|
18cd0568aa | ||
|
|
dc298847c7 | ||
|
|
246a80fdeb | ||
|
|
4b6fd31d08 | ||
|
|
44e35b8f6a | ||
|
|
fe4a94305b | ||
|
|
0453380858 | ||
|
|
957fc7702d | ||
|
|
5a0cd32191 | ||
|
|
5ca8d78562 | ||
|
|
1225c9240e | ||
|
|
10932c2450 | ||
|
|
b79f595379 | ||
|
|
479372f714 | ||
|
|
121310f696 | ||
|
|
43589ad851 | ||
|
|
b3145c9883 | ||
|
|
5a9886a844 | ||
|
|
bdd4ce2357 | ||
|
|
2fd19b59ca | ||
|
|
83756881c2 | ||
|
|
cc7edac87b | ||
|
|
a05875667e | ||
|
|
6bb74bf820 | ||
|
|
1a2f9f5104 | ||
|
|
0fd6896a25 | ||
|
|
d2a8a89e64 | ||
|
|
d95d7a794f | ||
|
|
9129dab024 | ||
|
|
897139b2ce | ||
|
|
2a29f7e763 | ||
|
|
3a830bc07c | ||
|
|
119722d581 | ||
|
|
4f821913ad | ||
|
|
6939711766 | ||
|
|
c499b4d2d2 | ||
|
|
a191673249 | ||
|
|
c6f8765250 | ||
|
|
5402805db0 | ||
|
|
e6e481cfb2 | ||
|
|
a3c0236a7d | ||
|
|
f8ee7cc273 | ||
|
|
e699b159cf | ||
|
|
41875e7bd6 | ||
|
|
3a2688b3eb | ||
|
|
524d195253 | ||
|
|
e1609b9dfd | ||
|
|
4f804014ca | ||
|
|
abe9816391 | ||
|
|
5876366b26 | ||
|
|
c1e389af0d | ||
|
|
73972e070d | ||
|
|
74aed951bb | ||
|
|
26929db6a9 | ||
|
|
4fb28f3858 | ||
|
|
4e04320979 | ||
|
|
b72aaff789 | ||
|
|
3b2d2eb296 | ||
|
|
166fe908ad | ||
|
|
0265686bbd | ||
|
|
f650a6e340 | ||
|
|
a20ca1559c | ||
|
|
2ab141deed | ||
|
|
498cad468e | ||
|
|
65d5132550 | ||
|
|
358432a7eb | ||
|
|
bbeab2dc4e | ||
|
|
5f81d8688f | ||
|
|
d6dfd5054c | ||
|
|
5d1e369c38 | ||
|
|
2f36bd7cac | ||
|
|
34859cf5b4 | ||
|
|
99cb19e838 | ||
|
|
f19f569f44 | ||
|
|
762b1ae3b0 | ||
|
|
fe2d2f46e4 | ||
|
|
6391dc21ca | ||
|
|
98bcf3697a | ||
|
|
4cda46d212 | ||
|
|
b2bc8dc586 | ||
|
|
96eec2b31c | ||
|
|
d5f04a3a88 | ||
|
|
13cb064031 | ||
|
|
a238d20430 | ||
|
|
66e2666696 | ||
|
|
55a328ff22 | ||
|
|
e632e338ef | ||
|
|
2ea5d74e6d | ||
|
|
5840034b59 | ||
|
|
d72ef1dbce | ||
|
|
e2db202b89 | ||
|
|
1cf4e2c02c | ||
|
|
ee28abf175 | ||
|
|
113935cbc5 |
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [macintoshplus] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
# patreon: # Replace with a single Patreon username
|
||||
# open_collective: # Replace with a single Open Collective username
|
||||
# ko_fi: # Replace with a single Ko-fi username
|
||||
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
# liberapay: # Replace with a single Liberapay username
|
||||
# issuehunt: # Replace with a single IssueHunt username
|
||||
# otechie: # Replace with a single Otechie username
|
||||
# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
# custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
27
.github/workflows/ci.yml
vendored
Normal file
27
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
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
Normal file
49
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
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 }}
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -6,10 +6,12 @@
|
||||
/tests/*.log
|
||||
/tests/*.php
|
||||
/tests/*.out
|
||||
/tests/*.mem
|
||||
/run-tests.php
|
||||
/modules
|
||||
/missing
|
||||
/.deps
|
||||
*.dep
|
||||
/.libs
|
||||
/Makefile
|
||||
/Makefile.fragments
|
||||
@@ -22,12 +24,14 @@
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.nice
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/configure.in
|
||||
/configure.ac
|
||||
/install-sh
|
||||
/intl.la
|
||||
/libtool
|
||||
@@ -36,3 +40,11 @@
|
||||
/.cproject
|
||||
/.project
|
||||
/.settings
|
||||
/pecl-rar.*
|
||||
/rar.la
|
||||
*.autosave
|
||||
/unrar/.libs
|
||||
/tmp-php.ini
|
||||
/php-rar.creator.user
|
||||
/compile_commands.json
|
||||
/.clangd
|
||||
|
||||
68
LICENSE
Normal file
68
LICENSE
Normal file
@@ -0,0 +1,68 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2010 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission. For
|
||||
written permission, please contact group@php.net.
|
||||
|
||||
4. Products derived from this software may not be called "PHP", nor
|
||||
may "PHP" appear in their name, without prior written permission
|
||||
from group@php.net. You may indicate that your software works in
|
||||
conjunction with PHP by saying "Foo for PHP" instead of calling
|
||||
it "PHP Foo" or "phpfoo"
|
||||
|
||||
5. The PHP Group may publish revised and/or new versions of the
|
||||
license from time to time. Each version will be given a
|
||||
distinguishing version number.
|
||||
Once covered code has been published under a particular version
|
||||
of the license, you may always continue to use it under the terms
|
||||
of that version. You may also choose to use such covered code
|
||||
under the terms of any subsequent version of the license
|
||||
published by the PHP Group. No one other than the PHP Group has
|
||||
the right to modify the terms applicable to covered code created
|
||||
under this License.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the PHP Group.
|
||||
|
||||
The PHP Group can be contacted via Email at group@php.net.
|
||||
|
||||
For more information on the PHP Group and the PHP project,
|
||||
please see <http://www.php.net>.
|
||||
|
||||
PHP includes the Zend Engine, freely available at
|
||||
<http://www.zend.com>.
|
||||
6
Makefile.frag
Normal file
6
Makefile.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
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
|
||||
12
README
12
README
@@ -1,12 +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.
|
||||
|
||||
42
README.md
Normal file
42
README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
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
|
||||
```
|
||||
21
composer.json
Normal file
21
composer.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
79
config.m4
79
config.m4
@@ -4,29 +4,70 @@ dnl config.m4 for extension rar
|
||||
PHP_ARG_ENABLE(rar, whether to enable rar support,
|
||||
[ --enable-rar Enable rar support])
|
||||
|
||||
unrar_sources="unrar/rar.cpp unrar/strlist.cpp unrar/strfn.cpp \
|
||||
unrar/pathfn.cpp unrar/smallfn.cpp unrar/savepos.cpp \
|
||||
unrar/global.cpp unrar/file.cpp unrar/filefn.cpp \
|
||||
unrar/filcreat.cpp unrar/archive.cpp unrar/arcread.cpp \
|
||||
unrar/unicode.cpp unrar/system.cpp unrar/isnt.cpp \
|
||||
unrar/crypt.cpp unrar/crc.cpp unrar/rawread.cpp \
|
||||
unrar/encname.cpp unrar/resource.cpp unrar/match.cpp \
|
||||
unrar/timefn.cpp unrar/rdwrfn.cpp unrar/consio.cpp \
|
||||
unrar/options.cpp unrar/ulinks.cpp unrar/errhnd.cpp \
|
||||
unrar/rarvm.cpp unrar/rijndael.cpp unrar/getbits.cpp \
|
||||
unrar/sha1.cpp unrar/extinfo.cpp unrar/extract.cpp \
|
||||
unrar/volume.cpp unrar/find.cpp \
|
||||
unrar/unpack.cpp unrar/cmddata.cpp unrar/dll.cpp \
|
||||
unrar/filestr.cpp unrar/recvol.cpp unrar/rs.cpp \
|
||||
unrar/scantree.cpp unrar/log.cpp unrar/extractchunk.cpp \
|
||||
unrar/secpassword.cpp"
|
||||
unrar_sources="unrar/sha256.cpp unrar/qopen.cpp \
|
||||
unrar/blake2s.cpp unrar/recvol.cpp \
|
||||
unrar/headers.cpp unrar/match.cpp \
|
||||
unrar/find.cpp \
|
||||
unrar/resource.cpp \
|
||||
unrar/pathfn.cpp \
|
||||
unrar/dll.cpp unrar/threadpool.cpp unrar/volume.cpp \
|
||||
unrar/unpack.cpp \
|
||||
unrar/extract.cpp unrar/errhnd.cpp \
|
||||
unrar/crc.cpp unrar/rijndael.cpp unrar/crypt.cpp \
|
||||
unrar/rawread.cpp \
|
||||
unrar/rs.cpp unrar/smallfn.cpp \
|
||||
unrar/isnt.cpp unrar/rar.cpp unrar/consio.cpp \
|
||||
unrar/scantree.cpp unrar/archive.cpp unrar/strfn.cpp \
|
||||
unrar/strlist.cpp \
|
||||
unrar/getbits.cpp unrar/hash.cpp \
|
||||
unrar/filestr.cpp \
|
||||
unrar/extinfo.cpp unrar/ui.cpp unrar/rarvm.cpp \
|
||||
unrar/timefn.cpp unrar/sha1.cpp \
|
||||
unrar/rdwrfn.cpp unrar/rs16.cpp unrar/cmddata.cpp \
|
||||
unrar/extractchunk.cpp unrar/system.cpp \
|
||||
unrar/unicode.cpp unrar/filcreat.cpp \
|
||||
unrar/arcread.cpp unrar/filefn.cpp \
|
||||
unrar/global.cpp unrar/list.cpp \
|
||||
unrar/encname.cpp unrar/file.cpp \
|
||||
unrar/secpassword.cpp unrar/options.cpp"
|
||||
|
||||
|
||||
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_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 $unrar_sources, $ext_shared,,-DRARDLL -DGUI -DSILENT -Wno-write-strings -Wno-logical-op-parentheses -I@ext_srcdir@/unrar)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c rar_time.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -Wno-write-strings -Wall -fvisibility=hidden -I@ext_srcdir@/unrar)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||
fi
|
||||
|
||||
47
config.w32
47
config.w32
@@ -4,25 +4,34 @@
|
||||
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", PHP_RAR_SHARED, "/DRARDLL /DGUI /DSILENT /EHsc /D_WSTDIO_DEFINED");
|
||||
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");
|
||||
ADD_SOURCES(configure_module_dirname + "/unrar",
|
||||
"rar.cpp strlist.cpp strfn.cpp \
|
||||
pathfn.cpp smallfn.cpp savepos.cpp \
|
||||
global.cpp file.cpp filefn.cpp \
|
||||
filcreat.cpp archive.cpp arcread.cpp \
|
||||
unicode.cpp system.cpp isnt.cpp \
|
||||
crypt.cpp crc.cpp rawread.cpp \
|
||||
encname.cpp resource.cpp match.cpp \
|
||||
timefn.cpp rdwrfn.cpp consio.cpp \
|
||||
options.cpp ulinks.cpp errhnd.cpp \
|
||||
rarvm.cpp rijndael.cpp getbits.cpp \
|
||||
sha1.cpp extinfo.cpp extract.cpp \
|
||||
volume.cpp find.cpp \
|
||||
unpack.cpp cmddata.cpp dll.cpp \
|
||||
filestr.cpp recvol.cpp rs.cpp \
|
||||
scantree.cpp extractchunk.cpp log.cpp", "rar");
|
||||
|
||||
"sha256.cpp qopen.cpp \
|
||||
blake2s.cpp recvol.cpp \
|
||||
headers.cpp match.cpp \
|
||||
find.cpp \
|
||||
resource.cpp \
|
||||
pathfn.cpp \
|
||||
dll.cpp threadpool.cpp volume.cpp \
|
||||
unpack.cpp \
|
||||
extract.cpp errhnd.cpp \
|
||||
crc.cpp rijndael.cpp crypt.cpp \
|
||||
rawread.cpp \
|
||||
rs.cpp smallfn.cpp \
|
||||
isnt.cpp rar.cpp consio.cpp \
|
||||
scantree.cpp archive.cpp strfn.cpp \
|
||||
strlist.cpp \
|
||||
getbits.cpp hash.cpp \
|
||||
filestr.cpp \
|
||||
extinfo.cpp ui.cpp rarvm.cpp \
|
||||
timefn.cpp sha1.cpp \
|
||||
rdwrfn.cpp rs16.cpp cmddata.cpp \
|
||||
extractchunk.cpp system.cpp \
|
||||
unicode.cpp filcreat.cpp \
|
||||
arcread.cpp filefn.cpp \
|
||||
global.cpp list.cpp \
|
||||
encname.cpp file.cpp \
|
||||
secpassword.cpp options.cpp", "rar", "unrar_obj");
|
||||
|
||||
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
||||
}
|
||||
|
||||
|
||||
|
||||
143
package.xml
143
package.xml
@@ -23,11 +23,11 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<active>no</active>
|
||||
</developer>
|
||||
|
||||
<date>2013-10-11</date>
|
||||
<time>13:00:00</time>
|
||||
<date>2020-12-06</date>
|
||||
<time>20:00:00</time>
|
||||
<version>
|
||||
<release>3.0.2</release>
|
||||
<api>3.0.0</api>
|
||||
<release>4.2.0</release>
|
||||
<api>4.2.0</api>
|
||||
</version>
|
||||
|
||||
<stability>
|
||||
@@ -36,8 +36,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
</stability>
|
||||
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<notes>- Fixed build with PHP 5.5.
|
||||
- Upgraded bundled unrar to version 4.2.4.
|
||||
<notes>- Support PHP 8.
|
||||
- Merge unrar 6.0.2.
|
||||
- RarArchive implements IteratorAggregate (PHP 8 only).
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
@@ -142,6 +143,22 @@ 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"/>
|
||||
@@ -157,6 +174,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file role="test" name="multi.part2.rar"/>
|
||||
<file role="test" name="multi.part3.rar"/>
|
||||
<file role="test" name="multi_broken.part1.rar"/>
|
||||
<file role="test" name="php8compat.php.inc"/>
|
||||
<file role="test" name="rar_notrar.rar"/>
|
||||
<file role="test" name="rar_unicode.rar"/>
|
||||
<file role="test" name="repeated_name.rar"/>
|
||||
@@ -165,6 +183,9 @@ 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" />
|
||||
@@ -173,9 +194,14 @@ 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="beosea.cpp" role="src" />
|
||||
<file name="blake2s.cpp" role="src" />
|
||||
<file name="blake2s.hpp" role="src" />
|
||||
<file name="blake2s_sse.cpp" role="src" />
|
||||
<file name="blake2sp.cpp" role="src" />
|
||||
<file name="cmddata.cpp" role="src" />
|
||||
<file name="cmddata.hpp" role="src" />
|
||||
<file name="cmdfilter.cpp" role="src" />
|
||||
<file name="cmdmix.cpp" role="src" />
|
||||
<file name="coder.cpp" role="src" />
|
||||
<file name="coder.hpp" role="src" />
|
||||
<file name="compress.hpp" role="src" />
|
||||
@@ -185,6 +211,10 @@ 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" />
|
||||
@@ -210,7 +240,12 @@ 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" />
|
||||
@@ -226,9 +261,10 @@ 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" />
|
||||
@@ -237,11 +273,31 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="rartypes.hpp" role="src" />
|
||||
<file name="rarvm.cpp" role="src" />
|
||||
<file name="rarvm.hpp" role="src" />
|
||||
<file name="rarvmtbl.cpp" role="src" />
|
||||
<file name="rawint.hpp" role="src" />
|
||||
<file name="rawread.cpp" role="src" />
|
||||
<file name="rawread.hpp" role="src" />
|
||||
<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" />
|
||||
@@ -251,7 +307,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="rijndael.hpp" role="src" />
|
||||
<file name="rs.cpp" role="src" />
|
||||
<file name="rs.hpp" role="src" />
|
||||
<file name="savepos.cpp" role="src" />
|
||||
<file name="savepos.hpp" role="src" />
|
||||
<file name="scantree.cpp" role="src" />
|
||||
<file name="scantree.hpp" role="src" />
|
||||
@@ -272,10 +327,8 @@ 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" />
|
||||
@@ -287,17 +340,23 @@ 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="README" role="doc" />
|
||||
<file name="LICENSE" role="doc" />
|
||||
<file name="Makefile.frag" role="src" />
|
||||
<file name="README.md" role="doc" />
|
||||
<file name="example.php" role="doc" />
|
||||
<file name="php_compat.h" role="src" />
|
||||
<file name="php_rar.h" role="src" />
|
||||
<file name="rar.c" role="src" />
|
||||
<file name="rar_stream.c" role="src" />
|
||||
<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>
|
||||
@@ -305,7 +364,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>5.2.0</min>
|
||||
<min>5.3.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0</min>
|
||||
@@ -316,8 +375,58 @@ 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>
|
||||
@@ -368,7 +477,7 @@ For the other changes, see the changelog for version 2.0.0RC1.
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2010-01-17</date>
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<license>PHP License and UnRar license</license>
|
||||
<notes>Changes in respect to release 1.0.0:
|
||||
PHP SUPPORT:
|
||||
- Support for PHP 4.3 dropped. PHP 5.2.x or 5.3.x is required.
|
||||
@@ -405,7 +514,7 @@ Other changes:
|
||||
- A lot of refactoring and compilation as C, not C++.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>1.0.0</release>
|
||||
|
||||
11
php-rar.config
Normal file
11
php-rar.config
Normal file
@@ -0,0 +1,11 @@
|
||||
// Add predefined macros for your project here. For example:
|
||||
// #define THE_ANSWER 42
|
||||
#define RARDLL 1
|
||||
#define HAVE_CONFIG_H 1
|
||||
#define _Float32 float
|
||||
#define _Float32x float
|
||||
#define _Float64 double
|
||||
#define _Float64x double
|
||||
#define _Float128 long double
|
||||
#define _Float128x long double
|
||||
#define _BITS_FLOATN_H
|
||||
1
php-rar.creator
Normal file
1
php-rar.creator
Normal file
@@ -0,0 +1 @@
|
||||
[General]
|
||||
161
php-rar.files
Normal file
161
php-rar.files
Normal file
@@ -0,0 +1,161 @@
|
||||
config.h
|
||||
php_compat.h
|
||||
php_compat.h
|
||||
php_rar.h
|
||||
rar.c
|
||||
rar_error.c
|
||||
rar_navigation.c
|
||||
rar_stream.c
|
||||
rar_time.c
|
||||
rararch.c
|
||||
rarentry.c
|
||||
unrar/arccmt.cpp
|
||||
unrar/archive.cpp
|
||||
unrar/archive.hpp
|
||||
unrar/arcread.cpp
|
||||
unrar/array.hpp
|
||||
unrar/blake2s.cpp
|
||||
unrar/blake2s.hpp
|
||||
unrar/blake2s_sse.cpp
|
||||
unrar/blake2sp.cpp
|
||||
unrar/cmddata.cpp
|
||||
unrar/cmddata.hpp
|
||||
unrar/cmdfilter.cpp
|
||||
unrar/cmdmix.cpp
|
||||
unrar/coder.cpp
|
||||
unrar/coder.hpp
|
||||
unrar/compress.hpp
|
||||
unrar/consio.cpp
|
||||
unrar/consio.hpp
|
||||
unrar/crc.cpp
|
||||
unrar/crc.hpp
|
||||
unrar/crypt.cpp
|
||||
unrar/crypt.hpp
|
||||
unrar/crypt1.cpp
|
||||
unrar/crypt2.cpp
|
||||
unrar/crypt3.cpp
|
||||
unrar/crypt5.cpp
|
||||
unrar/dll.cpp
|
||||
unrar/dll.hpp
|
||||
unrar/encname.cpp
|
||||
unrar/encname.hpp
|
||||
unrar/errhnd.cpp
|
||||
unrar/errhnd.hpp
|
||||
unrar/extinfo.cpp
|
||||
unrar/extinfo.hpp
|
||||
unrar/extract.cpp
|
||||
unrar/extract.hpp
|
||||
unrar/extractchunk.cpp
|
||||
unrar/filcreat.cpp
|
||||
unrar/filcreat.hpp
|
||||
unrar/file.cpp
|
||||
unrar/file.hpp
|
||||
unrar/filefn.cpp
|
||||
unrar/filefn.hpp
|
||||
unrar/filestr.cpp
|
||||
unrar/filestr.hpp
|
||||
unrar/find.cpp
|
||||
unrar/find.hpp
|
||||
unrar/getbits.cpp
|
||||
unrar/getbits.hpp
|
||||
unrar/global.cpp
|
||||
unrar/global.hpp
|
||||
unrar/hardlinks.cpp
|
||||
unrar/hash.cpp
|
||||
unrar/hash.hpp
|
||||
unrar/headers.cpp
|
||||
unrar/headers.hpp
|
||||
unrar/headers5.hpp
|
||||
unrar/isnt.cpp
|
||||
unrar/isnt.hpp
|
||||
unrar/list.cpp
|
||||
unrar/list.hpp
|
||||
unrar/loclang.hpp
|
||||
unrar/log.cpp
|
||||
unrar/log.hpp
|
||||
unrar/match.cpp
|
||||
unrar/match.hpp
|
||||
unrar/model.cpp
|
||||
unrar/model.hpp
|
||||
unrar/options.cpp
|
||||
unrar/options.hpp
|
||||
unrar/os.hpp
|
||||
unrar/pathfn.cpp
|
||||
unrar/pathfn.hpp
|
||||
unrar/qopen.cpp
|
||||
unrar/qopen.hpp
|
||||
unrar/rar.cpp
|
||||
unrar/rar.hpp
|
||||
unrar/rardefs.hpp
|
||||
unrar/rarlang.hpp
|
||||
unrar/raros.hpp
|
||||
unrar/rartypes.hpp
|
||||
unrar/rarvm.cpp
|
||||
unrar/rarvm.hpp
|
||||
unrar/rarvmtbl.cpp
|
||||
unrar/rawint.hpp
|
||||
unrar/rawread.cpp
|
||||
unrar/rawread.hpp
|
||||
unrar/rdwrfn.cpp
|
||||
unrar/rdwrfn.hpp
|
||||
unrar/recvol.cpp
|
||||
unrar/recvol.hpp
|
||||
unrar/recvol3.cpp
|
||||
unrar/recvol5.cpp
|
||||
unrar/resource.cpp
|
||||
unrar/resource.hpp
|
||||
unrar/rijndael.cpp
|
||||
unrar/rijndael.hpp
|
||||
unrar/rs.cpp
|
||||
unrar/rs.hpp
|
||||
unrar/rs16.cpp
|
||||
unrar/rs16.hpp
|
||||
unrar/savepos.hpp
|
||||
unrar/scantree.cpp
|
||||
unrar/scantree.hpp
|
||||
unrar/secpassword.cpp
|
||||
unrar/secpassword.hpp
|
||||
unrar/sha1.cpp
|
||||
unrar/sha1.hpp
|
||||
unrar/sha256.cpp
|
||||
unrar/sha256.hpp
|
||||
unrar/smallfn.cpp
|
||||
unrar/smallfn.hpp
|
||||
unrar/strfn.cpp
|
||||
unrar/strfn.hpp
|
||||
unrar/strlist.cpp
|
||||
unrar/strlist.hpp
|
||||
unrar/suballoc.cpp
|
||||
unrar/suballoc.hpp
|
||||
unrar/system.cpp
|
||||
unrar/system.hpp
|
||||
unrar/threadmisc.cpp
|
||||
unrar/threadpool.cpp
|
||||
unrar/threadpool.hpp
|
||||
unrar/timefn.cpp
|
||||
unrar/timefn.hpp
|
||||
unrar/ui.cpp
|
||||
unrar/ui.hpp
|
||||
unrar/uicommon.cpp
|
||||
unrar/uiconsole.cpp
|
||||
unrar/uisilent.cpp
|
||||
unrar/ulinks.cpp
|
||||
unrar/ulinks.hpp
|
||||
unrar/unicode.cpp
|
||||
unrar/unicode.hpp
|
||||
unrar/unpack.cpp
|
||||
unrar/unpack.hpp
|
||||
unrar/unpack15.cpp
|
||||
unrar/unpack20.cpp
|
||||
unrar/unpack30.cpp
|
||||
unrar/unpack50.cpp
|
||||
unrar/unpack50frag.cpp
|
||||
unrar/unpack50mt.cpp
|
||||
unrar/unpackinline.cpp
|
||||
unrar/uowners.cpp
|
||||
unrar/version.hpp
|
||||
unrar/volume.cpp
|
||||
unrar/volume.hpp
|
||||
unrar/win32acl.cpp
|
||||
unrar/win32lnk.cpp
|
||||
unrar/win32stm.cpp
|
||||
4
php-rar.includes
Normal file
4
php-rar.includes
Normal file
@@ -0,0 +1,4 @@
|
||||
/home/glopes/repos/php-src/Zend
|
||||
/home/glopes/repos/php-src/TSRM
|
||||
/home/glopes/repos/php-src/main
|
||||
/home/glopes/repos/php-src
|
||||
72
php_compat.h
Normal file
72
php_compat.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#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
|
||||
39
php_rar.h
39
php_rar.h
@@ -46,10 +46,12 @@
|
||||
#ifndef PHP_RAR_H
|
||||
#define PHP_RAR_H
|
||||
|
||||
#include <php.h>
|
||||
|
||||
extern zend_module_entry rar_module_entry;
|
||||
#define phpext_rar_ptr &rar_module_entry
|
||||
|
||||
#define PHP_RAR_VERSION "3.0.2"
|
||||
#define PHP_RAR_VERSION "4.2.1"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_RAR_API __declspec(dllexport)
|
||||
@@ -61,11 +63,14 @@ 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 */
|
||||
/* only these includes are necessary anyway: */
|
||||
#include "unrar/raros.hpp"
|
||||
#include "unrar/rartypes.hpp"
|
||||
/* no need to reinclude windows.h or new.h */
|
||||
#define LEAN_RAR_INCLUDES
|
||||
#include "unrar/os.hpp"
|
||||
@@ -76,8 +81,10 @@ enum HOST_SYSTEM {
|
||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||
HOST_BEOS=5,HOST_MAX
|
||||
};
|
||||
#define LHD_WINDOWMASK 0x00e0U
|
||||
#define LHD_DIRECTORY 0x00e0U
|
||||
enum FILE_SYSTEM_REDIRECT {
|
||||
FSREDIR_NONE=0, FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION,
|
||||
FSREDIR_HARDLINK, FSREDIR_FILECOPY
|
||||
};
|
||||
|
||||
/* maximum comment size if 64KB */
|
||||
#define RAR_MAX_COMMENT_SIZE 65536
|
||||
@@ -88,7 +95,7 @@ typedef struct _rar_cb_user_data {
|
||||
} rar_cb_user_data;
|
||||
|
||||
typedef struct rar {
|
||||
zend_object_handle id;
|
||||
rar_obj_ref obj_ref;
|
||||
struct _rar_entries *entries;
|
||||
struct RAROpenArchiveDataEx *list_open_data;
|
||||
struct RAROpenArchiveDataEx *extract_open_data;
|
||||
@@ -100,7 +107,7 @@ typedef struct rar {
|
||||
} rar_file_t;
|
||||
|
||||
/* Misc */
|
||||
#ifdef ZTS
|
||||
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||
# define RAR_TSRMLS_TC , void ***
|
||||
#else
|
||||
# define RAR_TSRMLS_TC
|
||||
@@ -135,7 +142,7 @@ typedef struct _rar_contents_cache {
|
||||
int misses;
|
||||
/* args: cache key, cache key size, cached object) */
|
||||
void (*put)(const char *, uint, zval * RAR_TSRMLS_TC);
|
||||
zval *(*get)(const char *, uint RAR_TSRMLS_TC);
|
||||
zval *(*get)(const char *, uint, zval * RAR_TSRMLS_TC);
|
||||
} rar_contents_cache;
|
||||
|
||||
/* Module globals, currently used for dir wrappers cache */
|
||||
@@ -170,6 +177,15 @@ ZEND_EXTERN_MODULE_GLOBALS(rar);
|
||||
#endif
|
||||
|
||||
/* Other compatibility quirks */
|
||||
/* PHP 5.3 doesn't have ZVAL_COPY_VALUE */
|
||||
#if !defined(ZEND_COPY_VALUE) && PHP_MAJOR_VERSION == 5
|
||||
#define ZVAL_COPY_VALUE(z, v) \
|
||||
do { \
|
||||
(z)->value = (v)->value; \
|
||||
Z_TYPE_P(z) = Z_TYPE_P(v); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRNLEN) || !HAVE_STRNLEN
|
||||
size_t _rar_strnlen(const char *s, size_t maxlen);
|
||||
# define strnlen _rar_strnlen
|
||||
@@ -262,8 +278,9 @@ void _rar_close_file_resource(rar_file_t *rar);
|
||||
/* Fetches the rar_file_t part of the RarArchive object in order to use the
|
||||
* operations above and (discouraged) to have direct access to the fields
|
||||
* RarEntry::extract/getStream access extract_open_dat and cb_userdata */
|
||||
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC);
|
||||
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
||||
int _rar_get_file_resource_zv(zval *zv_file, rar_file_t **rar_file TSRMLS_DC);
|
||||
int _rar_get_file_resource_zv_ex(zval *zv_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
||||
int _rar_get_file_resource_ex(rar_obj_ref objref_file, rar_file_t **rar_file, int silent TSRMLS_DC);
|
||||
void minit_rararch(TSRMLS_D);
|
||||
|
||||
PHP_FUNCTION(rar_open);
|
||||
@@ -291,6 +308,12 @@ 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 */
|
||||
|
||||
|
||||
|
||||
80
rar.c
80
rar.c
@@ -160,8 +160,14 @@ void _rar_destroy_userdata(rar_cb_user_data *udata) /* {{{ */
|
||||
efree(udata->password);
|
||||
}
|
||||
|
||||
if (udata->callable != NULL)
|
||||
if (udata->callable != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&udata->callable);
|
||||
#else
|
||||
zval_ptr_dtor(udata->callable);
|
||||
efree(udata->callable);
|
||||
#endif
|
||||
}
|
||||
|
||||
udata->password = NULL;
|
||||
udata->callable = NULL;
|
||||
@@ -295,7 +301,8 @@ int _rar_find_file_p(struct RAROpenArchiveDataEx *open_data, /* IN */
|
||||
|
||||
while ((result = RARReadHeaderEx(*arc_handle, used_header_data)) == 0) {
|
||||
/* skip entries that were split before with incrementing current pos */
|
||||
if ((used_header_data->Flags & 0x01U) || (curpos++ != position)) {
|
||||
if ((used_header_data->Flags & RHDF_SPLITBEFORE) ||
|
||||
(curpos++ != position)) {
|
||||
process_result = RARProcessFile(*arc_handle, RAR_SKIP, NULL, NULL);
|
||||
} else {
|
||||
*found = TRUE;
|
||||
@@ -403,7 +410,7 @@ PHP_FUNCTION(rar_wrapper_cache_stats) /* {{{ */
|
||||
len = spprintf(&result, 0, "%u/%u (hits/misses)",
|
||||
RAR_G(contents_cache).hits, RAR_G(contents_cache).misses);
|
||||
|
||||
RETURN_STRINGL(result, len, 0);
|
||||
RAR_RETURN_STRINGL(result, len, 0);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
@@ -440,27 +447,50 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||
zend_fcall_info_cache *cache
|
||||
TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *failed_vol,
|
||||
*retval_ptr = NULL,
|
||||
**params;
|
||||
#else
|
||||
zval failed_vol,
|
||||
retval,
|
||||
*params,
|
||||
*const retval_ptr = &retval;
|
||||
#endif
|
||||
int ret = -1;
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(failed_vol);
|
||||
ZVAL_STRING(failed_vol, dst_buffer, 1);
|
||||
RAR_ZVAL_STRING(failed_vol, dst_buffer, 1);
|
||||
params = &failed_vol;
|
||||
fci->retval_ptr_ptr = &retval_ptr;
|
||||
fci->params = ¶ms;
|
||||
#else
|
||||
ZVAL_STRING(&failed_vol, dst_buffer);
|
||||
ZVAL_NULL(&retval);
|
||||
params = &failed_vol;
|
||||
fci->retval = &retval;
|
||||
fci->params = params;
|
||||
#endif
|
||||
fci->param_count = 1;
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (zend_call_function(fci, cache TSRMLS_CC) != SUCCESS ||
|
||||
fci->retval_ptr_ptr == NULL ||
|
||||
*fci->retval_ptr_ptr == NULL) {
|
||||
#else
|
||||
if (zend_call_function(fci, cache TSRMLS_CC) != SUCCESS || EG(exception)) {
|
||||
#endif
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Failure to call volume find callback");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(*fci->retval_ptr_ptr == retval_ptr);
|
||||
#else
|
||||
assert(fci->retval == &retval);
|
||||
#endif
|
||||
if (Z_TYPE_P(retval_ptr) == IS_NULL) {
|
||||
/* let return -1 */
|
||||
}
|
||||
@@ -499,9 +529,15 @@ static int _rar_unrar_volume_user_callback(char* dst_buffer,
|
||||
}
|
||||
|
||||
cleanup:
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&failed_vol);
|
||||
if (retval_ptr != NULL)
|
||||
if (retval_ptr != NULL) {
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
}
|
||||
#else
|
||||
zval_ptr_dtor(&failed_vol);
|
||||
zval_ptr_dtor(&retval);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -615,12 +651,15 @@ static zend_function_entry rar_functions[] = {
|
||||
/* {{{ Globals' related activities */
|
||||
ZEND_DECLARE_MODULE_GLOBALS(rar);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static int _rar_array_apply_remove_first(void *pDest TSRMLS_DC)
|
||||
#else
|
||||
static int _rar_array_apply_remove_first(zval *pDest TSRMLS_DC)
|
||||
#endif
|
||||
{
|
||||
return (ZEND_HASH_APPLY_STOP | ZEND_HASH_APPLY_REMOVE);
|
||||
}
|
||||
|
||||
/* caller should increment zval refcount before calling this */
|
||||
static void _rar_contents_cache_put(const char *key,
|
||||
uint key_len,
|
||||
zval *zv TSRMLS_DC)
|
||||
@@ -633,21 +672,38 @@ static void _rar_contents_cache_put(const char *key,
|
||||
zend_hash_apply(cc->data, _rar_array_apply_remove_first TSRMLS_CC);
|
||||
assert(zend_hash_num_elements(cc->data) == cur_size - 1);
|
||||
}
|
||||
zval_add_ref(&zv);
|
||||
rar_zval_add_ref(&zv);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(Z_REFCOUNT_P(zv) > 1);
|
||||
SEPARATE_ZVAL(&zv); /* ensure we store a heap allocated copy */
|
||||
zend_hash_update(cc->data, key, key_len, &zv, sizeof(zv), NULL);
|
||||
#else
|
||||
zend_hash_str_update(cc->data, key, key_len, zv);
|
||||
#endif
|
||||
}
|
||||
|
||||
static zval *_rar_contents_cache_get(const char *key,
|
||||
uint key_len TSRMLS_DC)
|
||||
uint key_len,
|
||||
zval *rv TSRMLS_DC)
|
||||
{
|
||||
rar_contents_cache *cc = &RAR_G(contents_cache);
|
||||
zval **element = NULL;
|
||||
zend_hash_find(cc->data, key, key_len, (void **) &element);
|
||||
zval *element = NULL;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval **element_p = NULL;
|
||||
zend_hash_find(cc->data, key, key_len, (void **) &element_p);
|
||||
if (element_p) {
|
||||
element = *element_p;
|
||||
}
|
||||
#else
|
||||
element = zend_hash_str_find(cc->data, key, key_len);
|
||||
#endif
|
||||
|
||||
if (element != NULL) {
|
||||
cc->hits++;
|
||||
zval_add_ref(element);
|
||||
return *element;
|
||||
INIT_ZVAL(*rv);
|
||||
ZVAL_COPY_VALUE(rv, element);
|
||||
zval_copy_ctor(rv);
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
cc->misses++;
|
||||
|
||||
33
rar_error.c
33
rar_error.c
@@ -70,7 +70,7 @@ void _rar_handle_ext_error(const char *format TSRMLS_DC, ...) /* {{{ */
|
||||
va_list arg;
|
||||
char *message;
|
||||
|
||||
#ifdef ZTS
|
||||
#if defined(ZTS) && PHP_MAJOR_VERSION < 7
|
||||
va_start(arg, TSRMLS_C);
|
||||
#else
|
||||
va_start(arg, format);
|
||||
@@ -91,9 +91,13 @@ int _rar_using_exceptions(TSRMLS_D)
|
||||
zval *pval;
|
||||
pval = zend_read_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, (zend_bool) 1 TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(Z_TYPE_P(pval) == IS_BOOL);
|
||||
|
||||
return Z_BVAL_P(pval);
|
||||
#else
|
||||
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
||||
return Z_TYPE_P(pval) == IS_TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* returns a string or NULL if not an error */
|
||||
@@ -182,7 +186,11 @@ PHP_METHOD(rarexception, setUsingExceptions)
|
||||
Return whether exceptions are being used */
|
||||
PHP_METHOD(rarexception, isUsingExceptions)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval **pval;
|
||||
#else
|
||||
zval *pval;
|
||||
#endif
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE ) {
|
||||
return;
|
||||
@@ -192,15 +200,25 @@ PHP_METHOD(rarexception, isUsingExceptions)
|
||||
#if PHP_VERSION_ID < 50399
|
||||
pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, (zend_bool) 0 TSRMLS_CC);
|
||||
#else
|
||||
#elif PHP_MAJOR_VERSION < 7
|
||||
pval = zend_std_get_static_property(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, (zend_bool) 0, NULL TSRMLS_CC);
|
||||
#else
|
||||
zend_string *prop_name =
|
||||
zend_string_init("usingExceptions", sizeof("usingExceptions") - 1, 0);
|
||||
pval = zend_std_get_static_property(rarexception_ce_ptr, prop_name,
|
||||
(zend_bool) 0);
|
||||
zend_string_release(prop_name);
|
||||
#endif
|
||||
/* property always exists */
|
||||
assert(pval != NULL);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(Z_TYPE_PP(pval) == IS_BOOL);
|
||||
|
||||
RETURN_ZVAL(*pval, 0, 0);
|
||||
#else
|
||||
assert(Z_TYPE_P(pval) == IS_TRUE || Z_TYPE_P(pval) == IS_FALSE);
|
||||
RETURN_ZVAL(pval, 0, 0);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -224,12 +242,17 @@ void minit_rarerror(TSRMLS_D) /* {{{ */
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||
zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
||||
#else
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||
zend_ce_exception);
|
||||
#endif
|
||||
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
||||
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
||||
ZEND_ACC_PRIVATE | ZEND_ACC_STATIC TSRMLS_CC);
|
||||
ZEND_ACC_STATIC TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ static void _rar_nav_get_depth_and_length(wchar_t *filenamew, const size_t file_
|
||||
int *depth_out, size_t *wlen_out TSRMLS_DC);
|
||||
static int _rar_nav_get_depth(const wchar_t *filenamew, const size_t file_size);
|
||||
static int _rar_nav_compare_entries(const void *op1, const void *op2 TSRMLS_DC);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
static void _rar_nav_swap_entries(void *op1, void *op2);
|
||||
#endif
|
||||
static int _rar_nav_compare_entries_std(const void *op1, const void *op2);
|
||||
static inline int _rar_nav_compare_values(const wchar_t *str1, const int depth1,
|
||||
const wchar_t *str2, const int depth2,
|
||||
@@ -113,9 +116,15 @@ void _rar_entry_search_start(rar_file_t *rar,
|
||||
sizeof rar->entries->entries_array_s[0]);
|
||||
memcpy(rar->entries->entries_array_s, rar->entries->entries_array,
|
||||
rar->entries->num_entries * sizeof rar->entries->entries_array[0]);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zend_qsort(rar->entries->entries_array_s, rar->entries->num_entries,
|
||||
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries
|
||||
TSRMLS_CC);
|
||||
#else
|
||||
zend_qsort(rar->entries->entries_array_s, rar->entries->num_entries,
|
||||
sizeof *rar->entries->entries_array_s, _rar_nav_compare_entries,
|
||||
_rar_nav_swap_entries);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@@ -137,7 +146,11 @@ void _rar_entry_search_seek(rar_find_output *state, size_t pos)
|
||||
/* {{{ _rar_entry_search_end */
|
||||
void _rar_entry_search_end(rar_find_output *state)
|
||||
{
|
||||
efree(state);
|
||||
if (state) {
|
||||
/* may not have been initialized due to error conditions
|
||||
* in rararch_it_get_iterator that jumped out of the function */
|
||||
efree(state);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -300,6 +313,9 @@ 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);
|
||||
@@ -340,7 +356,11 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
ents->last_accessed = NULL;
|
||||
|
||||
while (result == 0) {
|
||||
struct RARHeaderDataEx entry;
|
||||
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) {
|
||||
@@ -350,19 +370,19 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
break;
|
||||
|
||||
if (first_file_check) {
|
||||
if (entry.Flags & 0x01U) /* LHD_SPLIT_BEFORE */
|
||||
if (entry.Flags & RHDF_SPLITBEFORE)
|
||||
continue;
|
||||
else
|
||||
first_file_check = FALSE;
|
||||
}
|
||||
|
||||
/* reset packed size if not split before */
|
||||
if ((entry.Flags & 0x01U) == 0)
|
||||
if ((entry.Flags & RHDF_SPLITBEFORE) == 0)
|
||||
packed_size = 0UL;
|
||||
|
||||
/* we would exceed size of ulong. cap at ulong_max
|
||||
* equivalent to packed_size + entry.PackSize > ULONG_MAX,
|
||||
* but without overflowing */
|
||||
* equivalent to packed_size + entry.PackSize > ULONG_MAX,
|
||||
* but without overflowing */
|
||||
if (ULONG_MAX - packed_size < entry.PackSize)
|
||||
packed_size = ULONG_MAX;
|
||||
else {
|
||||
@@ -376,7 +396,7 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.Flags & 0x02U) /* LHD_SPLIT_AFTER; do not commit */
|
||||
if (entry.Flags & RHDF_SPLITAFTER) /* do not commit */
|
||||
continue;
|
||||
|
||||
/* commit the entry */
|
||||
@@ -388,16 +408,22 @@ int _rar_list_files(rar_file_t *rar TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
assert(capacity > ents->num_entries);
|
||||
|
||||
ents->entries_array[ents->num_entries] =
|
||||
ents->entries_array[ents->num_entries] = ue =
|
||||
emalloc(sizeof *ents->entries_array[0]);
|
||||
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;
|
||||
memcpy(&ue->entry, &entry, sizeof ents->entries_array[0]->entry);
|
||||
ue->id = ents->num_entries;
|
||||
ue->packed_size = packed_size;
|
||||
_rar_nav_get_depth_and_length(entry.FileNameW,
|
||||
sizeof(entry.FileNameW) / sizeof(entry.FileNameW[0]), /* = 1024 */
|
||||
&ents->entries_array[ents->num_entries]->depth,
|
||||
&ents->entries_array[ents->num_entries]->name_wlen TSRMLS_CC);
|
||||
&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->num_entries++;
|
||||
}
|
||||
|
||||
@@ -423,7 +449,7 @@ static void _rar_nav_get_depth_and_length(wchar_t *filenamew, const size_t file_
|
||||
for (i = 0; i < file_size; i++) {
|
||||
if (filenamew[i] == L'\0')
|
||||
break;
|
||||
if (filenamew[i] == PATHDIVIDERW[0])
|
||||
if (filenamew[i] == SPATHDIVIDER[0])
|
||||
depth++;
|
||||
}
|
||||
|
||||
@@ -435,7 +461,7 @@ static void _rar_nav_get_depth_and_length(wchar_t *filenamew, const size_t file_
|
||||
filenamew[i] = L'\0';
|
||||
}
|
||||
|
||||
if ((i >= 1) && (filenamew[i-1] == PATHDIVIDERW[0])) {
|
||||
if ((i >= 1) && (filenamew[i-1] == SPATHDIVIDER[0])) {
|
||||
/* entry name ended in path divider. shouldn't happen */
|
||||
i--;
|
||||
filenamew[i] = L'\0';
|
||||
@@ -456,7 +482,7 @@ static int _rar_nav_get_depth(const wchar_t *filenamew, const size_t file_size)
|
||||
for (i = 0; i < file_size; i++) {
|
||||
if (filenamew[i] == L'\0')
|
||||
break;
|
||||
if (filenamew[i] == PATHDIVIDERW[0])
|
||||
if (filenamew[i] == SPATHDIVIDER[0])
|
||||
depth++;
|
||||
}
|
||||
assert(i < file_size);
|
||||
@@ -476,6 +502,21 @@ static int _rar_nav_compare_entries(const void *op1, const void *op2 TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
static void _rar_nav_swap_entries(void *op1, void *op2) /* {{{ */
|
||||
{
|
||||
/* just swaps two pointer values */
|
||||
struct _rar_unique_entry **a = op1,
|
||||
**b = op2,
|
||||
*tmp;
|
||||
tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
static int _rar_nav_compare_entries_std(const void *op1, const void *op2) /* {{{ */
|
||||
{
|
||||
const struct _rar_unique_entry *a = *((struct _rar_unique_entry **) op1),
|
||||
@@ -517,7 +558,7 @@ static int _rar_nav_directory_match(const wchar_t *dir, const size_t dir_len,
|
||||
if (wmemcmp(dir, entry, dir_len) != 0)
|
||||
return FALSE;
|
||||
/* directory name does not follow path sep or path sep ends the name */
|
||||
if (entry[dir_len] != PATHDIVIDERW[0] || entry_len == dir_len + 1)
|
||||
if (entry[dir_len] != SPATHDIVIDER[0] || entry_len == dir_len + 1)
|
||||
return FALSE;
|
||||
/* assert(entry_len > dir_len + 1) */
|
||||
entry_rem = &entry[dir_len + 1];
|
||||
@@ -528,7 +569,7 @@ static int _rar_nav_directory_match(const wchar_t *dir, const size_t dir_len,
|
||||
entry_rem_len = entry_len;
|
||||
}
|
||||
|
||||
chr = wmemchr(entry_rem, PATHDIVIDERW[0], entry_rem_len);
|
||||
chr = wmemchr(entry_rem, SPATHDIVIDER[0], entry_rem_len);
|
||||
/* must have no / after the directory */
|
||||
return (chr == NULL);
|
||||
}
|
||||
|
||||
371
rar_stream.c
371
rar_stream.c
@@ -41,7 +41,6 @@ extern "C" {
|
||||
#include <wchar.h>
|
||||
|
||||
#include "php_rar.h"
|
||||
#include "unrar/rartypes.hpp"
|
||||
|
||||
#include <php_streams.h>
|
||||
#include <ext/standard/url.h>
|
||||
@@ -52,10 +51,11 @@ typedef struct php_rar_stream_data_t {
|
||||
struct RAROpenArchiveDataEx open_data;
|
||||
struct RARHeaderDataEx header_data;
|
||||
HANDLE rar_handle;
|
||||
size_t file_size;
|
||||
/* TODO: consider encapsulating a php memory/tmpfile stream */
|
||||
unsigned char *buffer;
|
||||
size_t buffer_size;
|
||||
size_t buffer_cont_size; /* content size */
|
||||
size_t buffer_read_size; /* content size */
|
||||
size_t buffer_pos;
|
||||
uint64 cursor;
|
||||
int no_more_data;
|
||||
@@ -64,7 +64,7 @@ typedef struct php_rar_stream_data_t {
|
||||
} php_rar_stream_data, *php_rar_stream_data_P;
|
||||
|
||||
typedef struct php_rar_dir_stream_data_t {
|
||||
zval *rar_obj;
|
||||
zval rar_obj;
|
||||
rar_find_output *state;
|
||||
struct RARHeaderDataEx *self_header; /* NULL for root */
|
||||
wchar_t *directory;
|
||||
@@ -99,7 +99,11 @@ static char *_rar_wide_to_utf_with_alloc(const wchar_t *wide, int len)
|
||||
/* {{{ RAR file streams */
|
||||
|
||||
/* {{{ php_rar_ops_read */
|
||||
#if PHP_VERSION_ID < 70400
|
||||
static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||
#else
|
||||
static ssize_t php_rar_ops_read(php_stream *stream, char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
size_t n = 0;
|
||||
STREAM_DATA_FROM_STREAM
|
||||
@@ -114,12 +118,12 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
while (left > 0) {
|
||||
size_t this_read_size;
|
||||
/* if nothing in the buffer or buffer already read, fill buffer */
|
||||
if (/*self->buffer_cont_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_cont_size)
|
||||
if (/*self->buffer_read_size == 0 || > condition not necessary */
|
||||
self->buffer_pos == self->buffer_read_size)
|
||||
{
|
||||
int res;
|
||||
self->buffer_pos = 0;
|
||||
self->buffer_cont_size = 0;
|
||||
self->buffer_read_size = 0;
|
||||
/* Note: this condition is important, you cannot rely on
|
||||
* having a call to RARProcessFileChunk return no data and
|
||||
* break on the condition self->buffer_cont_size == 0 because
|
||||
@@ -129,25 +133,25 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
if (self->no_more_data)
|
||||
break;
|
||||
res = RARProcessFileChunk(self->rar_handle, self->buffer,
|
||||
self->buffer_size, &self->buffer_cont_size,
|
||||
self->buffer_size, &self->buffer_read_size,
|
||||
&self->no_more_data);
|
||||
if (_rar_handle_error(res TSRMLS_CC) == FAILURE) {
|
||||
break; /* finish in case of failure */
|
||||
}
|
||||
assert(self->buffer_cont_size <= self->buffer_size);
|
||||
assert(self->buffer_read_size <= self->buffer_size);
|
||||
/* we did not read anything. no need to continue */
|
||||
if (self->buffer_cont_size == 0)
|
||||
if (self->buffer_read_size == 0)
|
||||
break;
|
||||
}
|
||||
/* if we get here we have data to be read in the buffer */
|
||||
this_read_size = MIN(left,
|
||||
self->buffer_cont_size - self->buffer_pos);
|
||||
self->buffer_read_size - self->buffer_pos);
|
||||
assert(this_read_size > 0);
|
||||
memcpy(&buf[count-left], &self->buffer[self->buffer_pos],
|
||||
this_read_size);
|
||||
left -= this_read_size;
|
||||
n += this_read_size;
|
||||
self->buffer_pos += this_read_size;
|
||||
self->buffer_pos += this_read_size;
|
||||
assert(left >= 0);
|
||||
}
|
||||
|
||||
@@ -156,9 +160,16 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
|
||||
/* no more data upstream (for sure), buffer already read and
|
||||
* caller asked for more data than we're giving */
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_cont_size &&
|
||||
((size_t) n) < count)
|
||||
if (self->no_more_data && self->buffer_pos == self->buffer_read_size &&
|
||||
n < count && stream->eof != 1) {
|
||||
stream->eof = 1;
|
||||
if (self->cursor > self->file_size) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"The file size is supposed to be %lu bytes, but "
|
||||
"we read more: %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) {
|
||||
@@ -168,17 +179,29 @@ static size_t php_rar_ops_read(php_stream *stream, char *buf, size_t count TSRML
|
||||
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;
|
||||
@@ -266,50 +289,20 @@ static mode_t _rar_convert_file_attrs(unsigned os_attrs,
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((flags & LHD_WINDOWMASK) == LHD_DIRECTORY)
|
||||
if (flags & RHDF_DIRECTORY)
|
||||
ret = S_IFDIR;
|
||||
else
|
||||
ret = S_IFREG;
|
||||
|
||||
ret |= 0777;
|
||||
ret &= ~mask;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* If from is not set, sets to to default and returns SUCCESS.
|
||||
* If from is set, converts it to a time_t. In case of failure returns FAILURE.
|
||||
* In case of success, copies the result to to and returns SUCCESS. */
|
||||
static int _rar_time_convert(RARTime *from, time_t *to) /* {{{ */
|
||||
{
|
||||
time_t default_ = (time_t) 0;
|
||||
time_t retval;
|
||||
struct tm time_s = {0};
|
||||
|
||||
if (from->Year == 0U) {
|
||||
*to = default_;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
time_s.tm_sec = from->Second;
|
||||
time_s.tm_min = from->Minute;
|
||||
time_s.tm_hour = from->Hour;
|
||||
time_s.tm_mday = from->Day;
|
||||
time_s.tm_mon = from->Month - 1; /* starts at 0 in time_t */
|
||||
time_s.tm_year = from->Year - 1900;
|
||||
|
||||
if ((retval = mktime(&time_s)) == -1)
|
||||
return FAILURE;
|
||||
else {
|
||||
*to = retval;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
php_stream_statbuf *ssb) /* {{{ */
|
||||
{
|
||||
@@ -324,7 +317,7 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
* SUBHEAD_TYPE_UOWNER), but it is not exposed in unRAR */
|
||||
ssb->sb.st_uid = 0;
|
||||
ssb->sb.st_gid = 0;
|
||||
#ifdef HAVE_ST_RDEV
|
||||
#if defined(HAVE_ST_RDEV) || defined(HAVE_STRUCT_STAT_ST_RDEV)
|
||||
ssb->sb.st_rdev = 0;
|
||||
#endif
|
||||
/* never mind signedness, we'll never get sizes big enough for that to
|
||||
@@ -339,32 +332,26 @@ 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->atime, &ssb->sb.st_atime);
|
||||
_rar_time_convert(&header->ctime, &ssb->sb.st_ctime);
|
||||
|
||||
if (header->mtime.Year == 0) { /* high precision mod time undefined */
|
||||
struct tm time_s = {0};
|
||||
if (header->MtimeLow == 0 && header->MtimeHigh == 0) {
|
||||
/* high precision mod time undefined */
|
||||
time_t time;
|
||||
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)
|
||||
if (rar_dos_time_convert(header->FileTime, &time) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
ssb->sb.st_mtime = time;
|
||||
}
|
||||
else
|
||||
_rar_time_convert(&header->mtime, &ssb->sb.st_mtime);
|
||||
else {
|
||||
rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
||||
&ssb->sb.st_mtime);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ST_BLKSIZE
|
||||
#if defined(HAVE_ST_BLKSIZE) || defined(HAVE_STRUCT_STAT_ST_BLKSIZE)
|
||||
ssb->sb.st_blksize = 0;
|
||||
#endif
|
||||
#ifdef HAVE_ST_BLOCKS
|
||||
#if defined(HAVE_ST_BLOCKS) || defined (HAVE_STRUCT_STAT_ST_BLOCKS)
|
||||
ssb->sb.st_blocks = 0;
|
||||
#endif
|
||||
/* php_stat in filestat.c doesn't check this one, so don't touch it */
|
||||
@@ -400,19 +387,32 @@ static php_stream_ops php_stream_rario_ops = {
|
||||
/* {{{ RAR directory streams */
|
||||
|
||||
/* {{{ php_rar_dir_ops_read */
|
||||
#if PHP_VERSION_ID < 70400
|
||||
static size_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||
#else
|
||||
static ssize_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||
#endif
|
||||
{
|
||||
php_stream_dirent entry;
|
||||
int offset;
|
||||
size_t offset;
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
if (count != sizeof(entry))
|
||||
if (count != sizeof(entry)) {
|
||||
#if PHP_VERSION_ID < 70400
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
_rar_entry_search_advance(self->state, self->directory, self->dir_size, 1);
|
||||
if (!self->state->found) {
|
||||
stream->eof = 1;
|
||||
#if PHP_VERSION_ID < 70400
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (self->dir_size == 1) /* root */
|
||||
@@ -424,12 +424,19 @@ static size_t php_rar_dir_ops_read(php_stream *stream, char *buf, size_t count T
|
||||
entry.d_name, sizeof entry.d_name);
|
||||
|
||||
if (!self->no_encode) { /* urlencode entry */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
int new_len;
|
||||
char *encoded_name;
|
||||
encoded_name = php_url_encode(entry.d_name, strlen(entry.d_name),
|
||||
&new_len);
|
||||
strlcpy(entry.d_name, encoded_name, sizeof entry.d_name);
|
||||
efree(encoded_name);
|
||||
#else
|
||||
zend_string *encoded_name =
|
||||
php_url_encode(entry.d_name, strlen(entry.d_name));
|
||||
strlcpy(entry.d_name, encoded_name->val, sizeof entry.d_name);
|
||||
zend_string_release(encoded_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -445,7 +452,11 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
||||
{
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&self->rar_obj);
|
||||
#else
|
||||
zval_ptr_dtor(&self->rar_obj);
|
||||
#endif
|
||||
efree(self->directory);
|
||||
efree(self->state);
|
||||
efree(self);
|
||||
@@ -457,7 +468,11 @@ static int php_rar_dir_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_rar_dir_ops_rewind */
|
||||
#if PHP_VERSION_ID < 70400
|
||||
static int php_rar_dir_ops_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC)
|
||||
#else
|
||||
static int php_rar_dir_ops_rewind(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset)
|
||||
#endif
|
||||
{
|
||||
STREAM_DIR_DATA_FROM_STREAM
|
||||
|
||||
@@ -519,8 +534,7 @@ php_stream *php_stream_rar_open(char *arc_name,
|
||||
if (cb_udata_ptr->password != NULL)
|
||||
self->cb_userdata.password = estrdup(cb_udata_ptr->password);
|
||||
if (cb_udata_ptr->callable != NULL) {
|
||||
self->cb_userdata.callable = cb_udata_ptr->callable;
|
||||
zval_add_ref(&self->cb_userdata.callable);
|
||||
ZVAL_ALLOC_DUP(self->cb_userdata.callable, cb_udata_ptr->callable);
|
||||
}
|
||||
|
||||
result = _rar_find_file_p(&self->open_data, position, &self->cb_userdata,
|
||||
@@ -535,16 +549,18 @@ php_stream *php_stream_rar_open(char *arc_name,
|
||||
TSRMLS_CC, position, arc_name);
|
||||
else {
|
||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize);
|
||||
size_t buffer_size = MIN(
|
||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
||||
file_size);
|
||||
int process_result = RARProcessFileChunkInit(self->rar_handle);
|
||||
|
||||
if (_rar_handle_error(process_result TSRMLS_CC) == FAILURE) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
self->file_size = file_size;
|
||||
self->buffer = emalloc(buffer_size);
|
||||
self->buffer_size = buffer_size;
|
||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, "rb");
|
||||
@@ -641,7 +657,10 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
char **file_password, /* can be NULL */
|
||||
zval **volume_cb TSRMLS_DC)
|
||||
{
|
||||
zval **ctx_opt = NULL;
|
||||
zval *ctx_opt;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval **ctx_opt_p = NULL;
|
||||
#endif
|
||||
|
||||
assert(context != NULL);
|
||||
assert(open_password != NULL);
|
||||
@@ -651,32 +670,50 @@ static void php_rar_process_context(php_stream_context *context,
|
||||
|
||||
/* TODO: don't know if I can log errors and not fail. check that */
|
||||
|
||||
if (php_stream_context_get_option(context, "rar", "open_password", &ctx_opt) ==
|
||||
SUCCESS) {
|
||||
if (Z_TYPE_PP(ctx_opt) != IS_STRING)
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (php_stream_context_get_option(
|
||||
context, "rar", "open_password", &ctx_opt_p) == SUCCESS) {
|
||||
ctx_opt = *ctx_opt_p;
|
||||
#else
|
||||
if ((ctx_opt = php_stream_context_get_option(
|
||||
context, "rar", "open_password"))) {
|
||||
#endif
|
||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"RAR open password was provided, but not a string.");
|
||||
else
|
||||
*open_password = Z_STRVAL_PP(ctx_opt);
|
||||
*open_password = Z_STRVAL_P(ctx_opt);
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (file_password != NULL && php_stream_context_get_option(context, "rar",
|
||||
"file_password", &ctx_opt) == SUCCESS) {
|
||||
if (Z_TYPE_PP(ctx_opt) != IS_STRING)
|
||||
"file_password", &ctx_opt_p) == SUCCESS) {
|
||||
ctx_opt = *ctx_opt_p;
|
||||
#else
|
||||
if (file_password != NULL && (ctx_opt = php_stream_context_get_option(
|
||||
context, "rar", "file_password"))) {
|
||||
#endif
|
||||
if (Z_TYPE_P(ctx_opt) != IS_STRING)
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"RAR file password was provided, but not a string.");
|
||||
else
|
||||
*file_password = Z_STRVAL_PP(ctx_opt);
|
||||
*file_password = Z_STRVAL_P(ctx_opt);
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (php_stream_context_get_option(context, "rar", "volume_callback",
|
||||
&ctx_opt) == SUCCESS) {
|
||||
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 2
|
||||
if (zend_is_callable(*ctx_opt, IS_CALLABLE_STRICT, NULL)) {
|
||||
&ctx_opt_p) == SUCCESS) {
|
||||
ctx_opt = *ctx_opt_p;
|
||||
#else
|
||||
if (zend_is_callable(*ctx_opt, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
||||
if ((ctx_opt = php_stream_context_get_option(
|
||||
context, "rar", "volume_callback"))) {
|
||||
#endif
|
||||
*volume_cb = *ctx_opt;
|
||||
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 2
|
||||
if (zend_is_callable(ctx_opt, IS_CALLABLE_STRICT, NULL)) {
|
||||
#else
|
||||
if (zend_is_callable(ctx_opt, IS_CALLABLE_STRICT, NULL TSRMLS_CC)) {
|
||||
#endif
|
||||
*volume_cb = ctx_opt;
|
||||
}
|
||||
else
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
@@ -744,7 +781,23 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
|
||||
|
||||
if (!(options & STREAM_ASSUME_REALPATH)) {
|
||||
if (options & USE_PATH) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*archive = zend_resolve_path(tmp_archive, tmp_arch_len TSRMLS_CC);
|
||||
#else
|
||||
# if PHP_VERSION_ID < 80100
|
||||
zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
|
||||
# else
|
||||
zend_string *tmp_archive_str = zend_string_init_fast(tmp_archive, tmp_arch_len);
|
||||
zend_string *arc_str = zend_resolve_path(tmp_archive_str);
|
||||
zend_string_free(tmp_archive_str);
|
||||
# endif
|
||||
if (arc_str != NULL) {
|
||||
*archive = estrndup(arc_str->val, arc_str->len);
|
||||
} else {
|
||||
*archive = NULL;
|
||||
}
|
||||
zend_string_release(arc_str);
|
||||
#endif
|
||||
}
|
||||
if (*archive == NULL) {
|
||||
if ((*archive = expand_filepath(tmp_archive, NULL TSRMLS_CC))
|
||||
@@ -798,7 +851,7 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
|
||||
wchar_t *ptr;
|
||||
for (ptr = *fragment; *ptr != L'\0'; ptr++) {
|
||||
if (*ptr == L'\\' || *ptr == L'/')
|
||||
*ptr = PATHDIVIDERW[0];
|
||||
*ptr = SPATHDIVIDER[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,10 +865,17 @@ cleanup:
|
||||
|
||||
/* {{{ php_stream_rar_opener */
|
||||
static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
char *filename,
|
||||
char *mode,
|
||||
int options,
|
||||
char **opened_path,
|
||||
#else
|
||||
const char *filename,
|
||||
const char *mode,
|
||||
int options,
|
||||
zend_string **opened_path,
|
||||
#endif
|
||||
php_stream_context *context
|
||||
STREAMS_DC TSRMLS_DC)
|
||||
{
|
||||
@@ -862,9 +922,7 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
if (open_passwd != NULL)
|
||||
self->cb_userdata.password = estrdup(open_passwd);
|
||||
if (volume_cb != NULL) {
|
||||
self->cb_userdata.callable = volume_cb;
|
||||
zval_add_ref(&self->cb_userdata.callable);
|
||||
SEPARATE_ZVAL(&self->cb_userdata.callable);
|
||||
ZVAL_ALLOC_DUP(self->cb_userdata.callable, volume_cb);
|
||||
}
|
||||
|
||||
rar_result = _rar_find_file_w(&self->open_data, fragment,
|
||||
@@ -900,21 +958,23 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
|
||||
{
|
||||
/* no need to allocate a buffer bigger than the file uncomp size */
|
||||
size_t buffer_size = (size_t)
|
||||
MIN((uint64) RAR_CHUNK_BUFFER_SIZE,
|
||||
INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize));
|
||||
size_t file_size = INT32TO64(self->header_data.UnpSizeHigh,
|
||||
self->header_data.UnpSize);
|
||||
size_t buffer_size = MIN(
|
||||
MAX(RAR_CHUNK_BUFFER_SIZE, self->header_data.WinSize),
|
||||
file_size);
|
||||
rar_result = RARProcessFileChunkInit(self->rar_handle);
|
||||
|
||||
if ((rar_error = _rar_error_to_string(rar_result)) != NULL) {
|
||||
char *mb_entry = _rar_wide_to_utf_with_alloc(fragment, -1);
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Error opening file %s inside RAR archive %s: %s",
|
||||
mb_entry, tmp_open_path, rar_error);
|
||||
"Error opening file %s inside RAR archive %s: %s",
|
||||
mb_entry, tmp_open_path, rar_error);
|
||||
efree(mb_entry);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
self->file_size = file_size;
|
||||
self->buffer = emalloc(buffer_size);
|
||||
self->buffer_size = buffer_size;
|
||||
stream = php_stream_alloc(&php_stream_rario_ops, self, NULL, mode);
|
||||
@@ -926,10 +986,16 @@ static php_stream *php_stream_rar_opener(php_stream_wrapper *wrapper,
|
||||
cleanup:
|
||||
|
||||
if (tmp_open_path != NULL) {
|
||||
if (opened_path != NULL)
|
||||
if (opened_path != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*opened_path = tmp_open_path;
|
||||
else
|
||||
#else
|
||||
*opened_path =
|
||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||
#endif
|
||||
} else {
|
||||
efree(tmp_open_path);
|
||||
}
|
||||
}
|
||||
if (fragment != NULL)
|
||||
efree(fragment);
|
||||
@@ -972,25 +1038,30 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
const char* arch_path,
|
||||
const char* open_passwd,
|
||||
zval *volume_cb,
|
||||
zval **rar_obj,
|
||||
zval *rar_obj, /* output */
|
||||
rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char *cache_key = NULL;
|
||||
uint cache_key_len;
|
||||
int err_code,
|
||||
ret = FAILURE;
|
||||
zval *cache_zv;
|
||||
|
||||
assert(rar_obj != NULL);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
INIT_ZVAL(*rar_obj);
|
||||
#else
|
||||
ZVAL_UNDEF(rar_obj);
|
||||
#endif
|
||||
|
||||
_rar_arch_cache_get_key(arch_path, open_passwd, volume_cb, &cache_key,
|
||||
&cache_key_len);
|
||||
*rar_obj = RAR_G(contents_cache).get(cache_key, cache_key_len TSRMLS_CC);
|
||||
|
||||
if (*rar_obj == NULL) { /* cache miss */
|
||||
ALLOC_INIT_ZVAL(*rar_obj);
|
||||
cache_zv = RAR_G(contents_cache).get(
|
||||
cache_key, cache_key_len, rar_obj TSRMLS_CC);
|
||||
|
||||
if (cache_zv == NULL) { /* cache miss */
|
||||
if (_rar_create_rararch_obj(arch_path, open_passwd, volume_cb,
|
||||
*rar_obj, &err_code TSRMLS_CC) == FAILURE) {
|
||||
rar_obj, &err_code TSRMLS_CC) == FAILURE) {
|
||||
const char *err_str = _rar_error_to_string(err_code);
|
||||
if (err_str == NULL)
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
@@ -1007,7 +1078,7 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
int res;
|
||||
const char *err_str;
|
||||
|
||||
if (_rar_get_file_resource_ex(*rar_obj, rar, 1 TSRMLS_CC)
|
||||
if (_rar_get_file_resource_zv_ex(rar_obj, rar, 1 TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
@@ -1023,15 +1094,15 @@ static int _rar_get_cachable_rararch(php_stream_wrapper *wrapper,
|
||||
err_str);
|
||||
goto cleanup;
|
||||
}
|
||||
RAR_G(contents_cache).put(cache_key, cache_key_len, *rar_obj
|
||||
RAR_G(contents_cache).put(cache_key, cache_key_len, rar_obj
|
||||
TSRMLS_CC);
|
||||
_rar_close_file_resource(*rar);
|
||||
}
|
||||
}
|
||||
else { /* cache hit */
|
||||
/* refcount of rar_obj already incremented by cache get */
|
||||
if (_rar_get_file_resource_ex(*rar_obj, rar, 1 TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
/* 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) {
|
||||
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
|
||||
"Bug: could not retrieve RarArchive object from zval");
|
||||
goto cleanup;
|
||||
@@ -1043,9 +1114,14 @@ cleanup:
|
||||
if (cache_key != NULL)
|
||||
efree(cache_key);
|
||||
|
||||
if (ret != SUCCESS && *rar_obj != NULL) {
|
||||
if (ret != SUCCESS && Z_TYPE_P(rar_obj) == IS_OBJECT) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(rar_obj);
|
||||
Z_TYPE_P(rar_obj) = IS_NULL;
|
||||
#else
|
||||
zval_ptr_dtor(rar_obj);
|
||||
*rar_obj = NULL;
|
||||
ZVAL_UNDEF(rar_obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1075,16 +1151,20 @@ static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRML
|
||||
#else
|
||||
static void _rar_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC)
|
||||
{
|
||||
if (wrapper && FG(wrapper_errors)) {
|
||||
zend_hash_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper);
|
||||
}
|
||||
if (wrapper && FG(wrapper_errors)) {
|
||||
zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_stream_rar_stater */
|
||||
static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
char *url,
|
||||
#else
|
||||
const char *url,
|
||||
#endif
|
||||
int flags,
|
||||
php_stream_statbuf *ssb,
|
||||
php_stream_context *context TSRMLS_DC)
|
||||
@@ -1098,11 +1178,17 @@ static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||
zval *volume_cb = NULL;
|
||||
size_t fragment_len;
|
||||
rar_file_t *rar;
|
||||
zval *rararch = NULL;
|
||||
zval rararch;
|
||||
rar_find_output *state = NULL;
|
||||
int ret = FAILURE;
|
||||
|
||||
/* {{{ preliminaries */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_TYPE(rararch) = IS_NULL;
|
||||
#else
|
||||
ZVAL_UNDEF(&rararch);
|
||||
#endif
|
||||
|
||||
if (_rar_get_archive_and_fragment(wrapper, url, options, 1,
|
||||
&open_path, &fragment, NULL TSRMLS_CC) == FAILURE) {
|
||||
goto cleanup;
|
||||
@@ -1143,16 +1229,24 @@ static int php_stream_rar_stater(php_stream_wrapper *wrapper,
|
||||
|
||||
ret = SUCCESS;
|
||||
cleanup:
|
||||
if (open_path != NULL)
|
||||
if (open_path != NULL) {
|
||||
efree(open_path);
|
||||
}
|
||||
|
||||
if (fragment != NULL)
|
||||
if (fragment != NULL) {
|
||||
efree(fragment);
|
||||
}
|
||||
|
||||
if (rararch != NULL)
|
||||
if (Z_TYPE(rararch) == IS_OBJECT) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&rararch);
|
||||
#else
|
||||
zval_ptr_dtor(&rararch);
|
||||
if (state != NULL)
|
||||
#endif
|
||||
}
|
||||
if (state != NULL) {
|
||||
_rar_entry_search_end(state);
|
||||
}
|
||||
|
||||
/* note PHP_STREAM_URL_STAT_QUIET is not equivalent to ~REPORT_ERRORS.
|
||||
* ~REPORT_ERRORS instead of emitting a notice, stores the error in the
|
||||
@@ -1161,8 +1255,9 @@ cleanup:
|
||||
* consistency, I treat both the same way but clean the wrapper in the end
|
||||
* if necessary
|
||||
*/
|
||||
if (flags & PHP_STREAM_URL_STAT_QUIET)
|
||||
if (flags & PHP_STREAM_URL_STAT_QUIET) {
|
||||
_rar_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1170,10 +1265,17 @@ cleanup:
|
||||
|
||||
/* {{{ php_stream_rar_dir_opener */
|
||||
static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
char *filename,
|
||||
char *mode,
|
||||
int options,
|
||||
char **opened_path,
|
||||
#else
|
||||
const char *filename,
|
||||
const char *mode,
|
||||
int options,
|
||||
zend_string **opened_path,
|
||||
#endif
|
||||
php_stream_context *context
|
||||
STREAMS_DC TSRMLS_DC)
|
||||
{
|
||||
@@ -1225,7 +1327,7 @@ static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
||||
|
||||
/* Remove the ending in the path separator */
|
||||
if (fragment_len > 0 &&
|
||||
self->directory[fragment_len - 1] == PATHDIVIDERW[0]) {
|
||||
self->directory[fragment_len - 1] == SPATHDIVIDER[0]) {
|
||||
self->directory[fragment_len - 1] = L'\0';
|
||||
self->dir_size = fragment_len;
|
||||
}
|
||||
@@ -1239,8 +1341,8 @@ static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
||||
* to the archive, which I'll assume occurs in all good archives */
|
||||
_rar_entry_search_advance(
|
||||
self->state, self->directory, self->dir_size, 0);
|
||||
if (!self->state->found || ((self->state->header->Flags &
|
||||
LHD_WINDOWMASK) != LHD_DIRECTORY)) {
|
||||
if (!self->state->found || !(self->state->header->Flags &
|
||||
RHDF_DIRECTORY)) {
|
||||
const char *message;
|
||||
char *mb_entry = _rar_wide_to_utf_with_alloc(self->directory,
|
||||
(size_t) self->dir_size - 1);
|
||||
@@ -1271,22 +1373,35 @@ static php_stream *php_stream_rar_dir_opener(php_stream_wrapper *wrapper,
|
||||
cleanup:
|
||||
|
||||
if (tmp_open_path != NULL) {
|
||||
if (opened_path != NULL)
|
||||
if (opened_path != NULL) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
*opened_path = tmp_open_path;
|
||||
else
|
||||
#else
|
||||
*opened_path =
|
||||
zend_string_init(tmp_open_path, strlen(tmp_open_path), 0);
|
||||
#endif
|
||||
} else {
|
||||
efree(tmp_open_path);
|
||||
}
|
||||
}
|
||||
if (fragment != NULL)
|
||||
efree(fragment);
|
||||
|
||||
if (stream == NULL) { /* failed */
|
||||
if (self != NULL) {
|
||||
if (self->rar_obj != NULL)
|
||||
if (Z_TYPE(self->rar_obj) == IS_OBJECT) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&self->rar_obj);
|
||||
#else
|
||||
zval_ptr_dtor(&self->rar_obj);
|
||||
if (self->directory != NULL)
|
||||
#endif
|
||||
}
|
||||
if (self->directory != NULL) {
|
||||
efree(self->directory);
|
||||
if (self->state != NULL)
|
||||
}
|
||||
if (self->state != NULL) {
|
||||
_rar_entry_search_end(self->state);
|
||||
}
|
||||
efree(self);
|
||||
}
|
||||
}
|
||||
|
||||
63
rar_time.c
Normal file
63
rar_time.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#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
|
||||
513
rararch.c
513
rararch.c
@@ -27,28 +27,42 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "zend_types.h"
|
||||
#include <zend_API.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include <wchar.h>
|
||||
#include <php.h>
|
||||
#include <zend_interfaces.h>
|
||||
#include "php_rar.h"
|
||||
#include "php_compat.h"
|
||||
|
||||
/* {{{ Type definitions reserved for this translation unit */
|
||||
typedef struct _ze_rararch_object {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zend_object parent;
|
||||
rar_file_t *rar_file;
|
||||
#else
|
||||
rar_file_t *rar_file;
|
||||
zend_object parent;
|
||||
#endif
|
||||
} ze_rararch_object;
|
||||
|
||||
typedef struct _rararch_iterator {
|
||||
zend_object_iterator parent;
|
||||
rar_find_output *state;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *value;
|
||||
#else
|
||||
zval value;
|
||||
#endif
|
||||
int empty_iterator; /* iterator should give nothing */
|
||||
} rararch_iterator;
|
||||
/* }}} */
|
||||
@@ -72,28 +86,59 @@ static zend_object_handlers rararch_object_handlers;
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Function prototypes for functions with internal linkage */
|
||||
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv);
|
||||
static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj);
|
||||
|
||||
static ze_rararch_object *rararch_object_from_zv(const zval *zv);
|
||||
static ze_rararch_object *rararch_object_from_ref(const rar_obj_ref ref);
|
||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce);
|
||||
static void rararch_ce_free_object_storage(zend_object *zobj);
|
||||
#else
|
||||
#define rararch_object_from_zv zend_object_store_get_object
|
||||
#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_destroy_object(ze_rararch_object *object,
|
||||
zend_object_handle handle TSRMLS_DC);
|
||||
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC);
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive handlers */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_handlers_preamble(handler_this_t *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, long *index, int quiet TSRMLS_DC);
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC);
|
||||
static int rararch_count_elements(handler_this_t *object, long *count TSRMLS_DC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type 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);
|
||||
#else
|
||||
static zval *rararch_read_dimension(handler_this_t *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);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Function definitions with external linkage */
|
||||
int _rar_get_file_resource(zval *zval_file, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
int _rar_get_file_resource_zv(zval *zv, rar_file_t **rar_file TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return _rar_get_file_resource_ex(zval_file, rar_file, FALSE TSRMLS_CC);
|
||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
||||
rar_file, FALSE TSRMLS_CC);
|
||||
}
|
||||
int _rar_get_file_resource_zv_ex(zval *zv, rar_file_t **rar_file, int allow_closed TSRMLS_DC)
|
||||
{
|
||||
return _rar_get_file_resource_ex(rar_obj_ref_fetch(zv),
|
||||
rar_file, allow_closed TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _rar_get_file_resource_handler(handler_this_t *thiz,
|
||||
rar_file_t **rar_file TSRMLS_DC)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 8
|
||||
return _rar_get_file_resource_zv(thiz, rar_file TSRMLS_CC);
|
||||
#else
|
||||
return _rar_get_file_resource_ex(thiz, rar_file, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Creates a RarArchive object, all three in args will be dupped */
|
||||
int _rar_create_rararch_obj(const char* resolved_path,
|
||||
const char* open_password,
|
||||
@@ -126,15 +171,13 @@ int _rar_create_rararch_obj(const char* resolved_path,
|
||||
rar->cb_userdata.password = estrdup(open_password);
|
||||
}
|
||||
if (volume_callback != NULL) {
|
||||
rar->cb_userdata.callable = volume_callback;
|
||||
zval_add_ref(&rar->cb_userdata.callable);
|
||||
SEPARATE_ZVAL(&rar->cb_userdata.callable);
|
||||
ZVAL_ALLOC_DUP(rar->cb_userdata.callable, volume_callback);
|
||||
}
|
||||
|
||||
object_init_ex(object, rararch_ce_ptr);
|
||||
zobj = zend_object_store_get_object(object TSRMLS_CC);
|
||||
zobj = rararch_object_from_zv(object TSRMLS_CC);
|
||||
zobj->rar_file = rar;
|
||||
rar->id = Z_OBJ_HANDLE_P(object);
|
||||
rar->obj_ref = rar_obj_ref_fetch(object);
|
||||
|
||||
RARSetCallback(rar->arch_handle, _rar_unrar_callback,
|
||||
(LPARAM) &rar->cb_userdata);
|
||||
@@ -161,20 +204,21 @@ void _rar_close_file_resource(rar_file_t *rar) /* {{{ */
|
||||
/* When changed from resource to custom object, instead of fiddling
|
||||
* with the refcount to force object destruction, an indication that
|
||||
* the file is already closed is given by setting rar->arch_handle
|
||||
* to NULL. This is checked by _rar_get_file_resource. */
|
||||
* to NULL. This is checked by _rar_get_file_resource_zv. */
|
||||
RARCloseArchive(rar->arch_handle);
|
||||
rar->arch_handle = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Receives archive zval, returns object struct.
|
||||
* If silent is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* If allow_closed is FALSE, it checks whether the archive is alredy closed, and if it
|
||||
* is, an exception/error is raised and FAILURE is returned
|
||||
*/
|
||||
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC) /* {{{ */
|
||||
int _rar_get_file_resource_ex(rar_obj_ref zobjref_file, rar_file_t **rar_file,
|
||||
int allow_closed TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_rararch_object *zobj;
|
||||
zobj = zend_object_store_get_object(zval_file TSRMLS_CC);
|
||||
zobj = rararch_object_from_ref(zobjref_file);
|
||||
if (zobj == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not find object in the store. This is a bug, please report it.");
|
||||
@@ -182,7 +226,7 @@ int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent
|
||||
}
|
||||
|
||||
*rar_file = zobj->rar_file;
|
||||
if ((*rar_file)->arch_handle == NULL && !silent) { /* rar_close was called */
|
||||
if ((*rar_file)->arch_handle == NULL && !allow_closed) { /* rar_close was called */
|
||||
_rar_handle_ext_error("The archive is already closed" TSRMLS_CC);
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -198,16 +242,10 @@ int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent
|
||||
static void _rar_raw_entries_to_array(rar_file_t *rar, zval *target TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
rar_find_output *state;
|
||||
zval *rararch_obj;
|
||||
zval rararch_obj;
|
||||
|
||||
/* create zval to point to the RarArchive object) */
|
||||
MAKE_STD_ZVAL(rararch_obj);
|
||||
Z_TYPE_P(rararch_obj) = IS_OBJECT;
|
||||
Z_OBJ_HANDLE_P(rararch_obj) = rar->id;
|
||||
Z_OBJ_HT_P(rararch_obj) = &rararch_object_handlers;
|
||||
/* object has a new reference; if not incremented, the object would be
|
||||
* be destroyed when this new zval we created was destroyed */
|
||||
zend_objects_store_add_ref_by_handle(rar->id TSRMLS_CC);
|
||||
/* make zval point to the RarArchive object */
|
||||
rar_obj_ref_make_zv(rar->obj_ref, &rararch_obj TSRMLS_CC);
|
||||
|
||||
_rar_entry_search_start(rar, RAR_SEARCH_TRAVERSE, &state TSRMLS_CC);
|
||||
do {
|
||||
@@ -216,22 +254,74 @@ static void _rar_raw_entries_to_array(rar_file_t *rar, zval *target TSRMLS_DC) /
|
||||
zval *entry_obj;
|
||||
|
||||
MAKE_STD_ZVAL(entry_obj);
|
||||
_rar_entry_to_zval(rararch_obj, state->header, state->packed_size,
|
||||
_rar_entry_to_zval(&rararch_obj, state->header, state->packed_size,
|
||||
state->position, entry_obj TSRMLS_CC);
|
||||
|
||||
add_next_index_zval(target, entry_obj);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
/* PHP 7 copies the zval (but without increasing the refcount of the
|
||||
* obj), while 5.x simply copies the pointer. Only for PHP 5.x do we
|
||||
* keep the allocation) */
|
||||
efree(entry_obj);
|
||||
#endif
|
||||
}
|
||||
} while (state->eof == 0);
|
||||
_rar_entry_search_end(state);
|
||||
|
||||
/* it was created with refcount=1 and incremented for each RarEntry object
|
||||
* created, so we must decrease by one (this will also destroy it if
|
||||
* there were no entries */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_dtor(&rararch_obj);
|
||||
#else
|
||||
zval_ptr_dtor(&rararch_obj);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object_value rararch_ce_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
#if PHP_MAJOR_VERSION >=7
|
||||
static inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
||||
{
|
||||
return Z_OBJ(*zv);
|
||||
}
|
||||
static inline void rar_obj_ref_make_zv(rar_obj_ref zo, zval *zv TSRMLS_DC)
|
||||
{
|
||||
ZVAL_OBJ(zv, zo);
|
||||
zval_addref_p(zv);
|
||||
}
|
||||
#else
|
||||
inline rar_obj_ref rar_obj_ref_fetch(zval *zv)
|
||||
{
|
||||
return Z_OBJ_HANDLE_P(zv);
|
||||
}
|
||||
inline void rar_obj_ref_make_zv(rar_obj_ref zoh, zval *zv TSRMLS_DC)
|
||||
{
|
||||
INIT_ZVAL(*zv);
|
||||
Z_TYPE_P(zv) = IS_OBJECT;
|
||||
Z_OBJ_HANDLE_P(zv) = zoh;
|
||||
Z_OBJ_HT_P(zv) = &rararch_object_handlers;
|
||||
/* object has a new reference; if not incremented, the object would be
|
||||
* be destroyed when this new zval we created was destroyed */
|
||||
zend_objects_store_add_ref_by_handle(zoh TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION >=7
|
||||
static inline ze_rararch_object *rararch_object_fetch(zend_object *zobj)
|
||||
{
|
||||
return (ze_rararch_object *)
|
||||
((char *) zobj - XtOffsetOf(ze_rararch_object, parent));
|
||||
}
|
||||
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
|
||||
|
||||
/* {{{ */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zend_object_value rararch_ce_create_object(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
zend_object_value zov;
|
||||
ze_rararch_object *zobj;
|
||||
@@ -249,38 +339,44 @@ static zend_object_value rararch_ce_create_object(zend_class_entry *class_type T
|
||||
object_properties_init((zend_object*)zobj, class_type);
|
||||
#endif
|
||||
zov.handle = zend_objects_store_put(zobj,
|
||||
(zend_objects_store_dtor_t) rararch_ce_destroy_object,
|
||||
(zend_objects_store_dtor_t) zend_objects_destroy_object,
|
||||
(zend_objects_free_object_storage_t) rararch_ce_free_object_storage,
|
||||
NULL TSRMLS_CC);
|
||||
zov.handlers = &rararch_object_handlers;
|
||||
return zov;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void rararch_ce_destroy_object(ze_rararch_object *object,
|
||||
zend_object_handle handle TSRMLS_DC) /* {{{ */
|
||||
#else
|
||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
||||
{
|
||||
rar_file_t *rar = object->rar_file;
|
||||
ze_rararch_object *zobj =
|
||||
emalloc(sizeof(*zobj) + zend_object_properties_size(ce));
|
||||
|
||||
/* can safely assume rar != NULL here. This function is not called
|
||||
* if object construction fails */
|
||||
assert(rar != NULL);
|
||||
zobj->rar_file = NULL;
|
||||
zend_object_std_init(&zobj->parent, ce);
|
||||
zobj->parent.handlers = &rararch_object_handlers;
|
||||
|
||||
/* not really relevant, calls destr. zend func. ce->destructor if it exists */
|
||||
zend_objects_destroy_object((zend_object*) object, handle TSRMLS_CC);
|
||||
|
||||
if (rar->arch_handle != NULL) {
|
||||
RARCloseArchive(rar->arch_handle);
|
||||
}
|
||||
return &zobj->parent;
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC) /* {{{ */
|
||||
/* {{{ */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC)
|
||||
{
|
||||
#else
|
||||
static void rararch_ce_free_object_storage(zend_object *zobj)
|
||||
{
|
||||
ze_rararch_object *object = rararch_object_fetch(zobj);
|
||||
#endif
|
||||
rar_file_t *rar = object->rar_file;
|
||||
|
||||
/* may be NULL if the user did new RarArchive() */
|
||||
if (rar != NULL) {
|
||||
if (rar->arch_handle != NULL) {
|
||||
RARCloseArchive(rar->arch_handle);
|
||||
}
|
||||
|
||||
_rar_destroy_userdata(&rar->cb_userdata);
|
||||
|
||||
_rar_delete_entries(rar TSRMLS_CC);
|
||||
@@ -295,19 +391,22 @@ static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC)
|
||||
|
||||
/* could call zend_objects_free_object_storage here (not before!), but
|
||||
* instead I'll mimic its behaviour */
|
||||
zend_object_std_dtor((zend_object*) object TSRMLS_CC);
|
||||
zend_object_std_dtor(&object->parent TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
efree(object);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive handlers */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
static int rararch_handlers_preamble(handler_this_t *object,
|
||||
rar_file_t **rar TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
/* don't call zend_objects_get_address or zend_object_store_get directly;
|
||||
* _rar_get_file_resource checks if the archive was closed */
|
||||
if (_rar_get_file_resource(object, rar TSRMLS_CC) == FAILURE) {
|
||||
* _rar_get_file_resource_zv checks if the archive was closed */
|
||||
if (_rar_get_file_resource_handler(object, rar TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@@ -345,7 +444,7 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
return FAILURE;
|
||||
}
|
||||
else if (type == IS_DOUBLE) {
|
||||
if (d > LONG_MAX || d < LONG_MIN) {
|
||||
if (d > (double) LONG_MAX || d < (double) LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
@@ -355,7 +454,8 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
}
|
||||
}
|
||||
else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
if (Z_DVAL_P(offset) > LONG_MAX || Z_DVAL_P(offset) < LONG_MIN) {
|
||||
if (Z_DVAL_P(offset) > (double) LONG_MAX ||
|
||||
Z_DVAL_P(offset) < (double) LONG_MIN) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Dimension index is out of integer bounds");
|
||||
return FAILURE;
|
||||
@@ -363,11 +463,20 @@ 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) {
|
||||
/* get handler cannot return NULL */
|
||||
zval *newoffset = Z_OBJ_HT_P(offset)->get(offset TSRMLS_CC);
|
||||
zval *newoffset = NULL;
|
||||
int ret;
|
||||
# if PHP_MAJOR_VERSION < 7
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset TSRMLS_CC);
|
||||
# else
|
||||
zval zv_holder;
|
||||
ZVAL_NULL(&zv_holder);
|
||||
newoffset = Z_OBJ_HT_P(offset)->get(offset, &zv_holder);
|
||||
# endif
|
||||
|
||||
/* get handler cannot return NULL */
|
||||
assert(newoffset != NULL);
|
||||
if (Z_TYPE_P(newoffset) == IS_OBJECT) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not convert object given as dimension index into "
|
||||
@@ -377,8 +486,32 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
|
||||
ret = rararch_dimensions_preamble(rar, newoffset, index, quiet
|
||||
TSRMLS_CC);
|
||||
FREE_ZVAL(newoffset);
|
||||
# if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor(&newoffset);
|
||||
# else
|
||||
zval_ptr_dtor(newoffset);
|
||||
# endif
|
||||
return ret;
|
||||
} else
|
||||
#endif // PHP < 8
|
||||
if (Z_OBJ_HT_P(offset)->cast_object) {
|
||||
zval newoffset;
|
||||
int res = Z_OBJ_HT_P(offset)->cast_object(
|
||||
ZV_TO_THIS_FOR_HANDLER(offset), &newoffset, IS_LONG TSRMLS_CC);
|
||||
if (res == FAILURE) {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not convert object given as dimension index into "
|
||||
"an integer (cast_object failed)");
|
||||
return FAILURE;
|
||||
}
|
||||
if (Z_TYPE(newoffset) != IS_LONG) {
|
||||
zval_dtor(&newoffset);
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not convert object given as dimension index into "
|
||||
"an integer (cast_object did not return int as asked)");
|
||||
return FAILURE;
|
||||
}
|
||||
*index = Z_LVAL(newoffset);
|
||||
}
|
||||
else {
|
||||
RAR_DOCREF_IF_UNQUIET(NULL TSRMLS_CC, E_WARNING,
|
||||
@@ -411,7 +544,8 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive count_elements handler */
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||
|
||||
static int rararch_count_elements(zend_object *object, zend_long *count TSRMLS_DC)
|
||||
{
|
||||
rar_file_t *rar = NULL;
|
||||
size_t entry_count;
|
||||
@@ -422,17 +556,21 @@ static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||
}
|
||||
|
||||
entry_count = _rar_entry_count(rar);
|
||||
if (entry_count > LONG_MAX)
|
||||
entry_count = (size_t) LONG_MAX;
|
||||
if (entry_count > ZEND_LONG_MAX)
|
||||
entry_count = ZEND_LONG_MAX;
|
||||
|
||||
*count = (long) entry_count;
|
||||
*count = (zend_long) entry_count;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive read_dimension handler */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
#else
|
||||
static zval *rararch_read_dimension(handler_this_t *object, zval *offset, int type, zval *rv)
|
||||
#endif
|
||||
{
|
||||
long index;
|
||||
rar_file_t *rar = NULL;
|
||||
@@ -455,17 +593,31 @@ static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_
|
||||
_rar_entry_search_seek(out, (size_t) index);
|
||||
_rar_entry_search_advance(out, NULL, 0, 0);
|
||||
assert(out->found);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
ALLOC_INIT_ZVAL(ret);
|
||||
#else
|
||||
ret = rv;
|
||||
#endif
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
zval object_zv;
|
||||
ZVAL_OBJ(&object_zv, object);
|
||||
|
||||
_rar_entry_to_zval(&object_zv, out->header, out->packed_size, out->position,
|
||||
ret TSRMLS_CC);
|
||||
#else
|
||||
_rar_entry_to_zval(object, out->header, out->packed_size, out->position,
|
||||
ret TSRMLS_CC);
|
||||
#endif
|
||||
_rar_entry_search_end(out);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_DELREF_P(ret); /* set refcount to 0 */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive write_dimension handler */
|
||||
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
|
||||
static void rararch_write_dimension(handler_this_t *object, zval *offset, zval *value TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -473,7 +625,7 @@ static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRM
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive has_dimension handler */
|
||||
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
static int rararch_has_dimension(handler_this_t *object, zval *offset, int check_empty TSRMLS_DC)
|
||||
{
|
||||
long index;
|
||||
rar_file_t *rar = NULL;
|
||||
@@ -490,7 +642,7 @@ static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSR
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive unset_dimension handler */
|
||||
static void rararch_unset_dimension(zval *object, zval *offset TSRMLS_DC)
|
||||
static void rararch_unset_dimension(handler_this_t *object, zval *offset TSRMLS_DC)
|
||||
{
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"A RarArchive object is not writable");
|
||||
@@ -508,8 +660,8 @@ PHP_FUNCTION(rar_open)
|
||||
char *filename;
|
||||
char *password = NULL;
|
||||
char resolved_path[MAXPATHLEN];
|
||||
int filename_len;
|
||||
int password_len = 0;
|
||||
zpp_s_size_t filename_len,
|
||||
password_len; /* both ignored */
|
||||
zval *callable = NULL;
|
||||
int err_code;
|
||||
|
||||
@@ -569,7 +721,7 @@ PHP_FUNCTION(rar_list)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -589,7 +741,7 @@ PHP_FUNCTION(rar_entry_get)
|
||||
zval *file = getThis();
|
||||
char *filename;
|
||||
rar_file_t *rar = NULL;
|
||||
int filename_len;
|
||||
zpp_s_size_t filename_len;
|
||||
wchar_t *filename_c = NULL;
|
||||
rar_find_output *sstate;
|
||||
|
||||
@@ -604,7 +756,7 @@ PHP_FUNCTION(rar_entry_get)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -641,7 +793,7 @@ PHP_FUNCTION(rar_solid_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -659,7 +811,7 @@ PHP_FUNCTION(rar_comment_get)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -673,7 +825,7 @@ PHP_FUNCTION(rar_comment_get)
|
||||
|
||||
if (cmt_state == 1) { /* comment read completely */
|
||||
/* CmtSize - 1 because we don't need the null terminator */
|
||||
RETURN_STRINGL(rar->list_open_data->CmtBuf,
|
||||
RAR_RETURN_STRINGL(rar->list_open_data->CmtBuf,
|
||||
rar->list_open_data->CmtSize - 1, 1);
|
||||
}
|
||||
}
|
||||
@@ -690,7 +842,7 @@ PHP_FUNCTION(rar_broken_is)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -721,7 +873,7 @@ PHP_FUNCTION(rar_allow_broken_set)
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -739,7 +891,7 @@ PHP_FUNCTION(rar_close)
|
||||
|
||||
RAR_THIS_OR_NO_ARGS(file);
|
||||
|
||||
if (_rar_get_file_resource(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(file, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -763,7 +915,8 @@ PHP_METHOD(rararch, __toString)
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
if (_rar_get_file_resource_ex(arch_obj, &rar, TRUE TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv_ex(arch_obj, &rar, TRUE TSRMLS_CC)
|
||||
== FAILURE) {
|
||||
RETURN_FALSE; /* should never happen */
|
||||
}
|
||||
|
||||
@@ -780,10 +933,22 @@ PHP_METHOD(rararch, __toString)
|
||||
is_closed?closed:"");
|
||||
restring[restring_size - 1] = '\0'; /* just to be safe */
|
||||
|
||||
RETURN_STRINGL(restring, (int) restring_size - 1, 0);
|
||||
RAR_RETURN_STRINGL(restring, (int) restring_size - 1, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
@@ -799,8 +964,20 @@ 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[] = {
|
||||
@@ -815,8 +992,11 @@ static zend_function_entry php_rararch_class_functions[] = {
|
||||
PHP_ME_MAPPING(isBroken, rar_broken_is, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(setAllowBroken, rar_allow_broken_set, arginfo_rararchive_setallowbroken, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(close, rar_close, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rararch, __toString, arginfo_rararchive_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rararch, __toString, arginfo_rararchive_tostring, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rararchive_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
PHP_ME(rararch, getIterator, arginfo_rararchive_getiterator, ZEND_ACC_PUBLIC)
|
||||
#endif
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -830,60 +1010,29 @@ static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC);
|
||||
static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC);
|
||||
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static void rararch_it_current_data(zend_object_iterator *iter,
|
||||
zval ***data TSRMLS_DC);
|
||||
#else
|
||||
static zval *rararch_it_current_data(zend_object_iterator *iter);
|
||||
#endif
|
||||
static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
|
||||
static void rararch_it_rewind(zend_object_iterator *iter TSRMLS_DC);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_get_iterator */
|
||||
static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
zval *object,
|
||||
int by_ref TSRMLS_DC)
|
||||
{
|
||||
rararch_iterator *it;
|
||||
rar_file_t *rar;
|
||||
int res;
|
||||
|
||||
if (by_ref) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"An iterator cannot be used with foreach by reference");
|
||||
}
|
||||
|
||||
it = emalloc(sizeof *it);
|
||||
|
||||
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;
|
||||
|
||||
zval_add_ref(&object);
|
||||
it->parent.data = object;
|
||||
it->parent.funcs = ce->iterator_funcs.funcs;
|
||||
_rar_entry_search_start(rar, RAR_SEARCH_TRAVERSE, &it->state TSRMLS_CC);
|
||||
it->value = NULL;
|
||||
return (zend_object_iterator*) it;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_invalidate_current */
|
||||
static void rararch_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
rararch_iterator *it = (rararch_iterator *) iter;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
if (it->value != NULL) {
|
||||
zval_ptr_dtor(&it->value);
|
||||
it->value = NULL;
|
||||
}
|
||||
#else
|
||||
zval_ptr_dtor(&it->value);
|
||||
ZVAL_UNDEF(&it->value);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -894,10 +1043,16 @@ static void rararch_it_dtor(zend_object_iterator *iter TSRMLS_DC)
|
||||
|
||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_ptr_dtor((zval**) &it->parent.data); /* decrease refcount on zval object */
|
||||
#else
|
||||
zval_ptr_dtor(&it->parent.data);
|
||||
#endif
|
||||
|
||||
_rar_entry_search_end(it->state);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
efree(it);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -906,40 +1061,72 @@ static void rararch_it_fetch(rararch_iterator *it TSRMLS_DC)
|
||||
{
|
||||
rar_file_t *rar_file;
|
||||
int res;
|
||||
zval *robj;
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
assert(it->value == NULL);
|
||||
#else
|
||||
assert(Z_TYPE(it->value) == IS_UNDEF);
|
||||
#endif
|
||||
|
||||
if (it->empty_iterator) {
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(it->value);
|
||||
ZVAL_FALSE(it->value);
|
||||
#else
|
||||
ZVAL_FALSE(&it->value);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
res = _rar_get_file_resource_ex(it->parent.data, &rar_file, 1 TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
robj = it->parent.data;
|
||||
#else
|
||||
robj = &it->parent.data;
|
||||
#endif
|
||||
|
||||
res = _rar_get_file_resource_zv_ex(robj, &rar_file, 1 TSRMLS_CC);
|
||||
if (res == FAILURE)
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
"Cannot fetch RarArchive object");
|
||||
|
||||
_rar_entry_search_advance(it->state, NULL, 0, 0);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
MAKE_STD_ZVAL(it->value);
|
||||
if (it->state->found)
|
||||
_rar_entry_to_zval(it->parent.data, it->state->header,
|
||||
it->state->packed_size, it->state->position, it->value TSRMLS_CC);
|
||||
else
|
||||
_rar_entry_to_zval(robj, it->state->header, it->state->packed_size,
|
||||
it->state->position, it->value TSRMLS_CC);
|
||||
else {
|
||||
ZVAL_FALSE(it->value);
|
||||
}
|
||||
#else
|
||||
if (it->state->found)
|
||||
_rar_entry_to_zval(&it->parent.data, it->state->header,
|
||||
it->state->packed_size, it->state->position, &it->value TSRMLS_CC);
|
||||
else {
|
||||
ZVAL_FALSE(&it->value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_valid */
|
||||
static int rararch_it_valid(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *value = ((rararch_iterator *) iter)->value;
|
||||
assert(value != NULL);
|
||||
return (Z_TYPE_P(value) != IS_BOOL)?SUCCESS:FAILURE;
|
||||
#else
|
||||
zval *value = &((rararch_iterator *) iter)->value;
|
||||
assert(Z_TYPE_P(value) != IS_UNDEF);
|
||||
return Z_TYPE_P(value) != IS_FALSE ? SUCCESS : FAILURE;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_current_data */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static void rararch_it_current_data(zend_object_iterator *iter,
|
||||
zval ***data TSRMLS_DC)
|
||||
{
|
||||
@@ -947,6 +1134,15 @@ static void rararch_it_current_data(zend_object_iterator *iter,
|
||||
assert(*value != NULL);
|
||||
*data = value;
|
||||
}
|
||||
#else
|
||||
static zval *rararch_it_current_data(zend_object_iterator *iter)
|
||||
{
|
||||
zval *ret;
|
||||
ret = &((rararch_iterator *) iter)->value;
|
||||
assert(Z_TYPE_P(ret) != IS_UNDEF);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_move_forward */
|
||||
@@ -954,7 +1150,11 @@ static void rararch_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
|
||||
{
|
||||
rararch_iterator *it = (rararch_iterator *) iter;
|
||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
it->value = NULL;
|
||||
#else
|
||||
ZVAL_UNDEF(&it->value);
|
||||
#endif
|
||||
rararch_it_fetch(it TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -965,7 +1165,6 @@ static void rararch_it_rewind(zend_object_iterator *iter TSRMLS_DC)
|
||||
rararch_iterator *it = (rararch_iterator *) iter;
|
||||
rararch_it_invalidate_current((zend_object_iterator *) it TSRMLS_CC);
|
||||
_rar_entry_search_rewind(it->state);
|
||||
it->value = NULL;
|
||||
rararch_it_fetch(it TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -982,6 +1181,61 @@ 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;
|
||||
@@ -993,6 +1247,11 @@ void minit_rararch(TSRMLS_D)
|
||||
rararch_object_handlers.write_dimension = rararch_write_dimension;
|
||||
rararch_object_handlers.has_dimension = rararch_has_dimension;
|
||||
rararch_object_handlers.unset_dimension = rararch_unset_dimension;
|
||||
rararch_object_handlers.clone_obj = NULL;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
rararch_object_handlers.free_obj = rararch_ce_free_object_storage;
|
||||
rararch_object_handlers.offset = XtOffsetOf(ze_rararch_object, parent);
|
||||
#endif
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarArchive", php_rararch_class_functions);
|
||||
rararch_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
@@ -1000,8 +1259,14 @@ 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
|
||||
|
||||
308
rarentry.c
308
rarentry.c
@@ -27,11 +27,10 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <zend_types.h>
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
#include <php.h>
|
||||
@@ -41,39 +40,58 @@ extern "C" {
|
||||
zend_class_entry *rar_class_entry_ptr;
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Globals with internal linkage */
|
||||
static zend_object_handlers rarentry_object_handlers;
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Function prototypes for functions with internal linkage */
|
||||
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(int dos_time, char *date_string);
|
||||
static zend_object_value rarentry_ce_create_object(zend_class_entry *class_type TSRMLS_DC);
|
||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string);
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Functions with external linkage */
|
||||
/* should be passed the last entry that corresponds to a given file
|
||||
* only that one has the correct CRC. Still, it may have a wrong packedSize */
|
||||
void _rar_entry_to_zval(zval *parent, /* zval to RarArchive object, will have its refcount increased */
|
||||
/* parent is zval to RarArchive object. The object (not the zval, in PHP 5.x)
|
||||
* will have its refcount increased */
|
||||
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;
|
||||
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 */
|
||||
zval_addref_p(parent_copy);
|
||||
SEPARATE_ZVAL(&parent_copy);
|
||||
/* set refcount to 0; zend_update_property will increase it */
|
||||
Z_DELREF_P(parent_copy);
|
||||
#endif
|
||||
|
||||
object_init_ex(object, rar_class_entry_ptr);
|
||||
zend_update_property(rar_class_entry_ptr, object, "rarfile",
|
||||
sizeof("rararch") - 1, parent TSRMLS_CC);
|
||||
#if PHP_MAJOR_VERSION >= 8
|
||||
zend_object *obj = Z_OBJ_P(object);
|
||||
#else
|
||||
zval *obj = object;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX > 0xffffffffUL
|
||||
zend_update_property(rar_class_entry_ptr, obj, "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
|
||||
unp_size = ((long) entry->UnpSize) + (((long) entry->UnpSizeHigh) << 32);
|
||||
#else
|
||||
/* for 32-bit long, at least don't give negative values */
|
||||
@@ -84,7 +102,7 @@ void _rar_entry_to_zval(zval *parent, /* zval to RarArchive object, will have it
|
||||
unp_size = (long) entry->UnpSize;
|
||||
#endif
|
||||
|
||||
filename_size = sizeof(entry->FileNameW) * sizeof(wchar_t);
|
||||
filename_size = sizeof(entry->FileNameW) * 4;
|
||||
filename = (char*) emalloc(filename_size);
|
||||
|
||||
if (packed_size > (unsigned long) LONG_MAX)
|
||||
@@ -96,34 +114,56 @@ void _rar_entry_to_zval(zval *parent, /* zval to RarArchive object, will have it
|
||||
* properties from here with add_property_x, or
|
||||
* direct call to rarentry_object_handlers.write_property
|
||||
* zend_update_property_x updates the scope accordingly */
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "position",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "position",
|
||||
sizeof("position") - 1, (long) position TSRMLS_CC);
|
||||
zend_update_property_stringl(rar_class_entry_ptr, object, "name",
|
||||
zend_update_property_stringl(rar_class_entry_ptr, obj, "name",
|
||||
sizeof("name") - 1, filename, filename_len TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "unpacked_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "unpacked_size",
|
||||
sizeof("unpacked_size") - 1, unp_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "packed_size",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "packed_size",
|
||||
sizeof("packed_size") - 1, packed_size TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "host_os",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "host_os",
|
||||
sizeof("host_os") - 1, entry->HostOS TSRMLS_CC);
|
||||
|
||||
_rar_dos_date_to_text(entry->FileTime, time);
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "file_time",
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "file_time",
|
||||
sizeof("file_time") - 1, time TSRMLS_CC);
|
||||
|
||||
sprintf(tmp_s, "%x", entry->FileCRC);
|
||||
zend_update_property_string(rar_class_entry_ptr, object, "crc",
|
||||
zend_update_property_string(rar_class_entry_ptr, obj, "crc",
|
||||
sizeof("crc") - 1, tmp_s TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "attr",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "attr",
|
||||
sizeof("attr") - 1, entry->FileAttr TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "version",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "version",
|
||||
sizeof("version") - 1, entry->UnpVer TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "method",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "method",
|
||||
sizeof("method") - 1, entry->Method TSRMLS_CC);
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "flags",
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "flags",
|
||||
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, obj, "redir_type",
|
||||
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
||||
|
||||
if (entry->RedirName) {
|
||||
char *redir_target = NULL;
|
||||
size_t redir_target_size;
|
||||
|
||||
zend_update_property_bool(rar_class_entry_ptr, obj,
|
||||
"redir_to_directory", sizeof("redir_to_directory") - 1,
|
||||
!!entry->DirTarget TSRMLS_CC);
|
||||
|
||||
redir_target_size = entry->RedirNameSize * 4;
|
||||
redir_target = emalloc(redir_target_size);
|
||||
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",
|
||||
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
||||
|
||||
efree(redir_target);
|
||||
}
|
||||
|
||||
efree(filename);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -152,81 +192,98 @@ static int _rar_decl_priv_prop_null(zend_class_entry *ce, const char *name,
|
||||
int name_length, char *doc_comment,
|
||||
int doc_comment_len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval *property;
|
||||
ALLOC_PERMANENT_ZVAL(property);
|
||||
INIT_ZVAL(*property);
|
||||
return zend_declare_property_ex(ce, name, name_length, property,
|
||||
ZEND_ACC_PRIVATE, doc_comment, doc_comment_len TSRMLS_CC);
|
||||
#else
|
||||
zval property;
|
||||
zend_string *name_str,
|
||||
*doc_str;
|
||||
int ret;
|
||||
|
||||
ZVAL_NULL(&property);
|
||||
name_str = zend_string_init(name, (size_t) name_length, 1);
|
||||
doc_str = zend_string_init(doc_comment, (size_t) doc_comment_len, 1);
|
||||
# if PHP_MAJOR_VERSION >= 8
|
||||
zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
||||
doc_str);
|
||||
ret = SUCCESS;
|
||||
# else
|
||||
ret = zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
||||
doc_str);
|
||||
#endif
|
||||
zend_string_release(name_str);
|
||||
zend_string_release(doc_str);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *tmp;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval zv;
|
||||
#endif
|
||||
#if PHP_VERSION_ID < 70100
|
||||
zend_class_entry *orig_scope = EG(scope);
|
||||
|
||||
EG(scope) = rar_class_entry_ptr;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 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
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1 TSRMLS_CC);
|
||||
#endif
|
||||
if (tmp == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Bug: unable to find property '%s'. Please report.", name);
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 70100
|
||||
EG(scope) = orig_scope;
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _rar_dos_date_to_text(int dos_time, char *date_string) /* {{{ */
|
||||
static void _rar_dos_date_to_text(unsigned dos_time, char *date_string) /* {{{ */
|
||||
{
|
||||
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);
|
||||
}
|
||||
/* }}} */
|
||||
time_t time = 0;
|
||||
struct tm tm = {0};
|
||||
int res;
|
||||
|
||||
static zend_object_value rarentry_ce_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object_value zov;
|
||||
zend_object *zobj;
|
||||
res = rar_dos_time_convert(dos_time, &time) != FAILURE &&
|
||||
php_gmtime_r(&time, &tm) != NULL;
|
||||
|
||||
zobj = emalloc(sizeof *zobj);
|
||||
zend_object_std_init(zobj, class_type TSRMLS_CC);
|
||||
if (!res) {
|
||||
sprintf(date_string, "%s", "time conversion failure");
|
||||
}
|
||||
|
||||
#if PHP_VERSION_ID < 50399
|
||||
zend_hash_copy(zobj->properties, &(class_type->default_properties),
|
||||
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
|
||||
#else
|
||||
object_properties_init(zobj, class_type);
|
||||
#endif
|
||||
zov.handle = zend_objects_store_put(zobj,
|
||||
(zend_objects_store_dtor_t) zend_objects_destroy_object,
|
||||
(zend_objects_free_object_storage_t) zend_objects_free_object_storage,
|
||||
NULL TSRMLS_CC);
|
||||
zov.handlers = &rarentry_object_handlers;
|
||||
return zov;
|
||||
sprintf(date_string, "%u-%02u-%02u %02u:%02u:%02u",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
|
||||
tm.tm_sec);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Methods */
|
||||
/* {{{ proto bool RarEntry::extract(string dir [, string filepath = ''
|
||||
[, string password = NULL [, bool extended_data = FALSE]])
|
||||
/* {{{ public function extract(?string $dir, ?string $filepath = '',
|
||||
?string $password = null, bool $extended_data = false): void {}
|
||||
Extract file from the archive */
|
||||
PHP_METHOD(rarentry, extract)
|
||||
{ /* lots of variables, but no need to be intimidated */
|
||||
char *dir,
|
||||
*filepath = NULL,
|
||||
*password = NULL;
|
||||
int dir_len,
|
||||
zpp_s_size_t dir_len,
|
||||
filepath_len = 0,
|
||||
password_len = 0;
|
||||
char *considered_path;
|
||||
@@ -246,14 +303,14 @@ PHP_METHOD(rarentry, extract)
|
||||
* password that's different from the one stored in the rar_file_t object*/
|
||||
rar_cb_user_data cb_udata = {NULL};
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss!b", &dir,
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!|s!s!b", &dir,
|
||||
&dir_len, &filepath, &filepath_len, &password, &password_len,
|
||||
&process_ed) == FAILURE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -360,7 +417,7 @@ PHP_METHOD(rarentry, getName)
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "name");
|
||||
|
||||
RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
RAR_RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -410,7 +467,9 @@ PHP_METHOD(rarentry, getHostOs)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string RarEntry::getFileTime()
|
||||
Return modification time of the entry */
|
||||
Return modification time of the entry.
|
||||
Due to the way the unrar library returns this time, this is in the
|
||||
system's timezone. */
|
||||
PHP_METHOD(rarentry, getFileTime)
|
||||
{
|
||||
zval *tmp;
|
||||
@@ -420,7 +479,7 @@ PHP_METHOD(rarentry, getFileTime)
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "file_time");
|
||||
|
||||
RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
RAR_RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -435,7 +494,7 @@ PHP_METHOD(rarentry, getCrc)
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "crc");
|
||||
|
||||
RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
RAR_RETURN_STRINGL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -494,7 +553,7 @@ PHP_METHOD(rarentry, getStream)
|
||||
zval *entry_obj = getThis();
|
||||
php_stream *stream = NULL;
|
||||
char *password = NULL;
|
||||
int password_len; /* ignored */
|
||||
zpp_s_size_t password_len; /* ignored */
|
||||
rar_cb_user_data cb_udata = {NULL};
|
||||
|
||||
|
||||
@@ -505,7 +564,7 @@ PHP_METHOD(rarentry, getStream)
|
||||
|
||||
RAR_GET_PROPERTY(position, "position");
|
||||
RAR_GET_PROPERTY(tmp, "rarfile");
|
||||
if (_rar_get_file_resource(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
if (_rar_get_file_resource_zv(tmp, &rar TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -539,7 +598,7 @@ PHP_METHOD(rarentry, isDirectory)
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "flags");
|
||||
flags = Z_LVAL_P(tmp);
|
||||
is_dir = ((flags & LHD_WINDOWMASK) == LHD_DIRECTORY);
|
||||
is_dir = (flags & RHDF_DIRECTORY) != 0;
|
||||
|
||||
RETURN_BOOL(is_dir);
|
||||
}
|
||||
@@ -558,12 +617,66 @@ PHP_METHOD(rarentry, isEncrypted)
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "flags");
|
||||
flags = Z_LVAL_P(tmp);
|
||||
is_encrypted = (flags & 0x04);
|
||||
is_encrypted = (flags & RHDF_ENCRYPTED) != 0;
|
||||
|
||||
RETURN_BOOL(is_encrypted);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int RarEntry::getRedirType()
|
||||
Returns the redirection type, or NULL if there's none */
|
||||
PHP_METHOD(rarentry, getRedirType)
|
||||
{
|
||||
zval *tmp;
|
||||
zval *entry_obj = getThis();
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "redir_type");
|
||||
if (Z_TYPE_P(tmp) != IS_LONG) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "bad redir type stored");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (Z_LVAL_P(tmp) == FSREDIR_NONE) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
RETURN_LONG(Z_LVAL_P(tmp));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool RarEntry::isRedirectToDirectory()
|
||||
Returns true if there is redirection and the target is a directory,
|
||||
null if there is no redirection, false otherwise */
|
||||
PHP_METHOD(rarentry, isRedirectToDirectory)
|
||||
{
|
||||
zval *tmp;
|
||||
zval *entry_obj = getThis();
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "redir_to_directory");
|
||||
|
||||
RETURN_ZVAL(tmp, 1, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool RarEntry::getRedirTarget()
|
||||
Returns the redirection target, encoded as UTF-8, or NULL */
|
||||
PHP_METHOD(rarentry, getRedirTarget)
|
||||
{
|
||||
zval *tmp;
|
||||
zval *entry_obj = getThis();
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
RAR_GET_PROPERTY(tmp, "redir_target");
|
||||
|
||||
RETURN_ZVAL(tmp, 1, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string RarEntry::__toString()
|
||||
Return string representation for entry */
|
||||
PHP_METHOD(rarentry, __toString)
|
||||
@@ -577,14 +690,14 @@ PHP_METHOD(rarentry, __toString)
|
||||
char *name,
|
||||
*crc;
|
||||
char *restring;
|
||||
int restring_len;
|
||||
int restring_size;
|
||||
const char format[] = "RarEntry for %s \"%s\" (%s)";
|
||||
|
||||
RAR_RETNULL_ON_ARGS();
|
||||
|
||||
RAR_GET_PROPERTY(flags_zval, "flags");
|
||||
flags = Z_LVAL_P(flags_zval);
|
||||
is_dir = ((flags & 0xE0) == 0xE0);
|
||||
is_dir = flags & RHDF_DIRECTORY;
|
||||
|
||||
RAR_GET_PROPERTY(name_zval, "name");
|
||||
name = Z_STRVAL_P(name_zval);
|
||||
@@ -593,25 +706,34 @@ PHP_METHOD(rarentry, __toString)
|
||||
crc = Z_STRVAL_P(crc_zval);
|
||||
|
||||
/* 2 is size of %s, 8 is size of crc */
|
||||
restring_len = (sizeof(format)-1) - 2 * 3 + (sizeof("directory")-1) +
|
||||
restring_size = (sizeof(format)-1) - 2 * 3 + (sizeof("directory")-1) +
|
||||
strlen(name) + 8 + 1;
|
||||
restring = emalloc(restring_len);
|
||||
snprintf(restring, restring_len, format, is_dir?"directory":"file",
|
||||
restring = emalloc(restring_size);
|
||||
snprintf(restring, restring_size, format, is_dir?"directory":"file",
|
||||
name, crc);
|
||||
restring[restring_len - 1] = '\0'; /* just to be safe */
|
||||
restring[restring_size - 1] = '\0'; /* just to be safe */
|
||||
|
||||
RETURN_STRING(restring, 0);
|
||||
RAR_RETURN_STRINGL(restring, strlen(restring), 0);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
@@ -619,6 +741,13 @@ 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[] = {
|
||||
@@ -636,7 +765,10 @@ static zend_function_entry php_rar_class_functions[] = {
|
||||
PHP_ME(rarentry, getStream, arginfo_rarentry_getstream, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, isDirectory, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, isEncrypted, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, __toString, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, getRedirType, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, isRedirectToDirectory, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, getRedirTarget, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, __toString, arginfo_rar_tostring, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
@@ -645,15 +777,10 @@ void minit_rarentry(TSRMLS_D)
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
memcpy(&rarentry_object_handlers, zend_get_std_object_handlers(),
|
||||
sizeof rarentry_object_handlers);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarEntry", php_rar_class_functions);
|
||||
rar_class_entry_ptr = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
rar_class_entry_ptr->ce_flags |= ZEND_ACC_FINAL_CLASS;
|
||||
rar_class_entry_ptr->clone = NULL;
|
||||
/* Custom creation currently not really needed, but you never know... */
|
||||
rar_class_entry_ptr->create_object = &rarentry_ce_create_object;
|
||||
|
||||
REG_RAR_PROPERTY("rarfile", "Associated RAR archive");
|
||||
REG_RAR_PROPERTY("position", "Position inside the RAR archive");
|
||||
@@ -667,6 +794,9 @@ void minit_rarentry(TSRMLS_D)
|
||||
REG_RAR_PROPERTY("version", "RAR version needed to extract entry");
|
||||
REG_RAR_PROPERTY("method", "Identifier for packing method");
|
||||
REG_RAR_PROPERTY("flags", "Entry header flags");
|
||||
REG_RAR_PROPERTY("redir_type", "The type of redirection or NULL");
|
||||
REG_RAR_PROPERTY("redir_to_directory", "Whether the redirection target is a directory");
|
||||
REG_RAR_PROPERTY("redir_target", "Target of the redirectory");
|
||||
|
||||
REG_RAR_CLASS_CONST_LONG("HOST_MSDOS", HOST_MSDOS);
|
||||
REG_RAR_CLASS_CONST_LONG("HOST_OS2", HOST_OS2);
|
||||
@@ -675,6 +805,12 @@ void minit_rarentry(TSRMLS_D)
|
||||
REG_RAR_CLASS_CONST_LONG("HOST_MACOS", HOST_MACOS);
|
||||
REG_RAR_CLASS_CONST_LONG("HOST_BEOS", HOST_BEOS);
|
||||
|
||||
REG_RAR_CLASS_CONST_LONG("FSREDIR_UNIXSYMLINK", FSREDIR_UNIXSYMLINK);
|
||||
REG_RAR_CLASS_CONST_LONG("FSREDIR_WINSYMLINK", FSREDIR_WINSYMLINK);
|
||||
REG_RAR_CLASS_CONST_LONG("FSREDIR_JUNCTION", FSREDIR_JUNCTION);
|
||||
REG_RAR_CLASS_CONST_LONG("FSREDIR_HARDLINK", FSREDIR_HARDLINK);
|
||||
REG_RAR_CLASS_CONST_LONG("FSREDIR_FILECOPY", FSREDIR_FILECOPY);
|
||||
|
||||
/* see WinNT.h */
|
||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_WIN_READONLY", 0x00001L);
|
||||
REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_WIN_HIDDEN", 0x00002L);
|
||||
@@ -714,7 +850,3 @@ 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
|
||||
|
||||
0
report.xml
Normal file
0
report.xml
Normal file
3811
run-tests8.php
Normal file
3811
run-tests8.php
Normal file
File diff suppressed because it is too large
Load Diff
70
test_funcs.sh
Normal file
70
test_funcs.sh
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/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,6 +5,7 @@ rar_list() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$list1 = rar_list($rar_file1);
|
||||
var_dump($list1);
|
||||
@@ -14,8 +15,7 @@ $list2 = rar_list($rar_file2);
|
||||
var_dump($list2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
$list3 = rar_list($rar_file3);
|
||||
var_dump($list3);
|
||||
argerr(function() use ($rar_file3) { rar_list($rar_file3); });
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -24,7 +24,7 @@ array(2) {
|
||||
[0]=>
|
||||
object(RarEntry)#%d (%d) {
|
||||
["rarfile%sprivate%s=>
|
||||
object(RarArchive)#%s (%s) {
|
||||
object(RarArchive)#%d (%d) {
|
||||
}
|
||||
["position%sprivate%s=>
|
||||
int(0)
|
||||
@@ -47,12 +47,18 @@ array(2) {
|
||||
["method%sprivate%s=>
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(32800)
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
object(RarEntry)#%d (%d) {
|
||||
["rarfile%sprivate%s=>
|
||||
object(RarArchive)#%d (0) {
|
||||
object(RarArchive)#%d (%d) {
|
||||
}
|
||||
["position%sprivate%s=>
|
||||
int(1)
|
||||
@@ -75,7 +81,13 @@ array(2) {
|
||||
["method%sprivate%s=>
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(32800)
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
@@ -105,7 +117,13 @@ array(2) {
|
||||
["method%sprivate%s=>
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(36992)
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
object(RarEntry)#%d (%d) {
|
||||
@@ -133,12 +151,17 @@ array(2) {
|
||||
["method%sprivate%s=>
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(37008)
|
||||
int(16)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
|
||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Warning: rar_list() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_list() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
Done
|
||||
|
||||
@@ -5,6 +5,7 @@ rar_entry_get() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$entry1 = rar_entry_get($rar_file1, 'test file with whitespaces.txt');
|
||||
var_dump($entry1);
|
||||
@@ -14,8 +15,9 @@ $entry2 = rar_entry_get($rar_file2, '2.txt');
|
||||
var_dump($entry2);
|
||||
|
||||
$rar_file3 = rar_open(dirname(__FILE__).'/no_such_file.rar');
|
||||
$entry3 = rar_entry_get($rar_file3, '2.txt');
|
||||
var_dump($entry3);
|
||||
argerr(function() use ($rar_file3) {
|
||||
rar_entry_get($rar_file3, '2.txt');
|
||||
});
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@@ -45,7 +47,13 @@ object(RarEntry)#%d (%d) {
|
||||
["method%sprivate%s=>
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(32800)
|
||||
int(0)
|
||||
["redir_type%sprivate%s=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate%s=>
|
||||
NULL
|
||||
["redir_target%sprivate%s=>
|
||||
NULL
|
||||
}
|
||||
object(RarEntry)#%d (%d) {
|
||||
["rarfile%sprivate%s=>
|
||||
@@ -72,11 +80,16 @@ object(RarEntry)#%d (%d) {
|
||||
["method%sprivate%s=>
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(37008)
|
||||
int(16)
|
||||
["redir_type%sprivate%s=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate%s=>
|
||||
NULL
|
||||
["redir_target%sprivate%s=>
|
||||
NULL
|
||||
}
|
||||
|
||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
Done
|
||||
|
||||
@@ -55,7 +55,7 @@ blah-blah-blah
|
||||
string(5) "22222"
|
||||
object(RarEntry)#%d (%d) {
|
||||
["rarfile%sprivate%s=>
|
||||
object(RarArchive)#3 (0) {
|
||||
object(RarArchive)#%d (%d) {
|
||||
}
|
||||
["position%sprivate%s=>
|
||||
int(1)
|
||||
@@ -78,7 +78,13 @@ object(RarEntry)#%d (%d) {
|
||||
["method%sprivate%s=>
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(37008)
|
||||
int(16)
|
||||
["redir_type%sprivate%s=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate%s=>
|
||||
NULL
|
||||
["redir_target%sprivate%s=>
|
||||
NULL
|
||||
}
|
||||
bool(true)
|
||||
Done
|
||||
|
||||
@@ -5,6 +5,8 @@ rar_entry_get() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
|
||||
$rar_file1 = rar_open(dirname(__FILE__).'/multi.part1.rar');
|
||||
$entry = rar_entry_get($rar_file1, "file1.txt");
|
||||
echo "$entry\n";
|
||||
@@ -13,8 +15,9 @@ var_dump($entry);
|
||||
echo "\n";
|
||||
|
||||
$rar_file2 = rar_open(dirname(__FILE__).'/nonexistent.rar');
|
||||
$entry = rar_entry_get($rar_file2, "file1.txt");
|
||||
var_dump($entry);
|
||||
argerr(function() use ($rar_file2) {
|
||||
rar_entry_get($rar_file2, "file1.txt");
|
||||
});
|
||||
echo "\n";
|
||||
|
||||
echo "Done\n";
|
||||
@@ -28,7 +31,6 @@ bool(false)
|
||||
|
||||
Warning: rar_open(): Failed to open %s: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, boolean given in %s on line %d
|
||||
NULL
|
||||
Warning: rar_entry_get() expects parameter 1 to be RarArchive, %s given in %s on line %d
|
||||
|
||||
Done
|
||||
|
||||
@@ -9,10 +9,6 @@ $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) {
|
||||
@@ -25,7 +21,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -33,9 +33,9 @@ echo "Done\n";
|
||||
--EXPECTF--
|
||||
51 files (will test only the first 4):
|
||||
|
||||
: The great battle of Gunprex versus Optiter!!!!!1
|
||||
test%s: The great battle of Gunprex versus Optiter!!!!!1
|
||||
Gunprex, Fire!
|
||||
So long, Optiter!
|
||||
|
||||
:
|
||||
test%s
|
||||
Done
|
||||
|
||||
@@ -9,10 +9,6 @@ $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().": ";
|
||||
@@ -21,7 +17,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 512);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -9,10 +9,6 @@ $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().": ";
|
||||
@@ -21,7 +17,7 @@ foreach ($entries as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -4,6 +4,9 @@ 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 (preg_match('/_fail/', $vol))
|
||||
if (strpos($vol, '_fail') !== false)
|
||||
$ret = basename(str_replace('_fail', '', $vol));
|
||||
elseif (preg_match('/_broken/', $vol))
|
||||
elseif (strpos($vol, '_broken') !== false)
|
||||
$ret = basename(str_replace('_broken', '_fail', $vol));
|
||||
else
|
||||
$ret = null;
|
||||
|
||||
@@ -5,6 +5,7 @@ rar_open() with invalid volume callback
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
|
||||
class A {
|
||||
public static function resolve($vol) {
|
||||
@@ -29,12 +30,16 @@ $rar = RarArchive::open($fn, null, "A::resolveInstance");
|
||||
var_dump($rar);
|
||||
|
||||
echo "\nGiven callback that takes more arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'array_walk');
|
||||
$rar->getEntries();
|
||||
$rar = RarArchive::open($fn, null, 'strpos');
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
|
||||
echo "\nGiven callback that takes another kind of arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'ksort');
|
||||
$rar->getEntries();
|
||||
$rar = RarArchive::open($fn, null, 'array_keys');
|
||||
argerr(function() use ($rar) {
|
||||
$rar->getEntries();
|
||||
});
|
||||
|
||||
echo "\nGiven callback that returns another kind of arguments:\n";
|
||||
function testA($vol) { return true; }
|
||||
@@ -52,7 +57,7 @@ try {
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
Not given a callback:
|
||||
|
||||
Warning: RarArchive::open(): Expected the third argument, if provided, to be a valid callback in %s on line %d
|
||||
@@ -64,18 +69,34 @@ bool(false)
|
||||
|
||||
Given callback that takes more arguments:
|
||||
|
||||
Warning: array_walk() expects at least %d parameters, 1 given in %s on line %d
|
||||
<?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:
|
||||
|
||||
Warning: ksort() expects parameter 1 to be array, string given in %s on line %d
|
||||
|
||||
Warning: RarArchive::getEntries(): Wrong type returned by volume find callback, expected string or NULL in %s on line %d
|
||||
<?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:
|
||||
|
||||
Warning: RarArchive::getEntries(): Wrong type returned by volume find callback, expected string or NULL in %s on line %d
|
||||
|
||||
@@ -10,10 +10,6 @@ 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();
|
||||
@@ -23,7 +19,7 @@ foreach ($rar_file1 as $e) {
|
||||
$a .= fread($stream, 8192);
|
||||
}
|
||||
echo strlen($a)." bytes, CRC ";
|
||||
echo int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
@@ -10,10 +10,6 @@ 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');
|
||||
@@ -22,7 +18,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 int32_to_hex(crc32(file_get_contents(dirname(__FILE__) . "/temp_file2.txt")));
|
||||
echo strtoupper(hash("crc32b", file_get_contents(dirname(__FILE__) . "/temp_file2.txt")));
|
||||
echo "\n";
|
||||
echo "Done\n";
|
||||
?>
|
||||
|
||||
@@ -5,9 +5,9 @@ RarArchive::open() volume callback long return (case MAXPATHLEN > NM)
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (!defined("PHP_MAXPATHLEN"))
|
||||
define("PHP_MAXPATHLEN", RAR_MAXPATHLEN);
|
||||
if (!(PHP_MAXPATHLEN > 1024))
|
||||
die("skip test is for systems where MAXPATHLEN > 1024");
|
||||
$rp = dirname(__FILE__) . "/" . str_repeat("a", 1024);
|
||||
if (!(PHP_MAXPATHLEN > 2048))
|
||||
die("skip test is for systems where MAXPATHLEN > 2048");
|
||||
$rp = dirname(__FILE__) . "/" . str_repeat("a", 2048);
|
||||
if (strlen(dirname(__FILE__) > PHP_MAXPATHLEN - 1))
|
||||
die("skip current directory is too deep.");
|
||||
--FILE--
|
||||
@@ -17,8 +17,8 @@ if (!defined("PHP_MAXPATHLEN"))
|
||||
|
||||
chdir(dirname(__FILE__));
|
||||
$fn = dirname(__FILE__) . '/multi_broken.part1.rar';
|
||||
|
||||
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", 1024); }
|
||||
|
||||
function testA($vol) { if ($vol[0] != 'a') return str_repeat("a", 2048); }
|
||||
$rar = RarArchive::open($fn, null, 'testA');
|
||||
$rar->getEntries();
|
||||
|
||||
|
||||
@@ -50,11 +50,11 @@ string(5) "11111"
|
||||
Test with include path:
|
||||
Should fail (not in include):
|
||||
|
||||
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Should fail (include unused):
|
||||
|
||||
Warning: fopen(rar://tmp.rar#1.txt): failed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://tmp.rar#1.txt): %cailed to open stream: Error opening RAR archive %stmp.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
Should succeed:
|
||||
string(5) "11111"
|
||||
|
||||
@@ -20,9 +20,9 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Archive not found :
|
||||
|
||||
Warning: fopen(rar://%snot_found.rar#1.txt): failed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: fopen(rar://%snot_found.rar#1.txt): %cailed to open stream: Error opening RAR archive %snot_found.rar: ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
File not found :
|
||||
|
||||
Warning: fopen(rar://%slatest_winrar.rar#not_found.txt): failed to open stream: Can't file not_found.txt in RAR archive %s on line %d
|
||||
Done.
|
||||
Warning: fopen(rar://%slatest_winrar.rar#not_found.txt): %cailed to open stream: Can't file not_found.txt in RAR archive %s on line %d
|
||||
Done.
|
||||
|
||||
@@ -27,21 +27,21 @@ echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Test empty:
|
||||
|
||||
Warning: fopen(rar://): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no fragment:
|
||||
|
||||
Warning: fopen(rar://file.rar): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://file.rar): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test empty fragment:
|
||||
|
||||
Warning: fopen(rar://file.rar#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://file.rar#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no path:
|
||||
|
||||
Warning: fopen(rar://#frag): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://#frag): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
|
||||
Test no path and empty fragment:
|
||||
|
||||
Warning: fopen(rar://#): failed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Warning: fopen(rar://#): %cailed to open stream: The url must contain a path and a non-empty fragment; it must be in the form "rar://<urlencoded path to RAR archive>[*]#<urlencoded entry name>" in %s on line %d
|
||||
Done.
|
||||
|
||||
@@ -55,11 +55,11 @@ echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
Headers: should not work (no password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Headers: should not work (password given was file_password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): failed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_headers.rar#encfile1.txt): %cailed to open stream: Error opening RAR archive %sencrypted_headers.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Headers: should work (password given was open_password):
|
||||
string(26) "Encrypted file 1 contents."
|
||||
@@ -67,11 +67,11 @@ string(26) "Encrypted file 1 contents."
|
||||
|
||||
Files: should not work (no password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Files: should not work (password given was open_password):
|
||||
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): failed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
Warning: fopen(rar://%sencrypted_only_files.rar#encfile1.txt): %cailed to open stream: Error opening file encfile1.txt inside RAR archive %sencrypted_only_files.rar: ERAR_MISSING_PASSWORD (password needed but not specified) in %s on line %d
|
||||
|
||||
Files: should work (password given was file_password):
|
||||
string(26) "Encrypted file 1 contents."
|
||||
|
||||
@@ -11,17 +11,13 @@ 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 int32_to_hex(crc32($a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo strtoupper(hash("crc32b", $a))."\n\n"; //you can confirm they're equal to those given by $e->getCrc()
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
17704 bytes, CRC F2C79881
|
||||
|
||||
@@ -4,14 +4,20 @@ RAR file stream stat
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--ENV--
|
||||
TZ=Europe/Lisbon
|
||||
TZ=Asia/Tokyo
|
||||
--FILE--
|
||||
<?php
|
||||
umask(0);
|
||||
$stream = fopen("rar://" .
|
||||
dirname(__FILE__) . '/latest_winrar.rar' .
|
||||
"#1.txt", "r");
|
||||
print_r(array_slice(fstat($stream), 13));
|
||||
$r = array_slice(fstat($stream), 13);
|
||||
if (PHP_OS == 'WINNT') {
|
||||
// we don't return the correct value on windows
|
||||
$r['mtime'] = 1086948439;
|
||||
}
|
||||
|
||||
print_r($r);
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
|
||||
@@ -12,6 +12,6 @@ var_dump(opendir($u));
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
Warning: opendir(rar://%sdirlink_unix.rar#file): failed to open dir: Archive %sdirlink_unix.rar has an entry named file, but it is not a directory in %s on line %d
|
||||
Warning: opendir(rar://%sdirlink_unix.rar#file): %cailed to open dir%S: Archive %sdirlink_unix.rar has an entry named file, but it is not a directory in %s on line %d
|
||||
bool(false)
|
||||
Done.
|
||||
|
||||
@@ -21,7 +21,14 @@ echo "\nSub-root directory:\n";
|
||||
$u = "rar://" .
|
||||
dirname(__FILE__) . '/dirs_and_extra_headers.rar#%EF%AC%B0';
|
||||
|
||||
print_r(array_slice(fstat(opendir($u)), 13));
|
||||
$r = array_slice(fstat(opendir($u)), 13);
|
||||
if (PHP_OS == 'WINNT') {
|
||||
// we don't give the correct values on windows
|
||||
$r['atime'] = 1272938643;
|
||||
$r['mtime'] = 1272938643;
|
||||
$r['ctime'] = 1272813170;
|
||||
}
|
||||
print_r($r);
|
||||
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
RarArchive direct instantiation does not crash
|
||||
RarArchive direct instantiation does not crash (PHP 5.x)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
<?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
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--TEST--
|
||||
RarEntry direct instantiation does not crash
|
||||
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: count(): The archive is already closed in %s on line %d
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (2):
|
||||
|
||||
Warning: count(): The archive is already closed in %s on line %d
|
||||
Warning: %s(): The archive is already closed in %s on line %d
|
||||
int(0)
|
||||
|
||||
* Closed file test (3, exceptions):
|
||||
|
||||
@@ -15,10 +15,12 @@ echo "string (\"0.001\"). {$a['0.001']}\n";
|
||||
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
string ("0"). RarEntry for file "1.txt" (a0de71c0)
|
||||
<?php if (PHP_VERSION_ID < 80000) { ?>
|
||||
|
||||
Notice: A non well formed numeric value encountered in %s on line %d
|
||||
<?php } ?>
|
||||
string ("1abc"). RarEntry for file "2.txt" (45a918de)
|
||||
float (0.001). RarEntry for file "1.txt" (a0de71c0)
|
||||
string ("0.001"). RarEntry for file "1.txt" (a0de71c0)
|
||||
|
||||
@@ -42,7 +42,7 @@ echo $a[new stdClass()];
|
||||
|
||||
echo "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
--EXPECTF_DYNAMIC--
|
||||
* -1 (int):
|
||||
|
||||
Warning: main(): Dimension index must be non-negative, given -1 in %s on line %d
|
||||
@@ -81,6 +81,11 @@ Warning: main(): Attempt to use a non-numeric dimension to access a RarArchive o
|
||||
|
||||
* new stdClass():
|
||||
|
||||
Warning: main(): Attempt to use an object with no get handler as a dimension to access a RarArchive object in %s on line %d
|
||||
<?php if (PHP_VERSION_ID >= 80000) { ?>
|
||||
Warning: main(): Could not convert object given as dimension index into an integer (cast_object failed) in %s on line %d
|
||||
|
||||
<?php } else { ?>
|
||||
Notice: Object of class stdClass could not be converted to int in %s on line %d
|
||||
RarEntry for file "2.txt" (45a918de)
|
||||
<?php } ?>
|
||||
Done.
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -4,6 +4,9 @@ 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,9 +1,15 @@
|
||||
--TEST--
|
||||
RarArchive write_property gives a fatal error
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
if (key_exists('USE_ZEND_ALLOC', $_ENV) && PHP_VERSION_ID < 70000) die('skip do not use with valgrind in PHP <7')
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (PHP_VERSION_ID>=80500){
|
||||
ini_set('fatal_error_backtraces', 'Off');
|
||||
}
|
||||
|
||||
$f1 = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$a = RarArchive::open($f1);
|
||||
|
||||
@@ -4,6 +4,9 @@ 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,13 +5,18 @@ RarArchive::isBroken/rar_broken_is test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$f = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$b = dirname(__FILE__) . "/multi_broken.part1.rar";
|
||||
|
||||
echo "\n* unbroken file; bad arguments\n";
|
||||
$a = RarArchive::open($f);
|
||||
var_dump($a->isBroken("jjj"));
|
||||
var_dump(rar_broken_is($a, "jjj"));
|
||||
argerr(function() use ($a) {
|
||||
$a->isBroken("jjj");
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_broken_is($a, "jjj");
|
||||
});
|
||||
|
||||
echo "\n* unbroken file; as first call\n";
|
||||
var_dump($a->isBroken());
|
||||
@@ -46,10 +51,8 @@ echo "Done.\n";
|
||||
* unbroken file; bad arguments
|
||||
|
||||
Warning: RarArchive::isBroken() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: rar_broken_is() expects exactly 1 parameter, 2 given in %s on line %d
|
||||
NULL
|
||||
|
||||
* unbroken file; as first call
|
||||
bool(false)
|
||||
|
||||
@@ -5,13 +5,18 @@ RarArchive::setAllowBroken has the desired effect
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
function retnull() { return null; }
|
||||
$b = dirname(__FILE__) . "/multi_broken.part1.rar";
|
||||
|
||||
echo "* broken file; bad arguments\n";
|
||||
$a = RarArchive::open($b, null, 'retnull');
|
||||
$a->setAllowBroken();
|
||||
rar_allow_broken_set($a);
|
||||
argerr(function() use ($a) {
|
||||
$a->setAllowBroken();
|
||||
});
|
||||
argerr(function() use ($a) {
|
||||
rar_allow_broken_set($a);
|
||||
});
|
||||
|
||||
echo "\n* broken file; do not allow broken (default)\n";
|
||||
$a = RarArchive::open($b, null, 'retnull');
|
||||
@@ -54,7 +59,7 @@ Warning: rar_allow_broken_set() expects exactly 2 parameters, 1 given in %s on l
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; do not allow broken (explicit)
|
||||
@@ -62,7 +67,7 @@ int(0)
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: count(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
Warning: %s(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
int(0)
|
||||
|
||||
* broken file; allow broken
|
||||
|
||||
@@ -4,6 +4,9 @@ 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,6 +5,7 @@ Wrapper cache exaustion test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require __DIR__ . "/php8compat.php.inc";
|
||||
$f = array();
|
||||
$f[] = dirname(__FILE__) . "/latest_winrar.rar";
|
||||
$f[] = dirname(__FILE__) . "/directories.rar";
|
||||
@@ -18,7 +19,9 @@ function printstats() {
|
||||
}
|
||||
|
||||
echo "* Invalid call to rar_wrapper_cache_stats():\n";
|
||||
var_dump(rar_wrapper_cache_stats("sfddf"));
|
||||
argerr(function() {
|
||||
rar_wrapper_cache_stats("sfddf");
|
||||
});
|
||||
|
||||
echo "\n* Initial stats:\n";
|
||||
printstats();
|
||||
@@ -75,7 +78,6 @@ echo "Done.\n";
|
||||
* Invalid call to rar_wrapper_cache_stats():
|
||||
|
||||
Warning: rar_wrapper_cache_stats() expects exactly 0 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
* Initial stats:
|
||||
Stats: 0/0 (hits/misses)
|
||||
|
||||
@@ -10,7 +10,9 @@ phpinfo(INFO_MODULES);
|
||||
$phpinfo = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$phpinfo = preg_replace('/\r\n?/', "\n", $phpinfo); //normalize line endings
|
||||
//normalize line endings
|
||||
$phpinfo = str_replace("\r\n", "\n", $phpinfo);
|
||||
$phpinfo = str_replace("\r", "\n", $phpinfo);
|
||||
|
||||
$phpinfo = explode("\n", $phpinfo);
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@ foreach ($rar as $rar_file) {
|
||||
|
||||
echo "\nDone.\n";
|
||||
--EXPECTF--
|
||||
int(2279)
|
||||
int(1316)
|
||||
Warning: stream_get_contents(): The file size is supposed to be 2279 bytes, but we read more: 2288 bytes (corruption/wrong pwd) in %s on line %d
|
||||
int(2288)
|
||||
|
||||
Done.
|
||||
Warning: stream_get_contents(): The file size is supposed to be 1316 bytes, but we read more: 1328 bytes (corruption/wrong pwd) in %s on line %d
|
||||
int(1328)
|
||||
|
||||
Done.
|
||||
|
||||
@@ -32,6 +32,6 @@ opened
|
||||
|
||||
Testing 'r+'
|
||||
|
||||
Warning: fopen(%s): failed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
Warning: fopen(%s): %cailed to open stream: Only the "r" and "rb" open modes are permitted, given r+ in %s on line %d
|
||||
|
||||
Done.
|
||||
|
||||
55
tests/101.phpt
Normal file
55
tests/101.phpt
Normal file
@@ -0,0 +1,55 @@
|
||||
--TEST--
|
||||
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);
|
||||
$file = dirname(__FILE__) . '/rar5_multi.part1.rar';
|
||||
$rar = RarArchive::open($file);
|
||||
$entry = $rar->getEntry('usr' . DIRECTORY_SEPARATOR . 'bin' .
|
||||
DIRECTORY_SEPARATOR . 'text2image');
|
||||
var_dump($entry);
|
||||
$stream = $entry->getStream('passw0rd');
|
||||
$contents = stream_get_contents($stream);
|
||||
echo "(unpacked) MD5: ", md5($contents), "\n";
|
||||
echo "Done.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(RarEntry)#%d (%d) {
|
||||
["rarfile%sprivate%s=>
|
||||
object(RarArchive)#%d (%d) {
|
||||
}
|
||||
["position%sprivate%s=>
|
||||
int(0)
|
||||
["name%sprivate%s=>
|
||||
string(18) "usr%sbin%stext2image"
|
||||
["unpacked_size%sprivate%s=>
|
||||
int(147528)
|
||||
["packed_size%sprivate%s=>
|
||||
int(57104)
|
||||
["host_os%sprivate%s=>
|
||||
int(3)
|
||||
["file_time%sprivate%s=>
|
||||
string(19) "%s"
|
||||
["crc%sprivate%s=>
|
||||
string(8) "83c9a6b7"
|
||||
["attr%sprivate%s=>
|
||||
int(33261)
|
||||
["version%sprivate%s=>
|
||||
int(50)
|
||||
["method%sprivate%s=>
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(5)
|
||||
["redir_type%sprivate%s=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate%s=>
|
||||
NULL
|
||||
["redir_target%sprivate%s=>
|
||||
NULL
|
||||
}
|
||||
(unpacked) MD5: c07ce36ec260848f47fe8ac1408f938f
|
||||
Done.
|
||||
17
tests/102.phpt
Normal file
17
tests/102.phpt
Normal file
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
RarArchive direct instantiation does not crash (PHP 7)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70000) die("skip for PHP >= 7");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new RarArchive();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to private RarArchive::__construct() from %s in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
16
tests/103.phpt
Normal file
16
tests/103.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
RarEntry direct instantiation does not crash (PHP 7)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70000) die("skip for PHP >= 7");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new RarEntry();
|
||||
|
||||
echo "Done\n";
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to private RarEntry::__construct() from %s in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
19
tests/104.phpt
Normal file
19
tests/104.phpt
Normal file
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Clone of RarArchive is forbidden (PHP 7)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip";
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 70000) die("skip for PHP >= 7");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
$file = dirname(__FILE__) . '/rar5_multi.part1.rar';
|
||||
$rar = RarArchive::open($file);
|
||||
$rar2 = clone $rar;
|
||||
$rar2->getEntries();
|
||||
echo "Never reached.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Trying to clone an uncloneable object of class RarArchive in %s:5
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
||||
16
tests/105.phpt
Normal file
16
tests/105.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Clone of RarArchive is forbidden (PHP 5.x)
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip";
|
||||
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID >= 70000) die("skip for PHP 5.x");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
$file = dirname(__FILE__) . '/rar5_multi.part1.rar';
|
||||
$rar = RarArchive::open($file);
|
||||
$rar2 = clone $rar;
|
||||
$rar2->getEntries();
|
||||
echo "Never reached.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Trying to clone an uncloneable object of class RarArchive in %s on line %d
|
||||
19
tests/106.phpt
Normal file
19
tests/106.phpt
Normal file
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Stat times don't depend on timezone (cf. 056.phpt)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if(!extension_loaded("rar")) die("skip");
|
||||
--ENV--
|
||||
TZ=UTC
|
||||
--FILE--
|
||||
<?php
|
||||
umask(0);
|
||||
$stream = fopen("rar://" .
|
||||
dirname(__FILE__) . '/latest_winrar.rar' .
|
||||
"#1.txt", "r");
|
||||
$fs = fstat($stream);
|
||||
echo $fs['mtime'], "\n";
|
||||
echo "Done.\n";
|
||||
--EXPECTF--
|
||||
1086948439
|
||||
Done.
|
||||
53
tests/107.phpt
Normal file
53
tests/107.phpt
Normal file
@@ -0,0 +1,53 @@
|
||||
--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.
|
||||
14
tests/108.phpt
Normal file
14
tests/108.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--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.
|
||||
16
tests/109.phpt
Normal file
16
tests/109.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--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.
|
||||
14
tests/110.phpt
Normal file
14
tests/110.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--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.
|
||||
14
tests/111.phpt
Normal file
14
tests/111.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--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.
|
||||
14
tests/112.phpt
Normal file
14
tests/112.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--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.
|
||||
19
tests/113.phpt
Normal file
19
tests/113.phpt
Normal file
@@ -0,0 +1,19 @@
|
||||
--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.
|
||||
50
tests/114.phpt
Normal file
50
tests/114.phpt
Normal file
@@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
Bug 76592: solid files are partially extracted
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (PHP_OS != 'Linux') die('skip for linux');
|
||||
if (PHP_VERSION_ID < 50400) die("skip for PHP 5.4+");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$before = hex2bin('526172211a07010030f8db480d01050900080101c5808085800093f4589f2e02030b80808085800004808080858000b483020000000080380108746573742e6461740a031389bf735fa302a31c');
|
||||
$after = hex2bin('a6e7161b0e0306be0000be000080000102514fe6dcc40b3900b38080053393f4589f2e02030b80808085800004808080858000b483020000000080380108746573742e6461740a031389bf735fa302a31c1d77565103050400');
|
||||
|
||||
$middle = file_get_contents('/dev/urandom', false, null, 0, 10 * 1024 * 1024) or die('failed file_get_contents');
|
||||
$crc32hexbe = crc32($middle);
|
||||
$crc32le = pack('V', $crc32hexbe);
|
||||
|
||||
$before = substr($before, 0, 50) . $crc32le . substr($before, 54);
|
||||
$after = substr($after, 0, 56) . $crc32le . substr($after, 60);
|
||||
|
||||
$data = $before . $middle . $after;
|
||||
$file = tempnam('/tmp', 'rar');
|
||||
file_put_contents($file, $data) or die('failed file_put contents');
|
||||
|
||||
$rar = \RarArchive::open($file) or die('Unable to open archive');
|
||||
$rar->setAllowBroken(true); // we don't fixup the headers checksum, only the contents. Ignore the error
|
||||
$entry = $rar->getEntry('test.dat') or die('Unable to get entry');
|
||||
|
||||
$contents = stream_get_contents($entry->getStream(), $entry->getUnpackedSize());
|
||||
$crc32_rar = $entry->getCrc();
|
||||
$crc32_cont = dechex(crc32($contents));
|
||||
$crc32_orig_content = dechex(crc32($contents));
|
||||
|
||||
unlink($file);
|
||||
|
||||
echo 'orig content size: ', strlen($middle), "\n";
|
||||
echo 'read content size: ', strlen($contents), "\n";
|
||||
|
||||
if ($crc32_rar !== $crc32_cont) {
|
||||
die("CRC values do not match");
|
||||
}
|
||||
if ($crc32_rar !== $crc32_orig_content) {
|
||||
die("CRC values do not match (2)");
|
||||
}
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
orig content size: 10485760
|
||||
read content size: 10485760
|
||||
==DONE==
|
||||
25
tests/115.phpt
Normal file
25
tests/115.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
getIterator() (PHP 8+)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("rar")) die("skip");
|
||||
if (PHP_VERSION_ID < 80000) print "skip for PHP 8";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = rar_open(dirname(__FILE__).'/linux_rar.rar');
|
||||
$it = $a->getIterator();
|
||||
var_dump($it);
|
||||
foreach ($it as $e) {
|
||||
echo $e->getName(), "\n";
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
object(InternalIterator)#3 (0) {
|
||||
}
|
||||
plain.txt
|
||||
test file with whitespaces.txt
|
||||
Done
|
||||
17
tests/php8compat.php.inc
Normal file
17
tests/php8compat.php.inc
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
ini_set('pcre.jit', '0'); // avoid some valgrind errors
|
||||
|
||||
function argerr($cl) {
|
||||
try {
|
||||
return $cl();
|
||||
} catch (TypeError $err) {
|
||||
$msg = $err->getMessage();
|
||||
$msg = "Warning: $msg in {$err->getFile()} on line {$err->getLine()}";
|
||||
$msg = preg_replace('/: Argument #(\d) \(\$\S+\) must be of type/',
|
||||
' expects parameter \1 to be', $msg);
|
||||
$msg = preg_replace('/expects (.+) (\d) argument/',
|
||||
'expects \1 \2 parameter', $msg);
|
||||
echo "\n", $msg, "\n";
|
||||
}
|
||||
}
|
||||
BIN
tests/rar5-links.rar
Normal file
BIN
tests/rar5-links.rar
Normal file
Binary file not shown.
BIN
tests/rar5_multi.part1.rar
Normal file
BIN
tests/rar5_multi.part1.rar
Normal file
Binary file not shown.
BIN
tests/rar5_multi.part2.rar
Normal file
BIN
tests/rar5_multi.part2.rar
Normal file
Binary file not shown.
@@ -4,12 +4,13 @@
|
||||
|
||||
1. General
|
||||
|
||||
This package includes freeware Unrar C++ source and a few makefiles
|
||||
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
|
||||
is subset of RAR and generated from RAR source automatically,
|
||||
This package includes freeware Unrar C++ source and makefile for
|
||||
several Unix compilers.
|
||||
|
||||
Unrar source is subset of RAR and generated from RAR source automatically,
|
||||
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
|
||||
Such method is not perfect and you may find some RAR related
|
||||
stuff unnecessary in Unrar, especially in header files.
|
||||
Such method is not perfect and you may find some RAR related stuff
|
||||
unnecessary in Unrar, especially in header files.
|
||||
|
||||
If you wish to port Unrar to a new platform, you may need to edit
|
||||
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
|
||||
@@ -17,16 +18,7 @@
|
||||
|
||||
if computer architecture does not allow not aligned data access,
|
||||
you need to undefine ALLOW_NOT_ALIGNED_INT and define
|
||||
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
|
||||
requirements.
|
||||
|
||||
If you use Borland C++ makefile (makefile.bcc), you need to define
|
||||
BASEPATHCC environment (or makefile) variable containing
|
||||
the path to Borland C++ installation.
|
||||
|
||||
Makefile.unix contains numerous compiler option sets.
|
||||
GCC Linux is selected by default. If you need to compile Unrar
|
||||
for other platforms, uncomment corresponding lines.
|
||||
STRICT_ALIGNMENT_REQUIRED in os.h.
|
||||
|
||||
|
||||
2. Unrar binaries
|
||||
@@ -38,16 +30,8 @@
|
||||
|
||||
3. Acknowledgements
|
||||
|
||||
This source includes parts of code written by the following authors:
|
||||
|
||||
Dmitry Shkarin PPMII v.H text compression
|
||||
Dmitry Subbotin Carryless rangecoder
|
||||
Szymon Stefanek AES encryption
|
||||
Brian Gladman AES encryption
|
||||
Steve Reid SHA-1 hash function
|
||||
Marcus Herbert makefile.unix file
|
||||
Tomasz Klim fixes for libunrar.so
|
||||
Robert Riebisch makefile.dj and patches for DJGPP
|
||||
This source includes parts of code written by other authors.
|
||||
Please see acknow.txt file for details.
|
||||
|
||||
|
||||
4. Legal stuff
|
||||
|
||||
279
unrar/UnRAR.vcxproj
Normal file
279
unrar/UnRAR.vcxproj
Normal file
@@ -0,0 +1,279 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{95CC809B-03FC-4EDB-BB20-FD07A698C05F}</ProjectGuid>
|
||||
<RootNamespace>UnRAR</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.24720.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>build\unrar32\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrar32\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>build\unrar64\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrar64\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>build\unrar32\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrar32\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>build\unrar64\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrar64\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>UNRAR;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>UNRAR;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>UNRAR;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>UNRAR;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>false</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="archive.cpp" />
|
||||
<ClCompile Include="arcread.cpp" />
|
||||
<ClCompile Include="blake2s.cpp" />
|
||||
<ClCompile Include="cmddata.cpp" />
|
||||
<ClCompile Include="consio.cpp" />
|
||||
<ClCompile Include="crc.cpp" />
|
||||
<ClCompile Include="crypt.cpp" />
|
||||
<ClCompile Include="encname.cpp" />
|
||||
<ClCompile Include="errhnd.cpp" />
|
||||
<ClCompile Include="extinfo.cpp" />
|
||||
<ClCompile Include="extract.cpp" />
|
||||
<ClCompile Include="filcreat.cpp" />
|
||||
<ClCompile Include="file.cpp" />
|
||||
<ClCompile Include="filefn.cpp" />
|
||||
<ClCompile Include="filestr.cpp" />
|
||||
<ClCompile Include="find.cpp" />
|
||||
<ClCompile Include="getbits.cpp" />
|
||||
<ClCompile Include="global.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash.cpp" />
|
||||
<ClCompile Include="headers.cpp" />
|
||||
<ClCompile Include="isnt.cpp" />
|
||||
<ClCompile Include="list.cpp" />
|
||||
<ClCompile Include="match.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="pathfn.cpp" />
|
||||
<ClCompile Include="qopen.cpp" />
|
||||
<ClCompile Include="rar.cpp" />
|
||||
<ClCompile Include="rarpch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rarvm.cpp" />
|
||||
<ClCompile Include="rawread.cpp" />
|
||||
<ClCompile Include="rdwrfn.cpp" />
|
||||
<ClCompile Include="recvol.cpp" />
|
||||
<ClCompile Include="resource.cpp" />
|
||||
<ClCompile Include="rijndael.cpp" />
|
||||
<ClCompile Include="rs.cpp" />
|
||||
<ClCompile Include="rs16.cpp" />
|
||||
<ClCompile Include="scantree.cpp" />
|
||||
<ClCompile Include="secpassword.cpp" />
|
||||
<ClCompile Include="sha1.cpp" />
|
||||
<ClCompile Include="sha256.cpp" />
|
||||
<ClCompile Include="smallfn.cpp" />
|
||||
<ClCompile Include="strfn.cpp" />
|
||||
<ClCompile Include="strlist.cpp" />
|
||||
<ClCompile Include="system.cpp" />
|
||||
<ClCompile Include="threadpool.cpp" />
|
||||
<ClCompile Include="timefn.cpp" />
|
||||
<ClCompile Include="ui.cpp" />
|
||||
<ClCompile Include="unicode.cpp" />
|
||||
<ClCompile Include="unpack.cpp" />
|
||||
<ClCompile Include="volume.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
420
unrar/UnRARDll.vcxproj
Normal file
420
unrar/UnRARDll.vcxproj
Normal file
@@ -0,0 +1,420 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="release_nocrypt|Win32">
|
||||
<Configuration>release_nocrypt</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="release_nocrypt|x64">
|
||||
<Configuration>release_nocrypt</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>UnRAR</ProjectName>
|
||||
<ProjectGuid>{E815C46C-36C4-499F-BBC2-E772C6B17971}</ProjectGuid>
|
||||
<RootNamespace>UnRAR</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.24720.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>build\unrardll32\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll32\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>build\unrardll64\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll64\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>build\unrardll32\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll32\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>build\unrardll64\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll64\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'">
|
||||
<OutDir>build\unrardll32\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll32\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'">
|
||||
<OutDir>build\unrardll64\$(Configuration)\</OutDir>
|
||||
<IntDir>build\unrardll64\$(Configuration)\obj\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/SAFESEH %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>false</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;RAR_NOCRYPT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/SAFESEH %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll_nocrypt.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>RARDLL;UNRAR;SILENT;RAR_NOCRYPT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>false</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<DisableSpecificWarnings>4007;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)unrar.dll</OutputFile>
|
||||
<ModuleDefinitionFile>dll_nocrypt.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration />
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="archive.cpp" />
|
||||
<ClCompile Include="arcread.cpp" />
|
||||
<ClCompile Include="blake2s.cpp" />
|
||||
<ClCompile Include="cmddata.cpp" />
|
||||
<ClCompile Include="consio.cpp" />
|
||||
<ClCompile Include="crc.cpp" />
|
||||
<ClCompile Include="crypt.cpp" />
|
||||
<ClCompile Include="dll.cpp" />
|
||||
<ClCompile Include="encname.cpp" />
|
||||
<ClCompile Include="errhnd.cpp" />
|
||||
<ClCompile Include="extinfo.cpp" />
|
||||
<ClCompile Include="extract.cpp" />
|
||||
<ClCompile Include="filcreat.cpp" />
|
||||
<ClCompile Include="file.cpp" />
|
||||
<ClCompile Include="filefn.cpp" />
|
||||
<ClCompile Include="filestr.cpp" />
|
||||
<ClCompile Include="find.cpp" />
|
||||
<ClCompile Include="getbits.cpp" />
|
||||
<ClCompile Include="global.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hash.cpp" />
|
||||
<ClCompile Include="headers.cpp" />
|
||||
<ClCompile Include="isnt.cpp" />
|
||||
<ClCompile Include="match.cpp" />
|
||||
<ClCompile Include="options.cpp" />
|
||||
<ClCompile Include="pathfn.cpp" />
|
||||
<ClCompile Include="qopen.cpp" />
|
||||
<ClCompile Include="rar.cpp" />
|
||||
<ClCompile Include="rarpch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release_nocrypt|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rarvm.cpp" />
|
||||
<ClCompile Include="rawread.cpp" />
|
||||
<ClCompile Include="rdwrfn.cpp" />
|
||||
<ClCompile Include="rijndael.cpp" />
|
||||
<ClCompile Include="rs.cpp" />
|
||||
<ClCompile Include="rs16.cpp" />
|
||||
<ClCompile Include="scantree.cpp" />
|
||||
<ClCompile Include="secpassword.cpp" />
|
||||
<ClCompile Include="sha1.cpp" />
|
||||
<ClCompile Include="sha256.cpp" />
|
||||
<ClCompile Include="smallfn.cpp" />
|
||||
<ClCompile Include="strfn.cpp" />
|
||||
<ClCompile Include="strlist.cpp" />
|
||||
<ClCompile Include="system.cpp" />
|
||||
<ClCompile Include="threadpool.cpp" />
|
||||
<ClCompile Include="timefn.cpp" />
|
||||
<ClCompile Include="ui.cpp" />
|
||||
<ClCompile Include="unicode.cpp" />
|
||||
<ClCompile Include="unpack.cpp" />
|
||||
<ClCompile Include="volume.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="rar.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="dll.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,5 +1,12 @@
|
||||
ACKNOWLEDGMENTS
|
||||
|
||||
* We used "Screaming Fast Galois Field Arithmetic Using Intel
|
||||
SIMD Instructions" paper by James S. Plank, Kevin M. Greenan
|
||||
and Ethan L. Miller to improve Reed-Solomon coding performance.
|
||||
Also we are grateful to Artem Drobanov and Bulat Ziganshin
|
||||
for samples and ideas allowed to make Reed-Solomon coding
|
||||
more efficient.
|
||||
|
||||
* RAR text compression algorithm is based on Dmitry Shkarin PPMII
|
||||
and Dmitry Subbotin carryless rangecoder public domain source code.
|
||||
You may find it in ftp.elf.stuba.sk/pub/pc/pack.
|
||||
@@ -77,5 +84,9 @@
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
* RAR archives may optionally include BLAKE2sp hash ( https://blake2.net ),
|
||||
designed by Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn
|
||||
and Christian Winnerlein.
|
||||
|
||||
* Useful hints provided by Alexander Khoroshev and Bulat Ziganshin allowed
|
||||
to significantly improve RAR compression and speed.
|
||||
|
||||
252
unrar/arccmt.cpp
252
unrar/arccmt.cpp
@@ -1,64 +1,74 @@
|
||||
bool IsAnsiComment(const char *Data,int Size);
|
||||
static bool IsAnsiEscComment(const wchar *Data,size_t Size);
|
||||
|
||||
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||
bool Archive::GetComment(Array<wchar> *CmtData)
|
||||
{
|
||||
if (!MainComment)
|
||||
return(false);
|
||||
SaveFilePos SavePos(*this);
|
||||
return false;
|
||||
int64 SavePos=Tell();
|
||||
bool Success=DoGetComment(CmtData);
|
||||
Seek(SavePos,SEEK_SET);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
bool Archive::DoGetComment(Array<wchar> *CmtData)
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
ushort CmtLength;
|
||||
if (OldFormat)
|
||||
uint CmtLength;
|
||||
if (Format==RARFMT14)
|
||||
{
|
||||
Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
|
||||
Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
|
||||
CmtLength=GetByte();
|
||||
CmtLength+=(GetByte()<<8);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if ((NewMhd.Flags & MHD_COMMENT)!=0)
|
||||
if (MainHead.CommentInHeader)
|
||||
{
|
||||
// Old style (RAR 2.9) archive comment embedded into the main
|
||||
// archive header.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
|
||||
ReadHeader();
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
|
||||
if (!ReadHeader() || GetHeaderType()!=HEAD3_CMT)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current (RAR 3.0+) version of archive comment.
|
||||
Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
|
||||
return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
|
||||
Seek(GetStartPos(),SEEK_SET);
|
||||
return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
|
||||
}
|
||||
#ifndef SFX_MODULE
|
||||
// Old style (RAR 2.9) comment header embedded into the main
|
||||
// archive header.
|
||||
if (CommHead.HeadCRC!=HeaderCRC)
|
||||
if (BrokenHeader || CommHead.HeadSize<SIZEOF_COMMHEAD)
|
||||
{
|
||||
Log(FileName,St(MLogCommHead));
|
||||
Alarm();
|
||||
return(false);
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
}
|
||||
CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
|
||||
#endif
|
||||
}
|
||||
#ifndef SFX_MODULE
|
||||
if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT)!=0 || !OldFormat && CommHead.Method!=0x30)
|
||||
if (Format==RARFMT14 && MainHead.PackComment || Format!=RARFMT14 && CommHead.Method!=0x30)
|
||||
{
|
||||
if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
|
||||
return(false);
|
||||
if (Format!=RARFMT14 && (CommHead.UnpVer < 15 || CommHead.UnpVer > VER_UNPACK || CommHead.Method > 0x35))
|
||||
return false;
|
||||
ComprDataIO DataIO;
|
||||
DataIO.SetTestMode(true);
|
||||
uint UnpCmtLength;
|
||||
if (OldFormat)
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -66,168 +76,110 @@ bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||
DataIO.SetFiles(this,NULL);
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetPackedSizeToRead(CmtLength);
|
||||
DataIO.UnpHash.Init(HASH_CRC32,1);
|
||||
DataIO.SetNoFileHeader(true); // this->FileHead is not filled yet.
|
||||
|
||||
Unpack Unpack(&DataIO);
|
||||
Unpack.Init();
|
||||
Unpack.SetDestSize(UnpCmtLength);
|
||||
Unpack.DoUnpack(CommHead.UnpVer,false);
|
||||
Unpack CmtUnpack(&DataIO);
|
||||
CmtUnpack.Init(0x10000,false);
|
||||
CmtUnpack.SetDestSize(UnpCmtLength);
|
||||
CmtUnpack.DoUnpack(CommHead.UnpVer,false);
|
||||
|
||||
if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
|
||||
if (Format!=RARFMT14 && (DataIO.UnpHash.GetCRC32()&0xffff)!=CommHead.CommCRC)
|
||||
{
|
||||
Log(FileName,St(MLogCommBrk));
|
||||
Alarm();
|
||||
return(false);
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte *UnpData;
|
||||
size_t UnpDataSize;
|
||||
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
|
||||
CmtData->Alloc(UnpDataSize);
|
||||
memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
|
||||
if (UnpDataSize>0)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// If we ever decide to extend it to Android, we'll need to alloc
|
||||
// 4x memory for OEM to UTF-8 output here.
|
||||
OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
|
||||
#endif
|
||||
CmtData->Alloc(UnpDataSize+1);
|
||||
memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
|
||||
CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CmtData->Alloc(CmtLength);
|
||||
|
||||
Read(&((*CmtData)[0]),CmtLength);
|
||||
if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
|
||||
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.
|
||||
{
|
||||
Log(FileName,St(MLogCommBrk));
|
||||
Alarm();
|
||||
CmtData->Reset();
|
||||
return(false);
|
||||
CmtLength=ReadSize;
|
||||
CmtRaw.Alloc(CmtLength);
|
||||
}
|
||||
|
||||
if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
|
||||
{
|
||||
uiMsg(UIERROR_CMTBROKEN,FileName);
|
||||
return false;
|
||||
}
|
||||
CmtData->Alloc(CmtLength+1);
|
||||
CmtRaw.Push(0);
|
||||
#ifdef _WIN_ALL
|
||||
// If we ever decide to extend it to Android, we'll need to alloc
|
||||
// 4x memory for OEM to UTF-8 output here.
|
||||
OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
|
||||
#endif
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0)));
|
||||
}
|
||||
#endif
|
||||
#if defined(_WIN_ALL) && !defined(_WIN_CE)
|
||||
if (CmtData->Size()>0)
|
||||
{
|
||||
size_t CmtSize=CmtData->Size();
|
||||
char *DataA=(char *)CmtData->Addr();
|
||||
OemToCharBuffA(DataA,DataA,(DWORD)CmtSize);
|
||||
|
||||
if (CmtDataW!=NULL)
|
||||
{
|
||||
CmtDataW->Alloc(CmtSize+1);
|
||||
|
||||
// It can cause reallocation, so we should not use 'DataA' variable
|
||||
// with previosuly saved CmtData->Addr() after Push() call.
|
||||
CmtData->Push(0);
|
||||
|
||||
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||
CmtData->Alloc(CmtSize);
|
||||
CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return(CmtData->Size()>0);
|
||||
return CmtData->Size() > 0;
|
||||
}
|
||||
|
||||
|
||||
size_t Archive::ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||
bool Archive::ReadCommentData(Array<wchar> *CmtData)
|
||||
{
|
||||
bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE;
|
||||
if (!ReadSubData(CmtData,NULL))
|
||||
return(0);
|
||||
size_t CmtSize=CmtData->Size();
|
||||
if (Unicode)
|
||||
{
|
||||
CmtSize/=2;
|
||||
Array<wchar> DataW(CmtSize+1);
|
||||
RawToWide(CmtData->Addr(),DataW.Addr(),CmtSize);
|
||||
DataW[CmtSize]=0;
|
||||
size_t DestSize=CmtSize*4;
|
||||
CmtData->Alloc(DestSize+1);
|
||||
WideToChar(DataW.Addr(),(char *)CmtData->Addr(),DestSize);
|
||||
(*CmtData)[DestSize]=0;
|
||||
CmtSize=strlen((char *)CmtData->Addr());
|
||||
CmtData->Alloc(CmtSize);
|
||||
if (CmtDataW!=NULL)
|
||||
{
|
||||
*CmtDataW=DataW;
|
||||
CmtDataW->Alloc(CmtSize);
|
||||
}
|
||||
}
|
||||
Array<byte> CmtRaw;
|
||||
if (!ReadSubData(&CmtRaw,NULL,false))
|
||||
return false;
|
||||
size_t CmtSize=CmtRaw.Size();
|
||||
CmtRaw.Push(0);
|
||||
CmtData->Alloc(CmtSize+1);
|
||||
if (Format==RARFMT50)
|
||||
UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
else
|
||||
if (CmtDataW!=NULL)
|
||||
if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0)
|
||||
{
|
||||
CmtData->Push(0);
|
||||
CmtDataW->Alloc(CmtSize+1);
|
||||
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||
CmtData->Alloc(CmtSize);
|
||||
CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
|
||||
RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2);
|
||||
(*CmtData)[CmtSize/2]=0;
|
||||
|
||||
}
|
||||
return(CmtSize);
|
||||
else
|
||||
{
|
||||
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
|
||||
}
|
||||
CmtData->Alloc(wcslen(CmtData->Addr(0))); // Set buffer size to actual comment length.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Archive::ViewComment()
|
||||
{
|
||||
#ifndef GUI
|
||||
if (Cmd->DisableComment)
|
||||
return;
|
||||
Array<byte> CmtBuf;
|
||||
if (GetComment(&CmtBuf,NULL))
|
||||
Array<wchar> CmtBuf;
|
||||
if (GetComment(&CmtBuf)) // In GUI too, so "Test" command detects broken comments.
|
||||
{
|
||||
size_t CmtSize=CmtBuf.Size();
|
||||
char *ChPtr=(char *)memchr(&CmtBuf[0],0x1A,CmtSize);
|
||||
wchar *ChPtr=wcschr(&CmtBuf[0],0x1A);
|
||||
if (ChPtr!=NULL)
|
||||
CmtSize=ChPtr-(char *)&CmtBuf[0];
|
||||
mprintf("\n");
|
||||
OutComment((char *)&CmtBuf[0],CmtSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// Used for archives created by old RAR versions up to and including RAR 2.9.
|
||||
// New RAR versions store file comments in separate headers and such comments
|
||||
// are displayed in ListNewSubHeader function.
|
||||
void Archive::ViewFileComment()
|
||||
{
|
||||
if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat)
|
||||
return;
|
||||
#ifndef GUI
|
||||
mprintf(St(MFileComment));
|
||||
#endif
|
||||
const int MaxSize=0x8000;
|
||||
Array<char> CmtBuf(MaxSize);
|
||||
SaveFilePos SavePos(*this);
|
||||
Seek(CurBlockPos+SIZEOF_NEWLHD+NewLhd.NameSize,SEEK_SET);
|
||||
int64 SaveCurBlockPos=CurBlockPos;
|
||||
int64 SaveNextBlockPos=NextBlockPos;
|
||||
|
||||
size_t Size=ReadHeader();
|
||||
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
|
||||
if (Size<7 || CommHead.HeadType!=COMM_HEAD)
|
||||
return;
|
||||
if (CommHead.HeadCRC!=HeaderCRC)
|
||||
{
|
||||
#ifndef GUI
|
||||
Log(FileName,St(MLogCommHead));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER ||
|
||||
CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize)
|
||||
return;
|
||||
Read(&CmtBuf[0],CommHead.UnpSize);
|
||||
if (CommHead.CommCRC!=((~CRC(0xffffffff,&CmtBuf[0],CommHead.UnpSize)&0xffff)))
|
||||
{
|
||||
Log(FileName,St(MLogBrokFCmt));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutComment(&CmtBuf[0],CommHead.UnpSize);
|
||||
#ifndef GUI
|
||||
mprintf("\n");
|
||||
#endif
|
||||
CmtSize=ChPtr-&CmtBuf[0];
|
||||
mprintf(L"\n");
|
||||
OutComment(&CmtBuf[0],CmtSize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,110 +1,123 @@
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifndef SHELL_EXT
|
||||
#include "arccmt.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
Archive::Archive(RAROptions *InitCmd)
|
||||
{
|
||||
Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
|
||||
Cmd=NULL; // Just in case we'll have an exception in 'new' below.
|
||||
|
||||
DummyCmd=(InitCmd==NULL);
|
||||
Cmd=DummyCmd ? (new RAROptions):InitCmd;
|
||||
|
||||
OpenShared=Cmd->OpenShared;
|
||||
OldFormat=false;
|
||||
Format=RARFMT15;
|
||||
Solid=false;
|
||||
Volume=false;
|
||||
MainComment=false;
|
||||
Locked=false;
|
||||
Signed=false;
|
||||
NotFirstVolume=false;
|
||||
FirstVolume=false;
|
||||
NewNumbering=false;
|
||||
SFXSize=0;
|
||||
LatestTime.Reset();
|
||||
Protected=false;
|
||||
Encrypted=false;
|
||||
FailedHeaderDecryption=false;
|
||||
BrokenFileHeader=false;
|
||||
BrokenHeader=false;
|
||||
LastReadBlock=0;
|
||||
|
||||
CurBlockPos=0;
|
||||
NextBlockPos=0;
|
||||
|
||||
RecoveryPos=SIZEOF_MARKHEAD;
|
||||
RecoverySectors=-1;
|
||||
|
||||
memset(&NewMhd,0,sizeof(NewMhd));
|
||||
NewMhd.HeadType=MAIN_HEAD;
|
||||
NewMhd.HeadSize=SIZEOF_NEWMHD;
|
||||
HeaderCRC=0;
|
||||
memset(&MainHead,0,sizeof(MainHead));
|
||||
memset(&CryptHead,0,sizeof(CryptHead));
|
||||
memset(&EndArcHead,0,sizeof(EndArcHead));
|
||||
|
||||
VolNumber=0;
|
||||
VolWrite=0;
|
||||
AddingFilesSize=0;
|
||||
AddingHeadersSize=0;
|
||||
#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
|
||||
*HeadersSalt=0;
|
||||
*SubDataSalt=0;
|
||||
#endif
|
||||
*FirstVolumeName=0;
|
||||
*FirstVolumeNameW=0;
|
||||
|
||||
Splitting=false;
|
||||
NewArchive=false;
|
||||
|
||||
SilentOpen=false;
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
ProhibitQOpen=false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
Archive::~Archive()
|
||||
{
|
||||
if (DummyCmd)
|
||||
delete Cmd;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SHELL_EXT
|
||||
void Archive::CheckArc(bool EnableBroken)
|
||||
{
|
||||
if (!IsArchive(EnableBroken))
|
||||
{
|
||||
Log(FileName,St(MBadArc),FileName);
|
||||
// If FailedHeaderDecryption is set, we already reported that archive
|
||||
// password is incorrect.
|
||||
if (!FailedHeaderDecryption)
|
||||
uiMsg(UIERROR_BADARCHIVE,FileName);
|
||||
ErrHandler.Exit(RARX_FATAL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
void Archive::CheckOpen(const char *Name,const wchar *NameW)
|
||||
#if !defined(SFX_MODULE)
|
||||
void Archive::CheckOpen(const wchar *Name)
|
||||
{
|
||||
TOpen(Name,NameW);
|
||||
TOpen(Name);
|
||||
CheckArc(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool Archive::WCheckOpen(const char *Name,const wchar *NameW)
|
||||
bool Archive::WCheckOpen(const wchar *Name)
|
||||
{
|
||||
if (!WOpen(Name,NameW))
|
||||
return(false);
|
||||
if (!WOpen(Name))
|
||||
return false;
|
||||
if (!IsArchive(false))
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MNotRAR),FileName);
|
||||
#endif
|
||||
uiMsg(UIERROR_BADARCHIVE,FileName);
|
||||
Close();
|
||||
return(false);
|
||||
return false;
|
||||
}
|
||||
return(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ARCSIGN_TYPE Archive::IsSignature(const byte *D,size_t Size)
|
||||
RARFORMAT Archive::IsSignature(const byte *D,size_t Size)
|
||||
{
|
||||
ARCSIGN_TYPE Type=ARCSIGN_NONE;
|
||||
RARFORMAT Type=RARFMT_NONE;
|
||||
if (Size>=1 && D[0]==0x52)
|
||||
#ifndef SFX_MODULE
|
||||
if (Size>=4 && D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
|
||||
Type=ARCSIGN_OLD;
|
||||
Type=RARFMT14;
|
||||
else
|
||||
#endif
|
||||
if (Size>=7 && D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07)
|
||||
{
|
||||
// We check for non-zero last signature byte, so we can return
|
||||
// a sensible warning in case we'll want to change the archive
|
||||
// format sometimes in the future.
|
||||
Type=D[6]==0 ? ARCSIGN_CURRENT:ARCSIGN_FUTURE;
|
||||
// We check the last signature byte, so we can return a sensible
|
||||
// warning in case we'll want to change the archive format
|
||||
// sometimes in the future.
|
||||
if (D[6]==0)
|
||||
Type=RARFMT15;
|
||||
else
|
||||
if (D[6]==1)
|
||||
Type=RARFMT50;
|
||||
else
|
||||
if (D[6]>1 && D[6]<5)
|
||||
Type=RARFMT_FUTURE;
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
@@ -113,25 +126,25 @@ ARCSIGN_TYPE Archive::IsSignature(const byte *D,size_t Size)
|
||||
bool Archive::IsArchive(bool EnableBroken)
|
||||
{
|
||||
Encrypted=false;
|
||||
BrokenHeader=false; // Might be left from previous volume.
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
if (IsDevice())
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MInvalidName),FileName);
|
||||
#endif
|
||||
return(false);
|
||||
uiMsg(UIERROR_INVALIDNAME,FileName,FileName);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
|
||||
return(false);
|
||||
if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
|
||||
return false;
|
||||
SFXSize=0;
|
||||
|
||||
ARCSIGN_TYPE Type;
|
||||
if ((Type=IsSignature(MarkHead.Mark,sizeof(MarkHead.Mark)))!=ARCSIGN_NONE)
|
||||
RARFORMAT Type;
|
||||
if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE)
|
||||
{
|
||||
OldFormat=(Type==ARCSIGN_OLD);
|
||||
if (OldFormat)
|
||||
Seek(0,SEEK_SET);
|
||||
Format=Type;
|
||||
if (Format==RARFMT14)
|
||||
Seek(Tell()-SIZEOF_MARKHEAD3,SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -139,10 +152,10 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
long CurPos=(long)Tell();
|
||||
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
|
||||
for (int I=0;I<ReadSize;I++)
|
||||
if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=ARCSIGN_NONE)
|
||||
if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
|
||||
{
|
||||
OldFormat=(Type==ARCSIGN_OLD);
|
||||
if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
|
||||
Format=Type;
|
||||
if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31)
|
||||
{
|
||||
char *D=&Buffer[28-CurPos];
|
||||
if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
|
||||
@@ -150,62 +163,27 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
}
|
||||
SFXSize=CurPos+I;
|
||||
Seek(SFXSize,SEEK_SET);
|
||||
if (!OldFormat)
|
||||
Read(MarkHead.Mark,SIZEOF_MARKHEAD);
|
||||
if (Format==RARFMT15 || Format==RARFMT50)
|
||||
Read(MarkHead.Mark,SIZEOF_MARKHEAD3);
|
||||
break;
|
||||
}
|
||||
if (SFXSize==0)
|
||||
return false;
|
||||
}
|
||||
if (Type==ARCSIGN_FUTURE)
|
||||
if (Format==RARFMT_FUTURE)
|
||||
{
|
||||
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||
Log(FileName,St(MNewRarFormat));
|
||||
#endif
|
||||
uiMsg(UIERROR_NEWRARFORMAT,FileName);
|
||||
return false;
|
||||
}
|
||||
ReadHeader();
|
||||
SeekToNext();
|
||||
#ifndef SFX_MODULE
|
||||
if (OldFormat)
|
||||
if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
|
||||
{
|
||||
NewMhd.Flags=OldMhd.Flags & 0x3f;
|
||||
NewMhd.HeadSize=OldMhd.HeadSize;
|
||||
if (Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1)!=1 || MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
|
||||
return false;
|
||||
MarkHead.HeadSize=SIZEOF_MARKHEAD5;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (HeaderCRC!=NewMhd.HeadCRC)
|
||||
{
|
||||
#ifndef SHELL_EXT
|
||||
Log(FileName,St(MLogMainHead));
|
||||
#endif
|
||||
Alarm();
|
||||
if (!EnableBroken)
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
Volume=(NewMhd.Flags & MHD_VOLUME);
|
||||
Solid=(NewMhd.Flags & MHD_SOLID)!=0;
|
||||
MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
|
||||
Locked=(NewMhd.Flags & MHD_LOCK)!=0;
|
||||
Signed=(NewMhd.PosAV!=0);
|
||||
Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
|
||||
Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
|
||||
MarkHead.HeadSize=SIZEOF_MARKHEAD3;
|
||||
|
||||
if (NewMhd.EncryptVer>UNP_VER)
|
||||
{
|
||||
#ifdef RARDLL
|
||||
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
|
||||
#else
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
Log(FileName,St(MUnknownMeth),FileName);
|
||||
Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
|
||||
#endif
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
#ifdef RARDLL
|
||||
// If callback function is not set, we cannot get the password,
|
||||
// so we skip the initial header processing for encrypted header archive.
|
||||
@@ -215,45 +193,81 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
SilentOpen=true;
|
||||
#endif
|
||||
|
||||
// If not encrypted, we'll check it below.
|
||||
NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
|
||||
|
||||
if (!SilentOpen || !Encrypted)
|
||||
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.
|
||||
{
|
||||
SaveFilePos SavePos(*this);
|
||||
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||
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)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
{
|
||||
if (!FailedHeaderDecryption) // If not reported a wrong password already.
|
||||
uiMsg(UIERROR_MHEADERBROKEN,FileName);
|
||||
if (!EnableBroken)
|
||||
return false;
|
||||
}
|
||||
|
||||
MainComment=MainHead.CommentInHeader;
|
||||
|
||||
// If we process non-encrypted archive or can request a password,
|
||||
// we set 'first volume' flag based on file attributes below.
|
||||
// It is necessary for RAR 2.x archives, which did not have 'first volume'
|
||||
// flag in main header. Also for all RAR formats we need to scan until
|
||||
// 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))
|
||||
{
|
||||
int64 SavePos=Tell();
|
||||
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||
HEADER_TYPE SaveCurHeaderType=CurHeaderType;
|
||||
|
||||
NotFirstVolume=false;
|
||||
while (ReadHeader()!=0)
|
||||
{
|
||||
int HeaderType=GetHeaderType();
|
||||
if (HeaderType==NEWSUB_HEAD)
|
||||
HEADER_TYPE HeaderType=GetHeaderType();
|
||||
if (HeaderType==HEAD_SERVICE)
|
||||
{
|
||||
if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
|
||||
MainComment=true;
|
||||
if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
|
||||
Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
|
||||
NotFirstVolume=true;
|
||||
// If we have a split service headers, it surely indicates non-first
|
||||
// volume. But not split service header does not guarantee the first
|
||||
// volume, because we can have split file after non-split archive
|
||||
// comment. So we do not quit from loop here.
|
||||
FirstVolume=Volume && !SubHead.SplitBefore;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
|
||||
Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
|
||||
NotFirstVolume=true;
|
||||
break;
|
||||
}
|
||||
if (HeaderType==HEAD_FILE)
|
||||
{
|
||||
FirstVolume=Volume && !FileHead.SplitBefore;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (HeaderType==HEAD_ENDARC) // Might happen if archive contains only a split service header.
|
||||
break;
|
||||
SeekToNext();
|
||||
}
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
CurHeaderType=SaveCurHeaderType;
|
||||
Seek(SavePos,SEEK_SET);
|
||||
}
|
||||
if (!Volume || !NotFirstVolume)
|
||||
{
|
||||
strcpy(FirstVolumeName,FileName);
|
||||
wcscpy(FirstVolumeNameW,FileNameW);
|
||||
}
|
||||
if (!Volume || FirstVolume)
|
||||
wcsncpyz(FirstVolumeName,FileName,ASIZE(FirstVolumeName));
|
||||
|
||||
return(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -265,20 +279,60 @@ void Archive::SeekToNext()
|
||||
}
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
int Archive::GetRecoverySize(bool Required)
|
||||
|
||||
|
||||
|
||||
|
||||
// Calculate the block size including encryption fields and padding if any.
|
||||
uint Archive::FullHeaderSize(size_t Size)
|
||||
{
|
||||
if (!Protected)
|
||||
return(0);
|
||||
if (RecoverySectors!=-1 || !Required)
|
||||
return(RecoverySectors);
|
||||
SaveFilePos SavePos(*this);
|
||||
Seek(SFXSize,SEEK_SET);
|
||||
SearchSubBlock(SUBHEAD_TYPE_RR);
|
||||
return(RecoverySectors);
|
||||
if (Encrypted)
|
||||
{
|
||||
Size = ALIGN_VALUE(Size, CRYPT_BLOCK_SIZE); // Align to encryption block size.
|
||||
if (Format == RARFMT50)
|
||||
Size += SIZE_INITV;
|
||||
else
|
||||
Size += SIZE_SALT30;
|
||||
}
|
||||
return uint(Size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef USE_QOPEN
|
||||
bool Archive::Open(const wchar *Name,uint Mode)
|
||||
{
|
||||
// Important if we reuse Archive object and it has virtual QOpen
|
||||
// file position not matching real. For example, for 'l -v volname'.
|
||||
QOpen.Unload();
|
||||
|
||||
return File::Open(Name,Mode);
|
||||
}
|
||||
|
||||
|
||||
int Archive::Read(void *Data,size_t Size)
|
||||
{
|
||||
size_t Result;
|
||||
if (QOpen.Read(Data,Size,Result))
|
||||
return (int)Result;
|
||||
return File::Read(Data,Size);
|
||||
}
|
||||
|
||||
|
||||
void Archive::Seek(int64 Offset,int Method)
|
||||
{
|
||||
if (!QOpen.Seek(Offset,Method))
|
||||
File::Seek(Offset,Method);
|
||||
}
|
||||
|
||||
|
||||
int64 Archive::Tell()
|
||||
{
|
||||
int64 QPos;
|
||||
if (QOpen.Tell(&QPos))
|
||||
return QPos;
|
||||
return File::Tell();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,120 +1,147 @@
|
||||
#ifndef _RAR_ARCHIVE_
|
||||
#define _RAR_ARCHIVE_
|
||||
|
||||
class Pack;
|
||||
class PPack;
|
||||
class RawRead;
|
||||
class RawWrite;
|
||||
|
||||
enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4};
|
||||
enum NOMODIFY_FLAGS
|
||||
{
|
||||
NMDF_ALLOWLOCK=1,NMDF_ALLOWANYVOLUME=2,NMDF_ALLOWFIRSTVOLUME=4
|
||||
};
|
||||
|
||||
enum ARCSIGN_TYPE {ARCSIGN_NONE,ARCSIGN_OLD,ARCSIGN_CURRENT,ARCSIGN_FUTURE};
|
||||
enum RARFORMAT {RARFMT_NONE,RARFMT14,RARFMT15,RARFMT50,RARFMT_FUTURE};
|
||||
|
||||
enum ADDSUBDATA_FLAGS
|
||||
{
|
||||
ASDF_SPLIT = 1, // Allow to split archive just before header if necessary.
|
||||
ASDF_COMPRESS = 2, // Allow to compress data following subheader.
|
||||
ASDF_CRYPT = 4, // Encrypt data after subheader if password is set.
|
||||
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:
|
||||
ARCSIGN_TYPE IsSignature(const byte *D,size_t Size);
|
||||
void UpdateLatestTime(FileHeader *CurBlock);
|
||||
void ConvertNameCase(char *Name);
|
||||
void ConvertNameCase(wchar *Name);
|
||||
void ConvertUnknownHeader();
|
||||
size_t ReadOldHeader();
|
||||
void ConvertFileHeader(FileHeader *hd);
|
||||
size_t ReadHeader14();
|
||||
size_t ReadHeader15();
|
||||
size_t ReadHeader50();
|
||||
void ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb);
|
||||
void RequestArcPassword();
|
||||
void UnexpEndArcMsg();
|
||||
void BrokenHeaderMsg();
|
||||
void UnkEncVerMsg(const wchar *Name,const wchar *Info);
|
||||
bool DoGetComment(Array<wchar> *CmtData);
|
||||
bool ReadCommentData(Array<wchar> *CmtData);
|
||||
|
||||
#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT)
|
||||
#if !defined(RAR_NOCRYPT)
|
||||
CryptData HeadersCrypt;
|
||||
byte HeadersSalt[SALT_SIZE];
|
||||
#endif
|
||||
#ifndef SHELL_EXT
|
||||
ComprDataIO SubDataIO;
|
||||
byte SubDataSalt[SALT_SIZE];
|
||||
#endif
|
||||
RAROptions *Cmd,DummyCmd;
|
||||
bool DummyCmd;
|
||||
RAROptions *Cmd;
|
||||
|
||||
MarkHeader MarkHead;
|
||||
OldMainHeader OldMhd;
|
||||
|
||||
int RecoverySectors;
|
||||
int64 RecoveryPos;
|
||||
|
||||
bool FailedHeaderDecryption;
|
||||
|
||||
RarTime LatestTime;
|
||||
int LastReadBlock;
|
||||
int CurHeaderType;
|
||||
HEADER_TYPE CurHeaderType;
|
||||
|
||||
bool SilentOpen;
|
||||
#ifdef USE_QOPEN
|
||||
QuickOpen QOpen;
|
||||
bool ProhibitQOpen;
|
||||
#endif
|
||||
public:
|
||||
Archive(RAROptions *InitCmd=NULL);
|
||||
~Archive();
|
||||
static RARFORMAT IsSignature(const byte *D,size_t Size);
|
||||
bool IsArchive(bool EnableBroken);
|
||||
size_t SearchBlock(int BlockType);
|
||||
size_t SearchSubBlock(const char *Type);
|
||||
int ReadBlock(int BlockType);
|
||||
void WriteBlock(int BlockType,BaseBlock *wb=NULL);
|
||||
int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW);
|
||||
void SetLhdSize();
|
||||
size_t SearchBlock(HEADER_TYPE HeaderType);
|
||||
size_t SearchSubBlock(const wchar *Type);
|
||||
size_t SearchRR();
|
||||
size_t ReadHeader();
|
||||
void CheckArc(bool EnableBroken);
|
||||
void CheckOpen(const char *Name,const wchar *NameW=NULL);
|
||||
bool WCheckOpen(const char *Name,const wchar *NameW=NULL);
|
||||
bool GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||
void CheckOpen(const wchar *Name);
|
||||
bool WCheckOpen(const wchar *Name);
|
||||
bool GetComment(Array<wchar> *CmtData);
|
||||
void ViewComment();
|
||||
void ViewFileComment();
|
||||
void SetLatestTime(RarTime *NewTime);
|
||||
void SeekToNext();
|
||||
bool CheckAccess();
|
||||
bool IsArcDir();
|
||||
bool IsArcLabel();
|
||||
void ConvertAttributes();
|
||||
int GetRecoverySize(bool Required);
|
||||
void VolSubtractHeaderSize(size_t SubSize);
|
||||
void AddSubData(byte *SrcData,size_t DataSize,File *SrcFile,const char *Name,bool AllowSplit);
|
||||
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
|
||||
int GetHeaderType() {return(CurHeaderType);};
|
||||
size_t ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||
void WriteCommentData(byte *Data,size_t DataSize,bool FileComment);
|
||||
RAROptions* GetRAROptions() {return(Cmd);}
|
||||
uint FullHeaderSize(size_t Size);
|
||||
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;}
|
||||
RAROptions* GetRAROptions() {return Cmd;}
|
||||
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
|
||||
#if 0
|
||||
void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
|
||||
#endif
|
||||
#ifdef USE_QOPEN
|
||||
bool Open(const wchar *Name,uint Mode=FMF_READ);
|
||||
int Read(void *Data,size_t Size);
|
||||
void Seek(int64 Offset,int Method);
|
||||
int64 Tell();
|
||||
void QOpenUnload() {QOpen.Unload();}
|
||||
void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;}
|
||||
#endif
|
||||
|
||||
BaseBlock ShortBlock;
|
||||
MainHeader NewMhd;
|
||||
FileHeader NewLhd;
|
||||
MarkHeader MarkHead;
|
||||
MainHeader MainHead;
|
||||
CryptHeader CryptHead;
|
||||
FileHeader FileHead;
|
||||
EndArcHeader EndArcHead;
|
||||
SubBlockHeader SubBlockHead;
|
||||
FileHeader SubHead;
|
||||
CommentHeader CommHead;
|
||||
ProtectHeader ProtectHead;
|
||||
AVHeader AVHead;
|
||||
SignHeader SignHead;
|
||||
UnixOwnersHeader UOHead;
|
||||
MacFInfoHeader MACHead;
|
||||
EAHeader EAHead;
|
||||
StreamHeader StreamHead;
|
||||
|
||||
int64 CurBlockPos;
|
||||
int64 NextBlockPos;
|
||||
|
||||
bool OldFormat;
|
||||
RARFORMAT Format;
|
||||
bool Solid;
|
||||
bool Volume;
|
||||
bool MainComment;
|
||||
bool Locked;
|
||||
bool Signed;
|
||||
bool NotFirstVolume;
|
||||
bool FirstVolume;
|
||||
bool NewNumbering;
|
||||
bool Protected;
|
||||
bool Encrypted;
|
||||
size_t SFXSize;
|
||||
bool BrokenFileHeader;
|
||||
bool BrokenHeader;
|
||||
bool FailedHeaderDecryption;
|
||||
|
||||
#if !defined(RAR_NOCRYPT)
|
||||
byte ArcSalt[SIZE_SALT50];
|
||||
#endif
|
||||
|
||||
bool Splitting;
|
||||
|
||||
ushort HeaderCRC;
|
||||
|
||||
uint VolNumber;
|
||||
int64 VolWrite;
|
||||
int64 AddingFilesSize;
|
||||
size_t AddingHeadersSize;
|
||||
uint64 AddingFilesSize;
|
||||
uint64 AddingHeadersSize;
|
||||
|
||||
bool NewArchive;
|
||||
|
||||
char FirstVolumeName[NM];
|
||||
wchar FirstVolumeNameW[NM];
|
||||
wchar FirstVolumeName[NM];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
1689
unrar/arcread.cpp
1689
unrar/arcread.cpp
File diff suppressed because it is too large
Load Diff
@@ -9,12 +9,16 @@ template <class T> class Array
|
||||
T *Buffer;
|
||||
size_t BufSize;
|
||||
size_t AllocSize;
|
||||
size_t MaxSize;
|
||||
bool Secure; // Clean memory if true.
|
||||
public:
|
||||
Array();
|
||||
Array(size_t Size);
|
||||
Array(const Array &Src); // Copy constructor.
|
||||
~Array();
|
||||
inline void CleanData();
|
||||
inline T& operator [](size_t Item);
|
||||
inline T& operator [](size_t Item) const;
|
||||
inline T* operator + (size_t Pos);
|
||||
inline size_t Size(); // Returns the size in items, not in bytes.
|
||||
void Add(size_t Items);
|
||||
void Alloc(size_t Items);
|
||||
@@ -22,14 +26,22 @@ template <class T> class Array
|
||||
void SoftReset();
|
||||
void operator = (Array<T> &Src);
|
||||
void Push(T Item);
|
||||
T* Addr() {return(Buffer);}
|
||||
void Append(T *Item,size_t Count);
|
||||
T* Addr(size_t Item) {return Buffer+Item;}
|
||||
void SetMaxSize(size_t Size) {MaxSize=Size;}
|
||||
T* Begin() {return Buffer;}
|
||||
T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
|
||||
void SetSecure() {Secure=true;}
|
||||
};
|
||||
|
||||
|
||||
template <class T> void Array<T>::CleanData()
|
||||
{
|
||||
Buffer=NULL;
|
||||
BufSize=0;
|
||||
AllocSize=0;
|
||||
MaxSize=0;
|
||||
Secure=false;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,30 +53,47 @@ template <class T> Array<T>::Array()
|
||||
|
||||
template <class T> Array<T>::Array(size_t Size)
|
||||
{
|
||||
Buffer=(T *)malloc(sizeof(T)*Size);
|
||||
if (Buffer==NULL && Size!=0)
|
||||
ErrHandler.MemoryError();
|
||||
CleanData();
|
||||
Add(Size);
|
||||
}
|
||||
|
||||
AllocSize=BufSize=Size;
|
||||
|
||||
// Copy constructor in case we need to pass an object as value.
|
||||
template <class T> Array<T>::Array(const Array &Src)
|
||||
{
|
||||
CleanData();
|
||||
Alloc(Src.BufSize);
|
||||
if (Src.BufSize!=0)
|
||||
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
template <class T> Array<T>::~Array()
|
||||
{
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
if (Secure)
|
||||
cleandata(Buffer,AllocSize*sizeof(T));
|
||||
free(Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T& Array<T>::operator [](size_t Item)
|
||||
template <class T> inline T& Array<T>::operator [](size_t Item) const
|
||||
{
|
||||
return(Buffer[Item]);
|
||||
return Buffer[Item];
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline T* Array<T>::operator +(size_t Pos)
|
||||
{
|
||||
return Buffer+Pos;
|
||||
}
|
||||
|
||||
|
||||
template <class T> inline size_t Array<T>::Size()
|
||||
{
|
||||
return(BufSize);
|
||||
return BufSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,12 +102,35 @@ template <class T> void Array<T>::Add(size_t Items)
|
||||
BufSize+=Items;
|
||||
if (BufSize>AllocSize)
|
||||
{
|
||||
if (MaxSize!=0 && BufSize>MaxSize)
|
||||
{
|
||||
ErrHandler.GeneralErrMsg(L"Maximum allowed array size (%u) is exceeded",MaxSize);
|
||||
ErrHandler.MemoryError();
|
||||
}
|
||||
|
||||
size_t Suggested=AllocSize+AllocSize/4+32;
|
||||
size_t NewSize=Max(BufSize,Suggested);
|
||||
|
||||
Buffer=(T *)realloc(Buffer,NewSize*sizeof(T));
|
||||
if (Buffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
T *NewBuffer;
|
||||
if (Secure)
|
||||
{
|
||||
NewBuffer=(T *)malloc(NewSize*sizeof(T));
|
||||
if (NewBuffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
if (Buffer!=NULL)
|
||||
{
|
||||
memcpy(NewBuffer,Buffer,AllocSize*sizeof(T));
|
||||
cleandata(Buffer,AllocSize*sizeof(T));
|
||||
free(Buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
|
||||
if (NewBuffer==NULL)
|
||||
ErrHandler.MemoryError();
|
||||
}
|
||||
Buffer=NewBuffer;
|
||||
AllocSize=NewSize;
|
||||
}
|
||||
}
|
||||
@@ -105,7 +157,7 @@ template <class T> void Array<T>::Reset()
|
||||
}
|
||||
|
||||
|
||||
// Reste buffer size, but preserve already allocated memory if any,
|
||||
// Reset buffer size, but preserve already allocated memory if any,
|
||||
// so we can reuse it without wasting time to allocation.
|
||||
template <class T> void Array<T>::SoftReset()
|
||||
{
|
||||
@@ -128,4 +180,12 @@ template <class T> void Array<T>::Push(T Item)
|
||||
(*this)[Size()-1]=Item;
|
||||
}
|
||||
|
||||
|
||||
template <class T> void Array<T>::Append(T *Items,size_t Count)
|
||||
{
|
||||
size_t CurSize=Size();
|
||||
Add(Count);
|
||||
memcpy(Buffer+CurSize,Items,Count*sizeof(T));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
113
unrar/beosea.cpp
113
unrar/beosea.cpp
@@ -1,113 +0,0 @@
|
||||
|
||||
|
||||
void ExtractBeEA(Archive &Arc,char *FileName)
|
||||
{
|
||||
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
|
||||
{
|
||||
Log(Arc.FileName,St(MEAUnknHeader),FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
ComprDataIO DataIO;
|
||||
Unpack Unpack(&DataIO);
|
||||
Unpack.Init();
|
||||
|
||||
Array<byte> UnpData(Arc.EAHead.UnpSize);
|
||||
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
|
||||
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
|
||||
DataIO.EnableShowProgress(false);
|
||||
DataIO.SetFiles(&Arc,NULL);
|
||||
Unpack.SetDestSize(Arc.EAHead.UnpSize);
|
||||
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
|
||||
|
||||
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
|
||||
{
|
||||
Log(Arc.FileName,St(MEABroken),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_CRC);
|
||||
return;
|
||||
}
|
||||
int fd = open(FileName,O_WRONLY);
|
||||
if (fd==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
int AttrPos=0;
|
||||
while (AttrPos<Arc.EAHead.UnpSize)
|
||||
{
|
||||
unsigned char *CurItem=&UnpData[AttrPos];
|
||||
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||
char Name[1024];
|
||||
if (NameSize>=sizeof(Name))
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
memcpy(Name,CurItem+10,NameSize);
|
||||
Name[NameSize]=0;
|
||||
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
AttrPos+=10+NameSize+Size;
|
||||
}
|
||||
close(fd);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
|
||||
void ExtractBeEANew(Archive &Arc,char *FileName)
|
||||
{
|
||||
Array<byte> SubData;
|
||||
if (!Arc.ReadSubData(&SubData,NULL))
|
||||
return;
|
||||
|
||||
int fd = open(FileName,O_WRONLY);
|
||||
if (fd==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
int AttrPos=0;
|
||||
while (AttrPos<Arc.EAHead.UnpSize)
|
||||
{
|
||||
unsigned char *CurItem=&SubData[AttrPos];
|
||||
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||
char Name[1024];
|
||||
if (NameSize>=sizeof(Name))
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
memcpy(Name,CurItem+10,NameSize);
|
||||
Name[NameSize]=0;
|
||||
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||
{
|
||||
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||
ErrHandler.SetErrorCode(RARX_WARNING);
|
||||
break;
|
||||
}
|
||||
AttrPos+=10+NameSize+Size;
|
||||
}
|
||||
close(fd);
|
||||
mprintf(St(MShowEA));
|
||||
}
|
||||
|
||||
183
unrar/blake2s.cpp
Normal file
183
unrar/blake2s.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
// Based on public domain code written in 2012 by Samuel Neves
|
||||
|
||||
#include "rar.hpp"
|
||||
|
||||
#ifdef USE_SSE
|
||||
#include "blake2s_sse.cpp"
|
||||
#endif
|
||||
|
||||
static void blake2s_init_param( blake2s_state *S, uint32 node_offset, uint32 node_depth);
|
||||
static void blake2s_update( blake2s_state *S, const byte *in, size_t inlen );
|
||||
static void blake2s_final( blake2s_state *S, byte *digest );
|
||||
|
||||
#include "blake2sp.cpp"
|
||||
|
||||
static const uint32 blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const byte blake2s_sigma[10][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
static inline void blake2s_set_lastnode( blake2s_state *S )
|
||||
{
|
||||
S->f[1] = ~0U;
|
||||
}
|
||||
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline void blake2s_set_lastblock( blake2s_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2s_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0U;
|
||||
}
|
||||
|
||||
|
||||
static inline void blake2s_increment_counter( blake2s_state *S, const uint32 inc )
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
}
|
||||
|
||||
|
||||
/* init2 xors IV with input parameter block */
|
||||
void blake2s_init_param( blake2s_state *S, uint32 node_offset, uint32 node_depth)
|
||||
{
|
||||
#ifdef USE_SSE
|
||||
if (_SSE_Version>=SSE_SSE2)
|
||||
blake2s_init_sse();
|
||||
#endif
|
||||
|
||||
S->init(); // Clean data.
|
||||
for( int i = 0; i < 8; ++i )
|
||||
S->h[i] = blake2s_IV[i];
|
||||
|
||||
S->h[0] ^= 0x02080020; // We use BLAKE2sp parameters block.
|
||||
S->h[2] ^= node_offset;
|
||||
S->h[3] ^= (node_depth<<16)|0x20000000;
|
||||
}
|
||||
|
||||
|
||||
#define G(r,i,m,a,b,c,d) \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||
d = rotr32(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 12); \
|
||||
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||
d = rotr32(d ^ a, 8); \
|
||||
c = c + d; \
|
||||
b = rotr32(b ^ c, 7);
|
||||
|
||||
|
||||
static void blake2s_compress( blake2s_state *S, const byte block[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
uint32 m[16];
|
||||
uint32 v[16];
|
||||
|
||||
for( size_t i = 0; i < 16; ++i )
|
||||
m[i] = RawGet4( block + i * 4 );
|
||||
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
v[i] = S->h[i];
|
||||
|
||||
v[ 8] = blake2s_IV[0];
|
||||
v[ 9] = blake2s_IV[1];
|
||||
v[10] = blake2s_IV[2];
|
||||
v[11] = blake2s_IV[3];
|
||||
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||
|
||||
for ( uint r = 0; r <= 9; ++r ) // No gain on i7 if unrolled, but exe size grows.
|
||||
{
|
||||
G(r,0,m,v[ 0],v[ 4],v[ 8],v[12]);
|
||||
G(r,1,m,v[ 1],v[ 5],v[ 9],v[13]);
|
||||
G(r,2,m,v[ 2],v[ 6],v[10],v[14]);
|
||||
G(r,3,m,v[ 3],v[ 7],v[11],v[15]);
|
||||
G(r,4,m,v[ 0],v[ 5],v[10],v[15]);
|
||||
G(r,5,m,v[ 1],v[ 6],v[11],v[12]);
|
||||
G(r,6,m,v[ 2],v[ 7],v[ 8],v[13]);
|
||||
G(r,7,m,v[ 3],v[ 4],v[ 9],v[14]);
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
|
||||
void blake2s_update( blake2s_state *S, const byte *in, size_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||
S->buflen += fill;
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
#ifdef USE_SSE
|
||||
#ifdef _WIN_32 // We use SSSE3 _mm_shuffle_epi8 only in x64 mode.
|
||||
if (_SSE_Version>=SSE_SSE2)
|
||||
#else
|
||||
if (_SSE_Version>=SSE_SSSE3)
|
||||
#endif
|
||||
blake2s_compress_sse( S, S->buf );
|
||||
else
|
||||
blake2s_compress( S, S->buf ); // Compress
|
||||
#else
|
||||
blake2s_compress( S, S->buf ); // Compress
|
||||
#endif
|
||||
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, (size_t)inlen );
|
||||
S->buflen += (size_t)inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void blake2s_final( blake2s_state *S, byte *digest )
|
||||
{
|
||||
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||
blake2s_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2s_increment_counter( S, ( uint32 )S->buflen );
|
||||
blake2s_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2s_compress( S, S->buf );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) /* Output full hash */
|
||||
RawPut4( S->h[i], digest + 4 * i );
|
||||
}
|
||||
|
||||
102
unrar/blake2s.hpp
Normal file
102
unrar/blake2s.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// Based on public domain code written in 2012 by Samuel Neves
|
||||
#ifndef _RAR_BLAKE2_
|
||||
#define _RAR_BLAKE2_
|
||||
|
||||
#define BLAKE2_DIGEST_SIZE 32
|
||||
#define BLAKE2_THREADS_NUMBER 8
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32
|
||||
};
|
||||
|
||||
|
||||
// Alignment to 64 improves performance of both SSE and non-SSE versions.
|
||||
// Alignment to n*16 is required for SSE version, so we selected 64.
|
||||
// We use the custom alignment scheme instead of __declspec(align(x)),
|
||||
// because it is less compiler dependent. Also the compiler directive
|
||||
// does not help if structure is a member of class allocated through
|
||||
// 'new' operator.
|
||||
struct blake2s_state
|
||||
{
|
||||
enum { BLAKE_ALIGNMENT = 64 };
|
||||
|
||||
// buffer and uint32 h[8], t[2], f[2];
|
||||
enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES };
|
||||
|
||||
byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
|
||||
|
||||
byte *buf; // byte buf[2 * BLAKE2S_BLOCKBYTES].
|
||||
uint32 *h, *t, *f; // uint32 h[8], t[2], f[2].
|
||||
|
||||
size_t buflen;
|
||||
byte last_node;
|
||||
|
||||
blake2s_state()
|
||||
{
|
||||
set_pointers();
|
||||
}
|
||||
|
||||
// Required when we declare and assign in the same command.
|
||||
blake2s_state(blake2s_state &st)
|
||||
{
|
||||
set_pointers();
|
||||
*this=st;
|
||||
}
|
||||
|
||||
void set_pointers()
|
||||
{
|
||||
// Set aligned pointers. Must be done in constructor, not in Init(),
|
||||
// so assignments like 'blake2sp_state res=blake2ctx' work correctly
|
||||
// even if blake2sp_init is not called for 'res'.
|
||||
buf = (byte *) ALIGN_VALUE(ubuf, BLAKE_ALIGNMENT);
|
||||
h = (uint32 *) (buf + 2 * BLAKE2S_BLOCKBYTES);
|
||||
t = h + 8;
|
||||
f = t + 2;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
memset( ubuf, 0, sizeof( ubuf ) );
|
||||
buflen = 0;
|
||||
last_node = 0;
|
||||
}
|
||||
|
||||
// Since we use pointers, the default = would work incorrectly.
|
||||
blake2s_state& operator = (blake2s_state &st)
|
||||
{
|
||||
if (this != &st)
|
||||
{
|
||||
memcpy(buf, st.buf, BLAKE_DATA_SIZE);
|
||||
buflen = st.buflen;
|
||||
last_node = st.last_node;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifdef RAR_SMP
|
||||
class ThreadPool;
|
||||
#endif
|
||||
|
||||
struct blake2sp_state
|
||||
{
|
||||
blake2s_state S[8];
|
||||
blake2s_state R;
|
||||
byte buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
|
||||
#ifdef RAR_SMP
|
||||
ThreadPool *ThPool;
|
||||
uint MaxThreads;
|
||||
#endif
|
||||
};
|
||||
|
||||
void blake2sp_init( blake2sp_state *S );
|
||||
void blake2sp_update( blake2sp_state *S, const byte *in, size_t inlen );
|
||||
void blake2sp_final( blake2sp_state *S, byte *digest );
|
||||
|
||||
#endif
|
||||
|
||||
129
unrar/blake2s_sse.cpp
Normal file
129
unrar/blake2s_sse.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
// Based on public domain code written in 2012 by Samuel Neves
|
||||
|
||||
extern const byte blake2s_sigma[10][16];
|
||||
|
||||
// Initialization vector.
|
||||
static __m128i blake2s_IV_0_3, blake2s_IV_4_7;
|
||||
|
||||
#ifdef _WIN_64
|
||||
// Constants for cyclic rotation. Used in 64-bit mode in mm_rotr_epi32 macro.
|
||||
static __m128i crotr8, crotr16;
|
||||
#endif
|
||||
|
||||
static void blake2s_init_sse()
|
||||
{
|
||||
// We cannot initialize these 128 bit variables in place when declaring
|
||||
// them globally, because global scope initialization is performed before
|
||||
// our SSE check and it would make code incompatible with older non-SSE2
|
||||
// CPUs. Also we cannot initialize them as static inside of function
|
||||
// using these variables, because SSE static initialization is not thread
|
||||
// safe: first thread starts initialization and sets "init done" flag even
|
||||
// if it is not done yet, second thread can attempt to access half-init
|
||||
// SSE data. So we moved init code here.
|
||||
|
||||
blake2s_IV_0_3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
|
||||
blake2s_IV_4_7 = _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 );
|
||||
|
||||
#ifdef _WIN_64
|
||||
crotr8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
|
||||
crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
|
||||
#ifdef _WIN_32
|
||||
// 32-bit mode has less SSE2 registers and in MSVC2008 it is more efficient
|
||||
// to not use _mm_shuffle_epi8 here.
|
||||
#define mm_rotr_epi32(r, c) ( \
|
||||
_mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) )
|
||||
#else
|
||||
#define mm_rotr_epi32(r, c) ( \
|
||||
c==8 ? _mm_shuffle_epi8(r,crotr8) \
|
||||
: c==16 ? _mm_shuffle_epi8(r,crotr16) \
|
||||
: _mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) )
|
||||
#endif
|
||||
|
||||
|
||||
#define G1(row1,row2,row3,row4,buf) \
|
||||
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||
row4 = _mm_xor_si128( row4, row1 ); \
|
||||
row4 = mm_rotr_epi32(row4, 16); \
|
||||
row3 = _mm_add_epi32( row3, row4 ); \
|
||||
row2 = _mm_xor_si128( row2, row3 ); \
|
||||
row2 = mm_rotr_epi32(row2, 12);
|
||||
|
||||
#define G2(row1,row2,row3,row4,buf) \
|
||||
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||
row4 = _mm_xor_si128( row4, row1 ); \
|
||||
row4 = mm_rotr_epi32(row4, 8); \
|
||||
row3 = _mm_add_epi32( row3, row4 ); \
|
||||
row2 = _mm_xor_si128( row2, row3 ); \
|
||||
row2 = mm_rotr_epi32(row2, 7);
|
||||
|
||||
#define DIAGONALIZE(row1,row2,row3,row4) \
|
||||
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \
|
||||
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) );
|
||||
|
||||
#define UNDIAGONALIZE(row1,row2,row3,row4) \
|
||||
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \
|
||||
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) );
|
||||
|
||||
#ifdef _WIN_64
|
||||
// MSVC 2008 in x64 mode expands _mm_set_epi32 to store to stack and load
|
||||
// from stack operations, which are slower than this code.
|
||||
#define _mm_set_epi32(i3,i2,i1,i0) \
|
||||
_mm_unpacklo_epi32(_mm_unpacklo_epi32(_mm_cvtsi32_si128(i0),_mm_cvtsi32_si128(i2)), \
|
||||
_mm_unpacklo_epi32(_mm_cvtsi32_si128(i1),_mm_cvtsi32_si128(i3)))
|
||||
#endif
|
||||
|
||||
// Original BLAKE2 SSE4.1 message loading code was a little slower in x86 mode
|
||||
// and about the same in x64 mode in our test. Perhaps depends on compiler.
|
||||
// We also tried _mm_i32gather_epi32 and _mm256_i32gather_epi32 AVX2 gather
|
||||
// instructions here, but they did not show any speed gain on i7-6700K.
|
||||
#define SSE_ROUND(m,row,r) \
|
||||
{ \
|
||||
__m128i buf; \
|
||||
buf=_mm_set_epi32(m[blake2s_sigma[r][6]],m[blake2s_sigma[r][4]],m[blake2s_sigma[r][2]],m[blake2s_sigma[r][0]]); \
|
||||
G1(row[0],row[1],row[2],row[3],buf); \
|
||||
buf=_mm_set_epi32(m[blake2s_sigma[r][7]],m[blake2s_sigma[r][5]],m[blake2s_sigma[r][3]],m[blake2s_sigma[r][1]]); \
|
||||
G2(row[0],row[1],row[2],row[3],buf); \
|
||||
DIAGONALIZE(row[0],row[1],row[2],row[3]); \
|
||||
buf=_mm_set_epi32(m[blake2s_sigma[r][14]],m[blake2s_sigma[r][12]],m[blake2s_sigma[r][10]],m[blake2s_sigma[r][8]]); \
|
||||
G1(row[0],row[1],row[2],row[3],buf); \
|
||||
buf=_mm_set_epi32(m[blake2s_sigma[r][15]],m[blake2s_sigma[r][13]],m[blake2s_sigma[r][11]],m[blake2s_sigma[r][9]]); \
|
||||
G2(row[0],row[1],row[2],row[3],buf); \
|
||||
UNDIAGONALIZE(row[0],row[1],row[2],row[3]); \
|
||||
}
|
||||
|
||||
|
||||
static int blake2s_compress_sse( blake2s_state *S, const byte block[BLAKE2S_BLOCKBYTES] )
|
||||
{
|
||||
__m128i row[4];
|
||||
__m128i ff0, ff1;
|
||||
|
||||
const uint32 *m = ( uint32 * )block;
|
||||
|
||||
row[0] = ff0 = LOAD( &S->h[0] );
|
||||
row[1] = ff1 = LOAD( &S->h[4] );
|
||||
|
||||
row[2] = blake2s_IV_0_3;
|
||||
row[3] = _mm_xor_si128( blake2s_IV_4_7, LOAD( &S->t[0] ) );
|
||||
SSE_ROUND( m, row, 0 );
|
||||
SSE_ROUND( m, row, 1 );
|
||||
SSE_ROUND( m, row, 2 );
|
||||
SSE_ROUND( m, row, 3 );
|
||||
SSE_ROUND( m, row, 4 );
|
||||
SSE_ROUND( m, row, 5 );
|
||||
SSE_ROUND( m, row, 6 );
|
||||
SSE_ROUND( m, row, 7 );
|
||||
SSE_ROUND( m, row, 8 );
|
||||
SSE_ROUND( m, row, 9 );
|
||||
STORE( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row[0], row[2] ) ) );
|
||||
STORE( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row[1], row[3] ) ) );
|
||||
return 0;
|
||||
}
|
||||
153
unrar/blake2sp.cpp
Normal file
153
unrar/blake2sp.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
BLAKE2 reference source code package - reference C implementations
|
||||
|
||||
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
||||
|
||||
To the extent possible under law, the author(s) have dedicated all copyright
|
||||
and related and neighboring rights to this software to the public domain
|
||||
worldwide. This software is distributed without any warranty.
|
||||
|
||||
You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#define PARALLELISM_DEGREE 8
|
||||
|
||||
void blake2sp_init( blake2sp_state *S )
|
||||
{
|
||||
memset( S->buf, 0, sizeof( S->buf ) );
|
||||
S->buflen = 0;
|
||||
|
||||
blake2s_init_param( &S->R, 0, 1 ); // Init root.
|
||||
|
||||
for( uint i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_init_param( &S->S[i], i, 0 ); // Init leaf.
|
||||
|
||||
S->R.last_node = 1;
|
||||
S->S[PARALLELISM_DEGREE - 1].last_node = 1;
|
||||
}
|
||||
|
||||
|
||||
struct Blake2ThreadData
|
||||
{
|
||||
void Update();
|
||||
blake2s_state *S;
|
||||
const byte *in;
|
||||
size_t inlen;
|
||||
};
|
||||
|
||||
|
||||
void Blake2ThreadData::Update()
|
||||
{
|
||||
size_t inlen__ = inlen;
|
||||
const byte *in__ = ( const byte * )in;
|
||||
|
||||
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
#ifdef USE_SSE
|
||||
// We gain 5% in i7 SSE mode by prefetching next data block.
|
||||
if (_SSE_Version>=SSE_SSE && inlen__ >= 2 * PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES)
|
||||
_mm_prefetch((char*)(in__ + PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES), _MM_HINT_T0);
|
||||
#endif
|
||||
blake2s_update( S, in__, BLAKE2S_BLOCKBYTES );
|
||||
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RAR_SMP
|
||||
THREAD_PROC(Blake2Thread)
|
||||
{
|
||||
Blake2ThreadData *td=(Blake2ThreadData *)Data;
|
||||
td->Update();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void blake2sp_update( blake2sp_state *S, const byte *in, size_t inlen )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = sizeof( S->buf ) - left;
|
||||
|
||||
if( left && inlen >= fill )
|
||||
{
|
||||
memcpy( S->buf + left, in, fill );
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( &S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
Blake2ThreadData btd_array[PARALLELISM_DEGREE];
|
||||
|
||||
#ifdef RAR_SMP
|
||||
uint ThreadNumber = inlen < 0x1000 ? 1 : S->MaxThreads;
|
||||
|
||||
if (ThreadNumber==6 || ThreadNumber==7) // 6 and 7 threads work slower than 4 here.
|
||||
ThreadNumber=4;
|
||||
#else
|
||||
uint ThreadNumber=1;
|
||||
#endif
|
||||
|
||||
for (size_t id__=0;id__<PARALLELISM_DEGREE;)
|
||||
{
|
||||
for (uint Thread=0;Thread<ThreadNumber && id__<PARALLELISM_DEGREE;Thread++)
|
||||
{
|
||||
Blake2ThreadData *btd=btd_array+Thread;
|
||||
|
||||
btd->inlen = inlen;
|
||||
btd->in = in + id__ * BLAKE2S_BLOCKBYTES;
|
||||
btd->S = &S->S[id__];
|
||||
|
||||
#ifdef RAR_SMP
|
||||
if (ThreadNumber>1)
|
||||
S->ThPool->AddTask(Blake2Thread,(void*)btd);
|
||||
else
|
||||
btd->Update();
|
||||
#else
|
||||
btd->Update();
|
||||
#endif
|
||||
id__++;
|
||||
}
|
||||
#ifdef RAR_SMP
|
||||
if (S->ThPool!=NULL) // Can be NULL in -mt1 mode.
|
||||
S->ThPool->WaitDone();
|
||||
#endif // RAR_SMP
|
||||
}
|
||||
|
||||
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( inlen > 0 )
|
||||
memcpy( S->buf + left, in, (size_t)inlen );
|
||||
|
||||
S->buflen = left + (size_t)inlen;
|
||||
}
|
||||
|
||||
|
||||
void blake2sp_final( blake2sp_state *S, byte *digest )
|
||||
{
|
||||
byte hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
{
|
||||
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||
{
|
||||
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||
|
||||
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||
|
||||
blake2s_update( &S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||
}
|
||||
|
||||
blake2s_final( &S->S[i], hash[i] );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||
blake2s_update( &S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||
|
||||
blake2s_final( &S->R, digest );
|
||||
}
|
||||
1531
unrar/cmddata.cpp
1531
unrar/cmddata.cpp
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user