mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-13 12:10:50 +00:00
Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b8f72be99 | ||
|
|
f3030472de | ||
|
|
64433c46ca | ||
|
|
95064517d3 | ||
|
|
b1ca475703 | ||
|
|
c95107492d | ||
|
|
46ef5b1708 | ||
|
|
601b8fd2e5 | ||
|
|
20de5cc091 | ||
|
|
1434e56f6d | ||
|
|
9e38d04a7c | ||
|
|
b0207d34a1 | ||
|
|
b0d3aec8ad | ||
|
|
c52d7cb530 | ||
|
|
c48f944a04 | ||
|
|
aa53dcddab | ||
|
|
b03e53836e | ||
|
|
655e19326d | ||
|
|
604751ab87 | ||
|
|
73c8a340cf | ||
|
|
d1d605e80f | ||
|
|
af2e8a3db5 | ||
|
|
cef2cd485a | ||
|
|
69303b58a4 | ||
|
|
fde8b6006e | ||
|
|
2ae8d36a3c | ||
|
|
1620ddcb95 | ||
|
|
430dea8ef8 | ||
|
|
ebc108124b | ||
|
|
726e1efe86 | ||
|
|
a480ec36e7 | ||
|
|
77dfdccdd4 | ||
|
|
8f43323dee | ||
|
|
147ede8f37 | ||
|
|
b10c43905e |
No files matched your search
@@ -1,3 +1,342 @@
|
||||
2005-08-09 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* (PHP_5_1)
|
||||
NEWS:
|
||||
- This didn't end up being included
|
||||
|
||||
2005-08-09 Johannes Schlüter <schlueter@phpbar.de>
|
||||
|
||||
* NEWS
|
||||
ext/standard/string.c
|
||||
ext/standard/tests/strings/stristr.phpt
|
||||
ext/standard/tests/strings/strstr.phpt:
|
||||
- Added option to strstr() and stristr() to get a particular haystack
|
||||
component
|
||||
|
||||
2005-08-09 Ilia Alshanetsky <ilia@prohost.org>
|
||||
|
||||
* ext/standard/url.h:
|
||||
Missing patch bit.
|
||||
|
||||
2005-08-09 Andrei Zmievski <andrei@gravitonic.com>
|
||||
|
||||
* (PHP_4_4)
|
||||
ext/pcre/config.m4
|
||||
ext/pcre/pcrelib/AUTHORS
|
||||
ext/pcre/pcrelib/COPYING
|
||||
ext/pcre/pcrelib/ChangeLog
|
||||
ext/pcre/pcrelib/LICENCE
|
||||
ext/pcre/pcrelib/NEWS
|
||||
ext/pcre/pcrelib/NON-UNIX-USE
|
||||
ext/pcre/pcrelib/README
|
||||
ext/pcre/pcrelib/chartables.c
|
||||
ext/pcre/pcrelib/dftables.c
|
||||
ext/pcre/pcrelib/get.c
|
||||
ext/pcre/pcrelib/internal.h
|
||||
ext/pcre/pcrelib/libpcre.def
|
||||
ext/pcre/pcrelib/libpcreposix.def
|
||||
ext/pcre/pcrelib/maketables.c
|
||||
ext/pcre/pcrelib/pcre.c
|
||||
ext/pcre/pcrelib/pcre.def
|
||||
ext/pcre/pcrelib/pcre.h
|
||||
ext/pcre/pcrelib/pcre_chartables.c
|
||||
ext/pcre/pcrelib/pcre_compile.c
|
||||
ext/pcre/pcrelib/pcre_config.c
|
||||
ext/pcre/pcrelib/pcre_dfa_exec.c
|
||||
ext/pcre/pcrelib/pcre_exec.c
|
||||
ext/pcre/pcrelib/pcre_fullinfo.c
|
||||
ext/pcre/pcrelib/pcre_get.c
|
||||
ext/pcre/pcrelib/pcre_globals.c
|
||||
ext/pcre/pcrelib/pcre_info.c
|
||||
ext/pcre/pcrelib/pcre_internal.h
|
||||
ext/pcre/pcrelib/pcre_maketables.c
|
||||
ext/pcre/pcrelib/pcre_ord2utf8.c
|
||||
ext/pcre/pcrelib/pcre_printint.c
|
||||
ext/pcre/pcrelib/pcre_refcount.c
|
||||
ext/pcre/pcrelib/pcre_scanner.cc
|
||||
ext/pcre/pcrelib/pcre_scanner.h
|
||||
ext/pcre/pcrelib/pcre_scanner_unittest.cc
|
||||
ext/pcre/pcrelib/pcre_stringpiece.cc
|
||||
ext/pcre/pcrelib/pcre_stringpiece.h
|
||||
ext/pcre/pcrelib/pcre_stringpiece_unittest.cc
|
||||
ext/pcre/pcrelib/pcre_study.c
|
||||
ext/pcre/pcrelib/pcre_tables.c
|
||||
ext/pcre/pcrelib/pcre_try_flipped.c
|
||||
ext/pcre/pcrelib/pcre_ucp_findchar.c
|
||||
ext/pcre/pcrelib/pcre_valid_utf8.c
|
||||
ext/pcre/pcrelib/pcre_version.c
|
||||
ext/pcre/pcrelib/pcre_xclass.c
|
||||
ext/pcre/pcrelib/pcrecpp.cc
|
||||
ext/pcre/pcrelib/pcrecpp.h
|
||||
ext/pcre/pcrelib/pcrecpp_unittest.cc
|
||||
ext/pcre/pcrelib/pcregrep.c
|
||||
ext/pcre/pcrelib/pcreposix.c
|
||||
ext/pcre/pcrelib/pcreposix.h
|
||||
ext/pcre/pcrelib/pcretest.c
|
||||
ext/pcre/pcrelib/study.c
|
||||
ext/pcre/pcrelib/ucp.c
|
||||
ext/pcre/pcrelib/ucp.h
|
||||
ext/pcre/pcrelib/ucp_findchar.c
|
||||
ext/pcre/pcrelib/ucptypetable.c
|
||||
ext/pcre/pcrelib/doc/Tech.Notes
|
||||
ext/pcre/pcrelib/doc/pcre.txt
|
||||
ext/pcre/pcrelib/testdata/grepinput
|
||||
ext/pcre/pcrelib/testdata/grepinputx
|
||||
ext/pcre/pcrelib/testdata/greplist
|
||||
ext/pcre/pcrelib/testdata/grepoutput
|
||||
ext/pcre/pcrelib/testdata/testinput1
|
||||
ext/pcre/pcrelib/testdata/testinput2
|
||||
ext/pcre/pcrelib/testdata/testinput3
|
||||
ext/pcre/pcrelib/testdata/testinput4
|
||||
ext/pcre/pcrelib/testdata/testinput5
|
||||
ext/pcre/pcrelib/testdata/testinput6
|
||||
ext/pcre/pcrelib/testdata/testinput7
|
||||
ext/pcre/pcrelib/testdata/testinput8
|
||||
ext/pcre/pcrelib/testdata/testinput9
|
||||
ext/pcre/pcrelib/testdata/testoutput1
|
||||
ext/pcre/pcrelib/testdata/testoutput2
|
||||
ext/pcre/pcrelib/testdata/testoutput3
|
||||
ext/pcre/pcrelib/testdata/testoutput4
|
||||
ext/pcre/pcrelib/testdata/testoutput5
|
||||
ext/pcre/pcrelib/testdata/testoutput6
|
||||
ext/pcre/pcrelib/testdata/testoutput7
|
||||
ext/pcre/pcrelib/testdata/testoutput8
|
||||
ext/pcre/pcrelib/testdata/testoutput9:
|
||||
Upgrade to PCRE 6.2.
|
||||
|
||||
* ext/pcre/pcrelib/internal.h:
|
||||
Remove old internal.h file.
|
||||
|
||||
2005-08-09 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* NEWS:
|
||||
reword
|
||||
|
||||
2005-08-09 Ilia Alshanetsky <ilia@prohost.org>
|
||||
|
||||
* NEWS
|
||||
ext/standard/basic_functions.c:
|
||||
News and constants for parse_url().
|
||||
|
||||
* ext/standard/url.c:
|
||||
Added option to parse_url() to retrieve a particular URL component.
|
||||
|
||||
* ext/curl/interface.c
|
||||
ext/curl/php_curl.h:
|
||||
Added curl_setopt_array(), allowing setting of multiple cURL options.
|
||||
Added CURLINFO_HEADER_OUT to facilitate request retrieval.
|
||||
|
||||
2005-08-09 Derick Rethans <php@derickrethans.nl>
|
||||
|
||||
* buildconf:
|
||||
- Fixed buildconf for PHP 6.
|
||||
|
||||
2005-08-09 Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
|
||||
* ext/pcre/config.w32:
|
||||
MFB: Sync with config.m4.
|
||||
|
||||
2005-08-09 Derick Rethans <php@derickrethans.nl>
|
||||
|
||||
* configure.in
|
||||
ZendEngine2/zend_extensions.h
|
||||
ZendEngine2/zend_modules.h
|
||||
main/php.h
|
||||
main/php_version.h:
|
||||
- Changing the API numbers, which might be a bit premature, but it allows
|
||||
to differentiate between different branches.
|
||||
- Bumbed the version number to 6.0.0-dev. I know we didn't discuss this
|
||||
yet,
|
||||
but I feel it should be 6.0. See mail to the mailinglist.
|
||||
|
||||
2005-08-09 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* NEWS:
|
||||
UN
|
||||
|
||||
2005-08-09 Sebastian Bergmann <sb@sebastian-bergmann.de>
|
||||
|
||||
* (PHP_5_1)
|
||||
ext/pcre/config.w32:
|
||||
Sync with config.m4.
|
||||
|
||||
2005-08-09 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* (PHP_5_1)
|
||||
NEWS
|
||||
configure.in
|
||||
ZendEngine2/zend.h
|
||||
main/php_version.h:
|
||||
- No release today. Found a critical bug...
|
||||
|
||||
* (PHP_5_1)
|
||||
NEWS
|
||||
configure.in
|
||||
ZendEngine2/zend.h
|
||||
main/php_version.h:
|
||||
- RC1
|
||||
|
||||
2005-08-08 Andrei Zmievski <andrei@gravitonic.com>
|
||||
|
||||
* ext/pcre/config.m4
|
||||
ext/pcre/pcrelib/AUTHORS
|
||||
ext/pcre/pcrelib/COPYING
|
||||
ext/pcre/pcrelib/ChangeLog
|
||||
ext/pcre/pcrelib/LICENCE
|
||||
ext/pcre/pcrelib/NEWS
|
||||
ext/pcre/pcrelib/NON-UNIX-USE
|
||||
ext/pcre/pcrelib/README
|
||||
ext/pcre/pcrelib/chartables.c
|
||||
ext/pcre/pcrelib/dftables.c
|
||||
ext/pcre/pcrelib/get.c
|
||||
ext/pcre/pcrelib/libpcre.def
|
||||
ext/pcre/pcrelib/libpcreposix.def
|
||||
ext/pcre/pcrelib/maketables.c
|
||||
ext/pcre/pcrelib/pcre.c
|
||||
ext/pcre/pcrelib/pcre.def
|
||||
ext/pcre/pcrelib/pcre.h
|
||||
ext/pcre/pcrelib/pcre_chartables.c
|
||||
ext/pcre/pcrelib/pcre_compile.c
|
||||
ext/pcre/pcrelib/pcre_config.c
|
||||
ext/pcre/pcrelib/pcre_dfa_exec.c
|
||||
ext/pcre/pcrelib/pcre_exec.c
|
||||
ext/pcre/pcrelib/pcre_fullinfo.c
|
||||
ext/pcre/pcrelib/pcre_get.c
|
||||
ext/pcre/pcrelib/pcre_globals.c
|
||||
ext/pcre/pcrelib/pcre_info.c
|
||||
ext/pcre/pcrelib/pcre_internal.h
|
||||
ext/pcre/pcrelib/pcre_maketables.c
|
||||
ext/pcre/pcrelib/pcre_ord2utf8.c
|
||||
ext/pcre/pcrelib/pcre_printint.c
|
||||
ext/pcre/pcrelib/pcre_refcount.c
|
||||
ext/pcre/pcrelib/pcre_scanner.cc
|
||||
ext/pcre/pcrelib/pcre_scanner.h
|
||||
ext/pcre/pcrelib/pcre_scanner_unittest.cc
|
||||
ext/pcre/pcrelib/pcre_stringpiece.cc
|
||||
ext/pcre/pcrelib/pcre_stringpiece.h
|
||||
ext/pcre/pcrelib/pcre_stringpiece_unittest.cc
|
||||
ext/pcre/pcrelib/pcre_study.c
|
||||
ext/pcre/pcrelib/pcre_tables.c
|
||||
ext/pcre/pcrelib/pcre_try_flipped.c
|
||||
ext/pcre/pcrelib/pcre_ucp_findchar.c
|
||||
ext/pcre/pcrelib/pcre_valid_utf8.c
|
||||
ext/pcre/pcrelib/pcre_version.c
|
||||
ext/pcre/pcrelib/pcre_xclass.c
|
||||
ext/pcre/pcrelib/pcrecpp.cc
|
||||
ext/pcre/pcrelib/pcrecpp.h
|
||||
ext/pcre/pcrelib/pcrecpp_unittest.cc
|
||||
ext/pcre/pcrelib/pcregrep.c
|
||||
ext/pcre/pcrelib/pcreposix.c
|
||||
ext/pcre/pcrelib/pcreposix.h
|
||||
ext/pcre/pcrelib/pcretest.c
|
||||
ext/pcre/pcrelib/study.c
|
||||
ext/pcre/pcrelib/ucp.c
|
||||
ext/pcre/pcrelib/ucp.h
|
||||
ext/pcre/pcrelib/ucp_findchar.c
|
||||
ext/pcre/pcrelib/ucptypetable.c
|
||||
ext/pcre/pcrelib/doc/Tech.Notes
|
||||
ext/pcre/pcrelib/doc/pcre.txt
|
||||
ext/pcre/pcrelib/testdata/grepinput
|
||||
ext/pcre/pcrelib/testdata/grepinputx
|
||||
ext/pcre/pcrelib/testdata/greplist
|
||||
ext/pcre/pcrelib/testdata/grepoutput
|
||||
ext/pcre/pcrelib/testdata/testinput1
|
||||
ext/pcre/pcrelib/testdata/testinput2
|
||||
ext/pcre/pcrelib/testdata/testinput3
|
||||
ext/pcre/pcrelib/testdata/testinput4
|
||||
ext/pcre/pcrelib/testdata/testinput5
|
||||
ext/pcre/pcrelib/testdata/testinput6
|
||||
ext/pcre/pcrelib/testdata/testinput7
|
||||
ext/pcre/pcrelib/testdata/testinput8
|
||||
ext/pcre/pcrelib/testdata/testinput9
|
||||
ext/pcre/pcrelib/testdata/testoutput1
|
||||
ext/pcre/pcrelib/testdata/testoutput2
|
||||
ext/pcre/pcrelib/testdata/testoutput3
|
||||
ext/pcre/pcrelib/testdata/testoutput4
|
||||
ext/pcre/pcrelib/testdata/testoutput5
|
||||
ext/pcre/pcrelib/testdata/testoutput6
|
||||
ext/pcre/pcrelib/testdata/testoutput7
|
||||
ext/pcre/pcrelib/testdata/testoutput8
|
||||
ext/pcre/pcrelib/testdata/testoutput9:
|
||||
Upgrade to PCRE version 6.2.
|
||||
|
||||
|
||||
2005-08-08 Frank M. Kromann <frank@kromann.info>
|
||||
|
||||
* ext/mssql/php_mssql.c:
|
||||
Make sure this works for multiple results as well
|
||||
|
||||
* ext/mssql/php_mssql.c:
|
||||
Remove debug code and optimize a bit
|
||||
|
||||
2005-08-08 Magnus Määttä <novell@kiruna.se>
|
||||
|
||||
* ext/posix/posix.c:
|
||||
makedev is a macro on several systems.
|
||||
|
||||
2005-08-08 Frank M. Kromann <frank@kromann.info>
|
||||
|
||||
* NEWS:
|
||||
|
||||
News entry for Fix #32010
|
||||
|
||||
* ext/mssql/php_mssql.c
|
||||
ext/mssql/php_mssql.h:
|
||||
Fix #32010. Leak in mssql_fetch_batch().
|
||||
|
||||
2005-08-08 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* NEWS:
|
||||
BFNSF
|
||||
|
||||
2005-08-08 Hartmut Holzgraefe <hartmut@php-groupies.de>
|
||||
|
||||
* NEWS:
|
||||
finally!
|
||||
|
||||
cd some_extension
|
||||
phpize
|
||||
configure
|
||||
make
|
||||
make test # <<< THIS WORKS!!! :)
|
||||
|
||||
* (php_5_1_0RC1)
|
||||
Makefile.global:
|
||||
put the -d extension loading options in the right place,
|
||||
get rid of basename
|
||||
|
||||
2005-08-08 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* (php_5_1_0RC1)
|
||||
scripts/phpize.in:
|
||||
Fix cleanup
|
||||
|
||||
* (php_5_1_0RC1)
|
||||
ext/standard/dl.c
|
||||
ext/standard/dl.h
|
||||
main/php_ini.c
|
||||
sapi/cli/php_cli.c:
|
||||
- Fixed problem with -dextension=foobar.so not having it's MINIT run.
|
||||
|
||||
* Makefile.global
|
||||
configure.in
|
||||
scripts/Makefile.frag
|
||||
scripts/php-config.in
|
||||
scripts/phpize.in
|
||||
scripts/phpize.m4:
|
||||
- Made it possible to do "make test" for phpized extensions
|
||||
|
||||
* (php_5_1_0RC1)
|
||||
ZendEngine2/zend_API.c:
|
||||
- Show the dependancy name we could not find (req_mod is null here when it
|
||||
is not found :)
|
||||
|
||||
2005-08-08 Hartmut Holzgraefe <hartmut@php-groupies.de>
|
||||
|
||||
* sapi/cli/php_cli.c:
|
||||
fix extension loading from command line, resources didn't work
|
||||
(still related to Bug #33899)
|
||||
|
||||
2005-08-07 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* NEWS:
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 6.0
|
||||
- cURL improvements (Ilia)
|
||||
. Added curl_setopt_array() which allows setting of multiple cURL options.
|
||||
. Added CURLINFO_HEADER_OUT to facilitate request retrieval.
|
||||
- Added an optional parameter to parse_url() to allow retrieval of distinct URL
|
||||
components. (Ilia)
|
||||
- Added an optional parameter to strstr() and stristr() for retrieval of either
|
||||
the part of haystack before or after first occurence of needle. (Johannes)
|
||||
|
||||
?? ??? 2005, PHP 5.1
|
||||
- Upgraded PCRE library to version 6.2. (Andrei)
|
||||
- Updated bundled libraries in Windows distribution. (Edin)
|
||||
. zlib 1.2.3
|
||||
. curl 7.14.0
|
||||
@@ -10,6 +20,11 @@ PHP NEWS
|
||||
- Fixed "make test" to work for phpized extensions. (Hartmut, Jani)
|
||||
- Fixed failing queries (FALSE returned) with mysqli_query() on 64 bit systems.
|
||||
(Andrey)
|
||||
- Fixed bug #34064 (arr[] as param to function in class gives invalid opcode).
|
||||
(Dmitry)
|
||||
- Fixed bug #34062 (Crash in catch block when many arguments are used).
|
||||
(Dmitry)
|
||||
- Fixed bug #34045 (Buffer overflow with serialized object). (Dmitry)
|
||||
- Fixed bug #33999 (object remains object when cast to int). (Dmitry)
|
||||
- Fixed bug #33996 (No information given for fatal error on passing invalid
|
||||
value to typed argument). (Dmitry)
|
||||
@@ -18,6 +33,8 @@ PHP NEWS
|
||||
(Jani)
|
||||
- Fixed bug #33958 (duplicate cookies and magic_quotes=off may cause a crash).
|
||||
(Ilia)
|
||||
- Fixed bug #33940 (array_map() fails to pass by reference when called
|
||||
recursively). (Dmitry)
|
||||
- Fixed bug #33917 (number_format() output with > 1 char separators). (Jani)
|
||||
- Fixed bug #33904 (input array keys being escaped when magic quotes is off).
|
||||
(Ilia)
|
||||
@@ -38,6 +55,9 @@ PHP NEWS
|
||||
- Fixed bug #32139 (SOAP client does not auto-handle base64 encoding). (Ilia)
|
||||
- Fixed bug #32010 (Memory leak in mssql_fetch_batch). (fmk)
|
||||
- Fixed bug #29334 (win32 mail() provides incorrect Date: header). (Jani)
|
||||
- Fixed bug #29253 (array_diff with $GLOBALS argument fails). (Dmitry)
|
||||
- Fixed bug #25359 (array_multisort() doesn't work in a function if array is
|
||||
global or reference). (Dmitry)
|
||||
|
||||
14 Jul 2005, PHP 5.1 Beta 3
|
||||
- Upgraded bundled SQLite library for PDO:SQLite to 3.2.2 (Ilia)
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
2005-08-09 Derick Rethans <php@derickrethans.nl>
|
||||
|
||||
* zend_extensions.h
|
||||
zend_modules.h:
|
||||
- Changing the API numbers, which might be a bit premature, but it allows
|
||||
to differentiate between different branches.
|
||||
- Bumbed the version number to 6.0.0-dev. I know we didn't discuss this
|
||||
yet,
|
||||
but I feel it should be 6.0. See mail to the mailinglist.
|
||||
|
||||
2005-08-09 Andi Gutmans <andi@zend.com>
|
||||
|
||||
* (PHP_5_1)
|
||||
zend.h:
|
||||
- No release today. Found a critical bug...
|
||||
|
||||
* (PHP_5_1)
|
||||
zend.h:
|
||||
- RC1
|
||||
|
||||
2005-08-08 Jani Taskinen <jani.taskinen@sci.fi>
|
||||
|
||||
* zend_API.c:
|
||||
- Show the dependancy name we could not find (req_mod is null here when it
|
||||
is not found :)
|
||||
|
||||
2005-08-05 Dmitry Stogov <dmitry@zend.com>
|
||||
|
||||
* zend_execute.c
|
||||
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #34045 (Buffer overflow with serialized object)
|
||||
--FILE--
|
||||
<?php
|
||||
class BasicSingleton
|
||||
{
|
||||
private static $instance;
|
||||
|
||||
public function __wakeup() {
|
||||
self::$instance = $this;
|
||||
}
|
||||
|
||||
public static function singleton() {
|
||||
if (!(self::$instance instanceof BasicSingleton)) {
|
||||
$c = __CLASS__;
|
||||
self::$instance = new $c;
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
|
||||
$db = BasicSingleton::singleton();
|
||||
$db_str = serialize($db);
|
||||
$db2 = unserialize($db_str);
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #34064 (arr[] as param to function in class gives invalid opcode)
|
||||
--FILE--
|
||||
<?php
|
||||
class XmlTest {
|
||||
|
||||
function test_ref(&$test)
|
||||
{
|
||||
$test = "ok";
|
||||
}
|
||||
|
||||
function test($test)
|
||||
{
|
||||
}
|
||||
|
||||
function run()
|
||||
{
|
||||
$ar = array();
|
||||
$this->test_ref($ar[]);
|
||||
var_dump($ar);
|
||||
$this->test($ar[]);
|
||||
}
|
||||
}
|
||||
|
||||
$o = new XmlTest();
|
||||
$o->run();
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(2) "ok"
|
||||
}
|
||||
|
||||
Fatal error: Cannot use [] for reading in %sbug34064.php on line 18
|
||||
|
||||
+6
-1
@@ -1499,7 +1499,12 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
|
||||
}
|
||||
|
||||
if (function_ptr) {
|
||||
send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
|
||||
if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) {
|
||||
op = (param->op_type & (IS_VAR|IS_CV))?ZEND_SEND_REF:ZEND_SEND_VAL;
|
||||
send_by_reference = 0;
|
||||
} else {
|
||||
send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
|
||||
}
|
||||
} else {
|
||||
send_by_reference = 0;
|
||||
}
|
||||
|
||||
+22
-2
@@ -648,6 +648,10 @@ int zendlex(znode *zendlval TSRMLS_DC);
|
||||
#define ZEND_ARG_COMPILE_TIME_BOUND (1<<1)
|
||||
#define ZEND_ARG_SEND_FUNCTION (1<<2)
|
||||
|
||||
#define ZEND_SEND_BY_VAL 0
|
||||
#define ZEND_SEND_BY_REF 1
|
||||
#define ZEND_SEND_PREFER_REF 2
|
||||
|
||||
/* Lost In Stupid Parentheses */
|
||||
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
|
||||
( \
|
||||
@@ -657,15 +661,31 @@ int zendlex(znode *zendlval TSRMLS_DC);
|
||||
( \
|
||||
( \
|
||||
arg_num<=((zend_function *) zf)->common.num_args \
|
||||
&& ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference \
|
||||
&& ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_BY_REF \
|
||||
) \
|
||||
|| ( \
|
||||
arg_num>((zend_function *) zf)->common.num_args \
|
||||
&& ((zend_function *) zf)->common.pass_rest_by_reference \
|
||||
&& ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_BY_REF \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
|
||||
( \
|
||||
zf \
|
||||
&& ((zend_function *) zf)->common.arg_info \
|
||||
&& \
|
||||
( \
|
||||
( \
|
||||
arg_num<=((zend_function *) zf)->common.num_args \
|
||||
&& ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_PREFER_REF \
|
||||
) \
|
||||
|| ( \
|
||||
arg_num>((zend_function *) zf)->common.num_args \
|
||||
&& ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_PREFER_REF \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
#define ZEND_RETURN_VAL 0
|
||||
#define ZEND_RETURN_REF 1
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/* The first number is the engine version and the rest is the date.
|
||||
* This way engine 2 API no. is always greater than engine 1 API no..
|
||||
*/
|
||||
#define ZEND_EXTENSION_API_NO 220050617
|
||||
#define ZEND_EXTENSION_API_NO 220050809
|
||||
|
||||
typedef struct _zend_extension_version_info {
|
||||
int zend_extension_api_no;
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ extern struct _zend_arg_info third_arg_force_ref[4];
|
||||
extern struct _zend_arg_info fourth_arg_force_ref[5];
|
||||
extern struct _zend_arg_info all_args_by_ref[1];
|
||||
|
||||
#define ZEND_MODULE_API_NO 20050617
|
||||
#define ZEND_MODULE_API_NO 20050809
|
||||
#ifdef ZTS
|
||||
#define USING_ZTS 1
|
||||
#else
|
||||
|
||||
+13
-4
@@ -1051,7 +1051,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|CV)
|
||||
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
@@ -1075,13 +1075,17 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|CV)
|
||||
ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (OP2_TYPE == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
FREE_OP1_VAR_PTR();
|
||||
@@ -1838,10 +1842,14 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
}
|
||||
|
||||
EG(current_execute_data) = EXECUTE_DATA;
|
||||
|
||||
/* We shouldn't fix bad extensions here,
|
||||
because it can break proper ones (Bug #34045)
|
||||
if (!EX(function_state).function->common.return_reference) {
|
||||
EX_T(opline->result.u.var).var.ptr->is_ref = 0;
|
||||
EX_T(opline->result.u.var).var.ptr->refcount = 1;
|
||||
}
|
||||
*/
|
||||
if (!return_value_used) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
@@ -3571,6 +3579,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
while (*stack_zval_pp != NULL) {
|
||||
zval_ptr_dtor(stack_zval_pp);
|
||||
EG(argument_stack).top_element--;
|
||||
EG(argument_stack).top--;
|
||||
stack_zval_pp--;
|
||||
}
|
||||
|
||||
|
||||
+115
-20
@@ -187,10 +187,14 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
/* We shouldn't fix bad extensions here,
|
||||
because it can break proper ones (Bug #34045)
|
||||
if (!EX(function_state).function->common.return_reference) {
|
||||
EX_T(opline->result.u.var).var.ptr->is_ref = 0;
|
||||
EX_T(opline->result.u.var).var.ptr->refcount = 1;
|
||||
}
|
||||
*/
|
||||
if (!return_value_used) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
@@ -516,6 +520,7 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
while (*stack_zval_pp != NULL) {
|
||||
zval_ptr_dtor(stack_zval_pp);
|
||||
EG(argument_stack).top_element--;
|
||||
EG(argument_stack).top--;
|
||||
stack_zval_pp--;
|
||||
}
|
||||
|
||||
@@ -8525,8 +8530,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = &opline->op2.u.constant;
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = &opline->op2.u.constant;
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
@@ -9941,8 +9950,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, type TSRMLS_CC);
|
||||
zval_dtor(free_op2.var);
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
@@ -11360,8 +11373,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1, free_op2;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
@@ -12355,6 +12372,35 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *dim = NULL;
|
||||
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = NULL;
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@@ -13195,8 +13241,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
@@ -20420,8 +20470,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = &opline->op2.u.constant;
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = &opline->op2.u.constant;
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
|
||||
@@ -21828,8 +21882,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op2;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 1, type TSRMLS_CC);
|
||||
zval_dtor(free_op2.var);
|
||||
|
||||
@@ -23239,8 +23297,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op2;
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
|
||||
|
||||
@@ -24225,6 +24287,35 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
zval *dim = NULL;
|
||||
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
|
||||
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim;
|
||||
|
||||
if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = NULL;
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@@ -25064,8 +25155,12 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
|
||||
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
|
||||
zval *dim;
|
||||
|
||||
if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
|
||||
}
|
||||
dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
|
||||
|
||||
|
||||
@@ -27979,7 +28074,7 @@ void zend_init_opcodes_handlers()
|
||||
ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
@@ -27989,7 +28084,7 @@ void zend_init_opcodes_handlers()
|
||||
ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER,
|
||||
ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
@@ -28129,7 +28224,7 @@ void zend_init_opcodes_handlers()
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
@@ -28139,7 +28234,7 @@ void zend_init_opcodes_handlers()
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER,
|
||||
ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
||||
@@ -38,7 +38,7 @@ if test "$dev" = "0" -a "$devok" = "0"; then
|
||||
fi
|
||||
|
||||
if test -z "$ZENDDIR"; then
|
||||
if grep "PHP_MAJOR_VERSION 5" main/php_version.h >/dev/null; then
|
||||
if grep "PHP_MAJOR_VERSION 6" main/php_version.h >/dev/null; then
|
||||
v=5
|
||||
else
|
||||
v=4
|
||||
|
||||
+2
-2
@@ -39,8 +39,8 @@ PHP_CANONICAL_HOST_TARGET
|
||||
|
||||
AC_CONFIG_HEADER(main/php_config.h)
|
||||
|
||||
MAJOR_VERSION=5
|
||||
MINOR_VERSION=1
|
||||
MAJOR_VERSION=6
|
||||
MINOR_VERSION=0
|
||||
RELEASE_VERSION=0
|
||||
EXTRA_VERSION="-dev"
|
||||
VERSION="$MAJOR_VERSION.$MINOR_VERSION.$RELEASE_VERSION$EXTRA_VERSION"
|
||||
|
||||
+106
-17
@@ -91,6 +91,7 @@ function_entry curl_functions[] = {
|
||||
PHP_FE(curl_copy_handle, NULL)
|
||||
PHP_FE(curl_version, NULL)
|
||||
PHP_FE(curl_setopt, NULL)
|
||||
PHP_FE(curl_setopt_array, NULL)
|
||||
PHP_FE(curl_exec, NULL)
|
||||
PHP_FE(curl_getinfo, NULL)
|
||||
PHP_FE(curl_error, NULL)
|
||||
@@ -293,6 +294,7 @@ PHP_MINIT_FUNCTION(curl)
|
||||
REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE);
|
||||
REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME);
|
||||
REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT);
|
||||
REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT);
|
||||
|
||||
/* cURL protocol constants (curl_version) */
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6);
|
||||
@@ -670,6 +672,23 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int curl_debug(CURL *cp, curl_infotype type, char *buf, size_t buf_len, void *ctx)
|
||||
{
|
||||
php_curl *ch = (php_curl *) ctx;
|
||||
|
||||
if (type == CURLINFO_HEADER_OUT) {
|
||||
if (ch->header.str_len) {
|
||||
efree(ch->header.str);
|
||||
}
|
||||
if (buf_len > 0) {
|
||||
ch->header.str = estrndup(buf, buf_len);
|
||||
ch->header.str_len = buf_len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CURLOPT_PASSWDFUNCTION != 0
|
||||
/* {{{ curl_passwd
|
||||
*/
|
||||
@@ -792,6 +811,7 @@ static void alloc_curl_handle(php_curl **ch)
|
||||
(*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read));
|
||||
|
||||
(*ch)->in_callback = 0;
|
||||
(*ch)->header.str_len = 0;
|
||||
|
||||
memset(&(*ch)->err, 0, sizeof((*ch)->err));
|
||||
|
||||
@@ -900,24 +920,10 @@ PHP_FUNCTION(curl_copy_handle)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool curl_setopt(resource ch, int option, mixed value)
|
||||
Set an option for a CURL transfer */
|
||||
PHP_FUNCTION(curl_setopt)
|
||||
static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *return_value TSRMLS_DC)
|
||||
{
|
||||
zval **zid, **zoption, **zvalue;
|
||||
php_curl *ch;
|
||||
CURLcode error=CURLE_OK;
|
||||
int option;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &zid, &zoption, &zvalue) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl);
|
||||
|
||||
convert_to_long_ex(zoption);
|
||||
|
||||
option = Z_LVAL_PP(zoption);
|
||||
switch (option) {
|
||||
case CURLOPT_INFILESIZE:
|
||||
case CURLOPT_VERBOSE:
|
||||
@@ -1240,15 +1246,81 @@ PHP_FUNCTION(curl_setopt)
|
||||
|
||||
break;
|
||||
}
|
||||
case CURLINFO_HEADER_OUT:
|
||||
convert_to_long_ex(zvalue);
|
||||
if (Z_LVAL_PP(zvalue) == 1) {
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);
|
||||
} else {
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, NULL);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, NULL);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SAVE_CURL_ERROR(ch, error);
|
||||
if (error != CURLE_OK) {
|
||||
RETURN_FALSE;
|
||||
return 1;
|
||||
} else {
|
||||
RETURN_TRUE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto bool curl_setopt(resource ch, int option, mixed value)
|
||||
Set an option for a CURL transfer */
|
||||
PHP_FUNCTION(curl_setopt)
|
||||
{
|
||||
zval **zid, **zoption, **zvalue;
|
||||
php_curl *ch;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &zid, &zoption, &zvalue) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl);
|
||||
|
||||
convert_to_long_ex(zoption);
|
||||
|
||||
if (!_php_curl_setopt(ch, Z_LVAL_PP(zoption), zvalue, return_value TSRMLS_CC)) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool curl_setopt_array(resource ch, array options)
|
||||
Set an array of option for a CURL transfer */
|
||||
PHP_FUNCTION(curl_setopt_array)
|
||||
{
|
||||
zval *zid, *arr, **entry;
|
||||
php_curl *ch;
|
||||
long option;
|
||||
HashPosition pos;
|
||||
char *string_key;
|
||||
int str_key_len;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &zid, &arr) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
|
||||
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&entry, &pos) == SUCCESS) {
|
||||
if (zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &string_key, &str_key_len, &option, 0, &pos) == HASH_KEY_IS_STRING) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array keys must be CURLOPT constants or equivalent interger values.");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (_php_curl_setopt(ch, option, entry, return_value TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos);
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _php_curl_cleanup_handle(ch)
|
||||
@@ -1258,6 +1330,10 @@ void _php_curl_cleanup_handle(php_curl *ch)
|
||||
if (ch->handlers->write->buf.len > 0) {
|
||||
memset(&ch->handlers->write->buf, 0, sizeof(smart_str));
|
||||
}
|
||||
if (ch->header.str_len) {
|
||||
efree(ch->header.str);
|
||||
ch->header.str_len = 0;
|
||||
}
|
||||
|
||||
memset(ch->err.str, 0, CURL_ERROR_SIZE + 1);
|
||||
ch->err.no = 0;
|
||||
@@ -1389,6 +1465,9 @@ PHP_FUNCTION(curl_getinfo)
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) {
|
||||
CAAD("redirect_time", d_code);
|
||||
}
|
||||
if (ch->header.str_len > 0) {
|
||||
CAAS("request_header", ch->header.str);
|
||||
}
|
||||
} else {
|
||||
option = Z_LVAL_PP(zoption);
|
||||
switch (option) {
|
||||
@@ -1439,6 +1518,12 @@ PHP_FUNCTION(curl_getinfo)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CURLINFO_HEADER_OUT:
|
||||
if (ch->header.str_len > 0) {
|
||||
RETURN_STRINGL(ch->header.str, ch->header.str_len, 1);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1532,6 +1617,10 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
if (ch->handlers->passwd) {
|
||||
zval_ptr_dtor(&ch->handlers->passwd);
|
||||
}
|
||||
if (ch->header.str_len > 0) {
|
||||
efree(ch->header.str);
|
||||
}
|
||||
|
||||
efree(ch->handlers->write);
|
||||
efree(ch->handlers->write_header);
|
||||
efree(ch->handlers->read);
|
||||
|
||||
@@ -63,6 +63,7 @@ PHP_FUNCTION(curl_version);
|
||||
PHP_FUNCTION(curl_init);
|
||||
PHP_FUNCTION(curl_copy_handle);
|
||||
PHP_FUNCTION(curl_setopt);
|
||||
PHP_FUNCTION(curl_setopt_array);
|
||||
PHP_FUNCTION(curl_exec);
|
||||
PHP_FUNCTION(curl_getinfo);
|
||||
PHP_FUNCTION(curl_error);
|
||||
@@ -107,6 +108,11 @@ struct _php_curl_error {
|
||||
int no;
|
||||
};
|
||||
|
||||
struct _php_curl_send_headers {
|
||||
char *str;
|
||||
size_t str_len;
|
||||
};
|
||||
|
||||
struct _php_curl_free {
|
||||
zend_llist str;
|
||||
zend_llist post;
|
||||
@@ -116,6 +122,7 @@ struct _php_curl_free {
|
||||
typedef struct {
|
||||
struct _php_curl_error err;
|
||||
struct _php_curl_free to_free;
|
||||
struct _php_curl_send_headers header;
|
||||
void ***thread_ctx;
|
||||
CURL *cp;
|
||||
php_curl_handlers *handlers;
|
||||
|
||||
+80
-78
@@ -1,4 +1,4 @@
|
||||
/* Generated by re2c 0.9.8 on Tue Jul 26 18:01:10 2005 */
|
||||
/* Generated by re2c 0.9.8.dev on Tue Aug 9 23:05:03 2005 */
|
||||
#line 1 "resource/parse_date.re"
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -712,6 +712,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return -1 * timelib_parse_tz_cor(ptr);
|
||||
} else if (**ptr == '-') {
|
||||
@@ -719,6 +720,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return timelib_parse_tz_cor(ptr);
|
||||
} else {
|
||||
@@ -771,7 +773,7 @@ static int scan(Scanner *s)
|
||||
std:
|
||||
s->tok = cursor;
|
||||
s->len = 0;
|
||||
#line 876 "resource/parse_date.re"
|
||||
#line 878 "resource/parse_date.re"
|
||||
|
||||
|
||||
{
|
||||
@@ -810,7 +812,7 @@ std:
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
#line 814 "<stdout>"
|
||||
#line 816 "<stdout>"
|
||||
{
|
||||
YYCTYPE yych;
|
||||
unsigned int yyaccept;
|
||||
@@ -895,7 +897,7 @@ yy2:
|
||||
yy3:
|
||||
YYDEBUG(3, *YYCURSOR);
|
||||
|
||||
#line 1340 "resource/parse_date.re"
|
||||
#line 1342 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
TIMELIB_INIT;
|
||||
@@ -904,7 +906,7 @@ yy3:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_TIMEZONE;
|
||||
}
|
||||
#line 901 "<stdout>"
|
||||
#line 903 "<stdout>"
|
||||
yy4:
|
||||
YYDEBUG(4, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -990,13 +992,13 @@ yy6:
|
||||
yy7:
|
||||
YYDEBUG(7, *YYCURSOR);
|
||||
|
||||
#line 1404 "resource/parse_date.re"
|
||||
#line 1406 "resource/parse_date.re"
|
||||
{
|
||||
/* printf("unexpected character: #%d, %c ", *s->tok, *s->tok); */
|
||||
s->errors++;
|
||||
goto std;
|
||||
}
|
||||
#line 984 "<stdout>"
|
||||
#line 986 "<stdout>"
|
||||
yy8:
|
||||
YYDEBUG(8, *YYCURSOR);
|
||||
yyaccept = 0;
|
||||
@@ -1919,11 +1921,11 @@ yy43:
|
||||
yy44:
|
||||
YYDEBUG(44, *YYCURSOR);
|
||||
|
||||
#line 1393 "resource/parse_date.re"
|
||||
#line 1395 "resource/parse_date.re"
|
||||
{
|
||||
goto std;
|
||||
}
|
||||
#line 1832 "<stdout>"
|
||||
#line 1834 "<stdout>"
|
||||
yy45:
|
||||
YYDEBUG(45, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1931,12 +1933,12 @@ yy45:
|
||||
yy46:
|
||||
YYDEBUG(46, *YYCURSOR);
|
||||
|
||||
#line 1398 "resource/parse_date.re"
|
||||
#line 1400 "resource/parse_date.re"
|
||||
{
|
||||
s->pos = cursor; s->line++;
|
||||
goto std;
|
||||
}
|
||||
#line 1841 "<stdout>"
|
||||
#line 1843 "<stdout>"
|
||||
yy47:
|
||||
YYDEBUG(47, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -2394,7 +2396,7 @@ yy84:
|
||||
yy85:
|
||||
YYDEBUG(85, *YYCURSOR);
|
||||
|
||||
#line 1377 "resource/parse_date.re"
|
||||
#line 1379 "resource/parse_date.re"
|
||||
{
|
||||
timelib_ull i;
|
||||
|
||||
@@ -2409,7 +2411,7 @@ yy85:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 2231 "<stdout>"
|
||||
#line 2233 "<stdout>"
|
||||
yy86:
|
||||
YYDEBUG(86, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -3102,11 +3104,11 @@ yy150:
|
||||
yy151:
|
||||
YYDEBUG(151, *YYCURSOR);
|
||||
|
||||
#line 1335 "resource/parse_date.re"
|
||||
#line 1337 "resource/parse_date.re"
|
||||
{
|
||||
goto std;
|
||||
}
|
||||
#line 2794 "<stdout>"
|
||||
#line 2796 "<stdout>"
|
||||
yy152:
|
||||
YYDEBUG(152, *YYCURSOR);
|
||||
yyaccept = 1;
|
||||
@@ -3145,7 +3147,7 @@ yy157:
|
||||
yy158:
|
||||
YYDEBUG(158, *YYCURSOR);
|
||||
|
||||
#line 1319 "resource/parse_date.re"
|
||||
#line 1321 "resource/parse_date.re"
|
||||
{
|
||||
const timelib_relunit* relunit;
|
||||
|
||||
@@ -3160,7 +3162,7 @@ yy158:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 2834 "<stdout>"
|
||||
#line 2836 "<stdout>"
|
||||
yy159:
|
||||
YYDEBUG(159, *YYCURSOR);
|
||||
yyaccept = 1;
|
||||
@@ -3529,7 +3531,7 @@ yy189:
|
||||
yy190:
|
||||
YYDEBUG(190, *YYCURSOR);
|
||||
|
||||
#line 1303 "resource/parse_date.re"
|
||||
#line 1305 "resource/parse_date.re"
|
||||
{
|
||||
timelib_sll i;
|
||||
|
||||
@@ -3544,7 +3546,7 @@ yy190:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 3152 "<stdout>"
|
||||
#line 3154 "<stdout>"
|
||||
yy191:
|
||||
YYDEBUG(191, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -9174,7 +9176,7 @@ yy508:
|
||||
yy509:
|
||||
YYDEBUG(509, *YYCURSOR);
|
||||
|
||||
#line 1135 "resource/parse_date.re"
|
||||
#line 1137 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -9185,7 +9187,7 @@ yy509:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_TEXT;
|
||||
}
|
||||
#line 8144 "<stdout>"
|
||||
#line 8146 "<stdout>"
|
||||
yy510:
|
||||
YYDEBUG(510, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -9317,7 +9319,7 @@ yy526:
|
||||
yy527:
|
||||
YYDEBUG(527, *YYCURSOR);
|
||||
|
||||
#line 1350 "resource/parse_date.re"
|
||||
#line 1352 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
TIMELIB_INIT;
|
||||
@@ -9343,7 +9345,7 @@ yy527:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_SHORTDATE_WITH_TIME;
|
||||
}
|
||||
#line 8266 "<stdout>"
|
||||
#line 8268 "<stdout>"
|
||||
yy528:
|
||||
YYDEBUG(528, *YYCURSOR);
|
||||
yyaccept = 7;
|
||||
@@ -9651,7 +9653,7 @@ yy561:
|
||||
yy562:
|
||||
YYDEBUG(562, *YYCURSOR);
|
||||
|
||||
#line 1111 "resource/parse_date.re"
|
||||
#line 1113 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -9662,7 +9664,7 @@ yy562:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_NO_DAY;
|
||||
}
|
||||
#line 8515 "<stdout>"
|
||||
#line 8517 "<stdout>"
|
||||
yy563:
|
||||
YYDEBUG(563, *YYCURSOR);
|
||||
yyaccept = 6;
|
||||
@@ -9792,7 +9794,7 @@ yy576:
|
||||
yy577:
|
||||
YYDEBUG(577, *YYCURSOR);
|
||||
|
||||
#line 1239 "resource/parse_date.re"
|
||||
#line 1241 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -9803,7 +9805,7 @@ yy577:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_PG_TEXT;
|
||||
}
|
||||
#line 8626 "<stdout>"
|
||||
#line 8628 "<stdout>"
|
||||
yy578:
|
||||
YYDEBUG(578, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -11300,7 +11302,7 @@ yy672:
|
||||
yy673:
|
||||
YYDEBUG(673, *YYCURSOR);
|
||||
|
||||
#line 1289 "resource/parse_date.re"
|
||||
#line 1291 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
s->time->relative.y = 0 - s->time->relative.y;
|
||||
@@ -11313,7 +11315,7 @@ yy673:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_AGO;
|
||||
}
|
||||
#line 9944 "<stdout>"
|
||||
#line 9946 "<stdout>"
|
||||
yy674:
|
||||
YYDEBUG(674, *YYCURSOR);
|
||||
yyaccept = 1;
|
||||
@@ -13243,7 +13245,7 @@ yy776:
|
||||
yy777:
|
||||
YYDEBUG(777, *YYCURSOR);
|
||||
|
||||
#line 1147 "resource/parse_date.re"
|
||||
#line 1149 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -13252,7 +13254,7 @@ yy777:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_TEXT;
|
||||
}
|
||||
#line 11671 "<stdout>"
|
||||
#line 11673 "<stdout>"
|
||||
yy778:
|
||||
YYDEBUG(778, *YYCURSOR);
|
||||
yyaccept = 10;
|
||||
@@ -13341,7 +13343,7 @@ yy785:
|
||||
yy786:
|
||||
YYDEBUG(786, *YYCURSOR);
|
||||
|
||||
#line 963 "resource/parse_date.re"
|
||||
#line 965 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
|
||||
@@ -13364,7 +13366,7 @@ yy786:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_TIME24_WITH_ZONE;
|
||||
}
|
||||
#line 11765 "<stdout>"
|
||||
#line 11767 "<stdout>"
|
||||
yy787:
|
||||
YYDEBUG(787, *YYCURSOR);
|
||||
yyaccept = 11;
|
||||
@@ -13491,7 +13493,7 @@ yy800:
|
||||
yy801:
|
||||
YYDEBUG(801, *YYCURSOR);
|
||||
|
||||
#line 948 "resource/parse_date.re"
|
||||
#line 950 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("timeshort12 | timelong12");
|
||||
TIMELIB_INIT;
|
||||
@@ -13505,7 +13507,7 @@ yy801:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_TIME12;
|
||||
}
|
||||
#line 11876 "<stdout>"
|
||||
#line 11878 "<stdout>"
|
||||
yy802:
|
||||
YYDEBUG(802, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -13627,7 +13629,7 @@ yy813:
|
||||
yy814:
|
||||
YYDEBUG(814, *YYCURSOR);
|
||||
|
||||
#line 1087 "resource/parse_date.re"
|
||||
#line 1089 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -13638,7 +13640,7 @@ yy814:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_FULL;
|
||||
}
|
||||
#line 11983 "<stdout>"
|
||||
#line 11985 "<stdout>"
|
||||
yy815:
|
||||
YYDEBUG(815, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -14000,7 +14002,7 @@ yy855:
|
||||
yy856:
|
||||
YYDEBUG(856, *YYCURSOR);
|
||||
|
||||
#line 1099 "resource/parse_date.re"
|
||||
#line 1101 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -14011,7 +14013,7 @@ yy856:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_FULL_POINTED;
|
||||
}
|
||||
#line 12272 "<stdout>"
|
||||
#line 12274 "<stdout>"
|
||||
yy857:
|
||||
YYDEBUG(857, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -14738,7 +14740,7 @@ yy922:
|
||||
yy923:
|
||||
YYDEBUG(923, *YYCURSOR);
|
||||
|
||||
#line 1075 "resource/parse_date.re"
|
||||
#line 1077 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -14749,7 +14751,7 @@ yy923:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_ISO_DATE;
|
||||
}
|
||||
#line 12876 "<stdout>"
|
||||
#line 12878 "<stdout>"
|
||||
yy924:
|
||||
YYDEBUG(924, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -14771,7 +14773,7 @@ yy926:
|
||||
yy927:
|
||||
YYDEBUG(927, *YYCURSOR);
|
||||
|
||||
#line 1050 "resource/parse_date.re"
|
||||
#line 1052 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -14784,7 +14786,7 @@ yy927:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_AMERICAN;
|
||||
}
|
||||
#line 12903 "<stdout>"
|
||||
#line 12905 "<stdout>"
|
||||
yy928:
|
||||
YYDEBUG(928, *YYCURSOR);
|
||||
yyaccept = 12;
|
||||
@@ -15006,7 +15008,7 @@ yy959:
|
||||
yy960:
|
||||
YYDEBUG(960, *YYCURSOR);
|
||||
|
||||
#line 1263 "resource/parse_date.re"
|
||||
#line 1265 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
TIMELIB_INIT;
|
||||
@@ -15023,7 +15025,7 @@ yy960:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_CLF;
|
||||
}
|
||||
#line 13076 "<stdout>"
|
||||
#line 13078 "<stdout>"
|
||||
yy961:
|
||||
YYDEBUG(961, *YYCURSOR);
|
||||
yyaccept = 13;
|
||||
@@ -15332,7 +15334,7 @@ yy999:
|
||||
yy1000:
|
||||
YYDEBUG(1000, *YYCURSOR);
|
||||
|
||||
#line 1251 "resource/parse_date.re"
|
||||
#line 1253 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -15343,7 +15345,7 @@ yy1000:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_PG_TEXT;
|
||||
}
|
||||
#line 13315 "<stdout>"
|
||||
#line 13317 "<stdout>"
|
||||
yy1001:
|
||||
YYDEBUG(1001, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -15476,14 +15478,14 @@ yy1011:
|
||||
yy1012:
|
||||
YYDEBUG(1012, *YYCURSOR);
|
||||
|
||||
#line 1281 "resource/parse_date.re"
|
||||
#line 1283 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
s->time->y = timelib_get_nr((char **) &ptr, 4);
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_CLF;
|
||||
}
|
||||
#line 13430 "<stdout>"
|
||||
#line 13432 "<stdout>"
|
||||
yy1013:
|
||||
YYDEBUG(1013, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -15618,7 +15620,7 @@ yy1020:
|
||||
yy1021:
|
||||
YYDEBUG(1021, *YYCURSOR);
|
||||
|
||||
#line 1123 "resource/parse_date.re"
|
||||
#line 1125 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -15629,7 +15631,7 @@ yy1021:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_NO_DAY;
|
||||
}
|
||||
#line 13555 "<stdout>"
|
||||
#line 13557 "<stdout>"
|
||||
yy1022:
|
||||
YYDEBUG(1022, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -15838,7 +15840,7 @@ yy1040:
|
||||
yy1041:
|
||||
YYDEBUG(1041, *YYCURSOR);
|
||||
|
||||
#line 1220 "resource/parse_date.re"
|
||||
#line 1222 "resource/parse_date.re"
|
||||
{
|
||||
timelib_sll w, d;
|
||||
|
||||
@@ -15856,7 +15858,7 @@ yy1041:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_ISO_WEEK;
|
||||
}
|
||||
#line 13742 "<stdout>"
|
||||
#line 13744 "<stdout>"
|
||||
yy1042:
|
||||
YYDEBUG(1042, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -15864,7 +15866,7 @@ yy1042:
|
||||
yy1043:
|
||||
YYDEBUG(1043, *YYCURSOR);
|
||||
|
||||
#line 1201 "resource/parse_date.re"
|
||||
#line 1203 "resource/parse_date.re"
|
||||
{
|
||||
timelib_sll w, d;
|
||||
|
||||
@@ -15882,7 +15884,7 @@ yy1043:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_ISO_WEEK;
|
||||
}
|
||||
#line 13764 "<stdout>"
|
||||
#line 13766 "<stdout>"
|
||||
yy1044:
|
||||
YYDEBUG(1044, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -15951,7 +15953,7 @@ yy1046:
|
||||
yy1047:
|
||||
YYDEBUG(1047, *YYCURSOR);
|
||||
|
||||
#line 1189 "resource/parse_date.re"
|
||||
#line 1191 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -15962,7 +15964,7 @@ yy1047:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_PG_YEARDAY;
|
||||
}
|
||||
#line 13836 "<stdout>"
|
||||
#line 13838 "<stdout>"
|
||||
yy1048:
|
||||
YYDEBUG(1048, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -16077,7 +16079,7 @@ yy1053:
|
||||
yy1054:
|
||||
YYDEBUG(1054, *YYCURSOR);
|
||||
|
||||
#line 1157 "resource/parse_date.re"
|
||||
#line 1159 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -16087,7 +16089,7 @@ yy1054:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_DATE_NOCOLON;
|
||||
}
|
||||
#line 13943 "<stdout>"
|
||||
#line 13945 "<stdout>"
|
||||
yy1055:
|
||||
YYDEBUG(1055, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -16185,7 +16187,7 @@ yy1064:
|
||||
yy1065:
|
||||
YYDEBUG(1065, *YYCURSOR);
|
||||
|
||||
#line 1168 "resource/parse_date.re"
|
||||
#line 1170 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
TIMELIB_INIT;
|
||||
@@ -16205,7 +16207,7 @@ yy1065:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_XMLRPC_SOAP;
|
||||
}
|
||||
#line 14039 "<stdout>"
|
||||
#line 14041 "<stdout>"
|
||||
yy1066:
|
||||
YYDEBUG(1066, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -16822,7 +16824,7 @@ yy1158:
|
||||
yy1159:
|
||||
YYDEBUG(1159, *YYCURSOR);
|
||||
|
||||
#line 1064 "resource/parse_date.re"
|
||||
#line 1066 "resource/parse_date.re"
|
||||
{
|
||||
TIMELIB_INIT;
|
||||
TIMELIB_HAVE_DATE();
|
||||
@@ -16832,7 +16834,7 @@ yy1159:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_ISO_DATE;
|
||||
}
|
||||
#line 14478 "<stdout>"
|
||||
#line 14480 "<stdout>"
|
||||
yy1160:
|
||||
YYDEBUG(1160, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -17507,7 +17509,7 @@ yy1235:
|
||||
yy1236:
|
||||
YYDEBUG(1236, *YYCURSOR);
|
||||
|
||||
#line 987 "resource/parse_date.re"
|
||||
#line 989 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("gnunocolon");
|
||||
TIMELIB_INIT;
|
||||
@@ -17528,7 +17530,7 @@ yy1236:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_GNU_NOCOLON;
|
||||
}
|
||||
#line 15018 "<stdout>"
|
||||
#line 15020 "<stdout>"
|
||||
yy1237:
|
||||
YYDEBUG(1237, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -17625,7 +17627,7 @@ yy1243:
|
||||
yy1244:
|
||||
YYDEBUG(1244, *YYCURSOR);
|
||||
|
||||
#line 1032 "resource/parse_date.re"
|
||||
#line 1034 "resource/parse_date.re"
|
||||
{
|
||||
int tz_not_found;
|
||||
DEBUG_OUTPUT("iso8601nocolon");
|
||||
@@ -17642,7 +17644,7 @@ yy1244:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_ISO_NOCOLON;
|
||||
}
|
||||
#line 15116 "<stdout>"
|
||||
#line 15118 "<stdout>"
|
||||
yy1245:
|
||||
YYDEBUG(1245, *YYCURSOR);
|
||||
yyaccept = 21;
|
||||
@@ -17854,7 +17856,7 @@ yy1260:
|
||||
yy1261:
|
||||
YYDEBUG(1261, *YYCURSOR);
|
||||
|
||||
#line 924 "resource/parse_date.re"
|
||||
#line 926 "resource/parse_date.re"
|
||||
{
|
||||
timelib_ull i;
|
||||
|
||||
@@ -17877,7 +17879,7 @@ yy1261:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 15311 "<stdout>"
|
||||
#line 15313 "<stdout>"
|
||||
yy1262:
|
||||
YYDEBUG(1262, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -17948,7 +17950,7 @@ yy1269:
|
||||
yy1270:
|
||||
YYDEBUG(1270, *YYCURSOR);
|
||||
|
||||
#line 912 "resource/parse_date.re"
|
||||
#line 914 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("tomorrow");
|
||||
TIMELIB_INIT;
|
||||
@@ -17959,7 +17961,7 @@ yy1270:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 15375 "<stdout>"
|
||||
#line 15377 "<stdout>"
|
||||
yy1271:
|
||||
YYDEBUG(1271, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -17972,7 +17974,7 @@ yy1272:
|
||||
yy1273:
|
||||
YYDEBUG(1273, *YYCURSOR);
|
||||
|
||||
#line 902 "resource/parse_date.re"
|
||||
#line 904 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("today");
|
||||
TIMELIB_INIT;
|
||||
@@ -17981,7 +17983,7 @@ yy1273:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 15391 "<stdout>"
|
||||
#line 15393 "<stdout>"
|
||||
yy1274:
|
||||
YYDEBUG(1274, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -18015,7 +18017,7 @@ yy1275:
|
||||
yy1276:
|
||||
YYDEBUG(1276, *YYCURSOR);
|
||||
|
||||
#line 893 "resource/parse_date.re"
|
||||
#line 895 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("now");
|
||||
TIMELIB_INIT;
|
||||
@@ -18023,7 +18025,7 @@ yy1276:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 15427 "<stdout>"
|
||||
#line 15429 "<stdout>"
|
||||
yy1277:
|
||||
YYDEBUG(1277, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -18081,7 +18083,7 @@ yy1284:
|
||||
yy1285:
|
||||
YYDEBUG(1285, *YYCURSOR);
|
||||
|
||||
#line 881 "resource/parse_date.re"
|
||||
#line 883 "resource/parse_date.re"
|
||||
{
|
||||
DEBUG_OUTPUT("yesterday");
|
||||
TIMELIB_INIT;
|
||||
@@ -18092,10 +18094,10 @@ yy1285:
|
||||
TIMELIB_DEINIT;
|
||||
return TIMELIB_RELATIVE;
|
||||
}
|
||||
#line 15478 "<stdout>"
|
||||
#line 15480 "<stdout>"
|
||||
}
|
||||
}
|
||||
#line 1409 "resource/parse_date.re"
|
||||
#line 1411 "resource/parse_date.re"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -710,6 +710,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return -1 * timelib_parse_tz_cor(ptr);
|
||||
} else if (**ptr == '-') {
|
||||
@@ -717,6 +718,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return timelib_parse_tz_cor(ptr);
|
||||
} else {
|
||||
|
||||
@@ -710,6 +710,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return -1 * timelib_parse_tz_cor(ptr);
|
||||
} else if (**ptr == '-') {
|
||||
@@ -717,6 +718,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_
|
||||
t->is_localtime = 1;
|
||||
t->zone_type = TIMELIB_ZONETYPE_OFFSET;
|
||||
*tz_not_found = 0;
|
||||
t->dst = 0;
|
||||
|
||||
return timelib_parse_tz_cor(ptr);
|
||||
} else {
|
||||
|
||||
+8
-5
@@ -88,11 +88,13 @@ function_entry date_funcs_timezone[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static void date_register_classes(void);
|
||||
# define DATE_REGISTER_CLASSES date_register_classes()
|
||||
static void date_register_classes(TSRMLS_D);
|
||||
# define DATE_REGISTER_CLASSES date_register_classes(TSRMLS_C)
|
||||
#else
|
||||
# define DATE_REGISTER_CLASSES /* */
|
||||
#endif
|
||||
|
||||
static char* guess_timezone(TSRMLS_D);
|
||||
/* }}} */
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(date)
|
||||
@@ -237,7 +239,10 @@ PHP_MINFO_FUNCTION(date)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row(2, "date/time support", "enabled");
|
||||
php_info_print_table_row(2, "Default timezone", guess_timezone(TSRMLS_C));
|
||||
php_info_print_table_end();
|
||||
|
||||
DISPLAY_INI_ENTRIES();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -925,7 +930,6 @@ PHP_FUNCTION(getdate)
|
||||
static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
php_date_obj *intern;
|
||||
zval *tmp;
|
||||
zend_object_value retval;
|
||||
|
||||
intern = emalloc(sizeof(php_date_obj));
|
||||
@@ -941,7 +945,6 @@ static zend_object_value date_object_new_date(zend_class_entry *class_type TSRML
|
||||
static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
php_timezone_obj *intern;
|
||||
zval *tmp;
|
||||
zend_object_value retval;
|
||||
|
||||
intern = emalloc(sizeof(php_timezone_obj));
|
||||
@@ -975,7 +978,7 @@ static void date_object_free_storage_timezone(void *object TSRMLS_DC)
|
||||
efree(object);
|
||||
}
|
||||
|
||||
static void date_register_classes(void)
|
||||
static void date_register_classes(TSRMLS_D)
|
||||
{
|
||||
zend_class_entry ce_date, ce_timezone;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ wanted=Tuesday 00:00:00
|
||||
|
||||
TZ=America/Port-au-Prince - wrong day.
|
||||
tStamp=Monday 2005-03-28 17:17:17 EST 0
|
||||
result=Monday 2005-04-04 00:00:00 EST 0
|
||||
result=Monday 2005-04-04 00:00:00 EDT 1
|
||||
wanted=Monday 00:00:00
|
||||
|
||||
TZ=Pacific/Enderbury - wrong day, off by 2 days.
|
||||
@@ -102,7 +102,7 @@ wanted=Monday 00:00:00
|
||||
|
||||
TZ=America/Managua - wrong day.
|
||||
tStamp=Tuesday 2005-04-05 17:17:17 CST 0
|
||||
result=Tuesday 2005-04-12 00:00:00 CST 0
|
||||
result=Tuesday 2005-04-12 00:00:00 CDT 1
|
||||
wanted=Tuesday 00:00:00
|
||||
|
||||
TZ=Pacific/Pitcairn - wrong day.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
date_create() function [3]
|
||||
--FILE--
|
||||
<?php
|
||||
date_default_timezone_set("GMT");
|
||||
echo date_format(date_create("Dec31 2005 +0100"), DATE_ISO8601), "\n";
|
||||
echo date(DATE_ISO8601, strtotime("Dec31 2005 +0100")), "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
2005-12-31T00:00:00+0100
|
||||
2005-12-31T00:00:00+0100
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
mktime()
|
||||
mktime() [2]
|
||||
--INI--
|
||||
error_reporting=2047
|
||||
--FILE--
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
enchant
|
||||
Pierre-Alain Joye, Ilia Alshanetsky
|
||||
@@ -1,36 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
PHP_ARG_WITH(enchant,for ENCHANT support,
|
||||
[ --with-enchant[=DIR] Include enchant support.
|
||||
GNU Aspell version 1.1.3 or higher required.])
|
||||
|
||||
if test "$PHP_ENCHANT" != "no"; then
|
||||
PHP_NEW_EXTENSION(enchant, enchant.c, $ext_shared)
|
||||
if test "$PHP_ENCHANT" != "yes"; then
|
||||
ENCHANT_SEARCH_DIRS=$PHP_ENCHANT
|
||||
else
|
||||
ENCHANT_SEARCH_DIRS="/usr/local /usr"
|
||||
fi
|
||||
for i in $ENCHANT_SEARCH_DIRS; do
|
||||
if test -f $i/include/enchant/enchant.h; then
|
||||
ENCHANT_DIR=$i
|
||||
ENCHANT_INCDIR=$i/include/enchant
|
||||
elif test -f $i/include/enchant.h; then
|
||||
ENCHANT_DIR=$i
|
||||
ENCHANT_INCDIR=$i/include
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$ENCHANT_DIR"; then
|
||||
AC_MSG_ERROR(Cannot find enchant)
|
||||
fi
|
||||
|
||||
ENCHANT_LIBDIR=$ENCHANT_DIR/lib
|
||||
|
||||
AC_DEFINE(HAVE_ENCHANT,1,[ ])
|
||||
PHP_SUBST(ENCHANT_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(enchant, $ENCHANT_LIBDIR, ENCHANT_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($ENCHANT_INCDIR)
|
||||
fi
|
||||
@@ -1,13 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_ENABLE("enchant", "Enchant Support", "no");
|
||||
|
||||
if (PHP_ENCHANT == "yes") {
|
||||
if (CHECK_HEADER_ADD_INCLUDE("enchant.h", "CFLAGS_ENCHANT", PHP_ENCHANT)) {
|
||||
EXTENSION("enchant", "enchant.c");
|
||||
AC_DEFINE('HAVE_ENCHANT', 1, 'Have Enchant support', false);
|
||||
} else {
|
||||
WARNING('Could not find enchant.h; skipping');
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
$tag = 'en_US';
|
||||
$r = enchant_broker_init();
|
||||
$bprovides = enchant_broker_describe($r);
|
||||
echo "Current broker provides the following backend(s):\n";
|
||||
print_r($bprovides);
|
||||
|
||||
|
||||
if (enchant_broker_dict_exists($r,$tag)) {
|
||||
$d = enchant_broker_request_dict($r, $tag);
|
||||
$dprovides = enchant_dict_describe($d);
|
||||
echo "dictionary $tag provides:\n";
|
||||
$spellerrors = enchant_dict_check($d, "soong");
|
||||
print_r($dprovides);
|
||||
echo "found $spellerrors spell errors\n";
|
||||
if ($spellerrors) {
|
||||
$suggs = enchant_dict_suggest($d, "soong");
|
||||
echo "Suggestions for 'soong':";
|
||||
print_r($suggs);
|
||||
}
|
||||
enchant_broker_free_dict($d);
|
||||
} else {
|
||||
}
|
||||
enchant_broker_free($r);
|
||||
?>
|
||||
@@ -1,731 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Pierre-Alain Joye <paj@pearfr.org> |
|
||||
| Ilia Alshanetsky <ilia@prohost.org> |
|
||||
+----------------------------------------------------------------------+
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "enchant.h"
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "php_enchant.h"
|
||||
|
||||
|
||||
typedef EnchantBroker * EnchantBrokerPtr;
|
||||
typedef struct _broker_struct enchant_broker;
|
||||
typedef struct _dict_struct enchant_dict;
|
||||
|
||||
typedef enchant_broker * enchant_brokerPtr;
|
||||
typedef enchant_dict * enchant_dictPtr;
|
||||
|
||||
typedef struct _broker_struct {
|
||||
EnchantBroker *pbroker;
|
||||
enchant_dict **dict;
|
||||
unsigned int dictcnt;
|
||||
zval *rsrc_id;
|
||||
} _enchant_broker;
|
||||
|
||||
typedef struct _dict_struct {
|
||||
unsigned int id;
|
||||
EnchantDict *pdict;
|
||||
enchant_broker *pbroker;
|
||||
zval *rsrc_id;
|
||||
enchant_dict *next;
|
||||
enchant_dict *prev;
|
||||
} _enchant_dict;
|
||||
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_enchant_broker;
|
||||
static int le_enchant_dict;
|
||||
|
||||
/* If you declare any globals in php_enchant.h uncomment this:*/
|
||||
/*ZEND_DECLARE_MODULE_GLOBALS(enchant)*/
|
||||
|
||||
/* {{{ enchant_functions[]
|
||||
*
|
||||
* Every user visible function must have an entry in enchant_functions[].
|
||||
*/
|
||||
function_entry enchant_functions[] = {
|
||||
PHP_FE(enchant_broker_init, NULL)
|
||||
PHP_FE(enchant_broker_free, NULL)
|
||||
PHP_FE(enchant_broker_get_error, NULL)
|
||||
PHP_FE(enchant_broker_request_dict, NULL)
|
||||
PHP_FE(enchant_broker_request_pwl_dict, NULL)
|
||||
PHP_FE(enchant_broker_free_dict, NULL)
|
||||
PHP_FE(enchant_broker_dict_exists, NULL)
|
||||
PHP_FE(enchant_broker_set_ordering, NULL)
|
||||
PHP_FE(enchant_broker_describe, NULL)
|
||||
PHP_FE(enchant_dict_check, NULL)
|
||||
PHP_FE(enchant_dict_suggest, NULL)
|
||||
PHP_FE(enchant_dict_add_to_personal, NULL)
|
||||
PHP_FE(enchant_dict_add_to_session, NULL)
|
||||
PHP_FE(enchant_dict_is_in_session, NULL)
|
||||
PHP_FE(enchant_dict_store_replacement, NULL)
|
||||
PHP_FE(enchant_dict_get_error, NULL)
|
||||
PHP_FE(enchant_dict_describe, NULL)
|
||||
PHP_FE(enchant_dict_quick_check, third_arg_force_ref)
|
||||
|
||||
{NULL, NULL, NULL} /* Must be the last line in enchant_functions[] */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ enchant_module_entry
|
||||
*/
|
||||
zend_module_entry enchant_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"enchant",
|
||||
enchant_functions,
|
||||
PHP_MINIT(enchant),
|
||||
PHP_MSHUTDOWN(enchant),
|
||||
NULL, /* Replace with NULL if there's nothing to do at request start */
|
||||
NULL, /* Replace with NULL if there's nothing to do at request end */
|
||||
PHP_MINFO(enchant),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
"0.1", /* Replace with version number for your extension */
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_ENCHANT
|
||||
ZEND_GET_MODULE(enchant)
|
||||
#endif
|
||||
|
||||
static void
|
||||
enumerate_providers_fn (const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
zval *zdesc = (zval *) ud;
|
||||
zval *tmp_array;
|
||||
|
||||
MAKE_STD_ZVAL(tmp_array);
|
||||
array_init(tmp_array);
|
||||
|
||||
add_assoc_string(tmp_array, "name", (char *)name, 1);
|
||||
add_assoc_string(tmp_array, "desc", (char *)desc, 1);
|
||||
add_assoc_string(tmp_array, "file", (char *)file, 1);
|
||||
|
||||
if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
|
||||
array_init(zdesc);
|
||||
}
|
||||
|
||||
add_next_index_zval(zdesc, tmp_array);
|
||||
}
|
||||
|
||||
static void
|
||||
describe_dict_fn (const char * const lang,
|
||||
const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
zval *zdesc = (zval *) ud;
|
||||
array_init(zdesc);
|
||||
add_assoc_string(zdesc, "lang", (char *)lang, 1);
|
||||
add_assoc_string(zdesc, "name", (char *)name, 1);
|
||||
add_assoc_string(zdesc, "desc", (char *)desc, 1);
|
||||
add_assoc_string(zdesc, "file", (char *)file, 1);
|
||||
}
|
||||
|
||||
static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
enchant_broker *broker = (enchant_broker *)rsrc->ptr;
|
||||
if (broker) {
|
||||
if (broker->pbroker) {
|
||||
if (broker->dictcnt && broker->dict) {
|
||||
if (broker->dict) {
|
||||
int total, tofree;
|
||||
tofree = total = broker->dictcnt-1;
|
||||
do {
|
||||
zend_list_delete(Z_RESVAL_P(broker->dict[total]->rsrc_id));
|
||||
efree(broker->dict[total]);
|
||||
total--;
|
||||
} while (total>=0);
|
||||
}
|
||||
efree(broker->dict);
|
||||
broker->dict = NULL;
|
||||
}
|
||||
enchant_broker_free(broker->pbroker);
|
||||
}
|
||||
efree(broker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
enchant_dict *pdict = (enchant_dict *)rsrc->ptr;
|
||||
if (pdict) {
|
||||
if (pdict->pdict && pdict->pbroker) {
|
||||
enchant_broker_free_dict(pdict->pbroker->pbroker, pdict->pdict);
|
||||
}
|
||||
if (pdict->id) {
|
||||
pdict->pbroker->dict[pdict->id-1]->next = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(enchant)
|
||||
{
|
||||
le_enchant_broker = zend_register_list_destructors_ex(php_enchant_broker_free, NULL, "enchant broker", module_number);
|
||||
le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant dict", module_number);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(enchant)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
static void __enumerate_providers_fn (const char * const name,
|
||||
const char * const desc,
|
||||
const char * const file,
|
||||
void * ud)
|
||||
{
|
||||
php_info_print_table_row(3, name, desc, file);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(enchant)
|
||||
{
|
||||
EnchantBroker *pbroker;
|
||||
|
||||
pbroker = enchant_broker_init();
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "enchant support", "enabled");
|
||||
php_info_print_table_row(2, "Version", "@version@");
|
||||
php_info_print_table_row(2, "Revision", "$Revision$");
|
||||
php_info_print_table_end();
|
||||
|
||||
php_info_print_table_start();
|
||||
enchant_broker_describe(pbroker, __enumerate_providers_fn, NULL);
|
||||
php_info_print_table_end();
|
||||
enchant_broker_free(pbroker);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define PHP_ENCHANT_GET_BROKER \
|
||||
ZEND_FETCH_RESOURCE(pbroker, enchant_broker *, &broker, -1, "enchant_broker", le_enchant_broker); \
|
||||
if (!pbroker || !pbroker->pbroker) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Resource broker invalid"); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
#define PHP_ENCHANT_GET_DICT \
|
||||
ZEND_FETCH_RESOURCE(pdict, enchant_dict *, &dict, -1, "enchant dict", le_enchant_dict); \
|
||||
if (!pdict || !pdict->pdict) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Invalid dictionary resource."); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
/* {{{ proto resource enchant_broker_init()
|
||||
create a new broker object capable of requesting */
|
||||
PHP_FUNCTION(enchant_broker_init)
|
||||
{
|
||||
enchant_broker *broker;
|
||||
EnchantBroker *pbroker;
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
ZEND_WRONG_PARAM_COUNT();
|
||||
}
|
||||
|
||||
pbroker = enchant_broker_init();
|
||||
|
||||
if (pbroker) {
|
||||
broker = (enchant_broker *) emalloc(sizeof(enchant_broker));
|
||||
broker->pbroker = pbroker;
|
||||
broker->dict = NULL;
|
||||
broker->dictcnt = 0;
|
||||
ZEND_REGISTER_RESOURCE(return_value, broker, le_enchant_broker);
|
||||
broker->rsrc_id = return_value;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto boolean enchant_free(resource broker)
|
||||
Destroys the broker object and its dictionnaries */
|
||||
PHP_FUNCTION(enchant_broker_free)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(broker));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string enchant_broker_get_error(resource broker)
|
||||
Returns the last error of the broker */
|
||||
PHP_FUNCTION(enchant_broker_get_error)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
char *msg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
msg = enchant_broker_get_error(pbroker->pbroker);
|
||||
if (msg) {
|
||||
RETURN_STRING((char *)msg, 1);
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_request_dict(resource broker, string tag)
|
||||
create a new dictionary using tag, the non-empty language tag you wish to request
|
||||
a dictionary for ("en_US", "de_DE", ...) */
|
||||
PHP_FUNCTION(enchant_broker_request_dict)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
enchant_dict *dict;
|
||||
EnchantDict *d;
|
||||
char *tag;
|
||||
int taglen;
|
||||
int pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
|
||||
if (d) {
|
||||
if (pbroker->dictcnt) {
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
pos = pbroker->dictcnt++;
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
dict->id = pos;
|
||||
dict->pbroker = pbroker;
|
||||
dict->pdict = d;
|
||||
dict->rsrc_id = return_value;
|
||||
dict->prev = pos ? pbroker->dict[pos-1] : NULL;
|
||||
dict->next = NULL;
|
||||
pbroker->dict[pos] = dict;
|
||||
|
||||
if (pos) {
|
||||
pbroker->dict[pos-1]->next = dict;
|
||||
}
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_request_pwl_dict(resource dict, string filename)
|
||||
creates a dictionary using a PWL file. A PWL file is personal word file one word per line.
|
||||
It must exist before the call.*/
|
||||
PHP_FUNCTION(enchant_broker_request_pwl_dict)
|
||||
{
|
||||
zval *broker;
|
||||
enchant_broker *pbroker;
|
||||
enchant_dict *dict;
|
||||
EnchantDict *d;
|
||||
char *pwl;
|
||||
int pwllen;
|
||||
int pos;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &pwl, &pwllen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if ((PG(safe_mode) && (!php_checkuid(pwl, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(pwl TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
|
||||
if (d) {
|
||||
if (pbroker->dictcnt) {
|
||||
pos = pbroker->dictcnt++;
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
dict->id = pos;
|
||||
dict->pbroker = pbroker;
|
||||
dict->pdict = d;
|
||||
dict->rsrc_id = return_value;
|
||||
dict->prev = pos?pbroker->dict[pos-1]:NULL;
|
||||
dict->next = NULL;
|
||||
pbroker->dict[pos] = dict;
|
||||
if (pos) {
|
||||
pbroker->dict[pos-1]->next = dict;
|
||||
}
|
||||
ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource enchant_broker_free_dict(resource dict)
|
||||
Free the dictionary resource */
|
||||
PHP_FUNCTION(enchant_broker_free_dict)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(dict));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_broker_dict_exists(resource broker, string tag)
|
||||
Wether a dictionary exists or not. Using non-empty tag */
|
||||
PHP_FUNCTION(enchant_broker_dict_exists)
|
||||
{
|
||||
zval *broker;
|
||||
char *tag;
|
||||
int taglen;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &broker, &tag, &taglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
RETURN_BOOL(enchant_broker_dict_exists(pbroker->pbroker, tag));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto bool enchant_broker_set_ordering(resource broker, string tag, string ordering)
|
||||
Declares a preference of dictionaries to use for the language
|
||||
described/referred to by 'tag'. The ordering is a comma delimited
|
||||
list of provider names. As a special exception, the "*" tag can
|
||||
be used as a language tag to declare a default ordering for any
|
||||
language that does not explictly declare an ordering. */
|
||||
|
||||
PHP_FUNCTION(enchant_broker_set_ordering)
|
||||
{
|
||||
zval *broker;
|
||||
char *pordering;
|
||||
int porderinglen;
|
||||
char *ptag;
|
||||
int ptaglen;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &broker, &ptag, &ptaglen, &pordering, &porderinglen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
enchant_broker_set_ordering(pbroker->pbroker, ptag, pordering);
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_broker_describe(resource broker)
|
||||
Enumerates the Enchant providers and tells
|
||||
you some rudimentary information about them. The same info is provided through phpinfo() */
|
||||
PHP_FUNCTION(enchant_broker_describe)
|
||||
{
|
||||
EnchantBrokerDescribeFn describetozval = enumerate_providers_fn;
|
||||
zval *broker;
|
||||
enchant_broker * pbroker;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_BROKER;
|
||||
|
||||
enchant_broker_describe(pbroker->pbroker, describetozval, (void *)return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_quick_check(resource dict, string word [, array &suggestions])
|
||||
If the word is correctly spelled return true, otherwise return false, if suggestions variable
|
||||
is provided, fill it with spelling alternatives. */
|
||||
PHP_FUNCTION(enchant_dict_quick_check)
|
||||
{
|
||||
zval *dict, *sugg = NULL;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z/", &dict, &word, &wordlen, &sugg) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (sugg) {
|
||||
zval_dtor(sugg);
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
if (enchant_dict_check(pdict->pdict, word, wordlen) > 0) {
|
||||
if (!sugg && ZEND_NUM_ARGS() == 2) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
int n_sugg;
|
||||
char **suggs;
|
||||
|
||||
array_init(sugg);
|
||||
|
||||
suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg);
|
||||
if (suggs && n_sugg) {
|
||||
int i;
|
||||
for (i = 0; i < n_sugg; i++) {
|
||||
add_next_index_string(sugg, suggs[i], 1);
|
||||
}
|
||||
enchant_dict_free_suggestions(pdict->pdict, suggs);
|
||||
}
|
||||
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_check(resource dict, string word)
|
||||
If the word is correctly spelled return true, otherwise return false */
|
||||
PHP_FUNCTION(enchant_dict_check)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
RETURN_BOOL(!enchant_dict_check(pdict->pdict, word, wordlen));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_dict_suggest(resource dict, string word)
|
||||
Will return a list of values if any of those pre-conditions are not met.*/
|
||||
PHP_FUNCTION(enchant_dict_suggest)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
char **suggs;
|
||||
enchant_dict *pdict;
|
||||
int n_sugg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg);
|
||||
if (suggs && n_sugg) {
|
||||
int i;
|
||||
|
||||
array_init(return_value);
|
||||
for (i = 0; i < n_sugg; i++) {
|
||||
add_next_index_string(return_value, suggs[i], 1);
|
||||
}
|
||||
|
||||
enchant_dict_free_suggestions(pdict->pdict, suggs);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_add_to_personal(resource dict, string word)
|
||||
add 'word' to personal word list */
|
||||
PHP_FUNCTION(enchant_dict_add_to_personal)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_add_to_personal(pdict->pdict, word, wordlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_add_to_session(resource dict, string word)
|
||||
add 'word' to this spell-checking session */
|
||||
PHP_FUNCTION(enchant_dict_add_to_session)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_add_to_session(pdict->pdict, word, wordlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool enchant_dict_is_in_session(resource dict, string word)
|
||||
whether or not 'word' exists in this spelling-session */
|
||||
PHP_FUNCTION(enchant_dict_is_in_session)
|
||||
{
|
||||
zval *dict;
|
||||
char *word;
|
||||
int wordlen;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &dict, &word, &wordlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void enchant_dict_store_replacement(resource dict, string mis, string cor)
|
||||
add a correction for 'mis' using 'cor'.
|
||||
Notes that you replaced @mis with @cor, so it's possibly more likely
|
||||
that future occurrences of @mis will be replaced with @cor. So it might
|
||||
bump @cor up in the suggestion list.*/
|
||||
PHP_FUNCTION(enchant_dict_store_replacement)
|
||||
{
|
||||
zval *dict;
|
||||
char *mis, *cor;
|
||||
int mislen, corlen;
|
||||
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &dict, &mis, &mislen, &cor, &corlen) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_store_replacement(pdict->pdict, mis, mislen, cor, corlen);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string enchant_dict_get_error(resource dict)
|
||||
Returns the last error of the current spelling-session */
|
||||
PHP_FUNCTION(enchant_dict_get_error)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
char *msg;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
msg = enchant_dict_get_error(pdict->pdict);
|
||||
if (msg) {
|
||||
RETURN_STRING((char *)msg, 1);
|
||||
}
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array enchant_dict_describe(resource dict)
|
||||
Describes an individual dictionary 'dict' */
|
||||
PHP_FUNCTION(enchant_dict_describe)
|
||||
{
|
||||
zval *dict;
|
||||
enchant_dict *pdict;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &dict) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
PHP_ENCHANT_GET_DICT;
|
||||
|
||||
enchant_dict_describe(pdict->pdict, describe_dict_fn, (void *)return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,83 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package>
|
||||
<name>enchant</name>
|
||||
<summary>libenchant binder, support near all spelling tools</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>pajoye</user>
|
||||
<name>Pierre-Alain Joye</name>
|
||||
<email>paj@pearfr.org</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>ilia@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>Enchant is a binder for libenchant. Libenchant provides a common
|
||||
API for many spell libraries:
|
||||
- aspell/pspell (intended to replace ispell)
|
||||
- hspell (hebrew)
|
||||
- ispell
|
||||
- myspell (OpenOffice project, mozilla)
|
||||
- uspell (primarily Yiddish, Hebrew, and Eastern European languages)
|
||||
A plugin system allows to add custom spell support.
|
||||
see www.abisource.com/enchant/</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0</version>
|
||||
<date>2004-08-11</date>
|
||||
<notes>- Fixed leak inside MINFO function.
|
||||
- Fixed crash inside enchant_dict_suggest() when there are no suggestions.
|
||||
- Added missing safe_mode/open_basedir check inside enchant_broker_request_pwl_dict().
|
||||
- Fixed various function prototypes.
|
||||
- Fixed possible leak in suggestions result.</notes>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="enchant.c"/>
|
||||
<file role="src" name="php_enchant.h"/>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<dir name="docs" role="doc">
|
||||
<dir name="examples">
|
||||
<file name="example1.php"/>
|
||||
</dir>
|
||||
</dir>
|
||||
</filelist>
|
||||
<configureoptions>
|
||||
<configureoption name="with-enchant" default="shared" prompt="libenchant prefix?"/>
|
||||
</configureoptions>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5" />
|
||||
</deps>
|
||||
</release>
|
||||
<changelog>
|
||||
<release>
|
||||
<state>beta</state>
|
||||
<version>0.2.1</version>
|
||||
<date>2004-03-11</date>
|
||||
<notes>- Fix possible leak in suggestions result
|
||||
- Move to beta status</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>alpha</state>
|
||||
<version>0.2.0</version>
|
||||
<notes>- Add Ilia Alshanetsky as maintainer
|
||||
- Cleanup sources codes (ilia)
|
||||
- Add enchant_dict_quick_check (ilia)</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<state>alpha</state>
|
||||
<date>2003-03-08</date>
|
||||
<notes>Initial release</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
<!--
|
||||
vim:et:ts=1:sw=1
|
||||
-->
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2003 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Pierre-Alain Joye <paj@pearfr.org> |
|
||||
+----------------------------------------------------------------------+
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef PHP_ENCHANT_H
|
||||
#define PHP_ENCHANT_H
|
||||
|
||||
extern zend_module_entry enchant_module_entry;
|
||||
#define phpext_enchant_ptr &enchant_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_ENCHANT_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_ENCHANT_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
|
||||
PHP_MINIT_FUNCTION(enchant);
|
||||
PHP_MSHUTDOWN_FUNCTION(enchant);
|
||||
PHP_MINFO_FUNCTION(enchant);
|
||||
|
||||
PHP_FUNCTION(enchant_broker_init);
|
||||
PHP_FUNCTION(enchant_broker_free);
|
||||
PHP_FUNCTION(enchant_broker_get_error);
|
||||
PHP_FUNCTION(enchant_broker_request_dict);
|
||||
PHP_FUNCTION(enchant_broker_request_pwl_dict);
|
||||
PHP_FUNCTION(enchant_broker_free_dict);
|
||||
PHP_FUNCTION(enchant_broker_dict_exists);
|
||||
PHP_FUNCTION(enchant_broker_set_ordering);
|
||||
PHP_FUNCTION(enchant_broker_describe);
|
||||
|
||||
PHP_FUNCTION(enchant_dict_check);
|
||||
PHP_FUNCTION(enchant_dict_suggest);
|
||||
PHP_FUNCTION(enchant_dict_add_to_personal);
|
||||
PHP_FUNCTION(enchant_dict_add_to_session);
|
||||
PHP_FUNCTION(enchant_dict_is_in_session);
|
||||
PHP_FUNCTION(enchant_dict_store_replacement);
|
||||
PHP_FUNCTION(enchant_dict_get_error);
|
||||
PHP_FUNCTION(enchant_dict_describe);
|
||||
PHP_FUNCTION(enchant_dict_quick_check);
|
||||
|
||||
#ifdef ZTS
|
||||
#define ENCHANT_G(v) TSRMG(enchant_globals_id, zend_enchant_globals *, v)
|
||||
#else
|
||||
#define ENCHANT_G(v) (enchant_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_ENCHANT_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
fileinfo
|
||||
Ilia Alshanetsky
|
||||
Whitespace-only changes.
@@ -1,62 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension fileinfo
|
||||
|
||||
PHP_ARG_WITH(fileinfo, for fileinfo support,
|
||||
[ --with-fileinfo=DIR Include fileinfo support])
|
||||
|
||||
if test "$PHP_FILEINFO" != "no"; then
|
||||
SEARCH_PATH="/usr/local /usr /usr/share/file"
|
||||
if test -r $PHP_FILEINFO/include/magic.h || test -r $PHP_FILEINFO/magic.h; then
|
||||
FILEINFO_DIR=$PHP_FILEINFO
|
||||
else
|
||||
AC_MSG_CHECKING([for magic files in default path])
|
||||
for i in $SEARCH_PATH ; do
|
||||
if test -r $i/include/magic.h || test -r $i/magic.h; then
|
||||
FILEINFO_DIR=$i
|
||||
AC_MSG_RESULT(found in $i)
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$FILEINFO_DIR"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Please reinstall the libmagic distribution])
|
||||
fi
|
||||
|
||||
if test -r "$FILEINFO_DIR/include/magic.h"; then
|
||||
PHP_ADD_INCLUDE($FILEINFO_DIR/include)
|
||||
else
|
||||
PHP_ADD_INCLUDE($FILEINFO_DIR)
|
||||
fi
|
||||
|
||||
LIBNAME=magic
|
||||
LIBSYMBOL=magic_open
|
||||
|
||||
PHP_CHECK_FUNC(dl, dlopen)
|
||||
PHP_CHECK_FUNC(gzgets, z)
|
||||
PHP_CHECK_FUNC(round, m)
|
||||
|
||||
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
|
||||
[
|
||||
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $FILEINFO_DIR/lib, FILEINFO_SHARED_LIBADD)
|
||||
AC_DEFINE(HAVE_FILEINFOLIB,1,[ ])
|
||||
],[
|
||||
AC_MSG_ERROR([wrong magic lib version or lib not found])
|
||||
],[
|
||||
-L$FILEINFO_DIR/lib
|
||||
])
|
||||
|
||||
MAGIC_MIME_LOCATIONS="/usr/local/share/file/magic /usr/share/file/magic /usr/share/misc/file/magic /etc/magic /usr/share/misc"
|
||||
for i in $MAGIC_MIME_LOCATIONS; do
|
||||
if test -f $i; then
|
||||
PHP_DEFAULT_MAGIC_FILE=$i
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_DEFINE_UNQUOTED(PHP_DEFAULT_MAGIC_FILE,"$PHP_DEFAULT_MAGIC_FILE",[magic file path])
|
||||
|
||||
PHP_SUBST(FILEINFO_SHARED_LIBADD)
|
||||
|
||||
PHP_NEW_EXTENSION(fileinfo, fileinfo.c, $ext_shared)
|
||||
fi
|
||||
@@ -1,433 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Ilia Alshanetsky <ilia@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <magic.h>
|
||||
/*
|
||||
* HOWMANY specifies the maximum offset libmagic will look at
|
||||
* this is currently hardcoded in the libmagic source but not exported
|
||||
*/
|
||||
#ifndef HOWMANY
|
||||
#define HOWMANY 65536
|
||||
#endif
|
||||
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/file.h" /* needed for context stuff */
|
||||
#include "php_fileinfo.h"
|
||||
#include "fopen_wrappers.h" /* needed for is_url */
|
||||
|
||||
struct php_fileinfo {
|
||||
long options;
|
||||
struct magic_set *magic;
|
||||
};
|
||||
|
||||
#ifndef PHP_DEFAULT_MAGIC_FILE
|
||||
#define PHP_DEFAULT_MAGIC_FILE NULL
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_ENGINE_2
|
||||
|
||||
static zend_object_handlers finfo_object_handlers;
|
||||
zend_class_entry *finfo_class_entry;
|
||||
|
||||
struct finfo_object {
|
||||
zend_object zo;
|
||||
struct php_fileinfo *ptr;
|
||||
};
|
||||
|
||||
#define FILEINFO_DECLARE_INIT_OBJECT(object) \
|
||||
zval *object = getThis();
|
||||
|
||||
#define FILEINFO_REGISTER_OBJECT(_object, _ptr) \
|
||||
{ \
|
||||
struct finfo_object *obj; \
|
||||
obj = (struct finfo_object*)zend_object_store_get_object(_object TSRMLS_CC); \
|
||||
obj->ptr = _ptr; \
|
||||
}
|
||||
|
||||
#define FILEINFO_FROM_OBJECT(finfo, object) \
|
||||
{ \
|
||||
struct finfo_object *obj = zend_object_store_get_object(object TSRMLS_CC); \
|
||||
finfo = obj->ptr; \
|
||||
if (!finfo) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The invalid fileinfo object."); \
|
||||
RETURN_FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* {{{ finfo_objects_dtor
|
||||
*/
|
||||
static void finfo_objects_dtor(void *object, zend_object_handle handle TSRMLS_DC)
|
||||
{
|
||||
struct finfo_object *intern = (struct finfo_object *) object;
|
||||
|
||||
if (intern->ptr) {
|
||||
magic_close(intern->ptr->magic);
|
||||
efree(intern->ptr);
|
||||
}
|
||||
|
||||
efree(intern);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ finfo_objects_new
|
||||
*/
|
||||
PHP_FILEINFO_API zend_object_value finfo_objects_new(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
zend_object_value retval;
|
||||
struct finfo_object *intern;
|
||||
|
||||
intern = emalloc(sizeof(struct finfo_object));
|
||||
intern->zo.ce = class_type;
|
||||
intern->zo.in_get = 0;
|
||||
intern->zo.in_set = 0;
|
||||
intern->zo.properties = NULL;
|
||||
intern->ptr = NULL;
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, finfo_objects_dtor, NULL, NULL TSRMLS_CC);
|
||||
retval.handlers = (zend_object_handlers *) &finfo_object_handlers;
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ finfo_class_functions
|
||||
*/
|
||||
function_entry finfo_class_functions[] = {
|
||||
ZEND_ME_MAPPING(finfo, finfo_open, NULL)
|
||||
ZEND_ME_MAPPING(set_flags, finfo_set_flags,NULL)
|
||||
ZEND_ME_MAPPING(file, finfo_file, NULL)
|
||||
ZEND_ME_MAPPING(buffer, finfo_buffer, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#else
|
||||
|
||||
#define FILEINFO_REGISTER_OBJECT(_object, _ptr) {}
|
||||
#define FILEINFO_FROM_OBJECT(socket_id, object) {}
|
||||
|
||||
#define FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
#define object 0
|
||||
|
||||
#endif
|
||||
|
||||
#define FINFO_SET_OPTION(magic, options) \
|
||||
if (magic_setflags(magic, options) == -1) { \
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set option '%ld' %d:%s", \
|
||||
options, magic_errno(magic), magic_error(magic)); \
|
||||
RETURN_FALSE; \
|
||||
}
|
||||
|
||||
/* True global resources - no need for thread safety here */
|
||||
static int le_fileinfo;
|
||||
|
||||
void finfo_resource_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
if (rsrc->ptr) {
|
||||
struct php_fileinfo *finfo = (struct php_fileinfo *) rsrc->ptr;
|
||||
magic_close(finfo->magic);
|
||||
efree(rsrc->ptr);
|
||||
rsrc->ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ fileinfo_functions[]
|
||||
*/
|
||||
function_entry fileinfo_functions[] = {
|
||||
PHP_FE(finfo_open, NULL)
|
||||
PHP_FE(finfo_close, NULL)
|
||||
PHP_FE(finfo_set_flags, NULL)
|
||||
PHP_FE(finfo_file, NULL)
|
||||
PHP_FE(finfo_buffer, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(finfo)
|
||||
{
|
||||
#ifdef ZEND_ENGINE_2
|
||||
zend_class_entry _finfo_class_entry;
|
||||
INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
|
||||
_finfo_class_entry.create_object = finfo_objects_new;
|
||||
finfo_class_entry = zend_register_internal_class(&_finfo_class_entry TSRMLS_CC);
|
||||
|
||||
/* copy the standard object handlers to you handler table */
|
||||
memcpy(&finfo_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
#endif /* ZEND_ENGINE_2 */
|
||||
|
||||
le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);
|
||||
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_NONE", MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK", MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_MIME", MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS", MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_DEVICES", MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE", MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME", MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILEINFO_RAW", MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ fileinfo_module_entry
|
||||
*/
|
||||
zend_module_entry fileinfo_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"fileinfo",
|
||||
fileinfo_functions,
|
||||
PHP_MINIT(finfo),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(fileinfo),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
"0.1", /* Replace with version number for your extension */
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_FILEINFO
|
||||
ZEND_GET_MODULE(fileinfo)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(fileinfo)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "fileinfo support", "enabled");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource finfo_open([int options [, string arg]])
|
||||
Create a new fileinfo resource. */
|
||||
PHP_FUNCTION(finfo_open)
|
||||
{
|
||||
long options = MAGIC_NONE;
|
||||
char *file = PHP_DEFAULT_MAGIC_FILE;
|
||||
int file_len = 0;
|
||||
struct php_fileinfo *finfo;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
char resolved_path[MAXPATHLEN];
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &options, &file, &file_len) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (file_len) { /* user specified filed, perform open_basedir checks */
|
||||
if (!VCWD_REALPATH(file, resolved_path)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
file = resolved_path;
|
||||
|
||||
if ((PG(safe_mode) && (!php_checkuid(file, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(file TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
finfo = emalloc(sizeof(struct php_fileinfo));
|
||||
|
||||
finfo->options = options;
|
||||
finfo->magic = magic_open(options);
|
||||
|
||||
if (finfo->magic == NULL) {
|
||||
efree(finfo);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mode '%ld'.", options);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (magic_load(finfo->magic, file) == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database at '%s'.", file);
|
||||
magic_close(finfo->magic);
|
||||
efree(finfo);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (object) {
|
||||
FILEINFO_REGISTER_OBJECT(object, finfo);
|
||||
} else {
|
||||
ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto resource finfo_close(resource finfo)
|
||||
Close fileinfo resource. */
|
||||
PHP_FUNCTION(finfo_close)
|
||||
{
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfinfo) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
|
||||
zend_list_delete(Z_RESVAL_P(zfinfo));
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool finfo_set_flags(resource finfo, int options)
|
||||
Set libmagic configuration options. */
|
||||
PHP_FUNCTION(finfo_set_flags)
|
||||
{
|
||||
long options;
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
|
||||
if (object) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
FILEINFO_FROM_OBJECT(finfo, object);
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zfinfo, &options) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
}
|
||||
|
||||
FINFO_SET_OPTION(finfo->magic, options)
|
||||
finfo->options = options;
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode)
|
||||
{
|
||||
long options = 0;
|
||||
char *buffer, *tmp, *ret_val;
|
||||
int buffer_len;
|
||||
struct php_fileinfo *finfo;
|
||||
zval *zfinfo, *zcontext = NULL;
|
||||
FILEINFO_DECLARE_INIT_OBJECT(object)
|
||||
|
||||
if (object) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbz", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
FILEINFO_FROM_OBJECT(finfo, object);
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|lbz", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
|
||||
}
|
||||
|
||||
/* Set options for the current file/buffer. */
|
||||
if (options) {
|
||||
FINFO_SET_OPTION(finfo->magic, options)
|
||||
}
|
||||
|
||||
if (mode) { /* file */
|
||||
/* determine if the file is a local file or remote URL */
|
||||
char *tmp2;
|
||||
php_stream_wrapper *wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);
|
||||
if (wrap && wrap->is_url) {
|
||||
#ifdef ZEND_ENGINE_2
|
||||
php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
|
||||
#else
|
||||
php_stream_context *context = NULL;
|
||||
#endif
|
||||
php_stream *stream = php_stream_open_wrapper_ex(buffer, "rb",
|
||||
ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
buffer_len = php_stream_copy_to_mem(stream, &tmp, HOWMANY, 0);
|
||||
php_stream_close(stream);
|
||||
|
||||
if (buffer_len == 0) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else { /* local file */
|
||||
char resolved_path[MAXPATHLEN];
|
||||
if (!VCWD_REALPATH(buffer, resolved_path)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ret_val = (char *) magic_file(finfo->magic, buffer);
|
||||
goto common;
|
||||
}
|
||||
} else { /* buffer */
|
||||
tmp = buffer;
|
||||
}
|
||||
|
||||
ret_val = (char *) magic_buffer(finfo->magic, tmp, buffer_len);
|
||||
if (mode) {
|
||||
efree(tmp);
|
||||
}
|
||||
common:
|
||||
/* Restore options */
|
||||
if (options) {
|
||||
FINFO_SET_OPTION(finfo->magic, finfo->options)
|
||||
}
|
||||
|
||||
if (!ret_val) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed identify data %d:%s",
|
||||
magic_errno(finfo->magic), magic_error(finfo->magic));
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
RETURN_STRING(ret_val, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
|
||||
Return information about a file. */
|
||||
PHP_FUNCTION(finfo_file)
|
||||
{
|
||||
_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string finfo_buffer(resource finfo, char *string [, int options])
|
||||
Return infromation about a string buffer. */
|
||||
PHP_FUNCTION(finfo_buffer)
|
||||
{
|
||||
_php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
if(!extension_loaded('fileinfo')) {
|
||||
dl('fileinfo.' . PHP_SHLIB_SUFFIX);
|
||||
}
|
||||
if(!extension_loaded('fileinfo')) {
|
||||
die("fileinfo extension is not avaliable, please compile it.\n");
|
||||
}
|
||||
|
||||
// normal operation
|
||||
$res = finfo_open(FILEINFO_MIME); /* return mime type ala mimetype extension */
|
||||
$files = glob("*");
|
||||
foreach ($files as $file) {
|
||||
echo finfo_file($res, $file) . "\n";
|
||||
}
|
||||
finfo_close($res);
|
||||
|
||||
// OO mode
|
||||
/*
|
||||
* FILEINFO_PRESERVE_ATIME - if possible preserve the original access time
|
||||
* FILEINFO_SYMLINK - follow symlinks
|
||||
* FILEINFO_DEVICES - look at the contents of blocks or character special devices
|
||||
* FILEINFO_COMPRESS - decompress compressed files
|
||||
*/
|
||||
$fi = new finfo(FILEINFO_PRESERVE_ATIME|FILEINFO_SYMLINK|FILEINFO_DEVICES|FILEINFO_COMPRESS);
|
||||
$files = glob("*");
|
||||
foreach ($files as $file) {
|
||||
echo $fi->buffer(file_get_contents($file)) . "\n";
|
||||
}
|
||||
?>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package>
|
||||
<name>Fileinfo</name>
|
||||
<summary>libmagic bindings</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>iliaa</user>
|
||||
<name>Ilia Alshanetsky</name>
|
||||
<email>ilia@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
This extension allows retrieval of information regarding vast majority of file.
|
||||
This information may include dimensions, quality, length etc...
|
||||
|
||||
Additionally it can also be used to retrieve the mime type for a particular
|
||||
file and for text files proper language encoding.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0</version>
|
||||
<date>2005-06-30</date>
|
||||
<notes>
|
||||
1) Fixed library detection routines.
|
||||
</notes>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="fileinfo.c"/>
|
||||
<file role="src" name="php_fileinfo.h"/>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<file role="doc" name="EXPERIMENTAL"/>
|
||||
<file role="doc" name="fileinfo.php"/>
|
||||
</filelist>
|
||||
<deps>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
<!--
|
||||
vim:et:ts=1:sw=1
|
||||
-->
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Ilia Alshanetsky <ilia@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_FILEINFO_H
|
||||
#define PHP_FILEINFO_H
|
||||
|
||||
extern zend_module_entry fileinfo_module_entry;
|
||||
#define phpext_fileinfo_ptr &fileinfo_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_FILEINFO_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_FILEINFO_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINFO_FUNCTION(fileinfo);
|
||||
|
||||
PHP_FUNCTION(finfo_open);
|
||||
PHP_FUNCTION(finfo_close);
|
||||
PHP_FUNCTION(finfo_set_flags);
|
||||
PHP_FUNCTION(finfo_file);
|
||||
PHP_FUNCTION(finfo_buffer);
|
||||
|
||||
#ifdef ZTS
|
||||
#define FILEINFO_G(v) TSRMG(fileinfo_globals_id, zend_fileinfo_globals *, v)
|
||||
#else
|
||||
#define FILEINFO_G(v) (fileinfo_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_FILEINFO_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,2 +0,0 @@
|
||||
This doesn't work yet. There are no actual filters as of yet, just the
|
||||
framework code to call the filters and store the original data.
|
||||
@@ -1,11 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for input filtering extension
|
||||
|
||||
PHP_ARG_ENABLE(filter, whether to enable input filter support,
|
||||
[ --enable-filter Enable input filter support])
|
||||
|
||||
if test "$PHP_FILTER" != "no"; then
|
||||
PHP_SUBST(FILTER_SHARED_LIBADD)
|
||||
PHP_NEW_EXTENSION(filter, filter.c, $ext_shared)
|
||||
CPPFLAGS="$CPPFLAGS -Wall"
|
||||
fi
|
||||
@@ -1,544 +0,0 @@
|
||||
/*
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/php_string.h"
|
||||
#include "php_variables.h"
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(filter)
|
||||
|
||||
#ifndef PARSE_ENV
|
||||
#define PARSE_ENV 4
|
||||
#endif
|
||||
|
||||
#ifndef PARSE_SERVER
|
||||
#define PARSE_SERVER 5
|
||||
#endif
|
||||
|
||||
/* {{{ filter_functions[]
|
||||
*/
|
||||
function_entry filter_functions[] = {
|
||||
PHP_FE(filter, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ filter_module_entry
|
||||
*/
|
||||
zend_module_entry filter_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"filter",
|
||||
filter_functions,
|
||||
PHP_MINIT(filter),
|
||||
PHP_MSHUTDOWN(filter),
|
||||
NULL,
|
||||
PHP_RSHUTDOWN(filter),
|
||||
PHP_MINFO(filter),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_FILTER
|
||||
ZEND_GET_MODULE(filter)
|
||||
#endif
|
||||
|
||||
/* {{{ UpdateDefaultFilter
|
||||
*/
|
||||
static PHP_INI_MH(UpdateDefaultFilter) {
|
||||
if(!strcasecmp(new_value, "notags")) {
|
||||
IF_G(default_filter) = NOTAGS;
|
||||
}
|
||||
else
|
||||
if(!strcasecmp(new_value, "raw")) {
|
||||
IF_G(default_filter) = F_UNSAFE_RAW;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_INI
|
||||
*/
|
||||
PHP_INI_BEGIN()
|
||||
STD_PHP_INI_ENTRY("filter.default", "notags", PHP_INI_ALL, UpdateDefaultFilter, default_filter, zend_filter_globals, filter_globals)
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_filter_init_globals
|
||||
*/
|
||||
static void php_filter_init_globals(zend_filter_globals *filter_globals)
|
||||
{
|
||||
filter_globals->post_array = NULL;
|
||||
filter_globals->get_array = NULL;
|
||||
filter_globals->cookie_array = NULL;
|
||||
filter_globals->env_array = NULL;
|
||||
filter_globals->server_array = NULL;
|
||||
filter_globals->default_filter = NOTAGS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define PARSE_REQUEST 99
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(filter)
|
||||
{
|
||||
ZEND_INIT_MODULE_GLOBALS(filter, php_filter_init_globals, NULL);
|
||||
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
REGISTER_LONG_CONSTANT("FILTER_POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_REQUEST", PARSE_REQUEST, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_ENV", PARSE_ENV, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_SERVER", PARSE_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_NONE", FILTER_FLAG_NONE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_LOW", FILTER_FLAG_STRIP_LOW, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_STRIP_HIGH", FILTER_FLAG_STRIP_HIGH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_COOK_LOW", FILTER_FLAG_COOK_LOW, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_COOK_HIGH", FILTER_FLAG_COOK_HIGH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_SIGN", FILTER_FLAG_ALLOW_SIGN, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_FRACTION", FILTER_FLAG_ALLOW_FRACTION, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_ALLOW_THOUSAND", FILTER_FLAG_ALLOW_THOUSAND, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_FLAG_ENCODE_AMP", FILTER_FLAG_ENCODE_AMP, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_HTML_NO_TAGS", FILTER_HTML_NO_TAGS, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("FILTER_UNSAFE_RAW", F_UNSAFE_RAW, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_STRIPPED", F_STRIPPED, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_COOKED", F_COOKED, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_HTML", F_HTML, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_EMAIL", F_EMAIL, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_URL", F_URL, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("FILTER_NUMBER", F_NUMBER, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
sapi_register_input_filter(php_sapi_filter);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(filter)
|
||||
{
|
||||
UNREGISTER_INI_ENTRIES();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_RSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_RSHUTDOWN_FUNCTION(filter)
|
||||
{
|
||||
if(IF_G(get_array)) {
|
||||
zval_ptr_dtor(&IF_G(get_array));
|
||||
IF_G(get_array) = NULL;
|
||||
}
|
||||
if(IF_G(post_array)) {
|
||||
zval_ptr_dtor(&IF_G(post_array));
|
||||
IF_G(post_array) = NULL;
|
||||
}
|
||||
if(IF_G(cookie_array)) {
|
||||
zval_ptr_dtor(&IF_G(cookie_array));
|
||||
IF_G(cookie_array) = NULL;
|
||||
}
|
||||
if(IF_G(env_array)) {
|
||||
zval_ptr_dtor(&IF_G(env_array));
|
||||
IF_G(env_array) = NULL;
|
||||
}
|
||||
if(IF_G(server_array)) {
|
||||
zval_ptr_dtor(&IF_G(server_array));
|
||||
IF_G(server_array) = NULL;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(filter)
|
||||
{
|
||||
char tmp[256];
|
||||
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row( 2, "PHP extension for Input Validation and Filtering", "enabled" );
|
||||
php_info_print_table_row( 2, "Revision", "$Revision$");
|
||||
sprintf(tmp, "%d",IF_G(default_filter));
|
||||
php_info_print_table_row( 2, "default_filter", tmp);
|
||||
php_info_print_table_end();
|
||||
|
||||
DISPLAY_INI_ENTRIES();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned *new_val_len)
|
||||
*/
|
||||
unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)
|
||||
{
|
||||
zval new_var;
|
||||
zval *array_ptr = NULL;
|
||||
char *raw_var, *out;
|
||||
int var_len, res, ol, out_len;
|
||||
|
||||
assert(*val != NULL);
|
||||
|
||||
#if PHP_API_VERSION > 20041224
|
||||
if(IF_G(default_filter)==F_UNSAFE_RAW) {
|
||||
if(new_val_len) *new_val_len = val_len;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
if(IF_G(default_filter)==F_UNSAFE_RAW) return(val_len);
|
||||
#endif
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
if(!IF_G(get_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
IF_G(get_array) = array_ptr;
|
||||
}
|
||||
else {
|
||||
array_ptr = IF_G(get_array);
|
||||
}
|
||||
break;
|
||||
case PARSE_POST:
|
||||
if(!IF_G(post_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
IF_G(post_array) = array_ptr;
|
||||
}
|
||||
else {
|
||||
array_ptr = IF_G(post_array);
|
||||
}
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
if(!IF_G(cookie_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
IF_G(cookie_array) = array_ptr;
|
||||
}
|
||||
else {
|
||||
array_ptr = IF_G(cookie_array);
|
||||
}
|
||||
break;
|
||||
case PARSE_ENV:
|
||||
if(!IF_G(env_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
IF_G(env_array) = array_ptr;
|
||||
}
|
||||
else {
|
||||
array_ptr = IF_G(env_array);
|
||||
}
|
||||
break;
|
||||
case PARSE_SERVER:
|
||||
if(!IF_G(server_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
IF_G(server_array) = array_ptr;
|
||||
}
|
||||
else {
|
||||
array_ptr = IF_G(server_array);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Z_STRLEN(new_var) = val_len;
|
||||
Z_STRVAL(new_var) = estrndup(*val, val_len);
|
||||
Z_TYPE(new_var) = IS_STRING;
|
||||
|
||||
var_len = strlen(var);
|
||||
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len+5);
|
||||
|
||||
php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
|
||||
|
||||
ol = 0;
|
||||
out_len = val_len * 2;
|
||||
if(!out_len) out = estrdup("");
|
||||
else out = emalloc(out_len);
|
||||
while((res = php_filter_get_html(*val, val_len, out, &out_len, FILTER_HTML_NO_TAGS, FILTER_FLAG_ENCODE_AMP, NULL)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol; /* Just in case we don't actually get the right out_len for some reason */
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
*val = out;
|
||||
#if PHP_API_VERSION > 20041224
|
||||
if(new_val_len) *new_val_len = out_len?out_len-1:0;
|
||||
return 1;
|
||||
#else
|
||||
return(out_len?out_len-1:0);
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ static void filter_recursive(zval *array, long filter, long flags, char *charset TSRMLS_DC)
|
||||
*/
|
||||
static void filter_recursive(zval *array, long filter, long flags, char *charset TSRMLS_DC)
|
||||
{
|
||||
zval **element;
|
||||
HashPosition pos;
|
||||
int out_len, res, ol=0; /* Yes, ol should start at 0 here because the filter returns the right length */
|
||||
char *out;
|
||||
|
||||
if (Z_TYPE_P(array) == IS_ARRAY) {
|
||||
for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
|
||||
zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **) &element, &pos) == SUCCESS;
|
||||
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)) {
|
||||
filter_recursive(*element, filter, flags, charset TSRMLS_CC);
|
||||
}
|
||||
} else if(Z_STRLEN_P(array)) {
|
||||
switch(filter) {
|
||||
case F_STRIPPED:
|
||||
out_len = Z_STRLEN_P(array) + 1;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_stripped(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
break;
|
||||
|
||||
case F_COOKED:
|
||||
out_len = Z_STRLEN_P(array) * 2;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_cooked(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
break;
|
||||
|
||||
case F_EMAIL:
|
||||
out_len = Z_STRLEN_P(array) + 1;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_email(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
if(res==FILTER_RESULT_BAD_IN) { Z_TYPE_P(array) = IS_BOOL; Z_LVAL_P(array) = 0; }
|
||||
else {
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case F_URL:
|
||||
out_len = Z_STRLEN_P(array) + 1;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_url(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
if(res==FILTER_RESULT_BAD_IN) { Z_TYPE_P(array) = IS_BOOL; Z_LVAL_P(array) = 0; }
|
||||
else {
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case F_NUMBER:
|
||||
out_len = Z_STRLEN_P(array) + 1;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_number(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
if(res==FILTER_RESULT_BAD_IN) { Z_TYPE_P(array) = IS_BOOL; Z_LVAL_P(array) = 0; }
|
||||
else {
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case F_NOTAGS:
|
||||
default:
|
||||
out_len = Z_STRLEN_P(array) + 1;
|
||||
out = emalloc(out_len);
|
||||
while((res = php_filter_get_html(Z_STRVAL_P(array), Z_STRLEN_P(array), out, &out_len, FILTER_HTML_NO_TAGS, flags, charset)) == FILTER_RESULT_OUTLEN_SMALL) {
|
||||
efree(out);
|
||||
ol++;
|
||||
out_len *= ol;
|
||||
out = emalloc(out_len);
|
||||
}
|
||||
efree(Z_STRVAL_P(array));
|
||||
Z_STRVAL_P(array) = out;
|
||||
Z_STRLEN_P(array) = out_len - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ filter(constant type, string variable_name [, int filter [, int flags [, string charset]]])
|
||||
*/
|
||||
PHP_FUNCTION(filter)
|
||||
{
|
||||
long arg, filter = F_NOTAGS, flags = 0;
|
||||
char *var;
|
||||
int var_len, charset_len, found = 0;
|
||||
int argc = ZEND_NUM_ARGS();
|
||||
zval **tmp;
|
||||
zval *array_ptr = NULL, *array_ptr2 = NULL, *array_ptr3 = NULL;
|
||||
HashTable *hash_ptr;
|
||||
char *raw_var, *charset = NULL;
|
||||
|
||||
if(zend_parse_parameters(argc TSRMLS_CC, "ls|lls", &arg, &var, &var_len, &filter, &flags, &charset, &charset_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(get_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_GET];
|
||||
break;
|
||||
case PARSE_POST:
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(post_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_POST];
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(cookie_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_COOKIE];
|
||||
break;
|
||||
case PARSE_ENV:
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(env_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_ENV];
|
||||
break;
|
||||
case PARSE_SERVER:
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(server_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_SERVER];
|
||||
break;
|
||||
case PARSE_REQUEST:
|
||||
if (PG(variables_order)) {
|
||||
zval **a_ptr = &array_ptr;
|
||||
char *p, *variables_order = PG(variables_order);
|
||||
for (p=variables_order; p && *p; p++) {
|
||||
switch(*p) {
|
||||
case 'p':
|
||||
case 'P':
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) *a_ptr = IF_G(post_array);
|
||||
else *a_ptr = PG(http_globals)[TRACK_VARS_POST];
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) *a_ptr = IF_G(get_array);
|
||||
else *a_ptr = PG(http_globals)[TRACK_VARS_GET];
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) *a_ptr = IF_G(cookie_array);
|
||||
else *a_ptr = PG(http_globals)[TRACK_VARS_COOKIE];
|
||||
break;
|
||||
}
|
||||
if(array_ptr && !array_ptr2) { a_ptr = &array_ptr2; continue; }
|
||||
if(array_ptr2 && !array_ptr3) { a_ptr = &array_ptr3; }
|
||||
}
|
||||
} else {
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) array_ptr = IF_G(get_array);
|
||||
else array_ptr = PG(http_globals)[TRACK_VARS_GET];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!array_ptr) RETURN_FALSE;
|
||||
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) {
|
||||
/*
|
||||
* I'm changing the variable name here because when running with register_globals on,
|
||||
* the variable will end up in the global symbol table and I am using that var name
|
||||
* in the internal raw storage arrays as well.
|
||||
*/
|
||||
var_len += 5;
|
||||
raw_var = emalloc(var_len); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len);
|
||||
} else {
|
||||
raw_var = var;
|
||||
var_len++;
|
||||
}
|
||||
|
||||
if(array_ptr3) {
|
||||
hash_ptr = HASH_OF(array_ptr3);
|
||||
if(hash_ptr && zend_hash_find(hash_ptr, raw_var, var_len, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(array_ptr2 && !found) {
|
||||
hash_ptr = HASH_OF(array_ptr2);
|
||||
if(hash_ptr && zend_hash_find(hash_ptr, raw_var, var_len, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
hash_ptr = HASH_OF(array_ptr);
|
||||
|
||||
if(hash_ptr && zend_hash_find(hash_ptr, raw_var, var_len, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(found) {
|
||||
zval_copy_ctor(return_value); /* Watch out for empty strings */
|
||||
if(filter != F_UNSAFE_RAW) {
|
||||
filter_recursive(return_value, filter, flags, charset);
|
||||
}
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
|
||||
if(IF_G(default_filter)!=F_UNSAFE_RAW) {
|
||||
efree(raw_var);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef PHP_FILTER_H
|
||||
#define PHP_FILTER_H
|
||||
|
||||
extern zend_module_entry filter_module_entry;
|
||||
#define phpext_filter_ptr &filter_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_FILTER_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_FILTER_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#if PHP_API_VERSION > 20041224
|
||||
unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len);
|
||||
#else
|
||||
unsigned int php_sapi_filter(int arg, char *var, char **val, unsigned int val_len);
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(filter);
|
||||
PHP_MSHUTDOWN_FUNCTION(filter);
|
||||
PHP_RINIT_FUNCTION(filter);
|
||||
PHP_RSHUTDOWN_FUNCTION(filter);
|
||||
PHP_MINFO_FUNCTION(filter);
|
||||
|
||||
PHP_FUNCTION(filter);
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(filter)
|
||||
zval *post_array;
|
||||
zval *get_array;
|
||||
zval *cookie_array;
|
||||
zval *env_array;
|
||||
zval *server_array;
|
||||
int default_filter;
|
||||
ZEND_END_MODULE_GLOBALS(filter)
|
||||
|
||||
#ifdef ZTS
|
||||
#define IF_G(v) TSRMG(filter_globals_id, zend_filter_globals *, v)
|
||||
#else
|
||||
#define IF_G(v) (filter_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* FILTER_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@@ -1,9 +0,0 @@
|
||||
--TEST--
|
||||
Simple GET test
|
||||
--POST--
|
||||
--GET--
|
||||
a=1
|
||||
--FILE--
|
||||
<?php echo $_GET['a']; ?>
|
||||
--EXPECT--
|
||||
1
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
GET test with 2 values and an empty one
|
||||
--POST--
|
||||
--GET--
|
||||
a=1&b=&c=3
|
||||
--FILE--
|
||||
<?php echo $_GET['a'];
|
||||
echo $_GET['b'];
|
||||
echo $_GET['c'];
|
||||
?>
|
||||
--EXPECT--
|
||||
13
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
GET/POST/REQUEST Test
|
||||
--POST--
|
||||
d=4&e=5
|
||||
--GET--
|
||||
a=1&b=&c=3
|
||||
--FILE--
|
||||
<?php echo $_GET['a'];
|
||||
echo $_GET['b'];
|
||||
echo $_GET['c'];
|
||||
echo $_POST['d'];
|
||||
echo $_POST['e'];
|
||||
echo "\n";
|
||||
echo $_REQUEST['a'];
|
||||
echo $_REQUEST['b'];
|
||||
echo $_REQUEST['c'];
|
||||
echo $_REQUEST['d'];
|
||||
echo $_REQUEST['e'];
|
||||
?>
|
||||
--EXPECT--
|
||||
1345
|
||||
1345
|
||||
@@ -1,24 +0,0 @@
|
||||
--TEST--
|
||||
GET/POST/REQUEST Test with filtered data
|
||||
--INI--
|
||||
filter.default=notags
|
||||
--POST--
|
||||
d="quotes"&e=\slash
|
||||
--GET--
|
||||
a=O'Henry&b=&c=<b>Bold</b>
|
||||
--FILE--
|
||||
<?php echo $_GET['a'];
|
||||
echo $_GET['b'];
|
||||
echo $_GET['c'];
|
||||
echo $_POST['d'];
|
||||
echo $_POST['e'];
|
||||
echo "\n";
|
||||
echo $_REQUEST['a'];
|
||||
echo $_REQUEST['b'];
|
||||
echo $_REQUEST['c'];
|
||||
echo $_REQUEST['d'];
|
||||
echo $_REQUEST['e'];
|
||||
?>
|
||||
--EXPECT--
|
||||
O'HenryBold"quotes"\slash
|
||||
O'HenryBold"quotes"\slash
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
GET/REQUEST Test with fifa example data
|
||||
--INI--
|
||||
filter.default=notags
|
||||
--POST--
|
||||
--GET--
|
||||
id=f03_photos&pgurl=http%3A//fifaworldcup.yahoo.com/03/en/photozone/index.html
|
||||
--FILE--
|
||||
<?php
|
||||
echo $_GET['id'];
|
||||
echo "\n";
|
||||
echo $_GET['pgurl'];
|
||||
echo "\n";
|
||||
echo $_REQUEST['id'];
|
||||
echo "\n";
|
||||
echo $_REQUEST['pgurl'];
|
||||
?>
|
||||
--EXPECT--
|
||||
f03_photos
|
||||
http://fifaworldcup.yahoo.com/03/en/photozone/index.html
|
||||
f03_photos
|
||||
http://fifaworldcup.yahoo.com/03/en/photozone/index.html
|
||||
@@ -1,11 +0,0 @@
|
||||
--TEST--
|
||||
filter() test
|
||||
--POST--
|
||||
foo=<b>abc</b>
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php
|
||||
echo filter(FILTER_POST, 'foo', FILTER_HTML);
|
||||
?>
|
||||
--EXPECT--
|
||||
abc
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
#ifndef _INCLUDED_IMAP_H
|
||||
#define _INCLUDED_IMAP_H
|
||||
|
||||
#if COMPILE_DL
|
||||
#undef HAVE_IMAP
|
||||
#define HAVE_IMAP 1
|
||||
#endif
|
||||
|
||||
#if HAVE_IMAP
|
||||
|
||||
#ifndef PHP_WIN32
|
||||
#include "build-defs.h"
|
||||
#endif
|
||||
|
||||
/* Functions accessable to PHP */
|
||||
extern zend_module_entry imap_module_entry;
|
||||
#define imap_module_ptr &imap_module_entry
|
||||
|
||||
extern PHP_MINIT_FUNCTION(imap);
|
||||
extern PHP_RINIT_FUNCTION(imap);
|
||||
extern PHP_RSHUTDOWN_FUNCTION(imap);
|
||||
PHP_MINFO_FUNCTION(imap);
|
||||
PHP_FUNCTION(imap_open);
|
||||
PHP_FUNCTION(imap_popen);
|
||||
PHP_FUNCTION(imap_reopen);
|
||||
PHP_FUNCTION(imap_num_msg);
|
||||
PHP_FUNCTION(imap_num_recent);
|
||||
PHP_FUNCTION(imap_headers);
|
||||
PHP_FUNCTION(imap_headerinfo);
|
||||
PHP_FUNCTION(imap_rfc822_parse_headers);
|
||||
PHP_FUNCTION(imap_body);
|
||||
PHP_FUNCTION(imap_fetchstructure);
|
||||
PHP_FUNCTION(imap_fetchbody);
|
||||
PHP_FUNCTION(imap_expunge);
|
||||
PHP_FUNCTION(imap_delete);
|
||||
PHP_FUNCTION(imap_undelete);
|
||||
PHP_FUNCTION(imap_check);
|
||||
PHP_FUNCTION(imap_close);
|
||||
PHP_FUNCTION(imap_mail_copy);
|
||||
PHP_FUNCTION(imap_mail_move);
|
||||
PHP_FUNCTION(imap_createmailbox);
|
||||
PHP_FUNCTION(imap_renamemailbox);
|
||||
PHP_FUNCTION(imap_deletemailbox);
|
||||
PHP_FUNCTION(imap_listmailbox);
|
||||
PHP_FUNCTION(imap_scanmailbox);
|
||||
PHP_FUNCTION(imap_subscribe);
|
||||
PHP_FUNCTION(imap_unsubscribe);
|
||||
PHP_FUNCTION(imap_append);
|
||||
PHP_FUNCTION(imap_ping);
|
||||
PHP_FUNCTION(imap_base64);
|
||||
PHP_FUNCTION(imap_qprint);
|
||||
PHP_FUNCTION(imap_8bit);
|
||||
PHP_FUNCTION(imap_binary);
|
||||
PHP_FUNCTION(imap_mailboxmsginfo);
|
||||
PHP_FUNCTION(imap_rfc822_write_address);
|
||||
PHP_FUNCTION(imap_rfc822_parse_adrlist);
|
||||
PHP_FUNCTION(imap_setflag_full);
|
||||
PHP_FUNCTION(imap_clearflag_full);
|
||||
PHP_FUNCTION(imap_sort);
|
||||
PHP_FUNCTION(imap_fetchheader);
|
||||
PHP_FUNCTION(imap_fetchtext);
|
||||
PHP_FUNCTION(imap_uid);
|
||||
PHP_FUNCTION(imap_msgno);
|
||||
PHP_FUNCTION(imap_list);
|
||||
PHP_FUNCTION(imap_list_full);
|
||||
PHP_FUNCTION(imap_listscan);
|
||||
PHP_FUNCTION(imap_lsub);
|
||||
PHP_FUNCTION(imap_lsub_full);
|
||||
PHP_FUNCTION(imap_create);
|
||||
PHP_FUNCTION(imap_rename);
|
||||
PHP_FUNCTION(imap_status);
|
||||
PHP_FUNCTION(imap_bodystruct);
|
||||
PHP_FUNCTION(imap_fetch_overview);
|
||||
PHP_FUNCTION(imap_mail_compose);
|
||||
PHP_FUNCTION(imap_alerts);
|
||||
PHP_FUNCTION(imap_errors);
|
||||
PHP_FUNCTION(imap_last_error);
|
||||
PHP_FUNCTION(imap_mail);
|
||||
PHP_FUNCTION(imap_search);
|
||||
PHP_FUNCTION(imap_utf8);
|
||||
PHP_FUNCTION(imap_utf7_decode);
|
||||
PHP_FUNCTION(imap_utf7_encode);
|
||||
PHP_FUNCTION(imap_mime_header_decode);
|
||||
#else
|
||||
#define imap_module_ptr NULL
|
||||
#endif /* HAVE_IMAP */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define phpext_imap_ptr imap_module_ptr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ ARG_WITH("pcre-regex", "Perl Compatible Regular Expressions", "yes");
|
||||
|
||||
if (PHP_PCRE_REGEX == "yes") {
|
||||
EXTENSION("pcre", "php_pcre.c", PHP_PCRE_REGEX_SHARED,
|
||||
"-DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -Iext/pcre/pcrelib -DNO_RECURSE");
|
||||
ADD_SOURCES("ext/pcre/pcrelib", "maketables.c get.c study.c pcre.c", "pcre");
|
||||
"-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -Iext/pcre/pcrelib -DNO_RECURSE");
|
||||
ADD_SOURCES("ext/pcre/pcrelib", "pcre_chartables.c pcre_compile.c pcre_config.c pcre_dfa_exec.c pcre_exec.c pcre_fullinfo.c pcre_get.c pcre_globals.c pcre_info.c pcre_maketables.c pcre_ord2utf8.c pcre_printint.c pcre_refcount.c pcre_study.c pcre_tables.c pcre_try_flipped.c pcre_ucp_findchar.c pcre_valid_utf8.c pcre_version.c pcre_xclass.c", "pcre");
|
||||
|
||||
AC_DEFINE('HAVE_BUNDLED_PCRE', 1, 'Using bundled PCRE library');
|
||||
AC_DEFINE('HAVE_PCRE', 1, 'Have PCRE library');
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
dnl By default we'll compile and link against the bundled PCRE library
|
||||
dnl if DIR is supplied, we'll use that for linking
|
||||
|
||||
PHP_ARG_WITH(pcre-regex,for PCRE support,
|
||||
[ --without-pcre-regex Do not include Perl Compatible Regular Expressions
|
||||
support. Use --with-pcre-regex=DIR to specify DIR
|
||||
where PCRE's include and library files are located,
|
||||
if not using bundled library.],yes)
|
||||
|
||||
if test "$PHP_PCRE_REGEX" != "no"; then
|
||||
if test "$PHP_PCRE_REGEX" = "yes"; then
|
||||
PHP_NEW_EXTENSION(pcre, pcrelib/pcre_chartables.c pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_dfa_exec.c pcrelib/pcre_exec.c pcrelib/pcre_fullinfo.c pcrelib/pcre_get.c pcrelib/pcre_globals.c pcrelib/pcre_info.c pcrelib/pcre_maketables.c pcrelib/pcre_ord2utf8.c pcrelib/pcre_printint.c pcrelib/pcre_refcount.c pcrelib/pcre_study.c pcrelib/pcre_tables.c pcrelib/pcre_try_flipped.c pcrelib/pcre_ucp_findchar.c pcrelib/pcre_valid_utf8.c pcrelib/pcre_version.c pcrelib/pcre_xclass.c php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000 -I@ext_srcdir@/pcrelib)
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/pcrelib)
|
||||
AC_DEFINE(HAVE_BUNDLED_PCRE, 1, [ ])
|
||||
else
|
||||
for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre; do
|
||||
test -f $i/pcre.h && PCRE_INCDIR=$i
|
||||
done
|
||||
|
||||
if test -z "$PCRE_INCDIR"; then
|
||||
AC_MSG_ERROR([Could not find pcre.h in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
for j in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/$PHP_LIBDIR; do
|
||||
test -f $j/libpcre.a -o -f $j/libpcre.$SHLIB_SUFFIX_NAME && PCRE_LIBDIR=$j
|
||||
done
|
||||
|
||||
if test -z "$PCRE_LIBDIR" ; then
|
||||
AC_MSG_ERROR([Could not find libpcre.(a|$SHLIB_SUFFIX_NAME) in $PHP_PCRE_REGEX])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
pcre_major=`grep PCRE_MAJOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
pcre_minor=`grep PCRE_MINOR $PCRE_INCDIR/pcre.h | sed -e 's/[^0-9]//g'`
|
||||
changequote([,])
|
||||
pcre_minor_length=`echo "$pcre_minor" | wc -c | sed -e 's/[^0-9]//g'`
|
||||
if test "$pcre_minor_length" -eq 2 ; then
|
||||
pcre_minor="$pcre_minor"0
|
||||
fi
|
||||
pcre_version=$pcre_major$pcre_minor
|
||||
if test "$pcre_version" -lt 208; then
|
||||
AC_MSG_ERROR([The PCRE extension requires PCRE library version >= 2.08])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(pcre, $PCRE_LIBDIR, PCRE_SHARED_LIBADD)
|
||||
|
||||
AC_DEFINE(HAVE_PCRE, 1, [ ])
|
||||
PHP_ADD_INCLUDE($PCRE_INCDIR)
|
||||
PHP_NEW_EXTENSION(pcre, php_pcre.c, $ext_shared,,-DEXPORT= -DNEWLINE=10 -DSUPPORT_UTF8 -DSUPPORT_UCP -DLINK_SIZE=2 -DPOSIX_MALLOC_THRESHOLD=10 -DMATCH_LIMIT=10000000)
|
||||
fi
|
||||
PHP_SUBST(PCRE_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,770 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
|
||||
/* This is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language. See
|
||||
the file doc/Tech.Notes for some information on the internals.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
Copyright (c) 1997-2004 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* This header contains definitions that are shared between the different
|
||||
modules, but which are not relevant to the outside. */
|
||||
|
||||
/* Get the definitions provided by running "configure" */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# include "config.w32.h"
|
||||
#else
|
||||
# include <php_config.h>
|
||||
#endif
|
||||
|
||||
/* Standard C headers plus the external interface definition. The only time
|
||||
setjmp and stdarg are used is when NO_RECURSE is set. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef PCRE_SPY
|
||||
#define PCRE_DEFINITION /* Win32 __declspec(export) trigger for .dll */
|
||||
#endif
|
||||
|
||||
/* The value of NEWLINE determines the newline character. The default is to
|
||||
leave it up to the compiler, but some sites want to force a particular value.
|
||||
On Unix systems, "configure" can be used to override this default. */
|
||||
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE '\n'
|
||||
#endif
|
||||
|
||||
/* If you are compiling for a system that needs some magic to be inserted
|
||||
* before the definition of an exported function, define this macro to contain
|
||||
* the relevant magic. It apears at the start of every exported function. */
|
||||
|
||||
#define EXPORT
|
||||
|
||||
/* We need to have types that specify unsigned 16-bit and 32-bit integers. We
|
||||
cannot determine these outside the compilation (e.g. by running a program as
|
||||
part of "configure") because PCRE is often cross-compiled for use on other
|
||||
systems. Instead we make use of the maximum sizes that are available at
|
||||
preprocessor time in standard C environments. */
|
||||
|
||||
#if USHRT_MAX == 65535
|
||||
typedef unsigned short pcre_uint16;
|
||||
#elif UINT_MAX == 65535
|
||||
typedef unsigned int pcre_uint16;
|
||||
#else
|
||||
#error Cannot determine a type for 16-bit unsigned integers
|
||||
#endif
|
||||
|
||||
#if UINT_MAX == 4294967295
|
||||
typedef unsigned int pcre_uint32;
|
||||
#elif ULONG_MAX == 4294967295
|
||||
typedef unsigned long int pcre_uint32;
|
||||
#else
|
||||
#error Cannot determine a type for 32-bit unsigned integers
|
||||
#endif
|
||||
|
||||
/* All character handling must be done as unsigned characters. Otherwise there
|
||||
are problems with top-bit-set characters and functions such as isspace().
|
||||
However, we leave the interface to the outside world as char *, because that
|
||||
should make things easier for callers. We define a short type for unsigned char
|
||||
to save lots of typing. I tried "uchar", but it causes problems on Digital
|
||||
Unix, where it is defined in sys/types, so use "uschar" instead. */
|
||||
|
||||
typedef unsigned char uschar;
|
||||
|
||||
/* Include the public PCRE header */
|
||||
|
||||
#include "pcre.h"
|
||||
|
||||
/* When compiling for use with the Virtual Pascal compiler, these functions
|
||||
need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
|
||||
option on the command line. */
|
||||
|
||||
#ifdef VPCOMPAT
|
||||
#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
|
||||
#define memcpy(d,s,n) _memcpy(d,s,n)
|
||||
#define memmove(d,s,n) _memmove(d,s,n)
|
||||
#define memset(s,c,n) _memset(s,c,n)
|
||||
#else /* VPCOMPAT */
|
||||
|
||||
/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
|
||||
define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
|
||||
is set. Otherwise, include an emulating function for those systems that have
|
||||
neither (there some non-Unix environments where this is the case). This assumes
|
||||
that all calls to memmove are moving strings upwards in store, which is the
|
||||
case in PCRE. */
|
||||
|
||||
#if ! HAVE_MEMMOVE
|
||||
#undef memmove /* some systems may have a macro */
|
||||
#if HAVE_BCOPY
|
||||
#define memmove(a, b, c) bcopy(b, a, c)
|
||||
#else /* HAVE_BCOPY */
|
||||
void *
|
||||
pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)
|
||||
{
|
||||
int i;
|
||||
dest += n;
|
||||
src += n;
|
||||
for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
||||
}
|
||||
#define memmove(a, b, c) pcre_memmove(a, b, c)
|
||||
#endif /* not HAVE_BCOPY */
|
||||
#endif /* not HAVE_MEMMOVE */
|
||||
#endif /* not VPCOMPAT */
|
||||
|
||||
|
||||
/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
|
||||
in big-endian order) by default. These are used, for example, to link from the
|
||||
start of a subpattern to its alternatives and its end. The use of 2 bytes per
|
||||
offset limits the size of the compiled regex to around 64K, which is big enough
|
||||
for almost everybody. However, I received a request for an even bigger limit.
|
||||
For this reason, and also to make the code easier to maintain, the storing and
|
||||
loading of offsets from the byte string is now handled by the macros that are
|
||||
defined here.
|
||||
|
||||
The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
|
||||
the config.h file, but can be overridden by using -D on the command line. This
|
||||
is automated on Unix systems via the "configure" command. */
|
||||
|
||||
#if LINK_SIZE == 2
|
||||
|
||||
#define PUT(a,n,d) \
|
||||
(a[n] = (d) >> 8), \
|
||||
(a[(n)+1] = (d) & 255)
|
||||
|
||||
#define GET(a,n) \
|
||||
(((a)[n] << 8) | (a)[(n)+1])
|
||||
|
||||
#define MAX_PATTERN_SIZE (1 << 16)
|
||||
|
||||
|
||||
#elif LINK_SIZE == 3
|
||||
|
||||
#define PUT(a,n,d) \
|
||||
(a[n] = (d) >> 16), \
|
||||
(a[(n)+1] = (d) >> 8), \
|
||||
(a[(n)+2] = (d) & 255)
|
||||
|
||||
#define GET(a,n) \
|
||||
(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
|
||||
|
||||
#define MAX_PATTERN_SIZE (1 << 24)
|
||||
|
||||
|
||||
#elif LINK_SIZE == 4
|
||||
|
||||
#define PUT(a,n,d) \
|
||||
(a[n] = (d) >> 24), \
|
||||
(a[(n)+1] = (d) >> 16), \
|
||||
(a[(n)+2] = (d) >> 8), \
|
||||
(a[(n)+3] = (d) & 255)
|
||||
|
||||
#define GET(a,n) \
|
||||
(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
|
||||
|
||||
#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
|
||||
|
||||
|
||||
#else
|
||||
#error LINK_SIZE must be either 2, 3, or 4
|
||||
#endif
|
||||
|
||||
|
||||
/* Convenience macro defined in terms of the others */
|
||||
|
||||
#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
|
||||
|
||||
|
||||
/* PCRE uses some other 2-byte quantities that do not change when the size of
|
||||
offsets changes. There are used for repeat counts and for other things such as
|
||||
capturing parenthesis numbers in back references. */
|
||||
|
||||
#define PUT2(a,n,d) \
|
||||
a[n] = (d) >> 8; \
|
||||
a[(n)+1] = (d) & 255
|
||||
|
||||
#define GET2(a,n) \
|
||||
(((a)[n] << 8) | (a)[(n)+1])
|
||||
|
||||
#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2
|
||||
|
||||
|
||||
/* In case there is no definition of offsetof() provided - though any proper
|
||||
Standard C system should have one. */
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
|
||||
#endif
|
||||
|
||||
|
||||
/* These are the public options that can change during matching. */
|
||||
|
||||
#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
|
||||
|
||||
/* Private options flags start at the most significant end of the four bytes,
|
||||
but skip the top bit so we can use ints for convenience without getting tangled
|
||||
with negative values. The public options defined in pcre.h start at the least
|
||||
significant end. Make sure they don't overlap, though now that we have expanded
|
||||
to four bytes, there is plenty of space. */
|
||||
|
||||
#define PCRE_FIRSTSET 0x40000000 /* first_byte is set */
|
||||
#define PCRE_REQCHSET 0x20000000 /* req_byte is set */
|
||||
#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */
|
||||
#define PCRE_ICHANGED 0x08000000 /* i option changes within regex */
|
||||
#define PCRE_NOPARTIAL 0x04000000 /* can't use partial with this regex */
|
||||
|
||||
/* Options for the "extra" block produced by pcre_study(). */
|
||||
|
||||
#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
|
||||
|
||||
/* Masks for identifying the public options which are permitted at compile
|
||||
time, run time or study time, respectively. */
|
||||
|
||||
#define PUBLIC_OPTIONS \
|
||||
(PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
|
||||
PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
|
||||
PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT)
|
||||
|
||||
#define PUBLIC_EXEC_OPTIONS \
|
||||
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \
|
||||
PCRE_PARTIAL)
|
||||
|
||||
#define PUBLIC_STUDY_OPTIONS 0 /* None defined */
|
||||
|
||||
/* Magic number to provide a small check against being handed junk. */
|
||||
|
||||
#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
|
||||
|
||||
/* Negative values for the firstchar and reqchar variables */
|
||||
|
||||
#define REQ_UNSET (-2)
|
||||
#define REQ_NONE (-1)
|
||||
|
||||
/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
|
||||
variable-length repeat, or a anything other than literal characters. */
|
||||
|
||||
#define REQ_CASELESS 0x0100 /* indicates caselessness */
|
||||
#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */
|
||||
|
||||
/* Miscellaneous definitions */
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* Escape items that are just an encoding of a particular data value. Note that
|
||||
ESC_n is defined as yet another macro, which is set in config.h to either \n
|
||||
(the default) or \r (which some people want). */
|
||||
|
||||
#ifndef ESC_e
|
||||
#define ESC_e 27
|
||||
#endif
|
||||
|
||||
#ifndef ESC_f
|
||||
#define ESC_f '\f'
|
||||
#endif
|
||||
|
||||
#ifndef ESC_n
|
||||
#define ESC_n NEWLINE
|
||||
#endif
|
||||
|
||||
#ifndef ESC_r
|
||||
#define ESC_r '\r'
|
||||
#endif
|
||||
|
||||
/* We can't officially use ESC_t because it is a POSIX reserved identifier
|
||||
(presumably because of all the others like size_t). */
|
||||
|
||||
#ifndef ESC_tee
|
||||
#define ESC_tee '\t'
|
||||
#endif
|
||||
|
||||
/* These are escaped items that aren't just an encoding of a particular data
|
||||
value such as \n. They must have non-zero values, as check_escape() returns
|
||||
their negation. Also, they must appear in the same order as in the opcode
|
||||
definitions below, up to ESC_z. There's a dummy for OP_ANY because it
|
||||
corresponds to "." rather than an escape sequence. The final one must be
|
||||
ESC_REF as subsequent values are used for \1, \2, \3, etc. There is are two
|
||||
tests in the code for an escape greater than ESC_b and less than ESC_Z to
|
||||
detect the types that may be repeated. These are the types that consume
|
||||
characters. If any new escapes are put in between that don't consume a
|
||||
character, that code will have to change. */
|
||||
|
||||
enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,
|
||||
ESC_w, ESC_dum1, ESC_C, ESC_P, ESC_p, ESC_X, ESC_Z, ESC_z, ESC_E,
|
||||
ESC_Q, ESC_REF };
|
||||
|
||||
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
|
||||
contain UTF-8 characters with values greater than 255. */
|
||||
|
||||
#define XCL_NOT 0x01 /* Flag: this is a negative class */
|
||||
#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
|
||||
|
||||
#define XCL_END 0 /* Marks end of individual items */
|
||||
#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
|
||||
#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
|
||||
#define XCL_PROP 3 /* Unicode property (one property code) follows */
|
||||
#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
|
||||
|
||||
|
||||
/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
|
||||
that extract substrings. Starting from 1 (i.e. after OP_END), the values up to
|
||||
OP_EOD must correspond in order to the list of escapes immediately above.
|
||||
Note that whenever this list is updated, the two macro definitions that follow
|
||||
must also be updated to match. */
|
||||
|
||||
enum {
|
||||
OP_END, /* 0 End of pattern */
|
||||
|
||||
/* Values corresponding to backslashed metacharacters */
|
||||
|
||||
OP_SOD, /* 1 Start of data: \A */
|
||||
OP_SOM, /* 2 Start of match (subject + offset): \G */
|
||||
OP_NOT_WORD_BOUNDARY, /* 3 \B */
|
||||
OP_WORD_BOUNDARY, /* 4 \b */
|
||||
OP_NOT_DIGIT, /* 5 \D */
|
||||
OP_DIGIT, /* 6 \d */
|
||||
OP_NOT_WHITESPACE, /* 7 \S */
|
||||
OP_WHITESPACE, /* 8 \s */
|
||||
OP_NOT_WORDCHAR, /* 9 \W */
|
||||
OP_WORDCHAR, /* 10 \w */
|
||||
OP_ANY, /* 11 Match any character */
|
||||
OP_ANYBYTE, /* 12 Match any byte (\C); different to OP_ANY for UTF-8 */
|
||||
OP_NOTPROP, /* 13 \P (not Unicode property) */
|
||||
OP_PROP, /* 14 \p (Unicode property) */
|
||||
OP_EXTUNI, /* 15 \X (extended Unicode sequence */
|
||||
OP_EODN, /* 16 End of data or \n at end of data: \Z. */
|
||||
OP_EOD, /* 17 End of data: \z */
|
||||
|
||||
OP_OPT, /* 18 Set runtime options */
|
||||
OP_CIRC, /* 19 Start of line - varies with multiline switch */
|
||||
OP_DOLL, /* 20 End of line - varies with multiline switch */
|
||||
OP_CHAR, /* 21 Match one character, casefully */
|
||||
OP_CHARNC, /* 22 Match one character, caselessly */
|
||||
OP_NOT, /* 23 Match anything but the following char */
|
||||
|
||||
OP_STAR, /* 24 The maximizing and minimizing versions of */
|
||||
OP_MINSTAR, /* 25 all these opcodes must come in pairs, with */
|
||||
OP_PLUS, /* 26 the minimizing one second. */
|
||||
OP_MINPLUS, /* 27 This first set applies to single characters */
|
||||
OP_QUERY, /* 28 */
|
||||
OP_MINQUERY, /* 29 */
|
||||
OP_UPTO, /* 30 From 0 to n matches */
|
||||
OP_MINUPTO, /* 31 */
|
||||
OP_EXACT, /* 32 Exactly n matches */
|
||||
|
||||
OP_NOTSTAR, /* 33 The maximizing and minimizing versions of */
|
||||
OP_NOTMINSTAR, /* 34 all these opcodes must come in pairs, with */
|
||||
OP_NOTPLUS, /* 35 the minimizing one second. */
|
||||
OP_NOTMINPLUS, /* 36 This set applies to "not" single characters */
|
||||
OP_NOTQUERY, /* 37 */
|
||||
OP_NOTMINQUERY, /* 38 */
|
||||
OP_NOTUPTO, /* 39 From 0 to n matches */
|
||||
OP_NOTMINUPTO, /* 40 */
|
||||
OP_NOTEXACT, /* 41 Exactly n matches */
|
||||
|
||||
OP_TYPESTAR, /* 42 The maximizing and minimizing versions of */
|
||||
OP_TYPEMINSTAR, /* 43 all these opcodes must come in pairs, with */
|
||||
OP_TYPEPLUS, /* 44 the minimizing one second. These codes must */
|
||||
OP_TYPEMINPLUS, /* 45 be in exactly the same order as those above. */
|
||||
OP_TYPEQUERY, /* 46 This set applies to character types such as \d */
|
||||
OP_TYPEMINQUERY, /* 47 */
|
||||
OP_TYPEUPTO, /* 48 From 0 to n matches */
|
||||
OP_TYPEMINUPTO, /* 49 */
|
||||
OP_TYPEEXACT, /* 50 Exactly n matches */
|
||||
|
||||
OP_CRSTAR, /* 51 The maximizing and minimizing versions of */
|
||||
OP_CRMINSTAR, /* 52 all these opcodes must come in pairs, with */
|
||||
OP_CRPLUS, /* 53 the minimizing one second. These codes must */
|
||||
OP_CRMINPLUS, /* 54 be in exactly the same order as those above. */
|
||||
OP_CRQUERY, /* 55 These are for character classes and back refs */
|
||||
OP_CRMINQUERY, /* 56 */
|
||||
OP_CRRANGE, /* 57 These are different to the three sets above. */
|
||||
OP_CRMINRANGE, /* 58 */
|
||||
|
||||
OP_CLASS, /* 59 Match a character class, chars < 256 only */
|
||||
OP_NCLASS, /* 60 Same, but the bitmap was created from a negative
|
||||
class - the difference is relevant only when a UTF-8
|
||||
character > 255 is encountered. */
|
||||
|
||||
OP_XCLASS, /* 61 Extended class for handling UTF-8 chars within the
|
||||
class. This does both positive and negative. */
|
||||
|
||||
OP_REF, /* 62 Match a back reference */
|
||||
OP_RECURSE, /* 63 Match a numbered subpattern (possibly recursive) */
|
||||
OP_CALLOUT, /* 64 Call out to external function if provided */
|
||||
|
||||
OP_ALT, /* 65 Start of alternation */
|
||||
OP_KET, /* 66 End of group that doesn't have an unbounded repeat */
|
||||
OP_KETRMAX, /* 67 These two must remain together and in this */
|
||||
OP_KETRMIN, /* 68 order. They are for groups the repeat for ever. */
|
||||
|
||||
/* The assertions must come before ONCE and COND */
|
||||
|
||||
OP_ASSERT, /* 69 Positive lookahead */
|
||||
OP_ASSERT_NOT, /* 70 Negative lookahead */
|
||||
OP_ASSERTBACK, /* 71 Positive lookbehind */
|
||||
OP_ASSERTBACK_NOT, /* 72 Negative lookbehind */
|
||||
OP_REVERSE, /* 73 Move pointer back - used in lookbehind assertions */
|
||||
|
||||
/* ONCE and COND must come after the assertions, with ONCE first, as there's
|
||||
a test for >= ONCE for a subpattern that isn't an assertion. */
|
||||
|
||||
OP_ONCE, /* 74 Once matched, don't back up into the subpattern */
|
||||
OP_COND, /* 75 Conditional group */
|
||||
OP_CREF, /* 76 Used to hold an extraction string number (cond ref) */
|
||||
|
||||
OP_BRAZERO, /* 77 These two must remain together and in this */
|
||||
OP_BRAMINZERO, /* 78 order. */
|
||||
|
||||
OP_BRANUMBER, /* 79 Used for extracting brackets whose number is greater
|
||||
than can fit into an opcode. */
|
||||
|
||||
OP_BRA /* 80 This and greater values are used for brackets that
|
||||
extract substrings up to EXTRACT_BASIC_MAX. After
|
||||
that, use is made of OP_BRANUMBER. */
|
||||
};
|
||||
|
||||
/* WARNING WARNING WARNING: There is an implicit assumption in pcre.c and
|
||||
study.c that all opcodes are less than 128 in value. This makes handling UTF-8
|
||||
character sequences easier. */
|
||||
|
||||
/* The highest extraction number before we have to start using additional
|
||||
bytes. (Originally PCRE didn't have support for extraction counts highter than
|
||||
this number.) The value is limited by the number of opcodes left after OP_BRA,
|
||||
i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional
|
||||
opcodes. */
|
||||
|
||||
#define EXTRACT_BASIC_MAX 100
|
||||
|
||||
|
||||
/* This macro defines textual names for all the opcodes. There are used only
|
||||
for debugging, in pcre.c when DEBUG is defined, and also in pcretest.c. The
|
||||
macro is referenced only in printint.c. */
|
||||
|
||||
#define OP_NAME_LIST \
|
||||
"End", "\\A", "\\G", "\\B", "\\b", "\\D", "\\d", \
|
||||
"\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", \
|
||||
"notprop", "prop", "extuni", \
|
||||
"\\Z", "\\z", \
|
||||
"Opt", "^", "$", "char", "charnc", "not", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
|
||||
"*", "*?", "+", "+?", "?", "??", "{", "{", \
|
||||
"class", "nclass", "xclass", "Ref", "Recurse", "Callout", \
|
||||
"Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \
|
||||
"AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cond ref",\
|
||||
"Brazero", "Braminzero", "Branumber", "Bra"
|
||||
|
||||
|
||||
/* This macro defines the length of fixed length operations in the compiled
|
||||
regex. The lengths are used when searching for specific things, and also in the
|
||||
debugging printing of a compiled regex. We use a macro so that it can be
|
||||
incorporated both into pcre.c and pcretest.c without being publicly exposed.
|
||||
|
||||
As things have been extended, some of these are no longer fixed lenths, but are
|
||||
minima instead. For example, the length of a single-character repeat may vary
|
||||
in UTF-8 mode. The code that uses this table must know about such things. */
|
||||
|
||||
#define OP_LENGTHS \
|
||||
1, /* End */ \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* \A, \G, \B, \B, \D, \d, \S, \s, \W, \w */ \
|
||||
1, 1, /* Any, Anybyte */ \
|
||||
2, 2, 1, /* NOTPROP, PROP, EXTUNI */ \
|
||||
1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \
|
||||
2, /* Char - the minimum length */ \
|
||||
2, /* Charnc - the minimum length */ \
|
||||
2, /* not */ \
|
||||
/* Positive single-char repeats ** These are */ \
|
||||
2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
|
||||
4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \
|
||||
/* Negative single-char repeats - only for chars < 256 */ \
|
||||
2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
|
||||
4, 4, 4, /* NOT upto, minupto, exact */ \
|
||||
/* Positive type repeats */ \
|
||||
2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
|
||||
4, 4, 4, /* Type upto, minupto, exact */ \
|
||||
/* Character class & ref repeats */ \
|
||||
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
|
||||
5, 5, /* CRRANGE, CRMINRANGE */ \
|
||||
33, /* CLASS */ \
|
||||
33, /* NCLASS */ \
|
||||
0, /* XCLASS - variable length */ \
|
||||
3, /* REF */ \
|
||||
1+LINK_SIZE, /* RECURSE */ \
|
||||
2+2*LINK_SIZE, /* CALLOUT */ \
|
||||
1+LINK_SIZE, /* Alt */ \
|
||||
1+LINK_SIZE, /* Ket */ \
|
||||
1+LINK_SIZE, /* KetRmax */ \
|
||||
1+LINK_SIZE, /* KetRmin */ \
|
||||
1+LINK_SIZE, /* Assert */ \
|
||||
1+LINK_SIZE, /* Assert not */ \
|
||||
1+LINK_SIZE, /* Assert behind */ \
|
||||
1+LINK_SIZE, /* Assert behind not */ \
|
||||
1+LINK_SIZE, /* Reverse */ \
|
||||
1+LINK_SIZE, /* Once */ \
|
||||
1+LINK_SIZE, /* COND */ \
|
||||
3, /* CREF */ \
|
||||
1, 1, /* BRAZERO, BRAMINZERO */ \
|
||||
3, /* BRANUMBER */ \
|
||||
1+LINK_SIZE /* BRA */ \
|
||||
|
||||
|
||||
/* A magic value for OP_CREF to indicate the "in recursion" condition. */
|
||||
|
||||
#define CREF_RECURSE 0xffff
|
||||
|
||||
/* The texts of compile-time error messages are defined as macros here so that
|
||||
they can be accessed by the POSIX wrapper and converted into error codes. Yes,
|
||||
I could have used error codes in the first place, but didn't feel like changing
|
||||
just to accommodate the POSIX wrapper. */
|
||||
|
||||
#define ERR1 "\\ at end of pattern"
|
||||
#define ERR2 "\\c at end of pattern"
|
||||
#define ERR3 "unrecognized character follows \\"
|
||||
#define ERR4 "numbers out of order in {} quantifier"
|
||||
#define ERR5 "number too big in {} quantifier"
|
||||
#define ERR6 "missing terminating ] for character class"
|
||||
#define ERR7 "invalid escape sequence in character class"
|
||||
#define ERR8 "range out of order in character class"
|
||||
#define ERR9 "nothing to repeat"
|
||||
#define ERR10 "operand of unlimited repeat could match the empty string"
|
||||
#define ERR11 "internal error: unexpected repeat"
|
||||
#define ERR12 "unrecognized character after (?"
|
||||
#define ERR13 "POSIX named classes are supported only within a class"
|
||||
#define ERR14 "missing )"
|
||||
#define ERR15 "reference to non-existent subpattern"
|
||||
#define ERR16 "erroffset passed as NULL"
|
||||
#define ERR17 "unknown option bit(s) set"
|
||||
#define ERR18 "missing ) after comment"
|
||||
#define ERR19 "parentheses nested too deeply"
|
||||
#define ERR20 "regular expression too large"
|
||||
#define ERR21 "failed to get memory"
|
||||
#define ERR22 "unmatched parentheses"
|
||||
#define ERR23 "internal error: code overflow"
|
||||
#define ERR24 "unrecognized character after (?<"
|
||||
#define ERR25 "lookbehind assertion is not fixed length"
|
||||
#define ERR26 "malformed number after (?("
|
||||
#define ERR27 "conditional group contains more than two branches"
|
||||
#define ERR28 "assertion expected after (?("
|
||||
#define ERR29 "(?R or (?digits must be followed by )"
|
||||
#define ERR30 "unknown POSIX class name"
|
||||
#define ERR31 "POSIX collating elements are not supported"
|
||||
#define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support"
|
||||
#define ERR33 "spare error"
|
||||
#define ERR34 "character value in \\x{...} sequence is too large"
|
||||
#define ERR35 "invalid condition (?(0)"
|
||||
#define ERR36 "\\C not allowed in lookbehind assertion"
|
||||
#define ERR37 "PCRE does not support \\L, \\l, \\N, \\U, or \\u"
|
||||
#define ERR38 "number after (?C is > 255"
|
||||
#define ERR39 "closing ) for (?C expected"
|
||||
#define ERR40 "recursive call could loop indefinitely"
|
||||
#define ERR41 "unrecognized character after (?P"
|
||||
#define ERR42 "syntax error after (?P"
|
||||
#define ERR43 "two named groups have the same name"
|
||||
#define ERR44 "invalid UTF-8 string"
|
||||
#define ERR45 "support for \\P, \\p, and \\X has not been compiled"
|
||||
#define ERR46 "malformed \\P or \\p sequence"
|
||||
#define ERR47 "unknown property name after \\P or \\p"
|
||||
|
||||
/* The real format of the start of the pcre block; the index of names and the
|
||||
code vector run on as long as necessary after the end. We store an explicit
|
||||
offset to the name table so that if a regex is compiled on one host, saved, and
|
||||
then run on another where the size of pointers is different, all might still
|
||||
be well. For the case of compiled-on-4 and run-on-8, we include an extra
|
||||
pointer that is always NULL. For future-proofing, we also include a few dummy
|
||||
fields - even though you can never get this planning right!
|
||||
|
||||
NOTE NOTE NOTE:
|
||||
Because people can now save and re-use compiled patterns, any additions to this
|
||||
structure should be made at the end, and something earlier (e.g. a new
|
||||
flag in the options or one of the dummy fields) should indicate that the new
|
||||
fields are present. Currently PCRE always sets the dummy fields to zero.
|
||||
NOTE NOTE NOTE:
|
||||
*/
|
||||
|
||||
typedef struct real_pcre {
|
||||
pcre_uint32 magic_number;
|
||||
pcre_uint32 size; /* Total that was malloced */
|
||||
pcre_uint32 options;
|
||||
pcre_uint32 dummy1; /* For future use, maybe */
|
||||
|
||||
pcre_uint16 top_bracket;
|
||||
pcre_uint16 top_backref;
|
||||
pcre_uint16 first_byte;
|
||||
pcre_uint16 req_byte;
|
||||
pcre_uint16 name_table_offset; /* Offset to name table that follows */
|
||||
pcre_uint16 name_entry_size; /* Size of any name items */
|
||||
pcre_uint16 name_count; /* Number of name items */
|
||||
pcre_uint16 dummy2; /* For future use, maybe */
|
||||
|
||||
const unsigned char *tables; /* Pointer to tables or NULL for std */
|
||||
const unsigned char *nullpad; /* NULL padding */
|
||||
} real_pcre;
|
||||
|
||||
/* The format of the block used to store data from pcre_study(). The same
|
||||
remark (see NOTE above) about extending this structure applies. */
|
||||
|
||||
typedef struct pcre_study_data {
|
||||
pcre_uint32 size; /* Total that was malloced */
|
||||
pcre_uint32 options;
|
||||
uschar start_bits[32];
|
||||
} pcre_study_data;
|
||||
|
||||
/* Structure for passing "static" information around between the functions
|
||||
doing the compiling, so that they are thread-safe. */
|
||||
|
||||
typedef struct compile_data {
|
||||
const uschar *lcc; /* Points to lower casing table */
|
||||
const uschar *fcc; /* Points to case-flipping table */
|
||||
const uschar *cbits; /* Points to character type table */
|
||||
const uschar *ctypes; /* Points to table of type maps */
|
||||
const uschar *start_code; /* The start of the compiled code */
|
||||
const uschar *start_pattern; /* The start of the pattern */
|
||||
uschar *name_table; /* The name/number table */
|
||||
int names_found; /* Number of entries so far */
|
||||
int name_entry_size; /* Size of each entry */
|
||||
int top_backref; /* Maximum back reference */
|
||||
unsigned int backref_map; /* Bitmap of low back refs */
|
||||
int req_varyopt; /* "After variable item" flag for reqbyte */
|
||||
BOOL nopartial; /* Set TRUE if partial won't work */
|
||||
} compile_data;
|
||||
|
||||
/* Structure for maintaining a chain of pointers to the currently incomplete
|
||||
branches, for testing for left recursion. */
|
||||
|
||||
typedef struct branch_chain {
|
||||
struct branch_chain *outer;
|
||||
uschar *current;
|
||||
} branch_chain;
|
||||
|
||||
/* Structure for items in a linked list that represents an explicit recursive
|
||||
call within the pattern. */
|
||||
|
||||
typedef struct recursion_info {
|
||||
struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
|
||||
int group_num; /* Number of group that was called */
|
||||
const uschar *after_call; /* "Return value": points after the call in the expr */
|
||||
const uschar *save_start; /* Old value of md->start_match */
|
||||
int *offset_save; /* Pointer to start of saved offsets */
|
||||
int saved_max; /* Number of saved offsets */
|
||||
} recursion_info;
|
||||
|
||||
/* When compiling in a mode that doesn't use recursive calls to match(),
|
||||
a structure is used to remember local variables on the heap. It is defined in
|
||||
pcre.c, close to the match() function, so that it is easy to keep it in step
|
||||
with any changes of local variable. However, the pointer to the current frame
|
||||
must be saved in some "static" place over a longjmp(). We declare the
|
||||
structure here so that we can put a pointer in the match_data structure.
|
||||
NOTE: This isn't used for a "normal" compilation of pcre. */
|
||||
|
||||
struct heapframe;
|
||||
|
||||
/* Structure for passing "static" information around between the functions
|
||||
doing the matching, so that they are thread-safe. */
|
||||
|
||||
typedef struct match_data {
|
||||
unsigned long int match_call_count; /* As it says */
|
||||
unsigned long int match_limit;/* As it says */
|
||||
int *offset_vector; /* Offset vector */
|
||||
int offset_end; /* One past the end */
|
||||
int offset_max; /* The maximum usable for return data */
|
||||
const uschar *lcc; /* Points to lower casing table */
|
||||
const uschar *ctypes; /* Points to table of type maps */
|
||||
BOOL offset_overflow; /* Set if too many extractions */
|
||||
BOOL notbol; /* NOTBOL flag */
|
||||
BOOL noteol; /* NOTEOL flag */
|
||||
BOOL utf8; /* UTF8 flag */
|
||||
BOOL endonly; /* Dollar not before final \n */
|
||||
BOOL notempty; /* Empty string match not wanted */
|
||||
BOOL partial; /* PARTIAL flag */
|
||||
BOOL hitend; /* Hit the end of the subject at some point */
|
||||
const uschar *start_code; /* For use when recursing */
|
||||
const uschar *start_subject; /* Start of the subject string */
|
||||
const uschar *end_subject; /* End of the subject string */
|
||||
const uschar *start_match; /* Start of this match attempt */
|
||||
const uschar *end_match_ptr; /* Subject position at end match */
|
||||
int end_offset_top; /* Highwater mark at end of match */
|
||||
int capture_last; /* Most recent capture number */
|
||||
int start_offset; /* The start offset value */
|
||||
recursion_info *recursive; /* Linked list of recursion data */
|
||||
void *callout_data; /* To pass back to callouts */
|
||||
struct heapframe *thisframe; /* Used only when compiling for no recursion */
|
||||
} match_data;
|
||||
|
||||
/* Bit definitions for entries in the pcre_ctypes table. */
|
||||
|
||||
#define ctype_space 0x01
|
||||
#define ctype_letter 0x02
|
||||
#define ctype_digit 0x04
|
||||
#define ctype_xdigit 0x08
|
||||
#define ctype_word 0x10 /* alphameric or '_' */
|
||||
#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
|
||||
|
||||
/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
|
||||
of bits for a class map. Some classes are built by combining these tables. */
|
||||
|
||||
#define cbit_space 0 /* [:space:] or \s */
|
||||
#define cbit_xdigit 32 /* [:xdigit:] */
|
||||
#define cbit_digit 64 /* [:digit:] or \d */
|
||||
#define cbit_upper 96 /* [:upper:] */
|
||||
#define cbit_lower 128 /* [:lower:] */
|
||||
#define cbit_word 160 /* [:word:] or \w */
|
||||
#define cbit_graph 192 /* [:graph:] */
|
||||
#define cbit_print 224 /* [:print:] */
|
||||
#define cbit_punct 256 /* [:punct:] */
|
||||
#define cbit_cntrl 288 /* [:cntrl:] */
|
||||
#define cbit_length 320 /* Length of the cbits table */
|
||||
|
||||
/* Offsets of the various tables from the base tables pointer, and
|
||||
total length. */
|
||||
|
||||
#define lcc_offset 0
|
||||
#define fcc_offset 256
|
||||
#define cbits_offset 512
|
||||
#define ctypes_offset (cbits_offset + cbit_length)
|
||||
#define tables_length (ctypes_offset + 256)
|
||||
|
||||
/* End of internal.h */
|
||||
@@ -188,6 +188,13 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
||||
|
||||
if (mysql_stmt_prepare(S->stmt, sql, sql_len)) {
|
||||
/* TODO: might need to pull statement specific info here? */
|
||||
/* if the query isn't supported by the protocol, fallback to emulation */
|
||||
if (mysql_errno(H->server) == 1295) {
|
||||
if (nsql) {
|
||||
efree(nsql);
|
||||
}
|
||||
goto fallback;
|
||||
}
|
||||
pdo_mysql_error(dbh);
|
||||
if (nsql) {
|
||||
efree(nsql);
|
||||
@@ -212,9 +219,9 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
|
||||
|
||||
return 1;
|
||||
|
||||
#else
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
fallback:
|
||||
#endif
|
||||
stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
/**
|
||||
* @brief Iterator to filter parents
|
||||
* @author Marcus Boerger
|
||||
* @version 1.1
|
||||
* @since PHP 5.0
|
||||
* @version 1.2
|
||||
* @since PHP 6.0
|
||||
*
|
||||
* This extended FilterIterator allows a recursive iteration using
|
||||
* RecursiveIteratorIterator that only shows those elements which have
|
||||
* children.
|
||||
*/
|
||||
class ParentIterator extends FilterIterator implements RecursiveIterator
|
||||
class ParentIterator extends RecursiveFilterIterator
|
||||
{
|
||||
/** @param $it the RecursiveIterator to filter
|
||||
*/
|
||||
@@ -35,13 +35,6 @@ class ParentIterator extends FilterIterator implements RecursiveIterator
|
||||
return $this->it->hasChildren();
|
||||
}
|
||||
|
||||
/** @return whether the current element has children
|
||||
*/
|
||||
function hasChildren()
|
||||
{
|
||||
return $this->it->hasChildren();
|
||||
}
|
||||
|
||||
/** @return the ParentIterator for the current elements children
|
||||
*/
|
||||
function getChildren()
|
||||
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/** @file recursivefilteriterator.inc
|
||||
* @ingroup SPL
|
||||
* @brief class RecursiveFilterIterator
|
||||
* @author Marcus Boerger
|
||||
* @date 2003 - 2005
|
||||
*
|
||||
* SPL - Standard PHP Library
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Iterator to filter recursive iterators
|
||||
* @author Marcus Boerger
|
||||
* @version 1.0
|
||||
* @since PHP 6.0
|
||||
*
|
||||
* This extended FilterIterator allows a recursive iteration using
|
||||
* RecursiveIteratorIterator that only shows those elements which
|
||||
* are accepted. It is of course better to filter before doing the
|
||||
* recursion since it allows to prevent recursion into children that
|
||||
* get declined later anyway.
|
||||
*/
|
||||
class RecursiveFilterIterator extends FilterIterator implements RecursiveIterator
|
||||
{
|
||||
/** @param $it the RecursiveIterator to filter
|
||||
*/
|
||||
function __construct(RecursiveIterator $it)
|
||||
{
|
||||
parent::__construct($it);
|
||||
}
|
||||
|
||||
/** @return whether the current element has children
|
||||
*/
|
||||
function hasChildren()
|
||||
{
|
||||
return $this->it->hasChildren();
|
||||
}
|
||||
|
||||
/** @return the ParentIterator for the current elements children
|
||||
*/
|
||||
function getChildren()
|
||||
{
|
||||
return new RecursiveFilterIterator($this->it->getChildren());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Executable
+118
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/** @file splobjectstorage.inc
|
||||
* @ingroup SPL
|
||||
* @brief class SplObjectStorage
|
||||
* @author Marcus Boerger
|
||||
* @date 2003 - 2005
|
||||
*
|
||||
* SPL - Standard PHP Library
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Object storage
|
||||
* @author Marcus Boerger
|
||||
* @version 1.0
|
||||
* @since PHP 6.0
|
||||
*
|
||||
* This container allows to store objects uniquly without the need to compare
|
||||
* them one by one. This is only possible internally. The code represenation
|
||||
* here therefore has a complexity of O(n) while the actual implementation has
|
||||
* complexity O(1).
|
||||
*/
|
||||
class SplObjectStorage implements Iterator, Countable
|
||||
{
|
||||
private $storage = array();
|
||||
private $index = 0;
|
||||
|
||||
/** Rewind to top iterator as set in constructor
|
||||
*/
|
||||
function rewind()
|
||||
{
|
||||
rewind($this->storage);
|
||||
}
|
||||
|
||||
/** @return whether iterator is valid
|
||||
*/
|
||||
function valid()
|
||||
{
|
||||
return key($this->storage) !== false;
|
||||
}
|
||||
|
||||
/** @return current key
|
||||
*/
|
||||
function key()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/** @return current object
|
||||
*/
|
||||
function current()
|
||||
{
|
||||
return current($this->storage);
|
||||
}
|
||||
|
||||
/** Forward to next element
|
||||
*/
|
||||
function next()
|
||||
{
|
||||
next($this->storage);
|
||||
$this->index++;
|
||||
}
|
||||
|
||||
/** @return number of objects in storage
|
||||
*/
|
||||
function count()
|
||||
{
|
||||
return count($this->storage);
|
||||
}
|
||||
|
||||
/** @obj object to look for
|
||||
* @return whether $obj is contained in storage
|
||||
*/
|
||||
function contains($obj)
|
||||
{
|
||||
if (is_object($obj))
|
||||
{
|
||||
foreach($this->storage as $object)
|
||||
{
|
||||
if ($object === $obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @param $obj new object to attach to storage if not yet contained
|
||||
*/
|
||||
function attach($obj)
|
||||
{
|
||||
if (is_object($obj) && !$this->contains($obj))
|
||||
{
|
||||
$this->storage[] = $obj;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param $obj object to remove from storage
|
||||
*/
|
||||
function detach($obj)
|
||||
{
|
||||
if (is_object($obj))
|
||||
{
|
||||
foreach($this->storage as $idx => $object)
|
||||
{
|
||||
if ($object === $obj)
|
||||
{
|
||||
unset($this->storage[$idx]);
|
||||
$this->rewind();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
+54
-22
@@ -177,11 +177,13 @@ PHP_FUNCTION(class_implements)
|
||||
SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(SimpleXMLIterator, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(Subject, z_list, sub, allow, ce_flags); \
|
||||
SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \
|
||||
|
||||
@@ -316,6 +318,19 @@ PHP_FUNCTION(spl_autoload_extensions)
|
||||
RETURN_STRING(SPL_G(autoload_extensions), 1);
|
||||
} /* }}} */
|
||||
|
||||
typedef struct {
|
||||
zend_function *func_ptr;
|
||||
zval *obj;
|
||||
zend_class_entry *ce;
|
||||
} autoload_func_info;
|
||||
|
||||
static void autoload_func_info_dtor(autoload_func_info *alfi)
|
||||
{
|
||||
if (alfi->obj) {
|
||||
zval_ptr_dtor(&alfi->obj);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ void spl_autoload_call(string class_name)
|
||||
Try all registerd autoload function to load the requested class */
|
||||
PHP_FUNCTION(spl_autoload_call)
|
||||
@@ -325,7 +340,7 @@ PHP_FUNCTION(spl_autoload_call)
|
||||
int func_name_len;
|
||||
long dummy;
|
||||
HashPosition function_pos;
|
||||
zend_function **func_ptr_ptr;
|
||||
autoload_func_info *alfi;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class_name) == FAILURE || Z_TYPE_PP(class_name) != IS_STRING) {
|
||||
return;
|
||||
@@ -336,8 +351,8 @@ PHP_FUNCTION(spl_autoload_call)
|
||||
zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
|
||||
while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS && !EG(exception)) {
|
||||
zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &func_name_len, &dummy, 0, &function_pos);
|
||||
zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &func_ptr_ptr, &function_pos);
|
||||
zend_call_method(NULL, NULL, func_ptr_ptr, func_name, func_name_len, &retval, 1, *class_name, NULL TSRMLS_CC);
|
||||
zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
|
||||
zend_call_method(alfi->obj ? &alfi->obj : NULL, alfi->ce, &alfi->func_ptr, func_name, func_name_len, &retval, 1, *class_name, NULL TSRMLS_CC);
|
||||
if (retval) {
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
@@ -357,32 +372,48 @@ PHP_FUNCTION(spl_autoload_call)
|
||||
Register given function as __autoload() implementation */
|
||||
PHP_FUNCTION(spl_autoload_register)
|
||||
{
|
||||
char *func_name, *lc_name = NULL;
|
||||
char *func_name = NULL, *lc_name = NULL;
|
||||
zval *zcallable = NULL;
|
||||
int func_name_len;
|
||||
zend_bool do_throw = 1;
|
||||
zend_function *spl_func_ptr, *func_ptr, **func_ptr_ptr;
|
||||
zend_function *spl_func_ptr;
|
||||
autoload_func_info alfi;
|
||||
zval **obj_ptr;
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|sb", &func_name, &func_name_len, &do_throw) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &zcallable, &func_name_len, &do_throw) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
#if MBO_0
|
||||
if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_IS_STATIC, &func_name, &func_name_len, &func_ptr, NULL TSRMLS_CC)) {
|
||||
if (!zend_is_callable_ex(zcallable, 0, &func_name, &func_name_len, &alfi.func_ptr, &obj_ptr TSRMLS_CC)) {
|
||||
if (do_throw) {
|
||||
if (func_ptr) {
|
||||
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Non static methods are not supported yet");
|
||||
} else {
|
||||
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify a callable method or method");
|
||||
}
|
||||
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify a callable static method");
|
||||
}
|
||||
if (func_name) {
|
||||
efree(func_name);
|
||||
}
|
||||
return;
|
||||
} else if (!obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
if (do_throw) {
|
||||
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array specifies a non static method but no object");
|
||||
}
|
||||
if (func_name) {
|
||||
efree(func_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lc_name = do_alloca(func_name_len + 1);
|
||||
zend_str_tolower_copy(lc_name, func_name, func_name_len);
|
||||
#else
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Loader methods are not yet supported");
|
||||
#endif
|
||||
if (func_name) {
|
||||
efree(func_name);
|
||||
}
|
||||
if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
alfi.obj = *obj_ptr;
|
||||
alfi.obj->refcount++;
|
||||
alfi.ce = Z_OBJCE_P(alfi.obj);
|
||||
} else {
|
||||
alfi.obj = NULL;
|
||||
alfi.ce = NULL;
|
||||
}
|
||||
} else if (ZEND_NUM_ARGS()) {
|
||||
lc_name = do_alloca(func_name_len + 1);
|
||||
zend_str_tolower_copy(lc_name, func_name, func_name_len);
|
||||
@@ -395,28 +426,31 @@ PHP_FUNCTION(spl_autoload_register)
|
||||
return;
|
||||
}
|
||||
|
||||
if (zend_hash_find(EG(function_table), lc_name, func_name_len+1, (void **) &func_ptr) == FAILURE) {
|
||||
if (zend_hash_find(EG(function_table), lc_name, func_name_len+1, (void **) &alfi.func_ptr) == FAILURE) {
|
||||
if (do_throw) {
|
||||
zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not found", func_name);
|
||||
}
|
||||
free_alloca(lc_name);
|
||||
return;
|
||||
}
|
||||
alfi.obj = NULL;
|
||||
alfi.ce = NULL;
|
||||
}
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
if (!SPL_G(autoload_functions)) {
|
||||
ALLOC_HASHTABLE(SPL_G(autoload_functions));
|
||||
zend_hash_init(SPL_G(autoload_functions), 1, NULL, NULL, 0);
|
||||
zend_hash_init(SPL_G(autoload_functions), 1, NULL, (dtor_func_t) autoload_func_info_dtor, 0);
|
||||
}
|
||||
|
||||
zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr);
|
||||
|
||||
if (EG(autoload_func) == spl_func_ptr) { /* registered already, so we insert that first */
|
||||
zend_hash_add(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload"), &spl_func_ptr, sizeof(void*), (void**)&func_ptr_ptr);
|
||||
autoload_func_info spl_alfi = {spl_func_ptr, NULL, NULL};
|
||||
zend_hash_add(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload"), &spl_alfi, sizeof(autoload_func_info), NULL);
|
||||
}
|
||||
|
||||
zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &func_ptr, sizeof(void*), (void**)&func_ptr_ptr);
|
||||
zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &alfi, sizeof(autoload_func_info), NULL);
|
||||
|
||||
free_alloca(lc_name);
|
||||
}
|
||||
@@ -493,7 +527,6 @@ PHP_FUNCTION(spl_autoload_functions)
|
||||
zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
|
||||
while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
|
||||
zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &func_ptr_ptr, &function_pos);
|
||||
#if MBO_0
|
||||
if ((*func_ptr_ptr)->common.scope) {
|
||||
zval *tmp;
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
@@ -503,7 +536,6 @@ PHP_FUNCTION(spl_autoload_functions)
|
||||
add_next_index_string(tmp, (*func_ptr_ptr)->common.function_name, 1);
|
||||
add_next_index_zval(return_value, tmp);
|
||||
} else
|
||||
#endif
|
||||
add_next_index_string(return_value, (*func_ptr_ptr)->common.function_name, 1);
|
||||
|
||||
zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
|
||||
@@ -596,7 +628,7 @@ PHP_MINIT_FUNCTION(spl)
|
||||
|
||||
PHP_RINIT_FUNCTION(spl) /* {{{ */
|
||||
{
|
||||
SPL_G(autoload_extensions) = estrdup(".inc,.inc.php");
|
||||
SPL_G(autoload_extensions) = estrndup(".inc,.php", sizeof(".inc,.php")-1);
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
|
||||
+1
-1
@@ -945,7 +945,7 @@ SPL_METHOD(Array, exchangeArray)
|
||||
zval *object = getThis(), *tmp, **array;
|
||||
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
||||
|
||||
array_init(return_value);
|
||||
array_init(return_value);
|
||||
zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*));
|
||||
|
||||
if (ZEND_NUM_ARGS() > 1 || zend_get_parameters_ex(1, &array) == FAILURE) {
|
||||
|
||||
+47
-5
@@ -41,6 +41,7 @@
|
||||
PHPAPI zend_class_entry *spl_ce_RecursiveIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_RecursiveIteratorIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_FilterIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_RecursiveFilterIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_ParentIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_SeekableIterator;
|
||||
PHPAPI zend_class_entry *spl_ce_LimitIterator;
|
||||
@@ -1041,6 +1042,40 @@ SPL_METHOD(FilterIterator, next)
|
||||
spl_filter_it_next(getThis(), intern TSRMLS_CC);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto RecursiveFilterIterator::__construct(RecursiveIterator it)
|
||||
Create a RecursiveFilterIterator from a RecursiveIterator */
|
||||
SPL_METHOD(RecursiveFilterIterator, __construct)
|
||||
{
|
||||
spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveIterator, DIT_Default);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto boolean RecursiveFilterIterator::hasChildren()
|
||||
Check whether the inner iterator's current element has children */
|
||||
SPL_METHOD(RecursiveFilterIterator, hasChildren)
|
||||
{
|
||||
spl_dual_it_object *intern;
|
||||
zval *retval;
|
||||
|
||||
intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
|
||||
RETURN_ZVAL(retval, 0, 1);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto RecursiveFilterIterator RecursiveFilterIterator::getChildren()
|
||||
Return the inner iterator's children contained in a RecursiveFilterIterator */
|
||||
SPL_METHOD(RecursiveFilterIterator, getChildren)
|
||||
{
|
||||
spl_dual_it_object *intern;
|
||||
zval *retval;
|
||||
|
||||
intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
|
||||
spl_instantiate_arg_ex1(spl_ce_RecursiveFilterIterator, &return_value, 0, retval TSRMLS_CC);
|
||||
zval_ptr_dtor(&retval);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto ParentIterator::__construct(RecursiveIterator it)
|
||||
Create a ParentIterator from a RecursiveIterator */
|
||||
SPL_METHOD(ParentIterator, __construct)
|
||||
@@ -1142,15 +1177,21 @@ static zend_function_entry spl_funcs_FilterIterator[] = {
|
||||
|
||||
static
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_parent_it___construct, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, iterator, RecursiveIterator, 0)
|
||||
ZEND_END_ARG_INFO();
|
||||
|
||||
static zend_function_entry spl_funcs_RecursiveFilterIterator[] = {
|
||||
SPL_ME(RecursiveFilterIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(RecursiveFilterIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static zend_function_entry spl_funcs_ParentIterator[] = {
|
||||
SPL_ME(ParentIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC)
|
||||
SPL_MA(ParentIterator, accept, ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(ParentIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -1938,10 +1979,11 @@ PHP_MINIT_FUNCTION(spl_iterators)
|
||||
|
||||
REGISTER_SPL_STD_CLASS_EX(FilterIterator, spl_dual_it_new, spl_funcs_FilterIterator);
|
||||
REGISTER_SPL_ITERATOR(FilterIterator);
|
||||
spl_ce_FilterIterator->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
|
||||
|
||||
REGISTER_SPL_SUB_CLASS_EX(ParentIterator, FilterIterator, spl_dual_it_new, spl_funcs_ParentIterator);
|
||||
REGISTER_SPL_IMPLEMENTS(ParentIterator, RecursiveIterator);
|
||||
REGISTER_SPL_SUB_CLASS_EX(RecursiveFilterIterator, FilterIterator, spl_dual_it_new, spl_funcs_RecursiveFilterIterator);
|
||||
REGISTER_SPL_IMPLEMENTS(RecursiveFilterIterator, RecursiveIterator);
|
||||
|
||||
REGISTER_SPL_SUB_CLASS_EX(ParentIterator, RecursiveFilterIterator, spl_dual_it_new, spl_funcs_ParentIterator);
|
||||
|
||||
REGISTER_SPL_INTERFACE(SeekableIterator);
|
||||
REGISTER_SPL_ITERATOR(SeekableIterator);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
extern PHPAPI zend_class_entry *spl_ce_RecursiveIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_RecursiveIteratorIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_FilterIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_RecursiveFilterIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_ParentIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_SeekableIterator;
|
||||
extern PHPAPI zend_class_entry *spl_ce_LimitIterator;
|
||||
|
||||
+187
-2
@@ -32,6 +32,8 @@
|
||||
#include "spl_functions.h"
|
||||
#include "spl_engine.h"
|
||||
#include "spl_observer.h"
|
||||
#include "spl_iterators.h"
|
||||
#include "spl_array.h"
|
||||
|
||||
SPL_METHOD(Observer, update);
|
||||
SPL_METHOD(Subject, attach);
|
||||
@@ -65,14 +67,197 @@ static zend_function_entry spl_funcs_Subject[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
PHPAPI zend_class_entry *spl_ce_Observer;
|
||||
PHPAPI zend_class_entry *spl_ce_Subject;
|
||||
PHPAPI zend_class_entry *spl_ce_Observer;
|
||||
PHPAPI zend_class_entry *spl_ce_Subject;
|
||||
PHPAPI zend_class_entry *spl_ce_SplObjectStorage;
|
||||
PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
|
||||
|
||||
typedef struct _spl_SplObjectStorage {
|
||||
zend_object std;
|
||||
HashTable storage;
|
||||
long index;
|
||||
HashPosition pos;
|
||||
} spl_SplObjectStorage;
|
||||
|
||||
/* storage is an assoc aray of [zend_object_value]=>[zval*] */
|
||||
|
||||
void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;
|
||||
|
||||
zend_hash_destroy(intern->std.properties);
|
||||
FREE_HASHTABLE(intern->std.properties);
|
||||
|
||||
zend_hash_destroy(&intern->storage);
|
||||
|
||||
efree(object);
|
||||
} /* }}} */
|
||||
|
||||
static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object_value retval;
|
||||
spl_SplObjectStorage *intern;
|
||||
zval *tmp;
|
||||
|
||||
intern = emalloc(sizeof(spl_SplObjectStorage));
|
||||
memset(intern, 0, sizeof(spl_SplObjectStorage));
|
||||
intern->std.ce = class_type;
|
||||
*obj = intern;
|
||||
|
||||
ALLOC_HASHTABLE(intern->std.properties);
|
||||
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
|
||||
zend_hash_init(&intern->storage, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
|
||||
retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC);
|
||||
retval.handlers = &spl_handler_SplObjectStorage;
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_array_object_new */
|
||||
static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC)
|
||||
{
|
||||
spl_SplObjectStorage *tmp;
|
||||
return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto void SplObjectStorage::attach($obj)
|
||||
Attaches an object to the storage if not yet contained */
|
||||
SPL_METHOD(SplObjectStorage, attach)
|
||||
{
|
||||
zval *obj;
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_hash_update(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj), &obj, sizeof(zval**), NULL);
|
||||
obj->refcount++;
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto void SplObjectStorage::detach($obj)
|
||||
Detaches an object from the storage */
|
||||
SPL_METHOD(SplObjectStorage, detach)
|
||||
{
|
||||
zval *obj;
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_hash_del(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj));
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
intern->index = 0;
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto bool SplObjectStorage::contains($obj)
|
||||
Determine whethe an object is contained in the storage */
|
||||
SPL_METHOD(SplObjectStorage, contains)
|
||||
{
|
||||
zval *obj;
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
RETURN_BOOL(zend_hash_exists(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj)));
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto int SplObjectStorage::count()
|
||||
Determine number of objects in storage */
|
||||
SPL_METHOD(SplObjectStorage, count)
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RETURN_LONG(zend_hash_num_elements(&intern->storage));
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto void SplObjectStorage::rewind()
|
||||
*/
|
||||
SPL_METHOD(SplObjectStorage, rewind)
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
intern->index = 0;
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto bool SplObjectStorage::valid()
|
||||
*/
|
||||
SPL_METHOD(SplObjectStorage, valid)
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RETURN_BOOL(zend_hash_has_more_elements_ex(&intern->storage, &intern->pos) == SUCCESS);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto mixed SplObjectStorage::key()
|
||||
*/
|
||||
SPL_METHOD(SplObjectStorage, key)
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
RETURN_LONG(intern->index);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto mixed SplObjectStorage::current()
|
||||
*/
|
||||
SPL_METHOD(SplObjectStorage, current)
|
||||
{
|
||||
zval **entry;
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
if (zend_hash_get_current_data_ex(&intern->storage, (void**)&entry, &intern->pos) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
RETVAL_ZVAL(*entry, 1, 0);
|
||||
} /* }}} */
|
||||
|
||||
/* {{{ proto void SplObjectStorage::next()
|
||||
*/
|
||||
SPL_METHOD(SplObjectStorage, next)
|
||||
{
|
||||
spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
|
||||
intern->index++;
|
||||
} /* }}} */
|
||||
|
||||
static
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_Object, 0)
|
||||
ZEND_ARG_INFO(0, object 0)
|
||||
ZEND_END_ARG_INFO();
|
||||
|
||||
static zend_function_entry spl_funcs_SplObjectStorage[] = {
|
||||
SPL_ME(SplObjectStorage, attach, arginfo_Object, 0)
|
||||
SPL_ME(SplObjectStorage, detach, arginfo_Object, 0)
|
||||
SPL_ME(SplObjectStorage, contains, arginfo_Object, 0)
|
||||
SPL_ME(SplObjectStorage, count, NULL, 0)
|
||||
SPL_ME(SplObjectStorage, rewind, NULL, 0)
|
||||
SPL_ME(SplObjectStorage, valid, NULL, 0)
|
||||
SPL_ME(SplObjectStorage, key, NULL, 0)
|
||||
SPL_ME(SplObjectStorage, current, NULL, 0)
|
||||
SPL_ME(SplObjectStorage, next, NULL, 0)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION(spl_observer) */
|
||||
PHP_MINIT_FUNCTION(spl_observer)
|
||||
{
|
||||
REGISTER_SPL_INTERFACE(Observer);
|
||||
REGISTER_SPL_INTERFACE(Subject);
|
||||
|
||||
REGISTER_SPL_STD_CLASS_EX(SplObjectStorage, spl_SplObjectStorage_new, spl_funcs_SplObjectStorage);
|
||||
memcpy(&spl_handler_SplObjectStorage, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
|
||||
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable);
|
||||
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
extern PHPAPI zend_class_entry *spl_ce_Observer;
|
||||
extern PHPAPI zend_class_entry *spl_ce_Subject;
|
||||
extern PHPAPI zend_class_entry *spl_ce_SplObjectStorage;
|
||||
|
||||
PHP_MINIT_FUNCTION(spl_observer);
|
||||
|
||||
|
||||
Executable
+199
@@ -0,0 +1,199 @@
|
||||
--TEST--
|
||||
SPL: SplObjectStorage
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyObjectStorage extends SplObjectStorage
|
||||
{
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
parent::rewind();
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
echo __METHOD__ . "(" . (parent::valid() ? 1 : 0) . ")\n";
|
||||
return parent::valid();
|
||||
}
|
||||
|
||||
function key()
|
||||
{
|
||||
echo __METHOD__ . "(" . parent::key() . ")\n";
|
||||
return parent::key();
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
echo __METHOD__ . "(" . parent::current()->getName() . ")\n";
|
||||
return parent::current();
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
parent::next();
|
||||
}
|
||||
}
|
||||
|
||||
class ObserverImpl implements Observer
|
||||
{
|
||||
protected $name = '';
|
||||
|
||||
function __construct($name = 'obj')
|
||||
{
|
||||
$this->name = '$' . $name;
|
||||
}
|
||||
|
||||
function update(Subject $subject)
|
||||
{
|
||||
echo $this->name . '->' . __METHOD__ . '(' . $subject->getName() . ");\n";
|
||||
}
|
||||
|
||||
function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
class SubjectImpl implements Subject
|
||||
{
|
||||
protected $name = '';
|
||||
protected $observers;
|
||||
|
||||
function __construct($name = 'sub')
|
||||
{
|
||||
$this->observers = new MyObjectStorage;
|
||||
$this->name = '$' . $name;
|
||||
}
|
||||
|
||||
function attach(Observer $observer)
|
||||
{
|
||||
echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n";
|
||||
$this->observers->attach($observer);
|
||||
}
|
||||
|
||||
function detach(Observer $observer)
|
||||
{
|
||||
echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n";
|
||||
$this->observers->detach($observer);
|
||||
}
|
||||
|
||||
function count()
|
||||
{
|
||||
return $this->observers->count();
|
||||
}
|
||||
|
||||
function notify()
|
||||
{
|
||||
echo $this->name . '->' . __METHOD__ . "();\n";
|
||||
foreach($this->observers as $key => $observer)
|
||||
{
|
||||
$observer->update($this);
|
||||
}
|
||||
}
|
||||
|
||||
function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function contains($obj)
|
||||
{
|
||||
return $this->observers->contains($obj);
|
||||
}
|
||||
}
|
||||
|
||||
$sub = new SubjectImpl;
|
||||
|
||||
$ob1 = new ObserverImpl("ob1");
|
||||
$ob2 = new ObserverImpl("ob2");
|
||||
$ob3 = new ObserverImpl("ob3");
|
||||
|
||||
var_dump($sub->contains($ob1));
|
||||
$sub->attach($ob1);
|
||||
var_dump($sub->contains($ob1));
|
||||
$sub->attach($ob1);
|
||||
$sub->attach($ob2);
|
||||
$sub->attach($ob3);
|
||||
var_dump($sub->count());
|
||||
|
||||
$sub->notify();
|
||||
|
||||
$sub->detach($ob3);
|
||||
var_dump($sub->count());
|
||||
|
||||
$sub->notify();
|
||||
|
||||
$sub->detach($ob2);
|
||||
$sub->detach($ob1);
|
||||
var_dump($sub->count());
|
||||
|
||||
$sub->notify();
|
||||
|
||||
$sub->attach($ob3);
|
||||
var_dump($sub->count());
|
||||
|
||||
$sub->notify();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
$sub->SubjectImpl::attach($ob1);
|
||||
bool(true)
|
||||
$sub->SubjectImpl::attach($ob1);
|
||||
$sub->SubjectImpl::attach($ob2);
|
||||
$sub->SubjectImpl::attach($ob3);
|
||||
int(3)
|
||||
$sub->SubjectImpl::notify();
|
||||
MyObjectStorage::rewind()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob1)
|
||||
MyObjectStorage::key(0)
|
||||
$ob1->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob2)
|
||||
MyObjectStorage::key(1)
|
||||
$ob2->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob3)
|
||||
MyObjectStorage::key(2)
|
||||
$ob3->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(0)
|
||||
$sub->SubjectImpl::detach($ob3);
|
||||
int(2)
|
||||
$sub->SubjectImpl::notify();
|
||||
MyObjectStorage::rewind()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob1)
|
||||
MyObjectStorage::key(0)
|
||||
$ob1->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob2)
|
||||
MyObjectStorage::key(1)
|
||||
$ob2->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(0)
|
||||
$sub->SubjectImpl::detach($ob2);
|
||||
$sub->SubjectImpl::detach($ob1);
|
||||
int(0)
|
||||
$sub->SubjectImpl::notify();
|
||||
MyObjectStorage::rewind()
|
||||
MyObjectStorage::valid(0)
|
||||
$sub->SubjectImpl::attach($ob3);
|
||||
int(1)
|
||||
$sub->SubjectImpl::notify();
|
||||
MyObjectStorage::rewind()
|
||||
MyObjectStorage::valid(1)
|
||||
MyObjectStorage::current($ob3)
|
||||
MyObjectStorage::key(0)
|
||||
$ob3->ObserverImpl::update($sub);
|
||||
MyObjectStorage::next()
|
||||
MyObjectStorage::valid(0)
|
||||
===DONE===
|
||||
@@ -105,7 +105,7 @@ catch(Exception $e)
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
===EMPTY===
|
||||
string(13) ".inc,.inc.php"
|
||||
string(9) ".inc,.php"
|
||||
%stestclass.inc
|
||||
Exception: Class TestClass could not be loaded
|
||||
===()===
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
SPL: spl_autoload() with static methods
|
||||
--INI--
|
||||
include_path=.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyAutoLoader {
|
||||
|
||||
static function autoLoad($className) {
|
||||
echo __METHOD__ . "($className)\n";
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register(array('MyAutoLoader', 'autoLoad'));
|
||||
|
||||
// and
|
||||
|
||||
$myAutoLoader = new MyAutoLoader();
|
||||
|
||||
spl_autoload_register(array($myAutoLoader, 'autoLoad'));
|
||||
|
||||
var_dump(spl_autoload_functions());
|
||||
|
||||
// check
|
||||
var_dump(class_exists("TestClass", true));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(12) "MyAutoLoader"
|
||||
[1]=>
|
||||
string(8) "autoLoad"
|
||||
}
|
||||
}
|
||||
MyAutoLoader::autoLoad(TestClass)
|
||||
bool(false)
|
||||
===DONE===
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
--TEST--
|
||||
SPL: spl_autoload() with methods
|
||||
--INI--
|
||||
include_path=.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyAutoLoader {
|
||||
|
||||
function autoLoad($className)
|
||||
{
|
||||
echo __METHOD__ . "($className)\n";
|
||||
}
|
||||
|
||||
function autoThrow($className)
|
||||
{
|
||||
echo __METHOD__ . "($className)\n";
|
||||
throw new Exception("Unavailable");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
spl_autoload_register(array('MyAutoLoader', 'autoLoad'), true);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Exception: ' . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
// and
|
||||
|
||||
$myAutoLoader = new MyAutoLoader();
|
||||
|
||||
spl_autoload_register(array($myAutoLoader, 'autoLoad'));
|
||||
spl_autoload_register(array($myAutoLoader, 'autoThrow'));
|
||||
|
||||
try
|
||||
{
|
||||
var_dump(class_exists("TestClass", true));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Exception: ' . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
Exception: Passed array specifies a non static method but no object
|
||||
MyAutoLoader::autoLoad(TestClass)
|
||||
MyAutoLoader::autoThrow(TestClass)
|
||||
Exception: Unavailable
|
||||
===DONE===
|
||||
@@ -3044,6 +3044,15 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
|
||||
|
||||
/* copy the argument array */
|
||||
RETVAL_ZVAL(*args[0], 1, 0);
|
||||
if (return_value->value.ht == &EG(symbol_table)) {
|
||||
HashTable *ht;
|
||||
zval *tmp;
|
||||
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
return_value->value.ht = ht;
|
||||
}
|
||||
|
||||
if ((behavior & INTERSECT_NORMAL) && data_compare_type == INTERSECT_COMP_DATA_USER) {
|
||||
/* array_uintersect() */
|
||||
@@ -3420,6 +3429,15 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
|
||||
|
||||
/* copy the argument array */
|
||||
RETVAL_ZVAL(*args[0], 1, 0);
|
||||
if (return_value->value.ht == &EG(symbol_table)) {
|
||||
HashTable *ht;
|
||||
zval *tmp;
|
||||
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
return_value->value.ht = ht;
|
||||
}
|
||||
|
||||
if (behavior == DIFF_NORMAL && data_compare_type == DIFF_COMP_DATA_USER) {
|
||||
/* array_udiff() */
|
||||
@@ -4234,6 +4252,7 @@ PHP_FUNCTION(array_map)
|
||||
efree(array_pos);
|
||||
return;
|
||||
}
|
||||
SEPARATE_ZVAL_IF_NOT_REF(pargs[i]);
|
||||
args[i] = *pargs[i];
|
||||
array_len[i] = zend_hash_num_elements(Z_ARRVAL_PP(pargs[i]));
|
||||
if (array_len[i] > maxlen) {
|
||||
|
||||
@@ -142,6 +142,10 @@ static
|
||||
ZEND_ARG_PASS_INFO(1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
static
|
||||
ZEND_BEGIN_ARG_INFO(all_args_prefer_ref, ZEND_SEND_PREFER_REF)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
typedef struct _php_shutdown_function_entry {
|
||||
zval **arguments;
|
||||
int arg_count;
|
||||
@@ -449,7 +453,7 @@ function_entry basic_functions[] = {
|
||||
PHP_FE(call_user_func_array, NULL)
|
||||
PHP_FE(call_user_method, second_arg_force_ref)
|
||||
PHP_FE(call_user_method_array, second_arg_force_ref)
|
||||
PHP_FE(serialize, NULL)
|
||||
PHP_FE(serialize, NULL)
|
||||
PHP_FE(unserialize, NULL)
|
||||
|
||||
PHP_FE(var_dump, NULL)
|
||||
@@ -762,7 +766,7 @@ function_entry basic_functions[] = {
|
||||
PHP_FE(compact, NULL)
|
||||
PHP_FE(array_fill, NULL)
|
||||
PHP_FE(range, NULL)
|
||||
PHP_FE(array_multisort, NULL)
|
||||
PHP_FE(array_multisort, all_args_prefer_ref)
|
||||
PHP_FE(array_push, first_arg_force_ref)
|
||||
PHP_FE(array_pop, first_arg_force_ref)
|
||||
PHP_FE(array_shift, first_arg_force_ref)
|
||||
@@ -1029,6 +1033,15 @@ PHP_MINIT_FUNCTION(basic)
|
||||
REGISTER_LONG_CONSTANT("SUNFUNCS_RET_STRING", SUNFUNCS_RET_STRING, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("SUNFUNCS_RET_DOUBLE", SUNFUNCS_RET_DOUBLE, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_SCHEME", PHP_URL_SCHEME, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_HOST", PHP_URL_HOST, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_PORT", PHP_URL_PORT, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_USER", PHP_URL_USER, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_PASS", PHP_URL_PASS, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_PATH", PHP_URL_PATH, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_QUERY", PHP_URL_QUERY, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_FRAGMENT", PHP_URL_FRAGMENT, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
#define REGISTER_MATH_CONSTANT(x) REGISTER_DOUBLE_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
|
||||
REGISTER_MATH_CONSTANT(M_E);
|
||||
REGISTER_MATH_CONSTANT(M_LOG2E);
|
||||
@@ -2784,7 +2797,7 @@ PHP_FUNCTION(connection_status)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int ignore_user_abort(bool value)
|
||||
/* {{{ proto int ignore_user_abort(string value)
|
||||
Set whether we want to ignore a user abort event or not */
|
||||
PHP_FUNCTION(ignore_user_abort)
|
||||
{
|
||||
|
||||
+57
-40
@@ -1433,52 +1433,60 @@ PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string stristr(string haystack, string needle)
|
||||
/* {{{ proto string stristr(string haystack, string needle[, bool part])
|
||||
Finds first occurrence of a string within another, case insensitive */
|
||||
PHP_FUNCTION(stristr)
|
||||
{
|
||||
zval **haystack, **needle;
|
||||
char *haystack;
|
||||
long haystack_len;
|
||||
zval *needle;
|
||||
zend_bool part = 0;
|
||||
char *found = NULL;
|
||||
int found_offset;
|
||||
char *haystack_orig;
|
||||
char needle_char[2];
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
SEPARATE_ZVAL(haystack);
|
||||
SEPARATE_ZVAL(needle);
|
||||
|
||||
convert_to_string_ex(haystack);
|
||||
SEPARATE_ZVAL(&needle);
|
||||
|
||||
haystack_orig = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack));
|
||||
haystack_orig = estrndup(haystack, haystack_len);
|
||||
|
||||
if (Z_TYPE_PP(needle) == IS_STRING) {
|
||||
if (!Z_STRLEN_PP(needle)) {
|
||||
if (Z_TYPE_P(needle) == IS_STRING) {
|
||||
if (!Z_STRLEN_P(needle)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter.");
|
||||
efree(haystack_orig);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
found = php_stristr(Z_STRVAL_PP(haystack),
|
||||
Z_STRVAL_PP(needle),
|
||||
Z_STRLEN_PP(haystack),
|
||||
Z_STRLEN_PP(needle));
|
||||
found = php_stristr(haystack,
|
||||
Z_STRVAL_P(needle),
|
||||
haystack_len,
|
||||
Z_STRLEN_P(needle));
|
||||
} else {
|
||||
convert_to_long_ex(needle);
|
||||
needle_char[0] = (char) Z_LVAL_PP(needle);
|
||||
convert_to_long_ex(&needle);
|
||||
needle_char[0] = (char) Z_LVAL_P(needle);
|
||||
needle_char[1] = 0;
|
||||
|
||||
found = php_stristr(Z_STRVAL_PP(haystack),
|
||||
found = php_stristr(haystack,
|
||||
needle_char,
|
||||
Z_STRLEN_PP(haystack),
|
||||
haystack_len,
|
||||
1);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
found_offset = found - Z_STRVAL_PP(haystack);
|
||||
RETVAL_STRINGL(haystack_orig + found_offset, Z_STRLEN_PP(haystack) - found_offset, 1);
|
||||
found_offset = found - haystack;
|
||||
if (part) {
|
||||
char *ret;
|
||||
ret = emalloc(found_offset + 1);
|
||||
strncpy(ret, haystack_orig, found_offset);
|
||||
ret[found_offset] = '\0';
|
||||
RETVAL_STRINGL(ret , found_offset, 0);
|
||||
} else {
|
||||
RETVAL_STRINGL(haystack_orig + found_offset, haystack_len - found_offset, 1);
|
||||
}
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
@@ -1487,45 +1495,54 @@ PHP_FUNCTION(stristr)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string strstr(string haystack, string needle)
|
||||
/* {{{ proto string strstr(string haystack, string needle[, bool part])
|
||||
Finds first occurrence of a string within another */
|
||||
PHP_FUNCTION(strstr)
|
||||
{
|
||||
zval **haystack, **needle;
|
||||
char *haystack;
|
||||
long haystack_len;
|
||||
zval *needle;
|
||||
zend_bool part = 0;
|
||||
char *found = NULL;
|
||||
char needle_char[2];
|
||||
long found_offset;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
convert_to_string_ex(haystack);
|
||||
|
||||
if (Z_TYPE_PP(needle) == IS_STRING) {
|
||||
if (!Z_STRLEN_PP(needle)) {
|
||||
if (Z_TYPE_P(needle) == IS_STRING) {
|
||||
if (!Z_STRLEN_P(needle)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter.");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
found = php_memnstr(Z_STRVAL_PP(haystack),
|
||||
Z_STRVAL_PP(needle),
|
||||
Z_STRLEN_PP(needle),
|
||||
Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack));
|
||||
found = php_memnstr(haystack,
|
||||
Z_STRVAL_P(needle),
|
||||
Z_STRLEN_P(needle),
|
||||
haystack + haystack_len);
|
||||
} else {
|
||||
convert_to_long_ex(needle);
|
||||
needle_char[0] = (char) Z_LVAL_PP(needle);
|
||||
convert_to_long_ex(&needle);
|
||||
needle_char[0] = (char) Z_LVAL_P(needle);
|
||||
needle_char[1] = 0;
|
||||
|
||||
found = php_memnstr(Z_STRVAL_PP(haystack),
|
||||
found = php_memnstr(haystack,
|
||||
needle_char,
|
||||
1,
|
||||
Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack));
|
||||
haystack + haystack_len);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
found_offset = found - Z_STRVAL_PP(haystack);
|
||||
RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1);
|
||||
found_offset = found - haystack;
|
||||
if (part) {
|
||||
char *ret;
|
||||
ret = emalloc(found_offset + 1);
|
||||
strncpy(ret, haystack, found_offset);
|
||||
ret[found_offset] = '\0';
|
||||
RETURN_STRINGL(ret , found_offset, 0);
|
||||
} else {
|
||||
RETURN_STRINGL(found, haystack_len - found_offset, 1);
|
||||
}
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #29253 array_diff with $GLOBALS argument fails
|
||||
--FILE--
|
||||
<?php
|
||||
$zz = $GLOBALS;
|
||||
$gg = 'afad';
|
||||
var_dump(array_diff_assoc($GLOBALS, $zz));
|
||||
var_dump($gg);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
string(4) "afad"
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
--TEST--
|
||||
Bug #33940 array_map() fails to pass by reference when called recursively
|
||||
--INI--
|
||||
error_reporting=4095
|
||||
--FILE--
|
||||
<?php
|
||||
function ref_map(&$item) {
|
||||
if(!is_array($item)) {
|
||||
$item = 1;
|
||||
return 2;
|
||||
} else {
|
||||
$ret = array_map('ref_map', &$item);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
$a = array(array(0), 0);
|
||||
$ret = array_map('ref_map', $a);
|
||||
echo 'Array: '; print_r($a);
|
||||
echo 'Return: '; print_r($ret);
|
||||
$a = array(array(0), 0);
|
||||
$ret = array_map('ref_map', &$a);
|
||||
echo 'Array: '; print_r($a);
|
||||
echo 'Return: '; print_r($ret);
|
||||
?>
|
||||
--EXPECT--
|
||||
Array: Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => 0
|
||||
)
|
||||
|
||||
[1] => 0
|
||||
)
|
||||
Return: Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => 2
|
||||
)
|
||||
|
||||
[1] => 2
|
||||
)
|
||||
Array: Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => 1
|
||||
)
|
||||
|
||||
[1] => 1
|
||||
)
|
||||
Return: Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => 2
|
||||
)
|
||||
|
||||
[1] => 2
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
stristr() function
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(stristr("tEsT sTrInG", "tEsT"));
|
||||
var_dump(stristr("tEsT sTrInG", "stRiNg"));
|
||||
var_dump(stristr("tEsT sTrInG", "stRiN"));
|
||||
var_dump(stristr("tEsT sTrInG", "t S"));
|
||||
var_dump(stristr("tEsT sTrInG", "g"));
|
||||
var_dump(md5(stristr("te".chr(0)."st", chr(0))));
|
||||
var_dump(@stristr("", ""));
|
||||
var_dump(@stristr("a", ""));
|
||||
var_dump(@stristr("", "a"));
|
||||
var_dump(md5(@stristr("\\\\a\\", "\\a")));
|
||||
var_dump(stristr("tEsT sTrInG", " ", false));
|
||||
var_dump(stristr("tEsT sTrInG", " ", true));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(11) "tEsT sTrInG"
|
||||
string(6) "sTrInG"
|
||||
string(6) "sTrInG"
|
||||
string(8) "T sTrInG"
|
||||
string(1) "G"
|
||||
string(32) "7272696018bdeb2c9a3f8d01fc2a9273"
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
string(32) "6ec19f52f0766c463f3bb240f4396913"
|
||||
string(7) " sTrInG"
|
||||
string(4) "tEsT"
|
||||
@@ -14,6 +14,8 @@ strstr() function
|
||||
var_dump(@strstr("a", ""));
|
||||
var_dump(@strstr("", "a"));
|
||||
var_dump(md5(@strstr("\\\\a\\", "\\a")));
|
||||
var_dump(strstr("test string", " ", false));
|
||||
var_dump(strstr("test string", " ", true));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(11) "test string"
|
||||
@@ -28,3 +30,5 @@ bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
string(32) "6ec19f52f0766c463f3bb240f4396913"
|
||||
string(7) " string"
|
||||
string(4) "test"
|
||||
+38
-4
@@ -327,15 +327,16 @@ end:
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto array parse_url(string url)
|
||||
/* {{{ proto mixed parse_url(string url, [int url_component])
|
||||
Parse a URL and return its components */
|
||||
PHP_FUNCTION(parse_url)
|
||||
{
|
||||
char *str;
|
||||
int str_len;
|
||||
php_url *resource;
|
||||
long key = -1;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &key) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,6 +346,39 @@ PHP_FUNCTION(parse_url)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (key > -1) {
|
||||
switch (key) {
|
||||
case PHP_URL_SCHEME:
|
||||
if (resource->scheme != NULL) RETVAL_STRING(resource->scheme, 1);
|
||||
break;
|
||||
case PHP_URL_HOST:
|
||||
if (resource->host != NULL) RETVAL_STRING(resource->host, 1);
|
||||
break;
|
||||
case PHP_URL_PORT:
|
||||
if (resource->port != 0) RETVAL_LONG(resource->port);
|
||||
break;
|
||||
case PHP_URL_USER:
|
||||
if (resource->user != NULL) RETVAL_STRING(resource->user, 1);
|
||||
break;
|
||||
case PHP_URL_PASS:
|
||||
if (resource->pass != NULL) RETVAL_STRING(resource->pass, 1);
|
||||
break;
|
||||
case PHP_URL_PATH:
|
||||
if (resource->path != NULL) RETVAL_STRING(resource->path, 1);
|
||||
break;
|
||||
case PHP_URL_QUERY:
|
||||
if (resource->query != NULL) RETVAL_STRING(resource->query, 1);
|
||||
break;
|
||||
case PHP_URL_FRAGMENT:
|
||||
if (resource->fragment != NULL) RETVAL_STRING(resource->fragment, 1);
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid url component identifier %ld.", key);
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* allocate an array for return */
|
||||
array_init(return_value);
|
||||
|
||||
@@ -365,8 +399,8 @@ PHP_FUNCTION(parse_url)
|
||||
add_assoc_string(return_value, "query", resource->query, 1);
|
||||
if (resource->fragment != NULL)
|
||||
add_assoc_string(return_value, "fragment", resource->fragment, 1);
|
||||
|
||||
php_url_free(resource);
|
||||
done:
|
||||
php_url_free(resource);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -46,6 +46,15 @@ PHP_FUNCTION(rawurlencode);
|
||||
PHP_FUNCTION(rawurldecode);
|
||||
PHP_FUNCTION(get_headers);
|
||||
|
||||
#define PHP_URL_SCHEME 0
|
||||
#define PHP_URL_HOST 1
|
||||
#define PHP_URL_PORT 2
|
||||
#define PHP_URL_USER 3
|
||||
#define PHP_URL_PASS 4
|
||||
#define PHP_URL_PATH 5
|
||||
#define PHP_URL_QUERY 6
|
||||
#define PHP_URL_FRAGMENT 7
|
||||
|
||||
#endif /* URL_H */
|
||||
|
||||
/*
|
||||
|
||||
+14
-4
@@ -997,10 +997,20 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
|
||||
ent1->data->refcount--;
|
||||
add_property_zval(ent2->data, ent1->varname, ent1->data);
|
||||
EG(scope) = old_scope;
|
||||
} else
|
||||
zend_hash_update(target_hash,
|
||||
ent1->varname, strlen(ent1->varname)+1,
|
||||
&ent1->data, sizeof(zval *), NULL);
|
||||
} else {
|
||||
long l;
|
||||
double d;
|
||||
|
||||
switch (is_numeric_string(ent1->varname, strlen(ent1->varname), &l, &d, 0)) {
|
||||
case IS_DOUBLE:
|
||||
l = (long) d;
|
||||
case IS_LONG:
|
||||
zend_hash_index_update(target_hash, l, &ent1->data, sizeof(zval *), NULL);
|
||||
break;
|
||||
default:
|
||||
zend_hash_update(target_hash,ent1->varname, strlen(ent1->varname)+1, &ent1->data, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
efree(ent1->varname);
|
||||
} else {
|
||||
zend_hash_next_index_insert(target_hash,
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
XMLWriter
|
||||
Rob Richards
|
||||
Pierre-Alain Joye
|
||||
@@ -1,5 +0,0 @@
|
||||
- Fix up config file for PHP 5 to use libxml extension configuration
|
||||
- Add tests for Namespace functions/methods
|
||||
- Sync with xmlwriter (new dtd func?)
|
||||
- Write documentations in docbook
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
|
||||
AC_DEFUN([PHP_XMLWRITER_CHECK_VERSION],[
|
||||
old_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS=-I$XMLWRITER_DIR/include$XMLWRITER_DIR_ADD
|
||||
AC_MSG_CHECKING(for libxml version)
|
||||
AC_EGREP_CPP(yes,[
|
||||
#include <libxml/xmlversion.h>
|
||||
#if LIBXML_VERSION >= 20600
|
||||
yes
|
||||
#endif
|
||||
],[
|
||||
AC_MSG_RESULT(>= 2.6.0)
|
||||
],[
|
||||
AC_MSG_ERROR(libxml version 2.6.0 or greater required.)
|
||||
])
|
||||
CPPFLAGS=$old_CPPFLAGS
|
||||
])
|
||||
|
||||
PHP_ARG_WITH(xmlwriter, for XMLWriter support,
|
||||
[ --with-xmlwriter Include XMLWriter support.])
|
||||
|
||||
if test "$PHP_XMLWRITER" != "no"; then
|
||||
|
||||
XMLWRITER_DIR_ADD=""
|
||||
if test -r $PHP_XMLWRITER/include/libxml2/libxml/xmlwriter.h; then
|
||||
XMLWRITER_DIR=$PHP_XMLWRITER
|
||||
XMLWRITER_DIR_ADD="/libxml2"
|
||||
elif test -r $PHP_XMLWRITER/include/libxml/xmlwriter.h; then
|
||||
XMLWRITER_DIR=$PHP_XMLWRITER
|
||||
else
|
||||
for i in /usr/local /usr; do
|
||||
test -r $i/include/libxml/xmlwriter.h && XMLWRITER_DIR=$i
|
||||
test -r $i/include/libxml2/libxml/xmlwriter.h && XMLWRITER_DIR=$i && XMLWRITER_DIR_ADD="/libxml2"
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$XMLWRITER_DIR"; then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR(Please reinstall the libxml >= 2.6.0 distribution)
|
||||
fi
|
||||
|
||||
PHP_XMLWRITER_CHECK_VERSION
|
||||
|
||||
XML2_CONFIG=$XMLWRITER_DIR/bin/xml2-config
|
||||
|
||||
if test -x $XML2_CONFIG; then
|
||||
XMLWRITER_LIBS=`$XML2_CONFIG --libs`
|
||||
PHP_EVAL_LIBLINE($XMLWRITER_LIBS, XMLWRITER_SHARED_LIBADD)
|
||||
else
|
||||
PHP_ADD_LIBRARY_WITH_PATH($XMLWRITER_LIBNAME, $XMLWRITER_DIR/lib, XMLWRITER_SHARED_LIBADD)
|
||||
fi
|
||||
|
||||
PHP_ADD_INCLUDE($XMLWRITER_DIR/include$XMLWRITER_DIR_ADD)
|
||||
|
||||
AC_DEFINE(HAVE_XMLWRITER,1,[ ])
|
||||
PHP_NEW_EXTENSION(xmlwriter, php_xmlwriter.c, $ext_shared)
|
||||
PHP_SUBST(XMLWRITER_SHARED_LIBADD)
|
||||
fi
|
||||
@@ -1,18 +0,0 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("xmlwriter", "XMLWriter support", "no");
|
||||
|
||||
if (PHP_XMLWRITER == "yes" && PHP_LIBXML == "yes") {
|
||||
if (CHECK_HEADER_ADD_INCLUDE('libxml/xmlwriter.h', 'CFLAGS_XMLWRITER', PHP_XMLWRITER)) {
|
||||
EXTENSION("xmlwriter", "php_xmlwriter.c");
|
||||
AC_DEFINE("HAVE_XMLWRITER", 1, "XMLWriter support");
|
||||
if (!PHP_XMLWRITER_SHARED) {
|
||||
ADD_FLAG("CFLAGS_XMLWRITER", "/D LIBXML_STATIC");
|
||||
}
|
||||
ADD_EXTENSION_DEP('xmlwriter', 'libxml');
|
||||
} else {
|
||||
WARNING('Could not find xmlwriter.h');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
dl('xmlwriter.so');
|
||||
|
||||
$xw = xmlwriter_open_uri('./a.xml');
|
||||
xmlwriter_set_indent($xw, 1);
|
||||
$res = xmlwriter_set_indent_string($xw, ' ');
|
||||
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
|
||||
// A first element
|
||||
xmlwriter_start_element($xw, 'tag1');
|
||||
|
||||
// Attribute 'att1' for element 'tag1'
|
||||
xmlwriter_start_attribute($xw, 'att1');
|
||||
xmlwriter_text($xw, 'valueofatt1');
|
||||
xmlwriter_end_attribute($xw);
|
||||
|
||||
xmlwriter_write_comment($xw, 'this is a comment.');
|
||||
|
||||
// Start a child element
|
||||
xmlwriter_start_element($xw, 'tag11');
|
||||
xmlwriter_text($xw, utf8_encode('This is a sample text, ä'));
|
||||
xmlwriter_end_element($xw); // tag11
|
||||
|
||||
xmlwriter_end_element($xw); // tag1
|
||||
|
||||
|
||||
// CDATA
|
||||
xmlwriter_start_element($xw, 'testc');
|
||||
xmlwriter_write_cdata($xw, "This is a cdata content");
|
||||
xmlwriter_end_element($xw); // testctag
|
||||
|
||||
xmlwriter_start_element($xw, 'testc');
|
||||
xmlwriter_start_cdata($xw);
|
||||
xmlwriter_text($xw, "test cdata2");
|
||||
xmlwriter_end_cdata($xw);
|
||||
xmlwriter_end_element($xw); // testctag
|
||||
|
||||
// A processing instruction
|
||||
xmlwriter_start_pi($xw, 'php');
|
||||
xmlwriter_text($xw, '$foo=2;echo $foo;');
|
||||
xmlwriter_end_pi($xw);
|
||||
|
||||
xmlwriter_end_document($xw);
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
dl('xmlwriter.so');
|
||||
|
||||
$xw = xmlwriter_open_memory();
|
||||
xmlwriter_set_indent($xw, 1);
|
||||
$res = xmlwriter_set_indent_string($xw, ' ');
|
||||
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
|
||||
// A first element
|
||||
xmlwriter_start_element($xw, 'tag1');
|
||||
|
||||
// Attribute 'att1' for element 'tag1'
|
||||
xmlwriter_start_attribute($xw, 'att1');
|
||||
xmlwriter_text($xw, 'valueofatt1');
|
||||
xmlwriter_end_attribute($xw);
|
||||
|
||||
xmlwriter_text($xw, utf8_encode('This is a sample text, ä'));
|
||||
xmlwriter_end_element($xw); // tag1
|
||||
|
||||
|
||||
$res = xmlwriter_start_comment($xw);
|
||||
xmlwriter_text($xw, "Demo text comment");
|
||||
$res = xmlwriter_end_comment($xw);
|
||||
|
||||
xmlwriter_end_document($xw);
|
||||
$out = xmlwriter_output_memory($xw, 0);
|
||||
|
||||
echo $out;
|
||||
|
||||
// flush the xml buffer using optional
|
||||
// flust argument, default is 1
|
||||
$out = xmlwriter_output_memory($xw, 1);
|
||||
echo $out;
|
||||
|
||||
|
||||
$out = xmlwriter_output_memory($xw);
|
||||
echo $out;
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
dl('xmlwriter.so');
|
||||
|
||||
$xw = xmlwriter_open_memory();
|
||||
xmlwriter_set_indent($xw, 1);
|
||||
$res = xmlwriter_set_indent_string($xw, ' ');
|
||||
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
// A first element
|
||||
xmlwriter_start_element_ns($xw,'prefix', 'books', 'uri');
|
||||
xmlwriter_start_attribute($xw, 'isbn');
|
||||
|
||||
/* Uncomment this line if you have libxml 2.6.17 or CVS version
|
||||
after 2005/02/22
|
||||
earlier versions segfault
|
||||
*/
|
||||
/*
|
||||
xmlwriter_start_attribute_ns($xw, 'prefix', 'isbn', 'uri');
|
||||
xmlwriter_end_attribute($xw);
|
||||
*/
|
||||
xmlwriter_end_attribute($xw);
|
||||
|
||||
xmlwriter_text($xw, 'book1');
|
||||
xmlwriter_end_element($xw);
|
||||
|
||||
xmlwriter_end_document($xw);
|
||||
$out = xmlwriter_output_memory($xw, 0);
|
||||
|
||||
echo $out;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
$xw = new XMLWriter();
|
||||
$xw->openUri('test.xml');
|
||||
$xw->startDocument("1.0");
|
||||
$xw->startElement("book");
|
||||
$xw->text("example");
|
||||
$xw->endElement();
|
||||
$xw->endDocument();
|
||||
$xw->flush(0);
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../package.dtd">
|
||||
<package>
|
||||
<name>xmlwriter</name>
|
||||
<summary>Provides fast, non-cached, forward-only means to write XML data.</summary>
|
||||
<description>
|
||||
This extension wraps the libxml xmlWriter API. Represents a writer that
|
||||
provides a non-cached, forward-only means of generating streams or files
|
||||
containing XML data.
|
||||
</description>
|
||||
<license>PHP License</license>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>rrichards</user>
|
||||
<name>Rob Richards</name>
|
||||
<email>rrichards@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<maintainer>
|
||||
<user>pajoye</user>
|
||||
<name>Pierre-Alain Joye</name>
|
||||
<email>pierre.dev@gmail.com</email>
|
||||
<role>developer</role>
|
||||
</maintainer>
|
||||
<release>
|
||||
<version>2.0.0</version>
|
||||
<date>2005-08-07</date>
|
||||
<state>stable</state>
|
||||
<notes>
|
||||
fix tests using UTF-8
|
||||
move to stable state
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
<changelog>
|
||||
<release>
|
||||
<version>1.1.0</version>
|
||||
<date>2005-05-24</date>
|
||||
<state>beta</state>
|
||||
<notes>
|
||||
Add OO interface (php5 only)
|
||||
Add test cases
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>1.0</version>
|
||||
<date>2005-05-02</date>
|
||||
<state>stable</state>
|
||||
<notes>
|
||||
Many Bug Fixes
|
||||
Use PHP streams under PHP 4
|
||||
Add xmlwriter_flush function to flush buffer
|
||||
Add support for xmlTextWriterStart/EndComment
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<date>2004-07-20</date>
|
||||
<state>alpha</state>
|
||||
<notes>Initial Release </notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>0.2</version>
|
||||
<date>2004-10-08</date>
|
||||
<state>alpha</state>
|
||||
<notes>Fix bug 2482 and other function parameters</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
|
||||
<configureoptions>
|
||||
<configureoption name="with-xmlwriter" default="autodetect" prompt="Include XMLWriter support?"/>
|
||||
</configureoptions>
|
||||
<filelist>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="php_xmlwriter.c"/>
|
||||
<file role="src" name="php_xmlwriter.h"/>
|
||||
<dir name="tests" role="test">
|
||||
<file name="001.phpt"/>
|
||||
<file name="002.phpt"/>
|
||||
<file name="003.phpt"/>
|
||||
<file name="004.phpt"/>
|
||||
<file name="OO_001.phpt"/>
|
||||
<file name="OO_002.phpt"/>
|
||||
<file name="OO_003.phpt"/>
|
||||
<file name="OO_004.phpt"/>
|
||||
</dir>
|
||||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="4.3.0" />
|
||||
</deps>
|
||||
</package>
|
||||
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<package packagerversion="1.4.0a2" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<name>xmlwriter</name>
|
||||
<channel>pecl.php.net</channel>
|
||||
<summary>Provides fast, non-cached, forward-only means to write XML data.</summary>
|
||||
<description>
|
||||
This extension wraps the libxml xmlWriter API. Represents a writer that
|
||||
provides a non-cached, forward-only means of generating streams or files
|
||||
containing XML data.
|
||||
</description>
|
||||
<lead>
|
||||
<name>Rob Richards</name>
|
||||
<user>rrichards</user>
|
||||
<email>rrichards@php.net</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<developer>
|
||||
<name>Pierre-Alain Joye</name>
|
||||
<user>pajoye</user>
|
||||
<email>pajoye@php.net</email>
|
||||
<active>yes</active>
|
||||
</developer>
|
||||
<date>2005-08-07</date>
|
||||
<time>01:20:00</time>
|
||||
<version>
|
||||
<release>2.0.0</release>
|
||||
<api>2.0.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<license uri="http://www.php.net/license/3_0.txt">PHP</license>
|
||||
<notes>Promote to stable</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="php_xmlwriter.c"/>
|
||||
<file role="src" name="php_xmlwriter.h"/>
|
||||
<dir name="tests" role="test">
|
||||
<file role="test" name="001.phpt"/>
|
||||
<file role="test" name="002.phpt"/>
|
||||
<file role="test" name="003.phpt"/>
|
||||
<file role="test" name="004.phpt"/>
|
||||
<file role="test" name="OO_001.phpt"/>
|
||||
<file role="test" name="OO_002.phpt"/>
|
||||
<file role="test" name="OO_003.phpt"/>
|
||||
<file role="test" name="OO_004.phpt"/>
|
||||
</dir>
|
||||
</dir>
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>4.3.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0a2</min>
|
||||
</pearinstaller>
|
||||
</required>
|
||||
</dependencies>
|
||||
<providesextension>xmlwriter</providesextension>
|
||||
<extsrcrelease />
|
||||
</package>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Rob Richards <rrichards@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_XMLWRITER_H
|
||||
#define PHP_XMLWRITER_H
|
||||
|
||||
extern zend_module_entry xmlwriter_module_entry;
|
||||
#define phpext_xmlwriter_ptr &xmlwriter_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_XMLWRITER_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_XMLWRITER_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include <libxml/uri.h>
|
||||
|
||||
/* Resource struct, not the object :) */
|
||||
typedef struct _xmlwriter_object {
|
||||
xmlTextWriterPtr ptr;
|
||||
xmlBufferPtr output;
|
||||
#ifndef ZEND_ENGINE_2
|
||||
xmlOutputBufferPtr uri_output;
|
||||
#endif
|
||||
} xmlwriter_object;
|
||||
|
||||
|
||||
/* Extends zend object */
|
||||
typedef struct _ze_xmlwriter_object {
|
||||
zend_object zo;
|
||||
xmlwriter_object *xmlwriter_ptr;
|
||||
} ze_xmlwriter_object;
|
||||
|
||||
static void xmlwriter_free_resource_ptr(xmlwriter_object *intern TSRMLS_DC);
|
||||
static void xmlwriter_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
|
||||
|
||||
zend_class_entry *xmlwriter_class_entry_ce;
|
||||
|
||||
#if LIBXML_VERSION >= 20605
|
||||
PHP_FUNCTION(xmlwriter_set_indent);
|
||||
PHP_FUNCTION(xmlwriter_set_indent_string);
|
||||
#endif
|
||||
PHP_FUNCTION(xmlwriter_start_attribute);
|
||||
PHP_FUNCTION(xmlwriter_end_attribute);
|
||||
PHP_FUNCTION(xmlwriter_start_attribute_ns);
|
||||
PHP_FUNCTION(xmlwriter_write_attribute);
|
||||
#if LIBXML_VERSION > 20617
|
||||
PHP_FUNCTION(xmlwriter_write_attribute_ns);
|
||||
#endif
|
||||
PHP_FUNCTION(xmlwriter_start_element);
|
||||
PHP_FUNCTION(xmlwriter_end_element);
|
||||
PHP_FUNCTION(xmlwriter_start_element_ns);
|
||||
PHP_FUNCTION(xmlwriter_write_element);
|
||||
PHP_FUNCTION(xmlwriter_write_element_ns);
|
||||
PHP_FUNCTION(xmlwriter_start_pi);
|
||||
PHP_FUNCTION(xmlwriter_end_pi);
|
||||
PHP_FUNCTION(xmlwriter_write_pi);
|
||||
PHP_FUNCTION(xmlwriter_start_cdata);
|
||||
PHP_FUNCTION(xmlwriter_end_cdata);
|
||||
PHP_FUNCTION(xmlwriter_write_cdata);
|
||||
PHP_FUNCTION(xmlwriter_text);
|
||||
PHP_FUNCTION(xmlwriter_start_document);
|
||||
PHP_FUNCTION(xmlwriter_end_document);
|
||||
#if LIBXML_VERSION >= 20607
|
||||
PHP_FUNCTION(xmlwriter_start_comment);
|
||||
PHP_FUNCTION(xmlwriter_end_comment);
|
||||
#endif
|
||||
PHP_FUNCTION(xmlwriter_write_comment);
|
||||
PHP_FUNCTION(xmlwriter_start_dtd);
|
||||
PHP_FUNCTION(xmlwriter_end_dtd);
|
||||
PHP_FUNCTION(xmlwriter_write_dtd);
|
||||
PHP_FUNCTION(xmlwriter_start_dtd_element);
|
||||
PHP_FUNCTION(xmlwriter_end_dtd_element);
|
||||
PHP_FUNCTION(xmlwriter_open_uri);
|
||||
PHP_FUNCTION(xmlwriter_open_memory);
|
||||
PHP_FUNCTION(xmlwriter_output_memory);
|
||||
PHP_FUNCTION(xmlwriter_flush);
|
||||
|
||||
#endif /* PHP_XMLWRITER_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
||||
@@ -1,25 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, file buffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = xmlwriter_open_uri($doc_dest);
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
xmlwriter_start_element($xw, "tag1");
|
||||
xmlwriter_end_document($xw);
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$output_bytes = xmlwriter_flush($xw, true);
|
||||
echo file_get_contents($doc_dest);
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1/>
|
||||
===DONE===
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, membuffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = xmlwriter_open_memory($doc_dest);
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
xmlwriter_start_element($xw, "tag1");
|
||||
xmlwriter_end_document($xw);
|
||||
|
||||
// Force to write and empty the buffer
|
||||
echo xmlwriter_flush($xw, true);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1/>
|
||||
===DONE===
|
||||
@@ -1,35 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, membuffer, flush, attribute
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = xmlwriter_open_memory($doc_dest);
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
xmlwriter_start_element($xw, "tag1");
|
||||
|
||||
|
||||
$res = xmlwriter_start_attribute($xw, 'attr1');
|
||||
xmlwriter_text($xw, "attr1_value");
|
||||
xmlwriter_end_attribute($xw);
|
||||
|
||||
xmlwriter_write_attribute($xw, "att2", "att2_value");
|
||||
xmlwriter_text($xw, "Test text for tag1");
|
||||
$res = xmlwriter_start_element($xw, 'tag2');
|
||||
if ($res < 1) {
|
||||
echo "StartElement context validation failed\n";
|
||||
exit();
|
||||
}
|
||||
xmlwriter_end_document($xw);
|
||||
|
||||
// Force to write and empty the buffer
|
||||
echo xmlwriter_flush($xw, true);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1 attr1="attr1_value" att2="att2_value">Test text for tag1<tag2/></tag1>
|
||||
===DONE===
|
||||
@@ -1,36 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, file buffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = xmlwriter_open_uri($doc_dest);
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
xmlwriter_start_element($xw, "tag1");
|
||||
|
||||
xmlwriter_start_pi($xw, "PHP");
|
||||
xmlwriter_text($xw, 'echo $a;');
|
||||
xmlwriter_end_pi($xw);
|
||||
xmlwriter_end_document($xw);
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$output_bytes = xmlwriter_flush($xw, true);
|
||||
$md5_out = md5_file($doc_dest);
|
||||
$md5_res = md5('<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1><?PHP echo $a;?></tag1>
|
||||
');
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
if ($md5_out != $md5_res) {
|
||||
echo "failed: $md5_res != $md5_out\n";
|
||||
} else {
|
||||
echo "ok.\n";
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
ok.
|
||||
===DONE===
|
||||
@@ -1,33 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, comments
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("xmlwriter")) die("skip");
|
||||
if (!function_exists("xmlwriter_start_comment")) die("skip: libxml2 2.6.7+ required");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = xmlwriter_open_uri($doc_dest);
|
||||
xmlwriter_start_document($xw, '1.0', 'UTF-8');
|
||||
xmlwriter_start_element($xw, "tag1");
|
||||
|
||||
xmlwriter_start_comment($xw);
|
||||
xmlwriter_text($xw, 'comment');
|
||||
xmlwriter_end_comment($xw);
|
||||
xmlwriter_write_comment($xw, "comment #2");
|
||||
xmlwriter_end_document($xw);
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$output_bytes = xmlwriter_flush($xw, true);
|
||||
echo file_get_contents($doc_dest);
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1><!--comment--><!--comment #2--></tag1>
|
||||
===DONE===
|
||||
@@ -1,26 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, file buffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = new XMLWriter();
|
||||
$xw->openUri($doc_dest);
|
||||
$xw->startDocument('1.0', 'UTF-8', 'standalonearg');
|
||||
$xw->startElement("tag1");
|
||||
$xw->endDocument();
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$output_bytes = $xw->flush(true);
|
||||
echo file_get_contents($doc_dest);
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="standalonearg"?>
|
||||
<tag1/>
|
||||
===DONE===
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, membuffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$xw = new XMLWriter();
|
||||
$xw->openMemory();
|
||||
$xw->startDocument('1.0', 'UTF-8', 'standalone');
|
||||
$xw->startElement("tag1");
|
||||
$xw->endDocument();
|
||||
|
||||
// Force to write and empty the buffer
|
||||
echo $xw->flush(true);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="standalone"?>
|
||||
<tag1/>
|
||||
===DONE===
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, membuffer, flush, text, attribute
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$xw = new XMLWriter();
|
||||
$xw->openMemory();
|
||||
$xw->startDocument('1.0', 'UTF-8');
|
||||
$xw->startElement("tag1");
|
||||
|
||||
$res = $xw->startAttribute('attr1');
|
||||
$xw->text("attr1_value");
|
||||
$xw->endAttribute();
|
||||
|
||||
$res = $xw->startAttribute('attr2');
|
||||
$xw->text("attr2_value");
|
||||
$xw->endAttribute();
|
||||
|
||||
$xw->text("Test text for tag1");
|
||||
$res = $xw->startElement('tag2');
|
||||
if ($res < 1) {
|
||||
echo "StartElement context validation failed\n";
|
||||
exit();
|
||||
}
|
||||
$xw->endDocument();
|
||||
|
||||
// Force to write and empty the buffer
|
||||
echo $xw->flush(true);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1 attr1="attr1_value" attr2="attr2_value">Test text for tag1<tag2/></tag1>
|
||||
===DONE===
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, file buffer, flush
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlwriter")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = new XMLWriter();
|
||||
$xw->openUri($doc_dest);
|
||||
$xw->startDocument('1.0', 'UTF-8');
|
||||
$xw->startElement("tag1");
|
||||
|
||||
$xw->startPi("PHP");
|
||||
$xw->text('echo $a;');
|
||||
$xw->endPi();
|
||||
$xw->endDocument();
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$xw->flush(true);
|
||||
$md5_out = md5_file($doc_dest);
|
||||
$md5_res = md5('<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1><?PHP echo $a;?></tag1>
|
||||
');
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
if ($md5_out != $md5_res) {
|
||||
echo "failed: $md5_res != $md5_out\n";
|
||||
} else {
|
||||
echo "ok.\n";
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
ok.
|
||||
===DONE===
|
||||
@@ -1,33 +0,0 @@
|
||||
--TEST--
|
||||
XMLWriter: libxml2 XML Writer, comments
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("xmlwriter")) die("skip");
|
||||
if (!function_exists("xmlwriter_start_comment")) die("skip: libxml2 2.6.7+ required");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$doc_dest = '001.xml';
|
||||
$xw = new XMLWriter();
|
||||
$xw->openUri($doc_dest);
|
||||
$xw->startDocument('1.0', 'UTF-8');
|
||||
$xw->startElement("tag1");
|
||||
$xw->startComment();
|
||||
$xw->text('comment');
|
||||
$xw->endComment();
|
||||
$xw->writeComment("comment #2");
|
||||
$xw->endDocument();
|
||||
|
||||
// Force to write and empty the buffer
|
||||
$output_bytes = $xw->flush(true);
|
||||
echo file_get_contents($doc_dest);
|
||||
unset($xw);
|
||||
unlink('001.xml');
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tag1><!--comment--><!--comment #2--></tag1>
|
||||
===DONE===
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#define PHP_API_VERSION 20041225
|
||||
#define PHP_API_VERSION 20050809
|
||||
#define PHP_HAVE_STREAMS
|
||||
#define YYDEBUG 0
|
||||
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Sander Steffann (sander@steffann.nl) |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "php.h"
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef MAXSYMLINKS
|
||||
#define MAXSYMLINKS 32
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path[]);
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define IS_SLASH(p) ((p) == '/' || (p) == '\\')
|
||||
#else
|
||||
#define IS_SLASH(p) ((p) == '/')
|
||||
#endif
|
||||
|
||||
char *php_realpath(char *path, char resolved_path []) {
|
||||
char path_construction[MAXPATHLEN]; /* We build the result in here */
|
||||
char *writepos; /* Position to write next char */
|
||||
|
||||
char path_copy[MAXPATHLEN]; /* A work-copy of the path */
|
||||
char *workpos; /* working position in *path */
|
||||
|
||||
#if !defined(PHP_WIN32)
|
||||
char buf[MAXPATHLEN]; /* Buffer for readlink */
|
||||
int linklength; /* The result from readlink */
|
||||
#endif
|
||||
int linkcount = 0; /* Count symlinks to avoid loops */
|
||||
|
||||
struct stat filestat; /* result from stat */
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
char *temppos; /* position while counting '.' */
|
||||
int dotcount; /* number of '.' */
|
||||
int t; /* counter */
|
||||
#endif
|
||||
|
||||
/* Set the work-position to the beginning of the given path */
|
||||
strcpy(path_copy, path);
|
||||
workpos = path_copy;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* Find out where we start - Windows version */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
/* We start at the root of the current drive */
|
||||
/* Get the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
/* We only need the first three chars (for example "C:\") */
|
||||
path_construction[3] = 0;
|
||||
workpos++;
|
||||
} else if (workpos[1] == ':') {
|
||||
/* A drive-letter is specified, copy it */
|
||||
strncpy(path_construction, path, 2);
|
||||
strcat(path_construction, "\\");
|
||||
workpos++;
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "\\");
|
||||
}
|
||||
#else
|
||||
/* Find out where we start - Unix version */
|
||||
if (*workpos == '/') {
|
||||
/* We start at the root */
|
||||
strcpy(path_construction, "/");
|
||||
workpos++;
|
||||
} else {
|
||||
/* Use the current directory */
|
||||
if (V_GETCWD(path_construction, MAXPATHLEN-1) == NULL) {
|
||||
/* Unable to get cwd */
|
||||
resolved_path[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_construction, "/");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the next-char-position */
|
||||
writepos = &path_construction[strlen(path_construction)];
|
||||
|
||||
/* Go to the end, then stop */
|
||||
while(*workpos != 0) {
|
||||
/* Strip (back)slashes */
|
||||
while(IS_SLASH(*workpos)) workpos++;
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
/* reset dotcount */
|
||||
dotcount = 0;
|
||||
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
/* Windows accepts \...\ as \..\..\, \....\ as \..\..\..\, etc */
|
||||
/* At least Win98 does */
|
||||
|
||||
temppos = workpos;
|
||||
while(*temppos++ == '.') {
|
||||
dotcount++;
|
||||
if (!IS_SLASH(*temppos) && (*temppos != 0) && (*temppos != '.')) {
|
||||
/* This is not a /../ component, but a filename that starts with '.' */
|
||||
dotcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Go back dotcount-1 times */
|
||||
for (t=0 ; t<(dotcount-1) ; t++) {
|
||||
workpos++; /* move to next '.' */
|
||||
|
||||
/* Can we still go back? */
|
||||
if ((writepos-3) <= path_construction) return NULL;
|
||||
|
||||
/* Go back */
|
||||
writepos--; /* move to '\' */
|
||||
writepos--;
|
||||
while(!IS_SLASH(*writepos)) writepos--; /* skip until previous '\\' */
|
||||
}
|
||||
workpos++;
|
||||
}
|
||||
|
||||
/* No special case */
|
||||
if (dotcount == 0) {
|
||||
/* Append */
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just one '.', go to next element */
|
||||
if (dotcount == 1) {
|
||||
while(!IS_SLASH(*workpos) && (*workpos != 0)) {
|
||||
*workpos++;
|
||||
}
|
||||
|
||||
/* Avoid double \ in the result */
|
||||
writepos--;
|
||||
}
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (IS_SLASH(*workpos)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#else /* defined(PHP_WIN32) */
|
||||
/* Look for .. */
|
||||
if ((workpos[0] == '.') && (workpos[1] != 0)) {
|
||||
if ((workpos[1] == '.') && ((workpos[2] == '/') || (workpos[2] == 0))) {
|
||||
/* One directory back */
|
||||
/* Set pointers to right position */
|
||||
workpos++; /* move to second '.' */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Only apply .. if not in root */
|
||||
if ((writepos-1) > path_construction) {
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
}
|
||||
} else {
|
||||
if (workpos[1] == '/') {
|
||||
/* Found a /./ skip it */
|
||||
workpos++; /* move to '/' */
|
||||
|
||||
/* Avoid double / in the result */
|
||||
writepos--;
|
||||
} else {
|
||||
/* No special case, the name just started with a . */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No special case */
|
||||
/* Append */
|
||||
while((*workpos != '/') && (*workpos != 0)) {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SYMLINK
|
||||
/* We are going to use path_construction, so close it */
|
||||
*writepos = 0;
|
||||
|
||||
/* Check the current location to see if it is a symlink */
|
||||
if((linklength = readlink(path_construction, buf, MAXPATHLEN)) != -1) {
|
||||
/* Check linkcount */
|
||||
if (linkcount > MAXSYMLINKS) return NULL;
|
||||
|
||||
/* Count this symlink */
|
||||
linkcount++;
|
||||
|
||||
/* Set end of buf */
|
||||
buf[linklength] = 0;
|
||||
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + strlen(buf) + 1) >= MAXPATHLEN) return NULL;
|
||||
|
||||
/* Remove the symlink-component wrom path_construction */
|
||||
writepos--; /* move to '/' */
|
||||
while(*--writepos != '/') ; /* skip until previous '/' */
|
||||
*++writepos = 0; /* end of string after '/' */
|
||||
|
||||
/* If the symlink starts with a '/', empty path_construction */
|
||||
if (*buf == '/') {
|
||||
*path_construction = 0;
|
||||
writepos = path_construction;
|
||||
}
|
||||
|
||||
/* Insert symlink into path_copy */
|
||||
strcat(buf, workpos);
|
||||
strcpy(path_copy, buf);
|
||||
workpos = path_copy;
|
||||
}
|
||||
#endif /* HAVE_SYMLINK */
|
||||
|
||||
/* If it was a directory, append a slash */
|
||||
if (*workpos == '/') {
|
||||
*writepos++ = *workpos++;
|
||||
}
|
||||
*writepos = 0;
|
||||
#endif /* defined(PHP_WIN32) */
|
||||
}
|
||||
|
||||
/* Check if the resolved path is a directory */
|
||||
if (V_STAT(path_construction, &filestat) != 0) {
|
||||
if (errno != ENOENT) return NULL;
|
||||
} else {
|
||||
if (S_ISDIR(filestat.st_mode)) {
|
||||
/* It's a directory, append a / if needed */
|
||||
if (*(writepos-1) != '/') {
|
||||
/* Check for overflow */
|
||||
if ((strlen(workpos) + 2) >= MAXPATHLEN) {
|
||||
return NULL;
|
||||
}
|
||||
*writepos++ = '/';
|
||||
*writepos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(resolved_path, path_construction);
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -61,7 +61,7 @@ PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_arra
|
||||
{
|
||||
char *p = NULL;
|
||||
char *ip; /* index pointer */
|
||||
char *index;
|
||||
char *index, *escaped_index = NULL;
|
||||
int var_len, index_len;
|
||||
zval *gpc_element, **gpc_element_p;
|
||||
zend_bool is_array;
|
||||
@@ -114,7 +114,7 @@ PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_arra
|
||||
|
||||
while (1) {
|
||||
if (is_array) {
|
||||
char *escaped_index = NULL, *index_s;
|
||||
char *index_s;
|
||||
int new_idx_len = 0;
|
||||
|
||||
ip++;
|
||||
@@ -183,7 +183,6 @@ plain_var:
|
||||
zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
|
||||
} else {
|
||||
zval **tmp;
|
||||
char *escaped_index;
|
||||
|
||||
if (PG(magic_quotes_gpc)) {
|
||||
escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC);
|
||||
@@ -198,13 +197,13 @@ plain_var:
|
||||
*/
|
||||
if (PG(http_globals)[TRACK_VARS_COOKIE] && symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) &&
|
||||
zend_symtable_find(symtable1, escaped_index, index_len+1, (void **) &tmp) != FAILURE) {
|
||||
if (PG(magic_quotes_gpc)) {
|
||||
if (index != escaped_index) {
|
||||
efree(escaped_index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
zend_symtable_update(symtable1, escaped_index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
|
||||
if (PG(magic_quotes_gpc)) {
|
||||
if (index != escaped_index) {
|
||||
efree(escaped_index);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
/* automatically generated by configure */
|
||||
/* edit configure.in to change version number */
|
||||
#define PHP_MAJOR_VERSION 5
|
||||
#define PHP_MINOR_VERSION 1
|
||||
#define PHP_MAJOR_VERSION 6
|
||||
#define PHP_MINOR_VERSION 0
|
||||
#define PHP_RELEASE_VERSION 0
|
||||
#define PHP_EXTRA_VERSION "-dev"
|
||||
#define PHP_VERSION "5.1.0-dev"
|
||||
#define PHP_VERSION "6.0.0-dev"
|
||||
Loaded 100 of 103 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user