mirror of
https://github.com/php-win-ext/php-rar.git
synced 2026-03-24 04:52:07 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10932c2450 | ||
|
|
b79f595379 | ||
|
|
479372f714 | ||
|
|
121310f696 | ||
|
|
43589ad851 | ||
|
|
b3145c9883 | ||
|
|
5a9886a844 | ||
|
|
bdd4ce2357 | ||
|
|
2fd19b59ca | ||
|
|
83756881c2 | ||
|
|
cc7edac87b | ||
|
|
a05875667e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,3 +40,4 @@
|
||||
/pecl-rar.*
|
||||
/rar.la
|
||||
*.autosave
|
||||
/unrar/.libs
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -1,12 +1,19 @@
|
||||
language: c
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- valgrind
|
||||
|
||||
env:
|
||||
#- PHP_VERSION=5.2.17 ZTS=yes MIRROR=http://museum.php.net/php5/
|
||||
- PHP_VERSION=5.3.29 ZTS=yes
|
||||
- PHP_VERSION=5.4.45 ZTS=yes
|
||||
- PHP_VERSION=5.5.37 ZTS=yes
|
||||
- PHP_VERSION=5.6.30 ZTS=yes
|
||||
- PHP_VERSION=5.6.30 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||
- PHP_VERSION=5.6.30 ZTS=no
|
||||
- PHP_VERSION=7.0.21 ZTS=yes COVERAGE=yes
|
||||
- PHP_VERSION=7.1.7 ZTS=yes RUN_TESTS_FLAGS=-m
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -17,7 +24,10 @@ before_install:
|
||||
- maybe_install_php $PHP_VERSION $ZTS
|
||||
|
||||
install:
|
||||
- build $PHP_VERSION $ZTS
|
||||
- build $PHP_VERSION $ZTS "$COVERAGE"
|
||||
|
||||
script:
|
||||
- run_tests $PHP_VERSION $ZTS
|
||||
|
||||
after_success:
|
||||
- 'test "$COVERAGE" != "yes" || bash <(curl -s https://codecov.io/bash)'
|
||||
|
||||
@@ -10,3 +10,6 @@ unrar/LICENSE.txt for details.
|
||||
Some modifications have been applied to the UnRAR library, mainly to allow
|
||||
streaming extraction of files without using threads.
|
||||
|
||||
[](https://ci.appveyor.com/project/cataphract/php-rar/branch/master)
|
||||
[](https://travis-ci.org/cataphract/php-rar)
|
||||
[](https://codecov.io/gh/cataphract/php-rar)
|
||||
29
appveyor.bat
Normal file
29
appveyor.bat
Normal file
@@ -0,0 +1,29 @@
|
||||
echo Running appveyor.bat
|
||||
echo on
|
||||
|
||||
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
|
||||
|
||||
IF NOT EXIST "C:\projects\php-sdk" (
|
||||
wget -nv http://windows.php.net/downloads/php-sdk/php-sdk-binary-tools-20110915.zip
|
||||
7z x -y php-sdk-binary-tools-20110915.zip -oC:\projects\php-sdk
|
||||
)
|
||||
IF NOT EXIST "C:\projects\php-src\Release_TS\php7ts.lib" (
|
||||
git clone --depth=1 --branch=PHP-7.1 https://github.com/php/php-src C:\projects\php-src
|
||||
wget -nv http://windows.php.net/downloads/php-sdk/deps-7.1-vc14-x86.7z
|
||||
7z x -y deps-7.1-vc14-x86.7z -oC:\projects\php-src
|
||||
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||
cd C:\projects\php-src
|
||||
CALL buildconf.bat
|
||||
CALL configure.bat --disable-all --enable-cli --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||
nmake
|
||||
) ELSE (
|
||||
echo php7ts.lib already exists
|
||||
cd C:\projects\php-src
|
||||
CALL C:\projects\php-sdk\bin\phpsdk_setvars.bat
|
||||
)
|
||||
|
||||
CALL buildconf.bat --force --add-modules-dir=%APPVEYOR_BUILD_FOLDER%\..
|
||||
CALL configure.bat --disable-all --enable-cli --enable-rar=shared --with-config-file-scan-dir=C:\projects\extension\bin\modules.d --with-prefix=%APPVEYOR_BUILD_FOLDER%\bin --with-php-build=deps
|
||||
nmake || exit /b
|
||||
rmdir Release_TS\php-rar /S /Q
|
||||
del /S /Q "Release_TS\*.sbr"
|
||||
26
appveyor.yml
Normal file
26
appveyor.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
# Based on igbinary's appveyor config.
|
||||
|
||||
version: '{branch}.{build}'
|
||||
install:
|
||||
- cmd: choco feature enable -n=allowGlobalConfirmation
|
||||
- cmd: cinst wget
|
||||
- cmd: mkdir %APPVEYOR_BUILD_FOLDER%\bin
|
||||
|
||||
build_script:
|
||||
- cmd: "%APPVEYOR_BUILD_FOLDER%\\appveyor.bat"
|
||||
|
||||
test_script:
|
||||
- cmd: cd C:\projects\php-src
|
||||
- cmd: set NO_INTERACTION=1
|
||||
- cmd: set REPORT_EXIT_STATUS=1
|
||||
- cmd: set TZ=UTC
|
||||
- cmd: 'nmake test TESTS="--show-diff --set-timeout 30 -d extension=C:\projects\php-src\Release_TS\php_rar.dll %APPVEYOR_BUILD_FOLDER%\tests"'
|
||||
|
||||
after_test:
|
||||
# - cmd: dir /S C:\projects\php-src\Release_TS
|
||||
- cmd: 'del C:\projects\php-src\Release_TS\php_rar.*'
|
||||
|
||||
cache:
|
||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||
- C:\projects\php-src
|
||||
- C:\projects\php-sdk
|
||||
18
composer.json
Normal file
18
composer.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "rar",
|
||||
"type": "extension",
|
||||
"license": [
|
||||
"PHP License"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gustavo Lopes",
|
||||
"email": "cataphract@php.net"
|
||||
},
|
||||
{
|
||||
"name": "Antony Dovgal",
|
||||
"email": "tony@daylessday.org"
|
||||
}
|
||||
],
|
||||
"description": "rar extension"
|
||||
}
|
||||
@@ -37,6 +37,6 @@ if test "$PHP_RAR" != "no"; then
|
||||
PHP_REQUIRE_CXX()
|
||||
PHP_ADD_LIBRARY_WITH_PATH(stdc++, "", RAR_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -Wno-write-strings -Wall -I@ext_srcdir@/unrar)
|
||||
PHP_NEW_EXTENSION(rar, rar.c rar_error.c rararch.c rarentry.c rar_stream.c rar_navigation.c rar_time.c $unrar_sources, $ext_shared,,-DRARDLL -DSILENT -Wno-write-strings -Wall -I@ext_srcdir@/unrar)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/unrar)
|
||||
fi
|
||||
|
||||
48
config.w32
48
config.w32
@@ -4,26 +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 \
|
||||
secpassword.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");
|
||||
|
||||
AC_DEFINE("HAVE_RAR", 1, "Rar support");
|
||||
}
|
||||
|
||||
|
||||
|
||||
95
package.xml
95
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>2017-07-22</date>
|
||||
<time>03:00:00</time>
|
||||
<version>
|
||||
<release>3.0.2</release>
|
||||
<api>3.0.0</api>
|
||||
<release>4.0.0</release>
|
||||
<api>4.0.0</api>
|
||||
</version>
|
||||
|
||||
<stability>
|
||||
@@ -36,8 +36,11 @@ 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>- Merge changes made to unrar up to version 5.5.6.
|
||||
- Support PHP 7.0 and PHP 7.1.
|
||||
- Added functions RarEntry::getRedirType(), RarEntry::isRedirectToDirectory() and RarEntry::getRedirTarget(), as well as the following constants on RarEntry: FSREDIR_UNIXSYMLINK, FSREDIR_WINSYMLINK, FSREDIR_JUNCTION, FSREDIR_HARDLINK and FSREDIR_FILECOPY.
|
||||
- Changed stat handler to return UTC time for creation, modification and access time (does not work reliably on Windows).
|
||||
- Fix cloning of RarArchive being allowed.
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
@@ -142,6 +145,20 @@ 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="commented.rar"/>
|
||||
<file role="test" name="corrupted.rar"/>
|
||||
<file role="test" name="directories.rar"/>
|
||||
@@ -165,6 +182,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,7 +193,10 @@ 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="coder.cpp" role="src" />
|
||||
@@ -185,6 +208,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 +237,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 +258,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" />
|
||||
@@ -238,10 +271,31 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<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 +305,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" />
|
||||
@@ -275,7 +328,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<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" />
|
||||
@@ -291,7 +343,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<file name="config.w32" role="src" />
|
||||
<file name="CREDITS" role="doc" />
|
||||
<file name="LICENSE" role="doc" />
|
||||
<file name="README" role="doc" />
|
||||
<file name="README.md" role="doc" />
|
||||
<file name="example.php" role="doc" />
|
||||
<file name="php_rar.h" role="src" />
|
||||
<file name="rar.c" role="src" />
|
||||
@@ -299,6 +351,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<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 role="src" name="rar_navigation.c"/>
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
@@ -306,7 +359,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>
|
||||
@@ -319,6 +372,22 @@ http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<extsrcrelease />
|
||||
|
||||
<changelog>
|
||||
<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>
|
||||
@@ -406,7 +475,7 @@ Other changes:
|
||||
- A lot of refactoring and compilation as C, not C++.
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>1.0.0</release>
|
||||
|
||||
84
php_rar.h
84
php_rar.h
@@ -46,6 +46,8 @@
|
||||
#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
|
||||
|
||||
@@ -77,17 +79,78 @@ enum HOST_SYSTEM {
|
||||
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||
HOST_BEOS=5,HOST_MAX
|
||||
};
|
||||
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
|
||||
|
||||
/* PHP 7+ abstraction */
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
typedef zend_object* rar_obj_ref;
|
||||
|
||||
#define rar_zval_add_ref(ppzv) zval_add_ref(*ppzv)
|
||||
|
||||
#define ZVAL_ALLOC_DUP(dst, src) \
|
||||
do { \
|
||||
dst = (zval*) emalloc(sizeof(zval)); \
|
||||
ZVAL_DUP(dst, src); \
|
||||
} while (0)
|
||||
|
||||
#define RAR_RETURN_STRINGL(s, l, duplicate) \
|
||||
do { \
|
||||
RETVAL_STRINGL(s, l); \
|
||||
if (duplicate == 0) { \
|
||||
efree(s); \
|
||||
} \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
#define RAR_ZVAL_STRING(z, s, duplicate) \
|
||||
do { \
|
||||
ZVAL_STRING(z, s); \
|
||||
if (duplicate == 0) { \
|
||||
efree(s); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef size_t zpp_s_size_t;
|
||||
|
||||
#define MAKE_STD_ZVAL(zv_p) \
|
||||
do { \
|
||||
(zv_p) = emalloc(sizeof(zval)); \
|
||||
ZVAL_NULL(zv_p); \
|
||||
} while (0)
|
||||
#define INIT_ZVAL(zv) ZVAL_UNDEF(&zv)
|
||||
|
||||
#define ZEND_ACC_FINAL_CLASS ZEND_ACC_FINAL
|
||||
|
||||
#else /* PHP 5.x */
|
||||
typedef zend_object_handle rar_obj_ref;
|
||||
|
||||
#define rar_zval_add_ref zval_add_ref
|
||||
#define ZVAL_ALLOC_DUP(dst, src) \
|
||||
do { \
|
||||
zval *z_src = src; \
|
||||
dst = z_src; \
|
||||
zval_add_ref(&dst); \
|
||||
SEPARATE_ZVAL(&dst); \
|
||||
} while (0)
|
||||
#define RAR_ZVAL_STRING ZVAL_STRING
|
||||
#define RAR_RETURN_STRINGL(s, l, duplicate) RETURN_STRINGL(s, l, duplicate)
|
||||
typedef int zpp_s_size_t;
|
||||
#define zend_hash_str_del zend_hash_del
|
||||
#endif
|
||||
|
||||
typedef struct _rar_cb_user_data {
|
||||
char *password; /* can be NULL */
|
||||
zval *callable; /* can be NULL */
|
||||
} 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;
|
||||
@@ -99,7 +162,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
|
||||
@@ -134,7 +197,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 */
|
||||
@@ -169,6 +232,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
|
||||
@@ -290,6 +362,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 */
|
||||
|
||||
|
||||
|
||||
77
rar.c
77
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;
|
||||
@@ -404,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);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
@@ -441,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 */
|
||||
}
|
||||
@@ -500,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;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -616,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)
|
||||
@@ -634,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++;
|
||||
|
||||
31
rar_error.c
31
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,8 +242,13 @@ void minit_rarerror(TSRMLS_D) /* {{{ */
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "RarException", php_rarexception_class_functions);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||
zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
|
||||
#else
|
||||
rarexception_ce_ptr = zend_register_internal_class_ex(&ce,
|
||||
zend_exception_get_default(TSRMLS_C));
|
||||
#endif
|
||||
rarexception_ce_ptr->ce_flags |= ZEND_ACC_FINAL;
|
||||
zend_declare_property_bool(rarexception_ce_ptr, "usingExceptions",
|
||||
sizeof("usingExceptions") -1, 0L /* FALSE */,
|
||||
|
||||
@@ -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 _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) {
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
236
rar_stream.c
236
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>
|
||||
@@ -64,7 +63,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;
|
||||
@@ -280,25 +279,6 @@ static mode_t _rar_convert_file_attrs(unsigned os_attrs,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _rar_time_convert(unsigned low, unsigned high, time_t *to) /* {{{ */
|
||||
{
|
||||
time_t default_ = (time_t) 0;
|
||||
|
||||
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 */
|
||||
*to = (time_t) ((INT32TO64(high, low) * 100 - ushift) / 1000000000);
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
php_stream_statbuf *ssb) /* {{{ */
|
||||
{
|
||||
@@ -328,28 +308,19 @@ static int _rar_stat_from_header(struct RARHeaderDataEx *header,
|
||||
ssb->sb.st_size = (long) (unsigned long) (int64) unp_size;
|
||||
}
|
||||
|
||||
|
||||
_rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
||||
_rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
||||
rar_time_convert(header->AtimeLow, header->AtimeHigh, &ssb->sb.st_atime);
|
||||
rar_time_convert(header->CtimeLow, header->CtimeHigh, &ssb->sb.st_ctime);
|
||||
|
||||
if (header->MtimeLow == 0 && header->MtimeHigh == 0) {
|
||||
/* high precision mod time undefined */
|
||||
struct tm time_s = {0};
|
||||
time_t time;
|
||||
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->MtimeLow, header->MtimeHigh,
|
||||
rar_time_convert(header->MtimeLow, header->MtimeHigh,
|
||||
&ssb->sb.st_mtime);
|
||||
}
|
||||
|
||||
@@ -416,12 +387,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
|
||||
}
|
||||
|
||||
|
||||
@@ -437,7 +415,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);
|
||||
@@ -511,8 +493,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,
|
||||
@@ -633,7 +614,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);
|
||||
@@ -643,32 +627,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,
|
||||
@@ -736,7 +738,17 @@ 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
|
||||
zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
|
||||
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))
|
||||
@@ -804,10 +816,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)
|
||||
{
|
||||
@@ -854,9 +873,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,
|
||||
@@ -918,10 +935,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);
|
||||
@@ -964,25 +987,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,
|
||||
@@ -999,7 +1027,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_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");
|
||||
@@ -1015,15 +1043,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_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;
|
||||
@@ -1035,9 +1063,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;
|
||||
@@ -1067,16 +1100,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)
|
||||
@@ -1090,11 +1127,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;
|
||||
@@ -1135,16 +1178,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
|
||||
@@ -1153,8 +1204,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;
|
||||
}
|
||||
@@ -1162,10 +1214,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)
|
||||
{
|
||||
@@ -1263,22 +1322,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
|
||||
264
rararch.c
264
rararch.c
@@ -41,14 +41,23 @@ extern "C" {
|
||||
|
||||
/* {{{ 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,15 +81,30 @@ 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 zend_object *rararch_ce_create_object(zend_class_entry *ce);
|
||||
static void rararch_ce_free_object_storage(zend_object *zobj);
|
||||
#else
|
||||
#define rararch_object_from_zv zend_object_store_get_object
|
||||
static zend_object_value rararch_ce_create_object(zend_class_entry *class_type TSRMLS_DC);
|
||||
static void rararch_ce_free_object_storage(ze_rararch_object *object TSRMLS_DC);
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive handlers */
|
||||
static int rararch_handlers_preamble(zval *object, rar_file_t **rar TSRMLS_DC);
|
||||
static int rararch_dimensions_preamble(rar_file_t *rar, zval *offset, long *index, int quiet TSRMLS_DC);
|
||||
static int rararch_count_elements(zval *object, long *count TSRMLS_DC);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC);
|
||||
#else
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv);
|
||||
#endif
|
||||
static void rararch_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC);
|
||||
static int rararch_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC);
|
||||
/* }}} */
|
||||
@@ -124,15 +148,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);
|
||||
@@ -172,7 +194,7 @@ void _rar_close_file_resource(rar_file_t *rar) /* {{{ */
|
||||
int _rar_get_file_resource_ex(zval *zval_file, rar_file_t **rar_file, int silent TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ze_rararch_object *zobj;
|
||||
zobj = zend_object_store_get_object(zval_file TSRMLS_CC);
|
||||
zobj = rararch_object_from_zv(zval_file TSRMLS_CC);
|
||||
if (zobj == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"Could not find object in the store. This is a bug, please report it.");
|
||||
@@ -196,16 +218,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 {
|
||||
@@ -214,22 +230,70 @@ 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));
|
||||
}
|
||||
#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;
|
||||
@@ -253,10 +317,30 @@ static zend_object_value rararch_ce_create_object(zend_class_entry *class_type T
|
||||
zov.handlers = &rararch_object_handlers;
|
||||
return zov;
|
||||
}
|
||||
#else
|
||||
static zend_object *rararch_ce_create_object(zend_class_entry *ce)
|
||||
{
|
||||
ze_rararch_object *zobj =
|
||||
emalloc(sizeof(*zobj) + zend_object_properties_size(ce));
|
||||
|
||||
zobj->rar_file = NULL;
|
||||
zend_object_std_init(&zobj->parent, ce);
|
||||
zobj->parent.handlers = &rararch_object_handlers;
|
||||
|
||||
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() */
|
||||
@@ -279,8 +363,10 @@ 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
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -348,10 +434,18 @@ static int rararch_dimensions_preamble(rar_file_t *rar,
|
||||
}
|
||||
else if (Z_TYPE_P(offset) == IS_OBJECT) {
|
||||
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 "
|
||||
@@ -361,7 +455,11 @@ 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 {
|
||||
@@ -416,7 +514,11 @@ static int rararch_count_elements(zval *object, long *count TSRMLS_DC)
|
||||
/* }}} */
|
||||
|
||||
/* {{{ RarArchive read_dimension handler */
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
#else
|
||||
static zval *rararch_read_dimension(zval *object, zval *offset, int type, zval *rv)
|
||||
#endif
|
||||
{
|
||||
long index;
|
||||
rar_file_t *rar = NULL;
|
||||
@@ -439,11 +541,17 @@ 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
|
||||
_rar_entry_to_zval(object, out->header, out->packed_size, out->position,
|
||||
ret TSRMLS_CC);
|
||||
_rar_entry_search_end(out);
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
Z_DELREF_P(ret); /* set refcount to 0 */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -492,8 +600,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;
|
||||
|
||||
@@ -573,7 +681,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;
|
||||
|
||||
@@ -657,7 +765,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);
|
||||
}
|
||||
}
|
||||
@@ -764,7 +872,7 @@ 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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -814,8 +922,12 @@ 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);
|
||||
/* }}} */
|
||||
@@ -836,6 +948,19 @@ static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
|
||||
it = emalloc(sizeof *it);
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
zval_add_ref(&object);
|
||||
it->parent.data = object;
|
||||
it->value = NULL;
|
||||
#else
|
||||
zend_iterator_init((zend_object_iterator *) it);
|
||||
ZVAL_COPY(&it->parent.data, object);
|
||||
ZVAL_UNDEF(&it->value);
|
||||
#endif
|
||||
|
||||
it->parent.funcs = ce->iterator_funcs.funcs;
|
||||
it->state = NULL;
|
||||
|
||||
res = _rar_get_file_resource_ex(object, &rar, 1 TSRMLS_CC);
|
||||
if (res == FAILURE)
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR,
|
||||
@@ -851,11 +976,7 @@ static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
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;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -864,10 +985,15 @@ static zend_object_iterator *rararch_it_get_iterator(zend_class_entry *ce,
|
||||
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
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -878,10 +1004,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
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -890,40 +1022,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_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)
|
||||
{
|
||||
@@ -931,6 +1095,20 @@ 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;
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
ret = ((rararch_iterator *) iter)->value;
|
||||
assert(ret != NULL);
|
||||
#else
|
||||
ret = &((rararch_iterator *) iter)->value;
|
||||
assert(Z_TYPE_P(ret) != IS_UNDEF);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ rararch_it_move_forward */
|
||||
@@ -938,7 +1116,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);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -949,7 +1131,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);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -977,6 +1158,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);
|
||||
|
||||
210
rarentry.c
210
rarentry.c
@@ -41,23 +41,20 @@ 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,
|
||||
@@ -66,12 +63,21 @@ void _rar_entry_to_zval(zval *parent, /* zval to RarArchive object, will have it
|
||||
char tmp_s [MAX_LENGTH_OF_LONG + 1];
|
||||
char time[50];
|
||||
char *filename;
|
||||
int filename_size, filename_len;
|
||||
int filename_size,
|
||||
filename_len;
|
||||
long unp_size; /* zval stores PHP ints as long, so use that here */
|
||||
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);
|
||||
sizeof("rararch") - 1, parent_copy TSRMLS_CC);
|
||||
|
||||
#if ULONG_MAX > 0xffffffffUL
|
||||
unp_size = ((long) entry->UnpSize) + (((long) entry->UnpSizeHigh) << 32);
|
||||
@@ -84,7 +90,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)
|
||||
@@ -124,6 +130,28 @@ void _rar_entry_to_zval(zval *parent, /* zval to RarArchive object, will have it
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "flags",
|
||||
sizeof("flags") - 1, entry->Flags TSRMLS_CC);
|
||||
|
||||
zend_update_property_long(rar_class_entry_ptr, object, "redir_type",
|
||||
sizeof("redir_type") - 1, entry->RedirType TSRMLS_CC);
|
||||
|
||||
if (entry->RedirName) {
|
||||
char *redir_target = NULL;
|
||||
size_t redir_target_size;
|
||||
|
||||
zend_update_property_bool(rar_class_entry_ptr, object,
|
||||
"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, object, "redir_target",
|
||||
sizeof("redir_target") - 1, redir_target TSRMLS_CC);
|
||||
|
||||
efree(redir_target);
|
||||
}
|
||||
|
||||
efree(filename);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -152,67 +180,76 @@ 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);
|
||||
ret = zend_declare_property_ex(ce, name_str, &property, ZEND_ACC_PRIVATE,
|
||||
doc_str);
|
||||
zend_string_release(name_str);
|
||||
zend_string_release(doc_str);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zval *_rar_entry_get_property(zval *entry_obj, char *name, int namelen TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *tmp;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval zv;
|
||||
#endif
|
||||
#if PHP_VERSION_ID < 70100
|
||||
zend_class_entry *orig_scope = EG(scope);
|
||||
|
||||
EG(scope) = rar_class_entry_ptr;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION < 7
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1 TSRMLS_CC);
|
||||
#else
|
||||
tmp = zend_read_property(Z_OBJCE_P(entry_obj), entry_obj, name, namelen, 1, &zv);
|
||||
#endif
|
||||
if (tmp == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"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);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
@@ -226,7 +263,7 @@ PHP_METHOD(rarentry, extract)
|
||||
char *dir,
|
||||
*filepath = NULL,
|
||||
*password = NULL;
|
||||
int dir_len,
|
||||
zpp_s_size_t dir_len,
|
||||
filepath_len = 0,
|
||||
password_len = 0;
|
||||
char *considered_path;
|
||||
@@ -360,7 +397,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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -422,7 +459,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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -437,7 +474,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);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -496,7 +533,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};
|
||||
|
||||
|
||||
@@ -566,6 +603,60 @@ PHP_METHOD(rarentry, isEncrypted)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
@@ -579,7 +670,7 @@ 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();
|
||||
@@ -595,14 +686,14 @@ 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);
|
||||
}
|
||||
/* }}} */
|
||||
/* }}} */
|
||||
@@ -638,6 +729,9 @@ 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, getRedirType, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, isRedirectToDirectory, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, getRedirTarget, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(rarentry, __toString, arginfo_rar_void, ZEND_ACC_PUBLIC)
|
||||
PHP_ME_MAPPING(__construct, rar_bogus_ctor, arginfo_rar_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
@@ -647,15 +741,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");
|
||||
@@ -669,6 +758,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);
|
||||
@@ -677,6 +769,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);
|
||||
|
||||
@@ -48,6 +48,12 @@ array(2) {
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
object(RarEntry)#%d (%d) {
|
||||
@@ -76,6 +82,12 @@ array(2) {
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
array(2) {
|
||||
@@ -106,6 +118,12 @@ array(2) {
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(0)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
object(RarEntry)#%d (%d) {
|
||||
@@ -134,6 +152,12 @@ array(2) {
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(16)
|
||||
["redir_type%sprivate]=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate]=>
|
||||
NULL
|
||||
["redir_target%sprivate]=>
|
||||
NULL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@ object(RarEntry)#%d (%d) {
|
||||
int(51)
|
||||
["flags%sprivate%s=>
|
||||
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=>
|
||||
@@ -73,6 +79,12 @@ object(RarEntry)#%d (%d) {
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
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
|
||||
|
||||
@@ -79,6 +79,12 @@ object(RarEntry)#%d (%d) {
|
||||
int(53)
|
||||
["flags%sprivate%s=>
|
||||
int(16)
|
||||
["redir_type%sprivate%s=>
|
||||
int(0)
|
||||
["redir_to_directory%sprivate%s=>
|
||||
NULL
|
||||
["redir_target%sprivate%s=>
|
||||
NULL
|
||||
}
|
||||
bool(true)
|
||||
Done
|
||||
|
||||
@@ -33,9 +33,9 @@ echo "Done\n";
|
||||
--EXPECTF--
|
||||
51 files (will test only the first 4):
|
||||
|
||||
test/C:5B': The great battle of Gunprex versus Optiter!!!!!1
|
||||
test%s: The great battle of Gunprex versus Optiter!!!!!1
|
||||
Gunprex, Fire!
|
||||
So long, Optiter!
|
||||
|
||||
test/Sbv=Ð:
|
||||
test%s
|
||||
Done
|
||||
|
||||
@@ -29,11 +29,11 @@ $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 = RarArchive::open($fn, null, 'strpos');
|
||||
$rar->getEntries();
|
||||
|
||||
echo "\nGiven callback that takes another kind of arguments:\n";
|
||||
$rar = RarArchive::open($fn, null, 'ksort');
|
||||
$rar = RarArchive::open($fn, null, 'array_keys');
|
||||
$rar->getEntries();
|
||||
|
||||
echo "\nGiven callback that returns another kind of arguments:\n";
|
||||
@@ -64,15 +64,13 @@ bool(false)
|
||||
|
||||
Given callback that takes more arguments:
|
||||
|
||||
Warning: array_walk() expects at least %d parameters, 1 given in %s on line %d
|
||||
Warning: strpos() expects at least %d parameters, 1 given in %s on line %d
|
||||
|
||||
Warning: RarArchive::getEntries(): ERAR_EOPEN (file open error) in %s on line %d
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
@@ -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--
|
||||
@@ -26,7 +32,7 @@ Array
|
||||
[rdev] => 0
|
||||
[size] => 5
|
||||
[atime] => 0
|
||||
[mtime] => 1086944839
|
||||
[mtime] => 1086948439
|
||||
[ctime] => 0
|
||||
[blksize] => %s
|
||||
[blocks] => %s
|
||||
|
||||
@@ -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--
|
||||
@@ -54,9 +61,9 @@ Array
|
||||
[gid] => 0
|
||||
[rdev] => 0
|
||||
[size] => 0
|
||||
[atime] => 1272935043
|
||||
[mtime] => 1272935043
|
||||
[ctime] => 1272809570
|
||||
[atime] => 1272938643
|
||||
[mtime] => 1272938643
|
||||
[ctime] => 1272813170
|
||||
[blksize] => %s
|
||||
[blocks] => %s
|
||||
)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
--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");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
--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");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
--TEST--
|
||||
Supports version 5 RAR files
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("rar")) print "skip"; ?>
|
||||
<?php if(!extension_loaded("rar")) die("skip");
|
||||
if (isset($_ENV['APPVEYOR'])) die("skip failing on appveyor");
|
||||
--FILE--
|
||||
<?php
|
||||
RarException::setUsingExceptions(true);
|
||||
$file = dirname(__FILE__) . '/rar5_multi.part1.rar';
|
||||
$rar = RarArchive::open($file);
|
||||
$entry = $rar->getEntry('usr/bin/text2image');
|
||||
$entry = $rar->getEntry('usr' . DIRECTORY_SEPARATOR . 'bin' .
|
||||
DIRECTORY_SEPARATOR . 'text2image');
|
||||
var_dump($entry);
|
||||
$stream = $entry->getStream('passw0rd');
|
||||
$contents = stream_get_contents($stream);
|
||||
@@ -22,7 +24,7 @@ object(RarEntry)#%d (%d) {
|
||||
["position%sprivate%s=>
|
||||
int(0)
|
||||
["name%sprivate%s=>
|
||||
string(18) "usr/bin/text2image"
|
||||
string(18) "usr%sbin%stext2image"
|
||||
["unpacked_size%sprivate%s=>
|
||||
int(147528)
|
||||
["packed_size%sprivate%s=>
|
||||
@@ -41,6 +43,12 @@ object(RarEntry)#%d (%d) {
|
||||
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 invalid context 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 invalid context 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(200)
|
||||
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.
|
||||
BIN
tests/rar5-links.rar
Normal file
BIN
tests/rar5-links.rar
Normal file
Binary file not shown.
15
travis.sh
15
travis.sh
@@ -34,18 +34,29 @@ function install_php {
|
||||
}
|
||||
|
||||
function build_ext {
|
||||
local readonly prefix=$1
|
||||
local readonly prefix=$1 coverage=$2
|
||||
"$prefix"/bin/phpize
|
||||
if [[ $coverage = 'yes' ]]; then
|
||||
export CPPFLAGS="$CPPFLAGS --coverage"
|
||||
fi
|
||||
./configure --with-php-config="$prefix/bin/php-config"
|
||||
make -j $JOBS
|
||||
}
|
||||
|
||||
function do_tests {
|
||||
local readonly prefix=$1
|
||||
local found_leaks= dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
echo "--suppressions=$dir/valgrind.supp" | tee ~/.valgrindrc
|
||||
TEST_PHP_EXECUTABLE="$prefix/bin/php" REPORT_EXIT_STATUS=1 \
|
||||
"$prefix/bin/php" "$prefix"/lib/php/build/run-tests.php \
|
||||
-q -d extension=modules/rar.so --set-timeout 300 --show-diff \
|
||||
$RUN_TESTS_FLAGS tests
|
||||
found_leaks=$(find tests -name '*.mem' | wc -l)
|
||||
if [[ $found_leaks -gt 0 ]]; then
|
||||
echo "Found $found_leaks leaks. Failing."
|
||||
find tests -name "*.mem" -print -exec cat {} \;
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# public functions below
|
||||
@@ -64,7 +75,7 @@ function build {
|
||||
set -e
|
||||
set -o pipefail
|
||||
if [[ ! -f modules/rar.so ]]; then
|
||||
build_ext "$(prefix $1 $2)"
|
||||
build_ext "$(prefix $1 $2)" "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
21
valgrind.supp
Normal file
21
valgrind.supp
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
<CRC32>
|
||||
Memcheck:Value8
|
||||
fun:_Z5CRC32jPKvm
|
||||
fun:_ZN7RawRead8GetCRC15Eb
|
||||
...
|
||||
}
|
||||
{
|
||||
<Xor128>
|
||||
Memcheck:Value8
|
||||
fun:_Z6Xor128PhPKhS1_S1_S1_
|
||||
fun:_ZN8Rijndael12blockDecryptEPKhmPh
|
||||
...
|
||||
}
|
||||
{
|
||||
<Xor128-2>
|
||||
Memcheck:Value8
|
||||
fun:Xor128
|
||||
fun:_ZN8Rijndael12blockDecryptEPKhmPh
|
||||
...
|
||||
}
|
||||
Reference in New Issue
Block a user