diff --git a/.gdbinit b/.gdbinit index e7a565dfa9cc6..b14b03da9fe82 100644 --- a/.gdbinit +++ b/.gdbinit @@ -106,7 +106,7 @@ define dump_bt printf "%ld", $zvalue->value.lval end if $type == 2 - printf "%lf", $zvalue->value.dval + printf "%f", $zvalue->value.dval end if $type == 3 if $zvalue->value.lval @@ -185,7 +185,7 @@ define ____printzv_contents printf "long: %ld", $zvalue->value.lval end if $type == 2 - printf "double: %lf", $zvalue->value.dval + printf "double: %f", $zvalue->value.dval end if $type == 3 printf "bool: " diff --git a/CODING_STANDARDS b/CODING_STANDARDS index 5ceacdc4dce55..a05d761cf14bb 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -259,7 +259,10 @@ The file labelled 'EXPERIMENTAL' should include the following information:: Any authoring information (known bugs, future directions of the module). - Ongoing status notes which may not be appropriate for SVN comments. + Ongoing status notes which may not be appropriate for Git comments. + +In general new features should go to PECL or experimental branches until +there are specific reasons for directly adding it to the core distribution. Aliases & Legacy Documentation ----------------------------------- diff --git a/Makefile.global b/Makefile.global index 05c5d151b74cc..bd82daf4d891e 100644 --- a/Makefile.global +++ b/Makefile.global @@ -120,7 +120,7 @@ clean: distclean: clean rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module sapi/apache_hooks/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h rm -f php5.spec main/build-defs.h scripts/phpize - rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/mysqlnd/php_mysqlnd_config.h + rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/oci8/oci8_dtrace_gen.h ext/oci8/oci8_dtrace_gen.h.bak rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 ext/phar/phar.1 ext/phar/phar.phar.1 rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html rm -f ext/iconv/php_have_bsd_iconv.h ext/iconv/php_have_glibc_iconv.h ext/iconv/php_have_ibm_iconv.h ext/iconv/php_have_iconv.h ext/iconv/php_have_libiconv.h ext/iconv/php_iconv_aliased_libiconv.h ext/iconv/php_iconv_supports_errno.h ext/iconv/php_php_iconv_h_path.h ext/iconv/php_php_iconv_impl.h diff --git a/NEWS b/NEWS index d0359fe185f41..fdfaef53cb58f 100644 --- a/NEWS +++ b/NEWS @@ -1,8732 +1,81 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2013, PHP 5.5.6 - -- Core: - . Fixed bug #65947 (basename is no more working after fgetcsv in certain - situation). (Laruence) - . Improved performance of array_merge() and func_get_args() by eliminating - useless copying. (Dmitry) - . Fixed bug #65939 (Space before ";" breaks php.ini parsing). - (brainstorm at nopcode dot org) - . Fixed bug #65911 (scope resolution operator - strange behavior with $this). - (Bob Weinand) - . Fixed bug #65936 (dangling context pointer causes crash). (Tony) - -- FPM: - . Changed default listen() backlog to 65535. (Tony) - -- MySQLi: - . Fixed bug #66043 (Segfault calling bind_param() on mysqli). (Laruence) - -- OPcache - . Increased limit for opcache.max_accelerated_files to 1,000,000. (Chris) - . Fixed issue #115 (path issue when using phar). (Dmitry) - . Fixed issue #149 (Phar mount points not working with OPcache enabled). - (Dmitry) - -- ODBC - . Fixed bug #65950 (Field name truncation if the field name is bigger than - 32 characters). (patch submitted by: michael dot y at zend dot com, Yasuo) - -- PDO: - . Fixed bug #66033 (Segmentation Fault when constructor of PDO statement - throws an exception). (Laruence) - . Fixed bug 65946 (sql_parser permanently converts values bound to strings) - -- Standard: - . Fixed bug #64760 (var_export() does not use full precision for floating-point - numbers) (Yasuo) - - -17 Oct 2013, PHP 5.5.5 - -- Core: - . Fixed bug #64979 (Wrong behavior of static variables in closure generators). - (Nikita) - . Fixed bug #65322 (compile time errors won't trigger auto loading). (Nikita) - . Fixed bug #65821 (By-ref foreach on property access of string offset - segfaults). (Nikita) - -- CLI server: - . Fixed bug #65633 (built-in server treat some http headers as - case-sensitive). (Adam) - . Fixed bug #65818 (Segfault with built-in webserver and chunked transfer - encoding). (Felipe) - . Added application/pdf to PHP CLI Web Server mime types (Chris Jones) - -- Datetime: - . Fixed bug #64157 (DateTime::createFromFormat() reports confusing error - message). (Boro Sitnikovski) - . Fixed bug #65502 (DateTimeImmutable::createFromFormat returns DateTime). - (Boro Sitnikovski) - . Fixed bug #65548 (Comparison for DateTimeImmutable doesn't work). - (Boro Sitnikovski) - -- DBA extension: - . Fixed bug #65708 (dba functions cast $key param to string in-place, - bypassing copy on write). (Adam) - -- Filter: - . Add RFC 6598 IPs to reserved addresses. (Sebastian Nohn) - . Fixed bug #64441 (FILTER_VALIDATE_URL rejects fully qualified domain names). - (Syra) - -- FTP: - . Fixed bug #65667 (ftp_nb_continue produces segfault). (Philip Hofstetter) - -- GD - . Ensure that the defined interpolation method is used with the generic - scaling methods. (Pierre) - -- IMAP: - . Fixed bug #65721 (configure script broken in 5.5.4 and 5.4.20 when enabling - imap). (ryotakatsuki at gmail dot com) - -- OPcache: - . Added support for GNU Hurd. (Svante Signell) - . Added function opcache_compile_file() to load PHP scripts into cache - without execution. (Julien) - . Fixed bug #65845 (Error when Zend Opcache Optimizer is fully enabled). - (Dmitry) - . Fixed bug #65665 (Exception not properly caught when opcache enabled). - (Laruence) - . Fixed bug #65510 (5.5.2 crashes in _get_zval_ptr_ptr_var). (Dmitry) - . Fixed issue #135 (segfault in interned strings if initial memory is too - low). (Julien) - -- Sockets: - . Fixed bug #65808 (the socket_connect() won't work with IPv6 address). - (Mike) - -- SPL: - . Fix bug #64782 (SplFileObject constructor make $context optional / give it - a default value). (Nikita) - -- Standard: - . Fixed bug #61548 (content-type must appear at the end of headers for 201 - Location to work in http). (Mike) - -- XMLReader: - . Fixed bug #51936 (Crash with clone XMLReader). (Mike) - . Fixed bug #64230 (XMLReader does not suppress errors). (Mike) - -- Build system: - . Fixed bug #51076 (race condition in shtool's mkdir -p implementation). - (Mike, Raphael Geissert) - . Fixed bug #62396 ('make test' crashes starting with 5.3.14 (missing - gzencode())). (Mike) - - -19 Sep 2013, PHP 5.5.4 - -- Core: - . Fixed bug #60598 (cli/apache sapi segfault on objects manipulation). - (Laruence) - . Improved fputcsv() to allow specifying escape character. - . Fixed bug #65490 (Duplicate calls to get lineno & filename for - DTRACE_FUNCTION_*). (Chris Jones) - . Fixed bug #65483 (quoted-printable encode stream filter incorrectly encoding - spaces). (Michael M Slusarz) - . Fixed bug #65481 (shutdown segfault due to serialize) (Mike) - . Fixed bug #65470 (Segmentation fault in zend_error() with - --enable-dtrace). (Chris Jones, Kris Van Hees) - . Fixed bug #65225 (PHP_BINARY incorrectly set). (Patrick Allaert) - . Fixed bug #62692 (PHP fails to build with DTrace). (Chris Jones, Kris Van Hees) - . Fixed bug #61759 (class_alias() should accept classes with leading - backslashes). (Julien) - . Fixed bug #46311 (Pointer aliasing issue results in miscompile on gcc4.4). - (Nikita Popov) +?? ??? 20??, PHP 5.6.0 + +- Core: + . Improved IS_VAR operands fetching. (Laruence, Dmitry) + . Implemented internal operator overloading + (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita) + . Made calls from incompatible context issue an E_DEPRECATED warning instead + of E_STRICT (phase 1 of RFC: https://wiki.php.net/rfc/incompat_ctx). + (Gustavo) + . Uploads equal or greater than 2GB in size are now accepted. + (Ralf Lang, Mike) + . Reduced POST data memory usage by 200-300%. Removed INI setting + always_populate_raw_post_data and the $HTTP_RAW_POST_DATA global + variable. (Mike) + . Implemented dedicated syntax for variadic functions + (RFC: https://wiki.php.net/rfc/variadics). (Nikita) + . Fixed bug #50333 Improving multi-threaded scalability by using + emalloc/efree/estrdup (Anatol, Dmitry) - cURL: - . Fixed bug #65458 (curl memory leak). (Adam) - -- Datetime: - . Fixed bug #65554 (createFromFormat broken when weekday name is followed - by some delimiters). (Valentin Logvinskiy, Stas). - . Fixed bug #65564 (stack-buffer-overflow in DateTimeZone stuff caught - by AddressSanitizer). (Remi). - -- OPCache: - . Fixed bug #65561 (Zend Opcache on Solaris 11 x86 needs ZEND_MM_ALIGNMENT=4). - (Terry Ellison) - -- Openssl: - . Fixed bug #64802 (openssl_x509_parse fails to parse subject properly in - some cases). (Mark Jones) - -- PDO: - . Fixed bug #64953 (Postgres prepared statement positional parameter - casting). (Mike) - -- Session: - . Fixed bug #65475 (Session ID is not initialized properly when strict session - is enabled). (Yasuo) - . Fixed bug #51127/#65359 Request #25630/#43980/#54383 (Added php_serialize - session serialize handler that uses plain serialize()). (Yasuo) - -- Standard: - . Fix issue with return types of password API helper functions. Found via - static analysis by cjones. (Anthony Ferrara) - -- Zlib: - . Fixed bug #65391 (Unable to send vary header user-agent when - ob_start('ob_gzhandler') is called) (Mike) + . Implemented FR #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir + or safe_mode). (Adam) -22 Aug 2013, PHP 5.5.3 +- GMP: + . Moved GMP to use object as the underlying structure and implemented various + improvements based on this. + (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita) -- Openssl: - . Fixed UMR in fix for CVE-2013-4248. - -15 Aug 2013, PHP 5.5.2 - -- Core: - . Fixed bug #65372 (Segfault in gc_zval_possible_root when return reference - fails). (Laruence) - . Fixed value of FILTER_SANITIZE_FULL_SPECIAL_CHARS constant (previously was - erroneously set to FILTER_SANITIZE_SPECIAL_CHARS value). (Andrey - avp200681 gmail com). - . Fixed bug #65304 (Use of max int in array_sum). (Laruence) - . Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very - limited case). (Arpad) - . Fixed bug #62691 (solaris sed has no -i switch). (Chris Jones) - . Fixed bug #61345 (CGI mode - make install don't work). (Michael Heimpold) - . Fixed bug #61268 (--enable-dtrace leads make to clobber - Zend/zend_dtrace.d) (Chris Jones) +- Hash: + . Added gost-crypto (CryptoPro S-box) GOST hash algo. (Manuel Mausz) -- DOM: - . Added flags option to DOMDocument::schemaValidate() and - DOMDocument::schemaValidateSource(). Added LIBXML_SCHEMA_CREATE flag. - (Chris Wright) +- mysqlnd: + . Disabled flag for SP OUT variables for 5.5+ servers as they are not natively + supported by the overlying APIs. (Andrey) - OPcache: - . Added opcache.restrict_api configuration directive that may limit - usage of OPcache API functions only to particular script(s). (Dmitry) - . Added support for glob symbols in blacklist entries (?, *, **). - (Terry Elison, Dmitry) - . Fixed bug #65338 (Enabling both php_opcache and php_wincache AVs on - shutdown). (Dmitry) + . Added an optimization pass to convert FCALL_BY_NAME into DO_FCALL. + (Laruence, Dmitry) + . Added an optimization pass to merged identical constants (and related + cache_slots) in op_array->literals table. (Laruence, Dmitry) + . Added script level constant replacement optimization pass. (Dmitry) - Openssl: - . Fixed handling null bytes in subjectAltName (CVE-2013-4248). - (Christian Heimes) - -- PDO_mysql: - . Fixed bug #65299 (pdo mysql parsing errors). (Johannes) - -- Pgsql: - . Fixed bug #62978 (Disallow possible SQL injections with pg_select()/pg_update() - /pg_delete()/pg_insert()). (Yasuo) - -- Phar: - . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for - some specific contents). (Stas) - -- Sessions: - . Implemented strict sessions RFC (https://wiki.php.net/rfc/strict_sessions) - which protects against session fixation attacks and session collisions. - (CVE-2011-4718). (Yasuo Ohgaki) - . Fixed possible buffer overflow under Windows. Note: Not a security fix. - (Yasuo) - . Changed session.auto_start to PHP_INI_PERDIR. (Yasuo) - -- SOAP: - . Fixed bug #65018 (SoapHeader problems with SoapServer). (Dmitry) - -- SPL: - . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence) - . Added RecursiveTreeIterator setPostfix and getPostifx methods. (Joshua - Thijssen) - . Fixed bug #61697 (spl_autoload_functions returns lambda functions - incorrectly). (Laruence) - -- Streams: - . Fixed bug #65268 (select() implementation uses outdated tick API). (Anatol) - -- Pgsql: - . Fixed bug #65336 (pg_escape_literal/identifier() scilently returns false). - (Yasuo) - -18 Jul 2013, PHP 5.5.1 - -- Core: - . Fixed bug #65254 (Exception not catchable when exception thrown in autoload - with a namespace). (Laruence) - . Fixed bug #65088 (Generated configure script is malformed on OpenBSD). - (Adam) - . Fixed bug #65108 (is_callable() triggers Fatal Error). - (David Soria Parra, Laruence) - . Fixed bug #65035 (yield / exit segfault). (Nikita) - . Fixed bug #65161 (Generator + autoload + syntax error = segfault). (Nikita) - . hex2bin() raises E_WARNING for invalid hex string. (Yasuo) - . Fixed bug #65226 (chroot() does not get enabled). (Anatol) - -- OPcache - . Fixed bug #64827 (Segfault in zval_mark_grey (zend_gc.c)). (Laruence) - . OPcache must be compatible with LiteSpeed SAPI (Dmitry) - -- CGI: - . Fixed Bug #65143 (Missing php-cgi man page). (Remi) - -- CLI server: - . Fixed bug #65066 (Cli server not responsive when responding with 422 http - status code). (Adam) - -- DateTime - . Fixed fug #65184 (strftime() returns insufficient-length string under - multibyte locales). (Anatol) - -- GD - . Fixed #65070 (bgcolor does not use the same format as the input image with - imagerotate). (Pierre) - . Fixed Bug #65060 (imagecreatefrom... crashes with user streams). (Remi) - . Fixed Bug #65084 (imagecreatefromjpeg fails with URL). (Remi) - . Fix gdImageCreateFromWebpCtx and use same logic to load WebP image - that other formats. (Remi) - -- Intl: - . Add IntlCalendar::setMinimalDaysInFirstWeek()/ - intlcal_set_minimal_days_in_first_week(). - . Fixed trailing space in name of constant IntlCalendar::FIELD_FIELD_COUNT. - . Fixed bug #62759 (Buggy grapheme_substr() on edge case). (Stas) - . Fixed bug #61860 (Offsets may be wrong for grapheme_stri* functions). - (Stas) - -- OCI8: - . Bump PECL package info version check to allow PECL installs with PHP 5.5+ - -- PDO: - . Allowed PDO_OCI to compile with Oracle Database 12c client libraries. - (Chris Jones) - -- Pgsql - . pg_unescape_bytea() raises E_WARNING for invalid inputs. (Yasuo) - -- Phar: - . Fixed Bug #65142 (Missing phar man page). (Remi) - -- Session: - . Added optional create_sid() argument to session_set_save_handler(), - SessionHandler and new SessionIdInterface. (Leigh, Arpad) - -- Sockets: - . Implemented FR #63472 (Setting SO_BINDTODEVICE with socket_set_option). - (Damjan Cvetko) - . Allowed specifying paths in the abstract namespace for the functions - socket_bind(), socket_connect() and socket_sendmsg(). (Gustavo) - . Fixed bug #65260 (sendmsg() ancillary data construction for SCM_RIGHTS is - faulty). (Gustavo) - -- SPL: - . Fixed bug #65136 (RecursiveDirectoryIterator segfault). (Laruence) - . Fixed bug #61828 (Memleak when calling Directory(Recursive)Iterator - /Spl(Temp)FileObject ctor twice). (Laruence) - -- CGI/FastCGI SAPI: - . Added PHP_FCGI_BACKLOG, overrides the default listen backlog. (Arnaud Le - Blanc) - -20 Jun 2013, PHP 5.5.0 - -- Core: - . Added Zend Opcache extension and enable building it by default. - More details here: https://wiki.php.net/rfc/optimizerplus. (Dmitry) - . Added generators and coroutines (https://wiki.php.net/rfc/generators). - (Nikita Popov) - . Added "finally" keyword (https://wiki.php.net/rfc/finally). (Laruence) - . Added simplified password hashing API - (https://wiki.php.net/rfc/password_hash). (Anthony Ferrara) - . Added support for constant array/string dereferencing. (Laruence) - . Added array_column function which returns a column in a multidimensional - array. https://wiki.php.net/rfc/array_column. (Ben Ramsey) - . Added boolval(). (Jille Timmermans) - . Added "Z" option to pack/unpack. (Gustavo) - . Added Generator::throw() method. (Nikita Popov) - . Added Class Name Resolution As Scalar Via "class" Keyword. - (Ralph Schindler, Nikita Popov, Lars) - . Added optional second argument for assert() to specify custom message. Patch - by Lonny Kapelushnik (lonny@lonnylot.com). (Lars) - . Added support for using empty() on the result of function calls and - other expressions (https://wiki.php.net/rfc/empty_isset_exprs). - (Nikita Popov) - . Added support for non-scalar Iterator keys in foreach - (https://wiki.php.net/rfc/foreach-non-scalar-keys). (Nikita Popov) - . Added support for list in foreach (https://wiki.php.net/rfc/foreachlist). - (Laruence) - . Added support for changing the process's title in CLI/CLI-Server SAPIs. - The implementation is more robust that the proctitle PECL module. More - details here: https://wiki.php.net/rfc/cli_process_title. (Keyur) - . Added ARMv7/v8 versions of various Zend arithmetic functions that are - implemented using inline assembler (Ard Biesheuvel) - . Added systemtap support by enabling systemtap compatible dtrace probes on - linux. (David Soria Parra) - . Optimized access to temporary and compiled VM variables. 8% less memory - reads. (Dmitry) - . The VM stacks for passing function arguments and syntaticaly nested calls - were merged into a single stack. The stack size needed for op_array - execution is calculated at compile time and preallocated at once. As result - all the stack push operatins don't require checks for stack overflow - any more. (Dmitry) - . Improve set_exception_handler while doing reset. (Laruence) - . Return previous handler when passing NULL to set_error_handler and - set_exception_handler. (Nikita Popov) - . Remove php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid(), - zend_logo_guid(). (Adnrew Faulds) - . Drop Windows XP and 2003 support. (Pierre) - . Implemented FR #64175 (Added HTTP codes as of RFC 6585). (Jonh Wendell) - . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL). - (Laruence, Nikita Popov) - . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik). - . Implemented FR #46487 (Dereferencing process-handles no longer waits on - those processes). (Jille Timmermans) - . Fixed bug #65051 (count() off by one inside unset()). (Nikita) - . Fixed bug #64988 (Class loading order affects E_STRICT warning). (Laruence) - . Fixed bug #64966 (segfault in zend_do_fcall_common_helper_SPEC). (Laruence) - . Fixed bug #64960 (Segfault in gc_zval_possible_root). (Laruence) - . Fixed bug #64936 (doc comments picked up from previous scanner run). (Stas, - Jonathan Oddy) - . Fixed bug #64934 (Apache2 TS crash with get_browser()). (Anatol) - . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode, - CVE 2013-2110). (Stas) - . Fixed bug #64853 (Use of no longer available ini directives causes crash - on TS build). (Anatol) - . Fixed bug #64821 (Custom Exceptions crash when internal properties overridden). - (Anatol) - . Fixed bug #64720 (SegFault on zend_deactivate). (Dmitry) - . Fixed bug #64677 (execution operator `` stealing surrounding arguments). - . Fixed bug #64660 (Segfault on memory exhaustion within function definition). - (Stas, reported by Juha Kylmänen) - . Fixed bug #64578 (debug_backtrace in set_error_handler corrupts zend heap: - segfault). (Laruence) - . Fixed bug #64565 (copy doesn't report failure on partial copy). (Remi) - . Fixed bug #64555 (foreach no longer copies keys if they are interned). - (Nikita Popov) - . Fixed bugs #47675 and #64577 (fd leak on Solaris) - . Fixed bug #64544 (Valgrind warnings after using putenv). (Laruence) - . Fixed bug #64515 (Memoryleak when using the same variablename 2times in - function declaration). (Laruence) - . Fixed bug #64503 (Compilation fails with error: conflicting types for - 'zendparse'). (Laruence) - . Fixed bug #64239 (Debug backtrace changed behavior since 5.4.10 or 5.4.11). - (Dmitry, Laruence) - . Fixed bug #64523, allow XOR in php.ini. (Dejan Marjanovic, Lars) - . Fixed bug #64354 (Unserialize array of objects whose class can't - be autoloaded fail). (Laruence) - . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']). - (Anatol) - . Fixed bug #64166 (quoted-printable-encode stream filter incorrectly - discarding whitespace). (Michael M Slusarz) - (Laruence) - . Fixed bug #64142 (dval to lval different behavior on ppc64). (Remi) - . Fixed bug #64135 (Exceptions from set_error_handler are not always - propagated). (Laruence) - . Fixed bug #63980 (object members get trimmed by zero bytes). (Laruence) - . Fixed bug #63874 (Segfault if php_strip_whitespace has heredoc). (Pierrick) - . Fixed bug #63830 (Segfault on undefined function call in nested generator). - (Nikita Popov) - . Fixed bug #63822 (Crash when using closures with ArrayAccess). - (Nikita Popov) - . Fixed bug #61681 (Malformed grammar). (Nikita Popov, Etienne, Laruence) - . Fixed bug #61038 (unpack("a5", "str\0\0") does not work as expected). - (srgoogleguy, Gustavo) - . Fixed bug #61025 (__invoke() visibility not honored). (Laruence) - . Fixed bug #60833 (self, parent, static behave inconsistently - case-sensitive). (Stas, mario at include-once dot org) - . Fixed Bug #52126: timestamp for mail.log (Martin Jansen, Lars) - . Fixed bug #49348 (Uninitialized ++$foo->bar; does not cause a notice). - (Stas) - . Fixed Bug #23955: allow specifying Max-Age attribute in setcookie() (narfbg, Lars) - . Fixed bug #18556 (Engine uses locale rules to handle class names). (Stas) - . Fix undefined behavior when converting double variables to integers. - The double is now always rounded towards zero, the remainder of its division - by 2^32 or 2^64 (depending on sizeof(long)) is calculated and it's made - signed assuming a two's complement representation. (Gustavo) - . Drop support for bison < 2.4 when building PHP from GIT source. - (Laruence) - -- Apache2 Handler SAPI: - . Enabled Apache 2.4 configure option for Windows (Pierre, Anatoliy) - -- Calendar: - . Fixed bug #64895 (Integer overflow in SndToJewish). (Remi) - . Fixed bug #54254 (cal_from_jd returns month = 6 when there is only one Adar) - (Stas, Eitan Mosenkis) - -- CLI server: - . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi) - -- CURL: - . Remove curl stream wrappers. (Pierrick) - . Implemented FR #46439 - added CURLFile for safer file uploads. - (Stas) - . Added support for CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPT_APPEND, - CURLOPT_DIRLISTONLY, CURLOPT_NEW_DIRECTORY_PERMS, CURLOPT_NEW_FILE_PERMS, - CURLOPT_NETRC_FILE, CURLOPT_PREQUOTE, CURLOPT_KRBLEVEL, CURLOPT_MAXFILESIZE, - CURLOPT_FTP_ACCOUNT, CURLOPT_COOKIELIST, CURLOPT_IGNORE_CONTENT_LENGTH, - CURLOPT_CONNECT_ONLY, CURLOPT_LOCALPORT, CURLOPT_LOCALPORTRANGE, - CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPT_SSL_SESSIONID_CACHE, - CURLOPT_FTP_SSL_CCC, CURLOPT_HTTP_CONTENT_DECODING, - CURLOPT_HTTP_TRANSFER_DECODING, CURLOPT_PROXY_TRANSFER_MODE, - CURLOPT_ADDRESS_SCOPE, CURLOPT_CRLFILE, CURLOPT_ISSUERCERT, - CURLOPT_USERNAME, CURLOPT_PASSWORD, CURLOPT_PROXYUSERNAME, - CURLOPT_PROXYPASSWORD, CURLOPT_NOPROXY, CURLOPT_SOCKS5_GSSAPI_NEC, - CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPT_TFTP_BLKSIZE, - CURLOPT_SSH_KNOWNHOSTS, CURLOPT_FTP_USE_PRET, CURLOPT_MAIL_FROM, - CURLOPT_MAIL_RCPT, CURLOPT_RTSP_CLIENT_CSEQ, CURLOPT_RTSP_SERVER_CSEQ, - CURLOPT_RTSP_SESSION_ID, CURLOPT_RTSP_STREAM_URI, CURLOPT_RTSP_TRANSPORT, - CURLOPT_RTSP_REQUEST, CURLOPT_RESOLVE, CURLOPT_ACCEPT_ENCODING, - CURLOPT_TRANSFER_ENCODING, CURLOPT_DNS_SERVERS and CURLOPT_USE_SSL. - (Pierrick) - . Fixed bug #55635 (CURLOPT_BINARYTRANSFER no longer used. The constant - still exists for backward compatibility but is doing nothing). (Pierrick) - . Fixed bug #54995 (Missing CURLINFO_RESPONSE_CODE support). (Pierrick) - -- DateTime - . Added DateTimeImmutable - a variant of DateTime that only returns the - modified state instead of changing itself. (Derick) - . Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror - curl_pause, curl_reset, curl_share_close, curl_share_init, - curl_share_setopt curl_strerror and curl_unescape. (Pierrick) - . Addes new curl options CURLOPT_TELNETOPTIONS, CURLOPT_GSSAPI_DELEGATION, - CURLOPT_ACCEPTTIMEOUT_MS, CURLOPT_SSL_OPTIONS, CURLOPT_TCP_KEEPALIVE, - CURLOPT_TCP_KEEPIDLE and CURLOPT_TCP_KEEPINTVL. (Pierrick) - . Fixed bug #64825 (Invalid free when unserializing DateTimeZone). - (Anatol) - . Fixed bug #64359 (strftime crash with VS2012). (Anatol) - . Fixed bug #62852 (Unserialize Invalid Date causes crash). (Anatol) - . Fixed bug #61642 (modify("+5 weekdays") returns Sunday). - (Dmitri Iouchtchenko) - . Fixed bug #60774 (DateInterval::format("%a") is always zero when an - interval is created using the createFromDateString method) (Lonny - Kapelushnik, Derick) - . Fixed bug #54567 (DateTimeZone serialize/unserialize) (Lonny - Kapelushnik, Derick) - . Fixed bug #53437 (Crash when using unserialized DatePeriod instance). - (Gustavo, Derick, Anatol) - -- dba: - . Bug #62489: dba_insert not working as expected. - (marc-bennewitz at arcor dot de, Lars) - -- Filter: - . Implemented FR #49180 - added MAC address validation. (Martin) - -- Fileinfo: - . Upgraded libmagic to 5.14. (Anatol) - . Fixed bug #64830 (mimetype detection segfaults on mp3 file). (Anatol) - . Fixed bug #63590 (Different results in TS and NTS under Windows). - (Anatoliy) - . Fixed bug #63248 (Load multiple magic files from a directory under Windows). - (Anatoliy) - -- FPM: - . Add --with-fpm-systemd option to report health to systemd, and - systemd_interval option to configure this. The service can now use - Type=notify in the systemd unit file. (Remi) - . Ignore QUERY_STRING when sent in SCRIPT_FILENAME. (Remi) - . Log a warning when a syscall fails. (Remi) - . Implemented FR #64764 (add support for FPM init.d script). (Lior Kaplan) - . Fixed Bug #64915 (error_log ignored when daemonize=0). (Remi) - . Fixed bug #63999 (php with fpm fails to build on Solaris 10 or 11). (Adam) - . Fixed some possible memory or resource leaks and possible null dereference - detected by code coverity scan. (Remi) - -- GD: - . Fixed Bug #64962 (imagerotate produces corrupted image). (Remi) - . Fixed Bug #64961 (segfault in imagesetinterpolation). (Remi) - . Fix build with system libgd >= 2.1 which is now the minimal - version required (as build with previous version is broken). - No change when bundled libgd is used. (Ondrej Sury, Remi) - -- Hash: - . Added support for PBKDF2 via hash_pbkdf2(). (Anthony Ferrara) - . Fixed Bug #64745 (hash_pbkdf2() truncates data when using default length - and hex output). (Anthony Ferrara) - -- Intl: - . Added UConverter wrapper. - . The intl extension now requires ICU 4.0+. - . Added intl.use_exceptions INI directive, which controls what happens when - global errors are set together with intl.error_level. (Gustavo) - . MessageFormatter::format() and related functions now accepted named - arguments and mixed numeric/named arguments in ICU 4.8+. (Gustavo) - . MessageFormatter::format() and related functions now don't error out when - an insufficient argument count is provided. Instead, the placeholders will - remain unsubstituted. (Gustavo) - . MessageFormatter::parse() and MessageFormat::format() (and their static - equivalents) don't throw away better than second precision in the arguments. - (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() now accept for the - $timezone argument time zone identifiers, IntlTimeZone objects, DateTimeZone - objects and NULL. (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() no longer accept invalid - timezone identifiers or empty strings. (Gustavo) - . The default time zone used in IntlDateFormatter::__construct and - datefmt_create() (when the corresponding argument is not passed or NULL is - passed) is now the one given by date_default_timezone_get(), not the - default ICU time zone. (Gustavo) - . The time zone passed to the IntlDateFormatter is ignored if it is NULL and - if the calendar passed is an IntlCalendar object -- in this case, the - IntlCalendar's time zone will be used instead. Otherwise, the time zone - specified in the $timezone argument is used instead. This does not affect - old code, as IntlCalendar was introduced in this version. (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() now accept for the - $calendar argument also IntlCalendar objects. (Gustavo) - . IntlDateFormatter::getCalendar() and datefmt_get_calendar() return false - if the IntlDateFormatter was set up with an IntlCalendar instead of the - constants IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not - exist before this version. (Gustavo) - . IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also accept - an IntlCalendar object, in which case its time zone is taken. Passing a - constant is still allowed, and still keeps the time zone. (Gustavo) - . IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are - deprecated. Use IntlDateFormatter::setTimeZone() or datefmt_set_timezone() - instead. (Gustavo) - . IntlDateFormatter::format() and datefmt_format() now also accept an - IntlCalendar object for formatting. (Gustavo) - . Added the classes: IntlCalendar, IntlGregorianCalendar, IntlTimeZone, - IntlBreakIterator, IntlRuleBasedBreakIterator and - IntlCodePointBreakIterator. (Gustavo) - . Added the functions: intlcal_get_keyword_values_for_locale(), - intlcal_get_now(), intlcal_get_available_locales(), intlcal_get(), - intlcal_get_time(), intlcal_set_time(), intlcal_add(), - intlcal_set_time_zone(), intlcal_after(), intlcal_before(), intlcal_set(), - intlcal_roll(), intlcal_clear(), intlcal_field_difference(), - intlcal_get_actual_maximum(), intlcal_get_actual_minimum(), - intlcal_get_day_of_week_type(), intlcal_get_first_day_of_week(), - intlcal_get_greatest_minimum(), intlcal_get_least_maximum(), - intlcal_get_locale(), intlcal_get_maximum(), - intlcal_get_minimal_days_in_first_week(), intlcal_get_minimum(), - intlcal_get_time_zone(), intlcal_get_type(), - intlcal_get_weekend_transition(), intlcal_in_daylight_time(), - intlcal_is_equivalent_to(), intlcal_is_lenient(), intlcal_is_set(), - intlcal_is_weekend(), intlcal_set_first_day_of_week(), - intlcal_set_lenient(), intlcal_equals(), - intlcal_get_repeated_wall_time_option(), - intlcal_get_skipped_wall_time_option(), - intlcal_set_repeated_wall_time_option(), - intlcal_set_skipped_wall_time_option(), intlcal_from_date_time(), - intlcal_to_date_time(), intlcal_get_error_code(), - intlcal_get_error_message(), intlgregcal_create_instance(), - intlgregcal_set_gregorian_change(), intlgregcal_get_gregorian_change() and - intlgregcal_is_leap_year(). (Gustavo) - . Added the functions: intltz_create_time_zone(), intltz_create_default(), - intltz_get_id(), intltz_get_gmt(), intltz_get_unknown(), - intltz_create_enumeration(), intltz_count_equivalent_ids(), - intltz_create_time_zone_id_enumeration(), intltz_get_canonical_id(), - intltz_get_region(), intltz_get_tz_data_version(), - intltz_get_equivalent_id(), intltz_use_daylight_time(), intltz_get_offset(), - intltz_get_raw_offset(), intltz_has_same_rules(), intltz_get_display_name(), - intltz_get_dst_savings(), intltz_from_date_time_zone(), - intltz_to_date_time_zone(), intltz_get_error_code(), - intltz_get_error_message(). (Gustavo) - . Added the methods: IntlDateFormatter::formatObject(), - IntlDateFormatter::getCalendarObject(), IntlDateFormatter::getTimeZone(), - IntlDateFormatter::setTimeZone(). (Gustavo) - . Added the functions: datefmt_format_object(), datefmt_get_calendar_object(), - datefmt_get_timezone(), datefmt_set_timezone(), - datefmt_get_calendar_object(), intlcal_create_instance(). (Gustavo) - -- mbstring: - . Fixed bug #64769 (mbstring PHPTs crash on Windows x64). (Anatol) - -- MCrypt - . mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw - E_DEPRECATED. (GoogleGuy) - -- mysql - . This extension is now deprecated, and deprecation warnings will be generated - when connections are established to databases via mysql_connect(), - mysql_pconnect(), or through implicit connection: use MySQLi or PDO_MySQL - instead (https://wiki.php.net/rfc/mysql_deprecation). (Adam) - . Dropped support for LOAD DATA LOCAL INFILE handlers when using libmysql. - Known for stability problems. (Andrey) - . Added support for SHA256 authentication available with MySQL 5.6.6+. - (Andrey) - -- mysqli: - . Added mysqli_begin_transaction()/mysqli::begin_transaction(). Implemented - all options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT - and ROLLBACK through options to mysqli_commit()/mysqli_rollback() and their - respective OO counterparts. They work in libmysql and mysqlnd mode. (Andrey) - . Added mysqli_savepoint(), mysqli_release_savepoint(). (Andrey) - . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB - pointer has closed). (Laruence) - . Fixed bug #64394 (MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS undeclared when - using Connector/C). (Andrey) - -- mysqlnd - . Add new begin_transaction() call to the connection object. Implemented all - options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT - and ROLLBACK. (Andrey) - . Added mysqlnd_savepoint(), mysqlnd_release_savepoint(). (Andrey) - . Fixed bug #63530 (mysqlnd_stmt::bind_one_parameter crashes, uses wrong alloc - for stmt->param_bind). (Andrey) - . Fixed return value of mysqli_stmt_affected_rows() in the time after - prepare() and before execute(). (Andrey) - -- PCRE: - . Merged PCRE 8.32. (Anatol) - . Deprecated the /e modifier - (https://wiki.php.net/rfc/remove_preg_replace_eval_modifier). (Nikita Popov) - . Fixed bug #63284 (Upgrade PCRE to 8.31). (Anatoliy) - -- PDO: - . Fixed bug #63176 (Segmentation fault when instantiate 2 persistent PDO to - the same db server). (Laruence) - -- PDO_DBlib: - . Fixed bug #63638 (Cannot connect to SQL Server 2008 with PDO dblib). - (Stanley Sufficool) - . Fixed bug #64338 (pdo_dblib can't connect to Azure SQL). (Stanley - Sufficool) - . Fixed bug #64808 (FreeTDS PDO getColumnMeta on a prepared but not executed - statement crashes). (Stanley Sufficool) - -- PDO_pgsql: - . Fixed Bug #64949 (Buffer overflow in _pdo_pgsql_error). (Remi) - -- PDO_mysql: - . Fixed bug #48724 (getColumnMeta() doesn't return native_type for BIT, - TINYINT and YEAR). (Antony, Daniel Beardsley) - -- pgsql: - . Added pg_escape_literal() and pg_escape_identifier() (Yasuo) - . Bug #46408: Locale number format settings can cause pg_query_params to - break with numerics. (asmecher, Lars) - -- Phar: - . Fixed timestamp update on Phar contents modification. (Dmitry) - -- Readline: - . Implement FR #55694 (Expose additional readline variable to prevent - default filename completion). (Hartmel) - -- Reflection: - . Fixed bug #64007 (There is an ability to create instance of Generator by - hand). (Laruence) - -- Sockets: - . Added recvmsg() and sendmsg() wrappers. (Gustavo) - See https://wiki.php.net/rfc/sendrecvmsg - . Fixed bug #64508 (Fails to build with --disable-ipv6). (Gustavo) - . Fixed bug #64287 (sendmsg/recvmsg shutdown handler causes segfault). - (Gustavo) - -- SPL: - . Fixed bug #64997 (Segfault while using RecursiveIteratorIterator on - 64-bits systems). (Laruence) - . Fixed bug #64264 (SPLFixedArray toArray problem). (Laruence) - . Fixed bug #64228 (RecursiveDirectoryIterator always assumes SKIP_DOTS). - (patch by kriss@krizalys.com, Laruence) - . Fixed bug #64106 (Segfault on SplFixedArray[][x] = y when extended). - (Nikita Popov) - . Fix bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0, - keys are strings). (Adam) - . Fixed bug #52861 (unset fails with ArrayObject and deep arrays). - (Mike Willbanks) - . Implement FR #48358 (Add SplDoublyLinkedList::add() to insert an element - at a given offset). (Mark Baker, David Soria Parra) - -- SNMP: - . Fixed bug #64765 (Some IPv6 addresses get interpreted wrong). - (Boris Lytochkin) - . Fixed bug #64159 (Truncated snmpget). (Boris Lytochkin) - . Fixed bug #64124 (IPv6 malformed). (Boris Lytochkin) - . Fixed bug #61981 (OO API, walk: $suffix_as_key is not working correctly). - (Boris Lytochkin) - -- SOAP: - . Added SoapClient constructor option 'ssl_method' to specify ssl method. - (Eric Iversen) - -- Streams: - . Fixed bug #64770 (stream_select() fails with pipes returned by proc_open() - on Windows x64). (Anatol) - . Fixed Windows x64 version of stream_socket_pair() and improved error - handling. (Anatol Belski) - -- Tokenizer: - . Fixed bug #60097 (token_get_all fails to lex nested heredoc). (Nikita Popov) - -- Zip: - . Upgraded libzip to 0.10.1 (Anatoliy) - . Bug #64452 (Zip crash intermittently). (Anatol) - . Fixed bug #64342 (ZipArchive::addFile() has to check for file existence). - (Anatol) - -06 Jun 2013, PHP 5.4.16 - -- Core: - . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode, - CVE 2013-2110). (Stas) - . Fixed bug #64853 (Use of no longer available ini directives causes crash on - TS build). (Anatol) - . Fixed bug #64729 (compilation failure on x32). (Gustavo) - . Fixed bug #64720 (SegFault on zend_deactivate). (Dmitry) - . Fixed bug #64660 (Segfault on memory exhaustion within function definition). - (Stas, reported by Juha Kylmänen) - -- Calendar: - . Fixed bug #64895 (Integer overflow in SndToJewish). (Remi) - -- Fileinfo: - . Fixed bug #64830 (mimetype detection segfaults on mp3 file). (Anatol) - -- FPM: - . Ignore QUERY_STRING when sent in SCRIPT_FILENAME. (Remi) - . Fixed some possible memory or resource leaks and possible null dereference - detected by code coverity scan. (Remi) - . Log a warning when a syscall fails. (Remi) - . Add --with-fpm-systemd option to report health to systemd, and - systemd_interval option to configure this. The service can now use - Type=notify in the systemd unit file. (Remi) - -- MySQLi - . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB - pointer has closed). (Laruence) - -- Phar - . Fixed bug #64214 (PHAR PHPTs intermittently crash when run on DFS, SMB or - with non std tmp dir). (Pierre) - -- SNMP: - . Fixed bug #64765 (Some IPv6 addresses get interpreted wrong). - (Boris Lytochkin) - . Fixed bug #64159 (Truncated snmpget). (Boris Lytochkin) - -- Streams: - . Fixed bug #64770 (stream_select() fails with pipes returned by proc_open() - on Windows x64). (Anatol) - -- Zend Engine: - . Fixed bug #64821 (Custom Exceptions crash when internal properties - overridden). (Anatol) - -09 May 2013, PHP 5.4.15 -- Core: - . Fixed bug #64578 (debug_backtrace in set_error_handler corrupts zend heap: - segfault). (Laruence) - . Fixed bug #64458 (dns_get_record result with string of length -1). (Stas) - . Fixed bug #64433 (follow_location parameter of context is ignored for most - response codes). (Sergey Akbarov) - . Fixed bugs #47675 and #64577 (fd leak on Solaris) - -- Fileinfo: - . Upgraded libmagic to 5.14. (Anatol) - -- MySQLi: - . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB - pointer has closed). (Laruence) - -- Zip: - . Fixed bug #64342 (ZipArchive::addFile() has to check for file existence). - (Anatol) - -- Streams: - . Fixed Windows x64 version of stream_socket_pair() and improved error - handling. (Anatol Belski) - . Fixed bug #64770 (stream_select() fails with pipes returned by proc_open() - on Windows x64). (Anatol) - -11 Apr 2013, PHP 5.4.14 - -- Core: - . Fixed bug #64529 (Ran out of opcode space). (Dmitry) - . Fixed bug #64515 (Memoryleak when using the same variablename two times in - function declaration). (Laruence) - . Fixed bug #64432 (more empty delimiter warning in strX methods). (Laruence) - . Fixed bug #64417 (ArrayAccess::&offsetGet() in a trait causes fatal error). - (Dmitry) - . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']). - (Anatol) - . Fixed bug #64239 (Debug backtrace changed behavior since 5.4.10 or 5.4.11). - (Dmitry, Laruence) - . Fixed bug #63976 (Parent class incorrectly using child constant in class - property). (Dmitry) - . Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle - exceptions properly). (Jeff Welch) - . Fixed bug #62343 (Show class_alias In get_declared_classes()) (Dmitry) - -- PCRE: - . Merged PCRE 8.32. (Anatol) - -- SNMP: - . Fixed bug #61981 (OO API, walk: $suffix_as_key is not working correctly). - (Boris Lytochkin) - -- Zip: - . Bug #64452 (Zip crash intermittently). (Anatol) - -14 Mar 2013, PHP 5.4.13 - -- Core: - . Fixed bug #64354 (Unserialize array of objects whose class can't - be autoloaded fail). (Laruence) - . Fixed bug #64235 (Insteadof not work for class method in 5.4.11). - (Laruence) - . Fixed bug #64197 (_Offsetof() macro used but not defined on ARM/Clang). - (Ard Biesheuvel) - . Implemented FR #64175 (Added HTTP codes as of RFC 6585). (Jonh Wendell) - . Fixed bug #64142 (dval to lval different behavior on ppc64). (Remi) - . Fixed bug #64070 (Inheritance with Traits failed with error). (Dmitry) - -- CLI server: - . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi) - -- Mbstring: - . mb_split() can now handle empty matches like preg_split() does. (Moriyoshi) - -- mysqlnd - . Fixed bug #63530 (mysqlnd_stmt::bind_one_parameter crashes, uses wrong alloc - for stmt->param_bind). (Andrey) - -- OpenSSL: - . New SSL stream context option to prevent CRIME attack vector. (Daniel Lowrey, - Lars) - . Fixed bug #61930 (openssl corrupts ssl key resource when using - openssl_get_publickey()). (Stas) - -- PDO_mysql: - . Fixed bug #60840 (undefined symbol: mysqlnd_debug_std_no_trace_funcs). - (Johannes) - -- Phar: - . Fixed timestamp update on Phar contents modification. (Dmitry) - -- SOAP - . Added check that soap.wsdl_cache_dir conforms to open_basedir - (CVE-2013-1635). (Dmitry) - . Disabled external entities loading (CVE-2013-1643, CVE-2013-1824). - (Dmitry) - -- Phar: - . Fixed timestamp update on Phar contents modification. (Dmitry) - -- SPL: - . Fixed bug #64264 (SPLFixedArray toArray problem). (Laruence) - . Fixed bug #64228 (RecursiveDirectoryIterator always assumes SKIP_DOTS). - (patch by kriss@krizalys.com, Laruence) - . Fixed bug #64106 (Segfault on SplFixedArray[][x] = y when extended). - (Nikita Popov) - . Fixed bug #52861 (unset fails with ArrayObject and deep arrays). - (Mike Willbanks) - -- SNMP: - . Fixed bug #64124 (IPv6 malformed). (Boris Lytochkin) - -21 Feb 2013, PHP 5.4.12 - -- Core: - . Fixed bug #64099 (Wrong TSRM usage in zend_Register_class alias). (Johannes) - . Fixed bug #64011 (get_html_translation_table() output incomplete with - HTML_ENTITIES and ISO-8859-1). (Gustavo) - . Fixed bug #63982 (isset() inconsistently produces a fatal error on - protected property). (Stas) - . Fixed bug #63943 (Bad warning text from strpos() on empty needle). - (Laruence) - . Fixed bug #63899 (Use after scope error in zend_compile). (Laruence) - . Fixed bug #63893 (Poor efficiency of strtr() using array with keys of very - different length). (Gustavo) - . Fixed bug #63882 (zend_std_compare_objects crash on recursion). (Dmitry) - . Fixed bug #63462 (Magic methods called twice for unset protected - properties). (Stas) - . Fixed bug #62524 (fopen follows redirects for non-3xx statuses). - (Wes Mason) - . Support BITMAPV5HEADER in getimagesize(). (AsamK, Lars) - -- Date: - . Fixed bug #63699 (Performance improvements for various ext/date functions). - (Lars, original patch by njaguar at gmail dot com) - . Fixed bug #55397: Comparsion of incomplete DateTime causes SIGSEGV. - (Derick) - -- FPM: - . Fixed bug #63999 (php with fpm fails to build on Solaris 10 or 11). (Adam) - -- Litespeed: - . Fixed bug #63228 (-Werror=format-security error in lsapi code). (George) - -- ext/sqlite3: - . Fixed bug #63921 (sqlite3::bindvalue and relative PHP functions aren't - using sqlite3_*_int64 API). (srgoogleguy, Lars) - -- PDO_OCI - . Fixed bug #57702 (Multi-row BLOB fetches). (hswong3i, Laruence) - . Fixed bug #52958 (Segfault in PDO_OCI on cleanup after running a long - testsuite). (hswong3i, Lars) - -- PDO_sqlite: - . Fixed bug #63916 (PDO::PARAM_INT casts to 32bit int internally even - on 64bit builds in pdo_sqlite). (srgoogleguy, Lars) - -17 Jan 2013, PHP 5.4.11 - -- Core: - . Fixed bug #63762 (Sigsegv when Exception::$trace is changed by user). - (Johannes) - . Fixed bug #43177 (Errors in eval()'ed code produce status code 500). - (Todd Ruth, Stas). - -- Filter: - . Fixed bug #63757 (getenv() produces memory leak with CGI SAPI). (Dmitry) - . Fixed bug #54096 (FILTER_VALIDATE_INT does not accept +0 and -0). - (martin at divbyzero dot net, Lars) - -- JSON: - . Fixed bug #63737 (json_decode does not properly decode with options - parameter). (Adam) - -- CLI server - . Update list of common mime types. Added webm, ogv, ogg. (Lars, - pascalc at gmail dot com) - -- cURL extension: - . Fixed bug (segfault due to libcurl connection caching). (Pierrick) - . Fixed bug #63859 (Memory leak when reusing curl-handle). (Pierrick) - . Fixed bug #63795 (CURL >= 7.28.0 no longer support value 1 for - CURLOPT_SSL_VERIFYHOST). (Pierrick) - . Fixed bug #63352 (Can't enable hostname validation when using curl stream - wrappers). (Pierrick) - . Fixed bug #55438 (Curlwapper is not sending http header randomly). - (phpnet@lostreality.org, Pierrick) - -20 Dec 2012, PHP 5.4.10 - -- Core: - . Fixed bug #63726 (Memleak with static properties and internal/user - classes). (Laruence) - . Fixed bug #63635 (Segfault in gc_collect_cycles). (Dmitry) - . Fixed bug #63512 (parse_ini_file() with INI_SCANNER_RAW removes quotes - from value). (Pierrick) - . Fixed bug #63468 (wrong called method as callback with inheritance). - (Laruence) - . Fixed bug #63451 (config.guess file does not have AIX 7 defined, - shared objects are not created). (kemcline at au1 dot ibm dot com) - . Fixed bug #61557 (Crasher in tt-rss backend.php). - (i dot am dot jack dot mail at gmail dot com) - . Fixed bug #61272 (ob_start callback gets passed empty string). - (Mike, casper at langemeijer dot eu) - -- Date: - . Fixed bug #63666 (Poor date() performance). (Paul Taulborg). - . Fixed bug #63435 (Datetime::format('u') sometimes wrong by 1 microsecond). - (Remi) - -- Imap: - . Fixed bug #63126 (DISABLE_AUTHENTICATOR ignores array). (Remi) - -- Json: - . Fixed bug #63588 (use php_next_utf8_char and remove duplicate - implementation). (Remi) - -- MySQLi: - . Fixed bug #63361 (missing header). (Remi) - -- MySQLnd: - . Fixed bug #63398 (Segfault when polling closed link). (Laruence) - -- Fileinfo: - . Fixed bug #63590 (Different results in TS and NTS under Windows). - (Anatoliy) - -- FPM: - . Fixed bug #63581 Possible null dereference and buffer overflow (Remi) - -- Pdo_sqlite: - . Fixed Bug #63149 getColumnMeta should return the table name - when system SQLite used. (Remi) - -- Apache2 Handler SAPI: - . Enabled Apache 2.4 configure option for Windows (Pierre, Anatoliy) - -- Reflection: - . Fixed Bug #63614 (Fatal error on Reflection). (Laruence) - -- SOAP - . Fixed bug #63271 (SOAP wsdl cache is not enabled after initial requests). - (John Jawed, Dmitry) - -- Sockets - . Fixed bug #49341 (Add SO_REUSEPORT support for socket_set_option()). - (Igor Wiedler, Lars) - -- SPL - . Fixed bug #63680 (Memleak in splfixedarray with cycle reference). (Laruence) - -22 Nov 2012, PHP 5.4.9 - -- Core: - . Fixed bug #63305 (zend_mm_heap corrupted with traits). (Dmitry, Laruence) - . Fixed bug #63369 ((un)serialize() leaves dangling pointers, causes crashes). - (Tony, Andrew Sitnikov) - . Fixed bug #63241 (PHP fails to open Windows deduplicated files). - (daniel dot stelter-gliese at innogames dot de) - . Fixed bug #62444 (Handle leak in is_readable on windows). - (krazyest at seznam dot cz) - -- Curl: - . Fixed bug #63363 (Curl silently accepts boolean true for SSL_VERIFYHOST). - Patch by John Jawed GitHub PR #221 (Anthony) - -- Fileinfo: - . Fixed bug #63248 (Load multiple magic files from a directory under Windows). - (Anatoliy) - -- Libxml - . Fixed bug #63389 (Missing context check on libxml_set_streams_context() - causes memleak). (Laruence) - -- Mbstring: - . Fixed bug #63447 (max_input_vars doesn't filter variables when - mbstring.encoding_translation = On). (Laruence) - -- OCI8: - . Fixed bug #63265 (Add ORA-00028 to the PHP_OCI_HANDLE_ERROR macro) - (Chris Jones) - -- PCRE: - . Fixed bug #63180 (Corruption of hash tables). (Dmitry) - . Fixed bug #63055 (Segfault in zend_gc with SF2 testsuite). - (Dmitry, Laruence) - . Fixed bug #63284 (Upgrade PCRE to 8.31). (Anatoliy) - -- PDO: - . Fixed bug #63235 (buffer overflow in use of SQLGetDiagRec). - (Martin Osvald, Remi) - + . Added crypto_method option for the ssl stream context. (Martin Jansen) + . Added certificate fingerprint support. (Tjerk Meesters) + . Added explicit TLSv1.1 and TLSv1.2 stream transports. (Daniel Lowrey) + . Fixed bug #65729 (CN_match gives false positive). (Tjerk Meesters) + - PDO_pgsql: - . Fixed bug #62593 (Emulate prepares behave strangely with PARAM_BOOL). - (Will Fitch) - -- Phar: - . Fixed bug #63297 (Phar fails to write an openssl based signature). - (Anatoliy) - -- Streams: - . Fixed bug #63240 (stream_get_line() return contains delimiter string). - (Tjerk, Gustavo) - -- Reflection: - . Fixed bug #63399 (ReflectionClass::getTraitAliases() incorrectly resolves - traitnames). (Laruence) - -18 Oct 2012, PHP 5.4.8 - -- CLI server: - . Implemented FR #63242 (Default error page in PHP built-in web server uses - outdated html/css). (pascal.chevrel@free.fr) - . Changed response to unknown HTTP method to 501 according to RFC. - (Niklas Lindgren). - . Support HTTP PATCH method. Patch by Niklas Lindgren, GitHub PR #190. - (Lars) - -- Core: - . Fixed bug #63219 (Segfault when aliasing trait method when autoloader - throws excpetion). (Laruence) - . Added optional second argument for assert() to specify custom message. Patch - by Lonny Kapelushnik (lonny@lonnylot.com). (Lars) - . Support building PHP with the native client toolchain. (Stuart Langley) - . Added --offline option for tests. (Remi) - . Fixed bug #63162 (parse_url does not match password component). (husman) - . Fixed bug #63111 (is_callable() lies for abstract static method). (Dmitry) - . Fixed bug #63093 (Segfault while load extension failed in zts-build). - (Laruence) - . Fixed bug #62976 (Notice: could not be converted to int when comparing - some builtin classes). (Laruence) - . Fixed bug #62955 (Only one directive is loaded from "Per Directory Values" - Windows registry). (aserbulov at parallels dot com) - . Fixed bug #62907 (Double free when use traits). (Dmitry) - . Fixed bug #61767 (Shutdown functions not called in certain error - situation). (Dmitry) - . Fixed bug #60909 (custom error handler throwing Exception + fatal error - = no shutdown function). (Dmitry) - . Fixed bug #60723 (error_log error time has changed to UTC ignoring default - timezone). (Laruence) - -- cURL: - . Fixed bug #62085 (file_get_contents a remote file by Curl wrapper will - cause cpu Soaring). (Pierrick) - -- Date: - . Fixed bug #62896 ("DateTime->modify('+0 days')" modifies DateTime object) - (Lonny Kapelushnik) - . Fixed bug #62561 (DateTime add 'P1D' adds 25 hours). (Lonny Kapelushnik) - -- DOM: - . Fixed bug #63015 (Incorrect arginfo for DOMErrorHandler). (Rob) - -- FPM: - . Fixed bug #62954 (startup problems fpm / php-fpm). (fat) - . Fixed bug #62886 (PHP-FPM may segfault/hang on startup). (fat) - . Fixed bug #63085 (Systemd integration and daemonize). (remi, fat) - . Fixed bug #62947 (Unneccesary warnings on FPM). (fat) - . Fixed bug #62887 (Only /status?plain&full gives "last request cpu"). (fat) - . Fixed bug #62216 (Add PID to php-fpm init.d script). (fat) - -- OCI8: - . Fixed bug #60901 (Improve "tail" syntax for AIX installation) (Chris Jones) - -- OpenSSL: - . Implemented FR #61421 (OpenSSL signature verification missing RMD160, - SHA224, SHA256, SHA384, SHA512). (Mark Jones) - -- PDO: - . Fixed bug #63258 (seg fault with PDO and dblib using DBSETOPT(H->link, - DBQUOTEDIDENT, 1)). (Laruence) - . Fixed bug #63235 (buffer overflow in use of SQLGetDiagRec). - (Martin Osvald, Remi) - -- PDO Firebird: - . Fixed bug #63214 (Large PDO Firebird Queries). - (james at kenjim dot com) - -- SOAP - . Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice). - (Dmitry) - -- SPL: - . Bug #62987 (Assigning to ArrayObject[null][something] overrides all - undefined variables). (Laruence) - -- mbstring: - . Allow passing null as a default value to mb_substr() and mb_strcut(). Patch - by Alexander Moskaliov via GitHub PR #133. (Lars) - -- Filter extension: - . Bug #49510: Boolean validation fails with FILTER_NULL_ON_FAILURE with empty - string or false. (Lars) - -- Sockets - . Fixed bug #63000 (MCAST_JOIN_GROUP on OSX is broken, merge of PR 185 by - Igor Wiedler). (Lars) - -13 Sep 2012, PHP 5.4.7 - -- Core: - . Fixed bug (segfault while build with zts and GOTO vm-kind). (Laruence) - . Fixed bug #62844 (parse_url() does not recognize //). (Andrew Faulds). - . Fixed bug #62829 (stdint.h included on platform where HAVE_STDINT_H is not - set). (Felipe) - . Fixed bug #62763 (register_shutdown_function and extending class). - (Laruence) - . Fixed bug #62725 (Calling exit() in a shutdown function does not return - the exit value). (Laruence) - . Fixed bug #62744 (dangling pointers made by zend_disable_class). (Laruence) - . Fixed bug #62716 (munmap() is called with the incorrect length). - (slangley@google.com) - . Fixed bug #62358 (Segfault when using traits a lot). (Laruence) - . Fixed bug #62328 (implementing __toString and a cast to string fails) - (Laruence) - . Fixed bug #51363 (Fatal error raised by var_export() not caught by error - handler). (Lonny Kapelushnik) - . Fixed bug #40459 (Stat and Dir stream wrapper methods do not call - constructor). (Stas) - -- CURL: - . Fixed bug #62912 (CURLINFO_PRIMARY_* AND CURLINFO_LOCAL_* not exposed). - (Pierrick) - . Fixed bug #62839 (curl_copy_handle segfault with CURLOPT_FILE). (Pierrick) - -- Intl: - . Fixed Spoofchecker not being registered on ICU 49.1. (Gustavo) - . Fix bug #62933 (ext/intl compilation error on icu 3.4.1). (Gustavo) - . Fix bug #62915 (defective cloning in several intl classes). (Gustavo) - -- Installation: - . Fixed bug #62460 (php binaries installed as binary.dSYM). (Reeze Xia) - -- PCRE: - . Fixed bug #55856 (preg_replace should fail on trailing garbage). - (reg dot php at alf dot nu) - -- PDO: - . Fixed bug #62685 (Wrong return datatype in PDO::inTransaction()). (Laruence) - -- Reflection: - . Fixed bug #62892 (ReflectionClass::getTraitAliases crashes on importing - trait methods as private). (Felipe) - . Fixed bug #62715 (ReflectionParameter::isDefaultValueAvailable() wrong - result). (Laruence) + . Fixed Bug #42614 (PDO_pgsql: add pg_get_notify support). (Matteo) + . Fixed Bug #63657 (pgsqlCopyFromFile, pgsqlCopyToArray use Postgres < 7.3 + syntax). (Matteo) - Session: - . Fixed bug (segfault due to retval is not initialized). (Laruence) - . Fixed bug (segfault due to PS(mod_user_implemented) not be reseted - when close handler call exit). (Laruence) - -- SOAP - . Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice). - (Dmitry) - -- SPL: - . Fixed bug #62904 (Crash when cloning an object which inherits SplFixedArray) - (Laruence) - . Implemented FR #62840 (Add sort flag to ArrayObject::ksort). (Laruence) + . Fixed Bug #65315 (session.hash_function silently fallback to default md5) + (Yasuo) + . Implemented Request #54649 (Create session_serializer_name()). (Yasuo) + . Implemented Request #17860 (Session write short circuit). (Yasuo) + . Implemented Request #20421 (session_abort() and session_reset() function). + (Yasuo) + . Implemented Request #11100 (session_gc() function). (Yasuo) - Standard: - . Fixed bug #62836 (Seg fault or broken object references on unserialize()). - (Laruence) - -- FPM: - . Merged PR 121 by minitux to add support for slow request counting on PHP - FPM status page. (Lars) - -16 Aug 2012, PHP 5.4.6 - -- CLI Server: - . Implemented FR #62700 (have the console output 'Listening on - http://localhost:8000'). (pascal.chevrel@free.fr) - -- Core: - . Fixed bug #62661 (Interactive php-cli crashes if include() is used in - auto_prepend_file). (Laruence) - . Fixed bug #62653: (unset($array[$float]) causes a crash). (Nikita Popov, - Laruence) - . Fixed bug #62565 (Crashes due non-initialized internal properties_table). - (Felipe) - . Fixed bug #60194 (--with-zend-multibyte and --enable-debug reports LEAK - with run-test.php). (Laruence) - -- CURL: - . Fixed bug #62499 (curl_setopt($ch, CURLOPT_COOKIEFILE, "") returns false). - (r.hampartsumyan@gmail.com, Laruence) - -- DateTime: - . Fixed Bug #62500 (Segfault in DateInterval class when extended). (Laruence) - -- Fileinfo: - . Fixed bug #61964 (finfo_open with directory causes invalid free). - (reeze.xia@gmail.com) + . Implemented FR #65634 (HTTP wrapper is very slow with protocol_version + 1.1). (Adam) + . Implemented Change crypt() behavior w/o salt RFC. (Yasuo) + https://wiki.php.net/rfc/crypt_function_salt -- Intl: - . Fixed bug #62564 (Extending MessageFormatter and adding property causes - crash). (Felipe) - -- MySQLnd: - . Fixed bug #62594 (segfault in mysqlnd_res_meta::set_mode). (Laruence) - -- readline: - . Fixed bug #62612 (readline extension compilation fails with - sapi/cli/cli.h: No such file). (Johannes) - -- Reflection: - . Implemented FR #61602 (Allow access to name of constant used as default - value). (reeze.xia@gmail.com) - -- SimpleXML: - . Implemented FR #55218 Get namespaces from current node. (Lonny) - -- SPL: - . Fixed bug #62616 (ArrayIterator::count() from IteratorIterator instance - gives Segmentation fault). (Laruence, Gustavo) - . Fixed bug #61527 (ArrayIterator gives misleading notice on next() when - moved to the end). (reeze.xia@gmail.com) - -- Streams: - . Fixed bug #62597 (segfault in php_stream_wrapper_log_error with ZTS build). - (Laruence) - -- Zlib: - . Fixed bug #55544 (ob_gzhandler always conflicts with - zlib.output_compression). (Laruence) - -19 Jul 2012, PHP 5.4.5 - -- Core: - . Fixed bug #62443 (Crypt SHA256/512 Segfaults With Malformed - Salt). (Anthony Ferrara) - . Fixed bug #62432 (ReflectionMethod random corrupt memory on high - concurrent). (Johannes) - . Fixed bug #62373 (serialize() generates wrong reference to the object). - (Moriyoshi) - . Fixed bug #62357 (compile failure: (S) Arguments missing for built-in - function __memcmp). (Laruence) - . Fixed bug #61998 (Using traits with method aliases appears to result in - crash during execution). (Dmitry) - . Fixed bug #51094 (parse_ini_file() with INI_SCANNER_RAW cuts a value that - includes a semi-colon). (Pierrick) - . Fixed potential overflow in _php_stream_scandir (CVE-2012-2688). - (Jason Powell, Stas) - -- EXIF: - . Fixed information leak in ext exif (discovered by Martin Noga, - Matthew "j00ru" Jurczyk, Gynvael Coldwind) - -- FPM: - . Fixed bug #62205 (php-fpm segfaults (null passed to strstr)). (fat) - . Fixed bug #62160 (Add process.priority to set nice(2) priorities). (fat) - . Fixed bug #62153 (when using unix sockets, multiples FPM instances - . Fixed bug #62033 (php-fpm exits with status 0 on some failures to start). - (fat) - . Fixed bug #61839 (Unable to cross-compile PHP with --enable-fpm). (fat) - . Fixed bug #61835 (php-fpm is not allowed to run as root). (fat) - . Fixed bug #61295 (php-fpm should not fail with commented 'user' - . Fixed bug #61218 (FPM drops connection while receiving some binary values - in FastCGI requests). (fat) - . Fixed bug #61045 (fpm don't send error log to fastcgi clients). (fat) - for non-root start). (fat) - . Fixed bug #61026 (FPM pools can listen on the same address). (fat) - can be launched without errors). (fat) - -- Iconv: - . Fix bug #55042 (Erealloc in iconv.c unsafe). (Stas) - -- Intl: - . Fixed bug #62083 (grapheme_extract() memory leaks). (Gustavo) - . ResourceBundle constructor now accepts NULL for the first two arguments. - (Gustavo) - . Fixed bug #62081 (IntlDateFormatter constructor leaks memory when called - twice). (Gustavo) - . Fixed bug #62070 (Collator::getSortKey() returns garbage). (Gustavo) - . Fixed bug #62017 (datefmt_create with incorrectly encoded timezone leaks - pattern). (Gustavo) - . Fixed bug #60785 (memory leak in IntlDateFormatter constructor). (Gustavo) - -- JSON: - . Fixed bug #61359 (json_encode() calls too many reallocs). (Stas) - -- libxml: - . Fixed bug #62266 (Custom extension segfaults during xmlParseFile with FPM - SAPI). (Gustavo) - -- Phar: - . Fixed bug #62227 (Invalid phar stream path causes crash). (Felipe) - -- Readline: - . Fixed bug #62186 (readline fails to compile - void function should not - return a value). (Johannes) - -- Reflection: - . Fixed bug #62384 (Attempting to invoke a Closure more than once causes - segfault). (Felipe) - . Fixed bug #62202 (ReflectionParameter::getDefaultValue() memory leaks - with constant). (Laruence) - -- Sockets: - . Fixed bug #62025 (__ss_family was changed on AIX 5.3). (Felipe) - -- SPL: - . Fixed bug #62433 (Inconsistent behavior of RecursiveDirectoryIterator to - dot files). (Laruence) - . Fixed bug #62262 (RecursiveArrayIterator does not implement Countable). - (Nikita Popov) - -- XML Writer: - . Fixed bug #62064 (memory leak in the XML Writer module). - (jean-pierre dot lozi at lip6 dot fr) +- XMLReader: + . Fixed bug #55285 (XMLReader::getAttribute/No/Ns methods inconsistency). + (Mike) - Zip: - . Upgraded libzip to 0.10.1 (Anatoliy) - -14 Jun 2012, PHP 5.4.4 - -- COM: - . Fixed bug #62146 com_dotnet cannot be built shared. (Johannes) - -- CLI Server: - . Implemented FR #61977 (Need CLI web-server support for files with .htm & - svg extensions). (Sixd, Laruence) - . Improved performance while sending error page, this also fixed - bug #61785 (Memory leak when access a non-exists file without router). - (Laruence) - . Fixed bug #61546 (functions related to current script failed when chdir() - in cli sapi). (Laruence, reeze.xia@gmail.com) - -- Core: - . Fixed missing bound check in iptcparse(). (chris at chiappa.net) - . Fixed CVE-2012-2143. (Solar Designer) - . Fixed bug #62097 (fix for for bug #54547). (Gustavo) - . Fixed bug #62005 (unexpected behavior when incrementally assigning to a - member of a null object). (Laruence) - . Fixed bug #61978 (Object recursion not detected for classes that implement - JsonSerializable). (Felipe) - . Fixed bug #61991 (long overflow in realpath_cache_get()). (Anatoliy) - . Fixed bug #61922 (ZTS build doesn't accept zend.script_encoding config). - (Laruence) - . Fixed bug #61827 (incorrect \e processing on Windows) (Anatoliy) - . Fixed bug #61782 (__clone/__destruct do not match other methods when checking - access controls). (Stas) - . Fixed bug #61764 ('I' unpacks n as signed if n > 2^31-1 on LP64). (Gustavo) - . Fixed bug #61761 ('Overriding' a private static method with a different - signature causes crash). (Laruence) - . Fixed bug #61730 (Segfault from array_walk modifying an array passed by - reference). (Laruence) - . Fixed bug #61728 (PHP crash when calling ob_start in request_shutdown - phase). (Laruence) - . Fixed bug #61713 (Logic error in charset detection for htmlentities). - (Anatoliy) - . Fixed bug #61660 (bin2hex(hex2bin($data)) != $data). (Nikita Popov) - . Fixed bug #61650 (ini parser crashes when using ${xxxx} ini variables - (without apache2)). (Laruence) - . Fixed bug #61605 (header_remove() does not remove all headers). (Laruence) - . Fixed bug #54547 (wrong equality of string numbers). (Gustavo) - . Fixed bug #54197 ([PATH=] sections incompatibility with user_ini.filename - set to null). (Anatoliy) - . Changed php://fd to be available only for CLI. - -- CURL: - . Fixed bug #61948 (CURLOPT_COOKIEFILE '' raises open_basedir restriction). - (Laruence) - -- Fileinfo - . Fixed bug #61812 (Uninitialised value used in libmagic). - (Laruence, Gustavo) - . Fixed bug #61566 failure caused by the posix lseek and read versions - under windows in cdf_read(). (Anatoliy) - . Fixed bug #61565 where php_stream_open_wrapper_ex tries to open a - directory descriptor under windows. (Anatoliy) - -- Intl - . Fixed bug #62082 (Memory corruption in internal function - get_icu_disp_value_src_php()). (Gustavo) - -- Libxml: - . Fixed bug #61617 (Libxml tests failed(ht is already destroyed)). - (Laruence) - -- PDO: - . Fixed bug #61755 (A parsing bug in the prepared statements can lead to - access violations). (Johannes) - -- Phar: - . Fixed bug #61065 (Secunia SA44335, CVE-2012-2386). (Rasmus) - -- Pgsql: - . Added pg_escape_identifier/pg_escape_literal. (Yasuo Ohgaki) - -- Streams: - . Fixed bug #61961 (file_get_contents leaks when access empty file with - maxlen set). (Reeze) - -- Zlib: - . Fixed bug #61820 (using ob_gzhandler will complain about headers already - sent when no compression). (Mike) - . Fixed bug #61443 (can't change zlib.output_compression on the fly). (Mike) - . Fixed bug #60761 (zlib.output_compression fails on refresh). (Mike) - -08 May 2012, PHP 5.4.3 - -- CGI - . Re-Fix PHP-CGI query string parameter vulnerability, CVE-2012-1823. - (Stas) - . Fix bug #61807 - Buffer Overflow in apache_request_headers. - (nyt-php at countercultured dot net). - -03 May 2012, PHP 5.4.2 - -- Fix PHP-CGI query string parameter vulnerability, CVE-2012-1823. (Rasmus) - -26 Apr 2012, PHP 5.4.1 - -- CLI Server: - . Fixed bug #61461 (missing checks around malloc() calls). (Ilia) - . Implemented FR #60850 (Built in web server does not set - $_SERVER['SCRIPT_FILENAME'] when using router). (Laruence) - . "Connection: close" instead of "Connection: closed" (Gustavo) - -- Core: - . Fixed crash in ZTS using same class in many threads. (Johannes) - . Fixed bug #61374 (html_entity_decode tries to decode code points that don't - exist in ISO-8859-1). (Gustavo) - . Fixed bug #61273 (call_user_func_array with more than 16333 arguments - leaks / crashes). (Laruence) - . Fixed bug #61225 (Incorrect lexing of 0b00*+). (Pierrick) - . Fixed bug #61165 (Segfault - strip_tags()). (Laruence) - . Fixed bug #61106 (Segfault when using header_register_callback). (Nikita - Popov) - . Fixed bug #61087 (Memory leak in parse_ini_file when specifying - invalid scanner mode). (Nikic, Laruence) - . Fixed bug #61072 (Memory leak when restoring an exception handler). - (Nikic, Laruence) - . Fixed bug #61058 (array_fill leaks if start index is PHP_INT_MAX). - (Laruence) - . Fixed bug #61052 (Missing error check in trait 'insteadof' clause). (Stefan) - . Fixed bug #61011 (Crash when an exception is thrown by __autoload - accessing a static property). (Laruence) - . Fixed bug #61000 (Exceeding max nesting level doesn't delete numerical - vars). (Laruence) - . Fixed bug #60978 (exit code incorrect). (Laruence) - . Fixed bug #60911 (Confusing error message when extending traits). (Stefan) - . Fixed bug #60801 (strpbrk() mishandles NUL byte). (Adam) - . Fixed bug #60717 (Order of traits in use statement can cause a fatal - error). (Stefan) - . Fixed bug #60573 (type hinting with "self" keyword causes weird errors). - (Laruence) - . Fixed bug #60569 (Nullbyte truncates Exception $message). (Ilia) - . Fixed bug #52719 (array_walk_recursive crashes if third param of the - function is by reference). (Nikita Popov) - . Improve performance of set_exception_handler while doing reset (Laruence) - -- fileinfo: - . Fix fileinfo test problems. (Anatoliy Belsky) - -- FPM - . Fixed bug #61430 (Transposed memset() params in sapi/fpm/fpm/fpm_shm.c). - (michaelhood at gmail dot com, Ilia) - -- Ibase - . Fixed bug #60947 (Segmentation fault while executing ibase_db_info). - (Ilia) - -- Installation - . Fixed bug #61172 (Add Apache 2.4 support). (Chris Jones) - -- Intl: - . Fixed bug #61487 (Incorrent bounds checking in grapheme_strpos). - (Stas) - -- mbstring: - . MFH mb_ereg_replace_callback() for security enhancements. (Rui) - -- mysqli - . Fixed bug #61003 (mysql_stat() require a valid connection). (Johannes). - -- mysqlnd - . Fixed bug #61704 (Crash apache, phpinfo() threading issue). (Johannes) - . Fixed bug #60948 (mysqlnd FTBFS when -Wformat-security is enabled). - (Johannes) - -- PDO - . Fixed bug #61292 (Segfault while calling a method on an overloaded PDO - object). (Laruence) - -- PDO_mysql - . Fixed bug #61207 (PDO::nextRowset() after a multi-statement query doesn't - always work). (Johannes) - . Fixed bug #61194 (PDO should export compression flag with myslqnd). - (Johannes) - -- PDO_odbc - . Fixed bug #61212 (PDO ODBC Segfaults on SQL_SUCESS_WITH_INFO). (Ilia) - -- Phar - . Fixed bug #61184 (Phar::webPhar() generates headers with trailing NUL - bytes). (Nikita Popov) - -- Readline: - . Fixed bug #61088 (Memory leak in readline_callback_handler_install). - (Nikic, Laruence) - -- Reflection: - . Implemented FR #61602 (Allow access to the name of constant - used as function/method parameter's default value). (reeze.xia@gmail.com) - . Fixed bug #60968 (Late static binding doesn't work with - ReflectionMethod::invokeArgs()). (Laruence) - -- Session - . Fixed bug #60634 (Segmentation fault when trying to die() in - SessionHandler::write()). (Ilia) - -- SOAP - . Fixed bug #61423 (gzip compression fails). (Ilia) - . Fixed bug #60887 (SoapClient ignores user_agent option and sends no - User-Agent header). (carloschilazo at gmail dot com) - . Fixed bug #60842, #51775 (Chunked response parsing error when - chunksize length line is > 10 bytes). (Ilia) - . Fixed bug #49853 (Soap Client stream context header option ignored). - (Dmitry) - -- SPL: - . Fixed bug #61453 (SplObjectStorage does not identify objects correctly). - (Gustavo) - . Fixed bug #61347 (inconsistent isset behavior of Arrayobject). (Laruence) - -- Standard: - . Fixed memory leak in substr_replace. (Pierrick) - . Make max_file_uploads ini directive settable outside of php.ini (Rasmus) - . Fixed bug #61409 (Bad formatting on phpinfo()). (Jakub Vrana) - . Fixed bug #60222 (time_nanosleep() does validate input params). (Ilia) - . Fixed bug #60106 (stream_socket_server silently truncates long unix socket - paths). (Ilia) - -- XMLRPC: - . Fixed bug #61264 (xmlrpc_parse_method_descriptions leaks temporary - variable). (Nikita Popov) - . Fixed bug #61097 (Memory leak in xmlrpc functions copying zvals). (Nikita - Popov) - -- Zlib: - . Fixed bug #61306 (initialization of global inappropriate for ZTS). (Gustavo) - . Fixed bug #61287 (A particular string fails to decompress). (Mike) - . Fixed bug #61139 (gzopen leaks when specifying invalid mode). (Nikita Popov) - -01 Mar 2012, PHP 5.4.0 - -- Installation: - . autoconf 2.59+ is now supported (and required) for generating the - configure script with ./buildconf. Autoconf 2.60+ is desirable - otherwise the configure help order may be incorrect. (Rasmus, Chris Jones) - -- Removed legacy features: - . break/continue $var syntax. (Dmitry) - . Safe mode and all related php.ini options. (Kalle) - . register_globals and register_long_arrays php.ini options. (Kalle) - . import_request_variables(). (Kalle) - . allow_call_time_pass_reference. (Pierrick) - . define_syslog_variables php.ini option and its associated function. (Kalle) - . highlight.bg php.ini option. (Kalle) - . safe_mode, safe_mode_gid, safe_mode_include_dir, - safe_mode_exec_dir, safe_mode_allowed_env_vars and - safe_mode_protected_env_vars php.ini options. - . zend.ze1_compatibility_mode php.ini option. - . Session bug compatibility mode (session.bug_compat_42 and - session.bug_compat_warn php.ini options). (Kalle) - . session_is_registered(), session_register() and session_unregister() - functions. (Kalle) - . y2k_compliance php.ini option. (Kalle) - . magic_quotes_gpc, magic_quotes_runtime and magic_quotes_sybase - php.ini options. get_magic_quotes_gpc, get_magic_quotes_runtime are kept - but always return false, set_magic_quotes_runtime raises an - E_CORE_ERROR. (Pierrick, Pierre) - . Removed support for putenv("TZ=..") for setting the timezone. (Derick) - . Removed the timezone guessing algorithm in case the timezone isn't set with - date.timezone or date_default_timezone_set(). Instead of a guessed - timezone, "UTC" is now used instead. (Derick) - -- Moved extensions to PECL: - . ext/sqlite. (Note: the ext/sqlite3 and ext/pdo_sqlite extensions are - not affected) (Johannes) - -- General improvements: - . Added short array syntax support ([1,2,3]), see UPGRADING guide for full - details. (rsky0711 at gmail . com, sebastian.deutsch at 9elements . com, - Pierre) - . Added binary number format (0b001010). (Jonah dot Harris at gmail dot com) - . Added support for Class::{expr}() syntax (Pierrick) - . Added multibyte support by default. Previously PHP had to be compiled - with --enable-zend-multibyte. Now it can be enabled or disabled through - the zend.multibyte directive in php.ini. (Dmitry) - . Removed compile time dependency from ext/mbstring (Dmitry) - . Added support for Traits. (Stefan, with fixes by Dmitry and Laruence) - . Added closure $this support back. (Stas) - . Added array dereferencing support. (Felipe) - . Added callable typehint. (Hannes) - . Added indirect method call through array. FR #47160. (Felipe) - . Added DTrace support. (David Soria Parra) - . Added class member access on instantiation (e.g. (new foo)->bar()) support. - (Felipe) - . ). (Etienne) - . Fixed bug #60965 (Buffer overflow on htmlspecialchars/entities with - $double=false). (Gustavo) - . Fixed bug #60895 (Possible invalid handler usage in windows random - functions). (Pierre) - . Fixed bug #60879 (unserialize() Does not invoke __wakeup() on object). - (Pierre, Steve) - . Fixed bug #60825 (Segfault when running symfony 2 tests). - (Dmitry, Laruence) - . Fixed bug #60627 (httpd.worker segfault on startup with php_value). - . Fixed bug #60613 (Segmentation fault with $cls->{expr}() syntax). (Dmitry) - . Fixed bug #60611 (Segmentation fault with Cls::{expr}() syntax). (Laruence) - (Laruence) - . Fixed bug #60558 (Invalid read and writes). (Laruence) - . Fixed bug #60444 (Segmentation fault with include & class extending). - (Laruence, Dmitry). - . Fixed bug #60362 (non-existent sub-sub keys should not have values). - (Laruence, alan_k, Stas) - . Fixed bug #60350 (No string escape code for ESC (ascii 27), normally \e). - (php at mickweiss dot com) - . Fixed bug #60321 (ob_get_status(true) no longer returns an array when - buffer is empty). (Pierrick) - . Fixed bug #60282 (Segfault when using ob_gzhandler() with open buffers). - (Laruence) - . Fixed bug #60240 (invalid read/writes when unserializing specially crafted - strings). (Mike) - . Fixed bug #60227 (header() cannot detect the multi-line header with - CR(0x0D)). (rui) - . Fixed bug #60174 (Notice when array in method prototype error). - (Laruence) - . Fixed bug #60169 (Conjunction of ternary and list crashes PHP). - (Laruence) - . Fixed bug #60038 (SIGALRM cause segfault in php_error_cb). (Laruence) - (klightspeed at netspace dot net dot au) - . Fixed bug #55871 (Interruption in substr_replace()). (Stas) - . Fixed bug #55801 (Behavior of unserialize has changed). (Mike) - . Fixed bug #55758 (Digest Authenticate missed in 5.4) . (Laruence) - . Fixed bug #55748 (multiple NULL Pointer Dereference with zend_strndup()) - (CVE-2011-4153). (Stas) - . Fixed bug #55124 (recursive mkdir fails with current (dot) directory in path). - (Pierre) - . Fixed bug #55084 (Function registered by header_register_callback is - called only once per process). (Hannes) - . Implement FR #54514 (Get php binary path during script execution). - (Laruence) - . Fixed bug #52211 (iconv() returns part of string on error). (Felipe) - . Fixed bug #51860 (Include fails with toplevel symlink to /). (Dmitry) - -- Improved generic SAPI support: - . Added $_SERVER['REQUEST_TIME_FLOAT'] to include microsecond precision. - (Patrick) - . Added header_register_callback() which is invoked immediately - prior to the sending of headers and after default headers have - been added. (Scott) - . Added http_response_code() function. FR #52555. (Paul Dragoonis, Kalle) - . Fixed bug #55500 (Corrupted $_FILES indices lead to security concern). - (CVE-2012-1172). (Stas) - . Fixed bug #54374 (Insufficient validating of upload name leading to - corrupted $_FILES indices). (CVE-2012-1172). (Stas, lekensteyn at gmail dot com) - -- Improved CLI SAPI: - . Added built-in web server that is intended for testing purpose. - (Moriyoshi, Laruence, and fixes by Pierre, Derick, Arpad, - chobieee at gmail dot com) - . Added command line option --rz which shows information of the - named Zend extension. (Johannes) - . Interactive readline shell improvements: (Johannes) - . Added "cli.pager" php.ini setting to set a pager for output. - . Added "cli.prompt" php.ini setting to configure the shell prompt. - . Added shortcut #inisetting=value to change php.ini settings at run-time. - . Changed shell not to terminate on fatal errors. - . Interactive shell works with shared readline extension. FR #53878. - -- Improved CGI/FastCGI SAPI: (Dmitry) - . Added apache compatible functions: apache_child_terminate(), - getallheaders(), apache_request_headers() and apache_response_headers() - . Improved performance of FastCGI request parsing. - . Fixed reinitialization of SAPI callbacks after php_module_startup(). - (Dmitry) - -- Improved PHP-FPM SAPI: - . Removed EXPERIMENTAL flag. (fat) - . Fixed bug #60659 (FPM does not clear auth_user on request accept). - (bonbons at linux-vserver dot org) - -- Improved Litespeed SAPI: - . Fixed bug #55769 (Make Fails with "Missing Separator" error). (Adam) - -- Improved Date extension: - . Added the + modifier to parseFromFormat to allow trailing text in the - string to parse without throwing an error. (Stas, Derick) - -- Improved DBA extension: - . Added Tokyo Cabinet abstract DB support. (Michael Maclean) - . Added Berkeley DB 5 support. (Johannes, Chris Jones) - -- Improved DOM extension: - . Added the ability to pass options to loadHTML (Chregu, fxmulder at gmail dot com) - -- Improved filesystem functions: - . scandir() now accepts SCANDIR_SORT_NONE as a possible sorting_order value. - FR #53407. (Adam) - -- Improved HASH extension: - . Added Jenkins's one-at-a-time hash support. (Martin Jansen) - . Added FNV-1 hash support. (Michael Maclean) - . Made Adler32 algorithm faster. FR #53213. (zavasek at yandex dot ru) - . Removed Salsa10/Salsa20, which are actually stream ciphers (Mike) - . Fixed bug #60221 (Tiger hash output byte order) (Mike) - -- Improved intl extension: - . Added Spoofchecker class, allows checking for visibly confusable characters and - other security issues. (Scott) - . Added Transliterator class, allowing transliteration of strings. - (Gustavo) - . Added support for UTS #46. (Gustavo) - . Fixed build on Fedora 15 / Ubuntu 11. (Hannes) - . Fixed bug #55562 (grapheme_substr() returns false on big length). (Stas) - -- Improved JSON extension: - . Added new json_encode() option JSON_UNESCAPED_UNICODE. FR #53946. - (Alexander, Gwynne) - . Added JsonSerializable interface. (Sara) - . Added JSON_BIGINT_AS_STRING, extended json_decode() sig with $options. - (Sara) - . Added support for JSON_NUMERIC_CHECK option in json_encode() that converts - numeric strings to integers. (Ilia) - . Added new json_encode() option JSON_UNESCAPED_SLASHES. FR #49366. (Adam) - . Added new json_encode() option JSON_PRETTY_PRINT. FR #44331. (Adam) - -- Improved LDAP extension: - . Added paged results support. FR #42060. (ando@OpenLDAP.org, - iarenuno@eteo.mondragon.edu, jeanseb@au-fil-du.net, remy.saissy@gmail.com) - -- Improved mbstring extension: - . Added Shift_JIS/UTF-8 Emoji (pictograms) support. (Rui) - . Added JIS X0213:2004 (Shift_JIS-2004, EUC-JP-2004, ISO-2022-JP-2004) - support. (Rui) - . Ill-formed UTF-8 check for security enhancements. (Rui) - . Added MacJapanese (Shift_JIS) and gb18030 encoding support. (Rui) - . Added encode/decode in hex format to mb_[en|de]code_numericentity(). (Rui) - . Added user JIS X0213:2004 (Shift_JIS-2004, EUC-JP-2004, ISO-2022-JP-2004) - support. (Rui) - . Added the user defined area for CP936 and CP950 (Rui). - . Fixed bug #60306 (Characters lost while converting from cp936 to utf8). - (Laruence) - -- Improved MySQL extensions: - . MySQL: Deprecated mysql_list_dbs(). FR #50667. (Andrey) - . mysqlnd: Added named pipes support. FR #48082. (Andrey) - . MySQLi: Added iterator support in MySQLi. mysqli_result implements - Traversable. (Andrey, Johannes) - . PDO_mysql: Removed support for linking with MySQL client libraries older - than 4.1. (Johannes) - . ext/mysql, mysqli and pdo_mysql now use mysqlnd by default. (Johannes) - . Fixed bug #55473 (mysql_pconnect leaks file descriptors on reconnect). - (Andrey, Laruence) - . Fixed bug #55653 (PS crash with libmysql when binding same variable as - param and out). (Laruence) - -- Improved OpenSSL extension: - . Added AES support. FR #48632. (yonas dot y at gmail dot com, Pierre) - . Added no padding option to openssl_encrypt()/openssl_decrypt(). (Scott) - . Use php's implementation for Windows Crypto API in - openssl_random_pseudo_bytes. (Pierre) - . On error in openssl_random_pseudo_bytes() made sure we set strong result - to false. (Scott) - . Fixed possible attack in SSL sockets with SSL 3.0 / TLS 1.0. - CVE-2011-3389. (Scott) - . Fixed bug #61124 (Crash when decoding an invalid base64 encoded string). - (me at ktamura dot com, Scott) - -- Improved PDO: - . Fixed PDO objects binary incompatibility. (Dmitry) - -- PDO DBlib driver: - . Added nextRowset support. - . Fixed bug #50755 (PDO DBLIB Fails with OOM). - -- Improved PostgreSQL extension: - . Added support for "extra" parameter for PGNotify(). - (r dot i dot k at free dot fr, Ilia) - -- Improved PCRE extension: - . Changed third parameter of preg_match_all() to optional. FR #53238. (Adam) - -- Improved Readline extension: - . Fixed bug #54450 (Enable callback support when built against libedit). - (fedora at famillecollet dot com, Hannes) - -- Improved Reflection extension: - . Added ReflectionClass::newInstanceWithoutConstructor() to create a new - instance of a class without invoking its constructor. FR #55490. - (Sebastian) - . Added ReflectionExtension::isTemporary() and - ReflectionExtension::isPersistent() methods. (Johannes) - . Added ReflectionZendExtension class. (Johannes) - . Added ReflectionClass::isCloneable(). (Felipe) - -- Improved Session extension: - . Expose session status via new function, session_status (FR #52982) (Arpad) - . Added support for object-oriented session handlers. (Arpad) - . Added support for storing upload progress feedback in session data. (Arnaud) - . Changed session.entropy_file to default to /dev/urandom or /dev/arandom if - either is present at compile time. (Rasmus) - . Fixed bug #60860 (session.save_handler=user without defined function core - dumps). (Felipe) - . Implement FR #60551 (session_set_save_handler should support a core's - session handler interface). (Arpad) - . Fixed bug #60640 (invalid return values). (Arpad) - -- Improved SNMP extension (Boris Lytochkin): - . Added OO API. FR #53594 (php-snmp rewrite). - . Sanitized return values of existing functions. Now it returns FALSE on - failure. - . Allow ~infinite OIDs in GET/GETNEXT/SET queries. Autochunk them to max_oids - upon request. - . Introducing unit tests for extension with ~full coverage. - . IPv6 support. (FR #42918) - . Way of representing OID value can now be changed when SNMP_VALUE_OBJECT - is used for value output mode. Use or'ed SNMP_VALUE_LIBRARY(default if - not specified) or SNMP_VALUE_PLAIN. (FR #54502) - . Fixed bug #60749 (SNMP module should not strip non-standard SNMP port - from hostname). (Boris Lytochkin) - . Fixed bug #60585 (php build fails with USE flag snmp when IPv6 support - is disabled). (Boris Lytochkin) - . Fixed bug #53862 (snmp_set_oid_output_format does not allow returning to default) - . Fixed bug #46065 (snmp_set_quick_print() persists between requests) - . Fixed bug #45893 (Snmp buffer limited to 2048 char) - . Fixed bug #44193 (snmp v3 noAuthNoPriv doesn't work) - -- Improved SOAP extension: - . Added new SoapClient option "keep_alive". FR #60329. (Pierrick) - . Fixed basic HTTP authentication for WSDL sub requests. (Dmitry) - -- Improved SPL extension: - . Added RegexIterator::getRegex() method. (Joshua Thijssen) - . Added SplObjectStorage::getHash() hook. (Etienne) - . Added CallbackFilterIterator and RecursiveCallbackFilterIterator. (Arnaud) - . Added missing class_uses(..) as pointed out by #55266 (Stefan) - . Immediately reject wrong usages of directories under Spl(Temp)FileObject - and friends. (Etienne, Pierre) - . FilesystemIterator, GlobIterator and (Recursive)DirectoryIterator now use - the default stream context. (Hannes) - . Fixed bug #60201 (SplFileObject::setCsvControl does not expose third - argument via Reflection). (Peter) - . Fixed bug #55287 (spl_classes() not includes CallbackFilter classes) - (sasezaki at gmail dot com, salathe) - -- Improved Sysvshm extension: - . Fixed bug #55750 (memory copy issue in sysvshm extension). - (Ilia, jeffhuang9999 at gmail dot com) - -- Improved Tidy extension: - . Fixed bug #54682 (Tidy::diagnose() NULL pointer dereference). - (Maksymilian Arciemowicz, Felipe) - -- Improved Tokenizer extension: - . Fixed bug #54089 (token_get_all with regards to __halt_compiler is - not binary safe). (Nikita Popov) - -- Improved XSL extension: - . Added XsltProcessor::setSecurityPrefs($options) and getSecurityPrefs() to - define forbidden operations within XSLT stylesheets, default is not to - enable write operations from XSLT. Bug #54446 (Chregu, Nicolas Gregoire) - . XSL doesn't stop transformation anymore, if a PHP function can't be called - (Christian) - -- Improved ZLIB extension: - . Re-implemented non-file related functionality. (Mike) - . Fixed bug #55544 (ob_gzhandler always conflicts with zlib.output_compression). - (Mike) - -14 Jun 2012, PHP 5.3.14 - -- CLI SAPI: - . Fixed bug #61546 (functions related to current script failed when chdir() - in cli sapi). (Laruence, reeze.xia@gmail.com) - -- CURL: - . Fixed bug #61948 (CURLOPT_COOKIEFILE '' raises open_basedir restriction). - (Laruence) - -- COM: - . Fixed bug #62146 com_dotnet cannot be built shared. (Johannes) - -- Core: - . Fixed CVE-2012-2143. (Solar Designer) - . Fixed missing bound check in iptcparse(). (chris at chiappa.net) - . Fixed bug #62373 (serialize() generates wrong reference to the object). - (Moriyoshi) - . Fixed bug #62005 (unexpected behavior when incrementally assigning to a - member of a null object). (Laruence) - . Fixed bug #61991 (long overflow in realpath_cache_get()). (Anatoliy) - . Fixed bug #61764 ('I' unpacks n as signed if n > 2^31-1 on LP64). (Gustavo) - . Fixed bug #61730 (Segfault from array_walk modifying an array passed by - reference). (Laruence) - . Fixed bug #61713 (Logic error in charset detection for htmlentities). - (Anatoliy) - . Fixed bug #54197 ([PATH=] sections incompatibility with user_ini.filename - set to null). (Anatoliy) - . Changed php://fd to be available only for CLI. - -- Fileinfo: - . Fixed bug #61812 (Uninitialised value used in libmagic). - (Laruence, Gustavo) - -- Iconv extension: - . Fixed a bug that iconv extension fails to link to the correct library - when another extension makes use of a library that links to the iconv - library. See https://bugs.gentoo.org/show_bug.cgi?id=364139 for detail. - (Moriyoshi) - -- Intl: - . Fixed bug #62082 (Memory corruption in internal function - get_icu_disp_value_src_php()). (Gustavo) - -- JSON - . Fixed bug #61537 (json_encode() incorrectly truncates/discards - information). (Adam) - -- PDO: - . Fixed bug #61755 (A parsing bug in the prepared statements can lead to - access violations). (Johannes) - -- Phar: - . Fix bug #61065 (Secunia SA44335). (Rasmus) - -- Streams: - . Fixed bug #61961 (file_get_contents leaks when access empty file with - maxlen set). (Reeze) - -08 May 2012, PHP 5.3.13 -- CGI - . Improve fix for PHP-CGI query string parameter vulnerability, CVE-2012-2311. - (Stas) - -03 May 2012, PHP 5.3.12 -- Fix PHP-CGI query string parameter vulnerability, CVE-2012-1823. (Rasmus) - -26 Apr 2012, PHP 5.3.11 - -- Core: - . Fixed bug #61605 (header_remove() does not remove all headers). - (Laruence) - . Fixed bug #61541 (Segfault when using ob_* in output_callback). - (reeze.xia@gmail.com) - . Fixed bug #61273 (call_user_func_array with more than 16333 arguments - leaks / crashes). (Laruence) - . Fixed bug #61165 (Segfault - strip_tags()). (Laruence) - . Improved max_input_vars directive to check nested variables (Dmitry). - . Fixed bug #61095 (Incorect lexing of 0x00*+). (Etienne) - . Fixed bug #61087 (Memory leak in parse_ini_file when specifying - invalid scanner mode). (Nikic, Laruence) - . Fixed bug #61072 (Memory leak when restoring an exception handler). - (Nikic, Laruence) - . Fixed bug #61058 (array_fill leaks if start index is PHP_INT_MAX). - (Laruence) - . Fixed bug #61043 (Regression in magic_quotes_gpc fix for CVE-2012-0831). - (Ondřej Surý) - . Fixed bug #61000 (Exceeding max nesting level doesn't delete numerical - vars). (Laruence) - . Fixed bug #60895 (Possible invalid handler usage in windows random - functions). (Pierre) - . Fixed bug #60825 (Segfault when running symfony 2 tests). - (Dmitry, Laruence) - . Fixed bug #60801 (strpbrk() mishandles NUL byte). (Adam) - . Fixed bug #60569 (Nullbyte truncates Exception $message). (Ilia) - . Fixed bug #60227 (header() cannot detect the multi-line header with CR). - (rui, Gustavo) - . Fixed bug #60222 (time_nanosleep() does validate input params). (Ilia) - . Fixed bug #54374 (Insufficient validating of upload name leading to - corrupted $_FILES indices). (CVE-2012-1172). (Stas, lekensteyn at - gmail dot com, Pierre) - . Fixed bug #52719 (array_walk_recursive crashes if third param of the - function is by reference). (Nikita Popov) - . Fixed bug #51860 (Include fails with toplevel symlink to /). (Dmitry) - -- DOM - . Added debug info handler to DOM objects. (Gustavo, Joey Smith) - -- FPM - . Fixed bug #61430 (Transposed memset() params in sapi/fpm/fpm/fpm_shm.c). - (michaelhood at gmail dot com, Ilia) - -- Ibase - . Fixed bug #60947 (Segmentation fault while executing ibase_db_info). - (Ilia) - -- Installation - . Fixed bug #61172 (Add Apache 2.4 support). (Chris Jones) - -- Fileinfo - . Fixed bug #61173 (Unable to detect error from finfo constructor). (Gustavo) - -- Firebird Database extension (ibase): - . Fixed bug #60802 (ibase_trans() gives segfault when passing params). - -- Libxml: - . Fixed bug #61617 (Libxml tests failed(ht is already destroyed)). - (Laruence) - . Fixed bug #61367 (open_basedir bypass using libxml RSHUTDOWN). - (Tim Starling) - -- mysqli - . Fixed bug #61003 (mysql_stat() require a valid connection). (Johannes). - -- PDO_mysql - . Fixed bug #61207 (PDO::nextRowset() after a multi-statement query doesn't - always work). (Johannes) - . Fixed bug #61194 (PDO should export compression flag with myslqnd). - (Johannes) - -- PDO_odbc - . Fixed bug #61212 (PDO ODBC Segfaults on SQL_SUCESS_WITH_INFO). (Ilia) - -- PDO_pgsql - . Fixed bug #61267 (pdo_pgsql's PDO::exec() returns the number of SELECTed - rows on postgresql >= 9). (ben dot pineau at gmail dot com) - -- PDO_Sqlite extension: - . Add createCollation support. (Damien) - -- Phar: - . Fixed bug #61184 (Phar::webPhar() generates headers with trailing NUL - bytes). (Nikic) - -- PHP-FPM SAPI: - . Fixed bug #60811 (php-fpm compilation problem). (rasmus) - -- Readline: - . Fixed bug #61088 (Memory leak in readline_callback_handler_install). - (Nikic, Laruence) - . Add open_basedir checks to readline_write_history and readline_read_history. - (Rasmus, reported by Mateusz Goik) - -- Reflection: - . Fixed bug #61388 (ReflectionObject:getProperties() issues invalid reads - when get_properties returns a hash table with (inaccessible) dynamic - numeric properties). (Gustavo) - . Fixed bug #60968 (Late static binding doesn't work with - ReflectionMethod::invokeArgs()). (Laruence) - -- SOAP - . Fixed basic HTTP authentication for WSDL sub requests. (Dmitry) - . Fixed bug #60887 (SoapClient ignores user_agent option and sends no - User-Agent header). (carloschilazo at gmail dot com) - . Fixed bug #60842, #51775 (Chunked response parsing error when - chunksize length line is > 10 bytes). (Ilia) - . Fixed bug #49853 (Soap Client stream context header option ignored). - (Dmitry) - -- SPL - . Fixed memory leak when calling SplFileInfo's constructor twice. (Felipe) - . Fixed bug #61418 (Segmentation fault when DirectoryIterator's or - FilesystemIterator's iterators are requested more than once without - having had its dtor callback called in between). (Gustavo) - . Fixed bug #61347 (inconsistent isset behavior of Arrayobject). (Laruence) - . Fixed bug #61326 (ArrayObject comparison). (Gustavo) - -- SQLite3 extension: - . Add createCollation() method. (Brad Dewar) - -- Session: - . Fixed bug #60860 (session.save_handler=user without defined function core - dumps). (Felipe) - . Fixed bug #60634 (Segmentation fault when trying to die() in - SessionHandler::write()). (Ilia) - -- Streams: - . Fixed bug #61371 (stream_context_create() causes memory leaks on use - streams_socket_create). (Gustavo) - . Fixed bug #61253 (Wrappers opened with errors concurrency problem on ZTS). - (Gustavo) - . Fixed bug #61115 (stream related segfault on fatal error in - php_stream_context_link). (Gustavo) - . Fixed bug #60817 (stream_get_line() reads from stream even when there is - already sufficient data buffered). stream_get_line() now behaves more like - fgets(), as is documented. (Gustavo) - . Further fix for bug #60455 (stream_get_line misbehaves if EOF is not - detected together with the last read). (Gustavo) - . Fixed bug #60106 (stream_socket_server silently truncates long unix - socket paths). (Ilia) - -- Tidy: - . Fixed bug #54682 (tidy null pointer dereference). (Tony, David Soria Parra) - -- XMLRPC: - . Fixed bug #61264 (xmlrpc_parse_method_descriptions leaks temporary - variable). (Nikita Popov) - . Fixed bug #61097 (Memory leak in xmlrpc functions copying zvals). (Nikic) - -- Zlib: - . Fixed bug #61139 (gzopen leaks when specifying invalid mode). (Nikic) - -02 Feb 2012, PHP 5.3.10 - -- Core: - . Fixed arbitrary remote code execution vulnerability reported by Stefan - Esser, CVE-2012-0830. (Stas, Dmitry) - -10 Jan 2012, PHP 5.3.9 - -- Core: - . Added max_input_vars directive to prevent attacks based on hash collisions - (CVE-2011-4885) (Dmitry). - . Fixed bug #60205 (possible integer overflow in content_length). (Laruence) - . Fixed bug #60139 (Anonymous functions create cycles not detected by the - GC). (Dmitry) - . Fixed bug #60138 (GC crash with referenced array in RecursiveArrayIterator) - (Dmitry). - . Fixed bug #60120 (proc_open's streams may hang with stdin/out/err when - the data exceeds or is equal to 2048 bytes). (Pierre, Pascal Borreli) - . Fixed bug #60099 (__halt_compiler() works in braced namespaces). (Felipe) - . Fixed bug #60019 (Function time_nanosleep() is undefined on OS X). (Ilia) - . Fixed bug #55874 (GCC does not provide __sync_fetch_and_add on some archs). - (klightspeed at netspace dot net dot au) - . Fixed bug #55798 (serialize followed by unserialize with numeric object - prop. gives integer prop). (Gustavo) - . Fixed bug #55749 (TOCTOU issue in getenv() on Windows builds). (Pierre) - . Fixed bug #55707 (undefined reference to `__sync_fetch_and_add_4' on Linux - parisc). (Felipe) - . Fixed bug #55674 (fgetcsv & str_getcsv skip empty fields in some - tab-separated records). (Laruence) - . Fixed bug #55649 (Undefined function Bug()). (Laruence) - . Fixed bug #55622 (memory corruption in parse_ini_string). (Pierre) - . Fixed bug #55576 (Cannot conditionally move uploaded file without race - condition). (Gustavo) - . Fixed bug #55510: $_FILES 'name' missing first character after upload. - (Arpad) - . Fixed bug #55509 (segfault on x86_64 using more than 2G memory). (Laruence) - . Fixed bug #55504 (Content-Type header is not parsed correctly on - HTTP POST request). (Hannes) - . Fixed bug #55475 (is_a() triggers autoloader, new optional 3rd argument to - is_a and is_subclass_of). (alan_k) - . Fixed bug #52461 (Incomplete doctype and missing xmlns). - (virsacer at web dot de, Pierre) - . Fixed bug #55366 (keys lost when using substr_replace an array). (Arpad) - . Fixed bug #55273 (base64_decode() with strict rejects whitespace after - pad). (Ilia) - . Fixed bug #52624 (tempnam() by-pass open_basedir with nonnexistent - directory). (Felipe) - . Fixed bug #50982 (incorrect assumption of PAGE_SIZE size). (Dmitry) - . Fixed invalid free in call_user_method() function. (Felipe) - . Fixed bug #43200 (Interface implementation / inheritence not possible in - abstract classes). (Felipe) - - -- BCmath: - . Fixed bug #60377 (bcscale related crashes on 64bits platforms). (shm) - -- Calendar: - . Fixed bug #55797 (Integer overflow in SdnToGregorian leads to segfault (in - optimized builds). (Gustavo) - -- cURL: - . Fixed bug #60439 (curl_copy_handle segfault when used with - CURLOPT_PROGRESSFUNCTION). (Pierrick) - . Fixed bug #54798 (Segfault when CURLOPT_STDERR file pointer is closed - before calling curl_exec). (Hannes) - . Fixed issues were curl_copy_handle() would sometimes lose copied - preferences. (Hannes) - -- DateTime: - . Fixed bug #60373 (Startup errors with log_errors on cause segfault). - (Derick) - . Fixed bug #60236 (TLA timezone dates are not converted properly from - timestamp). (Derick) - . Fixed bug #55253 (DateTime::add() and sub() result -1 hour on objects with - time zone type 2). (Derick) - . Fixed bug #54851 (DateTime::createFromFormat() doesn't interpret "D"). - (Derick) - . Fixed bug #53502 (strtotime with timezone memory leak). (Derick) - . Fixed bug #52062 (large timestamps with DateTime::getTimestamp and - DateTime::setTimestamp). (Derick) - . Fixed bug #51994 (date_parse_from_format is parsing invalid date using 'yz' - format). (Derick) - . Fixed bug #52113 (Seg fault while creating (by unserialization) - DatePeriod). (Derick) - . Fixed bug #48476 (cloning extended DateTime class without calling - parent::__constr crashed PHP). (Hannes) - -- EXIF: - . Fixed bug #60150 (Integer overflow during the parsing of invalid exif - header). (CVE-2011-4566) (Stas, flolechaud at gmail dot com) - -- Fileinfo: - . Fixed bug #60094 (C++ comment fails in c89). (Laruence) - . Fixed possible memory leak in finfo_open(). (Felipe) - . Fixed memory leak when calling the Finfo constructor twice. (Felipe) - -- Filter: - . Fixed Bug #55478 (FILTER_VALIDATE_EMAIL fails with internationalized - domain name addresses containing >1 -). (Ilia) - -- FTP: - . Fixed bug #60183 (out of sync ftp responses). (bram at ebskamp dot me, - rasmus) - -- Gd: - . Fixed bug #60160 (imagefill() doesn't work correctly - for small images). (Florian) - . Fixed potential memory leak on a png error (Rasmus, Paul Saab) - -- Intl: - . Fixed bug #60192 (SegFault when Collator not constructed - properly). (Florian) - . Fixed memory leak in several Intl locale functions. (Felipe) - -- Json: - . Fixed bug #55543 (json_encode() with JSON_NUMERIC_CHECK fails on objects - with numeric string properties). (Ilia, dchurch at sciencelogic dot com) - -- Mbstring: - . Fixed possible crash in mb_ereg_search_init() using empty pattern. (Felipe) - -- MS SQL: - . Fixed bug #60267 (Compile failure with freetds 0.91). (Felipe) - -- MySQL: - . Fixed bug #55550 (mysql.trace_mode miscounts result sets). (Johannes) - -- MySQLi extension: - . Fixed bug #55859 (mysqli->stat property access gives error). (Andrey) - . Fixed bug #55582 (mysqli_num_rows() returns always 0 for unbuffered, when - mysqlnd is used). (Andrey) - . Fixed bug #55703 (PHP crash when calling mysqli_fetch_fields). - (eran at zend dot com, Laruence) - -- mysqlnd - . Fixed bug #55609 (mysqlnd cannot be built shared). (Johannes) - . Fixed bug #55067 (MySQL doesn't support compression - wrong config option). - (Andrey) - -- NSAPI SAPI: - . Don't set $_SERVER['HTTPS'] on unsecure connection (bug #55403). (Uwe - Schindler) - -- OpenSSL: - . Fixed bug #60279 (Fixed NULL pointer dereference in - stream_socket_enable_crypto, case when ssl_handle of session_stream is not - initialized.) (shm) - . Fix segfault with older versions of OpenSSL. (Scott) - -- Oracle Database extension (OCI8): - . Fixed bug #59985 (show normal warning text for OCI_NO_DATA). - (Chris Jones) - . Increased maximum Oracle error message buffer length for new 11.2.0.3 size. - (Chris Jones) - . Improve internal initalization failure error messages. (Chris Jones) - -- PDO - . Fixed bug #55776 (PDORow to session bug). (Johannes) - -- PDO Firebird: - . Fixed bug #48877 ("bindValue" and "bindParam" do not work for PDO Firebird). - (Mariuz) - . Fixed bug #47415 (PDO_Firebird segfaults when passing lowercased column name to bindColumn). - . Fixed bug #53280 (PDO_Firebird segfaults if query column count less than param count). - (Mariuz) - -- PDO MySQL driver: - . Fixed bug #60155 (pdo_mysql.default_socket ignored). (Johannes) - . Fixed bug #55870 (PDO ignores all SSL parameters when used with mysql - native driver). (Pierre) - . Fixed bug #54158 (MYSQLND+PDO MySQL requires #define - MYSQL_OPT_LOCAL_INFILE). (Andrey) - -- PDO OCI driver: - . Fixed bug #55768 (PDO_OCI can't resume Oracle session after it's been - killed). (mikhail dot v dot gavrilov at gmail dot com, Chris Jones, Tony) - -- Phar: - . Fixed bug #60261 (NULL pointer dereference in phar). (Felipe) - . Fixed bug #60164 (Stubs of a specific length break phar_open_from_fp - scanning for __HALT_COMPILER). (Ralph Schindler) - . Fixed bug #53872 (internal corruption of phar). (Hannes) - . Fixed bug #52013 (Unable to decompress files in a compressed phar). (Hannes) - -- PHP-FPM SAPI: - . Dropped restriction of not setting the same value multiple times, the last - one holds. (giovanni at giacobbi dot net, fat) - . Added .phar to default authorized extensions. (fat) - . Fixed bug #60659 (FPM does not clear auth_user on request accept). - (bonbons at linux-vserver dot org) - . Fixed bug #60629 (memory corruption when web server closed the fcgi fd). - (fat) - . Enhance error log when the primary script can't be open. FR #60199. (fat) - . Fixed bug #60179 (php_flag and php_value does not work properly). (fat) - . Fixed bug #55577 (status.html does not install). (fat) - . Fixed bug #55533 (The -d parameter doesn't work). (fat) - . Fixed bug #55526 (Heartbeat causes a lot of unnecessary events). (fat) - . Fixed bug #55486 (status show BIG processes number). (fat) - . Enhanced security by limiting access to user defined extensions. - FR #55181. (fat) - . Added process.max to control the number of process FPM can fork. FR #55166. - (fat) - . Implemented FR #54577 (Enhanced status page with full status and details - about each processes. Also provide a web page (status.html) for - real-time FPM status. (fat) - . Lowered default value for Process Manager. FR #54098. (fat) - . Implemented FR #52569 (Add the "ondemand" process-manager - to allow zero children). (fat) - . Added partial syslog support (on error_log only). FR #52052. (fat) - -- Postgres: - . Fixed bug #60244 (pg_fetch_* functions do not validate that row param - is >0). (Ilia) - . Added PGSQL_LIBPQ_VERSION/PGSQL_LIBPQ_VERSION_STR constants. (Yasuo) - -- Reflection: - . Fixed bug #60367 (Reflection and Late Static Binding). (Laruence) - -- Session: - . Fixed bug #55267 (session_regenerate_id fails after header sent). (Hannes) - -- SimpleXML: - . Reverted the SimpleXML->query() behaviour to returning empty arrays - instead of false when no nodes are found as it was since 5.3.3 - (bug #48601). (chregu, rrichards) - -- SOAP - . Fixed bug #54911 (Access to a undefined member in inherit SoapClient may - cause Segmentation Fault). (Dmitry) - . Fixed bug #48216 (PHP Fatal error: SOAP-ERROR: Parsing WSDL: - Extra content at the end of the doc, when server uses chunked transfer - encoding with spaces after chunk size). (Dmitry) - . Fixed bug #44686 (SOAP-ERROR: Parsing WSDL with references). (Dmitry) - -- Sockets: - . Fixed bug #60048 (sa_len a #define on IRIX). (china at thewrittenword dot - com) - -- SPL: - . Fixed bug #60082 (Crash in ArrayObject() when using recursive references). - (Tony) - . Fixed bug #55807 (Wrong value for splFileObject::SKIP_EMPTY). - (jgotti at modedemploi dot fr, Hannes) - . Fixed bug #54304 (RegexIterator::accept() doesn't work with scalar values). - (Hannes) - -- Streams: - . Fixed bug #60455 (stream_get_line misbehaves if EOF is not detected together - with the last read). (Gustavo) - -- Tidy: - . Fixed bug #54682 (Tidy::diagnose() NULL pointer dereference). - (Maksymilian Arciemowicz, Felipe) - -- XSL: - . Added xsl.security_prefs ini option to define forbidden operations within - XSLT stylesheets, default is not to enable write operations. This option - won't be in 5.4, since there's a new method. Fixes Bug #54446. (Chregu, - Nicolas Gregoire) - -23 Aug 2011, PHP 5.3.8 - -- Core: - . Fixed bug #55439 (crypt() returns only the salt for MD5). (Stas) - -- OpenSSL: - . Reverted a change in timeout handling restoring PHP 5.3.6 behavior, - as the new behavior caused mysqlnd SSL connections to hang (#55283). - (Pierre, Andrey, Johannes) - -18 Aug 2011, PHP 5.3.7 -- Upgraded bundled SQLite to version 3.7.7.1. (Scott) -- Upgraded bundled PCRE to version 8.12. (Scott) - -- Zend Engine: - . Fixed bug #55156 (ReflectionClass::getDocComment() returns comment even - though the class has none). (Felipe) - . Fixed bug #55007 (compiler fail after previous fail). (Felipe) - . Fixed bug #54910 (Crash when calling call_user_func with unknown function - name). (Dmitry) - . Fixed bug #54804 (__halt_compiler and imported namespaces). - (Pierrick, Felipe) - . Fixed bug #54624 (class_alias and type hint). (Felipe) - . Fixed bug #54585 (track_errors causes segfault). (Dmitry) - . Fixed bug #54423 (classes from dl()'ed extensions are not destroyed). - (Tony, Dmitry) - . Fixed bug #54372 (Crash accessing global object itself returned from its - __get() handle). (Dmitry) - . Fixed bug #54367 (Use of closure causes problem in ArrayAccess). (Dmitry) - . Fixed bug #54358 (Closure, use and reference). (Dmitry) - . Fixed bug #54262 (Crash when assigning value to a dimension in a non-array). - (Dmitry) - . Fixed bug #54039 (use() of static variables in lambda functions can break - staticness). (Dmitry) - -- Core - . Updated crypt_blowfish to 1.2. ((CVE-2011-2483) (Solar Designer) - . Removed warning when argument of is_a() or is_subclass_of() is not - a known class. (Stas) - . Fixed crash in error_log(). (Felipe) Reported by Mateusz Kocielski. - . Added PHP_MANDIR constant telling where the manpages were installed into, - and an --man-dir argument to php-config. (Hannes) - . Fixed a crash inside dtor for error handling. (Ilia) - . Fixed buffer overflow on overlog salt in crypt(). (Clément LECIGNE, Stas) - . Implemented FR #54459 (Range function accuracy). (Adam) - - . Fixed bug #55399 (parse_url() incorrectly treats ':' as a valid path). - (Ilia) - . Fixed bug #55339 (Segfault with allow_call_time_pass_reference = Off). - (Dmitry) - . Fixed bug #55295 [NEW]: popen_ex on windows, fixed possible heap overflow - (Pierre) - . Fixed bug #55258 (Windows Version Detecting Error). - ( xiaomao5 at live dot com, Pierre) - . Fixed bug #55187 (readlink returns weird characters when false result). - (Pierre) - . Fixed bug #55082 (var_export() doesn't escape properties properly). - (Gustavo) - . Fixed bug #55014 (Compile failure due to improper use of ctime_r()). (Ilia) - . Fixed bug #54939 (File path injection vulnerability in RFC1867 File upload - filename). (Felipe) Reported by Krzysztof Kotowicz. (CVE-2011-2202) - . Fixed bug #54935 php_win_err can lead to crash. (Pierre) - . Fixed bug #54924 (assert.* is not being reset upon request shutdown). (Ilia) - . Fixed bug #54895 (Fix compiling with older gcc version without need for - membar_producer macro). (mhei at heimpold dot de) - . Fixed bug #54866 (incorrect accounting for realpath_cache_size). - (Dustin Ward) - . Fixed bug #54723 (getimagesize() doesn't check the full ico signature). - (Scott) - . Fixed bug #54721 (Different Hashes on Windows, BSD and Linux on wrong Salt - size). (Pierre, os at irj dot ru) - . Fixed bug #54580 (get_browser() segmentation fault when browscap ini - directive is set through php_admin_value). (Gustavo) - . Fixed bug #54332 (Crash in zend_mm_check_ptr // Heap corruption). (Dmitry) - . Fixed bug #54305 (Crash in gc_remove_zval_from_buffer). (Dmitry) - . Fixed bug #54238 (use-after-free in substr_replace()). (Stas) - (CVE-2011-1148) - . Fixed bug #54204 (Can't set a value with a PATH section in php.ini). - (Pierre) - . Fixed bug #54180 (parse_url() incorrectly parses path when ? in fragment). - (tomas dot brastavicius at quantum dot lt, Pierrick) - . Fixed bug #54137 (file_get_contents POST request sends additional line - break). (maurice-php at mertinkat dot net, Ilia) - . Fixed bug #53848 (fgetcsv() ignores spaces at beginnings of fields). (Ilia) - . Alternative fix for bug #52550, as applied to the round() function (signed - overflow), as the old fix impacted the algorithm for numbers with magnitude - smaller than 0. (Gustavo) - . Fixed bug #53727 (Inconsistent behavior of is_subclass_of with interfaces) - (Ralph Schindler, Dmitry) - . Fixed bug #52935 (call exit in user_error_handler cause stream relate - core). (Gustavo) - . Fixed bug #51997 (SEEK_CUR with 0 value, returns a warning). (Ilia) - . Fixed bug #50816 (Using class constants in array definition fails). - (Pierrick, Dmitry) - . Fixed bug #50363 (Invalid parsing in convert.quoted-printable-decode - filter). (slusarz at curecanti dot org) - . Fixed bug #48465 (sys_get_temp_dir() possibly inconsistent when using - TMPDIR on Windows). (Pierre) - -- Apache2 Handler SAPI: - . Fixed bug #54529 (SAPI crashes on apache_config.c:197). - (hebergement at riastudio dot fr) - -- CLI SAPI: - . Fixed bug #52496 (Zero exit code on option parsing failure). (Ilia) - -- cURL extension: - . Added ini option curl.cainfo (support for custom cert db). (Pierre) - . Added CURLINFO_REDIRECT_URL support. (Daniel Stenberg, Pierre) - . Added support for CURLOPT_MAX_RECV_SPEED_LARGE and - CURLOPT_MAX_SEND_SPEED_LARGE. FR #51815. (Pierrick) - -- DateTime extension: - . Fixed bug where the DateTime object got changed while using date_diff(). - (Derick) - . Fixed bug #54340 (DateTime::add() method bug). (Adam) - . Fixed bug #54316 (DateTime::createFromFormat does not handle trailing '|' - correctly). (Adam) - . Fixed bug #54283 (new DatePeriod(NULL) causes crash). (Felipe) - . Fixed bug #51819 (Case discrepancy in timezone names cause Uncaught - exception and fatal error). (Hannes) - -- DBA extension: - . Supress warning on non-existent file open with Berkeley DB 5.2. (Chris Jones) - . Fixed bug #54242 (dba_insert returns true if key already exists). (Felipe) - -- Exif extesion: - . Fixed bug #54121 (error message format string typo). (Ilia) - -- Fileinfo extension: - . Fixed bug #54934 (Unresolved symbol strtoull in HP-UX 11.11). (Felipe) - -- Filter extension: - . Added 3rd parameter to filter_var_array() and filter_input_array() - functions that allows disabling addition of empty elements. (Ilia) - . Fixed bug #53037 (FILTER_FLAG_EMPTY_STRING_NULL is not implemented). (Ilia) - -- Interbase extension: - . Fixed bug #54269 (Short exception message buffer causes crash). (Felipe) - -- intl extension: - . Implemented FR #54561 (Expose ICU version info). (David Zuelke, Ilia) - . Implemented FR #54540 (Allow loading of arbitrary resource bundles when - fallback is disabled). (David Zuelke, Stas) - -- Imap extension: - . Fixed bug #55313 (Number of retries not set when params specified). - (kevin at kevinlocke dot name) - -- json extension: - . Fixed bug #54484 (Empty string in json_decode doesn't reset - json_last_error()). (Ilia) - -- LDAP extension: - . Fixed bug #53339 (Fails to build when compilng with gcc 4.5 and DSO - libraries). (Clint Byrum, Raphael) - -- libxml extension: - . Fixed bug #54601 (Removing the doctype node segfaults). (Hannes) - . Fixed bug #54440 (libxml extension ignores default context). (Gustavo) - -- mbstring extension: - . Fixed bug #54494 (mb_substr() mishandles UTF-32LE and UCS-2LE). (Gustavo) - -- MCrypt extension: - . Change E_ERROR to E_WARNING in mcrypt_create_iv when not enough data - has been fetched (Windows). (Pierre) - . Fixed bug #55169 (mcrypt_create_iv always fails to gather sufficient random - data on Windows). (Pierre) - -- mysqlnd - . Fixed crash when using more than 28,000 bound parameters. Workaround is to - set mysqlnd.net_cmd_buffer_size to at least 9000. (Andrey) - . Fixed bug #54674 mysqlnd valid_sjis_(head|tail) is using invalid operator - and range). (nihen at megabbs dot com, Andrey) - -- MySQLi extension: - . Fixed bug #55283 (SSL options set by mysqli_ssl_set ignored for MySQLi - persistent connections). (Andrey) - . Fixed Bug #54221 (mysqli::get_warnings segfault when used in multi queries). - (Andrey) - -- OpenSSL extension: - . openssl_encrypt()/openssl_decrypt() truncated keys of variable length - ciphers to the OpenSSL default for the algorithm. (Scott) - . On blocking SSL sockets respect the timeout option where possible. - (Scott) - . Fixed bug #54992 (Stream not closed and error not returned when SSL - CN_match fails). (Gustavo, laird_ngrps at dodo dot com dot au) - -- Oracle Database extension (OCI8): - . Added oci_client_version() returning the runtime Oracle client library - version. (Chris Jones) - -. PCRE extension: - . Increased the backtrack limit from 100000 to 1000000 (Rasmus) - -- PDO extension: - . Fixed bug #54929 (Parse error with single quote in sql comment). (Felipe) - . Fixed bug #52104 (bindColumn creates Warning regardless of ATTR_ERRMODE - settings). (Ilia) - -- PDO DBlib driver: - . Fixed bug #54329 (MSSql extension memory leak). - (dotslashpok at gmail dot com) - . Fixed bug #54167 (PDO_DBLIB returns null on SQLUNIQUE field). - (mjh at hodginsmedia dot com, Felipe) - -- PDO ODBC driver: - . Fixed data type usage in 64bit. (leocsilva at gmail dot com) - -- PDO MySQL driver: - . Fixed bug #54644 (wrong pathes in php_pdo_mysql_int.h). (Tony, Johannes) - . Fixed bug #53782 (foreach throws irrelevant exception). (Johannes, Andrey) - . Implemented FR #48587 (MySQL PDO driver doesn't support SSL connections). - (Rob) - -- PDO PostgreSQL driver: - . Fixed bug #54318 (Non-portable grep option used in PDO pgsql - configuration). (bwalton at artsci dot utoronto dot ca) - -- PDO Oracle driver: - . Fixed bug #44989 (64bit Oracle RPMs still not supported by pdo-oci). - (jbnance at tresgeek dot net) - -- Phar extension: - . Fixed bug #54395 (Phar::mount() crashes when calling with wrong parameters). - (Felipe) - -- PHP-FPM SAPI: - . Implemented FR #54499 (FPM ping and status_path should handle HEAD request). (fat) - . Implemented FR #54172 (Overriding the pid file location of php-fpm). (fat) - . Fixed missing Expires and Cache-Control headers for ping and status pages. - (fat) - . Fixed memory leak. (fat) Reported and fixed by Giovanni Giacobbi. - . Fixed wrong value of log_level when invoking fpm with -tt. (fat) - . Added xml format to the status page. (fat) - . Removed timestamp in logs written by children processes. (fat) - . Fixed exit at FPM startup on fpm_resources_prepare() errors. (fat) - . Added master rlimit_files and rlimit_core in the global configuration - settings. (fat) - . Removed pid in debug logs written by chrildren processes. (fat) - . Added custom access log (also added per request %CPU and memory - mesurement). (fat) - . Added a real scoreboard and several improvements to the status page. (fat) - -- Reflection extension: - . Fixed bug #54347 (reflection_extension does not lowercase module function - name). (Felipe, laruence at yahoo dot com dot cn) - -- SOAP extension: - . Fixed bug #55323 (SoapClient segmentation fault when XSD_TYPEKIND_EXTENSION - contains itself). (Dmitry) - . Fixed bug #54312 (soap_version logic bug). (tom at samplonius dot org) - -- Sockets extension: - . Fixed stack buffer overflow in socket_connect(). (CVE-2011-1938) - Found by Mateusz Kocielski, Marek Kroemeke and Filip Palian. (Felipe) - . Changed socket_set_block() and socket_set_nonblock() so they emit warnings - on error. (Gustavo) - . Fixed bug #51958 (socket_accept() fails on IPv6 server sockets). (Gustavo) - -- SPL extension: - . Fixed bug #54971 (Wrong result when using iterator_to_array with use_keys - on true). (Pierrick) - . Fixed bug #54970 (SplFixedArray::setSize() isn't resizing). (Felipe) - . Fixed bug #54609 (Certain implementation(s) of SplFixedArray cause hard - crash). (Felipe) - . Fixed bug #54384 (Dual iterators, GlobIterator, SplFileObject and - SplTempFileObject crash when user-space classes don't call the paren - constructor). (Gustavo) - . Fixed bug #54292 (Wrong parameter causes crash in - SplFileObject::__construct()). (Felipe) - . Fixed bug #54291 (Crash iterating DirectoryIterator for dir name starting - with \0). (Gustavo) - . Fixed bug #54281 (Crash in non-initialized RecursiveIteratorIterator). - (Felipe) - -- Streams: - . Fixed bug #54946 (stream_get_contents infinite loop). (Hannes) - . Fixed bug #54623 (Segfault when writing to a persistent socket after - closing a copy of the socket). (Gustavo) - . Fixed bug #54681 (addGlob() crashes on invalid flags). (Felipe) - - -17 Mar 2011, PHP 5.3.6 -- Upgraded bundled Sqlite3 to version 3.7.4. (Ilia) -- Upgraded bundled PCRE to version 8.11. (Ilia) - -- Zend Engine: - . Indirect reference to $this fails to resolve if direct $this is never used - in method. (Scott) - . Added options to debug backtrace functions. (Stas) - . Fixed bug numerous crashes due to setlocale (crash on error, pcre, mysql - etc.) on Windows in thread safe mode. (Pierre) - . Fixed Bug #53971 (isset() and empty() produce apparently spurious runtime - error). (Dmitry) - . Fixed Bug #53958 (Closures can't 'use' shared variables by value and by - reference). (Dmitry) - . Fixed Bug #53629 (memory leak inside highlight_string()). (Hannes, Ilia) - . Fixed Bug #51458 (Lack of error context with nested exceptions). (Stas) - . Fixed Bug #47143 (Throwing an exception in a destructor causes a fatal - error). (Stas) - . Fixed bug #43512 (same parameter name can be used multiple times in - method/function definition). (Felipe) - -- Core: - . Added ability to connect to HTTPS sites through proxy with basic - authentication using stream_context/http/header/Proxy-Authorization (Dmitry) - . Changed default value of ini directive serialize_precision from 100 to 17. - (Gustavo) - . Fixed bug #54055 (buffer overrun with high values for precision ini - setting). (Gustavo) - . Fixed bug #53959 (reflection data for fgetcsv out-of-date). (Richard) - . Fixed bug #53577 (Regression introduced in 5.3.4 in open_basedir with a - trailing forward slash). (lekensteyn at gmail dot com, Pierre) - . Fixed bug #53682 (Fix compile on the VAX). (Rasmus, jklos) - . Fixed bug #48484 (array_product() always returns 0 for an empty array). - (Ilia) - . Fixed bug #48607 (fwrite() doesn't check reply from ftp server before - exiting). (Ilia) - - -- Calendar extension: - . Fixed bug #53574 (Integer overflow in SdnToJulian, sometimes leading to - segfault). (Gustavo) - -- DOM extension: - . Implemented FR #39771 (Made DOMDocument::saveHTML accept an optional DOMNode - like DOMDocument::saveXML). (Gustavo) - -- DateTime extension: - . Fixed a bug in DateTime->modify() where absolute date/time statements had - no effect. (Derick) - . Fixed bug #53729 (DatePeriod fails to initialize recurrences on 64bit - big-endian systems). (Derick, rein@basefarm.no) - . Fixed bug #52808 (Segfault when specifying interval as two dates). (Stas) - . Fixed bug #52738 (Can't use new properties in class extended from - DateInterval). (Stas) - . Fixed bug #52290 (setDate, setISODate, setTime works wrong when DateTime - created from timestamp). (Stas) - . Fixed bug #52063 (DateTime constructor's second argument doesn't have a - null default value). (Gustavo, Stas) - -- Exif extension: - . Fixed bug #54002 (crash on crafted tag, reported by Luca Carettoni). - (Pierre) (CVE-2011-0708) - -- Filter extension: - . Fixed bug #53924 (FILTER_VALIDATE_URL doesn't validate port number). - (Ilia, Gustavo) - . Fixed bug #53150 (FILTER_FLAG_NO_RES_RANGE is missing some IP ranges). - (Ilia) - . Fixed bug #52209 (INPUT_ENV returns NULL for set variables (CLI)). (Ilia) - . Fixed bug #47435 (FILTER_FLAG_NO_RES_RANGE don't work with ipv6). - (Ilia, valli at icsurselva dot ch) - -- Fileinfo extension: - . Fixed bug #54016 (finfo_file() Cannot determine filetype in archives). - (Hannes) - -- Gettext - . Fixed bug #53837 (_() crashes on Windows when no LANG or LANGUAGE - environment variable are set). (Pierre) - -- IMAP extension: - . Implemented FR #53812 (get MIME headers of the part of the email). (Stas) - . Fixed bug #53377 (imap_mime_header_decode() doesn't ignore \t during long - MIME header unfolding). (Adam) - -- Intl extension: - . Fixed bug #53612 (Segmentation fault when using cloned several intl - objects). (Gustavo) - . Fixed bug #53512 (NumberFormatter::setSymbol crash on bogus $attr values). - (Felipe) - . Implemented clone functionality for number, date & message formatters. - (Stas). - -- JSON extension: - . Fixed bug #53963 (Ensure error_code is always set during some failed - decodings). (Scott) - -- mysqlnd - . Fixed problem with always returning 0 as num_rows for unbuffered sets. - (Andrey, Ulf) - -- MySQL Improved extension: - . Added 'db' and 'catalog' keys to the field fetching functions (FR #39847). - (Kalle) - . Fixed buggy counting of affected rows when using the text protocol. The - collected statistics were wrong when multi_query was used with mysqlnd - (Andrey) - . Fixed bug #53795 (Connect Error from MySqli (mysqlnd) when using SSL). - (Kalle) - . Fixed bug #53503 (mysqli::query returns false after successful LOAD DATA - query). (Kalle, Andrey) - . Fixed bug #53425 (mysqli_real_connect() ignores client flags when built to - call libmysql). (Kalle, tre-php-net at crushedhat dot com) - -- OpenSSL extension: - . Fixed stream_socket_enable_crypto() not honoring the socket timeout in - server mode. (Gustavo) - . Fixed bug #54060 (Memory leaks when openssl_encrypt). (Pierre) - . Fixed bug #54061 (Memory leaks when openssl_decrypt). (Pierre) - . Fixed bug #53592 (stream_socket_enable_crypto() busy-waits in client mode). - (Gustavo) - . Implemented FR #53447 (Cannot disable SessionTicket extension for servers - that do not support it) by adding a no_ticket SSL context option. (Adam, - Tony) - -- PDO MySQL driver: - . Fixed bug #53551 (PDOStatement execute segfaults for pdo_mysql driver). - (Johannes) - . Implemented FR #47802 (Support for setting character sets in DSN strings). - (Kalle) - -- PDO Oracle driver: - . Fixed bug #39199 (Cannot load Lob data with more than 4000 bytes on - ORACLE 10). (spatar at mail dot nnov dot ru) - -- PDO PostgreSQL driver: - . Fixed bug #53517 (segfault in pgsql_stmt_execute() when postgres is down). - (gyp at balabit dot hu) - -- Phar extension: - . Fixed bug #54247 (format-string vulnerability on Phar). (Felipe) - (CVE-2011-1153) - . Fixed bug #53541 (format string bug in ext/phar). - (crrodriguez at opensuse dot org, Ilia) - . Fixed bug #53898 (PHAR reports invalid error message, when the directory - does not exist). (Ilia) - -- PHP-FPM SAPI: - . Enforce security in the fastcgi protocol parsing. - (ef-lists at email dotde) - . Fixed bug #53777 (php-fpm log format now match php_error log format). (fat) - . Fixed bug #53527 (php-fpm --test doesn't set a valuable return value). (fat) - . Fixed bug #53434 (php-fpm slowlog now also logs the original request). (fat) - -- Readline extension: - . Fixed bug #53630 (Fixed parameter handling inside readline() function). - (jo at feuersee dot de, Ilia) - -- Reflection extension: - . Fixed bug #53915 (ReflectionClass::getConstant(s) emits fatal error on - constants with self::). (Gustavo) - -- Shmop extension: - . Fixed bug #54193 (Integer overflow in shmop_read()). (Felipe) - Reported by Jose Carlos Norte (CVE-2011-1092) - -- SNMP extension: - . Fixed bug #51336 (snmprealwalk (snmp v1) does not handle end of OID tree - correctly). (Boris Lytochkin) - -- SOAP extension: - . Fixed possible crash introduced by the NULL poisoning patch. - (Mateusz Kocielski, Pierre) - -- SPL extension: - . Fixed memory leak in DirectoryIterator::getExtension() and - SplFileInfo::getExtension(). (Felipe) - . Fixed bug #53914 (SPL assumes HAVE_GLOB is defined). (Chris Jones) - . Fixed bug #53515 (property_exists incorrect on ArrayObject null and 0 - values). (Felipe) - . Fixed bug #49608 (Using CachingIterator on DirectoryIterator instance - segfaults). (Felipe) - - . Added SplFileInfo::getExtension(). FR #48767. (Peter Cowburn) - -- SQLite3 extension: - . Fixed memory leaked introduced by the NULL poisoning patch. - (Mateusz Kocielski, Pierre) - . Fixed memory leak on SQLite3Result and SQLite3Stmt when assigning to a - reference. (Felipe) - . Add SQlite3_Stmt::readonly() for checking if a statement is read only. - (Scott) - . Implemented FR #53466 (SQLite3Result::columnType() should return false after - all of the rows have been fetched). (Scott) - -- Streams: - . Fixed bug #54092 (Segmentation fault when using HTTP proxy with the FTP - wrapper). (Gustavo) - . Fixed bug #53913 (Streams functions assume HAVE_GLOB is defined). (Chris - Jones) - . Fixed bug #53903 (userspace stream stat callback does not separate the - elements of the returned array before converting them). (Gustavo) - . Implemented FR #26158 (open arbitrary file descriptor with fopen). (Gustavo) - -- Tokenizer Extension - . Fixed bug #54089 (token_get_all() does not stop after __halt_compiler). - (Nikita Popov, Ilia) - -- XSL extension: - . Fixed memory leaked introduced by the NULL poisoning patch. - (Mateusz Kocielski, Pierre) - -- Zip extension: - . Added the filename into the return value of stream_get_meta_data(). (Hannes) - . Fixed bug #53923 (Zip functions assume HAVE_GLOB is defined). (Adam) - . Fixed bug #53893 (Wrong return value for ZipArchive::extractTo()). (Pierre) - . Fixed bug #53885 (ZipArchive segfault with FL_UNCHANGED on empty archive). - (Stas, Maksymilian Arciemowicz). (CVE-2011-0421) - . Fixed bug #53854 (Missing constants for compression type). (Richard, Adam) - . Fixed bug #53603 (ZipArchive should quiet stat errors). (brad dot froehle at - gmail dot com, Gustavo) - . Fixed bug #53579 (stream_get_contents() segfaults on ziparchive streams). - (Hannes) - . Fixed bug #53568 (swapped memset arguments in struct initialization). - (crrodriguez at opensuse dot org) - . Fixed bug #53166 (Missing parameters in docs and reflection definition). - (Richard) - . Fixed bug #49072 (feof never returns true for damaged file in zip). - (Gustavo, Richard Quadling) - -06 Jan 2011, PHP 5.3.5 -- Fixed Bug #53632 (infinite loop with x87 fpu). (CVE-2010-4645) (Scott, - Rasmus) - -09 Dec 2010, PHP 5.3.4 -- Upgraded bundled Sqlite3 to version 3.7.3. (Ilia) -- Upgraded bundled PCRE to version 8.10. (Ilia) - -- Security enhancements: - . Fixed crash in zip extract method (possible CWE-170). - (Maksymilian Arciemowicz, Pierre) - . Paths with NULL in them (foo\0bar.txt) are now considered as invalid. - (Rasmus) - . Fixed a possible double free in imap extension (Identified by Mateusz - Kocielski). (CVE-2010-4150). (Ilia) - . Fixed NULL pointer dereference in ZipArchive::getArchiveComment. - (CVE-2010-3709). (Maksymilian Arciemowicz) - . Fixed possible flaw in open_basedir (CVE-2010-3436). (Pierre) - . Fixed MOPS-2010-24, fix string validation. (CVE-2010-2950). (Pierre) - . Fixed symbolic resolution support when the target is a DFS share. (Pierre) - . Fixed bug #52929 (Segfault in filter_var with FILTER_VALIDATE_EMAIL with - large amount of data) (CVE-2010-3710). (Adam) - -- General improvements: - . Added stat support for zip stream. (Pierre) - . Added follow_location (enabled by default) option for the http stream - support. (Pierre) - . Improved support for is_link and related functions on Windows. (Pierre) - . Added a 3rd parameter to get_html_translation_table. It now takes a charset - hint, like htmlentities et al. (Gustavo) - -- Implemented feature requests: - . Implemented FR #52348, added new constant ZEND_MULTIBYTE to detect - zend multibyte at runtime. (Kalle) - . Implemented FR #52173, added functions pcntl_get_last_error() and - pcntl_strerror(). (nick dot telford at gmail dot com, Arnaud) - . Implemented symbolic links support for open_basedir checks. (Pierre) - . Implemented FR #51804, SplFileInfo::getLinkTarget on Windows. (Pierre) - . Implemented FR #50692, not uploaded files don't count towards - max_file_uploads limit. As a side improvement, temporary files are not - opened for empty uploads and, in debug mode, 0-length uploads. (Gustavo) - -- Improved MySQLnd: - . Added new character sets to mysqlnd, which are available in MySQL 5.5 - (Andrey) - -- Improved PHP-FPM SAPI: - . Added '-p/--prefix' to php-fpm to use a custom prefix and run multiple - instances. (fat) - . Added custom process title for FPM. (fat) - . Added '-t/--test' to php-fpm to check and validate FPM conf file. (fat) - . Added statistics about listening socket queue length for FPM. - (andrei dot nigmatulin at gmail dot com, fat) - -- Core: - . Fixed extract() to do not overwrite $GLOBALS and $this when using - EXTR_OVERWRITE. (jorto at redhat dot com) - . Fixed bug in the Windows implementation of dns_get_record, where the two - last parameters wouldn't be filled unless the type were DNS_ANY (Gustavo). - . Changed the $context parameter on copy() to actually have an effect. (Kalle) - . Fixed htmlentities/htmlspecialchars accepting certain ill-formed UTF-8 - sequences. (Gustavo) - . Fixed bug #53409 (sleep() returns NULL on Windows). (Pierre) - . Fixed bug #53319 (strip_tags() may strip '
' incorrectly). (Felipe) - . Fixed bug #53304 (quot_print_decode does not handle lower-case hex digits). - (Ilia, daniel dot mueller at inexio dot net) - . Fixed bug #53248 (rawurlencode RFC 3986 EBCDIC support misses tilde char). - (Justin Martin) - . Fixed bug #53226 (file_exists fails on big filenames). (Adam) - . Fixed bug #53198 (changing INI setting "from" with ini_set did not have any - effect). (Gustavo) - . Fixed bug #53180 (post_max_size=0 not disabling the limit when the content - type is application/x-www-form-urlencoded or is not registered with PHP). - (gm at tlink dot de, Gustavo) - . Fixed bug #53141 (autoload misbehaves if called from closing session). - (ladislav at marek dot su) - . Fixed bug #53021 (In html_entity_decode, failure to convert numeric entities - with ENT_NOQUOTES and ISO-8859-1). Fixed and extended the fix of - ENT_NOQUOTES in html_entity_decode that had introduced the bug (rev - #185591) to other encodings. Additionaly, html_entity_decode() now doesn't - decode " if ENT_NOQUOTES is given. (Gustavo) - . Fixed bug #52931 (strripos not overloaded with function overloading - enabled). (Felipe) - . Fixed bug #52772 (var_dump() doesn't check for the existence of - get_class_name before calling it). (Kalle, Gustavo) - . Fixed bug #52534 (var_export array with negative key). (Felipe) - . Fixed bug #52327 (base64_decode() improper handling of leading padding in - strict mode). (Ilia) - . Fixed bug #52260 (dns_get_record fails with non-existing domain on Windows). - (a_jelly_doughnut at phpbb dot com, Pierre) - . Fixed bug #50953 (socket will not connect to IPv4 address when the host has - both IPv4 and IPv6 addresses, on Windows). (Gustavo, Pierre) - . Fixed bug #50524 (proc_open on Windows does not respect cwd as it does on - other platforms). (Pierre) - . Fixed bug #49687 (utf8_decode vulnerabilities and deficiencies in the number - of reported malformed sequences). (CVE-2010-3870) (Gustavo) - . Fixed bug #49407 (get_html_translation_table doesn't handle UTF-8). - (Gustavo) - . Fixed bug #48831 (php -i has different output to php --ini). (Richard, - Pierre) - . Fixed bug #47643 (array_diff() takes over 3000 times longer than php 5.2.4). - (Felipe) - . Fixed bug #47168 (printf of floating point variable prints maximum of 40 - decimal places). (Ilia) - . Fixed bug #46587 (mt_rand() does not check that max is greater than min). - (Ilia) - . Fixed bug #29085 (bad default include_path on Windows). (Pierre) - . Fixed bug #25927 (get_html_translation_table calls the ' ' instead of - '). (Gustavo) - -- Zend engine: - . Reverted fix for bug #51176 (Static calling in non-static method behaves - like $this->). (Felipe) - . Changed deprecated ini options on startup from E_WARNING to E_DEPRECATED. - (Kalle) - . Fixed NULL dereference in lex_scan on zend multibyte builds where the script - had a flex incompatible encoding and there was no converter. (Gustavo) - . Fixed covariance of return-by-ref constraints. (Etienne) - . Fixed bug #53305 (E_NOTICE when defining a constant starts with - __COMPILER_HALT_OFFSET__). (Felipe) - . Fixed bug #52939 (zend_call_function does not respect ZEND_SEND_PREFER_REF). - (Dmitry) - . Fixed bug #52879 (Objects unreferenced in __get, __set, __isset or __unset - can be freed too early). (mail_ben_schmidt at yahoo dot com dot au, Dmitry) - . Fixed bug #52786 (PHP should reset section to [PHP] after ini sections). - (Fedora at famillecollet dot com) - . Fixed bug #52508 (newline problem with parse_ini_file+INI_SCANNER_RAW). - (Felipe) - . Fixed bug #52484 (__set() ignores setting properties with empty names). - (Felipe) - . Fixed bug #52361 (Throwing an exception in a destructor causes invalid - catching). (Dmitry) - . Fixed bug #51008 (Zend/tests/bug45877.phpt fails). (Dmitry) - -- Build issues: - . Fixed bug #52436 (Compile error if systems do not have stdint.h) - (Sriram Natarajan) - . Fixed bug #50345 (nanosleep not detected properly on some solaris versions). - (Ulf, Tony) - . Fixed bug #49215 (make fails on glob_wrapper). (Felipe) - -- Calendar extension: - . Fixed bug #52744 (cal_days_in_month incorrect for December 1 BCE). - (gpap at internet dot gr, Adam) - -- cURL extension: - . Fixed bug #52828 (curl_setopt does not accept persistent streams). - (Gustavo, Ilia) - . Fixed bug #52827 (cURL leaks handle and causes assertion error - (CURLOPT_STDERR)). (Gustavo) - . Fixed bug #52202 (CURLOPT_PRIVATE gets corrupted). (Ilia) - . Fixed bug #50410 (curl extension slows down PHP on Windows). (Pierre) - -- DateTime extension: - . Fixed bug #53297 (gettimeofday implementation in php/win32/time.c can return - 1 million microsecs). (ped at 7gods dot org) - . Fixed bug #52668 (Iterating over a dateperiod twice is broken). (Derick) - . Fixed bug #52454 (Relative dates and getTimestamp increments by one day). - (Derick) - . Fixed bug #52430 (date_parse parse 24:xx:xx as valid time). (Derick) - . Added support for the ( and ) delimiters/separators to - DateTime::createFromFormat(). (Derick) - -- DBA extension: - . Added Berkeley DB 5.1 support to the DBA extension. (Oracle Corp.) - -- DOM extension: - . Fixed bug #52656 (DOMCdataSection does not work with splitText). (Ilia) - -- Filter extension: - . Fixed the filter extension accepting IPv4 octets with a leading 0 as that - belongs to the unsupported "dotted octal" representation. (Gustavo) - . Fixed bug #53236 (problems in the validation of IPv6 addresses with leading - and trailing :: in the filter extension). (Gustavo) - . Fixed bug #50117 (problems in the validation of IPv6 addresses with IPv4 - addresses and ::). (Gustavo) - -- GD extension: - . Fixed bug #53492 (fix crash if anti-aliasing steps are invalid). (Pierre) - -- GMP extension: - . Fixed bug #52906 (gmp_mod returns negative result when non-negative is - expected). (Stas) - . Fixed bug #52849 (GNU MP invalid version match). (Adam) - -- Hash extension: - . Fixed bug #51003 (unaligned memory access in ext/hash/hash_tiger.c). - (Mike, Ilia) - -- Iconv extension: - . Fixed bug #52941 (The 'iconv_mime_decode_headers' function is skipping - headers). (Adam) - . Fixed bug #52599 (iconv output handler outputs incorrect content type - when flags are used). (Ilia) - . Fixed bug #51250 (iconv_mime_decode() does not ignore malformed Q-encoded - words). (Ilia) - -- Intl extension: - . Fixed crashes on invalid parameters in intl extension. (CVE-2010-4409). - (Stas, Maksymilian Arciemowicz) - . Added support for formatting the timestamp stored in a DateTime object. - (Stas) - . Fixed bug #50590 (IntlDateFormatter::parse result is limited to the integer - range). (Stas) - -- Mbstring extension: - . Fixed bug #53273 (mb_strcut() returns garbage with the excessive length - parameter). (CVE-2010-4156) (Mateusz Kocielski, Pierre, Moriyoshi) - . Fixed bug #52981 (Unicode casing table was out-of-date. Updated with - UnicodeData-6.0.0d7.txt and included the source of the generator program - with the distribution) (Gustavo). - . Fixed bug #52681 (mb_send_mail() appends an extra MIME-Version header). - (Adam) - -- MSSQL extension: - . Fixed possible crash in mssql_fetch_batch(). (Kalle) - . Fixed bug #52843 (Segfault when optional parameters are not passed in to - mssql_connect). (Felipe) - -- MySQL extension: - . Fixed bug #52636 (php_mysql_fetch_hash writes long value into int). - (Kalle, rein at basefarm dot no) - -- MySQLi extension: - . Fixed bug #52891 (Wrong data inserted with mysqli/mysqlnd when using - mysqli_stmt_bind_param and value> PHP_INT_MAX). (Andrey) - . Fixed bug #52686 (mysql_stmt_attr_[gs]et argument points to incorrect type). - (rein at basefarm dot no) - . Fixed bug #52654 (mysqli doesn't install headers with structures it uses). - (Andrey) - . Fixed bug #52433 (Call to undefined method mysqli::poll() - must be static). - (Andrey) - . Fixed bug #52417 (MySQLi build failure with mysqlnd on MacOS X). (Andrey) - . Fixed bug #52413 (MySQLi/libmysql build failure on OS X, FreeBSD). (Andrey) - . Fixed bug #52390 (mysqli_report() should be per-request setting). (Kalle) - . Fixed bug #52302 (mysqli_fetch_all does not work with MYSQLI_USE_RESULT). - (Andrey) - . Fixed bug #52221 (Misbehaviour of magic_quotes_runtime (get/set)). (Andrey) - . Fixed bug #45921 (Can't initialize character set hebrew). (Andrey) - -- MySQLnd: - . Fixed bug #52613 (crash in mysqlnd after hitting memory limit). (Andrey) - -- ODBC extension: - - Fixed bug #52512 (Broken error handling in odbc_execute). - (mkoegler at auto dot tuwien dot ac dot at) - -- Openssl extension: - . Fixed possible blocking behavior in openssl_random_pseudo_bytes on Windows. - (Pierre) - . Fixed bug #53136 (Invalid read on openssl_csr_new()). (Felipe) - . Fixed bug #52947 (segfault when ssl stream option capture_peer_cert_chain - used). (Felipe) - -- Oracle Database extension (OCI8): - . Fixed bug #53284 (Valgrind warnings in oci_set_* functions) (Oracle Corp.) - . Fixed bug #51610 (Using oci_connect causes PHP to take a long time to - exit). Requires Oracle 11.2.0.2 client libraries (or Oracle bug fix - 9891199) for this patch to have an effect. (Oracle Corp.) - -- PCNTL extension: - . Fixed bug #52784 (Race condition when handling many concurrent signals). - (nick dot telford at gmail dot com, Arnaud) - -- PCRE extension: - . Fixed bug #52971 (PCRE-Meta-Characters not working with utf-8). (Felipe) - . Fixed bug #52732 (Docs say preg_match() returns FALSE on error, but it - returns int(0)). (slugonamission at gmail dot com) - -- PHAR extension: - . Fixed bug #50987 (unaligned memory access in phar.c). - (geissert at debian dot org, Ilia) - -- PHP-FPM SAPI: - . Fixed bug #53412 (segfault when using -y). (fat) - . Fixed inconsistent backlog default value (-1) in FPM on many systems. (fat) - . Fixed bug #52501 (libevent made FPM crashed when forking -- libevent has - been removed). (fat) - . Fixed bug #52725 (gcc builtin atomic functions were sometimes used when they - were not available). (fat) - . Fixed bug #52693 (configuration file errors are not logged to stderr). (fat) - . Fixed bug #52674 (FPM Status page returns inconsistent Content-Type - headers). (fat) - . Fixed bug #52498 (libevent was not only linked to php-fpm). (fat) - -- PDO: - . Fixed bug #52699 (PDO bindValue writes long int 32bit enum). - (rein at basefarm dot no) - . Fixed bug #52487 (PDO::FETCH_INTO leaks memory). (Felipe) - -- PDO DBLib driver: - . Fixed bug #52546 (pdo_dblib segmentation fault when iterating MONEY values). - (Felipe) - -- PDO Firebird driver: - . Restored firebird support (VC9 builds only). (Pierre) - . Fixed bug #53335 (pdo_firebird did not implement rowCount()). - (preeves at ibphoenix dot com) - . Fixed bug #53323 (pdo_firebird getAttribute() crash). - (preeves at ibphoenix dot com) - -- PDO MySQL driver: - . Fixed bug #52745 (Binding params doesn't work when selecting a date inside a - CASE-WHEN). (Andrey) - -- PostgreSQL extension: - . Fixed bug #47199 (pg_delete() fails on NULL). (ewgraf at gmail dot com) - -- Reflection extension: - . Fixed ReflectionProperty::isDefault() giving a wrong result for properties - obtained with ReflectionClass::getProperties(). (Gustavo) -- Reflection extension: - . Fixed bug #53366 (Reflection doesnt get dynamic property value from - getProperty()). (Felipe) - . Fixed bug #52854 (ReflectionClass::newInstanceArgs does not work for classes - without constructors). (Johannes) - -- SOAP extension: - . Fixed bug #44248 (RFC2616 transgression while HTTPS request through proxy - with SoapClient object). (Dmitry) - -- SPL extension: - . Fixed bug #53362 (Segmentation fault when extending SplFixedArray). (Felipe) - . Fixed bug #53279 (SplFileObject doesn't initialise default CSV escape - character). (Adam) - . Fixed bug #53144 (Segfault in SplObjectStorage::removeAll()). (Felipe) - . Fixed bug #53071 (SPLObjectStorage defeats gc_collect_cycles). (Gustavo) - . Fixed bug #52573 (SplFileObject::fscanf Segmentation fault). (Felipe) - . Fixed bug #51763 (SplFileInfo::getType() does not work symbolic link - and directory). (Pierre) - . Fixed bug #50481 (Storing many SPLFixedArray in an array crashes). (Felipe) - . Fixed bug #50579 (RegexIterator::REPLACE doesn't work). (Felipe) - -- SQLite3 extension: - . Fixed bug #53463 (sqlite3 columnName() segfaults on bad column_number). - (Felipe) - -- Streams: - . Fixed forward stream seeking emulation in streams that don't support seeking - in situations where the read operation gives back less data than requested - and when there was data in the buffer before the emulation started. Also - made more consistent its behavior -- should return failure every time less - data than was requested was skipped. (Gustavo) - . Fixed bug #53241 (stream casting that relies on fdopen/fopencookie fails - with streams opened with, inter alia, the 'xb' mode). (Gustavo) - . Fixed bug #53006 (stream_get_contents has an unpredictable behavior when the - underlying stream does not support seeking). (Gustavo) - . Fixed bug #52944 (Invalid write on second and subsequent reads with an - inflate filter fed invalid data). (Gustavo) - . Fixed bug #52820 (writes to fopencookie FILE* not commited when seeking the - stream). (Gustavo) - -- WDDX extension: - . Fixed bug #52468 (wddx_deserialize corrupts integer field value when left - empty). (Felipe) - -- Zlib extension: - . Fixed bug #52926 (zlib fopen wrapper does not use context). (Gustavo) - -22 Jul 2010, PHP 5.3.3 -- Upgraded bundled sqlite to version 3.6.23.1. (Ilia) -- Upgraded bundled PCRE to version 8.02. (Ilia) - -- Added support for JSON_NUMERIC_CHECK option in json_encode() that converts - numeric strings to integers. (Ilia) -- Added stream_set_read_buffer, allows to set the buffer for read operation. - (Pierre) -- Added stream filter support to mcrypt extension (ported from - mcrypt_filter). (Stas) -- Added full_special_chars filter to ext/filter. (Rasmus) -- Added backlog socket context option for stream_socket_server(). (Mike) -- Added fifth parameter to openssl_encrypt()/openssl_decrypt() - (string $iv) to use non-NULL IV. - Made implicit use of NULL IV a warning. (Sara) -- Added openssl_cipher_iv_length(). (Sara) -- Added FastCGI Process Manager (FPM) SAPI. (Tony) -- Added recent Windows versions to php_uname and fix undefined windows - version support. (Pierre) -- Added Berkeley DB 5 support to the DBA extension. (Johannes, Chris Jones) -- Added support for copy to/from array/file for pdo_pgsql extension. - (Denis Gasparin, Ilia) -- Added inTransaction() method to PDO, with specialized support for Postgres. - (Ilia, Denis Gasparin) - -- Changed namespaced classes so that the ctor can only be named - __construct now. (Stas) -- Reset error state in PDO::beginTransaction() reset error state. (Ilia) - -- Implemented FR#51295 (SQLite3::busyTimeout not existing). (Mark) -- Implemented FR#35638 (Adding udate to imap_fetch_overview results). - (Charles_Duffy at dell dot com ) -- Rewrote var_export() to use smart_str rather than output buffering, prevents - data disclosure if a fatal error occurs (CVE-2010-2531). (Scott) -- Fixed possible buffer overflows in mysqlnd_list_fields, mysqlnd_change_user. - (Andrey) -- Fixed possible buffer overflows when handling error packets in mysqlnd. - Reported by Stefan Esser. (Andrey) -- Fixed very rare memory leak in mysqlnd, when binding thousands of columns. - (Andrey) -- Fixed a crash when calling an inexistent method of a class that inherits - PDOStatement if instantiated directly instead of doing by the PDO methods. - (Felipe) - -- Fixed memory leak on error in mcrypt_create_iv on Windows. (Pierre) -- Fixed a possible crash because of recursive GC invocation. (Dmitry) -- Fixed a possible resource destruction issues in shm_put_var(). - Reported by Stefan Esser. (Dmitry) -- Fixed a possible information leak because of interruption of XOR operator. - Reported by Stefan Esser. (Dmitry) -- Fixed a possible memory corruption because of unexpected call-time pass by - refernce and following memory clobbering through callbacks. - Reported by Stefan Esser. (Dmitry) -- Fixed a possible memory corruption in ArrayObject::uasort(). Reported by - Stefan Esser. (Dmitry) -- Fixed a possible memory corruption in parse_str(). Reported by Stefan Esser. - (Dmitry) -- Fixed a possible memory corruption in pack(). Reported by Stefan Esser. - (Dmitry) -- Fixed a possible memory corruption in substr_replace(). Reported by Stefan - Esser. (Dmitry) -- Fixed a possible memory corruption in addcslashes(). Reported by Stefan - Esser. (Dmitry) -- Fixed a possible stack exhaustion inside fnmatch(). Reported by Stefan - Esser. (Ilia) -- Fixed a possible dechunking filter buffer overflow. Reported by Stefan Esser. - (Pierre) -- Fixed a possible arbitrary memory access inside sqlite extension. Reported - by Mateusz Kocielski. (Ilia) -- Fixed string format validation inside phar extension. Reported by Stefan - Esser. (Ilia) -- Fixed handling of session variable serialization on certain prefix - characters. Reported by Stefan Esser. (Ilia) -- Fixed a NULL pointer dereference when processing invalid XML-RPC - requests (Fixes CVE-2010-0397, bug #51288). (Raphael Geissert) -- Fixed 64-bit integer overflow in mhash_keygen_s2k(). (Clément LECIGNE, Stas) -- Fixed SplObjectStorage unserialization problems (CVE-2010-2225). (Stas) -- Fixed the mail.log ini setting when no filename was given. (Johannes) - -- Fixed bug #52317 (Segmentation fault when using mail() on a rhel 4.x (only 64 - bit)). (Adam) -- Fixed bug #52262 (json_decode() shows no errors on invalid UTF-8). - (Scott) -- Fixed bug #52240 (hash_copy() does not copy the HMAC key, causes wrong - results and PHP crashes). (Felipe) -- Fixed bug #52238 (Crash when an Exception occured in iterator_to_array). - (Johannes) -- Fixed bug #52193 (converting closure to array yields empty array). (Felipe) -- Fixed bug #52183 (Reflectionfunction reports invalid number of arguments for - function aliases). (Felipe) -- Fixed bug #52162 (custom request header variables with numbers are removed). - (Sriram Natarajan) -- Fixed bug #52160 (Invalid E_STRICT redefined constructor error). (Felipe) -- Fixed bug #52138 (Constants are parsed into the ini file for section names). - (Felipe) -- Fixed bug #52115 (mysqli_result::fetch_all returns null, not an empty array). - (Andrey) -- Fixed bug #52101 (dns_get_record() garbage in 'ipv6' field on Windows). - (Pierre) -- Fixed bug #52082 (character_set_client & character_set_connection reset after - mysqli_change_user()). (Andrey) -- Fixed bug #52043 (GD doesn't recognize latest libJPEG versions). - (php at group dot apple dot com, Pierre) -- Fixed bug #52041 (Memory leak when writing on uninitialized variable returned - from function). (Dmitry) -- Fixed bug #52060 (Memory leak when passing a closure to method_exists()). - (Felipe) -- Fixed bug #52057 (ReflectionClass fails on Closure class). (Felipe) -- Fixed bug #52051 (handling of case sensitivity of old-style constructors - changed in 5.3+). (Felipe) -- Fixed bug #52037 (Concurrent builds fail in install-programs). (seanius at - debian dot org, Kalle) -- Fixed bug #52019 (make lcov doesn't support TESTS variable anymore). (Patrick) -- Fixed bug #52010 (open_basedir restrictions mismatch on vacuum command). - (Ilia) -- Fixed bug #52001 (Memory allocation problems after using variable variables). - (Dmitry) -- Fixed bug #51991 (spl_autoload and *nix support with namespace). (Felipe) -- Fixed bug #51943 (AIX: Several files are out of ANSI spec). (Kalle, - coreystup at gmail dot com) -- Fixed bug #51911 (ReflectionParameter::getDefaultValue() memory leaks with - constant array). (Felipe) -- Fixed bug #51905 (ReflectionParameter fails if default value is an array - with an access to self::). (Felipe) -- Fixed bug #51899 (Parse error in parse_ini_file() function when empy value - followed by no newline). (Felipe) -- Fixed bug #51844 (checkdnsrr does not support types other than MX). (Pierre) -- Fixed bug #51827 (Bad warning when register_shutdown_function called with - wrong num of parameters). (Felipe) -- Fixed bug #51822 (Segfault with strange __destruct() for static class - variables). (Dmitry) -- Fixed bug #51791 (constant() aborts execution when fail to check undefined - constant). (Felipe) -- Fixed bug #51732 (Fileinfo __construct or open does not work with NULL). - (Pierre) -- Fixed bug #51725 (xmlrpc_get_type() returns true on invalid dates). (Mike) -- Fixed bug #51723 (Content-length header is limited to 32bit integer with - Apache2 on Windows). (Pierre) -- Fixed bug #51721 (mark DOMNodeList and DOMNamedNodeMap as Traversable). - (David Zuelke) -- Fixed bug #51712 (Test mysql_mysqlnd_read_timeout_long must fail on MySQL4). - (Andrey) -- Fixed bug #51697 (Unsafe operations in free_storage of SPL iterators, - causes crash during shutdown). (Etienne) -- Fixed bug #51690 (Phar::setStub looks for case-sensitive - __HALT_COMPILER()). (Ilia) -- Fixed bug #51688 (ini per dir crashes when invalid document root are given). - (Pierre) -- Fixed bug #51671 (imagefill does not work correctly for small images). - (Pierre) -- Fixed bug #51670 (getColumnMeta causes segfault when re-executing query - after calling nextRowset). (Pierrick) -- Fixed bug #51647 Certificate file without private key (pk in another file) - doesn't work. (Andrey) -- Fixed bug #51629 (CURLOPT_FOLLOWLOCATION error message is misleading). - (Pierre) -- Fixed bug #51627 (script path not correctly evaluated). - (russell dot tempero at rightnow dot com) -- Fixed bug #51624 (Crash when calling mysqli_options()). (Felipe) -- Fixed bug #51615 (PHP crash with wrong HTML in SimpleXML). (Felipe) -- Fixed bug #51609 (pg_copy_to: Invalid results when using fourth parameter). - (Felipe) -- Fixed bug #51608 (pg_copy_to: WARNING: nonstandard use of \\ in a string - literal). (cbandy at jbandy dot com) -- Fixed bug #51607 (pg_copy_from does not allow schema in the tablename - argument). (cbandy at jbandy dot com) -- Fixed bug #51605 (Mysqli - zombie links). (Andrey) -- Fixed bug #51604 (newline in end of header is shown in start of message). - (Daniel Egeberg) -- Fixed bug #51590 (JSON_ERROR_UTF8 is undefined). (Felipe) -- Fixed bug #51583 (Bus error due to wrong alignment in mysqlnd). (Rainer Jung) -- Fixed bug #51582 (Don't assume UINT64_C it's ever available). - (reidrac at usebox dot net, Pierre) -- Fixed bug #51577 (Uninitialized memory reference with oci_bind_array_by_name) - (Oracle Corp.) -- Fixed bug #51562 (query timeout in mssql can not be changed per query). - (ejsmont dot artur at gmail dot com) -- Fixed bug #51552 (debug_backtrace() causes segmentation fault and/or memory - issues). (Dmitry) -- Fixed bug #51445 (var_dump() invalid/slow *RECURSION* detection). (Felipe) -- Fixed bug #51435 (Missing ifdefs / logic bug in crypt code cause compile - errors). (Felipe) -- Fixed bug #51424 (crypt() function hangs after 3rd call). (Pierre, Sriram) -- Fixed bug #51394 (Error line reported incorrectly if error handler throws an - exception). (Stas) -- Fixed bug #51393 (DateTime::createFromFormat() fails if format string contains - timezone). (Adam) -- Fixed bug #51347 (mysqli_close / connection memory leak). (Andrey, Johannes) -- Fixed bug #51338 (URL-Rewriter is still enabled if use_only_cookies is - on). (Ilia, j dot jeising at gmail dot com) -- Fixed bug #51291 (oci_error doesn't report last error when called two times) - (Oracle Corp.) -- Fixed bug #51276 (php_load_extension() is missing when HAVE_LIBDL is - undefined). (Tony) -- Fixed bug #51273 (Faultstring property does not exist when the faultstring is - empty) (Ilia, dennis at transip dot nl) -- Fixed bug #51269 (zlib.output_compression Overwrites Vary Header). (Adam) -- Fixed bug #51257 (CURL_VERSION_LARGEFILE incorrectly used after libcurl - version 7.10.1). (aron dot ujvari at microsec dot hu) -- Fixed bug #51242 (Empty mysql.default_port does not default to 3306 anymore, - but 0). (Adam) -- Fixed bug #51237 (milter SAPI crash on startup). (igmar at palsenberg dot com) -- Fixed bug #51213 (pdo_mssql is trimming value of the money column). (Ilia, - alexr at oplot dot com) -- Fixed bug #51190 (ftp_put() returns false when transfer was successful). - (Ilia) -- Fixed bug #51183 (ext/date/php_date.c fails to compile with Sun Studio). - (Sriram Natarajan) -- Fixed bug #51176 (Static calling in non-static method behaves like $this->). - (Felipe) -- Fixed bug #51171 (curl_setopt() doesn't output any errors or warnings when - an invalid option is provided). (Ilia) -- Fixed bug #51128 (imagefill() doesn't work with large images). (Pierre) -- Fixed bug #51096 ('last day' and 'first day' are handled incorrectly when - parsing date strings). (Derick) -- Fixed bug #51086 (DBA DB4 doesn't work with Berkeley DB 4.8). (Chris Jones) -- Fixed bug #51062 (DBA DB4 uses mismatched headers and libraries). (Chris - Jones) -- Fixed bug #51026 (mysqli_ssl_set not working). (Andrey) -- Fixed bug #51023 (filter doesn't detect int overflows with GCC 4.4). - (Raphael Geissert) -- Fixed bug #50999 (unaligned memory access in dba_fetch()). (Felipe) -- Fixed bug #50976 (Soap headers Authorization not allowed). - (Brain France, Dmitry) -- Fixed bug #50828 (DOMNotation is not subclass of DOMNode). (Rob) -- Fixed bug #50810 (property_exists does not work for private). (Felipe) -- Fixed bug #50762 (in WSDL mode Soap Header handler function only being called - if defined in WSDL). (mephius at gmail dot com) -- Fixed bug #50731 (Inconsistent namespaces sent to functions registered with - spl_autoload_register). (Felipe) -- Fixed bug #50563 (removing E_WARNING from parse_url). (ralph at smashlabs dot - com, Pierre) -- Fixed bug #50578 (incorrect shebang in phar.phar). (Fedora at FamilleCollet - dot com) -- Fixed bug #50392 (date_create_from_format enforces 6 digits for 'u' format - character). (Derick) -- Fixed bug #50383 (Exceptions thrown in __call / __callStatic do not include - file and line in trace). (Felipe) -- Fixed bug #50358 (Compile failure compiling ext/phar/util.lo). (Felipe) -- Fixed bug #50101 (name clash between global and local variable). - (patch by yoarvi at gmail dot com) -- Fixed bug #50055 (DateTime::sub() allows 'relative' time modifications). - (Derick) -- Fixed bug #51002 (fix possible memory corruption with very long names). - (Pierre) -- Fixed bug #49893 (Crash while creating an instance of Zend_Mail_Storage_Pop3). - (Dmitry) -- Fixed bug #49819 (STDOUT losing data with posix_isatty()). (Mike) -- Fixed bug #49778 (DateInterval::format("%a") is always zero when an interval - is created from an ISO string). (Derick) -- Fixed bug #49700 (memory leaks in php_date.c if garbage collector is - enabled). (Dmitry) -- Fixed bug #49576 (FILTER_VALIDATE_EMAIL filter needs updating) (Rasmus) -- Fixed bug #49490 (XPath namespace prefix conflict). (Rob) -- Fixed bug #49429 (odbc_autocommit doesn't work). (Felipe) -- Fixed bug #49320 (PDO returns null when SQLite connection fails). (Felipe) -- Fixed bug #49234 (mysqli_ssl_set not found). (Andrey) -- Fixed bug #49216 (Reflection doesn't seem to work properly on MySqli). - (Andrey) -- Fixed bug #49192 (PHP crashes when GC invoked on COM object). (Stas) -- Fixed bug #49081 (DateTime::diff() mistake if start in January and interval > - 28 days). (Derick) -- Fixed bug #49059 (DateTime::diff() repeats previous sub() operation). - (yoarvi@gmail.com, Derick) -- Fixed bug #48983 (DomDocument : saveHTMLFile wrong charset). (Rob) -- Fixed bug #48930 (__COMPILER_HALT_OFFSET__ incorrect in PHP >= 5.3). (Felipe) -- Fixed bug #48902 (Timezone database fallback map is outdated). (Derick) -- Fixed bug #48781 (Cyclical garbage collector memory leak). (Dmitry) -- Fixed bug #48601 (xpath() returns FALSE for legitimate query). (Rob) -- Fixed bug #48361 (SplFileInfo::getPathInfo should return the - parent dir). (Etienne) -- Fixed bug #48289 (iconv_mime_encode() quoted-printable scheme is broken). - (Adam, patch from hiroaki dot kawai at gmail dot com). -- Fixed bug #47842 (sscanf() does not support 64-bit values). (Mike) -- Fixed bug #46111 (Some timezone identifiers can not be parsed). (Derick) -- Fixed bug #45808 (stream_socket_enable_crypto() blocks and eats CPU). - (vincent at optilian dot com) -- Fixed bug #43233 (sasl support for ldap on Windows). (Pierre) -- Fixed bug #35673 (formatOutput does not work with saveHTML). (Rob) -- Fixed bug #33210 (getimagesize() fails to detect width/height on certain - JPEGs). (Ilia) - -04 Mar 2010, PHP 5.3.2 - -- Upgraded bundled sqlite to version 3.6.22. (Ilia) -- Upgraded bundled libmagic to version 5.03. (Mikko) -- Upgraded bundled PCRE to version 8.00. (Scott) -- Updated timezone database to version 2010.3. (Derick) - -- Improved LCG entropy. (Rasmus, Samy Kamkar) -- Improved crypt support for edge cases (UFC compatibility). (Solar Designer, - Joey, Pierre) - -- Reverted fix for bug #49521 (PDO fetchObject sets values before calling - constructor). (Pierrick, Johannes) - -- Changed gmp_strval() to use full range from 2 to 62, and -2 to -36. FR #50283 - (David Soria Parra) -- Changed "post_max_size" php.ini directive to allow unlimited post size by - setting it to 0. (Rasmus) -- Changed tidyNode class to disallow manual node creation. (Pierrick) - -- Removed automatic file descriptor unlocking happening on shutdown and/or - stream close (on all OSes). (Tony, Ilia) - -- Added libpng 1.4.0 support. (Pierre) -- Added support for DISABLE_AUTHENTICATOR for imap_open. (Pierre) -- Added missing host validation for HTTP urls inside FILTER_VALIDATE_URL. - (Ilia) -- Added stream_resolve_include_path(). (Mikko) -- Added INTERNALDATE support to imap_append. (nick at mailtrust dot com) -- Added support for SHA-256 and SHA-512 to php's crypt. (Pierre) -- Added realpath_cache_size() and realpath_cache_get() functions. (Stas) -- Added FILTER_FLAG_STRIP_BACKTICK option to the filter extension. (Ilia) -- Added protection for $_SESSION from interrupt corruption and improved - "session.save_path" check. (Stas) -- Added LIBXML_PARSEHUGE constant to override the maximum text size of a - single text node when using libxml2.7.3+. (Kalle) -- Added ReflectionMethod::setAccessible() for invoking non-public methods - through the Reflection API. (Sebastian) -- Added Collator::getSortKey for intl extension. (Stas) -- Added support for CURLOPT_POSTREDIR. FR #49571. (Sriram Natarajan) -- Added support for CURLOPT_CERTINFO. FR #49253. - (Linus Nielsen Feltzing ) -- Added client-side server name indication support in openssl. (Arnaud) - -- Improved fix for bug #50006 (Segfault caused by uksort()). (Stas) - -- Fixed mysqlnd hang when queries exactly 16777214 bytes long are sent. (Andrey) -- Fixed incorrect decoding of 5-byte BIT sequences in mysqlnd. (Andrey) -- Fixed error_log() to be binary safe when using message_type 3. (Jani) -- Fixed unnecessary invocation of setitimer when timeouts have been disabled. - (Arvind Srinivasan) -- Fixed memory leak in extension loading when an error occurs on Windows. - (Pierre) -- Fixed safe_mode validation inside tempnam() when the directory path does - not end with a /). (Martin Jansen) -- Fixed a possible open_basedir/safe_mode bypass in session extension - identified by Grzegorz Stachowiak. (Ilia) -- Fixed possible crash when a error/warning is raised during php startup. - (Pierre) -- Fixed possible bad behavior of rename on windows when used with symbolic - links or invalid paths. (Pierre) -- Fixed error output to stderr on Windows. (Pierre) -- Fixed memory leaks in is_writable/readable/etc on Windows. (Pierre) -- Fixed memory leaks in the ACL function on Windows. (Pierre) -- Fixed memory leak in the realpath cache on Windows. (Pierre) -- Fixed memory leak in zip_close. (Pierre) -- Fixed crypt's blowfish sanity check of the "setting" string, to reject - iteration counts encoded as 36 through 39. (Solar Designer, Joey, Pierre) - -- Fixed bug #51059 (crypt crashes when invalid salt are given). (Pierre) -- Fixed bug #50952 (allow underscore _ in constants parsed in php.ini files). - (Jani) -- Fixed bug #50940 (Custom content-length set incorrectly in Apache SAPIs). - (Brian France, Rasmus) -- Fixed bug #50930 (Wrong date by php_date.c patch with ancient gcc/glibc - versions). (Derick) -- Fixed bug #50907 (X-PHP-Originating-Script adding two new lines in *NIX). - (Ilia) -- Fixed bug #50859 (build fails with openssl 1.0 due to md2 deprecation). - (Ilia, hanno at hboeck dot de) -- Fixed bug #50847 (strip_tags() removes all tags greater then 1023 bytes - long). (Ilia) -- Fixed bug #50829 (php.ini directive pdo_mysql.default_socket is ignored). - (Ilia) -- Fixed bug #50832 (HTTP fopen wrapper does not support passwordless HTTP - authentication). (Jani) -- Fixed bug #50787 (stream_set_write_buffer() has no effect on socket streams). - (vnegrier at optilian dot com, Ilia) -- Fixed bug #50761 (system.multiCall crashes in xmlrpc extension). - (hiroaki dot kawai at gmail dot com, Ilia) -- Fixed bug #50756 (CURLOPT_FTP_SKIP_PASV_IP does not exist). (Sriram) -- Fixed bug #50732 (exec() adds single byte twice to $output array). (Ilia) -- Fixed bug #50728 (All PDOExceptions hardcode 'code' property to 0). - (Joey, Ilia) -- Fixed bug #50723 (Bug in garbage collector causes crash). (Dmitry) -- Fixed bug #50690 (putenv does not set ENV when the value is only one char). - (Pierre) -- Fixed bug #50680 (strtotime() does not support eighth ordinal number). (Ilia) -- Fixed bug #50661 (DOMDocument::loadXML does not allow UTF-16). (Rob) -- Fixed bug #50657 (copy() with an empty (zero-byte) HTTP source succeeds but - returns false). (Ilia) -- Fixed bug #50636 (MySQLi_Result sets values before calling constructor). - (Pierrick) -- Fixed bug #50632 (filter_input() does not return default value if the - variable does not exist). (Ilia) -- Fixed bug #50576 (XML_OPTION_SKIP_TAGSTART option has no effect). (Pierrick) -- Fixed bug #50558 (Broken object model when extending tidy). (Pierrick) -- Fixed bug #50540 (Crash while running ldap_next_reference test cases). - (Sriram) -- Fixed bug #50519 (segfault in garbage collection when using set_error_handler - and DomDocument). (Dmitry) -- Fixed bug #50508 (compile failure: Conflicting HEADER type declarations). - (Jani) -- Fixed bug #50496 (Use of is valid only in a c99 compilation - environment. (Sriram) -- Fixed bug #50464 (declare encoding doesn't work within an included file). - (Felipe) -- Fixed bug #50458 (PDO::FETCH_FUNC fails with Closures). (Felipe, Pierrick) -- Fixed bug #50445 (PDO-ODBC stored procedure call from Solaris 64-bit causes - seg fault). (davbrown4 at yahoo dot com, Felipe) -- Fixed bug #50416 (PROCEDURE db.myproc can't return a result set in the given - context). (Andrey) -- Fixed bug #50394 (Reference argument converted to value in __call). (Stas) -- Fixed bug #50351 (performance regression handling objects, ten times slower - in 5.3 than in 5.2). (Dmitry) -- Fixed bug #50392 (date_create_from_format() enforces 6 digits for 'u' - format character). (Ilia) -- Fixed bug #50345 (nanosleep not detected properly on some solaris versions). - (Jani) -- Fixed bug #50340 (php.ini parser does not allow spaces in ini keys). (Jani) -- Fixed bug #50334 (crypt ignores sha512 prefix). (Pierre) -- Fixed bug #50323 (Allow use of ; in values via ;; in PDO DSN). - (Ilia, Pierrick) -- Fixed bug #50285 (xmlrpc does not preserve keys in encoded indexed arrays). - (Felipe) -- Fixed bug #50282 (xmlrpc_encode_request() changes object into array in - calling function). (Felipe) -- Fixed bug #50267 (get_browser(null) does not use HTTP_USER_AGENT). (Jani) -- Fixed bug #50266 (conflicting types for llabs). (Jani) -- Fixed bug #50261 (Crash When Calling Parent Constructor with - call_user_func()). (Dmitry) -- Fixed bug #50255 (isset() and empty() silently casts array to object). - (Felipe) -- Fixed bug #50240 (pdo_mysql.default_socket in php.ini shouldn't used - if it is empty). (foutrelis at gmail dot com, Ilia) -- Fixed bug #50231 (Socket path passed using --with-mysql-sock is ignored when - mysqlnd is enabled). (Jani) -- Fixed bug #50219 (soap call Segmentation fault on a redirected url). - (Pierrick) -- Fixed bug #50212 (crash by ldap_get_option() with LDAP_OPT_NETWORK_TIMEOUT). - (Ilia, shigeru_kitazaki at cybozu dot co dot jp) -- Fixed bug #50209 (Compiling with libedit cannot find readline.h). - (tcallawa at redhat dot com) -- Fixed bug #50207 (segmentation fault when concatenating very large strings on - 64bit linux). (Ilia) -- Fixed bug #50196 (stream_copy_to_stream() produces warning when source is - not file). (Stas) -- Fixed bug #50195 (pg_copy_to() fails when table name contains schema. (Ilia) -- Fixed bug #50185 (ldap_get_entries() return false instead of an empty array - when there is no error). (Jani) -- Fixed bug #50174 (Incorrectly matched docComment). (Felipe) -- Fixed bug #50168 (FastCGI fails with wrong error on HEAD request to - non-existant file). (Dmitry) -- Fixed bug #50162 (Memory leak when fetching timestamp column from Oracle - database). (Felipe) -- Fixed bug #50159 (wrong working directory in symlinked files). (Dmitry) -- Fixed bug #50158 (FILTER_VALIDATE_EMAIL fails with valid addresses - containing = or ?). (Pierrick) -- Fixed bug #50152 (ReflectionClass::hasProperty behaves like isset() not - property_exists). (Felipe) -- Fixed bug #50146 (property_exists: Closure object cannot have properties). - (Felipe) -- Fixed bug #50145 (crash while running bug35634.phpt). (Felipe) -- Fixed bug #50140 (With default compilation option, php symbols are unresolved - for nsapi). (Uwe Schindler) -- Fixed bug #50087 (NSAPI performance improvements). (Uwe Schindler) -- Fixed bug #50073 (parse_url() incorrect when ? in fragment). (Ilia) -- Fixed bug #50023 (pdo_mysql doesn't use PHP_MYSQL_UNIX_SOCK_ADDR). (Ilia) -- Fixed bug #50005 (Throwing through Reflection modified Exception object - makes segmentation fault). (Felipe) -- Fixed bug #49990 (SNMP3 warning message about security level printed twice). - (Jani) -- Fixed bug #49985 (pdo_pgsql prepare() re-use previous aborted - transaction). (ben dot pineau at gmail dot com, Ilia, Matteo) -- Fixed bug #49938 (Phar::isBuffering() returns inverted value). (Greg) -- Fixed bug #49936 (crash with ftp stream in php_stream_context_get_option()). - (Pierrick) -- Fixed bug #49921 (Curl post upload functions changed). (Ilia) -- Fixed bug #49866 (Making reference on string offsets crashes PHP). (Dmitry) -- Fixed bug #49855 (import_request_variables() always returns NULL). (Ilia, - sjoerd at php dot net) -- Fixed bug #49851, #50451 (http wrapper breaks on 1024 char long headers). - (Ilia) -- Fixed bug #49800 (SimpleXML allow (un)serialize() calls without warning). - (Ilia, wmeler at wp-sa dot pl) -- Fixed bug #49719 (ReflectionClass::hasProperty returns true for a private - property in base class). (Felipe) -- Fixed bug #49677 (ini parser crashes with apache2 and using ${something} - ini variables). (Jani) -- Fixed bug #49660 (libxml 2.7.3+ limits text nodes to 10MB). (Felipe) -- Fixed bug #49647 (DOMUserData does not exist). (Rob) -- Fixed bug #49600 (imageTTFText text shifted right). (Takeshi Abe) -- Fixed bug #49585 (date_format buffer not long enough for >4 digit years). - (Derick, Adam) -- Fixed bug #49560 (oci8: using LOBs causes slow PHP shutdown). (Oracle Corp.) -- Fixed bug #49521 (PDO fetchObject sets values before calling constructor). - (Pierrick) -- Fixed bug #49472 (Constants defined in Interfaces can be overridden). - (Felipe) -- Fixed bug #49463 (setAttributeNS fails setting default namespace). (Rob) -- Fixed bug #49244 (Floating point NaN cause garbage characters). (Sjoerd) -- Fixed bug #49224 (Compile error due to old DNS functions on AIX systems). - (Scott) -- Fixed bug #49174 (crash when extending PDOStatement and trying to set - queryString property). (Felipe) -- Fixed bug #48811 (Directives in PATH section do not get applied to - subdirectories). (Patch by: ct at swin dot edu dot au) -- Fixed bug #48590 (SoapClient does not honor max_redirects). (Sriram) -- Fixed bug #48190 (Content-type parameter "boundary" is not case-insensitive - in HTTP uploads). (Ilia) -- Fixed bug #47848 (importNode doesn't preserve attribute namespaces). (Rob) -- Fixed bug #47409 (extract() problem with array containing word "this"). - (Ilia, chrisstocktonaz at gmail dot com) -- Fixed bug #47281 ($php_errormsg is limited in size of characters) - (Oracle Corp.) -- Fixed bug #46478 (htmlentities() uses obsolete mapping table for character - entity references). (Moriyoshi) -- Fixed bug #45599 (strip_tags() truncates rest of string with invalid - attribute). (Ilia, hradtke) -- Fixed bug #45120 (PDOStatement->execute() returns true then false for same - statement). (Pierrick) -- Fixed bug #44827 (define() allows :: in constant names). (Ilia) -- Fixed bug #44098 (imap_utf8() returns only capital letters). - (steffen at dislabs dot de, Pierre) -- Fixed bug #34852 (Failure in odbc_exec() using oracle-supplied odbc - driver). (tim dot tassonis at trivadis dot com) - -19 Nov 2009, PHP 5.3.1 -- Upgraded bundled sqlite to version 3.6.19. (Scott) -- Updated timezone database to version 2009.17 (2009q). (Derick) - -- Changed ini file directives [PATH=](on Win32) and [HOST=](on all) to be case - insensitive. (garretts) - -- Restored shebang line check to CGI sapi (not checked by scanner anymore). - (Jani) - -- Added "max_file_uploads" INI directive, which can be set to limit the - number of file uploads per-request to 20 by default, to prevent possible - DOS via temporary file exhaustion. (Ilia) -- Added missing sanity checks around exif processing. (Ilia) -- Added error constant when json_encode() detects an invalid UTF-8 sequence. - (Scott) -- Added support for ACL on Windows for thread safe SAPI (Apache2 for example) - and fix its support on NTS. (Pierre) - -- Improved symbolic, mounted volume and junctions support for realpath on - Windows. (Pierre) -- Improved readlink on Windows, suppress \??\ and use the drive syntax only. - (Pierre) -- Improved dns_get_record() AAAA support on windows. Always available when - IPv6 is support is installed, format is now the same than on unix. (Pierre) -- Improved the DNS functions on OSX to use newer APIs, also use Bind 9 API - where available on other platforms. (Scott) -- Improved shared extension loading on OSX to use the standard Unix dlopen() - API. (Scott) - -- Fixed crash in com_print_typeinfo when an invalid typelib is given. (Pierre) -- Fixed a safe_mode bypass in tempnam() identified by Grzegorz Stachowiak. - (Rasmus) -- Fixed a open_basedir bypass in posix_mkfifo() identified by Grzegorz - Stachowiak. (Rasmus) -- Fixed certificate validation inside php_openssl_apply_verification_policy - (Ryan Sleevi, Ilia) -- Fixed crash in SQLiteDatabase::ArrayQuery() and SQLiteDatabase::SingleQuery() - when calling using Reflection. (Felipe) -- Fixed crash when instantiating PDORow and PDOStatement through Reflection. - (Felipe) -- Fixed sanity check for the color index in imagecolortransparent. (Pierre) -- Fixed scandir/readdir when used mounted points on Windows. (Pierre) -- Fixed zlib.deflate compress filter to actually accept level parameter. (Jani) -- Fixed leak on error in popen/exec (and related functions) on Windows. - (Pierre) -- Fixed possible bad caching of symlinked directories in the realpath cache - on Windows. (Pierre) -- Fixed atime and mtime in stat related functions on Windows. (Pierre) -- Fixed spl_autoload_unregister/spl_autoload_functions wrt. Closures and - Functors. (Christian Seiler) -- Fixed open_basedir circumvention for "mail.log" ini directive. - (Maksymilian Arciemowicz, Stas) -- Fixed signature generation/validation for zip archives in ext/phar. (Greg) -- Fixed memory leak in stream_is_local(). (Felipe, Tony) -- Fixed BC break in mime_content_type(), removes the content encoding. (Scott) - -- Fixed PECL bug #16842 (oci_error return false when NO_DATA_FOUND is raised). - (Chris Jones) - -- Fixed bug #50063 (safe_mode_include_dir fails). (Johannes, christian at - elmerot dot se) -- Fixed bug #50052 (Different Hashes on Windows and Linux on wrong Salt size). - (Pierre) -- Fixed bug #49986 (Missing ICU DLLs on windows package). (Pierre) -- Fixed bug #49910 (no support for ././@LongLink for long filenames in phar - tar support). (Greg) -- Fixed bug #49908 (throwing exception in __autoload crashes when interface - is not defined). (Felipe) -- Fixed bug #49847 (exec() fails to return data inside 2nd parameter, given - output lines >4095 bytes). (Ilia) -- Fixed bug #49809 (time_sleep_until() is not available on OpenSolaris). (Jani) -- Fixed bug #49757 (long2ip() can return wrong value in a multi-threaded - applications). (Ilia, Florian Anderiasch) -- Fixed bug #49738 (calling mcrypt after mcrypt_generic_deinit crashes). - (Sriram Natarajan) -- Fixed bug #49732 (crashes when using fileinfo when timestamp conversion - fails). (Pierre) -- Fixed bug #49698 (Unexpected change in strnatcasecmp()). (Rasmus) -- Fixed bug #49630 (imap_listscan function missing). (Felipe) -- Fixed bug #49572 (use of C++ style comments causes build failure). - (Sriram Natarajan) -- Fixed bug #49531 (CURLOPT_INFILESIZE sometimes causes warning "CURLPROTO_FILE - cannot be set"). (Felipe) -- Fixed bug #49517 (cURL's CURLOPT_FILE prevents file from being deleted after - fclose). (Ilia) -- Fixed bug #49470 (FILTER_SANITIZE_EMAIL allows disallowed characters). - (Ilia) -- Fixed bug #49447 (php engine need to correctly check for socket API - return status on windows). (Sriram Natarajan) -- Fixed bug #49391 (ldap.c utilizing deprecated ldap_modify_s). (Ilia) -- Fixed bug #49372 (segfault in php_curl_option_curl). (Pierre) -- Fixed bug #49361 (wordwrap() wraps incorrectly on end of line boundaries). - (Ilia, code-it at mail dot ru) -- Fixed bug #49306 (inside pdo_mysql default socket settings are ignored). - (Ilia) -- Fixed bug #49289 (bcmath module doesn't compile with phpize configure). - (Jani) -- Fixed bug #49286 (php://input (php_stream_input_read) is broken). (Jani) -- Fixed bug #49269 (Ternary operator fails on Iterator object when used inside - foreach declaration). (Etienne, Dmitry) -- Fixed bug #49236 (Missing PHP_SUBST(PDO_MYSQL_SHARED_LIBADD)). (Jani) -- Fixed bug #49223 (Inconsistency using get_defined_constants). (Garrett) -- Fixed bug #49193 (gdJpegGetVersionString() inside gd_compact identifies - wrong type in declaration). (Ilia) -- Fixed bug #49183 (dns_get_record does not return NAPTR records). (Pierre) -- Fixed bug #49144 (Import of schema from different host transmits original - authentication details). (Dmitry) -- Fixed bug #49142 (crash when exception thrown from __tostring()). - (David Soria Parra) -- Fixed bug #49132 (posix_times returns false without error). - (phpbugs at gunnu dot us) -- Fixed bug #49125 (Error in dba_exists C code). (jdornan at stanford dot edu) -- Fixed bug #49122 (undefined reference to mysqlnd_stmt_next_result on compile - with --with-mysqli and MySQL 6.0). (Jani) -- Fixed bug #49108 (2nd scan_dir produces segfault). (Felipe) -- Fixed bug #49098 (mysqli segfault on error). (Rasmus) -- Fixed bug #49095 (proc_get_status['exitcode'] fails on win32). (Felipe) -- Fixed bug #49092 (ReflectionFunction fails to work with functions in fully - qualified namespaces). (Kalle, Jani) -- Fixed bug #49074 (private class static fields can be modified by using - reflection). (Jani) -- Fixed bug #49072 (feof never returns true for damaged file in zip). (Pierre) -- Fixed bug #49065 ("disable_functions" php.ini option does not work on - Zend extensions). (Stas) -- Fixed bug #49064 (--enable-session=shared does not work: undefined symbol: - php_url_scanner_reset_vars). (Jani) -- Fixed bug #49056 (parse_ini_file() regression in 5.3.0 when using non-ASCII - strings as option keys). (Jani) -- Fixed bug #49052 (context option headers freed too early when using - --with-curlwrappers). (Jani) -- Fixed bug #49047 (The function touch() fails on directories on Windows). - (Pierre) -- Fixed bug #49032 (SplFileObject::fscanf() variables passed by reference). - (Jani) -- Fixed bug #49027 (mysqli_options() doesn't work when using mysqlnd). (Andrey) -- Fixed bug #49026 (proc_open() can bypass safe_mode_protected_env_vars - restrictions). (Ilia) -- Fixed bug #49020 (phar misinterprets ustar long filename standard). - (Greg) -- Fixed bug #49018 (phar tar stores long filenames wit prefix/name reversed). - (Greg) -- Fixed bug #49014 (dechunked filter broken when serving more than 8192 bytes - in a chunk). (andreas dot streichardt at globalpark dot com, Ilia) -- Fixed bug #49012 (phar tar signature algorithm reports as Unknown (0) in - getSignature() call). (Greg) -- Fixed bug #49000 (PHP CLI in Interactive mode (php -a) crashes - when including files from function). (Stas) -- Fixed bug #48994 (zlib.output_compression does not output HTTP headers when - set to a string value). (Jani) -- Fixed bug #48980 (Crash when compiling with pdo_firebird). (Felipe) -- Fixed bug #48962 (cURL does not upload files with specified filename). - (Ilia) -- Fixed bug #48929 (Double \r\n after HTTP headers when "header" context - option is an array). (David Zülke) -- Fixed bug #48913 (Too long error code strings in pdo_odbc driver). - (naf at altlinux dot ru, Felipe) -- Fixed bug #48912 (Namespace causes unexpected strict behaviour with - extract()). (Dmitry) -- Fixed bug #48909 (Segmentation fault in mysqli_stmt_execute()). (Andrey) -- Fixed bug #48899 (is_callable returns true even if method does not exist in - parent class). (Felipe) -- Fixed bug #48893 (Problems compiling with Curl). (Felipe) -- Fixed bug #48880 (Random Appearing open_basedir problem). (Rasmus, Gwynne) -- Fixed bug #48872 (string.c: errors: duplicate case values). (Kalle) -- Fixed bug #48854 (array_merge_recursive modifies arrays after first one). - (Felipe) -- Fixed bug #48805 (IPv6 socket transport is not working). (Ilia) -- Fixed bug #48802 (printf() returns incorrect outputted length). (Jani) -- Fixed bug #48791 (open office files always reported as corrupted). (Greg) -- Fixed bug #48788 (RecursiveDirectoryIterator doesn't descend into symlinked - directories). (Ilia) -- Fixed bug #48783 (make install will fail saying phar file exists). (Greg) -- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). - (Sriram Natarajan) -- Fixed bug #48771 (rename() between volumes fails and reports no error on - Windows). (Pierre) -- Fixed bug #48768 (parse_ini_*() crash with INI_SCANNER_RAW). (Jani) -- Fixed bug #48763 (ZipArchive produces corrupt archive). (dani dot church at - gmail dot com, Pierre) -- Fixed bug #48762 (IPv6 address filter still rejects valid address). (Felipe) -- Fixed bug #48757 (ReflectionFunction::invoke() parameter issues). (Kalle) -- Fixed bug #48754 (mysql_close() crash php when no handle specified). - (Johannes, Andrey) -- Fixed bug #48752 (Crash during date parsing with invalid date). (Pierre) -- Fixed bug #48746 (Unable to browse directories within Junction Points). - (Pierre, Kanwaljeet Singla) -- Fixed bug #48745 (mysqlnd: mysql_num_fields returns wrong column count for - mysql_list_fields). (Andrey) -- Fixed bug #48740 (PHAR install fails when INSTALL_ROOT is not the final - install location). (james dot cohen at digitalwindow dot com, Greg) -- Fixed bug #48733 (CURLOPT_WRITEHEADER|CURLOPT_FILE|CURLOPT_STDERR warns on - files that have been opened with r+). (Ilia) -- Fixed bug #48719 (parse_ini_*(): scanner_mode parameter is not checked for - sanity). (Jani) -- Fixed bug #48718 (FILTER_VALIDATE_EMAIL does not allow numbers in domain - components). (Ilia) -- Fixed bug #48681 (openssl signature verification for tar archives broken). - (Greg) -- Fixed bug #48660 (parse_ini_*(): dollar sign as last character of value - fails). (Jani) -- Fixed bug #48645 (mb_convert_encoding() doesn't understand hexadecimal - html-entities). (Moriyoshi) -- Fixed bug #48637 ("file" fopen wrapper is overwritten when using - --with-curlwrappers). (Jani) -- Fixed bug #48608 (Invalid libreadline version not detected during configure). - (Jani) -- Fixed bug #48400 (imap crashes when closing stream opened with - OP_PROTOTYPE flag). (Jani) -- Fixed bug #48377 (error message unclear on converting phar with existing - file). (Greg) -- Fixed bug #48247 (Infinite loop and possible crash during startup with - errors when errors are logged). (Jani) -- Fixed bug #48198 error: 'MYSQLND_LLU_SPEC' undeclared. Cause for #48780 and - #46952 - both fixed too. (Andrey) -- Fixed bug #48189 (ibase_execute error in return param). (Kalle) -- Fixed bug #48182 (ssl handshake fails during asynchronous socket connection). - (Sriram Natarajan) -- Fixed bug #48116 (Fixed build with Openssl 1.0). (Pierre, - Al dot Smith at aeschi dot ch dot eu dot org) -- Fixed bug #48057 (Only the date fields of the first row are fetched, others - are empty). (info at programmiernutte dot net) -- Fixed bug #47481 (natcasesort() does not sort extended ASCII characters - correctly). (Herman Radtke) -- Fixed bug #47351 (Memory leak in DateTime). (Derick, Tobias John) -- Fixed bug #47273 (Encoding bug in SoapServer->fault). (Dmitry) -- Fixed bug #46682 (touch() afield returns different values on windows). - (Pierre) -- Fixed bug #46614 (Extended MySQLi class gives incorrect empty() result). - (Andrey) -- Fixed bug #46020 (with Sun Java System Web Server 7.0 on HPUX, #define HPUX). - (Uwe Schindler) -- Fixed bug #45905 (imagefilledrectangle() clipping error). - (markril at hotmail dot com, Pierre) -- Fixed bug #45554 (Inconsistent behavior of the u format char). (Derick) -- Fixed bug #45141 (setcookie will output expires years of >4 digits). (Ilia) -- Fixed bug #44683 (popen crashes when an invalid mode is passed). (Pierre) -- Fixed bug #43510 (stream_get_meta_data() does not return same mode as used - in fopen). (Jani) -- Fixed bug #42434 (ImageLine w/ antialias = 1px shorter). (wojjie at gmail dot - com, Kalle) -- Fixed bug #40013 (php_uname() does not return nodename on Netware (Guenter - Knauf) -- Fixed bug #38091 (Mail() does not use FQDN when sending SMTP helo). - (Kalle, Rick Yorgason) -- Fixed bug #28038 (Sent incorrect RCPT TO commands to SMTP server) (Garrett) -- Fixed bug #27051 (Impersonation with FastCGI does not exec process as - impersonated user). (Pierre) - - -30 Jun 2009, PHP 5.3.0 -- Upgraded bundled PCRE to version 7.9. (Nuno) -- Upgraded bundled sqlite to version 3.6.15. (Scott) - -- Moved extensions to PECL (Derick, Lukas, Pierre, Scott): - . ext/dbase - . ext/fbsql - . ext/fdf - . ext/ncurses - . ext/mhash (BC layer is now entirely within ext/hash) - . ext/ming - . ext/msql - . ext/sybase (not maintained anymore, sybase_ct has to be used instead) - -- Removed the experimental RPL (master/slave) functions from mysqli. (Andrey) -- Removed zend.ze1_compatibility_mode. (Dmitry) -- Removed all zend_extension_* php.ini directives. Zend extensions are now - always loaded using zend_extension directive. (Derick) -- Removed special treatment of "/tmp" in sessions for open_basedir. - Note: This undocumented behaviour was introduced in 5.2.2. (Alexey) -- Removed shebang line check from CGI sapi (checked by scanner). (Dmitry) - -- Changed PCRE, Reflection and SPL extensions to be always enabled. (Marcus) -- Changed md5() to use improved implementation. (Solar Designer, Dmitry) -- Changed HTTP stream wrapper to accept any code between and including - 200 to 399 as successful. (Mike, Noah Fontes) -- Changed __call() to be invoked on private/protected method access, similar to - properties and __get(). (Andrei) -- Changed dl() to be disabled by default. Enabled only when explicitly - registered by the SAPI. Currently enabled with cli, cgi and embed SAPIs. - (Dmitry) -- Changed opendir(), dir() and scandir() to use default context when no context - argument is passed. (Sara) -- Changed open_basedir to allow tightening in runtime contexts. (Sara) -- Changed PHP/Zend extensions to use flexible build IDs. (Stas) -- Changed error level E_ERROR into E_WARNING in Soap extension methods - parameter validation. (Felipe) -- Changed openssl info to show the shared library version number. (Scott) -- Changed floating point behaviour to consistently use double precision on all - platforms and with all compilers. (Christian Seiler) -- Changed round() to act more intuitively when rounding to a certain precision - and round very large and very small exponents correctly. (Christian Seiler) -- Changed session_start() to return false when session startup fails. (Jani) -- Changed property_exists() to check the existence of a property independent of - accessibility (like method_exists()). (Felipe) -- Changed array_reduce() to allow mixed $initial (Christian Seiler) - -- Improved PHP syntax and semantics: - . Added lambda functions and closures. (Christian Seiler, Dmitry) - . Added "jump label" operator (limited "goto"). (Dmitry, Sara) - . Added NOWDOC syntax. (Gwynne Raskind, Stas, Dmitry) - . Added HEREDOC syntax with double quotes. (Lars Strojny, Felipe) - . Added support for using static HEREDOCs to initialize static variables and - class members or constants. (Matt) - . Improved syntax highlighting and consistency for variables in double-quoted - strings and literal text in HEREDOCs and backticks. (Matt) - . Added "?:" operator. (Marcus) - . Added support for namespaces. (Dmitry, Stas, Gregory, Marcus) - . Added support for Late Static Binding. (Dmitry, Etienne Kneuss) - . Added support for __callStatic() magic method. (Sara) - . Added forward_static_call(_array) to complete LSB. (Mike Lively) - . Added support for dynamic access of static members using $foo::myFunc(). - (Etienne Kneuss) - . Improved checks for callbacks. (Marcus) - . Added __DIR__ constant. (Lars Strojny) - . Added new error modes E_USER_DEPRECATED and E_DEPRECATED. - E_DEPRECATED is used to inform about stuff being scheduled for removal - in future PHP versions. (Lars Strojny, Felipe, Marcus) - . Added "request_order" INI variable to control specifically $_REQUEST - behavior. (Stas) - . Added support for exception linking. (Marcus) - . Added ability to handle exceptions in destructors. (Marcus) - -- Improved PHP runtime speed and memory usage: - . Substitute global-scope, persistent constants with their values at compile - time. (Matt) - . Optimized ZEND_SIGNED_MULTIPLY_LONG(). (Matt) - . Removed direct executor recursion. (Dmitry) - . Use fastcall calling convention in executor on x86. (Dmitry) - . Use IS_CV for direct access to $this variable. (Dmitry) - . Use ZEND_FREE() opcode instead of ZEND_SWITCH_FREE(IS_TMP_VAR). (Dmitry) - . Lazy EG(active_symbol_table) initialization. (Dmitry) - . Optimized ZEND_RETURN opcode to not allocate and copy return value if it is - not used. (Dmitry) - . Replaced all flex based scanners with re2c based scanners. - (Marcus, Nuno, Scott) - . Added garbage collector. (David Wang, Dmitry). - . Improved PHP binary size and startup speed with GCC4 visibility control. - (Nuno) - . Improved engine stack implementation for better performance and stability. - (Dmitry) - . Improved memory usage by moving constants to read only memory. - (Dmitry, Pierre) - . Changed exception handling. Now each op_array doesn't contain - ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry) - . Optimized require_once() and include_once() by eliminating fopen(3) on - second usage. (Dmitry) - . Optimized ZEND_FETCH_CLASS + ZEND_ADD_INTERFACE into single - ZEND_ADD_INTERFACE opcode. (Dmitry) - . Optimized string searching for a single character. - (Michal Dziemianko, Scott) - . Optimized interpolated strings to use one less opcode. (Matt) - -- Improved php.ini handling: (Jani) - . Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI. - . Added support for special [PATH=/opt/httpd/www.example.com/] and - [HOST=www.example.com] sections. Directives set in these sections can - not be overridden by user-defined ini-files or during runtime. - . Added better error reporting for php.ini syntax errors. - . Allowed using full path to load modules using "extension" directive. - . Allowed "ini-variables" to be used almost everywhere ini php.ini files. - . Allowed using alphanumeric/variable indexes in "array" ini options. - . Added 3rd optional parameter to parse_ini_file() to specify the scanning - mode of INI_SCANNER_NORMAL or INI_SCANNER_RAW. In raw mode option values - and section values are treated as-is. - . Fixed get_cfg_var() to be able to return "array" ini options. - . Added optional parameter to ini_get_all() to only retrieve the current - value. (Hannes) - -- Improved Windows support: - . Update all libraries to their latest stable version. (Pierre, Rob, Liz, - Garrett). - . Added Windows support for stat(), touch(), filemtime(), filesize() and - related functions. (Pierre) - . Re-added socket_create_pair() for Windows in sockets extension. (Kalle) - . Added inet_pton() and inet_ntop() also for Windows platforms. - (Kalle, Pierre) - . Added mcrypt_create_iv() for Windows platforms. (Pierre) - . Added ACL Cache support on Windows. - (Kanwaljeet Singla, Pierre, Venkat Raman Don) - . Added constants based on Windows' GetVersionEx information. - PHP_WINDOWS_VERSION_* and PHP_WINDOWS_NT_*. (Pierre) - . Added support for ACL (is_writable, is_readable, reports now correct - results) on Windows. (Pierre, Venkat Raman Don, Kanwaljeet Singla) - . Added support for fnmatch() on Windows. (Pierre) - . Added support for time_nanosleep() and time_sleep_until() on Windows. - (Pierre) - . Added support for symlink(), readlink(), linkinfo() and link() on Windows. - They are available only when the running platform supports them. (Pierre) - . the GMP extension now relies on MPIR instead of the GMP library. (Pierre) - . Added Windows support for stream_socket_pair(). (Kalle) - . Drop all external dependencies for the core features. (Pierre) - . Drastically improve the build procedure (Pierre, Kalle, Rob): - . VC9 (Visual C++ 2008) or later support - . Initial experimental x64 support - . MSI installer now supports all recent Windows versions, including - Windows 7. (John, Kanwaljeet Singla) - -- Improved and cleaned CGI code: - . FastCGI is now always enabled and cannot be disabled. - See sapi/cgi/CHANGES for more details. (Dmitry) - . Added CGI SAPI -T option which can be used to measure execution - time of script repeated several times. (Dmitry) - -- Improved streams: - . Fixed confusing error message on failure when no errors are logged. (Greg) - . Added stream_supports_lock() function. (Benjamin Schulz) - . Added context parameter for copy() function. (Sara) - . Added "glob://" stream wrapper. (Marcus) - . Added "params" as optional parameter for stream_context_create(). (Sara) - . Added ability to use stream wrappers in include_path. (Gregory, Dmitry) - -- Improved DNS API - . Added Windows support for dns_check_record(), dns_get_mx(), checkdnsrr() and - getmxrr(). (Pierre) - . Added support for old style DNS functions (supports OSX and FBSD). (Scott) - . Added a new "entries" array in dns_check_record() containing the TXT - elements. (Felipe, Pierre) - -- Improved hash extension: - . Changed mhash to be a wrapper layer around the hash extension. (Scott) - . Added hash_copy() function. (Tony) - . Added sha224 hash algorithm to the hash extension. (Scott) - -- Improved IMAP support (Pierre): - . Added imap_gc() to clear the imap cache - . Added imap_utf8_to_mutf7() and imap_mutf7_to_utf8() - -- Improved mbstring extension: - . Added "mbstring.http_output_conv_mimetypes" INI directive that allows - common non-text types such as "application/xhtml+xml" to be converted - by mb_output_handler(). (Moriyoshi) - -- Improved OCI8 extension (Chris Jones/Oracle Corp.): - . Added Database Resident Connection Pooling (DRCP) and Fast - Application Notification (FAN) support. - . Added support for Oracle External Authentication (not supported - on Windows). - . Improve persistent connection handling of restarted DBs. - . Added SQLT_AFC (aka CHAR datatype) support to oci_bind_by_name. - . Fixed bug #45458 (Numeric keys for associative arrays are not - handled properly) - . Fixed bug #41069 (Segmentation fault with query over DB link). - . Fixed define of SQLT_BDOUBLE and SQLT_BFLOAT constants with Oracle - 10g ORACLE_HOME builds. - . Changed default value of oci8.default_prefetch from 10 to 100. - . Fixed PECL Bug #16035 (OCI8: oci_connect without ORACLE_HOME defined causes - segfault) (Chris Jones/Oracle Corp.) - . Fixed PECL Bug #15988 (OCI8: sqlnet.ora isn't read with older Oracle - libraries) (Chris Jones/Oracle Corp.) - . Fixed PECL Bug #14268 (Allow "pecl install oci8" command to "autodetect" an - Instant Client RPM install) (Chris Jones/Oracle Corp.) - . Fixed PECL bug #12431 (OCI8 ping functionality is broken). - . Allow building (e.g from PECL) the PHP 5.3-based OCI8 code with - PHP 4.3.9 onwards. - . Provide separate extensions for Oracle 11g and 10g on Windows. - (Pierre, Chris) - -- Improved OpenSSL extension: - . Added support for OpenSSL digest and cipher functions. (Dmitry) - . Added access to internal values of DSA, RSA and DH keys. (Dmitry) - . Fixed a memory leak on openssl_decrypt(). (Henrique) - . Fixed segfault caused by openssl_pkey_new(). (Henrique) - . Fixed bug caused by uninitilized variables in openssl_pkcs7_encrypt() and - openssl_pkcs7_sign(). (Henrique) - . Fixed error message in openssl_seal(). (Henrique) - -- Improved pcntl extension: (Arnaud) - . Added pcntl_signal_dispatch(). - . Added pcntl_sigprocmask(). - . Added pcntl_sigwaitinfo(). - . Added pcntl_sigtimedwait(). - -- Improved SOAP extension: - . Added support for element names in context of XMLSchema's . (Dmitry) - . Added ability to use Traversable objects instead of plain arrays. - (Joshua Reese, Dmitry) - . Fixed possible crash bug caused by an uninitialized value. (Zdash Urf) - -- Improved SPL extension: - . Added SPL to list of standard extensions that cannot be disabled. (Marcus) - . Added ability to store associative information with objects in - SplObjectStorage. (Marcus) - . Added ArrayAccess support to SplObjectStorage. (Marcus) - . Added SplDoublyLinkedList, SplStack, SplQueue classes. (Etienne) - . Added FilesystemIterator. (Marcus) - . Added GlobIterator. (Marcus) - . Added SplHeap, SplMinHeap, SplMaxHeap, SplPriorityQueue classes. (Etienne) - . Added new parameter $prepend to spl_autoload_register(). (Etienne) - . Added SplFixedArray. (Etienne, Tony) - . Added delaying exceptions in SPL's autoload mechanism. (Marcus) - . Added RecursiveTreeIterator. (Arnaud, Marcus) - . Added MultipleIterator. (Arnaud, Marcus, Johannes) - -- Improved Zend Engine: - . Added "compact" handler for Zend MM storage. (Dmitry) - . Added "+" and "*" specifiers to zend_parse_parameters(). (Andrei) - . Added concept of "delayed early binding" that allows opcode caches to - perform class declaration (early and/or run-time binding) in exactly - the same order as vanilla PHP. (Dmitry) - -- Improved crypt() function: (Pierre) - . Added Blowfish and extended DES support. (Using Blowfish implementation - from Solar Designer). - . Made crypt features portable by providing our own implementations - for crypt_r and the algorithms which are used when OS does not provide - them. PHP implementations are always used for Windows builds. - -- Deprecated session_register(), session_unregister() and - session_is_registered(). (Hannes) -- Deprecated define_syslog_variables(). (Kalle) -- Deprecated ereg extension. (Felipe) - -- Added new extensions: - . Added Enchant extension as a way to access spell checkers. (Pierre) - . Added fileinfo extension as replacement for mime_magic extension. (Derick) - . Added intl extension for Internationalization. (Ed B., Vladimir I., - Dmitry L., Stanislav M., Vadim S., Kirti V.) - . Added mysqlnd extension as replacement for libmysql for ext/mysql, mysqli - and PDO_mysql. (Andrey, Johannes, Ulf) - . Added phar extension for handling PHP Archives. (Greg, Marcus, Steph) - . Added SQLite3 extension. (Scott) - -- Added new date/time functionality: (Derick) - . date_parse_from_format(): Parse date/time strings according to a format. - . date_create_from_format()/DateTime::createFromFormat(): Create a date/time - object by parsing a date/time string according to a given format. - . date_get_last_errors()/DateTime::getLastErrors(): Return a list of warnings - and errors that were found while parsing a date/time string through: - . strtotime() / new DateTime - . date_create_from_format() / DateTime::createFromFormat() - . date_parse_from_format(). - . support for abbreviation and offset based timezone specifiers for - the 'e' format specifier, DateTime::__construct(), DateTime::getTimeZone() - and DateTimeZone::getName(). - . support for selectively listing timezone identifiers by continent or - country code through timezone_identifiers_list() / - DateTimezone::listIdentifiers(). - . timezone_location_get() / DateTimezone::getLocation() for retrieving - location information from timezones. - . date_timestamp_set() / DateTime::setTimestamp() to set a Unix timestamp - without invoking the date parser. (Scott, Derick) - . date_timestamp_get() / DateTime::getTimestamp() to retrieve the Unix - timestamp belonging to a date object. - . two optional parameters to timezone_transitions_get() / - DateTimeZone::getTranstions() to limit the range of transitions being - returned. - . support for "first/last day of " style texts. - . support for date/time strings returned by MS SQL. - . support for serialization and unserialization of DateTime objects. - . support for diffing date/times through date_diff() / DateTime::diff(). - . support for adding/subtracting weekdays with strtotime() and - DateTime::modify(). - . DateInterval class to represent the difference between two date/times. - . support for parsing ISO intervals for use with DateInterval. - . date_add() / DateTime::add(), date_sub() / DateTime::sub() for applying an - interval to an existing date/time. - . proper support for "this week", "previous week"/"last week" and "next week" - phrases so that they actually mean the week and not a seven day period - around the current day. - . support for " of" and "last of" phrases to be used - with months - like in "last saturday of februari 2008". - . support for "back of " and "front of " phrases that are used in - Scotland. - . DatePeriod class which supports iterating over a DateTime object applying - DateInterval on each iteration, up to an end date or limited by maximum - number of occurences. - -- Added compatibility mode in GD, imagerotate, image(filled)ellipse - imagefilter, imageconvolution and imagecolormatch are now always enabled. - (Pierre) -- Added array_replace() and array_replace_recursive() functions. (Matt) -- Added ReflectionProperty::setAccessible() method that allows non-public - property's values to be read through ::getValue() and set through - ::setValue(). (Derick, Sebastian) -- Added msg_queue_exists() function to sysvmsg extension. (Benjamin Schulz) -- Added Firebird specific attributes that can be set via PDO::setAttribute() - to control formatting of date/timestamp columns: PDO::FB_ATTR_DATE_FORMAT, - PDO::FB_ATTR_TIME_FORMAT and PDO::FB_ATTR_TIMESTAMP_FORMAT. (Lars W) -- Added gmp_testbit() function. (Stas) -- Added icon format support to getimagesize(). (Scott) -- Added LDAP_OPT_NETWORK_TIMEOUT option for ldap_set_option() to allow - setting network timeout (FR #42837). (Jani) -- Added optional escape character parameter to fgetcsv(). (David Soria Parra) -- Added an optional parameter to strstr() and stristr() for retrieval of either - the part of haystack before or after first occurrence of needle. - (Johannes, Felipe) -- Added xsl->setProfiling() for profiling stylesheets. (Christian) -- Added long-option feature to getopt() and made getopt() available also on - win32 systems by adding a common getopt implementation into core. - (David Soria Parra, Jani) -- Added support for optional values, and = as separator, in getopt(). (Hannes) -- Added lcfirst() function. (David C) -- Added PREG_BAD_UTF8_OFFSET_ERROR constant. (Nuno) -- Added native support for asinh(), acosh(), atanh(), log1p() and expm1(). - (Kalle) -- Added LIBXML_LOADED_VERSION constant (libxml2 version currently used). (Rob) -- Added JSON_FORCE_OBJECT flag to json_encode(). (Scott, Richard Quadling) -- Added timezone_version_get() to retrieve the version of the used timezone - database. (Derick) -- Added 'n' flag to fopen to allow passing O_NONBLOCK to the underlying - open(2) system call. (Mikko) -- Added "dechunk" filter which can decode HTTP responses with chunked - transfer-encoding. HTTP streams use this filter automatically in case - "Transfer-Encoding: chunked" header is present in response. It's possible to - disable this behaviour using "http"=>array("auto_decode"=>0) in stream - context. (Dmitry) -- Added support for CP850 encoding in mbstring extension. - (Denis Giffeler, Moriyoshi) -- Added stream_cast() and stream_set_options() to user-space stream wrappers, - allowing stream_select(), stream_set_blocking(), stream_set_timeout() and - stream_set_write_buffer() to work with user-space stream wrappers. (Arnaud) -- Added header_remove() function. (chsc at peytz dot dk, Arnaud) -- Added stream_context_get_params() function. (Arnaud) -- Added optional parameter "new" to sybase_connect(). (Timm) -- Added parse_ini_string() function. (grange at lemonde dot fr, Arnaud) -- Added str_getcsv() function. (Sara) -- Added openssl_random_pseudo_bytes() function. (Scott) -- Added ability to send user defined HTTP headers with SOAP request. - (Brian J.France, Dmitry) -- Added concatenation option to bz2.decompress stream filter. - (Keisial at gmail dot com, Greg) -- Added support for using compressed connections with PDO_mysql. (Johannes) -- Added the ability for json_decode() to take a user specified depth. (Scott) -- Added support for the mysql_stmt_next_result() function from libmysql. - (Andrey) -- Added function preg_filter() that does grep and replace in one go. (Marcus) -- Added system independent realpath() implementation which caches intermediate - directories in realpath-cache. (Dmitry) -- Added optional clear_realpath_cache and filename parameters to - clearstatcache(). (Jani, Arnaud) -- Added litespeed SAPI module. (George Wang) -- Added ext/hash support to ext/session's ID generator. (Sara) -- Added quoted_printable_encode() function. (Tony) -- Added stream_context_set_default() function. (Davey Shafik) -- Added optional "is_xhtml" parameter to nl2br() which makes the function - output
when false and
when true (FR #34381). (Kalle) -- Added PHP_MAXPATHLEN constant (maximum length of a path). (Pierre) -- Added support for SSH via libssh2 in cURL. (Pierre) -- Added support for gray levels PNG image with alpha in GD extension. (Pierre) -- Added support for salsa hashing functions in HASH extension. (Scott) -- Added DOMNode::getLineNo to get line number of parsed node. (Rob) -- Added table info to PDO::getColumnMeta() with SQLite. (Martin Jansen, Scott) -- Added mail logging functionality that allows logging of mail sent via - mail() function. (Ilia) -- Added json_last_error() to return any error information from json_decode(). - (Scott) -- Added gethostname() to return the current system host name. (Ilia) -- Added shm_has_var() function. (Mike) -- Added depth parameter to json_decode() to lower the nesting depth from the - maximum if required. (Scott) -- Added pixelation support in imagefilter(). (Takeshi Abe, Kalle) -- Added SplObjectStorage::addAll/removeAll. (Etienne) - -- Implemented FR #41712 (curl progress callback: CURLOPT_PROGRESSFUNCTION). - (sdteffen[at]gmail[dot].com, Pierre) -- Implemented FR #47739 (Missing cURL option do disable IPv6). (Pierre) -- Implemented FR #39637 (Missing cURL option CURLOPT_FTP_FILEMETHOD). (Pierre) - -- Fixed an issue with ReflectionProperty::setAccessible(). - (Sebastian, Roman Borschel) -- Fixed html_entity_decode() incorrectly converting numeric html entities - to different characters with cp1251 and cp866. (Scott) -- Fixed an issue in date() where a : was printed for the O modifier after a P - modifier was used. (Derick) -- Fixed exec() on Windows to not eat the first and last double quotes. (Scott) -- Fixed readlink on Windows in thread safe SAPI (apache2.x etc.). (Pierre) -- Fixed a bug causing miscalculations with the "last of month" - relative time string. (Derick) -- Fixed bug causing the algorithm parameter of mhash() to be modified. (Scott) -- Fixed invalid calls to free when internal fileinfo magic file is used. (Scott) -- Fixed memory leak inside wddx_add_vars() function. (Felipe) -- Fixed check in recode extension to allow builing of recode and mysql - extensions when using a recent libmysql. (Johannes) - -- Fixed PECL bug #12794 (PDOStatement->nextRowset() doesn't work). (Johannes) -- Fixed PECL bug #12401 (Add support for ATTR_FETCH_TABLE_NAMES). (Johannes) - -- Fixed bug #48696 (ldap_read() segfaults with invalid parameters). (Felipe) -- Fixed bug #48643 (String functions memory issue). (Dmitry) -- Fixed bug #48641 (tmpfile() uses old parameter parsing). - (crrodriguez at opensuse dot org) -- Fixed bug #48624 (.user.ini never gets parsed). (Pierre) -- Fixed bug #48620 (X-PHP-Originating-Script assumes no trailing CRLF in - existing headers). (Ilia) -- Fixed bug #48578 (Can't build 5.3 on FBSD 4.11). (Rasmus) -- Fixed bug #48535 (file_exists returns false when impersonate is used). - (Kanwaljeet Singla, Venkat Raman Don) -- Fixed bug #48493 (spl_autoload_register() doesn't work correctly when - prepending functions). (Scott) -- Fixed bug #48215 (Calling a method with the same name as the parent class - calls the constructor). (Scott) -- Fixed bug #48200 (compile failure with mbstring.c when - --enable-zend-multibyte is used). (Jani) -- Fixed bug #48188 (Cannot execute a scrollable cursors twice with PDO_PGSQL). - (Matteo) -- Fixed bug #48185 (warning: value computed is not used in - pdo_sqlite_stmt_get_col line 271). (Matteo) -- Fixed bug #48087 (call_user_method() invalid free of arguments). (Felipe) -- Fixed bug #48060 (pdo_pgsql - large objects are returned as empty). (Matteo) -- Fixed bug #48034 (PHP crashes when script is 8192 (8KB) bytes long). (Dmitry) -- Fixed bug #48004 (Error handler prevents creation of default object). (Dmitry) -- Fixed bug #47880 (crashes in call_user_func_array()). (Dmitry) -- Fixed bug #47856 (stristr() converts needle to lower-case). (Ilia) -- Fixed bug #47851 (is_callable throws fatal error). (Dmitry) -- Fixed bug #47816 (pcntl tests failing on NetBSD). (Matteo) -- Fixed bug #47779 (Wrong value for SIG_UNBLOCK and SIG_SETMASK constants). - (Matteo) -- Fixed bug #47771 (Exception during object construction from arg call calls - object's destructor). (Dmitry) -- Fixed bug #47767 (include_once does not resolve windows symlinks or junctions) - (Kanwaljeet Singla, Venkat Raman Don) -- Fixed bug #47757 (rename JPG to JPEG in phpinfo). (Pierre) -- Fixed bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer). (Dmitry) -- Fixed bug #47714 (autoloading classes inside exception_handler leads to - crashes). (Dmitry) -- Fixed bug #47671 (Cloning SplObjectStorage instances). (Etienne) -- Fixed bug #47664 (get_class returns NULL instead of FALSE). (Dmitry) -- Fixed bug #47662 (Support more than 127 subpatterns in preg_match). (Nuno) -- Fixed bug #47596 (Bus error on parsing file). (Dmitry) -- Fixed bug #47572 (Undefined constant causes segmentation fault). (Felipe) -- Fixed bug #47560 (explode()'s limit parameter odd behaviour). (Matt) -- Fixed bug #47549 (get_defined_constants() return array with broken array - categories). (Ilia) -- Fixed bug #47535 (Compilation failure in ps_fetch_from_1_to_8_bytes()). - (Johannes) -- Fixed bug #47534 (RecursiveDiteratoryIterator::getChildren ignoring - CURRENT_AS_PATHNAME). (Etienne) -- Fixed bug #47443 (metaphone('scratch') returns wrong result). (Felipe) -- Fixed bug #47438 (mysql_fetch_field ignores zero offset). (Johannes) -- Fixed bug #47398 (PDO_Firebird doesn't implements quoter correctly). (Felipe) -- Fixed bug #47390 (odbc_fetch_into - BC in php 5.3.0). (Felipe) -- Fixed bug #47359 (Use the expected unofficial mimetype for bmp files). (Scott) -- Fixed bug #47343 (gc_collect_cycles causes a segfault when called within a - destructor in one case). (Dmitry) -- Fixed bug #47320 ($php_errormsg out of scope in functions). (Dmitry) -- Fixed bug #47318 (UMR when trying to activate user config). (Pierre) -- Fixed bug #47243 (OCI8: Crash at shutdown on Windows) (Chris Jones/Oracle - Corp.) -- Fixed bug #47231 (offsetGet error using incorrect offset). (Etienne) -- Fixed bug #47229 (preg_quote() should escape the '-' char). (Nuno) -- Fixed bug #47165 (Possible memory corruption when passing return value by - reference). (Dmitry) -- Fixed bug #47087 (Second parameter of mssql_fetch_array()). (Felipe) -- Fixed bug #47085 (rename() returns true even if the file in PHAR does not - exist). (Greg) -- Fixed bug #47050 (mysqli_poll() modifies improper variables). (Johannes) -- Fixed bug #47045 (SplObjectStorage instances compared with ==). (Etienne) -- Fixed bug #47038 (Memory leak in include). (Dmitry) -- Fixed bug #47031 (Fix constants in DualIterator example). (Etienne) -- Fixed bug #47021 (SoapClient stumbles over WSDL delivered with - "Transfer-Encoding: chunked"). (Dmitry) -- Fixed bug #46994 (OCI8: CLOB size does not update when using CLOB IN OUT param - in stored procedure) (Chris Jones/Oracle Corp.) -- Fixed bug #46979 (use with non-compound name *has* effect). (Dmitry) -- Fixed bug #46957 (The tokenizer returns deprecated values). (Felipe) -- Fixed bug #46944 (UTF-8 characters outside the BMP aren't encoded correctly). - (Scott) -- Fixed bug #46897 (ob_flush() should fail to flush unerasable buffers). - (David C.) -- Fixed bug #46849 (Cloning DOMDocument doesn't clone the properties). (Rob) -- Fixed bug #46847 (phpinfo() is missing some settings). (Hannes) -- Fixed bug #46844 (php scripts or included files with first line starting - with # have the 1st line missed from the output). (Ilia) -- Fixed bug #46817 (tokenizer misses last single-line comment (PHP 5.3+, with - re2c lexer)). (Matt, Shire) -- Fixed bug #46811 (ini_set() doesn't return false on failure). (Hannes) -- Fixed bug #46763 (mb_stristr() wrong output when needle does not exist). - (Henrique M. Decaria) -- Fixed bug #46755 (warning: use statement with non-compound name). (Dmitry) -- Fixed bug #46746 (xmlrpc_decode_request outputs non-suppressable error when - given bad data). (Ilia) -- Fixed bug #46738 (Segfault when mb_detect_encoding() fails). (Scott) -- Fixed bug #46731 (Missing validation for the options parameter of the - imap_fetch_overview() function). (Ilia) -- Fixed bug #46711 (cURL curl_setopt leaks memory in foreach loops). (magicaltux - [at] php [dot] net) -- Fixed bug #46701 (Creating associative array with long values in the key fails - on 32bit linux). (Shire) -- Fixed bug #46681 (mkdir() fails silently on PHP 5.3). (Hannes) -- Fixed bug #46653 (can't extend mysqli). (Johannes) -- Fixed bug #46646 (Restrict serialization on some internal classes like Closure - and SplFileInfo using exceptions). (Etienne) -- Fixed bug #46623 (OCI8: phpinfo doesn't show compile time ORACLE_HOME with - phpize) (Chris Jones/Oracle Corp.) -- Fixed bug #46578 (strip_tags() does not honor end-of-comment when it - encounters a single quote). (Felipe) -- Fixed bug #46546 (Segmentation fault when using declare statement with - non-string value). (Felipe) -- Fixed bug #46542 (Extending PDO class with a __call() function doesn't work as - expected). (Johannes) -- Fixed bug #46421 (SplFileInfo not correctly handling /). (Etienne) -- Fixed bug #46347 (parse_ini_file() doesn't support * in keys). (Nuno) -- Fixed bug #46268 (DateTime::modify() does not reset relative time values). - (Derick) -- Fixed bug #46241 (stacked error handlers, internal error handling in general). - (Etienne) -- Fixed bug #46238 (Segmentation fault on static call with empty string method). - (Felipe) -- Fixed bug #46192 (ArrayObject with objects as storage serialization). - (Etienne) -- Fixed bug #46185 (importNode changes the namespace of an XML element). (Rob) -- Fixed bug #46178 (memory leak in ext/phar). (Greg) -- Fixed bug #46160 (SPL - Memory leak when exception is thrown in offsetSet). - (Felipe) -- Fixed Bug #46147 (after stream seek, appending stream filter reads incorrect - data). (Greg) -- Fixed bug #46127 (php_openssl_tcp_sockop_accept forgets to set context on - accepted stream) (Mark Karpeles, Pierre) -- Fixed bug #46115 (Memory leak when calling a method using Reflection). - (Dmitry) -- Fixed bug #46110 (XMLWriter - openmemory() and openuri() leak memory on - multiple calls). (Ilia) -- Fixed bug #46108 (DateTime - Memory leak when unserializing). (Felipe) -- Fixed bug #46106 (Memory leaks when using global statement). (Dmitry) -- Fixed bug #46099 (Xsltprocessor::setProfiling - memory leak). (Felipe, Rob). -- Fixed bug #46087 (DOMXPath - segfault on destruction of a cloned object). - (Ilia) -- Fixed bug #46048 (SimpleXML top-level @attributes not part of iterator). - (David C.) -- Fixed bug #46044 (Mysqli - wrong error message). (Johannes) -- Fixed bug #46042 (memory leaks with reflection of mb_convert_encoding()). - (Ilia) -- Fixed bug #46039 (ArrayObject iteration is slow). (Arnaud) -- Fixed bug #46033 (Direct instantiation of SQLite3stmt and SQLite3result cause - a segfault.) (Scott) -- Fixed bug #45991 (Ini files with the UTF-8 BOM are treated as invalid). - (Scott) -- Fixed bug #45989 (json_decode() doesn't return NULL on certain invalid - strings). (magicaltux, Scott) -- Fixed bug #45976 (Moved SXE from SPL to SimpleXML). (Etienne) -- Fixed bug #45928 (large scripts from stdin are stripped at 16K border). - (Christian Schneider, Arnaud) -- Fixed bug #45911 (Cannot disable ext/hash). (Arnaud) -- Fixed bug #45907 (undefined reference to 'PHP_SHA512Init'). (Greg) -- Fixed bug #45826 (custom ArrayObject serialization). (Etienne) -- Fixed bug #45820 (Allow empty keys in ArrayObject). (Etienne) -- Fixed bug #45791 (json_decode() doesn't convert 0e0 to a double). (Scott) -- Fixed bug #45786 (FastCGI process exited unexpectedly). (Dmitry) -- Fixed bug #45757 (FreeBSD4.11 build failure: failed include; stdint.h). - (Hannes) -- Fixed bug #45743 (property_exists fails to find static protected member in - child class). (Felipe) -- Fixed bug #45717 (Fileinfo/libmagic build fails, missing err.h and getopt.h). - (Derick) -- Fixed bug #45706 (Unserialization of classes derived from ArrayIterator - fails). (Etienne, Dmitry) -- Fixed bug #45696 (Not all DateTime methods allow method chaining). (Derick) -- Fixed bug #45682 (Unable to var_dump(DateInterval)). (Derick) -- Fixed bug #45447 (Filesystem time functions on Vista and server 2008). - (Pierre) -- Fixed bug #45432 (PDO: persistent connection leak). (Felipe) -- Fixed bug #45392 (ob_start()/ob_end_clean() and memory_limit). (Ilia) -- Fixed bug #45384 (parse_ini_file will result in parse error with no trailing - newline). (Arnaud) -- Fixed bug #45382 (timeout bug in stream_socket_enable_crypto). (vnegrier at - optilian dot com, Ilia) -- Fixed bug #45044 (relative paths not resolved correctly). (Dmitry) -- Fixed bug #44861 (scrollable cursor don't work with pgsql). (Matteo) -- Fixed bug #44842 (parse_ini_file keys that start/end with underscore). - (Arnaud) -- Fixed bug #44575 (parse_ini_file comment # line problems). (Arnaud) -- Fixed bug #44409 (PDO::FETCH_SERIALIZE calls __construct()). (Matteo) -- Fixed bug #44173 (PDO->query() parameter parsing/checking needs an update). - (Matteo) -- Fixed bug #44154 (pdo->errorInfo() always have three elements in the returned - array). (David C.) -- Fixed bug #44153 (pdo->errorCode() returns NULL when there are no errors). - (David C.) -- Fixed bug #44135 (PDO MySQL does not support CLIENT_FOUND_ROWS). (Johannes, - chx1975 at gmail dot com) -- Fixed bug #44100 (Inconsistent handling of static array declarations with - duplicate keys). (Dmitry) -- Fixed bug #43831 ($this gets mangled when extending PDO with persistent - connection). (Felipe) -- Fixed bug #43817 (opendir() fails on Windows directories with parent directory - unaccessible). (Dmitry) -- Fixed bug #43069 (SoapClient causes 505 HTTP Version not supported error - message). (Dmitry) -- Fixed bug #43008 (php://filter uris ignore url encoded filternames and can't - handle slashes). (Arnaud) -- Fixed bug #42362 (HTTP status codes 204 and 304 should not be gzipped). - (Scott, Edward Z. Yang) -- Fixed bug #41874 (separate STDOUT and STDERR in exec functions). (Kanwaljeet - Singla, Venkat Raman Don, Pierre) -- Fixed bug #41534 (SoapClient over HTTPS fails to reestablish connection). - (Dmitry) -- Fixed bug #38802 (max_redirects and ignore_errors). (patch by - datibbaw@php.net) -- Fixed bug #35980 (touch() works on files but not on directories). (Pierre) - -17 Jun 2009, PHP 5.2.10 -- Updated timezone database to version 2009.9 (2009i) (Derick) - -- Added "ignore_errors" option to http fopen wrapper. (David Zulke, Sara) -- Added new CURL options CURLOPT_REDIR_PROTOCOLS, CURLOPT_PROTOCOLS, - and CURLPROTO_* for redirect fixes in CURL 7.19.4. (Yoram Bar Haim, Stas) -- Added support for Sun CC (FR #46595 and FR #46513). (David Soria Parra) - -- Changed default value of array_unique()'s optional sorting type parameter - back to SORT_STRING to fix backwards compatibility breakage introduced in - PHP 5.2.9. (Moriyoshi) - -- Fixed memory corruptions while reading properties of zip files. (Ilia) -- Fixed memory leak in ob_get_clean/ob_get_flush. (Christian) -- Fixed segfault on invalid session.save_path. (Hannes) -- Fixed leaks in imap when a mail_criteria is used. (Pierre) -- Fixed missing erealloc() in fix for Bug #40091 in spl_autoload_register. (Greg) - -- Fixed bug #48562 (Reference recursion causes segfault when used in - wddx_serialize_vars()). (Felipe) -- Fixed bug #48557 (Numeric string keys in Apache Hashmaps are not cast to - integers). (David Zuelke) -- Fixed bug #48518 (curl crashes when writing into invalid file handle). (Tony) -- Fixed bug #48514 (cURL extension uses same resource name for simple and - multi APIs). (Felipe) -- Fixed bug #48469 (ldap_get_entries() leaks memory on empty search - results). (Patrick) -- Fixed bug #48456 (CPPFLAGS not restored properly in phpize.m4). (Jani, - spisek at kerio dot com) -- Fixed bug #48448 (Compile failure under IRIX 6.5.30 building cast.c). - (Kalle) -- Fixed bug #48441 (ldap_search() sizelimit, timelimit and deref options - persist). (Patrick) -- Fixed bug #48434 (Improve memory_get_usage() accuracy). (Arnaud) -- Fixed bug #48416 (Force a cache limit in ereg() to stop excessive memory - usage). (Scott) -- Fixed bug #48409 (Crash when exception is thrown while passing function - arguments). (Arnaud) -- Fixed bug #48378 (exif_read_data() segfaults on certain corrupted .jpeg - files). (Pierre) -- Fixed bug #48359 (Script hangs on snmprealwalk if OID is not increasing). - (Ilia, simonov at gmail dot com) -- Fixed bug #48336 (ReflectionProperty::getDeclaringClass() does not work - with redeclared property). - (patch by Markus dot Lidel at shadowconnect dot com) -- Fixed bug #48326 (constant MSG_DONTWAIT not defined). (Arnaud) -- Fixed bug #48313 (fgetcsv() does not return null for empty rows). (Ilia) -- Fixed bug #48309 (stream_copy_to_stream() and fpasstru() do not update - stream position of plain files). (Arnaud) -- Fixed bug #48307 (stream_copy_to_stream() copies 0 bytes when $source is a - socket). (Arnaud) -- Fixed bug #48273 (snmp*_real_walk() returns SNMP errors as values). - (Ilia, lytboris at gmail dot com) -- Fixed bug #48256 (Crash due to double-linking of history.o). - (tstarling at wikimedia dot org) -- Fixed bug #48248 (SIGSEGV when access to private property via &__get). - (Felipe) -- Fixed bug #48247 (Crash on errors during startup). (Stas) -- Fixed bug #48240 (DBA Segmentation fault dba_nextkey). (Felipe) -- Fixed bug #48224 (Incorrect shuffle in array_rand). (Etienne) -- Fixed bug #48221 (memory leak when passing invalid xslt parameter). - (Felipe) -- Fixed bug #48207 (CURLOPT_(FILE|WRITEHEADER options do not error out when - working with a non-writable stream). (Ilia) -- Fixed bug #48206 (Iterating over an invalid data structure with - RecursiveIteratorIterator leads to a segfault). (Scott) -- Fixed bug #48204 (xmlwriter_open_uri() does not emit warnings on invalid - paths). (Ilia) -- Fixed bug #48203 (Crash when CURLOPT_STDERR is set to regular file). (Jani) -- Fixed bug #48202 (Out of Memory error message when passing invalid file - path) (Pierre) -- Fixed bug #48156 (Added support for lcov v1.7). (Ilia) -- Fixed bug #48132 (configure check for curl ssl support fails with - --disable-rpath). (Jani) -- Fixed bug #48131 (Don't try to bind ipv4 addresses to ipv6 ips via bindto). - (Ilia) -- Fixed bug #48070 (PDO_OCI: Segfault when using persistent connection). - (Pierre, Matteo, jarismar dot php at gmail dot com) -- Fixed bug #48058 (Year formatter goes wrong with out-of-int range). (Derick) -- Fixed bug #48038 (odbc_execute changes variables used to form params array). - (Felipe) -- Fixed bug #47997 (stream_copy_to_stream returns 1 on empty streams). (Arnaud) -- Fixed bug #47991 (SSL streams fail if error stack contains items). (Mikko) -- Fixed bug #47981 (error handler not called regardless). (Hannes) -- Fixed bug #47969 (ezmlm_hash() returns different values depend on OS). (Ilia) -- Fixed bug #47946 (ImageConvolution overwrites background). (Ilia) -- Fixed bug #47940 (memory leaks in imap_body). (Pierre, Jake Levitt) -- Fixed bug #47937 (system() calls sapi_flush() regardless of output - buffering). (Ilia) -- Fixed bug #47903 ("@" operator does not work with string offsets). (Felipe) -- Fixed bug #47893 (CLI aborts on non blocking stdout). (Arnaud) -- Fixed bug #47849 (Non-deep import loses the namespace). (Rob) -- Fixed bug #47845 (PDO_Firebird omits first row from query). (Lars W) -- Fixed bug #47836 (array operator [] inconsistency when the array has - PHP_INT_MAX index value). (Matt) -- Fixed bug #47831 (Compile warning for strnlen() in main/spprintf.c). - (Ilia, rainer dot jung at kippdata dot de) -- Fixed bug #47828 (openssl_x509_parse() segfaults when a UTF-8 conversion - fails). (Scott, Kees Cook, Pierre) -- Fixed bug #47818 (Segfault due to bound callback param). (Felipe) -- Fixed bug #47801 (__call() accessed via parent:: operator is provided - incorrect method name). (Felipe) -- Fixed bug #47769 (Strange extends PDO). (Felipe) -- Fixed bug #47745 (FILTER_VALIDATE_INT doesn't allow minimum integer). - (Dmitry) -- Fixed bug #47721 (Alignment issues in mbstring and sysvshm extension). - (crrodriguez at opensuse dot org, Ilia) -- Fixed bug #47704 (PHP crashes on some "bad" operations with string - offsets). (Dmitry) -- Fixed bug #47695 (build error when xmlrpc and iconv are compiled against - different iconv versions). (Scott) -- Fixed bug #47667 (ZipArchive::OVERWRITE seems to have no effect). - (Mikko, Pierre) -- Fixed bug #47644 (Valid integers are truncated with json_decode()). (Scott) -- Fixed bug #47639 (pg_copy_from() WARNING: nonstandard use of \\ in a - string literal). (Ilia) -- Fixed bug #47616 (curl keeps crashing). (Felipe) -- Fixed bug #47598 (FILTER_VALIDATE_EMAIL is locale aware). (Ilia) -- Fixed bug #47566 (pcntl_wexitstatus() returns signed status). - (patch by james at jamesreno dot com) -- Fixed bug #47564 (unpacking unsigned long 32bit bit endian returns wrong - result). (Ilia) -- Fixed bug #47487 (performance degraded when reading large chunks after - fix of bug #44607). (Arnaud) -- Fixed bug #47468 (enable cli|cgi-only extensions for embed sapi). (Jani) -- Fixed bug #47435 (FILTER_FLAG_NO_PRIV_RANGE does not work with ipv6 - addresses in the filter extension). (Ilia) -- Fixed bug #47430 (Errors after writing to nodeValue parameter of an absent - previousSibling). (Rob) -- Fixed bug #47365 (ip2long() may allow some invalid values on certain 64bit - systems). (Ilia) -- Fixed bug #47254 (Wrong Reflection for extends class). (Felipe) -- Fixed bug #47042 (cgi sapi is incorrectly removing SCRIPT_FILENAME). - (Sriram Natarajan, David Soria Parra) -- Fixed bug #46882 (Serialize / Unserialize misbehaviour under OS with - different bit numbers). (Matt) -- Fixed bug #46812 (get_class_vars() does not include visible private variable - looking at subclass). (Arnaud) -- Fixed bug #46386 (Digest authentication with SOAP module fails against MSSQL - SOAP services). (Ilia, lordelph at gmail dot com) -- Fixed bug #46109 (Memory leak when mysqli::init() is called multiple times). - (Andrey) -- Fixed bug #45997 (safe_mode bypass with exec/system/passthru (windows only)). - (Pierre) -- Fixed bug #45877 (Array key '2147483647' left as string). (Matt) -- Fixed bug #45822 (Near infinite-loops while parsing huge relative offsets). - (Derick, Mike Sullivan) -- Fixed bug #45799 (imagepng() crashes on empty image). - (Martin McNickle, Takeshi Abe) -- Fixed bug #45622 (isset($arrayObject->p) misbehaves with - ArrayObject::ARRAY_AS_PROPS set). (robin_fernandes at uk dot ibm dot com, Arnaud) -- Fixed bug #45614 (ArrayIterator::current(), ::key() can show 1st private prop - of wrapped object). (robin_fernandes at uk dot ibm dot com, Arnaud) -- Fixed bug #45540 (stream_context_create creates bad http request). (Arnaud) -- Fixed bug #45202 (zlib.output_compression can not be set with ini_set()). - (Jani) -- Fixed bug #45191 (error_log ignores date.timezone php.ini val when setting - logging timestamps). (Derick) -- Fixed bug #45092 (header HTTP context option not being used when compiled - using --with-curlwrappers). (Jani) -- Fixed bug #44996 (xmlrpc_decode() ignores time zone on iso8601.datetime). - (Ilia, kawai at apache dot org) -- Fixed bug #44827 (define() is missing error checks for class constants). - (Ilia) -- Fixed bug #44214 (Crash using preg_replace_callback() and global variables). - (Nuno, Scott) -- Fixed bug #43073 (TrueType bounding box is wrong for angle<>0). - (Martin McNickle) -- Fixed bug #42663 (gzinflate() try to allocate all memory with truncated - data). (Arnaud) -- Fixed bug #42414 (some odbc_*() functions incompatible with Oracle ODBC - driver). (jhml at gmx dot net) -- Fixed bug #42362 (HTTP status codes 204 and 304 should not be gzipped). - (Scott, Edward Z. Yang) -- Fixed bug #42143 (The constant NAN is reported as 0 on Windows) - (Kanwaljeet Singla, Venkat Raman Don) -- Fixed bug #38805 (PDO truncates text from SQL Server text data type field). - (Steph) - -26 Feb 2009, PHP 5.2.9 -- Changed __call() to be invoked on private/protected method access, similar to - properties and __get(). (Andrei) - -- Added optional sorting type flag parameter to array_unique(). Default is - SORT_REGULAR. (Andrei) - -- Fixed a crash on extract in zip when files or directories entry names contain - a relative path. (Pierre) -- Fixed error conditions handling in stream_filter_append(). (Arnaud) -- Fixed zip filename property read. (Pierre) -- Fixed explode() behavior with empty string to respect negative limit. (Shire) -- Fixed security issue in imagerotate(), background colour isn't validated - correctly with a non truecolour image. Reported by Hamid Ebadi, - APA Laboratory (Fixes CVE-2008-5498). (Scott) -- Fixed a segfault when malformed string is passed to json_decode(). (Scott) -- Fixed bug in xml_error_string() which resulted in messages being - off by one. (Scott) - -- Fixed bug #47422 (modulus operator returns incorrect results on 64 bit - linux). (Matt) -- Fixed bug #47399 (mb_check_encoding() returns true for some illegal SJIS - characters). (for-bugs at hnw dot jp, Moriyoshi) -- Fixed bug #47353 (crash when creating a lot of objects in object - destructor). (Tony) -- Fixed bug #47322 (sscanf %d doesn't work). (Felipe) -- Fixed bug #47282 (FILTER_VALIDATE_EMAIL is marking valid email addresses - as invalid). (Ilia) -- Fixed bug #47220 (segfault in dom_document_parser in recovery mode). (Rob) -- Fixed bug #47217 (content-type is not set properly for file uploads). (Ilia) -- Fixed bug #47174 (base64_decode() interprets pad char in mid string as - terminator). (Ilia) -- Fixed bug #47165 (Possible memory corruption when passing return value by - reference). (Dmitry) -- Fixed bug #47152 (gzseek/fseek using SEEK_END produces strange results). - (Felipe) -- Fixed bug #47131 (SOAP Extension ignores "user_agent" ini setting). (Ilia) -- Fixed bug #47109 (Memory leak on $a->{"a"."b"} when $a is not an object). - (Etienne, Dmitry) -- Fixed bug #47104 (Linking shared extensions fails with icc). (Jani) -- Fixed bug #47049 (SoapClient::__soapCall causes a segmentation fault). - (Dmitry) -- Fixed bug #47048 (Segfault with new pg_meta_data). (Felipe) -- Fixed bug #47042 (PHP cgi sapi is removing SCRIPT_FILENAME for non - apache). (Sriram Natarajan) -- Fixed bug #47037 (No error when using fopen with empty string). (Cristian - Rodriguez R., Felipe) -- Fixed bug #47035 (dns_get_record returns a garbage byte at the end of a - TXT record). (Felipe) -- Fixed bug #47027 (var_export doesn't show numeric indices on ArrayObject). - (Derick) -- Fixed bug #46985 (OVERWRITE and binary mode does not work, regression - introduced in 5.2.8). (Pierre) -- Fixed bug #46973 (IPv6 address filter rejects valid address). (Felipe) -- Fixed bug #46964 (Fixed pdo_mysql build with older version of MySQL). (Ilia) -- Fixed bug #46959 (Unable to disable PCRE). (Scott) -- Fixed bug #46918 (imap_rfc822_parse_adrlist host part not filled in - correctly). (Felipe) -- Fixed bug #46889 (Memory leak in strtotime()). (Derick) -- Fixed bug #46887 (Invalid calls to php_error_docref()). (oeriksson at - mandriva dot com, Ilia) -- Fixed bug #46873 (extract($foo) crashes if $foo['foo'] exists). (Arnaud) -- Fixed bug #46843 (CP936 euro symbol is not converted properly). (ty_c at - cybozuy dot co dot jp, Moriyoshi) -- Fixed bug #46798 (Crash in mssql extension when retrieving a NULL value - inside a binary or image column type). (Ilia) -- Fixed bug #46782 (fastcgi.c parse error). (Matt) -- Fixed bug #46760 (SoapClient doRequest fails when proxy is used). (Felipe) -- Fixed bug #46748 (Segfault when an SSL error has more than one error). - (Scott) -- Fixed bug #46739 (array returned by curl_getinfo should contain - content_type key). (Mikko) -- Fixed bug #46699 (xml_parse crash when parser is namespace aware). (Rob) -- Fixed bug #46419 (Elements of associative arrays with NULL value are - lost). (Dmitry) -- Fixed bug #46282 (Corrupt DBF When Using DATE). (arne at bukkie dot nl) -- Fixed bug #46026 (bz2.decompress/zlib.inflate filter tries to decompress - after end of stream). (Greg) -- Fixed bug #46005 (User not consistently logged under Apache2). (admorten - at umich dot edu, Stas) -- Fixed bug #45996 (libxml2 2.7 causes breakage with character data in - xml_parse()). (Rob) -- Fixed bug #45940 (MySQLI OO does not populate connect_error property on - failed connect). (Johannes) -- Fixed bug #45923 (mb_st[r]ripos() offset not handled correctly). (Moriyoshi) -- Fixed bug #45327 (memory leak if offsetGet throws exception). (Greg) -- Fixed bug #45239 (Encoding detector hangs with mbstring.strict_detection - enabled). (Moriyoshi) -- Fixed bug #45161 (Reusing a curl handle leaks memory). (Mark Karpeles, Jani) -- Fixed bug #44336 (Improve pcre UTF-8 string matching performance). (frode - at coretrek dot com, Nuno) -- Fixed bug #43841 (mb_strrpos() offset is byte count for negative values). - (Moriyoshi) -- Fixed bug #37209 (mssql_execute with non fatal errors). (Kalle) -- Fixed bug #35975 (Session cookie expires date format isn't the most - compatible. Now matches that of setcookie()). (Scott) - - -08 Dec 2008, PHP 5.2.8 -- Reverted bug fix #42718 that broke magic_quotes_gpc (Scott) - -04 Dec 2008, PHP 5.2.7 -- Upgraded PCRE to version 7.8 (Fixes CVE-2008-2371). (Ilia) -- Updated timezone database to version 2008.9. (Derick) -- Upgraded bundled libzip to 0.9.0. (Pierre) - -- Added logging option for error_log to send directly to SAPI. (Stas) -- Added PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, - PHP_EXTRA_VERSION, PHP_VERSION_ID, PHP_ZTS and PHP_DEBUG constants. (Pierre) -- Added "PHP_INI_SCAN_DIR" environment variable which can be used to - either disable or change the compile time ini scan directory (FR #45114). - (Jani) - -- Fixed missing initialization of BG(page_uid) and BG(page_gid), - reported by Maksymilian Arciemowicz. (Stas) -- Fixed memory leak inside sqlite_create_aggregate(). (Felipe) -- Fixed memory leak inside PDO sqlite's sqliteCreateAggregate() method. - (Felipe) -- Fixed a crash inside gd with invalid fonts (Fixes CVE-2008-3658). (Pierre) -- Fixed a possible overflow inside memnstr (Fixes CVE-2008-3659). - (LaurentGaffie) -- Fixed incorrect php_value order for Apache configuration, reported by - Maksymilian Arciemowicz. (Stas) -- Fixed memory leak inside readline_callback_handler_remove() function. - (Felipe) -- Fixed sybase_fetch_*() to continue reading after CS_ROW_FAIL status (Timm) -- Fixed a bug inside dba_replace() that could cause file truncation - withinvalid keys. (Ilia) -- Fixed memory leak inside readline_callback_handler_install() function.(Ilia) -- Fixed memory leak inside readline_completion_function() function. (Felipe) -- Fixed stream_get_contents() when using $maxlength and socket is notclosed. - indeyets [at] php [dot] net on #46049. (Arnaud) -- Fixed stream_get_line() to behave as documented on non-blocking streams. - (Arnaud) -- Fixed endless loop in PDOStatement::debugDumpParams(). - (jonah.harris at gmail dot com) -- Fixed ability to use "internal" heaps in extensions. (Arnaud, Dmitry) -- Fixed weekdays adding/subtracting algorithm. (Derick) -- Fixed some ambiguities in the date parser. (Derick) -- Fixed a bug with the YYYY-MM format not resetting the day correctly. - (Derick) -- Fixed a bug in the DateTime->modify() methods, it would not use the advanced - relative time strings. (Derick) -- Fixed extraction of zip files or directories when the entry name is a - relative path. (Pierre) -- Fixed read or write errors for large zip archives. (Pierre) -- Fixed security issues detailed in CVE-2008-2665 and CVE-2008-2666. - (Christian Hoffmann) -- Fixed simplexml asXML() not to lose encoding when dumping entire - document to file. (Ilia) -- Fixed a crash inside PDO when trying instantiate PDORow manually. - (Felipe) -- Fixed build failure of ext/mysqli with libmysql 6.0 - missing - rplfunctions. (Andrey) -- Fixed a regression when using strip_tags() and < is within an - attribute.(Scott) -- Fixed a crash on invalid method in ReflectionParameter constructor. - (Christian Seiler) -- Reverted fix for bug #44197 due to behaviour change in minor version. - (Felipe) - -- Fixed bug #46732 (mktime.year description is wrong). (Derick) -- Fixed bug #46696 (cURL fails in upload files with specified content-type). - (Ilia) -- Fixed bug #46673 (stream_lock call with wrong parameter). (Arnaud) -- Fixed bug #46649 (Setting array element with that same array produces - inconsistent results). (Arnaud) -- Fixed bug #46626 (mb_convert_case does not handle apostrophe correctly). - (Ilia) -- Fixed bug #46543 (ibase_trans() memory leaks when using wrong parameters). - (Felipe) -- Fixed bug #46521 (Curl ZTS OpenSSL, error in config.m4 fragment). - (jd at cpanel dot net) -- Fixed bug #46496 (wddx_serialize treats input as ISO-8859-1). (Mark Karpeles) -- Fixed bug #46427 (SoapClient() stumbles over its "stream_context" parameter). - (Dmitry, Herman Radtke) -- Fixed bug #46426 (offset parameter of stream_get_contents() does not - workfor "0"). (Felipe) -- Fixed bug #46406 (Unregistering nodeclass throws E_FATAL). (Rob) -- Fixed bug #46389 (NetWare needs small patch for _timezone). - (patch by guenter@php.net) -- Fixed bug #46388 (stream_notification_callback inside of object destroys - object variables). (Felipe) -- Fixed bug #46381 (wrong $this passed to internal methods causes segfault). - (Tony) -- Fixed bug #46379 (Infinite loop when parsing '#' in one line file). (Arnaud) -- Fixed bug #46366 (bad cwd with / as pathinfo). (Dmitry) -- Fixed bug #46360 (TCP_NODELAY constant for socket_{get,set}_option). - (bugs at trick dot vanstaveren dot us) -- Fixed bug #46343 (IPv6 address filter accepts invalid address). (Ilia) -- Fixed bug #46335 (DOMText::splitText doesn't handle multibyte characters). - (Rob) -- Fixed bug #46323 (compilation of simplexml for NetWare breaks). - (Patch by guenter [at] php [dot] net) -- Fixed bug #46319 (PHP sets default Content-Type header for HTTP 304 - response code, in cgi sapi). (Ilia) -- Fixed bug #46313 (Magic quotes broke $_FILES). (Arnaud) -- Fixed bug #46308 (Invalid write when changing property from inside getter). - (Dmitry) -- Fixed bug #46292 (PDO::setFetchMode() shouldn't requires the 2nd arg when - using FETCH_CLASSTYPE). (Felipe) -- Fixed bug #46274, #46249 (pdo_pgsql always fill in NULL for empty BLOB and - segfaults when returned by SELECT). (Felipe) -- Fixed bug #46271 (local_cert option is not resolved to full path). (Ilia) -- Fixed bug #46247 (ibase_set_event_handler() is allowing to pass callback - without event). (Felipe) -- Fixed bug #46246 (difference between call_user_func(array($this, $method)) - and $this->$method()). (Dmitry) -- Fixed bug #46222 (ArrayObject EG(uninitialized_var_ptr) overwrite). - (Etienne) -- Fixed bug #46215 (json_encode mutates its parameter and has some - class-specific state). (Felipe) -- Fixed bug #46206 (pg_query_params/pg_execute convert passed values to - strings). (Ilia) -- Fixed bug #46191 (BC break: DOMDocument saveXML() doesn't accept null). - (Rob) -- Fixed bug #46164 (stream_filter_remove() closes the stream). (Arnaud) -- Fixed bug #46157 (PDOStatement::fetchObject prototype error). (Felipe) -- Fixed bug #46147 (after stream seek, appending stream filter reads - incorrect data). (Greg) -- Fixed bug #46139 (PDOStatement->setFetchMode() forgets FETCH_PROPS_LATE). - (chsc at peytz dot dk, Felipe) -- Fixed bug #46127 (php_openssl_tcp_sockop_accept forgets to set context - on accepted stream) (Mark Karpeles, Pierre) -- Fixed bug #46110 (XMLWriter - openmemory() and openuri() leak memory on - multiple calls). (Ilia) -- Fixed bug #46088 (RegexIterator::accept - segfault). (Felipe) -- Fixed bug #46082 (stream_set_blocking() can cause a crash in some - circumstances). (Felipe) -- Fixed bug #46064 (Exception when creating ReflectionProperty object - on dynamicly created property). (Felipe) -- Fixed bug #46059 (Compile failure under IRIX 6.5.30 building posix.c). - (Arnaud) -- Fixed bug #46053 (SplFileObject::seek - Endless loop). (Arnaud) -- Fixed bug #46051 (SplFileInfo::openFile - memory overlap). (Arnaud) -- Fixed bug #46047 (SimpleXML converts empty nodes into object with - nested array). (Rob) -- Fixed bug #46031 (Segfault in AppendIterator::next). (Arnaud) -- Fixed bug #46029 (Segfault in DOMText when using with Reflection). (Rob) -- Fixed bug #46026 (bzip2.decompress/zlib.inflate filter tries to decompress - after end of stream). (Keisial at gmail dot com, Greg) -- Fixed bug #46024 (stream_select() doesn't return the correct number). - (Arnaud) -- Fixed bug #46010 (warnings incorrectly generated for iv in ecb mode). - (Felipe) -- Fixed bug #46003 (isset on nonexisting node return unexpected results). (Rob) -- Fixed bug #45956 (parse_ini_file() does not return false with syntax errors - in parsed file). (Jani) -- Fixed bug #45901 (wddx_serialize_value crash with SimpleXMLElement object). - (Rob) -- Fixed bug #45862 (get_class_vars is inconsistent with 'protected' and - 'private' variables). (ilewis at uk dot ibm dot com, Felipe) -- Fixed bug #45860 (header() function fails to correctly replace all Status - lines). (Dmitry) -- Fixed bug #45805 (Crash on throwing exception from error handler). (Dmitry) -- Fixed bug #45765 (ReflectionObject with default parameters of self::xxx cause - an error). (Felipe) -- Fixed bug #45751 (Using auto_prepend_file crashes (out of scope stack address - use)). (basant dot kukreja at sun dot com) -- Fixed bug #45722 (mb_check_encoding() crashes). (Moriyoshi) -- Fixed bug #45705 (rfc822_parse_adrlist() modifies passed address parameter). - (Jani) -- Fixed bug #45691 (Some per-dir or runtime settings may leak into other - requests). (Moriyoshi) -- Fixed bug #45581 (htmlspecialchars() double encoding &#x hex items). (Arnaud) -- Fixed bug #45580 (levenshtein() crashes with invalid argument). (Ilia) -- Fixed bug #45575 (Segfault with invalid non-string as event handler callback). - (Christian Seiler) -- Fixed bug #45568 (ISAPI doesn't properly clear auth_digest in header). - (Patch by: navara at emclient dot com) -- Fixed bug #45556 (Return value from callback isn't freed). (Felipe) -- Fixed bug #45555 (Segfault with invalid non-string as - register_introspection_callback). (Christian Seiler) -- Fixed bug #45553 (Using XPath to return values for attributes with a - namespace does not work). (Rob) -- Fixed bug #45529 (new DateTimeZone() and date_create()->getTimezone() behave - different). (Derick) -- Fixed bug #45522 (FCGI_GET_VALUES request does not return supplied values). - (Arnaud) -- Fixed bug #45486 (mb_send_mail(); header 'Content-Type: text/plain; charset=' - parsing incorrect). (Felipe) -- Fixed bug #45485 (strip_tags and ). (Dmitry) -- Fixed bug #43668 (Added odbc.default_cursortype to control the ODBCcursor - model). (Patrick) -- Fixed bug #43666 (Fixed code to use ODBC 3.52 datatypes for 64bit - systems). (Patrick) -- Fixed bug #43540 (rfc1867 handler newlength problem). (Arnaud) -- Fixed bug #43452 (strings containing a weekday, or a number plus weekday - behaved incorrect of the current day-of-week was the same as the one in the - phrase). (Derick) -- Fixed bug #43353 (wrong detection of 'data' wrapper causes notice). - (gk at gknw dot de, Arnaud) -- Fixed bug #43053 (Regression: some numbers shown in scientific notation). - (int-e at gmx dot de) -- Fixed bug #43045 (SOAP encoding violation on "INF" for type double/float). - (Dmitry) -- Fixed bug #42862 (IMAP toolkit crash: rfc822.c legacy routine buffer - overflow). (Fixes CVE-2008-2829) (Dmitry) -- Fixed bug #42855 (dns_get_record() doesn't return all text from TXT record). - (a dot u dot savchuk at gmail dot com) -- Fixed bug #42737 (preg_split('//u') triggers a E_NOTICE with newlines). - (Nuno) -- Fixed bug #42718 (FILTER_UNSAFE_RAW not applied when configured as default - filter). (Arnaud) -- Fixed bug #42604 ("make test" fails with --with-config-file-scan-dir=path). - (Jani) -- Fixed bug #42473 (ob_start php://output and headers). (Arnaud) -- Fixed bug #42318 (problem with nm on AIX, not finding object files). - (Dmitry) -- Fixed bug #42294 (Unified solution for round() based on C99 round). (Ilia) -- Fixed bug #42078 (pg_meta_data mix tables metadata from different schemas). - (Felipe) -- Fixed bug #41348 (OCI8: allow compilation with Oracle 8.1). (Chris Jones) -- Fixed bug #41033 (enable signing with DSA keys. - (gordyf at google dot com, Pierre) -- Fixed bug #37100 (data is returned truncated with BINARY CURSOR). (Tony) -- Fixed bug #30312 (crash in sybase_unbuffered_query() function). (Timm) -- Fixed bug #24679 (pg_* functions doesn't work using schema). (Felipe) -- Fixed bug #14962 (PECL) (::extractTo 2nd argument is not really optional) - (Mark van Der Velden) -- Fixed bug #14032 (Mail() always returns false but mail is sent). (Mikko) - - -01 May 2008, PHP 5.2.6 -- Fixed two possible crashes inside posix extension (Tony) -- Fixed incorrect heredoc handling when label is used within the block. - (Matt) -- Fixed possible stack buffer overflow in FastCGI SAPI. (Andrei Nigmatulin) -- Fixed sending of uninitialized paddings which may contain some information. (Andrei Nigmatulin) -- Fixed a bug in formatting timestamps when DST is active in the default timezone (Derick) -- Properly address incomplete multibyte chars inside escapeshellcmd() (Ilia, Stefan Esser) -- Fix integer overflow in printf(). (Stas, Maksymilian Aciemowicz) -- Fixed security issue detailed in CVE-2008-0599. (Rasmus) -- Fixed potential memleak in stream filter parameter for zlib filter. (Greg) -- Added Reflection API metadata for the methods of the DOM classes. (Sebastian) -- Fixed weird behavior in CGI parameter parsing. (Dmitry, Hannes Magnusson) -- Fixed a safe_mode bypass in cURL identified by Maksymilian Arciemowicz. - (Ilia) -- Fixed a bug with PDO::FETCH_COLUMN|PDO::FETCH_GROUP mode when a column # by - which to group by data is specified. (Ilia) -- Fixed segfault in filter extension when using callbacks. (Arnar Mar Sig, - Felipe) -- Fixed faulty fix for bug #40189 (endless loop in zlib.inflate stream filter). (Greg) -- Upgraded PCRE to version 7.6 (Nuno) - -- Fixed bug #44742 (timezone_offset_get() causes segmentation faults). (Derick) -- Fixed bug #44720 (Prevent crash within session_register()). (Scott) -- Fixed bug #44703 (htmlspecialchars() does not detect bad character set argument). (Andy Wharmby) -- Fixed bug #44673 (With CGI argv/argc starts from arguments, not from script) (Dmitry) -- Fixed bug #44667 (proc_open() does not handle pipes with the mode 'wb' correctly). (Jani) -- Fixed bug #44663 (Crash in imap_mail_compose if "body" parameter invalid). (Ilia) -- Fixed bug #44650 (escaepshellscmd() does not check arg count). (Ilia) -- Fixed bug #44613 (Crash inside imap_headerinfo()). (Ilia, jmessa) -- Fixed bug #44603 (Order issues with Content-Type/Length headers on POST). (Ilia) -- Fixed bug #44594 (imap_open() does not validate # of retries parameter). (Ilia) -- Fixed bug #44591 (imagegif's filename parameter). (Felipe) -- Fixed bug #44557 (Crash in imap_setacl when supplied integer as username) (Thomas Jarosch) -- Fixed bug #44487 (call_user_method_array issues a warning when throwing an exception). (David Soria Parra) -- Fixed bug #44478 (Inconsistent behaviour when assigning new nodes). (Rob, Felipe) -- Fixed bug #44445 (email validator does not handle domains starting/ending with a -). (Ilia) -- Fixed bug #44440 (st_blocks undefined under BeOS). (Felipe) -- Fixed bug #44394 (Last two bytes missing from output). (Felipe) -- Fixed bug #44388 (Crash inside exif_read_data() on invalid images) (Ilia) -- Fixed bug #44373 (PDO_OCI extension compile failed). (Felipe) -- Fixed bug #44333 (SEGFAULT when using mysql_pconnect() with client_flags). (Felipe) -- Fixed bug #44306 (Better detection of MIPS processors on Windows). (Ilia) -- Fixed bug #44242 (metaphone('CMXFXM') crashes PHP). (Felipe) -- Fixed bug #44233 (MSG_PEEK undefined under BeOS R5). (jonathonfreeman at gmail dot com, Ilia) -- Fixed bug #44216 (strftime segfaults on large negative value). (Derick) -- Fixed bug #44209 (strtotime() doesn't support 64 bit timestamps on 64 bit platforms). (Derick) -- Fixed bug #44206 (OCI8 selecting ref cursors leads to ORA-1000 maximum open cursors reached). (Oracle Corp.) -- Fixed bug #44200 (A crash in PDO when no bound targets exists and yet bound parameters are present). (Ilia) -- Fixed bug #44197 (socket array keys lost on socket_select). (Felipe) -- Fixed bug #44191 (preg_grep messes up array index). (Felipe) -- Fixed bug #44189 (PDO setAttribute() does not properly validate values for native numeric options). (Ilia) -- Fixed bug #44184 (Double free of loop-variable on exception). (Dmitry) -- Fixed bug #44171 (Invalid FETCH_COLUMN index does not raise an error). (Ilia) -- Fixed bug #44166 (Parameter handling flaw in PDO::getAvailableDrivers()). (Ilia) -- Fixed bug #44159 (Crash: $pdo->setAttribute(PDO::STATEMENT_ATTR_CLASS, NULL)). (Felipe) -- Fixed bug #44152 (Possible crash with syslog logging on ZTS builds). (Ilia) -- Fixed bug #44141 (private parent constructor callable through static function). (Dmitry) -- Fixed bug #44113 (OCI8 new collection creation can fail with OCI-22303). (Oracle Corp.) -- Fixed bug #44069 (Huge memory usage with concatenation using . instead of .=). (Dmitry) -- Fixed bug #44046 (crash inside array_slice() function with an invalid by-ref offset). (Ilia) -- Fixed bug #44028 (crash inside stream_socket_enable_crypto() when enabling encryption without crypto type). (Ilia) -- Fixed bug #44018 (RecursiveDirectoryIterator options inconsistancy). (Marcus) -- Fixed bug #44008 (OCI8 incorrect usage of OCI-Lob->close crashes PHP). (Oracle Corp.) -- Fixed bug #43998 (Two error messages returned for incorrect encoding for mb_strto[upper|lower]). (Rui) -- Fixed bug #43994 (mb_ereg 'successfully' matching incorrect). (Rui) -- Fixed bug #43954 (Memory leak when sending the same HTTP status code multiple times). (Scott) -- Fixed bug #43927 (koi8r is missing from html_entity_decode()). (andy at demos dot su, Tony) -- Fixed bug #43912 (Interbase column names are truncated to 31 characters). (Ilia) -- Fixed bug #43875 (Two error messages returned for $new and $flag argument in mysql_connect()). (Hannes) -- Fixed bug #43863 (str_word_count() breaks on cyrillic "ya" in locale cp1251). (phprus at gmail dot com, Tony) -- Fixed bug #43841 (mb_strrpos offset is byte count for negative values). (Rui) -- Fixed bug #43840 (mb_strpos bounds check is byte count rather than a character count). (Rui) -- Fixed bug #43808 (date_create never fails (even when it should)). (Derick) -- Fixed bug #43793 (zlib filter is unable to auto-detect gzip/zlib file headers). (Greg) -- Fixed bug #43703 (Signature compatibility check broken). (Dmitry) -- Fixed bug #43677 (Inconsistent behaviour of include_path set with php_value). (manuel at mausz dot at) -- Fixed bug #43663 (Extending PDO class with a __call() function doesn't work). (David Soria Parra) -- Fixed bug #43647 (Make FindFile use PATH_SEPARATOR instead of ";"). (Ilia) -- Fixed bug #43635 (mysql extension ingores INI settings on NULL values passed to mysql_connect()). (Ilia) -- Fixed bug #43620 (Workaround for a bug inside libcurl 7.16.2 that can result in a crash). (Ilia) -- Fixed bug #43614 (incorrect processing of numerical string keys of array in arbitrary serialized data). (Dmitriy Buldakov, Felipe) -- Fixed bug #43606 (define missing depencies of the exif extension). (crrodriguez at suse dot de) -- Fixed bug #43589 (a possible infinite loop in bz2_filter.c). (Greg) -- Fixed bug #43580 (removed bogus declaration of a non-existent php_is_url() function). (Ilia) -- Fixed bug #43559 (array_merge_recursive() doesn't behave as expected with duplicate NULL values). (Felipe, Tony) -- Fixed bug #43533 (escapeshellarg('') returns null). (Ilia) -- Fixed bug #43527 (DateTime created from a timestamp reports environment timezone). (Derick) -- Fixed bug #43522 (stream_get_line() eats additional characters). (Felipe, Ilia, Tony) -- Fixed bug #43507 (SOAPFault HTTP Status 500 - would like to be able to set the HTTP Status). (Dmitry) -- Fixed bug #43505 (Assign by reference bug). (Dmitry) -- Fixed bug #43498 (file_exists() on a proftpd server got SIZE not allowed in ASCII mode). (Ilia, crrodriguez at suse dot de) -- Fixed bug #43497 (OCI8 XML/getClobVal aka temporary LOBs leak UGA memory). (Chris) -- Fixed bug #43495 (array_merge_recursive() crashes with recursive arrays). (Ilia) -- Fixed bug #43493 (pdo_pgsql does not send username on connect when password is not available). (Ilia) -- Fixed bug #43491 (Under certain conditions, file_exists() never returns). (Dmitry) -- Fixed bug #43483 (get_class_methods() does not list all visible methods). (Dmitry) -- Fixed bug #43482 (array_pad() does not warn on very small pad numbers). (Ilia) -- Fixed bug #43457 (Prepared statement with incorrect parms doesn't throw exception with pdo_pgsql driver). (Ilia) -- Fixed bug #43450 (Memory leak on some functions with implicit object __toString() call). (David C.) -- Fixed bug #43386 (array_globals not reset to 0 properly on init). (Ilia) -- Fixed bug #43377 (PHP crashes with invalid argument for DateTimeZone). (Ilia) -- Fixed bug #43373 (pcntl_fork() should not raise E_ERROR on error). (Ilia) -- Fixed bug #43364 (recursive xincludes don't remove internal xml nodes properly). (Rob, patch from ddb@bitxtender.de) -- Fixed bug #43301 (mb_ereg*_replace() crashes when replacement string is invalid PHP expression and 'e' option is used). (Jani) -- Fixed bug #43295 (crash because of uninitialized SG(sapi_headers).mimetype). (Dmitry) -- Fixed bug #43293 (Multiple segfaults in getopt()). (Hannes) -- Fixed bug #43279 (pg_send_query_params() converts all elements in 'params' to strings). (Ilia) -- Fixed bug #43276 (Incomplete fix for bug #42739, mkdir() under safe_mode). (Ilia) -- Fixed bug #43248 (backward compatibility break in realpath()). (Dmitry) -- Fixed bug #43221 (SimpleXML adding default namespace in addAttribute). (Rob) -- Fixed bug #43216 (stream_is_local() returns false on "file://"). (Dmitry) -- Fixed bug #43201 (Crash on using uninitialized vals and __get/__set). (Dmitry) -- Fixed bug #43182 (file_put_contents() LOCK_EX does not work properly on file truncation). (Ilia) -- Fixed bug #43175 (__destruct() throwing an exception with __call() causes segfault). (Dmitry) -- Fixed bug #43128 (Very long class name causes segfault). (Dmitry) -- Fixed bug #43105 (PHP seems to fail to close open files). (Hannes) -- Fixed bug #43092 (curl_copy_handle() crashes with > 32 chars long URL). (Jani) -- Fixed bug #43003 (Invalid timezone reported for DateTime objects constructed using a timestamp). (Derick) -- Fixed bug #42978 (mismatch between number of bound params and values causes a crash in pdo_pgsql). (Ilia) -- Fixed bug #42945 (preg_split() swallows part of the string). (Nuno) -- Fixed bug #42937 (__call() method not invoked when methods are called on parent from child class). (Dmitry) -- Fixed bug #42841 (REF CURSOR and oci_new_cursor() crash PHP). (Chris) -- Fixed bug #42838 (Wrong results in array_diff_uassoc) (Felipe) -- Fixed bug #42779 (Incorrect forcing from HTTP/1.0 request to HTTP/1.1 response). (Ilia) -- Fixed bug #42736 (xmlrpc_server_call_method() crashes). (Tony) -- Fixed bug #42692 (Procedure 'int1' not present with doc/lit SoapServer). (Dmitry) -- Fixed bug #42548 (mysqli PROCEDURE calls can't return result sets). (Hartmut) -- Fixed bug #42505 (new sendmail default breaks on Netware platform) (Guenter Knauf) -- Fixed bug #42369 (Implicit conversion to string leaks memory). (David C., Rob). -- Fixed bug #42272 (var_export() incorrectly escapes char(0)). (Derick) -- Fixed bug #42261 (Incorrect lengths for date and boolean data types). (Ilia) -- Fixed bug #42190 (Constructing DateTime with TimeZone Indicator invalidates DateTimeZone). (Derick) -- Fixed bug #42177 (Warning "array_merge_recursive(): recursion detected" comes again...). (Felipe) -- Fixed bug #41941 (oci8 extension not lib64 savvy). (Chris) -- Fixed bug #41828 (Failing to call RecursiveIteratorIterator::__construct() causes a sefault). (Etienne) -- Fixed bug #41599 (setTime() fails after modify() is used). (Derick) -- Fixed bug #41562 (SimpleXML memory issue). (Rob) -- Fixed bug #40013 (php_uname() does not return nodename on Netware (Guenter Knauf) -- Fixed bug #38468 (Unexpected creation of cycle). (Dmitry) -- Fixed bug #32979 (OpenSSL stream->fd casts broken in 64-bit build) (stotty at tvnet dot hu) - -08 Nov 2007, PHP 5.2.5 -- Upgraded PCRE to version 7.3 (Nuno) -- Added optional parameter $provide_object to debug_backtrace(). (Sebastian) -- Added alpha support for imagefilter() IMG_FILTER_COLORIZE. (Pierre) -- Added ability to control memory consumption between request using - ZEND_MM_COMPACT environment variable. (Dmitry) - -- Improved speed of array_intersect_key(), array_intersect_assoc(), - array_uintersect_assoc(), array_diff_key(), array_diff_assoc() and - array_udiff_assoc(). (Dmitry) - -- Fixed move_uploaded_file() to always set file permissions of resulting file - according to UMASK. (Andrew Sitnikov) -- Fixed possible crash in ext/soap because of uninitialized value. (Zdash Urf) -- Fixed regression in glob() when enforcing safe_mode/open_basedir checks on - paths containing '*'. (Ilia) -- Fixed "mail.force_extra_parameters" php.ini directive not to be modifiable - in .htaccess due to the security implications - reported by SecurityReason. - (Stas) -- Fixed PDO crash when driver returns empty LOB stream. (Stas) -- Fixed dl() to only accept filenames - reported by Laurent Gaffie. (Stas) -- Fixed dl() to limit argument size to MAXPATHLEN (CVE-2007-4887). - (Christian Hoffmann) -- Fixed iconv_*() functions to limit argument sizes as workaround to libc - bug (CVE-2007-4783, CVE-2007-4840 by Laurent Gaffie). - (Christian Hoffmann, Stas) -- Fixed missing brackets leading to build warning and error in the log. - Win32 code. (Andrey) -- Fixed leaks with multiple connects on one mysqli object. (Andrey) -- Fixed endianness detection on MacOS when building universal binary. - (Uwe Schindler, Christian Speich, Tony) -- Fixed possible triggering of buffer overflows inside glibc - implementations of the fnmatch(), setlocale() and glob() functions. - Reported by Laurent Gaffie. (Ilia) -- Fixed imagerectangle regression with 1x1 rectangle (libgd #106). (Pierre) -- Fixed htmlentities/htmlspecialchars not to accept partial multibyte - sequences. (Stas) - -- Fixed bug #43196 (array_intersect_assoc() crashes with non-array input). - (Jani) -- Fixed bug #43139 (PDO ignores ATTR_DEFAULT_FETCH_MODE in some cases with - fetchAll()). (Ilia) -- Fixed bug #43137 (rmdir() and rename() do not clear statcache). (Jani) -- Fixed bug #43130 (Bound parameters cannot have - in their name). (Ilia) -- Fixed bug #43099 (XMLWriter::endElement() does not check # of params). - (Ilia) -- Fixed bug #43020 (Warning message is missing with shuffle() and more - than one argument). (Scott) -- Fixed bug #42976 (Crash when constructor for newInstance() or - newInstanceArgs() fails) (Ilia) -- Fixed bug #42943 (ext/mssql: Move *timeout initialization from RINIT - to connect time). (Ilia) -- Fixed bug #42917 (PDO::FETCH_KEY_PAIR doesn't work with setFetchMode). - (Ilia) -- Fixed bug #42890 (Constant "LIST" defined by mysqlclient and c-client). - (Andrey) -- Fixed bug #42869 (automatic session id insertion adds sessions id to - non-local forms). (Ilia) -- Fixed bug #42818 ($foo = clone(array()); leaks memory). (Dmitry) -- Fixed bug #42817 (clone() on a non-object does not result in a fatal - error). (Ilia) -- Fixed bug #42785 (json_encode() formats doubles according to locale rather - then following standard syntax). (Ilia) -- Fixed bug #42783 (pg_insert() does not accept an empty list for - insertion). (Ilia) -- Fixed bug #42773 (WSDL error causes HTTP 500 Response). (Dmitry) -- Fixed bug #42772 (Storing $this in a static var fails while handling a cast - to string). (Dmitry) -- Fixed bug #42767 (highlight_string() truncates trailing comment). (Ilia) -- Fixed bug #42739 (mkdir() doesn't like a trailing slash when safe_mode is - enabled). (Ilia) -- Fixed bug #42703 (Exception raised in an iterator::current() causes segfault - in FilterIterator) (Marcus) -- Fixed bug #42699 (PHP_SELF duplicates path). (Dmitry) -- Fixed bug #42654 (RecursiveIteratorIterator modifies only part of leaves) - (Marcus) -- Fixed bug #42643 (CLI segfaults if using ATTR_PERSISTENT). (Ilia) -- Fixed bug #42637 (SoapFault : Only http and https are allowed). (Bill Moran) -- Fixed bug #42629 (Dynamically loaded PHP extensions need symbols exported - on MacOSX). (jdolecek at NetBSD dot org) -- Fixed bug #42627 (bz2 extension fails to build with -fno-common). - (dolecek at netbsd dot org) -- Fixed Bug #42596 (session.save_path MODE option does not work). (Ilia) -- Fixed bug #42590 (Make the engine recognize \v and \f escape sequences). - (Ilia) -- Fixed bug #42587 (behavior change regarding symlinked .php files). (Dmitry) -- Fixed bug #42579 (apache_reset_timeout() does not exist). (Jani) -- Fixed bug #42549 (ext/mysql failed to compile with libmysql 3.23). (Scott) -- Fixed bug #42523 (PHP_SELF duplicates path). (Dmitry) -- Fixed bug #42512 (ip2long('255.255.255.255') should return 4294967295 on - 64-bit PHP). (Derick) -- Fixed bug #42506 (php_pgsql_convert() timezone parse bug) (nonunnet at - gmail dot com, Ilia) -- Fixed bug #42496 (OCI8 cursor is not closed when using 2 clobs in a select - query). (Oracle Corp.) -- Fixed bug #42462 (Segmentation when trying to set an attribute in a - DOMElement). (Rob) -- Fixed bug #42453 (CGI SAPI does not shut down cleanly with -i/-m/-v cmdline - options). (Dmitry) -- Fixed bug #42452 (PDO classes do not expose Reflection API information). - (Hannes) -- Fixed bug #42468 (Write lock on file_get_contents fails when using a - compression stream). (Ilia) -- Fixed bug #42488 (SoapServer reports an encoding error and the error itself - breaks). (Dmitry) -- Fixed bug #42378 (mysqli_stmt_bind_result memory exhaustion). (Andrey) -- Fixed bug #42359 (xsd:list type not parsed). (Dmitry) -- Fixed bug #42326 (SoapServer crash). (Dmitry) -- Fixed bug #42214 (SoapServer sends clients internal PHP errors). (Dmitry) -- Fixed bug #42189 (xmlrpc_set_type() crashes php on invalid datetime - values). (Ilia) -- Fixed bug #42139 (XMLReader option constants are broken using XML()). (Rob) -- Fixed bug #42086 (SoapServer return Procedure '' not present for WSIBasic - compliant wsdl). (Dmitry) -- Fixed bug #41822 (Relative includes broken when getcwd() fails). (Ab5602, - Jani) -- Fixed bug #41561 (Values set with php_admin_* in httpd.conf can be overwritten - with ini_set()). (Stas, Jani) -- Fixed bug #39651 (proc_open() append mode doesn't work on windows). (Nuno) - -30 Aug 2007, PHP 5.2.4 -- Removed --enable-versioning configure option. (Jani) - -- Upgraded PCRE to version 7.2 (Nuno) -- Updated timezone database to version 2007.6. (Derick) - -- Improved openssl_x509_parse() to return extensions in readable form. (Dmitry) - -- Enabled changing the size of statement cache for non-persistent OCI8 - connections. (Chris Jones, Tony) - -- Changed "display_errors" php.ini option to accept "stderr" as value which - makes the error messages to be outputted to STDERR instead of STDOUT with - CGI and CLI SAPIs (FR #22839). (Jani) -- Changed error handler to send HTTP 500 instead of blank page on PHP errors. - (Dmitry, Andrei Nigmatulin) -- Changed mail() function to be always available. (Johannes) - -- Added check for unknown options passed to configure. (Jani) -- Added persistent connection status checker to pdo_pgsql. - (Elvis Pranskevichus, Ilia) -- Added support for ATTR_TIMEOUT inside pdo_pgsql driver. (Ilia) -- Added php_ini_loaded_file() function which returns the path to the actual - php.ini in use. (Jani) -- Added GD version constants GD_MAJOR_VERSION, GD_MINOR_VERSION, - GD_RELEASE_VERSION, GD_EXTRA_VERSION and GD_VERSION_STRING. (Pierre) -- Added missing open_basedir checks to CGI. - (anight at eyelinkmedia dot com, Tony) -- Added missing format validator to unpack() function. (Ilia) -- Added missing error check inside bcpowmod(). (Ilia) -- Added CURLOPT_PRIVATE & CURLINFO_PRIVATE constants. - (Andrey A. Belashkov, Tony) -- Added missing MSG_EOR and MSG_EOF constants to sockets extension. (Jani) -- Added PCRE_VERSION constant. (Tony) -- Added ReflectionExtension::info() function to print the phpinfo() - block for an extension. (Johannes) - -- Implemented FR #41884 (ReflectionClass::getDefaultProperties() does not - handle static attributes). (Tony) - -- Fixed "Floating point exception" inside wordwrap(). - (Mattias Bengtsson, Ilia) -- Fixed several integer overflows in ImageCreate(), ImageCreateTrueColor(), - ImageCopyResampled() and ImageFilledPolygon() reported by Mattias Bengtsson. - (Tony) -- Fixed size calculation in chunk_split(). (Stas) -- Fixed integer overflow in str[c]spn(). (Stas) -- Fixed money_format() not to accept multiple %i or %n tokens. - (Stas, Ilia) -- Fixed zend_alter_ini_entry() memory_limit interruption - vulnerability. (Ilia) -- Fixed INFILE LOCAL option handling with MySQL extensions not to be - allowed when open_basedir or safe_mode is active. (Stas) -- Fixed session.save_path and error_log values to be checked against - open_basedir and safe_mode (CVE-2007-3378) (Stas, Maksymilian Arciemowicz) -- Fixed possible invalid read in glob() win32 implementation (CVE-2007-3806). - (Tony) -- Improved fix for MOPB-03-2007. (Ilia) -- Corrected fix for CVE-2007-2872. (Ilia) - -- Fixed possible crash in imagepsloadfont(), work around a bug in the pslib on - Windows. (Pierre) -- Fixed oci8 and PDO_OCI extensions to allow configuring with Oracle 11g - client libraries. (Chris Jones) -- Fixed EOF handling in case of reading from file opened in write only mode. - (Dmitry) -- Fixed var_export() to use the new H modifier so that it can generate - parseable PHP code for floats, independent of the locale. (Derick) -- Fixed regression introduced by the fix for the libgd bug #74. (Pierre) -- Fixed SimpleXML's behavior when used with empty(). (Sara) -- Fixed crash in OpenSSL extension because of non-string passphrase. (Dmitry) - -- Fixed PECL Bug #11345 (PDO_OCI crash after National language Support "NLS" - environment initialization error). (Chris Jones) -- Fixed PECL bug #11216 (crash in ZipArchive::addEmptyDir when a directory - already exists). (Pierre) - -- Fixed bug #43926 (isInstance() isn't equivalent to instanceof operator). (Marcus) -- Fixed bug #42368 (Incorrect error message displayed by pg_escape_string). - (Ilia) -- Fixed bug #42365 (glob() crashes and/or accepts way too many flags). - (Jani) -- Fixed Bug #42364 (Crash when using getRealPath with DirectoryIterator). - (Johannes) -- Fixed bug #42292 ($PHP_CONFIG not set for phpized builds). (Jani) -- Fixed bug #42261 (header wrong for date field). - (roberto at spadim dot com dot br, Ilia) -- Fixed bug #42259 (SimpleXMLIterator loses ancestry). (Rob) -- Fixed bug #42247 (ldap_parse_result() not defined under win32). (Jani) -- Fixed bug #42243 (copy() does not output an error when the first arg is a - dir). (Ilia) -- Fixed bug #42242 (sybase_connect() crashes). (Ilia) -- Fixed bug #42237 (stream_copy_to_stream returns invalid values for mmaped - streams). (andrew dot minerd at sellingsource dot com, Ilia) -- Fixed bug #42233 (Problems with æøå in extract()). (Jani) -- Fixed bug #42222 (possible buffer overflow in php_openssl_make_REQ). (Pierre) -- Fixed bug #42211 (property_exists() fails to find protected properties - from a parent class). (Dmitry) -- Fixed bug #42208 (substr_replace() crashes when the same array is passed - more than once). (crrodriguez at suse dot de, Ilia) -- Fixed bug #42198 (SCRIPT_NAME and PHP_SELF truncated when inside a userdir - and using PATH_INFO). (Dmitry) -- Fixed bug #42195 (C++ compiler required always). (Jani) -- Fixed bug #42183 (classmap causes crash in non-wsdl mode). (Dmitry) -- Fixed bug #42173 (oci8 INTERVAL and TIMESTAMP type fixes). (Chris) -- Fixed bug #42151 (__destruct functions not called after catching a SoapFault - exception). (Dmitry) -- Fixed bug #42142 (substr_replace() returns FALSE when length > string length). - (Ilia) -- Fixed bug #42135 (Second call of session_start() causes creation of SID). - (Ilia) -- Fixed bug #42134 (oci_error() returns false after oci_new_collection() fails). - (Tony) -- Fixed bug #42119 (array_push($arr,&$obj) doesn't work with - zend.ze1_compatibility_mode On). (Dmitry) -- Fixed bug #42117 (bzip2.compress loses data in internal buffer). - (Philip, Ilia) -- Fixed bug #42112 (deleting a node produces memory corruption). (Rob) -- Fixed bug #42107 (sscanf broken when using %2$s format parameters). (Jani) -- Fixed bug #42090 (json_decode causes segmentation fault). (Hannes) -- Fixed bug #42082 (NodeList length zero should be empty). (Hannes) -- Fixed bug #42072 (No warning message for clearstatcache() with arguments). - (Ilia) -- Fixed bug #42071 (ini scanner allows using NULL as option name). (Jani) -- Fixed bug #42027 (is_file() / is_dir() matches file/dirnames with wildcard char - or trailing slash in Windows). (Dmitry) -- Fixed bug #42019 (configure option --with-adabas=DIR does not work). (Jani) -- Fixed bug #42015 (ldap_rename(): server error "DSA is unwilling to perform"). - (bob at mroczka dot com, Jani) -- Fixed bug #42009 (is_a() and is_subclass_of() should NOT call autoload, in the - same way as "instanceof" operator). (Dmitry) -- Fixed bug #41989 (move_uploaded_file() & relative path in ZTS mode). (Tony) -- Fixed bug #41984 (Hangs on large SoapClient requests). (Dmitry) -- Fixed bug #41983 (Error Fetching http headers terminated by '\n'). (Dmitry) -- Fixed bug #41973 (--with-ldap=shared fails with LDFLAGS="-Wl,--as-needed"). (Nuno) -- Fixed bug #41971 (PDOStatement::fetch and PDOStatement::setFetchMode causes - unexpected behavior). (Ilia) -- Fixed bug #41964 (strtotime returns a timestamp for non-time string of - pattern '(A|a) .+'). (Derick) -- Fixed bug #41961 (Ensure search for hidden private methods does not stray from - class hierarchy). (robin_fernandes at uk dot ibm dot com) -- Fixed bug #41947 (SimpleXML incorrectly registers empty strings asnamespaces). - (Rob) -- Fixed bug #41929 (Foreach on object does not iterate over all visible properties). - (Dmitry) -- Fixed bug #41919 (crash in string to array conversion). - (judas dot iscariote at gmail dot com, Ilia) -- Fixed bug #41909 (var_export() is locale sensitive when exporting float - values). (Derick) -- Fixed bug #41908 (CFLAGS="-Os" ./configure --enable-debug fails). - (christian at hoffie dot info, Tony) -- Fixed bug #41904 (proc_open(): empty env array should cause empty environment - to be passed to process). (Jani) -- Fixed bug #41867 (SimpleXML: getName is broken). (Rob) -- Fixed bug #41865 (fputcsv(): 2nd parameter is not optional). (Jani) -- Fixed bug #41861 (SimpleXML: getNamespaces() returns the namespaces of a node's - siblings). (Rob) -- Fixed bug #41845 (pgsql extension does not compile with PostgreSQL <7.4). (Ilia) -- Fixed bug #41844 (Format returns incorrect number of digits for negative years - -0001 to -0999). (Derick) -- Fixed bug #41842 (Cannot create years < 0100 & negative years with date_create - or new DateTime). (Derick) -- Fixed bug #41833 (addChild() on a non-existent node, no node created, - getName() segfaults). (Rob) -- Fixed bug #41831 (pdo_sqlite prepared statements convert resources to - strings). (Ilia) -- Fixed bug #41815 (Concurrent read/write fails when EOF is reached). (Sascha) -- Fixed bug #41813 (segmentation fault when using string offset as an object). - (judas dot iscariote at gmail dot com, Tony) -- Fixed bug #41795 (checkdnsrr does not support DNS_TXT type). - (lucas at facebook dot com, Tony) -- Fixed bug #41773 (php_strip_whitespace() sends headers with errors - suppressed). (Tony) -- Fixed bug #41770 (SSL: fatal protocol error due to buffer issues). (Ilia) -- Fixed bug #41765 (Recode crashes/does not work on amd64). - (nexus at smoula dot net, Stas) -- Fixed bug #41724 (libxml_get_last_error() - errors service request scope). - (thekid at php dot net, Ilia) -- Fixed bug #41717 (imagepolygon does not respect thickness). (Pierre) -- Fixed bug #41713 (Persistent memory consumption on win32 since 5.2). (Dmitry) -- Fixed bug #41711 (NULL temporary lobs not supported in OCI8). - (Chris Jones, Tony) -- Fixed bug #41709 (strtotime() does not handle 00.00.0000). (Derick) -- Fixed bug #41698 (float parameters truncated to integer in prepared - statements). (Ilia) -- Fixed bug #41692 (ArrayObject shows weird behavior in respect to - inheritance). (Tony) -- Fixed bug #41691 (ArrayObject::exchangeArray hangs Apache). (Tony) -- Fixed bug #41686 (Omitting length param in array_slice not possible). (Ilia) -- Fixed bug #41685 (array_push() fails to warn when next index is - already occupied). (Ilia) -- Fixed bug #41655 (open_basedir bypass via glob()). (Ilia) -- Fixed bug #41640 (get_class_vars produces error on class constants). - (Johannes) -- Fixed bug #41635 (SoapServer and zlib.output_compression with FastCGI - result in major slowdown). (Dmitry) -- Fixed bug #41633 (Crash instantiating classes with self-referencing - constants). (Dmitry) -- Fixed bug #41630 (segfault when an invalid color index is present in the - image data). (Reported by Elliot ) (Pierre) -- Fixed bug #41628 (PHP settings leak between Virtual Hosts in Apache 1.3). - (Scott, manuel at mausz dot at) -- Fixed bug #41608 (segfault on a weird code with objects and switch()). - (Tony) -- Fixed bug #41600 (url rewriter tags doesn't work with namespaced tags). - (Ilia) -- Fixed bug #41596 (Fixed a crash inside pdo_pgsql on some non-well-formed - SQL queries). (Ilia) -- Fixed bug #41594 (OCI8 statement cache is flushed too frequently). (Tony) -- Fixed bug #41582 (SimpleXML crashes when accessing newly created element). - (Tony) -- Fixed bug #41576 (configure failure when using --without-apxs or some other - SAPIs disabling options). (Jani) -- Fixed bug #41567 (json_encode() double conversion is inconsistent with PHP). - (Lucas, Ilia) -- Fixed bug #41566 (SOAP Server not properly generating href attributes). - (Dmitry) -- Fixed bug #41555 (configure failure: regression caused by fix for #41265). - (Jani) -- Fixed bug #41527 (WDDX deserialize numeric string array key). - (Matt, Ilia) -- Fixed bug #41523 (strtotime('0000-00-00 00:00:00') is parsed as 1999-11-30). - (Derick) -- Fixed bug #41518 (file_exists() warns of open_basedir restriction on - non-existent file). (Tony) -- Fixed bug #41445 (parse_ini_file() has a problem with certain types of - integer as sections). (Tony) -- Fixed bug #41433 (DBA: configure fails to include correct db.h for db4). - (Jani) -- Fixed bug #41372 (Internal pointer of source array resets during array - copying). (Dmitry) -- Fixed bug #41350 (my_thread_global_end() error during request shutdown on - Windows). (Scott, Andrey) -- Fixed bug #41278 (get_loaded_extensions() should list Zend extensions). - (Johannes) -- Fixed bug #41127 (Memory leak in ldap_{first|next}_attribute functions). - (Jani) -- Fixed bug #40757 (get_object_vars get nothing in child class). (Dmitry) -- Fixed bug #40705 (Iterating within function moves original array pointer). - (Dmitry) -- Fixed bug #40509 (key() function changed behaviour if global array is used - within function). (Dmitry) -- Fixed bug #40419 (Trailing slash in CGI request does not work). (Dmitry) -- Fixed bug #39330 (apache2handler does not call shutdown actions before - apache child die). (isk at ecommerce dot com, Gopal, Tony) -- Fixed bug #39291 (ldap_sasl_bind() misses the sasl_authc_id parameter). - (diafour at gmail dot com, Jani) -- Fixed bug #37715 (array pointers resetting on copy). (Dmitry) -- Fixed bug #37273 (Symlinks and mod_files session handler allow open_basedir - bypass). (Ilia) -- Fixed bug #36492 (Userfilters can leak buckets). (Sara) -- Fixed bugs #36796, #36918, #41371 (stream_set_blocking() does not work). - (Jani) -- Fixed bug #35981 (pdo-pgsql should not use pkg-config when not present). - (Jani) -- Fixed bug #31892 (PHP_SELF incorrect without cgi.fix_pathinfo, but turning on - screws up PATH_INFO). (Dmitry) -- Fixed bug #21197 (socket_read() outputs error with PHP_NORMAL_READ). - (Nuno, Jani) - -31 May 2007, PHP 5.2.3 -- Changed CGI install target to php-cgi and 'make install' to install CLI - when CGI is selected. (Jani) -- Changed JSON maximum nesting depth from 20 to 128. (Rasmus) - -- Improved compilation of heredocs and interpolated strings. (Matt, Dmitry) -- Optimized out a couple of per-request syscalls. (Rasmus) -- Optimized digest generation in md5() and sha1() functions. (Ilia) -- Upgraded bundled SQLite 3 to version 3.3.17. (Ilia) - -- Added "max_input_nesting_level" php.ini option to limit nesting level of - input variables. Fix for MOPB-03-2007. (Stas) -- Added a 4th parameter flag to htmlspecialchars() and htmlentities() that - makes the function not encode existing html entities. (Ilia) -- Added PDO::FETCH_KEY_PAIR mode that will fetch a 2 column result set into - an associated array. (Ilia) -- Added CURLOPT_TIMEOUT_MS and CURLOPT_CONNECTTIMEOUT_MS cURL constants. (Sara) -- Added --ini switch to CLI that prints out configuration file names. (Marcus) -- Added mysql_set_charset() to allow runtime altering of connection encoding. - (Scott) - -- Implemented FR #41416 (getColumnMeta() should also return table name). (Tony) - -- Fixed an integer overflow inside chunk_split(). Identified by Gerhard Wagner. - (Ilia) -- Fixed SOAP extension's handler() to work even when - "always_populate_raw_post_data" is off. (Ilia) -- Fixed possible infinite loop in imagecreatefrompng. (libgd #86) - (by Xavier Roche, CVE-2007-2756). (Pierre) -- Fixed ext/filter Email Validation Vulnerability (MOPB-45 by Stefan Esser). - (Ilia) -- Fixed altering $this via argument named "this". (Dmitry) -- Fixed PHP CLI usage of php.ini from the binary location. (Hannes) -- Fixed segfault in strripos(). (Tony, Joxean Koret) -- Fixed bug #41693 (scandir() allows empty directory names). (Ilia) -- Fixed bug #41673 (json_encode breaks large numbers in arrays). (Ilia) -- Fixed bug #41525 (ReflectionParameter::getPosition() not available). (Marcus) -- Fixed bug #41511 (Compile failure under IRIX 6.5.30 building md5.c). (Jani) -- Fixed bug #41504 (json_decode() incorrectly decodes JSON arrays with empty - string keys). (Ilia) -- Fixed bug #41492 (open_basedir/safe_mode bypass inside realpath()). (Ilia) -- Fixed bug #41477 (no arginfo about SoapClient::__soapCall()). (Ilia) -- Fixed bug #41455 (ext/dba/config.m4 pollutes global $LIBS and $LDFLAGS). - (mmarek at suse dot cz, Tony) -- Fixed bug #41442 (imagegd2() under output control). (Tony) -- Fixed bug #41430 (Fatal error with negative values of maxlen parameter of - file_get_contents()). (Tony) -- Fixed bug #41423 (PHP assumes wrongly that certain ciphers are enabled in - OpenSSL). (Pierre) -- Fixed bug #41421 (Uncaught exception from a stream wrapper segfaults). - (Tony, Dmitry) -- Fixed bug #41403 (json_decode cannot decode floats if localeconv - decimal_point is not '.'). (Tony) -- Fixed bug #41401 (wrong unary operator precedence). (Stas) -- Fixed bug #41394 (dbase_create creates file with corrupted header). (Tony) -- Fixed bug #41390 (Clarify error message with invalid protocol scheme). - (Scott) -- Fixed bug #41378 (fastcgi protocol lacks support for Reason-Phrase in - "Status:" header). (anight at eyelinkmedia dot com, Dmitry) -- Fixed bug #41374 (whole text concats values of wrong nodes). (Rob) -- Fixed bug #41358 (configure cannot determine SSL lib with libcurl >= 7.16.2). - (Mike) -- Fixed bug #41353 (crash in openssl_pkcs12_read() on invalid input). (Ilia) -- Fixed bug #41351 (Invalid opcode with foreach ($a[] as $b)). (Dmitry, Tony) -- Fixed bug #41347 (checkdnsrr() segfaults on empty hostname). (Scott) -- Fixed bug #41337 (WSDL parsing doesn't ignore non soap bindings). (Dmitry) -- Fixed bug #41326 (Writing empty tags with Xmlwriter::WriteElement[ns]) - (Pierre) -- Fixed bug #41321 (downgrade read errors in getimagesize() to E_NOTICE). - (Ilia) -- Fixed bug #41304 (compress.zlib temp files left). (Dmitry) -- Fixed bug #41293 (Fixed creation of HTTP_RAW_POST_DATA when there is no - default post handler). (Ilia) -- Fixed bug #41291 (FastCGI does not set SO_REUSEADDR). - (fmajid at kefta dot com, Dmitry) -- Fixed gd build when used with freetype 1.x (Pierre, Tony) -- Fixed bug #41287 (Namespace functions don't allow xmlns definition to be - optional). (Rob) -- Fixed bug #41285 (Improved fix for CVE-2007-1887 to work with non-bundled - sqlite2 lib). (Ilia) -- Fixed bug #41283 (Bug with deserializing array key that are doubles or - floats in wddx). (Ilia) -- Fixed bug #41257 (lookupNamespaceURI does not work as expected). (Rob) -- Fixed bug #41236 (Regression in timeout handling of non-blocking SSL - connections during reads and writes). (Ilia) -- Fixed bug #41134 (zend_ts_hash_clean not thread-safe). - (marco dot cova at gmail dot com, Tony) -- Fixed bug #41097 (ext/soap returning associative array as indexed without - using WSDL). (Dmitry) -- Fixed bug #41004 (minOccurs="0" and null class member variable). (Dmitry) -- Fixed bug #39542 (Behavior of require/include different to < 5.2.0). - (Dmitry) - -03 May 2007, PHP 5.2.2 -- Improved bundled GD - . Sync to 2.0.35 - . Added imagegrabwindow and imagegrabscreen, capture a screen or a - window using its handle (Pierre) - . colors allocated henceforth from the resulting image overwrite the palette - colors (Rob Leslie) - . Improved thread safety of the gif support (Roman Nemecek, Nuno, Pierre) - . Use the dimension of the GIF frame to create the destination image (Pierre) - . Load only once the local color map from a GIF data (Pierre) - . Improved thread safety of the freetype cache (Scott MacVicar, Nuno, Pierre) - . imagearc huge CPU usage with large angles, libgd bug #74 (Pierre) -- Improved FastCGI SAPI to support external pipe and socket servers on win32. - (Dmitry) -- Improved Zend Memory Manager - . guarantee of reasonable time for worst cases of best-fit free block - searching algorithm. (Dmitry) - . better cache usage and less fragmentation on erealloc() (Tony, Dmitry) -- Improved SPL (Marcus) - . Added SplFileInfo::getBasename(), DirectoryIterator::getBasename(). - . Added SplFileInfo::getLinkTarget(), SplFileInfo::getRealPath(). - . Made RecursiveFilterIterator::accept() abstract as stated in documentation. -- Improved SOAP - . Added ability to encode arrays with "SOAP-ENC:Array" type instead of WSDL - type. To activate the ability use "feature"=>SOAP_USE_XSI_ARRAY_TYPE - option in SoapClient/SoapServer constructors. (Rob, Dmitry) - -- Added GMP_VERSION constant. (Tony) -- Added --ri switch to CLI which allows to check extension information. (Marcus) -- Added tidyNode::getParent() method (John, Nuno) -- Added openbasedir and safemode checks in zip:// stream wrapper and - ZipArchive::open (Pierre) -- Added php_pdo_sqlite_external.dll, a version of the PDO SQLite driver that - links against an external sqlite3.dll. This provides Windows users to upgrade - their sqlite3 version outside of the PHP release cycle. (Wez, Edin) -- Added linenumbers to array returned by token_get_all(). (Johannes) - -- Upgraded SQLite 3 to version 3.3.16 (Ilia) -- Upgraded libraries bundled in the Windows distribution. (Edin) - . c-client (imap) to version 2006e - . libpq (PostgreSQL) to version 8.2.3 - . libmysql (MySQL) to version 5.0.37 - . openssl to version 0.9.8e -- Upgraded PCRE to version 7.0 (Nuno) - -- Updated timezone database to version 2007.5. (Derick) - -- Fixed commandline handling for CLI and CGI. (Marcus, Johannes) -- Fixed iterator_apply() with a callback using __call(). (Johannes) -- Fixed possible multi bytes issues in openssl csr parser (Pierre) -- Fixed shmop_open() with IPC_CREAT|IPC_EXCL flags on Windows. - (Vladimir Kamaev, Tony). -- Fixed possible leak in ZipArchive::extractTo when safemode checks fails (Ilia) -- Fixed possible relative path issues in zip_open and TS mode (old API) (Pierre) -- Fixed zend_llist_remove_tail (Michael Wallner, Dmitry) -- Fixed a thread safety issue in gd gif read code (Nuno, Roman Nemecek) -- Fixed CVE-2007-1001, GD wbmp used with invalid image size (Pierre) -- Fixed unallocated memory access/double free in in array_user_key_compare() - (MOPB-24 by Stefan Esser) (Stas) -- Fixed wrong length calculation in unserialize S type - (MOPB-29 by Stefan Esser) (Stas) - -- Fixed bug #41215 (setAttribute return code reversed). (Ilia) -- Fixed bug #41192 (Per Directory Values only work for one key). (Dmitry) -- Fixed bug #41175 (addAttribute() fails to add an attribute with an empty - value). (Ilia) -- Fixed bug #41159 (mysql_pconnect() hash does not account for connect - flags). (Ilia) -- Fixed bug #41121 (range() overflow handling for large numbers on 32bit - machines). (Ilia) -- Fixed bug #41118 (PHP does not handle overflow of octal integers). (Tony) -- Fixed bug #41109 (recursiveiterator.inc says "implements" Iterator instead of - "extends"). (Marcus) -- Fixed bug #40130 (TTF usage doesn't work properly under Netware). (Scott, - gk at gknw dot de) -- Fixed bug #41093 (magic_quotes_gpc ignores first arrays keys). (Arpad, Ilia) -- Fixed bug #41075 (memleak when creating default object caused exception). - (Dmitry) -- Fixed bug #41067 (json_encode() problem with UTF-16 input). (jp at df5ea - dot net. Ilia) -- Fixed bug #41063 (chdir doesn't like root paths). (Dmitry) -- Fixed bug #41061 ("visibility error" in ReflectionFunction::export()). - (Johannes) -- Fixed bug #41043 (pdo_oci crash when freeing error text with persistent - connection). (Tony) -- Fixed bug #41037 (unregister_tick_function() inside the tick function crash PHP). - (Tony) -- Fixed bug #41034 (json_encode() ignores null byte started keys in arrays). - (Ilia) -- Fixed bug #41026 (segfault when calling "self::method()" in shutdown functions). - (Tony) -- Fixed bug #40999 (mcrypt_create_iv() not using random seed). (Ilia) -- Fixed bug #40998 (long session array keys are truncated). (Tony) -- Implement feature request #40947, allow a single filter as argument - for filter_var_array (Pierre) -- Fixed bug #40935 (pdo_mysql does not raise an exception on empty - fetchAll()). (Ilia) -- Fixed bug #40931 (open_basedir bypass via symlink and move_uploaded_file()). - (Tony) -- Fixed bug #40921 (php_default_post_reader crashes when post_max_size is - exceeded). (trickie at gmail dot com, Ilia) -- Fixed bug #40915 (addcslashes unexpected behavior with binary input). (Tony) -- Fixed bug #40899 (memory leak when nesting list()). (Dmitry) -- Fixed bug #40897 (error_log file not locked). (Ilia) -- Fixed bug #40883 (mysql_query() is allocating memory incorrectly). (Tony) -- Fixed bug #40872 (inconsistency in offsetSet, offsetExists treatment of - string enclosed integers). (Marcus) -- Fixed bug #40861 (strtotime() doesn't handle double negative relative time - units correctly). (Derick, Ilia) -- Fixed bug #40854 (imap_mail_compose() creates an invalid terminator for - multipart e-mails). (Ilia) -- Fixed bug #40848 (sorting issue on 64-bit Solaris). (Wez) -- Fixed bug #40836 (Segfault in ext/dom). (Rob) -- Fixed bug #40833 (Crash when using unset() on an ArrayAccess object retrieved - via __get()). (Dmitry) -- Fixed bug #40822 (pdo_mysql does not return rowCount() on select). (Ilia) -- Fixed bug #40815 (using strings like "class::func" and static methods in - set_exception_handler() might result in crash). (Tony) -- Fixed bug #40809 (Poor performance of ".="). (Dmitry) -- Fixed bug #40805 (Failure executing function ibase_execute()). (Tony) -- Fixed bug #40800 (cannot disable memory_limit with -1). (Dmitry, Tony) -- Fixed bug #40794 (ReflectionObject::getValues() may crash when used with - dynamic properties). (Tony) -- Fixed bug #40784 (Case sensitivity in constructor's fallback). (Tony) -- Fixed bug #40770 (Apache child exits when PHP memory limit reached). (Dmitry) -- Fixed bug #40764 (line thickness not respected for horizontal and vertical - lines). (Pierre) -- Fixed bug #40758 (Test fcgi_is_fastcgi() is wrong on windows). (Dmitry) -- Fixed bug #40754 (added substr() & substr_replace() overflow checks). (Ilia) -- Fixed bug #40752 (parse_ini_file() segfaults when a scalar setting is - redeclared as an array). (Tony) -- Fixed bug #40750 (openssl stream wrapper ignores default_stream_timeout). - (Tony) -- Fixed bug #40727 (segfault in PDO when failed to bind parameters). (Tony) -- Fixed bug #40709 (array_reduce() behaves strange with one item stored arrays). - (Ilia) -- Fixed bug #40703 (Resolved a possible namespace conflict between libxmlrpc - and MySQL's NDB table handler). (Ilia) -- Fixed bug #40961 (Incorrect results of DateTime equality check). (Mike) -- Fixed bug #40678 (Cross compilation fails). (Tony) -- Fixed bug #40621 (Crash when constructor called inappropriately). (Tony) -- Fixed bug #40609 (Segfaults when using more than one SoapVar in a request). - (Rob, Dmitry) -- Fixed bug #40606 (umask is not being restored when request is finished). - (Tony) -- Fixed bug #40598 (libxml segfault). (Rob) -- Fixed bug #40591 (list()="string"; gives invalid opcode). (Dmitry) -- Fixed bug #40578 (imagettftext() multithreading issue). (Tony, Pierre) -- Fixed bug #40576 (double values are truncated to 6 decimal digits when - encoding). (Tony) -- Fixed bug #40560 (DIR functions do not work on root UNC path). (Dmitry) -- Fixed bug #40548 (SplFileInfo::getOwner/getGroup give a warning on broken - symlink). (Marcus) -- Fixed bug #40546 (SplFileInfo::getPathInfo() throws an exception if directory - is in root dir). (Marcus) -- Fixed bug #40545 (multithreading issue in zend_strtod()). (Tony) -- Fixed bug #40503 (json_encode() value corruption on 32bit systems with - overflown values). (Ilia) -- Fixed bug #40467 (Partial SOAP request sent when XSD sequence or choice - include minOccurs=0). (Dmitry) -- Fixed bug #40465 (Ensure that all PHP elements are printed by var_dump). - (wharmby at uk dot ibm dot com, Ilia) -- Fixed bug #40464 (session.save_path wont use default-value when safe_mode - or open_basedir is enabled). (Ilia) -- Fixed bug #40455 (proc_open() uses wrong command line when safe_mode_exec_dir - is set). (Tony) -- Fixed bug #40432 (strip_tags() fails with greater than in attribute). (Ilia) -- Fixed bug #40431 (dynamic properties may cause crash in ReflectionProperty - methods). (Tony) -- Fixed bug #40451 (addAttribute() may crash when used with non-existent child - node). (Tony) -- Fixed bug #40442 (ArrayObject::offsetExists broke in 5.2.1, works in 5.2.0). - (olivier at elma dot fr, Marcus) -- Fixed bug #40428 (imagepstext() doesn't accept optional parameter). (Pierre) -- Fixed bug #40417 (Allow multiple instances of the same named PDO token in - prepared statement emulation code). (Ilia) -- Fixed bug #40414 (possible endless fork() loop when running fastcgi). - (Dmitry) -- Fixed bug #40410 (ext/posix does not compile on MacOS 10.3.9). (Tony) -- Fixed bug #40392 (memory leaks in PHP milter SAPI). - (tuxracer69 at gmail dot com, Tony) -- Fixed bug #40371 (pg_client_encoding() not working on Windows). (Edin) -- Fixed bug #40352 (FCGI_WEB_SERVER_ADDRS function get lost). (Dmitry) -- Fixed bug #40290 (strtotime() returns unexpected result with particular - timezone offset). (Derick) -- Fixed bug #40286 (PHP fastcgi with PHP_FCGI_CHILDREN don't kill children when - parent is killed). (Dmitry) -- Fixed bug #40261 (Extremely slow data handling due to memory fragmentation). - (Dmitry) -- Fixed bug #40236 (php -a function allocation eats memory). (Dmitry) -- Fixed bug #40109 (iptcembed fails on non-jfif jpegs). (Tony) -- Fixed bug #39965 (Latitude and longitude are backwards in date_sun_info()). - (Derick) -- Implement #39867 (openssl PKCS#12 support) (Marc Delling, Pierre) -- Fixed bug #39836 (SplObjectStorage empty after unserialize). (Marcus) -- Fixed bug #39416 (Milliseconds in date()). (Derick) -- Fixed bug #39396 (stream_set_blocking crashes on Win32). (Ilia, maurice at - iceblog dot de) -- Fixed bug #39351 (relative include fails on Solaris). (Dmitry, Tony) -- Fixed bug #39322 (proc_terminate() destroys process resource). (Nuno) -- Fixed bug #38406 (crash when assigning objects to SimpleXML attributes). (Tony) -- Fixed bug #37799 (ftp_ssl_connect() falls back to non-ssl connection). (Nuno) -- Fixed bug #36496 (SSL support in imap_open() not working on Windows). (Edin) -- Fixed bug #36226 (Inconsistent handling when passing nillable arrays). - (Dmitry) -- Fixed bug #35872 (Avoid crash caused by object store being referenced during - RSHUTDOWN). (Andy) -- Fixed bug #34794 (proc_close() hangs when used with two processes). - (jdolecek at netbsd dot org, Nuno) -- Fixed PECL bug #10194 (crash in Oracle client when memory limit reached in - the callback). (Tony) -- Fixed substr_compare and substr_count information leak (MOPB-14) (Stas, Ilia) -- Fixed crash on op-assign where argument is string offset (Brian, Stas) -- Fixed bug #38710 (data leakage because of nonexisting boundary checking in - statements in mysqli) (Stas) -- Fixed bug #37386 (autocreating element doesn't assign value to first node). - (Rob) -- Fixed bug #37013 (server hangs when returning circular object references). - (Dmitry) -- Fixed bug #33664 Console window appears when using exec() - (Richard Quadling, Stas) - - -08 Feb 2007, PHP 5.2.1 -- Added read-timeout context option "timeout" for HTTP streams. (Hannes, Ilia). -- Added CURLOPT_TCP_NODELAY constant to Curl extension. (Sara) -- Added support for hex numbers of any size. (Matt) -- Added function stream_socket_shutdown(). It is a wrapper for system - shutdown() function, that shut downs part of a full-duplex connection. - (Dmitry) -- Added internal heap protection (Dmitry) - . memory-limit is always enabled (--enable-memory-limit removed) - . default value if memory-limit is set to 128M - . safe unlinking - . cookies - . canary protection (debug build only) - . random generation of cookies and canaries -- Added forward support for 'b' prefix in front of string literals. (Andrei) -- Added three new functions to ext/xmlwriter (Rob, Ilia) - . xmlwriter_start_dtd_entity() - . xmlwriter_end_dtd_entity() - . xmlwriter_write_dtd_entity() -- Added a meta tag to phpinfo() output to prevent search engines from indexing - the page. (Ilia) -- Added new function, sys_get_temp_dir(). (Hartmut) -- Added missing object support to file_put_contents(). (Ilia) -- Added support for md2, ripemd256 and ripemd320 algos to hash(). (Sara) -- Added forward support for (binary) cast. (Derick) -- Added optimization for imageline with horizontal and vertical lines (Pierre) - -- Removed dependency from SHELL32.DLL. (Dmitry) -- Removed double "wrong parameter count" warnings in various functions. - (Hannes) -- Moved extensions to PECL: - . ext/informix (Derick, Tony) - -- Changed double-to-string utilities to use BSD implementation. (Dmitry, Tony) -- Updated bundled libcURL to version 7.16.0 in the Windows distro. (Edin) -- Updated timezone database to version 2006.16. (Derick) -- cgi.* and fastcgi.* directives are moved to INI subsystem. The new directive - cgi.check_shebang_line can be used to omitting check for "#! /usr/bin/php" - line. (Dmitry). -- Improved proc_open(). Now on Windows it can run external commands not - through CMD.EXE. (Dmitry) -- VCWD_REALPATH() is improved to use realpath cache without VIRTUAL_DIR. - (Dmitry) -- ext/bcmath initialization code is moved from request startup to module - startup. (Dmitry) -- Zend Memory Manager Improvements (Dmitry) - . use HeapAlloc() instead of VirtualAlloc() - . use "win32" storage manager (instead of "malloc") on Windows by default -- Zip Extension Improvements (Pierre) - . Fixed leak in statName and stateIndex - . Fixed return setComment (Hannes) - . Added addEmptyDir method -- Filter Extension Improvements (Ilia, Pierre) - . Fixed a bug when callback function returns a non-modified value. - . Added filter support for $_SERVER in cgi/apache2 sapis. - . Make sure PHP_SELF is filtered in Apache 1 sapi. - . Fixed bug #39358 (INSTALL_HEADERS contains incorrect reference to - php_filter.h). - . Added "default" option that allows a default value to be set for an - invalid or missing value. - . Invalid filters fails instead of returning unsafe value - . Fixed possible double encoding problem with sanitizing filters - . Make use of space-strict strip_tags() function - . Fixed whitespace trimming - . Added support for FastCGI environment variables. (Dmitry) -- PDO_MySQL Extension Improvements (Ilia) - . Enabled buffered queries by default. - . Enabled prepared statement emulation by default. - -- Small optimization of the date() function. (Matt,Ilia) -- Optimized the internal is_numeric_string() function. (Matt,Ilia) -- Optimized array functions utilizing php_splice(). (Ilia) -- Windows related optimizations (Dmitry, Stas) - . COM initialization/deinitialization are done only if necessary - . removed unnecessary checks for ISREG file and corresponding stat() calls - . opendir() is reimplementation using GetFistFile/GetNextFile those are - faster then _findfirst/_findnext - . implemented registry cache that prevent registry lookup on each request. - In case of modification of corresponding registry-tree PHP will reload it - automatic - . start timeout thread only if necessary - . stat() is reimplementation using GetFileAttributesEx(). The new - implementation is faster then implementation in MS VC CRT, but it doesn't - support Windows 95. -- Streams optimization (Dmitry) - . removed unnecessary ftell() calls (one call for each included PHP file) - . disabled calls to read() after EOF - -- Fixed incorrect function names on FreeBSD where inet_pton() was named - __inet_pton() and inet_ntop() was named __inet_ntop(). (Hannes) -- Fixed FastCGI impersonation for persistent connections on Windows. (Dmitry) -- Fixed wrong signature initialization in imagepng (Takeshi Abe) -- Fixed ftruncate() with negative size on FreeBSD. (Hannes) -- Fixed segfault in RegexIterator when given invalid regex. (Hannes) -- Fixed segfault in SplFileObject->openFile()->getPathname(). (Hannes) -- Fixed segfault in ZTS mode when OCI8 statements containing sub-statements - are destroyed in wrong order. (Tony) -- Fixed the validate email filter so that the letter "v" can also be used in - the user part of the email address. (Derick) -- Fixed bug #40297 (compile failure in ZTS mode when collections support is - missing). (Tony) -- Fixed bug #40285 (The PDO prepare parser goes into an infinite loop in - some instances). (Ilia) -- Fixed bug #40274 (Sessions fail with numeric root keys). (Ilia) -- Fixed bug #40259 (ob_start call many times - memory error). (Dmitry) -- Fixed bug #40231 (file_exists incorrectly reports false). (Dmitry) -- Fixed bug #40228 (ZipArchive::extractTo does create empty directories - recursively). (Pierre) -- Fixed bug #40200 (The FastCgi version has different realpath results than - thread safe version). (Dmitry) -- Fixed bug #40191 (use of array_unique() with objects triggers segfault). - (Tony) -- Fixed bug #40189 (possible endless loop in zlib.inflate stream filter). - (Greg, Tony) -- Fixed bug #40169 (CURLOPT_TCP_NODELAY only available in curl >= 7.11.2). - (Tony) -- Fixed bug #40129 (iconv extension doesn't compile with CodeWarrior on - Netware). (gk at gknw dot de, Tony) -- Fixed bug #40127 (apache2handler doesn't compile on Netware). - (gk at gknw dot de) -- Fixed bug #40121 (PDO_DBLIB driver wont free statements). (Ilia) -- Fixed bug #40098 (php_fopen_primary_script() not thread safe). (Ilia) -- Fixed bug #40092 (chroot() doesn't clear realpath cache). (Dmitry) -- Fixed bug #40091 (spl_autoload_register with 2 instances of the same class). - (Ilia) -- Fixed bug #40083 (milter SAPI functions always return false/null). (Tony) -- Fixed bug #40079 (php_get_current_user() not thread safe). - (Ilia, wharmby at uk dot ibm dot com) -- Fixed bug #40078 (ORA-01405 when fetching NULL values using - oci_bind_array_by_name()). (Tony) -- Fixed bug #40076 (zend_alloc.c: Value of enumeration constant must be in - range of signed integer). (Dmitry) -- Fixed bug #40073 (exif_read_data dies on certain images). (Tony, Marcus) -- Fixed bug #40036 (empty() does not work correctly with ArrayObject when - using ARRAY_AS_PROPS). (Ilia) -- Fixed bug #40012 (php_date.c doesn't compile on Netware). - (gk at gknw dot de, Derick) -- Fixed bug #40009 (http_build_query(array()) returns NULL). (Ilia) -- Fixed bug #40002 (Try/Catch performs poorly). (Dmitry) -- Fixed bug #39993 (tr_TR.UTF-8 locale has problems with PHP). (Ilia) -- Fixed bug #39990 (Cannot "foreach" over overloaded properties). (Dmitry) -- Fixed bug #39988 (type argument of oci_define_by_name() is ignored). - (Chris Jones, Tony) -- Fixed bug #39984 (redirect response code in header() could be ignored - in CGI sapi). (Ilia) -- Fixed bug #39979 (PGSQL_CONNECT_FORCE_NEW will causes next connect to - establish a new connection). (Ilia) -- Fixed bug #39971 (pg_insert/pg_update do not allow now() to be used - for timestamp fields). (Ilia) -- Fixed bug #39969 (ini setting short_open_tag has no effect when using - --enable-maintainer-zts). (Dmitry) -- Fixed bug #39952 (zip ignoring --with-libdir on zlib checks) - (judas dot iscariote at gmail dot com) -- Fixed bug #39944 (References broken). (Dmitry) -- Fixed bug #39935 (Extensions tidy,mcrypt,mhash,pdo_sqlite ignores - --with-libdir). (judas dot iscariote at gmail dot com, Derick) -- Fixed bug #39903 (Notice message when executing __halt_compiler() more than - once). (Tony) -- Fixed bug #39898 (FILTER_VALIDATE_URL validates \r\n\t etc). (Ilia) -- Fixed bug #39890 (using autoconf 2.6x and --with-layout=GNU breaks PEAR - install path). (Tony) -- Fixed bug #39884 (ReflectionParameter::getClass() throws exception for - type hint self). (thekid at php dot net) -- Fixed bug #39878 (CURL doesn't compile on Sun Studio Pro). (Ilia) -- Fixed bug #39873 (number_format() breaks with locale & decimal points). - (Ilia) -- Fixed bug #39869 (safe_read does not initialize errno). - (michiel at boland dot org, Dmitry) -- Fixed bug #39850 (SplFileObject throws contradictory/wrong error messages - when trying to open "php://wrong"). (Tony) -- Fixed bug #39846 (Invalid IPv4 treated as valid). (Ilia) -- Fixed bug #39845 (Persistent connections generate a warning in pdo_pgsql). - (Ilia) -- Fixed bug #39832 (SOAP Server: parameter not matching the WSDL specified - type are set to 0). (Dmitry) -- Fixed bug #39825 (foreach produces memory error). (Dmitry) -- Fixed bug #39816 (apxs2filter ignores httpd.conf & .htaccess php config - settings). (Ilia) -- Fixed bug #39815 (SOAP double encoding is not locale-independent). (Dmitry) -- Fixed bug #39797 (virtual() does not reset changed INI settings). (Ilia) -- Fixed bug #39795 (build fails on AIX because crypt_r() uses different - data struct). (Tony) -- Fixed bug #39791 (Crash in strtotime() on overly long relative date - multipliers). (Ilia) -- Fixed bug #39787 (PHP doesn't work with Apache 2.3). - (mv at binarysec dot com). -- Fixed bug #39782 (setTime() on a DateTime constructed with a Weekday - yields incorrect results). (Ilia) -- Fixed bug #39780 (PNG image with CRC/data error raises fatal error) (Pierre) -- Fixed bug #39779 (Enable AUTH PLAIN mechanism in underlying libc-client). - (michael dot heimpold at s2000 dot tu-chemnitz dot de, Ilia) -- Fixed bug #39775 ("Indirect modification ..." message is not shown). - (Dmitry) -- Fixed bug #39763 (magic quotes are applied twice by ext/filter in - parse_str()). (Ilia) -- Fixed bug #39760 (cloning fails on nested SimpleXML-Object). (Rob) -- Fixed bug #39759 (Can't use stored procedures fetching multiple result - sets in pdo_mysql). (Ilia) -- Fixed bug #39754 (Some POSIX extension functions not thread safe). - (Ilia, wharmby at uk dot ibm dot com) -- Fixed bug #39751 (putenv crash on Windows). (KevinJohnHoffman at gmail.com) -- Fixed bug #39732 (oci_bind_array_by_name doesn't work on Solaris 64bit). - (Tony) -- Fixed bug #39724 (Broken build due to spl/filter usage of pcre extension). - (Tony, Ilia) -- Fixed bug #39718 (possible crash if assert.callback is set in ini). (Ilia) -- Fixed bug #39702 (php crashes in the allocator on linux-m68k). (Dmitry) -- Fixed bug #39685 (iconv() - undefined function). (Hannes) -- Fixed bug #39673 (file_get_contents causes bus error on certain offsets). - (Tony) -- Fixed bug #39663 (Memory leak in pg_get_notify() and a possible memory - corruption on Windows in pgsql and pdo_pgsql extensions). - (Ilia, matteo at beccati dot com) -- Fixed bug #39662 (Segfault when calling asXML() of a cloned - SimpleXMLElement). (Rob, Tony) -- Fixed bug #39656 (crash when calling fetch() on a PDO statment object after - closeCursor()). (Ilia, Tony) -- Fixed bug #39653 (ext/dba doesn't check for db-4.5 and db-4.4 when db4 - support is enabled). (Tony) -- Fixed bug #39652 (Wrong negative results from memory_get_usage()). (Dmitry) -- Fixed bug #39648 (Implementation of PHP functions chown() and chgrp() are - not thread safe). (Ilia, wharmby at uk dot ibm dot com) -- Fixed bug #39640 (Segfault with "Allowed memory size exhausted"). (Dmitry) -- Fixed bug #39625 (Apache crashes on importStylesheet call). (Rob) -- Fixed bug #39623 (thread safety fixes on *nix for putenv() & mime_magic). - (Ilia, wharmby at uk dot ibm dot com) -- Fixed bug #39621 (str_replace() is not binary safe on strings with equal - length). (Tony) -- Fixed bug #39613 (Possible segfault in imap initialization due to missing - module dependency). (wharmby at uk dot ibm dot com, Tony) -- Fixed bug #39606 (Use of com.typelib_file in PHP.ini STILL causes A/V). (Rob) -- Fixed bug #39602 (Invalid session.save_handler crashes PHP). (Dmitry) -- Fixed bug #39596 (Creating Variant of type VT_ARRAY). (Rob) -- Fixed bug #39583 (ftp_put() does not change transfer mode to ASCII). (Tony) -- Fixed bug #39576 (array_walk() doesn't separate user data zval). (Tony) -- Fixed bug #39575 (move_uploaded_file() no longer working (safe mode - related)). (Tony) -- Fixed bug #39571 (timeout ssl:// connections). (Ilia) -- Fixed bug #39564 (PDO::errorInfo() returns inconsistent information when - sqlite3_step() fails). (Tony) -- Fixed bug #39548 (ZMSG_LOG_SCRIPT_NAME not routed to OutputDebugString() - on Windows). (Dmitry) -- Fixed bug #39538 (fgetcsv can't handle starting newlines and trailing odd - number of backslashes). (David Soria Parra, Pierre) -- Fixed bug #39534 (Error in maths to calculate of - ZEND_MM_ALIGNED_MIN_HEADER_SIZE). (wharmby at uk dot ibm dot com, Dmitry) -- Fixed bug #39527 (Failure to retrieve results when multiple unbuffered, - prepared statements are used in pdo_mysql). (Ilia) -- Fixed bug #39508 (imagefill crashes with small images 3 pixels or less). - (Pierre) -- Fixed bug #39506 (Archive corrupt with ZipArchive::addFile method). (Pierre) -- Fixed bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not - entity). (Hannes) -- Fixed bug #39483 (Problem with handling of \ char in prepared statements). - (Ilia, suhachov at gmail dot com) -- Fixed bug #39458 (ftp_nlist() returns false on empty dirs). (Nuno) -- Fixed bug #39454 (Returning a SOAP array segfaults PHP). (Dmitry) -- Fixed bug #39450 (getenv() fills other super-globals). (Ilia, Tony) -- Fixed bug #39449 (Overloaded array properties do not work correctly). - (Dmitry) -- Fixed bug #39445 (Calling debug_backtrace() in the __toString() - function produces a crash). (Dmitry) -- Fixed bug #39438 (Fatal error: Out of memory). (Dmitry) -- Fixed bug #39435 ('foo' instanceof bar gives invalid opcode error). (Sara) -- Fixed bug #39414 (Syntax error while compiling with Sun Workshop Complier). - (Johannes) -- Fixed bug #39398 (Booleans are not automatically translated to integers). - (Ilia) -- Fixed bug #39394 (Missing check for older variants of openssl). (Ilia) -- Fixed bug #39367 (clearstatcache() doesn't clear realpath cache). - (j at pureftpd dot org, Dmitry) -- Fixed bug #39366 (imagerotate does not use alpha with angle > 45 degrees) - (Pierre) -- Fixed bug #39364 (Removed warning on empty haystack inside mb_strstr()). - (Ilia) -- Fixed bug #39362 (Added an option to imap_open/imap_reopen to control the - number of connection retries). (Ilia) -- Fixed bugs #39361 & #39400 (mbstring function overloading problem). (Seiji) -- Fixed bug #39354 (Allow building of curl extension against libcurl - 7.16.0). (Ilia) -- Fixed bug #39350 (crash with implode("\n", array(false))). (Ilia) -- Fixed bug #39344 (Unnecessary calls to OnModify callback routine for - an extension INI directive). (wharmby at uk dot ibm dot com, Dmitry) -- Fixed bug #39320 (ZEND_HASH_APPLY_STOP causes deletion). (Marcus) -- Fixed bug #39313 (spl_autoload triggers Fatal error). (Marcus) -- Fixed bug #39300 (make install fails if wget is not available). (Tony) -- Fixed bug #39297 (Memory corruption because of indirect modification of - overloaded array). (Dmitry) -- Fixed bug #39286 (misleading error message when invalid dimensions are - given) (Pierre) -- Fixed bug #39273 (imagecopyresized may ignore alpha channel) (Pierre) -- Fixed bug #39265 (Fixed path handling inside mod_files.sh). - (michal dot taborsky at gmail dot com, Ilia) -- Fixed bug #39217 (serialNumber might be -1 when the value is too large). - (Pierre, Tony) -- Fixed bug #39215 (Inappropriate close of stdin/stdout/stderr). (Wez, Ilia) -- Fixed bug #39201 (Possible crash in Apache 2 with 413 ErrorHandler). (Ilia) -- Fixed bug #39151 (Parse error in recursiveiteratoriterator.php). (Marcus) -- Fixed bug #39121 (Incorrect return array handling in non-wsdl soap client). - (Dmitry) -- Fixed bug #39090 (DirectoryFilterDots doxygen docs and example is wrong). - (Marcus) -- Fixed bug #38852 (XML-RPC Breaks iconv). (Hannes) -- Fixed bug #38770 (unpack() broken with longs on 64 bit machines). - (Ilia, David Soria Parra). -- Fixed bug #38698 (for some keys cdbmake creates corrupted db and cdb can't - read valid db). (Marcus) -- Fixed bug #38680 (Added missing handling of basic types in json_decode). - (Ilia) -- Fixed bug #38604 (Fixed request time leak inside foreach() when iterating - through virtual properties). (Dmitry) -- Fixed bug #38602 (header( "HTTP/1.0 ..." ) does not change proto version). - (Ilia) -- Fixed bug #38542 (proc_get_status() returns wrong PID on windows). (Nuno) -- Fixed bug #38536 (SOAP returns an array of values instead of an object). - (Dmitry) -- Fixed bug #38456 (Apache2 segfaults when virtual() is called in .php - ErrorDocument). (Ilia) -- Fixed bug #38325 (spl_autoload_register() gives wrong line for "class not - found"). (Ilia) -- Fixed bug #38319 (Remove bogus warnings from persistent PDO connections). - (Ilia) -- Fixed bug #38274 (Memlimit fatal error sent to "wrong" stderr when using - fastcgi). (Dmitry) -- Fixed bug #38252 (Incorrect PDO error message on invalid default fetch - mode). (Ilia) -- Fixed bug #37927 (Prevent trap when COM extension processes argument of - type VT_DISPATCH|VT_REF) (Andy) -- Fixed bug #37773 (iconv_substr() gives "Unknown error" when string - length = 1"). (Ilia) -- Fixed bug #37627 (session save_path check checks the parent directory). - (Ilia) -- Fixed bug #37619 (proc_open() closes stdin on fork() failure). - (jdolecek at NetBSD dot org, Nuno) -- Fixed bug #37588 (COM Property propputref converts to PHP function - and can't be accesed). (Rob) -- Fixed bug #36975 (natcasesort() causes array_pop() to misbehave). - (Hannes) -- Fixed bug #36812 (pg_execute() modifies input array). (Ilia) -- Fixed bug #36798 (Error parsing named parameters with queries containing - high-ascii chars). (Ilia) -- Fixed bug #36644 (possible crash in variant_date_from_timestamp()). (Ilia) -- Fixed bug #36427 (proc_open() / proc_close() leak handles on windows). - (jdolecek at NetBSD dot org, Nuno) -- Fixed bug #36392 (wrong number of decimal digits with %e specifier in - sprintf). (Matt,Ilia) -- Fixed bug #36214 (__get method works properly only when conditional - operator is used). (Dmitry) -- Fixed bug #35634 (Erroneous "Class declarations may not be nested" - error raised). (Carl P. Corliss, Dmitry) -- Fixed bug #35106 (nested foreach fails when array variable has a - reference). (Dmitry) -- Fixed bug #34564 (COM extension not returning modified "out" argument) (Andy) -- Fixed bug #33734 (Something strange with COM Object). (Rob) -- Fixed bug #33386 (ScriptControl only sees last function of class). (Rob) -- Fixed bug #33282 (Re-assignment by reference does not clear the is_ref - flag) (Ilia, Dmitry, Matt Wilmas) -- Fixed bug #30074 (apparent symbol table error with - extract($blah, EXTR_REFS)) (Brian) -- Fixed bug #29840 (is_executable() does not honor safe_mode_exec_dir - setting). (Ilia) -- Fixed PECL bug #7295 (ORA-01405: fetched column value is NULL on LOB - fields). (Tony) - -02 Nov 2006, PHP 5.2.0 -- Updated bundled OpenSSL to version 0.9.8d in the Windows distro. (Edin) -- Updated Postgresql client libraries to 8.1.4 in the Windows distro. (Edin) -- Updated PCRE to version 6.7. (Ilia) -- Updated libsqlite in ext/pdo_sqlite to 3.3.7. (Ilia) -- Updated bundled MySQL client library to version 5.0.22 in the Windows - distribution. (Edin) -- Updated timezonedb to version 2006.7. (Derick) - -- Added ability to make SOAP call userspace PHP<->XML converters. (Dmitry) -- Added support for character sets in pg_escape_string() for PostgreSQL 8.1.4 - and higher. (Ilia) -- Added support for character sets in PDO quote() method for PostgreSQL 8.1.4 - and higher. (Ilia) -- Added DSA key generation support to openssl_pkey_new(), FR #38731 (marci - at balabit dot hu, Tony) -- Added SoapServer::setObject() method (it is a simplified version of - SoapServer::setClass() method). (Dmitry) -- Added support for hexadecimal entity in imagettftext() for the bundled GD. - (Pierre) -- Added support for httpOnly flag for session extension and cookie setting - functions. (Scott MacVicar, Ilia) -- Added version specific registry keys to allow different configurations for - different php version. (Richard, Dmitry) -- Added "PHPINIDir" Apache directive to apache and apache_hooks SAPIs. - (Dmitry) -- Added an optional boolean parameter to memory_get_usage() and - memory_get_peak_usage() to get memory size allocated by emalloc() or real - size of memory allocated from system. (Dmitry) -- Added Zip Archive extension. (Pierre) -- Added RFC1867 fileupload processing hook. (Stefan E.) -- Added JSON and Filter extensions. (Derick, Rasmus) -- Added error messages to disk_free_space() and disk_total_space() functions. - FR #37971 (Tony) -- Added PATHINFO_FILENAME option to pathinfo() to get the filename. - (Toby S. and Christian S.) -- Added array_fill_keys() function. (Marcus, Matt Wilmas) -- Added posix_initgroups() function. (Ilia) -- Added an optional parameter to parse_url() to allow retrieval of distinct - URL components. (Ilia) -- Added optional parameter to http_build_query() to allow specification of - string separator. (Ilia) -- Added image_type_to_extension() function. (Hannes, Ilia) -- Added allow_url_include ini directive to complement allow_url_fopen. (Rasmus) -- Added automatic module globals management. (Dmitry) -- Added RFC2397 (data: stream) support. (Marcus) -- Added new error mode E_RECOVERABLE_ERROR. (Derick, Marcus, Tony) -- Added support for getenv() input filtering. (Rasmus) -- Added support for constructors in interfaces to force constructor signature - checks in implementations. (Marcus) -- Added memory_get_peak_usage() function for retrieving peak memory usage of - a PHP script. (Ilia) -- Added pg_field_table() function. (Edin) -- Added SimpleXMLElement::saveXML() as an alias for SimpleXMLElement::asXML(). - (Hannes) -- Added DOMNode::getNodePath() for getting an XPath for a node. (Christian) -- Added gmp_nextprime() function. (ants dot aasma at gmail dot com, Tony) -- Added error_get_last() function. (Mike) - -- Removed current working directory from the php.ini search path for CLI and - re-added it for other SAPIs (restore to pre 5.1.x behavior). (Edin) -- Moved extensions to PECL: - . ext/filepro (Derick, Tony) - . ext/hwapi (Derick, Tony) -- Disabled CURLOPT_FOLLOWLOCATION in curl when open_basedir or - safe_mode are enabled. (Stefan E., Ilia) - -- Increased default memory limit to 16 megabytes to accommodate for a more - accurate memory utilization measurement. -- In addition to path to php.ini, PHPRC now may specify full file name. - (Dmitry) - -- Optimized array/HashTable copying. (Matt Wilmas, Dmitry) -- Optimized zend_try/zend_catch macros by eliminating memcpy(3). (Dmitry) -- Optimized require_once() and include_once() by eliminating fopen(3) on - second usage. (Dmitry) -- Optimized request shutdown sequence. Restoring ini directives now iterates - only over modified directives instead of all. (Dmitry) - -- Changed priority of PHPRC environment variable on win32 to be higher then - value from registry. (Dmitry) -- Changed __toString() to be called wherever applicable. (Marcus) -- Changed E_ALL error reporting mode to include E_RECOVERABLE_ERROR. (Marcus) -- Changed realpath cache to be disabled when "open_basedir" or "safe_mode" - are enabled on per-request basis. (Ilia) - -- Improved SNMP extension: (Jani) - . Renamed snmp_set_oid_numeric_print() to snmp_set_oid_output_format(). - . Added 2 new constants: SNMP_OID_OUTPUT_FULL and SNMP_OID_OUTPUT_NUMERIC - . Fixed bug #37564 (AES privacy encryption not possible due to net-snmp 5.2 - compatibility issue). (Patch: scott dot moynes+php at gmail dot com) -- Improved OpenSSL extension: (Pierre) - . Added support for all supported algorithms in openssl_verify - . Added openssl_pkey_get_details, returns the details of a key - . Added x509 v3 extensions support - . Added openssl_csr_get_subject() and openssl_csr_get_public_key() - . Added 3 new constants OPENSSL_VERSION_TEXT and OPENSSL_VERSION_NUMBER and - OPENSSL_KEYTYPE_EC -- Improved the Zend memory manager: (Dmitry) - . Removed unnecessary "--disable-zend-memory-manager" configure option. - . Added "--enable-malloc-mm" configure option which is enabled by default in - debug builds to allow using internal and external memory debuggers. - . Allow tweaking the memory manager with ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE - environment variables. - . For more information: Zend/README.ZEND_MM -- Improved safe_mode check for the error_log() function. (Ilia) -- Improved the error reporting in SOAP extension on request failure. (Ilia) -- Improved crypt() on win32 to be about 10 times faster and to have friendlier - license. (Frank, Dmitry) -- Improved performance of the implode() function on associated arrays. (Ilia) -- Improved performance of str_replace() when doing 1 char to 1 char or 1 char - to many chars replacement. (Ilia) -- Improved apache2filter SAPI: - . Allowed PHP to be an arbitrary filter in the chain and read the script from - the Apache stream. (John) - . Added support for apache2filter in the Windows build including binary - support for both Apache 2.0.x (php5apache2_filter.dll) and Apache 2.2.x - (php5apache2_2_filter.dll). (Edin) -- Improved apache2handler SAPI: - . Changed ap_set_content_type() to be called only once. (Mike) - . Added support for Apache 2.2 handler in the Windows distribution. (Edin) -- Improved FastCGI SAPI: (Dmitry) - . Removed source compatibility with libfcgi. - . Optimized access to FastCGI environment variables by using HashTable - instead of linear search. - . Allowed PHP_FCGI_MAX_REQUESTS=0 that assumes no limit. - . Allowed PHP_FCGI_CHILDREN=0 that assumes no worker children. (FastCGI - requests are handled by main process itself) -- Improved CURL: - . Added control character checks for "open_basedir" and "safe_mode" checks. - (Ilia) - . Added implementation of curl_multi_info_read(). (Brian) -- Improved PCRE: (Andrei) - . Added run-time configurable backtracking/recursion limits. - . Added preg_last_error(). (Andrei) -- Improved PDO: - . Added new attribute ATTR_DEFAULT_FETCH_MODE. (Pierre) - . Added FETCH_PROPS_LATE. (Marcus) -- Improved SPL: (Marcus) - . Made most iterator code exception safe. - . Added RegExIterator and RecursiveRegExIterator. - . Added full caching support and ArrayAccess to CachingIterator. - . Added array functions to ArrayObject/ArrayIterator and made them faster. - . Added support for reading csv and skipping empty lines in SplFileObject. - . Added CachingIterator::TOSTRING_USE_INNER, calls inner iterator __toString. - . Added ability to set the CSV separator per SplFileObject. -- Improved xmlReader: (Rob) - . Added readInnerXml(), xmlReader::setSchema(). - . Added readInnerXML(), readOuterXML(), readString(), setSchema(). (2.6.20+) - . Changed to passing libxml options when loading reader. - -- Fixed invalid read in imagecreatefrompng when an empty file is given - (Pierre, Tony) -- Fixed infinite loop when a wrong color index is given to imagefill (Pierre) -- Fixed mess with CGI/CLI -d option (now it works with cgi; constants are - working exactly like in php.ini; with FastCGI -d affects all requests). - (Dmitry) -- Fixed missing open_basedir check inside chdir() function. (Ilia) -- Fixed overflow on 64bit systems in str_repeat() and wordwrap(). (Stefan E.) -- Fixed XSLTProcessor::importStylesheet() to return TRUE on success - (Christian) -- Fixed leaks in openssl_csr_sign and openssl_csr_new (Pierre) -- Fixed phpinfo() cutoff of variables at \0. (Ilia) -- Fixed a bug in the filter extension that prevented magic_quotes_gpc from - being applied when RAW filter is used. (Ilia) -- Fixed memory leaks in openssl streams context options. (Pierre) -- Fixed handling of extremely long paths inside tempnam() function. (Ilia) -- Fixed bug #39721 (Runtime inheritance causes data corruption). (Dmitry) -- Fixed bug #39304 (Segmentation fault with list unpacking of string offset). - (Dmitry) -- Fixed bug #39192 (Not including nsapi.h properly with SJSWS 7). This will - make PHP 5.2 compatible to new Sun Webserver. (Uwe) -- Fixed bug #39140 (Uncaught exception may cause crash). (Dmitry) -- Fixed bug #39125 (Memleak when reflecting non-existing class/method). (Tony) -- Fixed bug #39067 (getDeclaringClass() and private properties). (Tony) -- Fixed bug #39039 (SSL: fatal protocol error when fetching HTTPS from servers - running Google web server). (Ilia) -- Fixed bug #39035 (Compatibility issue between DOM and - zend.ze1_compatibility_mode). (Rob) -- Fixed bug #39034 (curl_exec() with return transfer returns TRUE on empty - files). (Ilia) -- Fixed bug #39032 (strcspn() stops on null character). (Tony) -- Fixed bug #39020 (PHP in FastCGI server mode crashes). (Dmitry) -- Fixed bug #39017 (foreach(($obj = new myClass) as $v); echo $obj; - segfaults). (Dmitry) -- Fixed bug #39004 (Fixed generation of config.nice with autoconf 2.60). (Ilia) -- Fixed bug #39003 (__autoload() is called for type hinting). (Dmitry, Tony) -- Fixed bug #39001 (ReflectionProperty returns incorrect declaring class for - protected properties). (Tony) -- Fixed bug #38996 (PDO_MYSQL doesn't check connections for liveness). (Tony) -- Fixed bug #38993 (Fixed safe_mode/open_basedir checks for session.save_path, - allowing them to account for extra parameters). (Ilia) -- Fixed bug #38989 (Absolute path with slash at beginning doesn't work on win). - (Dmitry) -- Fixed bug #38985 (Can't cast COM objects). (Wez) -- Fixed bug #38981 (using FTP URLs in get_headers() causes crash). (Tony) -- Fixed bug #38963 (Fixed a possible open_basedir bypass in tempnam()). (Ilia) -- Fixed bug #38961 (metaphone() results in segmentation fault on NetBSD). - (Tony) -- Fixed bug #38949 (Cannot get xmlns value attribute). (Rob) -- Fixed bug #38942 (Double old-style-ctor inheritance). (Dmitry) -- Fixed bug #38941 (imap extension does not compile against new version of the - imap library). (Ilia) -- Fixed bug #38934 (move_uploaded_file() cannot read uploaded file outside of - open_basedir). (Ilia) -- Fixed bug #38904 (apache2filter changes cwd to /). (Ilia, Hannes) -- Fixed bug #38891 (get_headers() do not work with curl-wrappers). (Ilia) -- Fixed bug #38882 (ldap_connect causes segfault with newer versions of - OpenLDAP). (Tony) -- Fixed bug #38859 (parse_url() fails if passing '@' in passwd). (Tony) -- Fixed bug #38850 (lookupNamespaceURI doesn't return default namespace). (Rob) -- Fixed bug #38844 (curl_easy_strerror() is defined only since cURL 7.12.0). - (Tony) -- Fixed bug #38813 (DOMEntityReference->__construct crashes when called - explicitly). (Rob) -- Fixed bug #38808 ("maybe ref" issue for current() and others). (Dmitry) -- Fixed bug #38779 (engine crashes when require()'ing file with syntax error - through userspace stream wrapper). (Tony, Dmitry) -- Fixed bug #38772 (inconsistent overriding of methods in different visibility - contexts). (Dmitry) -- Fixed bug #38759 (PDO sqlite2 empty query causes segfault). (Tony) -- Fixed bug #38721 (Invalid memory read in date_parse()). (Tony, Derick) -- Fixed bug #38700 (SoapClient::__getTypes never returns). (Dmitry) -- Fixed bug #38693 (curl_multi_add_handle() set curl handle to null). (Ilia) -- Fixed bug #38687 (sockaddr local storage insufficient for all sock families). - (Sara) -- Fixed bug #38661 (mixed-case URL breaks url-wrappers). (Ilia) -- Fixed bug #38653 (memory leak in ReflectionClass::getConstant()). (Tony) -- Fixed bug #38649 (uninit'd optional arg in stream_socket_sendto()). (Sara) -- Fixed bug #38637 (curl_copy_handle() fails to fully copy the cURL handle). - (Tony, Ilia) -- Fixed bug #38624 (Strange warning when incrementing an object property and - exception is thrown from __get method). (Tony) -- Fixed bug #38623 (leaks in a tricky code with switch() and exceptions). - (Dmitry) -- Fixed bug #38579 (include_once() may include the same file twice). (Dmitry) -- Fixed bug #38574 (missing curl constants and improper constant detection). - (Ilia) -- Fixed bug #38543 (shutdown_executor() may segfault when memory_limit is too - low). (Dmitry) -- Fixed bug #38535 (memory corruption in pdo_pgsql driver on error retrieval - inside a failed query executed via query() method). (Ilia) -- Fixed bug #38534 (segfault when calling setlocale() in userspace session - handler). (Tony) -- Fixed bug #38524 (strptime() does not initialize the internal date storage - structure). (Ilia) -- Fixed bug #38511, #38473, #38263 (Fixed session extension request shutdown - order to ensure it is shutdown before the extensions it may depend on). - (Ilia) -- Fixed bug #38488 (Access to "php://stdin" and family crashes PHP on win32). - (Dmitry) -- Fixed bug #38474 (getAttribute select attribute by order, even when - prefixed). (Rob) -- Fixed bug #38467 (--enable-versioning causes make fail on OS X). (Tony) -- Fixed bug #38465 (ReflectionParameter fails if default value is an access - to self::). (Johannes) -- Fixed bug #38464 (array_count_values() mishandles numeric strings). - (Matt Wilmas, Ilia) -- Fixed bug #38461 (setting private attribute with __set() produces - segfault). (Tony) -- Fixed bug #38458, PECL bug #8944, PECL bug #7775 (error retrieving columns - after long/text columns with PDO_ODBC). (Wez) -- Fixed bug #38454 (warning upon disabling handler via - xml_set_element_handler). (dtorop933 at gmail dot com, Rob) -- Fixed bug #38451 (PDO_MYSQL doesn't compile on Solaris). (Tony) -- Fixed bug #38450 (constructor is not called for classes used in userspace - stream wrappers). (Tony) -- Fixed bug #38438 (DOMNodeList->item(0) segfault on empty NodeList). (Ilia) -- Fixed bug #38431 (xmlrpc_get_type() crashes PHP on objects). (Tony) -- Fixed bug #38427 (unicode causes xml_parser to misbehave). (Rob) -- Fixed bug #38424 (Different attribute assignment if new or existing). (Rob) -- Fixed bug #38400 (Use of com.typelib_file may cause a crash). (Ilia) -- Fixed bug #38394 (PDO fails to recover from failed prepared statement - execution). (Ilia) -- Fixed bug #38377 (session_destroy() gives warning after - session_regenerate_id()). (Ilia) -- Implemented #38357 (dbase_open can't open DBase 3 dbf file). - (rodrigo at fabricadeideias dot com, Mike) -- Fixed bug #38354 (Unwanted reformatting of XML when using AsXML). (Christian) -- Fixed bug #38347 (Segmentation fault when using foreach with an unknown/empty - SimpleXMLElement). (Tony) -- Fixed bug #38322 (reading past array in sscanf() leads to arbitrary code - execution). (Tony) -- Fixed bug #38315 (Constructing in the destructor causes weird behavior). - (Dmitry) -- Fixed bug #38303 (spl_autoload_register() suppress all errors silently). - (Ilia) -- Fixed bug #38290 (configure script ignores --without-cdb,inifile,flatfile). - (Marcus) -- Fixed bug #38289 (segfault in session_decode() when _SESSION is NULL). - (Tony) -- Fixed bug #38287 (static variables mess up global vars). (Dmitry) -- Fixed bug #38278 (session_cache_expire()'s value does not match phpinfo's - session.cache_expire). (Tony) -- Fixed bug #38276 (file_exists() works incorrectly with long filenames - on Windows). (Ilia, Tony) -- Fixed bug #38269 (fopen wrapper doesn't fail on invalid hostname with - curlwrappers enabled). (Tony) -- Fixed bug #38265 (heap corruption). (Dmitry) -- Fixed bug #38261 (openssl_x509_parse() leaks with invalid cert) (Pierre) -- Fixed bug #38255 (openssl possible leaks while passing keys) (Pierre) -- Fixed bug #38253 (PDO produces segfault with default fetch mode). (Tony) -- Fixed bug #38251 (socket_select() and invalid arguments). (Tony) -- Fixed bug #38236 (Binary data gets corrupted on multipart/formdata POST). - (Ilia) -- Fixed bug #38234 (Exception in __clone makes memory leak). (Dmitry, Nuno) -- Fixed bug #38229 (strtotime() does not parse YYYY-MM format). (Ilia) -- Fixed bug #38224 (session extension can't handle broken cookies). (Ilia) -- Fixed bug #38220 (Crash on some object operations). (Dmitry) -- Fixed bug #38217 (ReflectionClass::newInstanceArgs() tries to allocate too - much memory). (Tony) -- Fixed bug #38214 (gif interlace output cannot work). (Pierre) -- Fixed bug #38213, #37611, #37571 (wddx encoding fails to handle certain - characters). (Ilia) -- Fixed bug #38212 (Segfault on invalid imagecreatefromgd2part() parameters). - (Pierre) -- Fixed bug #38211 (variable name and cookie name match breaks script - execution). (Dmitry) -- Fixed bug #38199 (fclose() unable to close STDOUT and STDERR). (Tony) -- Fixed bug #38198 (possible crash when COM reports an exception). (Ilia) -- Fixed bug #38194 (ReflectionClass::isSubclassOf() returns TRUE for the - class itself). (Ilia) -- Fixed bug #38183 (disable_classes=Foobar causes disabled class to be - called Foo). (Jani) -- Fixed bug #38179 (imagecopy from a palette to a truecolor image loose alpha - channel) (Pierre) -- Fixed bug #38173 (Freeing nested cursors causes OCI8 to segfault). (Tony) -- Fixed bug #38168 (Crash in pdo_pgsql on missing bound parameters). (Ilia) -- Fixed bug #38161 (oci_bind_by_name() returns garbage when Oracle didn't set - the variable). (Tony) -- Fixed bug #38146 (Cannot use array returned from foo::__get('bar') in write - context). (Dmitry) -- Fixed bug #38132 (ReflectionClass::getStaticProperties() retains \0 in key - names). (Ilia) -- Fixed bug #38125 (undefined reference to spl_dual_it_free_storage). (Marcus) -- Fixed bug #38112 (corrupted gif segfaults) (Pierre) -- Fixed bug #38096 (large timeout values ignored on 32bit machines in - stream_socket_accept() and stream_socket_client()). (Ilia) -- Fixed bug #38086 (stream_copy_to_stream() returns 0 when maxlen is bigger - than the actual length). (Tony) -- Fixed bug #38072 (boolean arg for mysqli_autocommit() is always true on - Solaris). (Tony) -- Fixed bug #38067 (Parameters are not decoded from utf-8 when using encoding - option). (Dmitry) -- Fixed bug #38064 (ignored constructor visibility). (Marcus) -- Fixed bug #38055 (Wrong interpretation of boolean parameters). (Dmitry) -- Fixed bug #38047 ("file" and "line" sometimes not set in backtrace from - inside error handler). (Dmitry) -- Fixed bug #38019 (segfault extending mysqli class). (Dmitry) -- Fixed bug #38005 (SoapFault faultstring doesn't follow encoding rules). - (Dmitry) -- Fixed bug #38004 (Parameters in SoapServer are decoded twice). (Dmitry) -- Fixed bug #38003 (in classes inherited from MySQLi it's possible to call - private constructors from invalid context). (Tony) -- Fixed bug #37987 (invalid return of file_exists() in safe mode). (Ilia) -- Fixed bug #37947 (zend_ptr_stack reallocation problem). (Dmitry) -- Fixed bug #37945 (pathinfo() cannot handle argument with special characters - like German "Umlaut"). (Mike) -- Fixed bug #37931 (possible crash in OCI8 after database restart - when using persistent connections). (Tony) -- Fixed bug #37923 (Display constant value in reflection::export). (Johannes) -- Fixed bug #37920 (compilation problems on z/OS). (Tony) -- Fixed bug #37870 (pgo_pgsql tries to de-allocate unused statements). - (Ilia, ce at netage dot bg) -- Fixed bug #37864 (file_get_contents() leaks on empty file). (Hannes) -- Fixed bug #37862 (Integer pointer comparison to numeric value). - (bugs-php at thewrittenword dot com) -- Fixed bug #37846 (wordwrap() wraps incorrectly). (ddk at krasn dot ru, Tony) -- Fixed bug #37816 (ReflectionProperty does not throw exception when accessing - protected attribute). (Marcus) -- Fixed bug #37811 (define not using toString on objects). (Marcus) -- Fixed bug #37807 (segmentation fault during SOAP schema import). (Tony) -- Fixed bug #37806 (weird behavior of object type and comparison). (Marcus) -- Fixed bug #37780 (memory leak trying to execute a non existing file (CLI)). - (Mike) -- Fixed bug #37779 (empty include_path leads to search for files inside /). - (jr at terragate dot net, Ilia) -- Fixed bug #37747 (strtotime segfaults when given "nextyear"). (Derick) -- Fixed bug #37720 (merge_php_config scrambles values). - (Mike, pumuckel at metropolis dot de) -- Fixed bug #37709 (Possible crash in PDO::errorCode()). (Ilia) -- Fixed bug #37707 (clone without assigning leaks memory). (Ilia, Nuno, Dmitri) -- Fixed bug #37705 (Semaphore constants not available). (Ilia) -- Fixed bug #37671 (MySQLi extension fails to recognize BIT column). (Ilia) -- Fixed bug #37667 (Object is not added into array returned by __get). (Marcus) -- Fixed bug #37635 (parameter of pcntl signal handler is trashed). (Mike) -- Fixed bug #37632 (Protected method access problem). (Marcus) -- Fixed bug #37630 (MySQL extensions should link against thread safe client - libs if built with ZTS). (Mike) -- Fixed bug #37620 (mysqli_ssl_set validation is inappropriate). (Georg) -- Fixed bug #37616 (DATE_RFC822 does not product RFC 822 dates). - (Hannes Magnusson, Derick) -- Fixed bug #37614 (Class name lowercased in error message). (Johannes) -- Fixed bug #37587 (var without attribute causes segfault). (Marcus) -- Fixed bug #37586 (Bumped minimum PCRE version to 6.6, needed for recursion - limit support). (Ilia) -- Fixed bug #37581 (oci_bind_array_by_name clobbers input array when using - SQLT_AFC, AVC). (Tony) -- Fixed bug #37569 (WDDX incorrectly encodes high-ascii characters). (Ilia) -- Fixed bug #37565 (Using reflection::export with simplexml causing a crash). - (Marcus) -- Fixed bug #37564 (AES privacy encryption not possible due to net-snmp 5.2 - compatibility issue). (Jani, patch by scott dot moynes+php at gmail dot com) -- Fixed bug #37563 (array_key_exists performance is poor for &$array). (Ilia) -- Fixed bug #37558 (timeout functionality doesn't work after a second PHP - start-up on the same thread). (p dot desarnaud at wanadoo dot fr) -- Fixed bug #37531 (oci8 persistent connection corruption). (Tony) -- Fixed bug #37523 (namespaces added too late, leads to missing xsi:type - attributes. Incompatibility with libxml2-2.6.24). (Dmitry) -- Fixed bug #37514 (strtotime doesn't assume year correctly). (Derick) -- Fixed bug #37510 (session_regenerate_id changes session_id() even on - failure). (Hannes) -- Fixed bug #37505 (touch() truncates large files). (Ilia) -- Fixed bug #37499 (CLI segmentation faults during cleanup with sybase-ct - extension enabled). (Tony) -- Fixed bug #37496 (FastCGI output buffer overrun). (Piotr, Dmitry) -- Fixed bug #37487 (oci_fetch_array() array-type should always default to - OCI_BOTH). (Tony) -- Fixed bug #37457 (Crash when an exception is thrown in accept() method of - FilterIterator). (Marcus) -- Fixed bug #37456 (DOMElement->setAttribute() loops forever). (Rob) -- Fixed bug #37445 (Fixed crash in pdo_mysql resulting from premature object - destruction). (Ilia) -- Fixed bug #37428 (PHP crashes on windows if there are start-up errors and - event log is used for logging them). (Edin) -- Fixed bug #37418 (tidy module crashes on shutdown). (Tony) -- Fixed bug #37416 (iterator_to_array() hides exceptions thrown in rewind() - method). (Tony) -- Fixed bug #37413 (Rejected versions of flex that don't work). (Ilia) -- Fixed bug #37395 (recursive mkdir() fails to create nonexistent directories - in root dir). (Tony) -- Fixed bug #37394 (substr_compare() returns an error when offset equals - string length). (Ilia) -- Fixed bug #37392 (Unnecessary call to OCITransRollback() at the end of - request). (Tony) -- Fixed bug #37376 (fastcgi.c compile fail with gcc 2.95.4). (Ilia) -- Fixed bug #37368 (Incorrect timestamp returned for strtotime()). (Derick) -- Fixed bug #37363 (PDO_MYSQL does not build if no other mysql extension is - enabled). (Mike) -- Fixed bug #37348 (make PEAR install ignore open_basedir). (Ilia) -- Fixed bug #37341 ($_SERVER in included file is shortened to two entries, - if $_ENV gets used). (Dmitry) -- Fixed bug #37313 (sigemptyset() used without including ). - (jdolecek) -- Fixed bug #37306 (max_execution_time = max_input_time). (Dmitry) -- Fixed bug #37278 (SOAP not respecting uri in __soapCall). (Dmitry) -- Fixed bug #37265 (Added missing safe_mode & open_basedir checks to - imap_body()). (Ilia) -- Fixed bug #37262 (var_export() does not escape \0 character). (Ilia) -- Fixed bug #37256 (php-fastcgi doesn't handle connection abort). (Dmitry) -- Fixed bug #37244 (Added strict flag to base64_decode() that enforces - RFC3548 compliance). (Ilia) -- Fixed bug #37144 (PHP crashes trying to assign into property of dead object). - (Dmitry) -- Fixed bug #36949 (invalid internal mysqli objects dtor). (Mike) -- Implement #36732 (req/x509 extensions support for openssl_csr_new and - openssl_csr_sign) (ben at psc dot edu, Pierre) -- Fixed bug #36759 (Objects destructors are invoked in wrong order when script - is finished). (Dmitry) -- Fixed bug #36681 (pdo_pgsql driver incorrectly ignored some errors). - (Wez, Ilia) -- Fixed bug #36630 (umask not reset at the end of the request). (Ilia) -- Fixed bug #36515 (Unlinking buckets from non-existent brigades). (Sara) -- Fixed bug #35973 (Error ORA-24806 occurs when trying to fetch a NCLOB - field). (Tony) -- Fixed bug #35886 (file_get_contents() fails with some combinations of - offset & maxlen). (Nuno) -- Fixed bug #35512 (Lack of read permission on main script results in - E_WARNING rather then E_ERROR). (Ilia) -- Fixed bug #34180 (--with-curlwrappers causes PHP to disregard some HTTP - stream context options). (Mike) -- Fixed bug #34066 (recursive array_walk causes segfault). (Tony) -- Fixed bug #34065 (throw in foreach causes memory leaks). (Dmitry) -- Fixed bug #34005 (oci_password_change() fails). - (pholdaway at technocom-wireless dot com, Tony) -- Fixed bug #33895 (Missing math constants). (Hannes) -- Fixed bug #33770 (https:// or ftps:// do not work when --with-curlwrappers - is used and ssl certificate is not verifiable). (Ilia) -- Fixed bug #29538 (number_format and problem with 0). (Matt Wilmas) -- Implement #28382 (openssl_x509_parse() extensions support) (Pierre) -- Fixed PECL bug #9061 (oci8 might reuse wrong persistent connection). (Tony) -- Fixed PECL bug #8816 (issue in php_oci_statement_fetch with more than one - piecewise column) (jeff at badtz-maru dot com, Tony) -- Fixed PECL bug #8112 (OCI8 persistent connections misbehave when Apache - process times out). (Tony) -- Fixed PECL bug #7755 (error selecting DOUBLE fields with PDO_ODBC). - ("slaws", Wez) - - -04 May 2006, PHP 5.1.4 -- Added "capture_peer_cert" and "capture_peer_cert_chain" context options - for SSL streams. (Wez). -- Added PDO::PARAM_EVT_* family of constants. (Sara) -- Fixed possible crash in highlight_string(). (Dmitry) -- Fixed bug #37291 (FastCGI no longer works with isapi_fcgi.dll). (Dmitry) -- Fixed bug #37277 (cloning Dom Documents or Nodes does not work). (Rob) -- Fixed bug #37276 (problems with $_POST array). (Dmitry) -- Fixed bug #36632 (bad error reporting for pdo_odbc exec UPDATE). (Wez). -- Fixed bug #35552 (crash when pdo_odbc prepare fails). (Wez). - -28 Apr 2006, PHP 5.1.3 -- Updated bundled PCRE library to version 6.6. (Andrei) -- Moved extensions to PECL: - . ext/msession (Derick) -- Reimplemented FastCGI interface. (Dmitry) -- Improved SPL: (Marcus) - - Fixed issues with not/double calling of constructors of SPL iterators. - - Fixed issues with info-class/file-class in SPL directory handling classes. - - Fixed ArrayIterator::seek(). - - Added SimpleXMLIterator::count(). - - Dropped erroneous RecursiveDirectoryIterator::getSubPathInfo(). -- Improved SimpleXML: (Marcus, Rob) - . Added SimpleXMLElement::getName() to retrieve name of element. - . Added ability to create elements on the fly. - . Added addChild() method for element creation supporting namespaces. - . Added addAttribute() method for attribute creation supporting namespaces. - . Added ability to delete specific elements and attributes by offset. -- Improved Reflection API: (Marcus) - . Added ReflectionClass::newInstanceArgs($args). - . Added ability to analyze extension dependency. - . Added ReflectionFunction::isDeprecated() and constant IS_DEPRECATED. - . Added ReflectionParameter::getDeclaringClass(). - . Changed reflection constants to be prefixed with IS_. (Johannes) -- Improved cURL extension: (Ilia) - . Added curl_setopt_array() function that allows setting of multiple - options via an associated array. - . Added the ability to retrieve the request message sent to the server. -- Improved GD extension: (Pierre) - . Added a weak/tolerant mode to the JPEG loader. - . Added filtering mode option to imagepng() to allow reducing file size. - . Fixed imagecolorallocate() and imagecolorallocatelapha() to return FALSE - on error. -- Changed get_headers() to retrieve headers also from non-200 responses. - (Ilia) -- Changed get_headers() to use the default context. (Ilia) -- Added lchown() and lchgrp() to change user/group ownership of symlinks. - (Derick) -- Added support for exif date format in strtotime(). (Derick) -- Added a check for special characters in the session name. (Ilia) -- Added "consumed" stream filter. (Marcus) -- Added new mysqli constants for BIT and NEW_DECIMAL field types: - MYSQLI_TYPE_NEWDECIMAL and MYSQLI_TYPE_BIT. FR #36007. (Georg) -- Added imap_savebody() that allows message body to be written to a - file. (Mike) -- Added overflow checks to wordwrap() function. (Ilia) -- Added support for BINARY_DOUBLE and BINARY_FLOAT to PDO_OCI and OCI8 - (also fixes bug #36764). (Tony) -- Eliminated run-time constant fetching for TRUE, FALSE and NULL. (Dmitry) -- Removed the E_STRICT deprecation notice from "var". (Ilia) -- Fixed reading stream filters never notified about EOF. (Mike) -- Fixed tempnam() 2nd parameter to be checked against path components. (Ilia) -- Fixed a bug that would not fill in the fifth argument to preg_replace() - properly, if the variable was not declared previously. (Andrei) -- Fixed safe_mode check for source argument of the copy() function. (Ilia) -- Fixed mysqli bigint conversion under Windows (Georg) -- Fixed XSS inside phpinfo() with long inputs. (Ilia) -- Fixed Apache2 SAPIs header handler modifying header strings. (Mike) -- Fixed 'auto_globals_jit' to work together with 'register_argc_argv'. (Dmitry) -- Fixed offset/length parameter validation in substr_compare() function. (Ilia) -- Fixed debug_zval_dump() to support private and protected members. (Dmitry) -- Fixed SoapFault::getMessage(). (Dmitry) -- Fixed issue with iconv_mime_decode where the "encoding" would only allow - upper case specifiers. (Derick) -- Fixed tiger hash algorithm generating wrong results on big endian platforms. - (Mike) -- Fixed crash with DOMImplementation::createDocumentType("name:"). (Mike) -- Fixed bug #37205 (Serving binary content/images fails with "comm with server - aborted" FastCGI err). (Dmitry) -- Fixed bug #37192 (cc may complain about non-constant initializers in - hash_adler.c). (Mike) -- Fixed bug #37191 (chmod takes off sticky bit when safe_mode is On). (Tony) -- Fixed bug #37167 (PDO segfaults when throwing exception from the - fetch handler). (Tony) -- Fixed bug #37162 (wddx does not build as a shared extension). - (jdolecek at NetBSD dot org, Ilia) -- Fixed bug #37158 (fread behavior changes after calling - stream_wrapper_register). (Wez) -- Fixed bug #37138 (__autoload tries to load callback'ed self and parent). - (Dmitry) -- Fixed bug #37103 (libmbfl headers not installed). (Jani) -- Fixed bug #37062 (compile failure on ARM architecture). (Tony) -- Fixed bug #37061 (curl_exec() doesn't zero-terminate binary strings). (Tony) -- Fixed bug #37060 (Type of retval of Countable::count() is not checked). - (Johannes) -- Fixed bug #37059 (oci_bind_by_name() doesn't support RAW and LONG RAW - fields). (Tony) -- Fixed bug #37057 (xmlrpc_decode() may produce arrays with numeric strings, - which are unaccessible). (Tony) -- Fixed bug #37055 (incorrect reference counting for persistent OCI8 - connections). (Tony) -- Fixed bug #37054 (SoapClient Error Fetching http headers). (Dmitry) -- Fixed bug #37053 (html_errors with internal classes produces wrong links). - (Tony) -- Fixed bug #37046 (foreach breaks static scope). (Dmitry) -- Fixed bug #37045 (Fixed check for special chars for http redirects). (Ilia) -- Fixed bug #37017 (strtotime fails before 13:00:00 with some time zones - identifiers). (Derick) -- Fixed bug #37002 (Have to quote literals in INI when concatenating with - vars). (Dmitry)z -- Fixed bug #36988 (mktime freezes on long numbers). (Derick) -- Fixed bug #36981 (SplFileObject->fgets() ignores max_length). (Tony) -- Fixed bug #36957 (serialize() does not handle recursion). (Ilia) -- Fixed bug #36944 (strncmp & strncasecmp do not return false on negative - string length). (Tony) -- Fixed bug #36941 (ArrayIterator does not clone itself). (Marcus) -- Fixed bug #36934 (OCILob->read() doesn't move internal pointer when - reading 0's). (Tony) -- Fixed bug #36908 (wsdl default value overrides value in soap request). - (Dmitry) -- Fixed bug #36898 (__set() leaks in classes extending internal ones). - (Tony, Dmitry) -- Fixed bug #36886 (User filters can leak buckets in some situations). (Ilia) -- Fixed bug #36878 (error messages are printed even though an exception has - been thrown). (Tony) -- Fixed bug #36875 (is_*() functions do not account for open_basedir). (Ilia) -- Fixed bug #36872 (session_destroy() fails after call to - session_regenerate_id(true)). (Ilia) -- Fixed bug #36869 (memory leak in output buffering when using chunked - output). (Tony) -- Fixed bug #36859 (DOMElement crashes when calling __construct when - cloning). (Tony) -- Fixed bug #36857 (Added support for partial content fetching to the - HTTP streams wrapper). (Ilia) -- Fixed bug #36851 (Documentation and code discrepancies for NULL - data in oci_fetch_*() functions). (Tony) -- Fixed bug #36825 (Exceptions thrown in ArrayObject::offsetGet cause - segfault). (Tony) -- Fixed bug #36820 (Privileged connection with an Oracle password file - fails). (Tony) -- Fixed bug #36809 (__FILE__ behavior changed). (Dmitry) -- Fixed bug #36808 (syslog ident becomes garbage between requests). (Tony) -- Fixed bug #36802 (mysqli_set_charset() crash with a non-open connection). - (Ilia) -- Fixed bug #36756 (DOMDocument::removeChild corrupts node). (Rob) -- Fixed bug #36749 (SOAP: 'Error Fetching http body' when using HTTP Proxy). - (Dmitry) -- Fixed bug #36745 (No error message when load data local file isn't found). - (Georg) -- Fixed bug #36743 (In a class extending XMLReader array properties are not - writable). (Tony) -- Fixed bug #36727 (segfault in pdo_pgsql bindValue() when no parameters are - defined). (Tony) -- Fixed bug #36721 (The SoapServer is not able to send a header that it didn't - receive). (Dmitry) -- Fixed bug #36697 (Transparency is lost when using imagecreatetruecolor). - (Pierre) -- Fixed bug #36689 (Removed arbitrary limit on the length of syslog messages). - (Ilia) -- Fixed bug #36656 (http_build_query generates invalid URIs due to use of - square brackets). (Mike) -- Fixed bug #36638 (strtotime() returns false when 2nd argument < 1). (Derick) -- Fixed bug #36629 (SoapServer::handle() exits on SOAP faults). (Dmitry) -- Fixed bug #36625 (pg_trace() does not work). (iakio at mono-space dot net) -- Fixed bug #36614 (Segfault when using Soap). (Dmitry) -- Fixed bug #36611 (assignment to SimpleXML object attribute changes argument - type to string). (Tony) -- Fixed bug #36606 (pg_query_params() changes arguments type to string). (Tony) -- Fixed bug #36599 (DATE_W3C format constant incorrect). (Derick) -- Fixed bug #36575 (SOAP: Incorrect complex type instantiation with - hierarchies). (Dmitry) -- Fixed bug #36572 (Added PDO::MYSQL_ATTR_DIRECT_QUERY constant that should - be set when executing internal queries like "show master status" via MySQL). - (Ilia) -- Fixed bug #36568 (memory_limit setting on win32 has no effect). (Dmitry) -- Fixed bug #36513 (comment will be outputted in last line). (Dmitry) -- Fixed bug #36510 (strtotime() fails to parse date strings with tabs). - (Ilia, Derick) -- Fixed bug #36459 (Incorrect adding PHPSESSID to links, which contains \r\n). - (Ilia) -- Fixed bug #36458 (sleep() accepts negative values). (Ilia) -- Fixed bug #36436 (DBA problem with Berkeley DB4). (Marcus) -- Fixed bug #36434 (Improper resolution of declaring class name of an - inherited property). (Ilia) -- Fixed bug #36420 (segfault when access result->num_rows after calling - result->close()). (Ilia,Tony) -- Fixed bug #36403 (oci_execute() no longer supports OCI_DESCRIBE_ONLY). (Tony) -- Fixed bug #36400 (Custom 5xx error does not return correct HTTP response error - code). (Tony) -- Fixed bug #36396 (strtotime() fails to parse dates in dd-mm-yyyy format). - (Derick) -- Fixed bug #36388 (ext/soap crashes when throwing exception and session - persistence). (David) -- Fixed bug #36382 (PDO/PgSQL's getColumnMeta() crashes). (Derick) -- Fixed bug #36359 (splFileObject::fwrite() doesn't write when no data - length specified). (Tony) -- Fixed bug #36351 (parse_url() does not parse numeric paths properly). (Ilia) -- Fixed bug #36345 (PDO/MySQL problem loading BLOB over 1MB). (Ilia) -- Fixed bug #36337 (ReflectionProperty fails to return correct visibility). - (Ilia) -- Fixed bug #36334 (Added missing documentation about realpath cache INI - settings). (Ilia) -- Fixed bug #36308 (ReflectionProperty::getDocComment() does not reflect - extended class commentary). (Ilia) -- Fixed bug #36306 (crc32() differ on 32-bit and 64-bit platforms) - (anight@eyelinkmedia dot com, Pierre) -- Fixed bug #36303 (foreach on error_zval produces segfault). (Dmitry) -- Fixed bug #36295 (typo in SplFileObject::flock() parameter name). (Tony) -- Fixed bug #36287 (Segfault with SplFileInfo conversion). (Marcus) -- Fixed bug #36283 (SOAPClient Compression Broken). (Dmitry) -- Fixed bug #36268 (Object destructors called even after fatal errors). (Dmitry) -- Fixed bug #36258 (SplFileObject::getPath() may lead to segfault). (Tony) -- Fixed bug #36250 (PHP causes ORA-07445 core dump in Oracle server 9.2.x). - (Tony) -- Fixed bug #36242 (Possible memory corruption in stream_select()). (Tony) -- Fixed bug #36235 (ocicolumnname returns false before a successful fetch). - (Tony) -- Fixed bug #36226 (Inconsistent handling when passing potential arrays). - (Dmitry) -- Fixed bug #36224 (date(DATE_ATOM) gives wrong results). - (Derick, Hannes Magnusson) -- Fixed bug #36222 (errorInfo in PDOException is always NULL). (Ilia) -- Fixed bug #36208 (symbol namespace conflicts using bundled gd). (Jakub Moc) -- Fixed bug #36205 (Memory leaks on duplicate cookies). (Dmitry) -- Fixed bug #36185 (str_rot13() crash on non-string parameter). (Pierre) -- Fixed bug #36176 (PDO_PGSQL - PDO::exec() does not return number of rows - affected by the operation). (Ilia) -- Fixed bug #36158 (SIGTERM is not handled correctly when running as a - FastCGI server). (Dmitry) -- Fixed bug #36152 (problems with curl+ssl and pgsql+ssl in same PHP). (Mike) -- Fixed bug #36148 (unpack("H*hex", $data) is adding an extra character to - the end of the string). (Ilia) -- Fixed bug #36134 (DirectoryIterator constructor failed to detect empty - directory names). (Ilia) -- Fixed bug #36113 (Reading records of unsupported type causes segfault). - (Tony) -- Fixed bug #36096 (oci_result() returns garbage after oci_fetch() failed). - (Tony) -- Fixed bug #36083 (SoapClient waits for responses on one-way operations). - (Dmitry) -- Fixed bug #36071 (Engine Crash related with 'clone'). (Dmitry) -- Fixed bug #36055 (possible OCI8 crash in multi-threaded environment). (Tony) -- Fixed bug #36046 (parse_ini_file() miscounts lines in multi-line values). - (Ilia) -- Fixed bug #36038 (ext/hash compile failure on Mac OSX). (Tony) -- Fixed bug #36037 (heredoc adds extra line number). (Dmitry) -- Fixed bug #36016 (realpath cache memleaks). (Dmitry, Nuno) -- Fixed bug #36011 (Strict errormsg wrong for call_user_func() and the likes). - (Marcus) -- Fixed bug #36010 (Segfault when re-creating and re-executing statements with - bound parameters). (Tony) -- Fixed bug #36006 (Problem with $this in __destruct()). (Dmitry) -- Fixed bug #35999 (recursive mkdir() does not work with relative path - like "foo/bar"). (Tony) -- Fixed bug #35998 (SplFileInfo::getPathname() returns unix style filenames - in win32). (Marcus) -- Fixed bug #35988 (Unknown persistent list entry type in module shutdown). - (Dmitry) -- Fixed bug #35954 (Fatal com_exception casting object). (Rob) -- Fixed bug #35900 (stream_select() should warning when tv_sec is negative). - (Ilia) -- Fixed bug #35785 (SimpleXML causes memory read error zend engine). (Marcus) -- Fixed bug #34272 (empty array onto COM object blows up). (Rob) -- Fixed bug #33292 (apache_get_modules() crashes on Windows). (Edin) -- Fixed bug #29476 (sqlite_fetch_column_types() locks the database forever). - (Ilia) - -12 Jan 2006, PHP 5.1.2 -- Updated libsqlite in ext/sqlite to 2.8.17. (Ilia) -- Updated libsqlite in ext/pdo_sqlite to 3.2.8. (Ilia) -- Updated to libxml2-2.6.22 and libxslt-1.1.15 in the win32 bundle. (Rob) -- Added new extensions: (Ilia, Wez) - . XMLWriter - . Hash -- Added PNG compression support to GD extension. (Pierre) -- Added reflection constants as class constants. (Johannes) -- Added --enable-gcov configure option to enable C-level code coverage. - (John, Jani, Ilia, Marcus) -- Added missing support for 'B' format identifier to date() function. (Ilia) -- Changed reflection to be an extension. (Marcus) -- Improved SPL extension: (Marcus) - . Added class SplFileInfo as root class for DirectoryIterator and - SplFileObject - . Added SplTempFileObject -- Improved SimpleXML extension: (Marcus) - . Fixed memleaks - . Fixed var_dump() - . Fixed isset/empty/(bool) behavior - . Fixed iterator edge cases - . Added methods getNamespaces(), getDocNamespaces() -- Upgraded pear to version 1.4.6. (Greg) -- Added constants for libxslt and libexslt versions: LIBXSLT_VERSION, - LIBXSLT_DOTTED_VERSION, LIBEXSLT_VERSION and LIBEXSLT_DOTTED_VERSION. (Pierre) -- Fixed possible crash in apache_getenv()/apache_setenv() on invalid parameters. - (Ilia) -- Changed errors to warnings in imagecolormatch(). (Pierre) -- Fixed segfault/leak in imagecolormatch(). (Pierre) -- Fixed small leak in mysqli_stmt_fetch() when bound variable was empty string. - (Andrey) -- Fixed prepared statement name conflict handling in PDO_PGSQL. (Thies, Ilia) -- Fixed memory corruption when PDO::FETCH_LAZY mode is being used. (Ilia) -- Fixed possible leaks in imagecreatefromstring() with invalid data. (Pierre) -- Fixed possible memory corruption inside mb_strcut(). (Ilia) -- Fixed possible header injection by limiting each header to a single line. - (Ilia) -- Fixed possible XSS inside error reporting functionality. (Ilia) -- Fixed many bugs in OCI8. (Tony) -- Fixed crash and leak in mysqli when using 4.1.x client libraries and - connecting to 5.x server. (Andrey) -- Fixed bug #35916 (Duplicate calls to stream_bucket_append() lead to a crash). - (Ilia) -- Fixed bug #35908 (curl extension uses undefined GCRY_THREAD_OPTIONS_USER). - (Ilia) -- Fixed bug #35907 (PDO_OCI uses hardcoded lib path $ORACLE_HOME/lib). (Tony) -- Fixed bug #35887 (wddx_deserialize not parsing dateTime fields properly). - (Derick) -- Fixed bug #35885 (strtotime("NOW") no longer works). (Derick) -- Fixed bug #35821 (array_map() segfaults when exception is throwed from - the callback). (Tony) -- Fixed bug #35817 (unpack() does not decode odd number of hexadecimal values). - (Ilia) -- Fixed bug #35797 (segfault on PDOStatement::execute() with - zend.ze1_compatibility_mode = On). (Tony, Ilia) -- Fixed bug #35781 (stream_filter_append() can cause segfault). (Tony) -- Fixed bug #35760 (sybase_ct doesn't compile on Solaris using old gcc). (Tony) -- Fixed bug #35759 (mysqli_stmt_bind_result() makes huge allocation when - column empty). (Andrey) -- Fixed bug #35751 (using date with a timestamp makes httpd segfault). (Derick) -- Fixed bug #35740 (memory leak when including a directory). (Tony) -- Fixed bug #35730 (ext/mssql + freetds: Use correct character encoding - and allow setting it). (Frank) -- Fixed bug #35723 (xmlrpc_introspection.c fails compile per C99 std). (Jani) -- Fixed bug #35720 (A final constructor can be overwritten). (Marcus) -- Fixed bug #35713 (getopt() returns array with numeric strings when passed - options like '-1'). (Tony) -- Fixed bug #35705 (strtotime() fails to parse soap date format without TZ). - (Ilia) -- Fixed bug #35699 (date() can't handle leap years before 1970). (Derick) -- Fixed bug #35694 (Improved error message for invalid fetch mode). (Ilia) -- Fixed bug #35692 (iconv_mime_decode() segmentation fault; with libiconv - only). (Tony) -- Fixed bug #35690 (pack() tries to allocate huge memory block when packing - float values to strings). (Tony) -- Fixed bug #35669 (imap_mail_compose() crashes with - multipart-multiboundary-email). (Ilia) -- Fixed bug #35660 (AIX TZ variable format not understood, yields UTC - timezone). (Derick) -- Fixed bug #35655 (whitespace following end of heredoc is lost). (Ilia) -- Fixed bug #35630 (strtotime() crashes on certain relative identifiers). - (Ilia) -- Fixed bug #35629 (crash in http:// wrapper on multiple redirects). (Ilia) -- Fixed bug #35624 (strtotime() does not handle 3 character weekdays). (Ilia) -- Fixed bug #35612 (iis6 Access Violation crash). (Dmitry, alacn.uhahaa) -- Fixed bug #35594 (Multiple calls to getopt() may result in a crash). - (rabbitt at gmail dot com, Ilia) -- Fixed bug #35571 (Fixed crash in Apache 2 SAPI when more then one php - script is loaded via SSI include). (Ilia) -- Fixed bug #35570 (segfault when re-using soap client object). (Dmitry) -- Fixed bug #35558 (mktime() interpreting 3 digit years incorrectly). (Ilia) -- Fixed bug #35543 (php crash when calling non existing method of a class - that extends PDO). (Tony) -- Fixed bug #35539 (typo in error message for ErrorException). (Tony) -- FIxed bug #35536 (mysql_field_type() doesn't handle NEWDECIMAL). (Tony) -- Fixed bug #35517 (mysql_stmt_fetch returns NULL on data truncation). (Georg) -- Fixed bug #35509 (string constant as array key has different behavior inside - object). (Dmitry) -- Fixed bug #35508 (PDO fails when unknown fetch mode specified). (Tony) -- Fixed bug #35499 (strtotime() does not handle whitespace around the date - string). (Ilia) -- Fixed bug #35496 (Crash in mcrypt_generic()/mdecrypt_generic() without - proper init). (Ilia) -- Fixed bug #35490 (socket_sendto() unable to handle IPv6 addresses). (Tony) -- Fixed bug #35461 (Ming extension fails to compile with ming 0.3beta1). (Jani) -- Fixed bug #35437 (Segfault or Invalid Opcode 137/1/4). (Dmitry) -- Fixed bug #35470 (Assigning global using variable name from array doesn't - function). (Dmitry) -- Fixed bug #35456 (+ 1 [time unit] format did not work). (Ilia) -- Fixed bug #35447 (xml_parse_into_struct() chokes on the UTF-8 BOM). (Rob) -- Fixed bug #35431 (PDO crashes when using LAZY fetch with fetchAll). (Wez) -- Fixed bug #35430 (PDO crashes on incorrect FETCH_FUNC use). (Tony) -- Fixed bug #35427 (str_word_count() handles '-' incorrectly). (Ilia) -- Fixed bug #35425 (idate() function ignores timezone settings). (Ilia) -- Fixed bug #35422 (strtotime() does not parse times with UTC as timezone). - (Ilia) -- Fixed bug #35414 (strtotime() no longer works with ordinal suffix). (Ilia) -- Fixed bug #35410 (wddx_deserialize() doesn't handle large ints as keys - properly). (Ilia) -- Fixed bug #35409 (undefined reference to 'rl_completion_matches'). (Jani) -- Fixed bug #35399 (Since fix of bug #35273 SOAP decoding of - soapenc:base64binary fails). (Dmitry) -- Fixed bug #35393 (changing static protected members from outside the class, - one more reference issue). (Dmitry) -- Fixed bug #35381 (ssl library is not initialized properly). (Alan) -- Fixed bug #35377 (PDO_SQLITE: undefined reference to "fdatasync"). - (Nuno, Jani) -- Fixed bug #35373 (HP-UX "alias not allowed in this configuration"). (Dmitry) -- Fixed bug #35288 (iconv() function defined as libiconv()). (Nuno) -- Fixed bug #35103 (mysqli handles bad unsigned (big)int incorrectly).(Andrey) -- Fixed bug #35062 (socket_read() produces warnings on non blocking sockets). - (Nuno, Ilia) -- Fixed bug #35028 (SimpleXML object fails FALSE test). (Marcus) -- Fixed bug #34729 (Crash in ZTS mode under Apache). (Dmitry, Zeev) -- Fixed bug #34429 (Output buffering cannot be turned off with FastCGI). - (Dmitry, Ilya) -- Fixed bug #34359 (Possible crash inside fopen http wrapper). (Ilia,Sara,Nuno) -- Fixed bug #33789 (Many Problems with SunFuncs). (Derick) -- Fixed bug #33671 (sun_rise and sun_set don't return a GMT timestamp if one - passes an offset). (Derick) -- Fixed bug #32820 (date_sunrise and date_sunset don't handle GMT offset - well). (Derick) -- Fixed bug #31347 (is_dir and is_file (incorrectly) return true for any string - greater then 255 characters). (Nuno,Ilia) -- Fixed bug #30937 (date_sunrise() & date_sunset() don't handle endless - day/night at high latitudes). (Derick) -- Fixed bug #30760 (Remove MessageBox on win32 for E_CORE errors if - display_startup_error is off). (Ilia) -- Fixed bug #29955 (mb_strtoupper() / lower() broken with Turkish encoding). - (Rui) -- Fixed bug #28899 (mb_substr() and substr() behave differently when - "mbstring.func_overload" is enabled). (Rui) -- Fixed bug #27678 (number_format() crashes with large numbers). (Marcus) - -28 Nov 2005, PHP 5.1.1 -- Disabled native date class to prevent pear::date conflict. (Ilia) -- Changed reflection constants be both PHP and class constants. (Johannes) -- Added an additional field $frame['object'] to the result array of - debug_backtrace() that contains a reference to the respective object when the - frame was called from an object. (Sebastian) -- Fixed bug #35423 (RecursiveDirectoryIterator doesnt appear to recurse with - RecursiveFilterIterator). (Marcus) -- Fixed bug #35413 (Removed -dev flag from Zend Engine version). (Ilia) -- Fixed bug #35411 (Regression with \{$ handling). (Ilia) -- Fixed bug #35406 (eval hangs when evall'ed code ends with comment w/o - newline). (Marcus) -- Fixed bug #35391 (pdo_mysql::exec does not return number of affected rows). - (Tony) -- Fixed bug #35382 (Comment in end of file produces fatal error). (Ilia) -- Fixed bug #35360 (exceptions in interactive mode (php -a) may cause crash). - (Dmitry) -- Fixed bug #35358 (Incorrect error messages for PDO class constants). (Ilia) -- Fixed bug #35338 (pdo_pgsql does not handle binary bound params). (Wez) -- Fixed bug #35316 (Application exception trying to create COM object). (Rob) -- Fixed bug #35170 (PHP_AUTH_DIGEST differs under Apache 1.x and 2.x). (Ilia) - -24 Nov 2005, PHP 5.1 -- Added support for class constants and static members for internal classes. - (Dmitry, Michael Wallner) -- Added "new_link" parameter to mssql_connect() (Bug #34369). (Frank) -- Added missing safe_mode checks for image* functions and cURL. (Ilia) -- Added missing safe_mode/open_basedir checks for file uploads. (Ilia) -- Added PDO_MYSQL_ATTR_USE_BUFFERED_QUERY parameter for pdo_mysql. (Ilia) -- Added date_timezone_set() function to set the timezone that the date - function will use. (Derick) -- Added pg_fetch_all_columns() function to fetch all values of a column from a - result cursor. (Ilia) -- Added support for LOCK_EX flag for file_put_contents(). (Ilia) -- Added bindto socket context option. (Ilia) -- Added offset parameter to the stream_copy_to_stream() function. (Ilia) -- Added offset & length parameters to substr_count() function. (Ilia) -- Added man pages for "phpize" and "php-config" scripts. (Jakub Vrana) -- Added support for .cc files in extensions. (Brian) -- Added PHP_INT_MAX and PHP_INT_SIZE as predefined constants. (Andrey) -- Added user opcode API that allow overloading of opcode handlers. (Dmitry) -- Added an optional remove old session parameter to session_regenerate_id(). - (Ilia) -- Added array type hinting. (Dmitry) -- Added the tidy_get_opt_doc() function to return documentation for - configuration options in tidy. (Patch by: nlopess@php.net) -- Added support for .cc files in extensions. (Brian) -- Added imageconvolution() function which can be used to apply a custom 3x3 - matrix convolution to an image. (Pierre) -- Added optional first parameter to XsltProcessor::registerPHPFunctions to - only allow certain functions to be called from XSLT. (Christian) -- Added the ability to override the autotools executables used by the - buildconf script via the PHP_AUTOCONF and PHP_AUTOHEADER environmental - variables. (Jon) -- Added several new functions to support the PostgreSQL v3 protocol introduced - in PostgreSQL 7.4. (Christopher) - . pg_transaction_status() - in-transaction status of a database connection. - . pg_query_params() - execution of parameterized queries. - . pg_prepare() - prepare named queries. - . pg_execute() - execution of named prepared queries. - . pg_send_query_params() - async equivalent of pg_query_params(). - . pg_send_prepare() - async equivalent of pg_prepare(). - . pg_send_execute() - async equivalent of pg_execute(). - . pg_result_error_field() - highly detailed error information, most - importantly - the SQLSTATE error code. - . pg_set_error_verbosity() - set verbosity of errors. -- Added optional fifth parameter "count" to preg_replace_callback() and - preg_replace() to count the number of replacements made. FR #32275. (Andrey) -- Added optional third parameter "charlist" to str_word_count() which contains - characters to be considered as word part. FR #31560. (Andrey, Ilia) -- Added interface Serializable. (Stanislav, Marcus) -- Added pg_field_type_oid() PostgreSQL function. (mauroi at digbang dot com) -- Added zend_declare_property_...() and zend_update_property_...() API - functions for bool, double and binary safe strings. (Hartmut) -- Added possibility to access INI variables from within .ini file. (Andrei) -- Added variable $_SERVER['REQUEST_TIME'] containing request start time. - (Ilia) -- Added optional float parameter to gettimeofday(). (Ilia) -- Added apache_reset_timeout() Apache1 function. (Rasmus) -- Added sqlite_fetch_column_types() 3rd argument for arrays. (Ilia) -- Added optional offset parameter to stream_get_contents() and - file_get_contents(). (Ilia) -- Added optional maxlen parameter to file_get_contents(). (Ilia) -- Added SAPI hook to get the current request time. (Rasmus) -- Added new functions: - . array_diff_key() (Andrey) - . array_diff_ukey() (Andrey) - . array_intersect_key() (Christiano Duarte) - . array_intersect_ukey() (Christiano Duarte) - . array_product() (Andrey) - . DomDocumentFragment::appendXML() (Christian) - . fputcsv() (David Sklar) - . htmlspecialchars_decode() (Ilia) - . inet_pton() (Sara) - . inet_ntop() (Sara) - . mysqli::client_info property (Georg) - . posix_access() (Magnus) - . posix_mknod() (Magnus) - . SimpleXMLElement::registerXPathNamespace() (Christian) - . stream_context_get_default() (Wez) - . stream_socket_enable_crypto() (Wez) - . stream_wrapper_unregister() (Sara) - . stream_wrapper_restore() (Sara) - . stream_filter_remove() (Sara) - . time_sleep_until() (Ilia) -- Added DomDocument::$recover property for parsing not well-formed XML - Documents. (Christian) -- Added Cursor support for MySQL 5.0.x in mysqli (Georg) -- Added proxy support to ftp wrapper via http. (Sara) -- Added MDTM support to ftp_url_stat. (Sara) -- Added zlib stream filter support. (Sara) -- Added bz2 stream filter support. (Sara) -- Added max_redirects context option that specifies how many HTTP - redirects to follow. (Ilia) -- Added support of parameter=>value arrays to - xsl_xsltprocessor_set_parameter(). (Tony) - -- PHP extension loading mechanism with support for module - dependencies and conflicts. (Jani, Dmitry) -- Improved interactive mode of PHP CLI (php -a). (Johannes, Marcus) -- Improved performance of: - . general execution/compilation. (Andi, Thies, Sterling, Dmitry, Marcus) - . switch() statement. (Dmitry) - . several array functions. (Marcus) - . virtual path handling by adding a realpath() cache. (Andi) - . variable fetches. (Andi) - . magic method invocations. (Marcus) -- Improved support for embedded server in mysqli. (Georg) -- Improved mysqli extension. (Georg) - . added constructor for mysqli_stmt and mysqli_result classes - . added new function mysqli_get_charset() - . added new function mysqli_set_charset() - . added new class mysqli_driver - . added new class mysqli_warning - . added new class mysqli_exception - . added new class mysqli_sql_exception -- Improved SPL extension. (Marcus) - . Moved RecursiveArrayIterator from examples into extension - . Moved RecursiveFilterIterator from examples into extension - . Added SplObjectStorage - . Made all SPL constants class constants - . Renamed CachingRecursiveIterator to RecursiveCachingIterator to follow - Recursive<*>Iterator naming scheme. - . added standard hierarchy of Exception classes - . added interface Countable - . added interfaces Subject and SplObserver - . added spl_autoload*() functions - . converted several 5.0 examples into c code - . added class SplFileObject - . added possibility to use a string with class_parents() and - class_implements(). (Andrey) - -- Changed type hints to allow "null" as default value for class and array. - (Marcus, Derick, Dmitry) -- Changed SQLite extension to be a shared module in Windows distribution. - (Edin) -- Changed "instanceof" and "catch" operators, is_a() and is_subclass_of() - functions to not call __autoload(). (Dmitry) -- Changed sha1_file() and md5_file() functions to use streams instead of low - level IO. (Uwe) -- Changed abstract private methods to be not allowed anymore. (Stas) -- Changed stream_filter_(ap|pre)pend() to return resource. (Sara) -- Changed mysqli_exception and sqlite_exception to use RuntimeException as - base if SPL extension is present. (Georg, Marcus) - -- Upgraded bundled libraries: - . PCRE library to version 6.2. (Andrei) - . SQLite 3 library in ext/pdo_sqlite to 3.2.7. (Ilia) - . SQLite 2 library in ext/sqlite to 2.8.16. (Ilia) -- Upgraded bundled libraries in Windows distribution. (Edin) - . zlib 1.2.3 - . curl 7.14.0 - . openssl 0.9.8 - . ming 0.3b - . libpq (PostgreSQL) 8.0.1 - -- Implemented feature request #33452 (Year belonging to ISO week). (Derick) -- Allowed return by reference from internal functions. (Marcus, Andi, Dmitry) -- Rewrote strtotime() with support for timezones and many new formats. - Implements feature requests #21399, #26694, #28088, #29150, #29585 and - #29595. (Derick) - -- Moved extensions to PECL: - . ext/cpdf (Tony, Derick) - . ext/dio (Jani, Derick) - . ext/fam (Jani, Derick) - . ext/ingres_ii (Jani, Derick) - . ext/mnogosearch (Jani, Derick) - . ext/w32api (Jani, Derick) - . ext/yp (Jani, Derick) - . ext/mcve (Jani, Derick, Pierre) - . ext/oracle (Jani, Derick) - . ext/ovrimos (Jani, Derick, Pierre) - . ext/pfpro (Jani, Derick, Pierre) - . ext/dbx (Jani, Derick) - . ext/ircg (Jani, Derick) - -- Removed php_check_syntax() function which never worked properly. (Ilia) -- Removed garbage manager in Zend Engine which results in more aggressive - freeing of data. (Dmitry, Andi) - -- Fixed "make test" to work for phpized extensions. (Hartmut, Jani) -- Fixed Apache 2 regression with sub-request handling on non-linux systems. - (Ilia, Tony) -- Fixed PDO shutdown problem (possible infinite loop running rollback on - shutdown). (Wez) -- Fixed PECL bug #3714 (PDO: beginTransaction doesn't work if you're in - auto-commit mode). (Wez) -- Fixed ZTS destruction. (Marcus) -- Fixed __get/__set to allow recursive calls for different properties. (Dmitry) -- Fixed a bug where stream_get_meta_data() did not return the "uri" element - for files opened with tmpname(). (Derick) -- Fixed a problem with SPL iterators aggregating the inner iterator. (Marcus) -- Fixed an error in mysqli_fetch_fields (returned NULL instead of an array - when row number > field_count). (Georg) -- Fixed bug in mysql::client_version(). (Georg) -- Fixed bug in mysqli extension with unsigned int(11) being represented as - signed integer in PHP instead of string in 32bit systems. (Andrey) -- Fixed bug with $HTTP_RAW_POST_DATA not getting set. (Brian) -- Fixed crash inside stream_get_line() when length parameter equals 0. (Ilia) -- Fixed ext/mysqli to allocate less memory when fetching bound params of type - (MEDIUM|LONG)BLOB/(MEDIUM|LONG)TEXT. (Andrey) -- Fixed extension initialization to respect dependencies between extensions. - (Wez) -- Fixed failing queries (FALSE returned) with mysqli_query() on 64 bit systems. - (Andrey) -- Fixed fgetcsv() and fputcsv() inconsistency. (Dmitry) -- Fixed inheritance check to control return by reference and pass by - reference correctly (ArrayAccess can no longer support references correctly). - (Marcus, Andi, Dmitry) -- Fixed initializing and argument checking for posix_mknod(). (Derick) -- Fixed memory corruption in ImageTTFText() with 64bit systems. (Andrey) -- Fixed memory corruption in pg_copy_from() in case the as_null parameter was - passed. (Derick) -- Fixed memory corruption in stristr(). (Derick) -- Fixed possible GLOBALS variable override when register_globals are ON. - (Ilia, Stefan) -- Fixed possible INI setting leak via virtual() in Apache 2 sapi. (Ilia) -- Fixed possible register_globals toggle via parse_str(). (Ilia, Stefan) -- Fixed potential GLOBALS overwrite via import_request_variables() and - possible crash and/or memory corruption. (Ilia) -- Fixed segfaults when CURL callback functions throw exception. (Tony) -- Fixed support for shared extensions on AIX. (Dmitry) -- Fixed bug #35342 (isset(DOMNodeList->length) returns false). (Rob) -- Fixed bug #35341 (Fix for bug #33760 breaks build with older curl). (Tony) -- Fixed bug #35336 (crash on PDO::FETCH_CLASS + __set()). (Tony) -- Fixed bug #35303 (PDO prepare() crashes with invalid parameters). (Ilia) -- Fixed bug #35293 (PDO segfaults when using persistent connections). (Tony) -- Fixed bug #35278 (Multiple virtual() calls crash Apache 2 php module). (Ilia) -- Fixed bug #35273 (Error in mapping soap - java types). (Dmitry) -- Fixed bug #35249 (compile failure when ext/readline is compiled as shared). - (Jani) -- Fixed bug #35248 (sqlite_query() doesn't set error_msg when return value is - being used). (Ilia) -- Fixed bug #35243 (php_mblen() crashes when compiled with thread-safety on - Linux). (Patch: shulmanb at il dot ibm dot com, Jani) -- Fixed bug #35239 (Objects can lose references). (Dmitry) -- Fixed bug #35229 (call_user_func() crashes when argument_stack is nearly - full). (Dmitry) -- Fixed bug #35197 (Destructor is not called). (Tony) -- Fixed bug #35179 (tokenizer extension needs T_HALT_COMPILER). (Greg) -- Fixed bug #35176 (include()/require()/*_once() produce wrong error messages - about main()). (Dmitry) -- Fixed bug #35147 (__HALT_COMPILER() breaks with --enable-zend-multibyte). - (Dmitry, Moriyoshi) -- Fixed bug #35143 (gettimeofday() ignores current time zone). (Derick) -- Fixed bug #35142 (SOAP Client/Server Complex Object Support). (Dmitry) -- Fixed bug #35135 (PDOStatment without related PDO object may crash). (Ilia) -- Fixed bug #35091 (SoapClient leaks memory). (Dmitry) -- Fixed bug #35079 (stream_set_blocking(true) toggles, not enables blocking). - (askalski at gmail dot com, Tony) -- Fixed bug #35078 (configure does not find ldap_start_tls_s). (Jani) -- Fixed bug #35046 (phpinfo() uses improper css enclosure). (Ilia) -- Fixed bugs #35022, #35019 (Regression in the behavior of key() and - current() functions). (Ilia) -- Fixed bug #35017 (Exception thrown in error handler may cause unexpected - behavior). (Dmitry) -- Fixed bug #35014 (array_product() always returns 0). (Ilia) -- Fixed bug #35009 (ZTS: Persistent resource destruct crashes when extension - is compiled as shared). (Dmitry) -- Fixed bug #34996 (ImageTrueColorToPalette() crashes when ncolors is zero). - (Tony) -- Fixed bug #34982 (array_walk_recursive() modifies elements outside function - scope). (Dmitry) -- Fixed bug #34977 (Compile failure on MacOSX due to use of varargs.h). (Tony) -- Fixed bug #34968 (bz2 extension fails on to build on some win32 setups). - (Ilia) -- Fixed bug #34965 (tidy is not binary safe). (Mike) -- Fixed bug #34957 (PHP doesn't respect ACLs for access checks). (Wez) -- Fixed bug #34950 (Unable to get WSDL through proxy). (Dmitry) -- Fixed bug #34938 (dns_get_record() doesn't resolve long hostnames and - leaks). (Tony) -- Fixed bug #34905 (Digest authentication does not work with Apache 1). (Ilia) -- Fixed bug #34902 (mysqli::character_set_name() - undefined method). (Tony) -- Fixed bug #34899 (Fixed sqlite extension compile failure). (Ilia) -- Fixed bug #34893 (PHP5.1 overloading, Cannot access private property). - (Dmitry) -- Fixed bug #34884 (Possible crash in ext/sqlite when sqlite.assoc_case is - being used). (Tony, Ilia) -- Fixed bug #34879 (str_replace, array_map corrupt negative array indexes on - 64-bit platforms). (Dmitry) -- Fixed bug #34873 (Segmentation Fault on foreach in object). (Dmitry) -- Fixed bug #34856 (configure fails to detect libiconv's type). (Tony) -- Fixed bug #34855 (ibase_service_attach() segfault on AMD64). - (irie at gmx dot de, Tony) -- Fixed bug #34851 (SO_RECVTIMEO and SO_SNDTIMEO socket options expect - integer parameter on Windows). (Mike) -- Fixed bug #34850 (--program-suffix and --program-prefix not included in - man page names). (Jani) -- Fixed bug #34821 (zlib encoders fail on widely varying binary data on - windows). (Mike, Ilia) -- Fixed bug #34818 (several functions crash when invalid mysqli_link object - is passed). (Tony) -- Fixed bug #34810 (mysqli::init() and others use wrong $this pointer without - checks). (Tony) -- Fixed bug #34809 (FETCH_INTO in PDO crashes without a destination object). - (Ilia) -- Fixed bug #34802 (Fixed crash on object instantiation failure). (Ilia) -- Fixed bug #34796 (missing SSL linking in ext/ftp when configured as shared). - (Jani) -- Fixed bug #34790 (preg_match_all(), named capturing groups, variable - assignment/return => crash). (Dmitry) -- Fixed bug #34788 (SOAP Client not applying correct namespace to generated - values). (Dmitry) -- Fixed bug #34787 (SOAP Client not handling boolean types correctly). (Dmitry) -- Fixed bug #34786 (2 @ results in change to error_reporting() to random - value) (Dmitry, Tony) -- Fixed bug #34785 (subclassing of mysqli_stmt does not work). (Georg) -- Fixed bug #34782 (token_get_all() gives wrong result). (Dmitry) -- Fixed bug #34777 (Crash in dblib when fetching non-existent error info). - (Ilia) -- Fixed bug #34771 (strtotime() fails with 1-12am/pm). (Derick) -- Fixed bug #34767 (Zend Engine 1 Compatibility not copying objects - correctly). (Dmitry) -- Fixed bug #34758 (PDO_DBLIB did not implement rowCount()). (Ilia) -- Fixed bug #34757 (iconv_substr() gives "Unknown error" when offset > string - length). (Tony) -- Fixed bug #34742 (ftp wrapper failures caused from segmented command - transfer). (Ilia) -- Fixed bug #34725 (CLI segmentation faults during cleanup). (Dmitry) -- Fixed bug #34723 (array_count_values() strips leading zeroes). (Tony) -- Fixed bug #34712 (zend.ze1_compatibility_mode = on segfault). (Dmitry) -- Fixed bug #34704 (Infinite recursion due to corrupt JPEG). (Marcus) -- Fixed bug #34678 (__call(), is_callable() and static methods). (Dmitry) -- Fixed bug #34676 (missing support for strtotime("midnight") and - strtotime("noon")). (Derick) -- Fixed bug #34645 (ctype corrupts memory when validating large numbers). - (Ilia) -- Fixed bug #34643 (wsdl default value has no effect). (Dmitry) -- Fixed bug #34623 (Crash in pdo_mysql on longtext fields). (Ilia) -- Fixed bug #34617 (zend_deactivate: objects_store used after - zend_objects_store_destroy is called). (Dmitry) -- Fixed bug #34590 (User defined PDOStatement class can't implement - methods). (Marcus) -- Fixed bug #34584 (Segfault with SPL autoload handler). (Marcus) -- Fixed bug #34581 (crash with mod_rewrite). (Tony, Ilia) -- Fixed bug #34565 (mb_send_mail does not fetch - mail.force_extra_parameters). (Marco, Ilia) -- Fixed bug #34557 (php -m exits with "error" 1). (Johannes) -- Fixed bug #34518 (Unset doesn't separate container in CV). (Dmitry) -- Fixed bug #34505 (Possible memory corruption when unmangling properties - with empty names). (Tony) -- Fixed bug #34478 (Incorrect parsing of url's fragment (#...)). (Dmitry) -- Fixed bug #34467 (foreach + __get + __set inconsistency). (Dmitry) -- Fixed bug #34456 (Possible crash inside pspell extension). (Ilia) -- Fixed bug #34453 (parsing http://www.w3.org/2001/xml.xsd exception). (Dmitry) -- Fixed bug #34450 (Segfault when calling mysqli_close() in destructor). (Tony) -- Fixed bug #34449 (ext/soap: XSD_ANYXML functionality not exposed). (Dmitry) -- Fixed bug #34420 (Possible crash inside curl_multi_remove_handle()). (Ilia) -- Fixed bug #34358 (Fatal error: Cannot re-assign $this). (Dmitry) -- Fixed bug #34331 (php crashes when variables_order is empty). (Ilia) -- Fixed bug #34321 (Possible crash in filter code). (Ilia) -- Fixed bug #34311 (unserialize() crashes with chars above 191 dec). (Nuno) -- Fixed bug #34310 (foreach($arr as $c->d => $x) crashes). (Dmitry) -- Fixed bug #34307 (on_modify handler not called to set the default value if - setting from php.ini was invalid). (Andrei) -- Fixed bug #34306 (wddx_serialize_value() crashes with long array keys). - (Jani) -- Fixed bug #34304 (date() doesn't have a modifier for ISO Week Day). (Derick) -- Fixed bug #34302 (date('W') do not return leading zeros for week 1 to 9). - (Derick) -- Fixed bug #34299 (ReflectionClass::isInstantiable() returns true for abstract - classes). (Marcus) -- Fixed bug #34284 (CLI phpinfo showing html on _SERVER["argv"]). (Jani) -- Fixed bug #34277 (array_filter() crashes with references and objects). - (Dmitry) -- Fixed bug #34276 (setAttributeNS doesn't work with default namespace). - (Rob) -- Fixed bug #34260 (Segfault with callbacks (array_map) + overloading). - (Dmitry) -- Fixed bug #34257 (lib64 not handled correctly in ming extension). (Marcus) -- Fixed bug #34221 (Compiling xmlrpc as shared fails other parts). (Jani) -- Fixed bug #34216 (Segfault with autoload). (Marcus) -- Fixed bug #34199 (if($obj)/if(!$obj) inconsistency because of cast handler). - (Dmitry, Alex) -- Fixed bug #34191 (ob_gzhandler does not enforce trailing \0). (Ilia) -- Fixed bug #34156 (memory usage remains elevated after memory limit is - reached). (Ilia) -- Fixed bug #34148 (+,- and . not supported as parts of scheme). (Ilia) -- Fixed bug #34137 (assigning array element by reference causes binary mess). - (Dmitry) -- Fixed bug #34103 (line numbering not maintained in dom document). (Rob) -- Fixed bug #34078 (Reflection API problems in methods with boolean or - null default values). (Tony) -- Fixed bug #34068 (Numeric string as array key not cast to integer in - wddx_deserialize()). (Ilia) -- 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 #34052 (date('U') returns %ld not unix timestamp). (Nuno) -- Fixed bug #34045 (Buffer overflow with serialized object). (Dmitry) -- Fixed bug #34001 (pdo_mysql truncates numeric fields at 4 chars). (Ilia) -- 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) -- Fixed bug #33989 (extract($GLOBALS,EXTR_REFS) crashes PHP). (Dmitry) -- Fixed bug #33987 (php script as ErrorDocument causes crash in Apache 2). - (Ilia) -- Fixed bug #33967 (misuse of Exception constructor doesn't display - errorfile). (Jani) -- Fixed bug #33966 (Wrong use of reflectionproperty causes a segfault). (Tony) -- Fixed bug #33963 (mssql_bind() fails on input parameters). (Frank) -- Fixed bug #33958 (duplicate cookies and magic_quotes=off may cause a crash). - (Ilia) -- Fixed bug #33957 (gmdate('W')/date('W') sometimes returns wrong week number). - (Derick) -- 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) -- Fixed bug #33903 (spl_autoload_register class method). (Marcus) -- Fixed bug #33899 (CLI: setting extension_dir=some/path extension=foobar.so - does not work). (Jani) -- Fixed bug #33882 (CLI was looking for php.ini in wrong path). (Hartmut) -- Fixed bug #33869 (strtotime() problem with "+1days" format). (Ilia) -- Fixed bug #33841 (pdo sqlite driver forgets to update affected column - count on execution of prepared statments). (Ilia) -- Fixed bug #33837 (Informix ESQL version numbering schema changed). (Jani) -- Fixed bug #33829 (mime_content_type() returns text/plain for gzip and bzip - files). (Derick) -- Fixed bug #33802 (throw Exception in error handler causes crash). (Dmitry) -- Fixed bug #33771 (error_reporting falls to 0 when @ was used inside - try/catch block). (Tony) -- Fixed bug #33760 (cURL needs to implement CRYPTO_callback functions to - prevent locking). (Mike, Ilia) -- Fixed bug #33732 (Wrong behavior of constants in class and interface - extending). (Dmitry) -- Fixed bug #33723 (php_value overrides php_admin_value). (Dmitry) -- Fixed bug #33720 (mb_encode_mimeheader does not work for multibyte - chars). (Rui) -- Fixed bug #33710 (ArrayAccess objects does not initialize $this). (Dmitry) -- Fixed bug #33690 (Crash setting some ini directives in httpd.conf). (Rasmus) -- Fixed bug #33673 (Added detection for partially uploaded files). (Ilia) -- Fixed bug #33605 (substr_compare() crashes with negative offset and length). - (Tony) -- Fixed bug #33597 (setcookie() "expires" date format doesn't comply with RFC). - (Tony) -- Fixed bug #33588 (LDAP: RootDSE query not possible). (Jani) -- Fixed bug #33578 (strtotime() problem with "Oct17" format). (Derick) -- Fixed bug #33578 (strtotime() doesn't understand "11 Oct" format). (Derick) -- Fixed bug #33562 (date("") crashes). (Derick) -- Fixed bug #33558 (warning with nested calls to functions returning by - reference). (Dmitry) -- Fixed bug #33536 (strtotime() defaults to now even on non time string). - (Derick) -- Fixed bug #33532 (Different output for strftime() and date()). (Derick) -- Fixed bug #33523 (Memory leak in xmlrpc_encode_request()). (Ilia) -- Fixed bug #33520 (crash if safe_mode is on and session.save_path is changed). - (Dmitry) -- Fixed bug #33512 (Add missing support for isset()/unset() overloading to - complement the property get/set methods). (Dmitry) -- Fixed bug #33491 (crash after extending MySQLi internal class). (Tony) -- Fixed bug #33475 (cURL handle is not closed on curl_close(). (Ilia) -- Fixed bug #33469 (Compile error undefined reference to ifx_checkAPI). (Jani) -- Fixed bug #33433 (strtoll not available on Tru64). (Jani, Derick) -- Fixed bug #33427 (ext/odbc: check if unixODBC header file exists). (Jani) -- Fixed bug #33415 (strtotime() related bugs). (Derick) -- Fixed bug #33414 (Comprehensive list of incorrect days returned after - strtotime() / date() tests). (Derick) -- Fixed bug #33389 (double free() when exporting a ReflectionClass). (Marcus) -- Fixed bug #33383 (crash when retrieving empty LOBs). (Tony) -- Fixed bug #33382 (array_reverse() fails after *sort()), introduced by - zend_hash_sort() optimizations in HEAD. (Tony) -- Fixed bug #33340 (CLI Crash when calling php:function from XSLT). (Rob) -- Fixed bug #33326 (Cannot build extensions with phpize on Macosx). (Jani) -- Fixed bug #33318 (throw 1; results in Invalid opcode 108/1/8). (Dmitry) -- Fixed bug #33312 (ReflectionParameter methods do not work correctly). - (Dmitry) -- Fixed bug #33299 (php:function no longer handles returned dom objects). - (Rob, Joe Orton) -- Fixed bug #33286 (nested array_walk() calls and user array compare functions - broken; FCI cache). (Andrei, patch from m.bretz@metropolis-ag.de) -- Fixed bug #33277 (private method accessed by child class). (Dmitry) -- Fixed bug #33268 (iconv_strlen() works only with a parameter of < 3 in - length). (Ilia) -- Fixed bug #33257 (array_splice() inconsistent when passed function instead of - variable). (Dmitry) -- Fixed bug #33243 (ze1_compatibility_mode does not work as expected). (Dmitry) -- Fixed bug #33242 (Mangled error message when stream fails). (Derick) -- Fixed bug #33222 (segfault when CURL handle is closed in a callback). (Tony) -- Fixed bug #33214 (odbc_next_result does not signal SQL errors with - 2-statement SQL batches). (rich at kastle dot com, Tony) -- Fixed bug #33212 ([GCC 4]: 'zend_error_noreturn' aliased to external symbol - 'zend_error'). (Dmitry) -- Fixed bug #33210 (relax jpeg recursive loop protection). (Ilia) -- Fixed bug #33201 (Crash when fetching some data types). (Frank) -- Fixed bug #33200 (preg_replace(): magic_quotes_sybase=On makes 'e' modifier - misbehave). (Jani) -- Fixed bug #33185 (--enable-session=shared does not build). (Jani) -- Fixed bug #33171 (foreach enumerates private fields declared in base - classes). (Dmitry) -- Fixed bug #33167 (Possible crash inside pg_fetch_array()). (Ilia) -- Fixed bug #33164 (Soap extension incorrectly detects HTTP/1.1). (Ilia) -- Fixed bug #33156 (cygwin version of setitimer doesn't accept ITIMER_PROF). - (Nuno) -- Fixed bug #33153 (crash in mssql_next result). (Frank) -- Fixed bug #33150 (shtool: insecure temporary file creation). (Jani) -- Fixed bug #33136 (method offsetSet in class extended from ArrayObject crash - PHP). (Marcus) -- Fixed bug #33125 (imagecopymergegray() produces mosaic rainbow effect). - (Pierre) -- Fixed bug #33116 (crash when assigning class name to global variable in - __autoload). (Dmitry) -- Fixed bug #33090 (mysqli_prepare() doesn't return an error). (Georg) -- Fixed bug #33076 (str_ireplace() incorrectly counts result string length - and may cause segfault). (Tony) -- Fixed bug #33072 (Add a safemode/open_basedir check for runtime - "session.save_path" change using session_save_path() function). (Rasmus) -- Fixed bug #33070 (Improved performance of bzdecompress() by several orders - of magnitude). (Ilia) -- Fixed bug #33059 (crash when moving xml attribute set in dtd). (Ilia) -- Fixed bug #33057 (Don't send extraneous entity-headers on a 304 as per - RFC 2616 section 10.3.5) (Rasmus, Choitel) -- Fixed bug #33019 (socket errors cause memory leaks in php_strerror()). - (jwozniak23 at poczta dot onet dot pl, Tony). -- Fixed bug #33017 ("make distclean" gives an error with VPATH build). (Jani) -- Fixed bug #33013 ("next month" was handled wrong while parsing dates). - (Derick) -- Fixed bug #32993 (implemented Iterator function current() don't throw - exception). (Dmitry) -- Fixed bug #32981 (ReflectionMethod::getStaticVariables() causes apache2.0.54 - seg fault). (Dmitry) -- Fixed bug #32956 (mysql_bind_result() doesn't support MYSQL_TYPE_NULL). - (Georg) -- Fixed bug #32947 (Incorrect option for mysqli default password). (Georg) -- Fixed bug #32944 (Disabling session.use_cookies doesn't prevent reading - session cookies). (Jani, Tony) -- Fixed bug #32941 (Sending structured SOAP fault kills a php). (Dmitry) -- Fixed bug #32937 (open_basedir looses trailing / in the limiter). - (Adam Conrad) -- Fixed bug #32936 (http redirects URLs are not checked for control chars). - (Ilia) -- Fixed bug #32933 (Cannot extend class "SQLiteDatabase"). (Marcus) -- Fixed bug #32932 (Oracle LDAP: ldap_get_entries(), invalid pointer). (Jani) -- Fixed bug #32930 (class extending DOMDocument doesn't clone properly). (Rob) -- Fixed bug #32924 (file included with "auto_prepend_file" can be included - with require_once() or include_once()). (Stas) -- Fixed bug #32904 (pg_get_notify() ignores result_type parameter). (Tony) -- Fixed bug #32852 (Crash with singleton and __destruct when - zend.ze1_compatibility_mode = On). (Dmitry) -- Fixed bug #32833 (Invalid opcode). (Dmitry) -- Fixed bug #32813 (parse_url() does not handle scheme-only urls properly). - (Ilia) -- Fixed bug #32810 (temporary files not using plain file wrapper). (Ilia) -- Fixed bug #32809 (Missing T1LIB support on Windows). (Edin) -- Fixed bug #32802 (General cookie overrides more specific cookie). (Ilia) -- Fixed bugs #32800, #32830 (ext/odbc: Problems with 64bit systems). (Jani) -- Fixed bug #32799 (crash: calling the corresponding global var during the - destruct). (Dmitry) -- Fixed bug #32776 (SOAP doesn't support one-way operations). (Dmitry) -- Fixed bug #32773 (GMP functions break when second parameter is 0). (Stas) -- Fixed bug #32759 (incorrect determination of default value (COM)). (Wez) -- Fixed bug #32758 (Cannot access safearray properties in VB6 objects). (Wez) -- Fixed bug #32755 (Segfault in replaceChild() when DocumentFragment has no - children). (Rob) -- Fixed bug #32753 (Undefined constant SQLITE_NOTADB). (Ilia) -- Fixed bug #32742 (segmentation fault when the stream with a wrapper - is not closed). (Tony, Dmitry) -- Fixed bug #32699 (pg_affected_rows() was defined when it was not available). - (Derick) -- Fixed bug #32686 (Require/include file in destructor causes segfault). - (Marcus) -- Fixed bug #32682 (ext/mssql: Error on module shutdown when called from - activescript). (Frank) -- Fixed bug #32674 (exception in iterator causes crash). (Dmitry) -- Fixed bug #32660 (Assignment by reference causes crash when field access is - overloaded (__get)). (Dmitry) -- Fixed bug #32647 (Using register_shutdown_function() with invalid callback - can crash PHP). (Jani) -- Fixed bug #32615 (Segfault in replaceChild() using fragment when - previousSibling is NULL). (Rob) -- Fixed bug #32613 (ext/snmp: use of snmp_shutdown() causes snmpapp.conf - access errors). (Jani, ric at arizona dot edu) -- Fixed bug #32608 (html_entity_decode() converts single quotes even if - ENT_NOQUOTES is given). (Ilia) -- Fixed bug #32596 (Segfault/Memory Leak by getClass (etc) in __destruct). - (Dmitry) -- Fixed bug #32591 (ext/mysql: Unsatisfied symbol: ntohs with HP-UX). (Jani) -- Fixed bug #32589 (possible crash inside imap_mail_compose() function). - (Ilia) -- Fixed bug #32589 (Possible crash inside imap_mail_compose, with charsets). - (Ilia) -- Fixed bug #32587 (Apache2: errors sent to error_log do not include - timestamps). (Jani) -- Fixed bug #32560 (configure looks for incorrect db2 library). (Tony) -- Fixed bug #32553 (mmap loads only the 1st 2000000 bytes on Win32). (Ilia) -- Fixed bug #32533 (proc_get_status() returns the incorrect process status). - (Ilia) -- Fixed bug #32530 (chunk_split() does not append endstr if chunklen is - longer then the original string). (Ilia) -- Fixed bug #32491 (File upload error - unable to create a temporary file). - (Uwe Schindler) -- Fixed bug #32455 (wrong setting property to unset value). (Dmitry) -- Fixed bug #32429 (method_exists() always return TRUE if __call method - exists). (Dmitry) -- Fixed bug #32428 (The @ warning error suppression operator is broken). - (Dmitry) -- Fixed bug #32427 (Interfaces are not allowed 'static' access modifier). - (Dmitry) -- Fixed bug #32405 (mysqli::fetch() returns bad data - 64bit problem). - (Andrey) -- Fixed bug #32296 (get_class_methods() output has changed between 5.0.2 and - 5.0.3). (Dmitry) -- Fixed bug #32282 (Segfault in mysqli_fetch_array on 64-bit). (Georg) -- Fixed bug #32245 (xml_parser_free() in a function assigned to the xml - parser gives a segfault). (Rob) -- Fixed bug #32179 (xmlrpc_encode() segfaults with recursive references). - (Tony) -- Fixed bug #32171 (Userspace stream wrapper crashes PHP). (Tony, Dmitry) -- Fixed bug #32160 (copying a file into itself leads to data loss). (Ilia) -- Fixed bug #32139 (SOAP client does not auto-handle base64 encoding). (Ilia) -- Fixed bug #32109 ($_POST is not populated in multi-threaded environment). - (Moriyoshi) -- Fixed bug #32080 (segfault when assigning object to itself with - zend.ze1_compatibility_mode=On). (Dmitry) -- Fixed bug #32021 (Crash caused by range('', 'z')). (Derick) -- Fixed bug #32013 (ext/mysqli bind_result causes fatal error: memory limit). - (Andrey) -- Fixed bug #32010 (Memory leak in mssql_fetch_batch). (fmk) -- Fixed bug #32009 (crash when mssql_bind() is called more than once). (Frank) -- Fixed bug #31971 (ftp_login fails on some SSL servers). - (frantisek at augusztin dot com) -- Fixed bug #31887 (ISAPI: Custom 5xx error does not return correct HTTP - response message). (Jani) -- Fixed bug #31828 (Crash with zend.ze1_compatibility_mode=On). (Dmitry) -- Fixed bug #31668 (multi_query works exactly every other time - multi query - d/e flag global and not per connection). (Andrey) -- Fixed bug #31636 (another crash when echoing a COM object). (Wez) -- Fixed bug #31583 (php_std_date() uses short day names in non-y2k_compliance - mode). (mike at php dot net) -- Fixed bug #31525 (object reference being dropped. $this getting lost). - (Stas, Dmitry) -- Fixed bug #31502 (Wrong deserialization from session when using WDDX - serializer). (Dmitry) -- Fixed bug #31478 (segfault with empty() / isset()). (Moriyoshi) -- Fixed bug #31465 (False warning in unpack() when working with *). (Ilia) -- Fixed bug #31363 (broken non-blocking flock()). (ian at snork dot net) -- Fixed bug #31358 (Older GCC versions do not provide portable va_copy()). - (Jani) -- Fixed bug #31341 (escape on curly inconsistent). (Dmitry) -- Fixed bug #31256 (PHP_EVAL_LIBLINE configure macro does not handle - -pthread). (Jani) -- Fixed bug #31213 (Side effects caused by fix of bug #29493). (Dmitry) -- Fixed bug #31177 (memory leaks and corruption because of incorrect - refcounting). (Dmitry) -- Fixed bug #31158 (array_splice on $GLOBALS crashes). (Dmitry) -- Fixed bug #31054 (safe_mode & open_basedir checks only check first - include_path value). (Ilia) -- Fixed bug #31033 (php:function(string, nodeset) with xsl:key crashes PHP). - (Rob) -- Fixed bug #30961 (Wrong line number in ReflectionClass getStartLine()). - (Dmitry) -- Fixed bug #30889 (Conflict between __get/__set and ++ operator). (Dmitry) -- Fixed bug #30833 (array_count_values() modifying input array). (Tony) -- Fixed bug #30828 (debug_backtrace() reports incorrect class in overridden - methods). (Dmitry) -- Fixed bug #30820 (static member conflict with $this->member silently - ignored). (Dmitry) -- Fixed bug #30819 (Better support for LDAP SASL bind). (Jani) -- Fixed bug #30791 (magic methods (__sleep/__wakeup/__toString) call - __call if object is overloaded). (Dmitry) -- Fixed bug #30707 (Segmentation fault on exception in method). - (Stas, Dmitry) -- Fixed bug #30702 (cannot initialize class variable from class constant). - (Dmitry) -- Fixed bug #30578 (Output buffers flushed before calling __destruct() - functions). (Jani) -- Fixed bug #30519 (Interface not existing says Class not found). (Dmitry) -- Fixed bug #30407 (Strange behavior of default arguments). (Dmitry) -- Fixed bug #30394 (Assignment operators yield wrong result with __get/__set). - (Dmitry) -- Fixed bug #30332 (zend.ze1_compatibility_mode isn't fully compatible with - array_push()). (Dmitry) -- Fixed bug #30162 (Catching exception in constructor causes lose of - $this). (Dmitry) -- Fixed bug #30140 (Problem with array in static properties). (Dmitry) -- Fixed bug #30126 (Enhancement for error message for abstract classes). - (Marcus) -- Fixed bug #30096 (gmmktime does not return the current time). (Derick) -- Fixed bug #30080 (Passing array or non array of objects). (Dmitry) -- Fixed bug #30052 (Crash on shutdown after odbc_pconnect()). (Edin) -- Fixed bug #29983 (PHP does not explicitly set mime type & charset). (Ilia) -- Fixed bug #29975 (memory leaks when set_error_handler() is used inside error - handler). (Tony) -- Fixed bug #29971 (variables_order behavior). (Dmitry) -- Fixed bug #29944 (Function defined in switch, crashes). (Dmitry) -- Fixed bug #29896 (Backtrace argument list out of sync). (Dmitry) -- Fixed bug #29728 (Reflection API Feature: Default parameter value). (Marcus) -- Fixed bug #29689 (default value of protected member overrides default value - of private and other private variable problems in inherited classes). (Stas) -- Fixed bug #29683 (headers_list() returns empty array). (Tony) -- Fixed bug #29583 (crash when echoing a COM object). (M.Sisolak, Wez) -- Fixed bug #29522 (accessing properties without connection). (Georg) -- Fixed bug #29361 (var_export() producing invalid code). (Derick) -- Fixed bug #29338 (unencoded spaces get ignored after certain tags). (Ilia) -- Fixed bug #29335 (fetch functions now use MYSQLI_BOTH as default). (Georg) -- Fixed bug #29334 (win32 mail() provides incorrect Date: header). (Jani) -- Fixed bug #29311 (calling parent constructor in mysqli). (Georg) -- Fixed bug #29268 (__autoload() not called with Reflection->getClass()). - (Dmitry) -- Fixed bug #29256 (SOAP HTTP Error when envelop size is more than 24345 - bytes). (Dmitry, Wez) -- Fixed bug #29253 (array_diff with $GLOBALS argument fails). (Dmitry) -- Fixed bug #29236 (memory error when wsdl-cache is enabled). (Dmitry) -- Fixed bug #29210 (Function: is_callable - no support for private and - protected classes). (Dmitry) -- Fixed bug #29109 (SoapFault exception: [WSDL] Out of memory). (Dmitry) -- Fixed bug #29104 (Function declaration in method doesn't work). (Dmitry) -- Fixed bug #29061 (soap extension segfaults). (Dmitry) -- Fixed bug #29015 (Incorrect behavior of member vars(non string ones)-numeric - mem vars and others). (Dmitry) -- Fixed bug #28985 (__getTypes() returning nothing on complex WSDL). (Dmitry) -- Fixed bug #28969 (Wrong data encoding of special characters). (Dmitry) -- Fixed bug #28839 (SIGSEGV in interactive mode (php -a)). - (kameshj at fastmail dot fm) -- Fixed bug #28605 (Need to use -[m]ieee option for Alpha CPUs). (Jani) -- Fixed bug #28568 (SAPI::known_post_content_types is not thread safe). - (Moriyoshi) -- Fixed bug #28377 (debug_backtrace is intermittently passing args). (Dmitry) -- Fixed bug #28355 (glob wont error if dir is not readable). (Hartmut) -- Fixed bug #28072 (static array with some constant keys will be incorrectly - ordered). (Dmitry) -- Fixed bug #27908 (xml default_handlers not being called). (Rob) -- Fixed bug #27598 (list() array key assignment causes HUGE memory leak). - (Dmitry) -- Fixed bug #27268 (Bad references accentuated by clone). (Dmitry) -- Fixed bug #26456 (Wrong results from Reflection-API getDocComment() when - called via STDIN). (Dmitry) -- Fixed bug #25922 (In error handler, modifying 5th arg (errcontext) may - result in seg fault). (Dmitry) -- Fixed bug #25359 (array_multisort() doesn't work in a function if array is - global or reference). (Dmitry) -- Fixed bug #22836 (returning reference to uninitialized variable). (Dmitry) -- Fixed bug #21306 (ext/sesssion: catch bailouts of write handler during - RSHUTDOWN). (Jani, Xuefer at 21cn dot com) -- Fixed bug #15854 (boolean ini options may be incorrectly displayed as Off - when they are On). (Tony) -- Fixed bugs #14561, #20382, #26090, #26320, #28024, #30532, #32086, #32270, - #32555, #32588, #33056 (strtotime() related bugs). (Derick) - -31 Mar 2005, PHP 5.0.4 -- Added SNMPv2 support. (harrie) -- Added Oracle Instant Client support. (cjbj at hotmail dot com, Tony) -- Added length and charsetnr for field array and object in mysqli. (Georg) -- Added checks for negative values to gmp_sqrt(), gmp_powm(), gmp_sqrtrem() - and gmp_fact() to prevent SIGFPE. (Tony) -- Changed foreach() to throw an exception if IteratorAggregate::getIterator() - does not return an Iterator. (Marcus) -- Changed phpize not to require libtool. (Jani) -- Updated bundled oniguruma library (used for multibyte regular expression) - to 3.7.0. (Moriyoshi) -- Updated bundled libmbfl library (used for multibyte functions). (Moriyoshi) - Fixed bugs: - . Bug #32311 (mb_encode_mimeheader() does not properly escape characters) - . Bug #32063 (mb_convert_encoding ignores named entity 'alpha') - . Bug #31911 (mb_decode_mimeheader() is case-sensitive to hex escapes) - . bug #30573 (compiler warnings in libmbfl due to invalid type cast) - . Bug #30549 (incorrect character translations for some ISO8859 charsets). -- Fixed bug preventing from building oci8 as shared. - (stanislav dot voroniy at portavita dot nl, Tony) -- Fixed a bug in mysql_affected_rows and mysql_stmt_affected_rows when the - api function returns -1 (Georg) -- Fixed several leaks in ext/browscap and sapi/embed. (Andrei) -- Fixed several leaks in ext/filepro. (Tony) -- Fixed build system to always use bundled libtool files. (Jani) -- Fixed a bug in mysqli_stmt_execute() (type conversion with NULL values). - (Georg) -- Fixed segfault in mysqli_fetch_field_direct() when invalid field offset - is passed. (Tony) -- Fixed posix_getsid() & posix_getpgid() to return sid & pgid instead - of true. (Tony) -- Fixed bug #32394 (offsetUnset() segfaults in a foreach). (Marcus) -- Fixed bug #32373 (segfault in bzopen() if supplied path to non-existent - file). (Tony) -- Fixed bug #32326 (Check values of Connection/Transfer-Encoding - case-incentively in SOAP extension). (Ilia) -- Fixed bug #32290 (call_user_func_array() calls wrong class method within - child class). (Marcus) -- Fixed bug #32238 (spl_array.c: void function cannot return value). (Johannes) -- Fixed bug #32210 (proc_get_status() sets "running" always to true). (Ilia) -- Fixed bug #32200 (Prevent using both --with-apxs2 and --with-apxs2filter). - (Jani) -- Fixed bug #32134 (Overloading offsetGet/offsetSet). (Marcus) -- Fixed bug #32130 (ArrayIterator::seek() does not throw an Exception on - invalid index). (Marcus) -- Fixed bug #32115 (dateTime SOAP encoding of timezone incorrect). (Dmitry) -- Fixed bug #32081 (in mysqli default socket value is not being used). (Ilia) -- Fixed bug #32021 (Crash caused by range('', 'z')). (Derick) -- Fixed bug #32011 (Fragments which replaced Nodes are not globaly useable). - (Rob) -- Fixed bug #32001 (xml_parse_into_struct() function exceeds maximum - execution time). (Rob, Moriyoshi) -- Fixed bug #31980 (Unicode exif data not available on Windows). (Edin) -- Fixed bug #31960 (msql_fetch_row() and msql_fetch_array() dropping columns - with NULL values). (Daniel Convissor) -- Fixed bug #31878 (Segmentation fault using clone keyword on nodes). (Rob) -- Fixed bug #31858 (--disable-cli does not force --without-pear). (Jani) -- Fixed bug #31842 (*date('r') does not return RFC2822 conforming date string). - (Jani) -- Fixed bug #31832 (SOAP encoding problem with complex types in WSDL mode with - multiple parts). (Dmitry) -- Fixed bug #31797 (exif_read_data() uses too low nesting limit). (Ilia) -- Fixed bug #31796 (readline completion handler does not handle empty return - values). (Ilia) -- Fixed bug #31792 (getrusage() does not provide ru_nswap value). (Ilia) -- Fixed bug #31755 (Cannot create SOAP header in no namespace). (Dmitry) -- Fixed bug #31754 (dbase_open() fails for mode = 1). (Mehdi, Derick) -- Fixed bug #31751 (pg_parameter_status() missing on Windows). (Edin) -- Fixed bug #31747 (SOAP Digest Authentication doesn't work with - "HTTP/1.1 100 Continue" response). (Dmitry) -- Fixed bug #31732 (mb_get_info() causes segfault when no parameters - specified). (Tony) -- Fixed bug #31710 (Wrong return values for mysqli_autocommit/commit/rollback). - (Georg) -- Fixed bug #31705 (parse_url() does not recognize http://foo.com#bar). (Ilia) -- Fixed bug #31695 (Cannot redefine endpoint when using WSDL). (Dmitry) -- Fixed bug #31684 (dio_tcsetattr(): misconfigured termios settings). - (elod at itfais dot com) -- Fixed bug #31683 (changes to $name in __get($name) override future - parameters) (Dmitry) -- Fixed bug #31699 (unserialize() float problem on non-English locales). (Ilia) -- Fixed bug #31562 (__autoload() problem with static variables). (Marcus) -- Fixed bug #31651 (ReflectionClass::getDefaultProperties segfaults with arrays). - (Marcus) -- Fixed bug #31623 (OCILogin does not support password grace period). - (daniel dot beet at accuratesoftware dot com, Tony) -- Fixed bug #31527 (crash in msg_send() when non-string is stored without - being serialized). (Ilia) -- Fixed bug #31515 (Improve performance of scandir() by factor of 10 or so). (Ilia) -- Fixed bug #31514 (open_basedir uses path_translated rather then cwd for . - translation). (Ilia) -- Fixed bug #31480 (Possible infinite loop in imap_mail_compose()). (Ilia) -- Fixed bug #31479 (Fixed crash in chunk_split(), when chunklen > strlen). (Ilia) -- Fixed bug #31454 (session_set_save_handler crashes PHP when supplied - non-existent object ref). (Tony) -- Fixed bug #31444 (Memory leak in zend_language_scanner.c). - (hexer at studentcenter dot org) -- Fixed bug #31442 (unserialize broken on 64-bit systems). (Marcus) -- Fixed bug #31440 ($GLOBALS can be overwritten via GPC when register_globals - is enabled). (Ilia) -- Fixed bug #31422 (No Error-Logging on SoapServer-Side). (Dmitry) -- Fixed bug #31413 (curl POSTFIELDS crashes on 64-bit platforms). (Joe) -- Fixed bug #31396 (compile fails with gd 2.0.33 without freetype). (Jani) -- Fixed bug #31371 (highlight_file() trims new line after heredoc). (Ilia) -- Fixed bug #31361 (simplexml/domxml segfault when adding node twice). (Rob) -- Fixed bug #31348 (CachingIterator::rewind() leaks). (Marcus) -- Fixed bug #31346 (ArrayIterator::next segfaults). (Marcus) -- Fixed bug #31190 (Unexpected warning then exception is thrown from - call_user_func_array()). (phpbugs at domain51 dot net, Dmitry) -- Fixed bug #31142 (imap_mail_compose() fails to generate correct output). (Ilia) -- Fixed bug #31139 (XML Parser Functions seem to drop & when parsing). (Rob) -- Fixed bug #31398 (When magic_guotes_gpc are enabled filenames with ' get cutoff). - (Ilia) -- Fixed bug #31288 (Possible crash in mysql_fetch_field(), if mysql_list_fields() - was not called previously). (Ilia) -- Fixed bug #31107, #31110, #31111, #31249 (Compile failure of zend_strtod.c). - (Jani) -- Fixed bug #31110 (PHP 4.3.10 does not compile on Tru64 UNIX 5.1B). (Derick) -- Fixed bug #31107 (Compile failure on Solaris 9 (Intel) and gcc 3.4.3). (Derick) -- Fixed bug #31103 (Better error message when c-client cannot be found). (Ilia) -- Fixed bug #31101 (missing kerberos header file path with --with-openssl). (Jani) -- Fixed bug #31098 (isset() / empty() incorrectly return true in dereference of - a string type). (Moriyoshi) -- Fixed bug #31087 (broken php_url_encode_hash macro). (Ilia) -- Fixed bug #31072 (var_export() does not output an array element with an empty - string key). (Derick) -- Fixed bug #31060 (imageftbbox() does not use linespacing parameter). (Jani) -- Fixed bug #31056 (php_std_date() returns invalid formatted date if - y2k_compliance is On). (Ilia) -- Fixed bug #31055 (apache2filter: per request leak proportional to the full - path of the request URI). (kameshj at fastmail dot fm) -- Fixed bug #30901 (can't send cookies with soap envelop). (Dmitry) -- Fixed bug #30871 (Misleading warning message for array_combine()). (Andrey) -- Fixed bug #30868 (evaluated pointer comparison in mbregex causes compile - failure). (Moriyoshi) -- Fixed bug #30862 (Static array with boolean indexes). (Marcus) -- Fixed bug #30726 (-.1 like numbers are not being handled correctly). (Ilia) -- Fixed bug #30725 (PHP segfaults when an exception is thrown in getIterator() - within foreach). (Marcus) -- Fixed bug #30609 (cURL functions bypass open_basedir). (Jani) -- Fixed bug #30446 (apache2handler: virtual() includes files out of sequence) -- Fixed bug #30430 (odbc_next_result() doesn't bind values and that results - in segfault). (pdan-php at esync dot org, Tony) -- Fixed bug #30266 (Invalid opcode 137/1/8). (Marcus) -- Fixed bug #30120 imagettftext() and imagettfbbox() accept too many - parameters). (Jani) -- Fixed bug #30106 (SOAP cannot not parse 'ref' element. Causes Uncaught - SoapFault exception). (Dmitry) -- Fixed bug #29989 (type re_registers redefined in oniguruma.h). (Moriyoshi) -- Fixed bug #28803 (enabled debug causes bailout errors with CLI on AIX - because of fflush() called on already closed filedescriptor). (Tony) -- Fixed bug #29767 (Weird behaviour of __set($name, $value)). (Dmitry) -- Fixed bug #29733 (printf() handles repeated placeholders wrong). - (bugs dot php dot net at bluetwanger dot de, Ilia) -- Fixed bug #29424 (width and height inverted for JPEG2000 files). (Ilia) -- Fixed bug #29329 (configure for mysqli with shared doesn't work). (Georg) -- Fixed bug #29136 (make test - libtool failure on MacOSX). (Jani) -- Fixed bug #28976 (mail(): use "From:" from headers if sendmail_from is empty). - (Jani) -- Fixed bug #28930 (PHP sources pick wrong header files generated by bison). - (eggert at gnu dot org, Jani) -- Fixed bug #28840 (__destruct of a class that extends mysqli not called). - (Marcus) -- Fixed bug #28804 (ini-file section parsing pattern is buggy). - (wendland at scan-plus dot de) -- Fixed bug #28451 (corrupt EXIF headers have unlimited recursive IFD directory - entries). (Andrei) -- Fixed bug #28444 (Cannot access undefined property for object with overloaded - property access). (Dmitry) -- Fixed bug #28442 (Changing a static variables in a class changes it across - sub/super classes.) (Marcus) -- Fixed bug #28324 (HTTP_SESSION_VARS appear when register_long_arrays is - Off). (Tony) -- Fixed bug #28074 (FastCGI: stderr should be written in a FCGI stderr stream). - (chris at ex-parrot dot com) -- Fixed bug #28067 (partially incorrect utf8 to htmlentities mapping). (Derick, - Benjamin Greiner) -- Fixed bug #28041 (SOAP HTTP Digest Access Authentication). (Dmitry) -- Fixed bug #27633 (Double \r problem on ftp_get in ASCII mode on Win32). (Ilia) -- Fixed bug #18613 (Multiple OUs in x509 certificate not handled properly). - (Jani) - -15 Dec 2004, PHP 5.0.3 -- Added the %F modifier to *printf to render a non-locale-aware representation - of a float with the . as decimal seperator. (Derick) -- Fixed error handling in mysqli_multi_query. (Georg) -- Extended the functionality of is_subclass_of() to accept either a class name - or an object as first parameter. (Andrey) -- Fixed potential problems with unserializing invalid serialize data. (Marcus) -- Fixed bug #32076 (ReflectionMethod::isDestructor() always return true). - (Derick, Tony) -- Fixed bug #31034 (Problem with non-existing iconv header file). (Derick) -- Fixed bug #30995 (snmp extension does not build with net-snmp 5.2). (Ilia) -- Fixed bug #30994 (SOAP server unable to handle request with references). - (Dmitry) -- Fixed bug #30990 (allow popen() on *NIX to accept 'b' flag). (Ilia) -- Fixed bug #30967 (properties in extended mysqli classes don't work). (Georg) -- Fixed bug #30928 (When Using WSDL, SoapServer doesn't handle private or - protected properties). (Dmitry) -- Fixed bug #30922 (reflective functions crash PHP when interfaces extend - themselves). (Tony, Dmitry) -- Fixed bug #30904 (segfault when recording soapclient into session). (Tony, - Dmitry) -- Fixed bug #30890 (MySQLi testsuite) -- Fixed bug #30856 (ReflectionClass::getStaticProperties segfaults). (Marcus) -- Fixed bug #30832 ("!" stripped off comments in xml parser). (Rob) -- Fixed bug #30799 (SoapServer doesn't handle private or protected properties). - (Dmitry) -- Fixed bug #30783 (Apache crash when using ReflectionFunction:: - getStaticVariables()). (Marcus) -- Fixed bug #30750 (Meaningful error message when upload directory is not - accessible). (Ilia) -- Fixed bug #30685 (Malformed SOAPClient http header reequest). (Dmitry) -- Fixed bug #30672 (Problem handling exif data in jpeg images at unusual - places). (Marcus) -- Fixed bug #30658 (Ensure that temporary files created by GD are removed). - (Ilia) -- Fixed bug #30645 (def. multi result set support for mysql_connect). (Georg) -- Fixed bug #30637 (compile with pear error). (Antony) -- Fixed bug #30587 (array_multisort doesn't separate zvals before - changing them). (Tony) -- Fixed bug #30572 (crash when comparing SimpleXML attribute to a boolean). - (Andi) -- Fixed bug #30566 (attribute namespace URIs are inconsistent when parsing). - (Rob) -- Fixed bug #30490 (PEAR installation fails). (Antony) -- Fixed bug #30475 (curl_getinfo() may crash in some situations). (Ilia) -- Fixed bug #30442 (segfault when parsing ?getvariable[][ ). (Tony) -- Fixed bug #30388 (rename across filesystems loses ownership and - permission info). (Tony) -- Fixed bug #30387 (stream_socket_client async connect was broken). - (vnegrier at esds dot com, Wez). -- Fixed bug #30381 (Strange results with get_class_vars()). (Marcus) -- Fixed bug #30375 (cal_info() does not work without a parameter). (Ilia) -- Fixed bug #30362 (stream_get_line() not handling end string correctly). - (Ilia) -- Fixed bug #30359 (SOAP client requests have no port in "Host" field). - (Dmitry) -- Fixed bug #30356 (str_ireplace() does not work on all strings). (Ilia) -- Fixed bug #30344 (Reflection::getModifierNames() returns too long strings). - (Marcus) -- Fixed bug #30329 (Error Fetching http body, No Content-Length, connection - closed or chunked data). (Dmitry) -- Fixed bug #30282 (segfault when using unknown/unsupported - session.save_handler and/or session.serialize_handler). (Tony) -- Fixed bug #30281 (Prevent non-wbmp images from being detected as such). - (Ilia) -- Fixed bug #30276 (Possible crash in ctype_digit on large numbers). (Ilia) -- Fixed bug #30230 (exception handler not working with objects). (Marcus) -- Fixed bug #30224 (Sybase date strings are sometimes not null terminated). - (Ilia) -- Fixed bug #30175 (SOAP results aren't parsed correctly). (Dmitry) -- Fixed bug #30147 (OO sqlite_fetch_object did not reset error handler). (Wez) -- Fixed bug #30133 (get_current_user() crashes on Windows). (Edin) -- Fixed bug #30061 (xml_set_start_namespace_decl_handler not called). (Rob) -- Fixed bug #30057 (did not detect IPV6 on FreeBSD 4.1). (Wez) -- Fixed bug #30042 (strtotime does not use second param). (Derick) -- Fixed bug #30027 (Possible crash inside ftp_get()). - (cfield at affinitysolutions dot com) -- Fixed bug #29954 (array_reduce segfaults when initial value is array). (Tony) -- Fixed bug #29883 (isset gives invalid values on strings). (Tony, Dmitry) -- Fixed bug #29801 (Set limit on the size of mmapable data). (Ilia) -- Fixed bug #29557 (strtotime error). (Derick) -- Fixed bug #29418 (double free when openssl_csr_new fails). - (Kamesh Jayachandran). -- Fixed bug #29385 (Soapserver always uses std class). (David, Dmitry) -- Fixed bug #29211 (SoapClient doesn't request wsdl through proxy). (Rob) -- Fixed bug #28817 (Var problem when extending domDocument). (Georg) -- Fixed bug #28599 (strtotime fails with zero base time). (Derick) -- Fixed bug #28598 (Lost support for MS Symbol fonts). (Pierre) -- Fixed bug #28220 (mb_strwidth() returns wrong width values for some hangul - characters). (Moriyoshi) -- Fixed bug #28228 (NULL decimal separator is not being handled correctly). - (Ilia) -- Fixed bug #28209 (strtotime("now")). (Derick) -- Fixed bug #27798 (private / protected variables not exposed by - get_object_vars() inside class). (Marcus) -- Fixed bug #27728 (Can't return within a zend_try {} block or the previous - bailout state isn't restored. (Andi) -- Fixed bug #27183 (Userland stream wrapper segfaults on stream_write). - (Christian) - -23 Sep 2004, PHP 5.0.2 -- Added new boolean (fourth) parameter to array_slice() that turns on the - preservation of keys in the returned array. (Derick) -- Added the sorting flag SORT_LOCALE_STRING to the sort() functions which makes - them sort based on the current locale. (Derick) -- Added interface_exists() and make class_exists() only return true for real - classes. (Andrey) -- Added PHP_EOL constant that contains the OS way of representing newlines. - (Paul Hudson, Derick) -- Implemented periodic PCRE compiled regexp cache cleanup, to avoid memory - exhaustion. (Andrei) -- Renamed SoapClient->__call() to SoapClinet->__soapCall(). (Dmitry) -- Fixed bug with raw_post_data not getting set (Brian) -- Fixed a file-descriptor leak with phpinfo() and other 'special' URLs (Zeev) -- Fixed bug #30209 (ReflectionClass::getMethod() lowercases attribute). - (Marcus) -- Fixed bug #30182 (SOAP module processing WSDL file dumps core). (Dmitry) -- Fixed bug #30045 (Cannot pass big integers (> 2147483647) in SOAP requests). - (Dmitry) -- Fixed bug #29985 (unserialize()/ __PHP_Incomplete_class does not report - correctly class name). (Marcus, Tony) -- Fixed bug #29945 (simplexml_load_file URL limitation 255 char). (Rob) -- Fixed bug #29873 (No defines around pcntl_*priority definitions). (Derick) -- Fixed bug #29844 (SOAP doesn't return the result of a valid SOAP request). - (Dmitry) -- Fixed bug #29842 (soapclient return null value). (Dmitry) -- Fixed bug #29839 (incorrect convert (xml:lang to lang)). (Dmitry) -- Fixed bug #29830 (SoapServer::setClass() should not export non-public - methods). (Dmitry) -- Fixed bug #29828 (Interfaces no longer work). (Marcus) -- Fixed bug #29821 (Fixed possible crashes in convert_uudecode() on invalid - data). (Ilia) -- Fixed bug #29808 (array_count_values() breaks with numeric strings). (Ilia) -- Fixed bug #29805 (HTTP Authentication Issues). (Uwe Schindler) -- Fixed bug #29795 (SegFault with Soap and Amazon's Web Services). (Dmitry) -- Fixed bug #29737 (ip2long should return -1 if IP is 255.255.255.255 and FALSE - on error). (Tony) -- Fixed bug #29711 (Changed ext/xml to default to UTF-8 output). (Rob) -- Fixed bug #29678 (opendir() with ftp:// wrapper segfaults if path does not - have trailing slash). (Ilia) -- Fixed bug #29657 (xml_* functions throw non descriptive error). - (Christian, Rob) -- Fixed bug #29656 (segfault on result and statement properties). (Georg) -- Fixed bug #29566 (foreach/string handling strangeness (crash)). (Dmitry) -- Fixed bug #29447 (Reflection API issues). (Marcus) -- Fixed bug #29296 (Added sslv2 and sslv3 transports). (Wez) -- Fixed bug #29283 (Invalid statement handle in mysqli on execute). (Georg) -- Fixed bug #29913 (parse_url() is now binary safe). (Ilia) -- Fixed bug #27994 (segfault with Soapserver when WSDL-Cache is enabled). - (Dmitry) -- Fixed bug #27791 (Apache 2.0 SAPI build against Apache 2 HEAD). (Joe Orton, - Derick) -- Fixed bug #26737 (private/protected properties not serialized when user - declared method __sleep() exists). E_NOTICE thrown when __sleep() returns - name of non-existing member. (Andrey, Curt) - -12 Aug 2004, PHP 5.0.1 -- Changed destructor mechanism so that destructors are called prior to request - shutdown. (Marcus) -- Rewritten UNIX and Windows install help files. (Documentation Team) -- Updated several libraries bundled with the windows release which now - includes libxml2-2.6.11, libxslt-1.1.7 and iconv-1.9.1. (Rob, Edin) -- Improved and moved ActiveScript SAPI to PECL. (Wez) -- Fixed bug #29606 (php_strip_whitespace() prints to stdout rather then - returning the value). (Ilia) -- Fixed bug #29577 (MYSQLI_CLIENT_FOUND_ROWS undefined) (Georg) -- Fixed bug #29573 (Segmentation fault, when exception thrown within - PHP function called from XSLT). (Christian) -- Fixed bug #29522 (accessing properties without connection) (Georg) -- Fixed bug #29505 (get_class_vars() severely broken when used with arrays). - (Marcus) -- Fixed bug #29490 (.Net object instantiation failed). (Michael Sisolak). -- Fixed bug #29474 (win32: usleep() doesn't work). (Wez) -- Fixed bug #29449 (win32: feof() hangs on empty tcp stream). (Wez) -- Fixed bug #29437 (Possible crash inside array_walk_recursive()). (Ilia) -- Fixed bug #29431 (crash when parsing invalid address; invalid address - returned by stream_socket_recvfrom(), stream_socket_getname()). (Wez) -- Fixed bug #29409 (Segfault in PHP functions called from XSLT). (Rob) -- Fixed unloading of dynamically loaded extensions. - (Marcus, kameshj at fastmail dot fm) -- Fixed bug #29395 (sqlite_escape_string() returns bogus data on empty - strings). (Ilia, Tony) -- Fixed bug #29392 (com_dotnet crashes when echo'ing an object). (Wez) -- Fixed bug #29368 (The destructor is called when an exception is thrown from - the constructor). (Marcus) -- Fixed bug #29354 (Exception constructor marked as both public and protected). - (Marcus) -- Fixed bug #29342 (strtotime() does not handle empty date string properly). - (Ilia) -- Fixed bug #29340 (win32 build produces invalid php_ifx.dll). (Edin) -- Fixed bug #29335 (fetch functions now use MYSQLI_BOTH as default) (Georg) -- Fixed bug #29291 (get_class_vars() return names with NULLs). (Marcus) -- Fixed bug #29264 (gettext extension not working). (Edin) -- Fixed bug #29258 (variant_date_from_timestamp() does not honour - timezone). (Wez) -- Fixed bug #29256 (error when sending large packets on a socket). (Dmitry) -- Fixed bug #29236 (memory error when wsdl-cache is enabled). (Dmitry) -- Fixed bug #29147 (Compile Error in mnoGoSearch functions). (Sergey, Antony) -- Fixed bug #29132 ($_SERVER["PHP_AUTH_USER"] isn't defined). (Stefan) -- Fixed bug #29119 (html_entity_decode() misbehaves with UTF-8). (Moriyoshi) -- Fixed bug #29109 (SoapFault exception: [WSDL] Out of memory). (Dmitry) -- Fixed bug #29061 (soap extension segfaults). (Dmitry) -- Fixed bug #28985 (__getTypes() returning nothing on complex WSDL). (Dmitry) -- Fixed bug #28969 (Wrong data encoding of special characters). (Dmitry) -- Fixed bug #28895 (ReflectionClass::isAbstract always returns false). (Marcus) -- Fixed bug #28829 (Thread-unsafety in bcmath elementary values). (Sara) -- Fixed bug #28464 (catch() does not catch exceptions by interfaces). (Marcus) -- Fixed bug #27669 (PHP 5 didn't support all possibilities for calling static - methods dynamically). (Dmitry) -- Fixed ReflectionClass::getMethod() and ReflectionClass::getProperty() to - raise an ReflectionException instead of returning NULL on failure. - (Sebastian) -- Fixed convert.* filters to consume remaining buckets_in on flush. (Sara) -- Fixed bug in mysqli->client_version. (Georg) + . update libzip to version 1.11.1. + PHP don't use any ilibzip private symbol anymore. (Pierre, Remi) + . new method ZipArchive::setPassword($password). (Pierre) + . add --with-libzip option to build with system libzip. (Remi) -13 Jul 2004, PHP 5.0.0 -- Updated PCRE to provide better error handling in certain cases. (Andrei) -- Changed doc comments to require a single white space after '/**'. (Marcus) -- Fixed bug #29019 (Database not closing). (Marcus) -- Fixed bug #29008 (array_combine() does not handle non-numeric/string keys). - (Ilia) -- Fixed bug #28999 (fixed behaviour of exec() to work as it did in 4.X). (Ilia) -- Fixed bug #28868 (Internal filter registry not thread safe). (Sara) -- Fixed bug #28851 (call_user_func_array has typo in error message). (Marcus) -- Fixed bug #28831 (ArrayObject::offsetGet() does the work of offsetUnset()). - (Marcus) -- Fixed bug #28822 (ArrayObject::offsetExists() works inverted). (Marcus) -- Fixed bug #28789 (ReflectionProperty getValue() fails on public static - members). (Marcus) -- Fixed bug #28771 (Segfault when using xslt and clone). (Rob) -- Fixed bug #28751 (SoapServer does not call _autoload()). (Dmitry) -- Fixed bug #28739 (array_*diff() and array_*intersect() not clearing the fci - cache before work). (Andrey) -- Fixed bug #28721 (appendChild() and insertBefore() unset DOMText).(Rob) -- Fixed bug #28702 (SOAP does not parse WSDL service address correctly). (Dmitry) -- Fixed bug #28699 (Reflection api bugs). (Marcus) -- Fixed bug #28694 (ReflectionExtension::getFunctions() crashes PHP). (Marcus) -- Fixed bug #28512 (Allocate enough space to store MSSQL data). (Frank) -- Fixed strip_tags() to correctly handle '\0' characters. (Stefan) +<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/README.EXTENSIONS b/README.EXTENSIONS deleted file mode 100644 index 06d6cdd85f2e4..0000000000000 --- a/README.EXTENSIONS +++ /dev/null @@ -1,39 +0,0 @@ -Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way -that broke both source and binary compatibility. If you are -maintaining a third party extension, here's how to update it: - -If this was your old module entry: - -zend_module_entry foo_module_entry = { - "foo", /* extension name */ - foo_functions, /* extension function list */ - NULL, /* extension-wide startup function */ - NULL, /* extension-wide shutdown function */ - PHP_RINIT(foo), /* per-request startup function */ - PHP_RSHUTDOWN(foo), /* per-request shutdown function */ - PHP_MINFO(foo), /* information function */ - STANDARD_MODULE_PROPERTIES -}; - -Here's how it should look if you want your code to build with PHP -4.1.0 and up: - -zend_module_entry foo_module_entry = { -#if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, -#endif - "foo", /* extension name */ - foo_functions, /* extension function list */ - NULL, /* extension-wide startup function */ - NULL, /* extension-wide shutdown function */ - PHP_RINIT(foo), /* per-request startup function */ - PHP_RSHUTDOWN(foo), /* per-request shutdown function */ - PHP_MINFO(foo), /* information function */ -#if ZEND_MODULE_API_NO >= 20010901 - PHP_FOO_VERSION, /* extension version number (string) */ -#endif - STANDARD_MODULE_PROPERTIES -}; - -If you don't care about source compatibility with earlier PHP releases -than 4.1.0, you can drop the #if/#endif lines. diff --git a/README.PHP4-TO-PHP5-THIN-CHANGES b/README.PHP4-TO-PHP5-THIN-CHANGES deleted file mode 100644 index 0a2c6d6657131..0000000000000 --- a/README.PHP4-TO-PHP5-THIN-CHANGES +++ /dev/null @@ -1,155 +0,0 @@ -1. strrpos() and strripos() now use the entire string as a needle. Be aware - that the existing scripts may no longer work as you expect. - - EX : - - - Will give you different results. The former returns 3 while the latter - returns false rather than the position of the last occurrence of 'D'. - The same applies to strripos(). - -2. Illegal use of string offsets causes E_ERROR instead of E_WARNING. - - EX : - - - Fatal error: Cannot use string offset as an array in ... on line 1 - -3. array_merge() was changed to accept only arrays. If a non-array variable is - passed, a E_WARNING will be thrown for every such parameter. Be careful - because your code may start emitting E_WARNING out of the blue. - -4. Be careful when porting from ext/mysql to ext/mysqli. The following - functions return NULL when no more data is available in the result set - (ext/mysql's functions return FALSE). - - - mysqli_fetch_row() - - mysqli_fetch_array() - - mysqli_fetch_assoc() - -5. PATH_TRANSLATED server variable is no longer set implicitly under - Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the - same value as the SCRIPT_FILENAME server variable when it is not populated - by Apache. This change was made to comply with the CGI specification. - Please refer to bug #23610 for further information. - -6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the - ext/tokenizer extension. If error_reporting is set to E_ALL notices will - be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant - is used, thus both // and /* */ are resolved as the T_COMMENT constant. - However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed - by PHP, are recongnized as T_DOC_COMMENT. - -7. $_SERVER should be populated with argc and argv if variables_order - includes "S". If you have specifically configured your system to not - create $_SERVER, then of course it shouldn't be there. The change was to - always make argc and argv available in the CLI version regardless of the - variables_order setting. As in, the CLI version will now always populate - the global $argc and $argv variables. - -8. In some cases classes must be declared before used. It only happens only - if some of the new features of PHP 5 are used. Otherwise the behaviour is - the old. - Example 1 (works with no errors): - - - Example 2 (throws an error): - - - Output (example 2) : - Fatal error: Class 'a' not found in /tmp/cl.php on line 2 - -9. get_class() starting PHP 5 returns the name of the class as it was - declared which may lead to problems in older scripts that rely on - the previous behaviour - the class name is lowercased. Expect the - same behaviour from get_parent_class() when applicable. - Example : - - - Output (PHP 4): - string(6) "foobar" - string(9) "extfoobar" - - Output (PHP 5): - string(6) "FooBar" - string(9) "ExtFooBar" - ---------------------------------------------------------------------- - Example code that will break : - //.... - function someMethod($p) { - if (get_class($p) != 'helpingclass') { - return FALSE; - } - //... - } - //... - Possible solution is to search for get_class() and get_parent_class() in - all your scripts and use strtolower(). - -10. get_class_methods() returns the names of the methods of a class as they - declared. In PHP4 the names are all lowercased. - Example code : - - Output (PHP4): - array(2) { - [0]=> - string(5) "dofoo" - [1]=> - string(6) "hasfoo" - } - Output (PHP5): - array(2) { - [0]=> - string(5) "doFoo" - [1]=> - string(6) "hasFoo" - } - -11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special - meaning in class methods and is recognized by the PHP parser. The latter - will generate a parse error when assignment to $this is found - Example code : - assignNew($b); - echo "I was executed\n"; - ?> - Output (PHP 4): - I was executed - Output (PHP 5): - PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4 - diff --git a/README.STREAMS b/README.STREAMS index f625406a3bae6..0046e6a75438d 100644 --- a/README.STREAMS +++ b/README.STREAMS @@ -46,7 +46,7 @@ Opening Streams =============== In most cases, you should use this API: -PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode, +PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode, int options, char **opened_path TSRMLS_DC); Where: diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 63b7156f100b2..d1b74bd18d996 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -5,7 +5,7 @@ This document describes how to submit an enhancement or patch for PHP. It's easy! You don't need any login accounts or special access to download, -build, debug and begin submitting PHP, PECL or PEAR code, tests or +build, debug and begin submitting PHP or PECL code, tests or documentation. Once you've followed this README and had several patches accepted, commit privileges are often quickly granted. @@ -16,8 +16,8 @@ http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith Online Forums ------------- There are several IRC channels where PHP developers are often -available to discuss questions. They include #php.pecl, #php.doc and -#pear on the EFNet network and #php-dev-win on FreeNode. +available to discuss questions. They include #php.pecl and #php.doc +on the EFNet network and #php-dev-win on FreeNode. PHP Patches @@ -78,7 +78,7 @@ of type 'text/*' are accepted. PECL Extension Patches: http://pecl.php.net/ -------------------------------------------- If you are fixing broken functionality in a PECL extension then create -a bug or identify an existing bug at http://pecl.php.net/bugs/. A bug +a bug or identify an existing bug at http://bugs.php.net/. A bug can be used to track the patch progress and prevent your changes getting lost in the PHP mail archives. @@ -114,15 +114,15 @@ http://pear.php.net/manual/en/guide-developers.php How to create your PHP, PHP Documentation or PECL patch ------------------------------------------------------- -PHP and PECL use Subversion (SVN) for revision control. Read -http://www.php.net/svn.php for help on using SVN to get and build PHP -source code. We recommend using a Sparse Directory checkout described -in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read -http://svnbook.red-bean.com. +PHP and most PECL packages use Git for revision control. Some PECL +packages use Subversion (SVN) Read http://www.php.net/git.php for help +on using Git to get and build PHP source code. We recommend to look +at our workflow on https://wiki.php.net/vcs/gitworkflow and our FAQ +https://wiki.php.net/vcs/gitfaq. Generally we ask that bug fix patches work on the current stable PHP -development branches and on "trunk". New PHP features only need to -work on "trunk". +development branches and on "master". New PHP features only need to +work on "master". Read CODING_STANDARDS before you start working. @@ -134,7 +134,7 @@ comprehensive. After testing is finished, create a patch file using the command: - svn diff > your_patch.txt + git diff > your_patch.txt For ease of review and later troubleshooting, submit individual patches for each bug or feature. @@ -142,7 +142,7 @@ patches for each bug or feature. Checklist for submitting your PHP or PECL code patch ---------------------------------------------------- - - Update SVN source just before running your final 'diff' and + - Update git source just before running your final 'diff' and before testing. - Add in-line comments and/or have external documentation ready. Use only "/* */" style comments, not "//". @@ -175,7 +175,7 @@ about these questions: What happens when your PHP or PECL patch is applied --------------------------------------------------- -Your name will likely be included in the SVN commit log. If your +Your name will likely be included in the Git commit log. If your patch affects end users, a brief description and your name might be added to the NEWS file. diff --git a/TSRM/Makefile.am b/TSRM/Makefile.am index 91e585b65c89a..e232381a019e1 100644 --- a/TSRM/Makefile.am +++ b/TSRM/Makefile.am @@ -1,6 +1,6 @@ ## process this file with automake to produce Makefile.am AUTOMAKE_OPTIONS=foreign noinst_LTLIBRARIES=libtsrm.la -libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c +libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c depend: diff --git a/TSRM/TSRM.dsp b/TSRM/TSRM.dsp index 1a5693f5a23c4..6c3e8bfb8bede 100644 --- a/TSRM/TSRM.dsp +++ b/TSRM/TSRM.dsp @@ -143,10 +143,6 @@ SOURCE=.\tsrm_strtok_r.c # End Source File # Begin Source File -SOURCE=.\tsrm_virtual_cwd.c -# End Source File -# Begin Source File - SOURCE=.\tsrm_win32.c # End Source File # End Group diff --git a/TSRM/config.w32 b/TSRM/config.w32 index 5498f8e7bd3ec..91b4eead2a07d 100644 --- a/TSRM/config.w32 +++ b/TSRM/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript // $Id$ -ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c"); +ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_win32.c"); diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index 2ec97be0116bc..7b9ebc3061b34 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -32,7 +32,7 @@ #ifdef TSRM_WIN32 #include #include "tsrm_win32.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #ifdef ZTS static ts_rsrc_id win32_globals_id; diff --git a/UPGRADING b/UPGRADING index 43e4118b21245..022918cb14594 100755 --- a/UPGRADING +++ b/UPGRADING @@ -1,486 +1,149 @@ $Id$ -PHP 5.5 UPGRADE NOTES - -1. Backward Incompatible Changes -2. New Features -2. Changes in SAPI modules -3. Deprecated Functionality -4. Changed Functions -5. New Functions -6. New Classes and Interfaces -7. Removed Extensions -8. Other Changes to Extensions -9. New Global Constants +PHP X.Y UPGRADE NOTES + +1. Backward Incompatible Changes +2. New Features +2. Changes in SAPI modules +3. Deprecated Functionality +4. Changed Functions +5. New Functions +6. New Classes and Interfaces +7. Removed Extensions +8. Other Changes to Extensions +9. New Global Constants 10. Changes to INI File Handling -11. Windows Support -12. Other Changes +11. Other Changes ======================================== 1. Backward Incompatible Changes ======================================== -- Dropped Windows XP and 2003 support. (Pierre) - -- All internal case insensitivity handling for class, function and constant - names is done according to ASCII rules. Current locale settings are ignored. - -- self, parent & static keywords now are always case-insensitive (see bug - #60833). - -- Removed Logo GUIDs: php_logo_guid(), php_egg_logo_guid(), - php_real_logo_guid() and zend_logo_guid() +- Core: + Removed $HTTP_RAW_POST_DATA global variable. Restore backwards compatibility + by: + ======================================== 2. New Features ======================================== -- Support list in foreach. (Laruence) - (http://php.net/foreach#control-structures.foreach.list, - http://wiki.php.net/rfc/foreachlist) - -- Support "finally" keyword. (Laruence) - (http://php.net/exceptions, http://wiki.php.net/rfc/finally) +- Added dedicated syntax for variadic functions. + (https://wiki.php.net/rfc/variadics) -- Support constant array/string dereferencing. (Laruence) - (http://php.net/manual/en/language.types.array.php, - https://wiki.php.net/rfc/constdereference) +- The php://input stream is now re-usable and can be used concurrently with + enable_post_data_reading=0. -- Add support for using empty() on the result of function calls and - other expressions. Thus it is now possible to write empty(getArray()), - for example. (http://php.net/manual/en/function.empty.php, - https://wiki.php.net/rfc/empty_isset_exprs) +- Added gost-crypto (CryptoPro S-box) hash algo. -- Added generators. - (http://php.net/generators, https://wiki.php.net/rfc/generators) +- Added openssl certificate fingerprint support (inclusive stream context + option). -- ClassName::class syntax returning full class name for a class as a - string constant. (http://php.net/oop5.basic, - https://wiki.php.net/rfc/class_name_scalars) - -- Added support for non-scalar Iterator keys in foreach. - (http://php.net/manual/en/control-structures.foreach.php, - https://wiki.php.net/rfc/foreach-non-scalar-keys). - -- Bundled Zend OPcache extension to improve performance - (http://php.net/manual/en/book.opcache.php, - https://wiki.php.net/rfc/optimizerplus) - -- Added a simplified password hashing API - (http://php.net/password, https://wiki.php.net/rfc/password_hash) +- Added openssl crypto method stream context option. ======================================== 2. Changes in SAPI modules ======================================== -- Support for changing the process's title in CLI/CLI-Server - SAPIs. (Keyur) - (http://php.net/manual/en/function.cli-set-process-title.php, - http://php.net/manual/en/function.cli-get-process-title.php, - https://wiki.php.net/rfc/cli_process_title) - -- Support for systemd in php-fpm: Add --with-fpm-systemd option to - report health to systemd, and add systemd_interval option to - configure this. The service can now use Type=notify in the systemd - unit file. (Remi) ======================================== 3. Deprecated Functionality ======================================== -- The original MySQL extension is now deprecated and will generate - deprecation warnings when connecting to a database through - mysql_connect(), mysql_pconnect() or by establishing an implicit - connection. Use MySQLi or PDO instead. - -- The preg_replace /e modifier is now deprecated. Use - preg_replace_callback instead. - (https://wiki.php.net/rfc/remove_preg_replace_eval_modifier) - -- IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are - deprecated. Use IntlDateFormatter::setTimeZone() or - datefmt_set_timezone() instead. - -- mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw - E_DEPRECATED. Their use was already previously discouraged in the - documentation, but that predated the existence of E_DEPRECATED. +- Incompatible context calls: + Instance calls from an incompatible context are now deprecated and issue + E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx ======================================== 4. Changed Functions ======================================== -- pack()/unpack() had the following changes, which bring it more in - line with Perl's behavior: - Implemented format character "Z": NULL - padded string, with trailing NULL bytes removed. - Changed format - character "a": this no longer removes trailing NULL bytes. - - Changed format character "A": all trailing ASCII whitespace is now - removed (defined as spaces, tabs, \r, \n and NULL). - -- MessageFormatter::format() and related functions now accepted named - arguments and mixed numeric/named arguments in ICU 4.8+. - -- MessageFormatter::format() and related functions now don't error out - when an insufficient argument count is provided. Instead, the - placeholders will remain unsubstituted. - -- MessageFormatter::parse() and MessageFormat::format() (and their - static equivalents) now don't throw away better than second - precision in the arguments. - -- IntlDateFormatter::__construct and datefmt_create() now accept for - the $timezone argument time zone identifiers, IntlTimeZone objects, - DateTimeZone objects and NULL. It used to accept only time zone - identifiers and NULL. Invalid time zone identifiers are no longer - accepted. Empty strings are no longer accepted. - -- The default time zone used in IntlDateFormatter::__construct and - datefmt_create() (when the corresponding argument is not passed or - NULL is passed) is now the one given by date_default_timezone_get(), - not the default ICU time zone. - -- The time zone passed to the IntlDateFormatter is ignored if it is - NULL and if the calendar passed is an IntlCalendar object -- in this - case, the IntlCalendar's time zone will be used instead. Otherwise, - the time zone specified in the $timezone argument is used - instead. This does not affect old code, as IntlCalendar was - introduced in this version. - -- IntlDateFormatter::__construct and datefmt_create() now accept for - the $calendar argument also IntlCalendar objects. - -- IntlDateFormatter::getCalendar() and datefmt_get_calendar() return - false if the IntlDateFormatter was set up with an IntlCalendar - instead of the constants - IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not exist - before this version. - -- IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also - accept an IntlCalendar object, in which case its time zone is - taken. Passing a constant is still allowed, and still keeps the time - zone. - -- IntlDateFormatter::format() and datefmt_format() now also accept an - IntlCalendar object for formatting. - -- set_error_handler(NULL) can now be used to reset the error handler. - Furthermore both set_error_handler(NULL) and - set_exception_handler(NULL) will now return the previously defined - error/exception handler. Previously bool(true) was returned. - -- setcookie(), setrawcookie() and ext/session now send Max-Age headers - alongside Expires headers. (see - https://wiki.php.net/rfc/cookie_max-age) - -- curl_setopt now accepts new option CURLOPT_SAFE_UPLOAD and CURLFile - object for safer file uploads (see - https://wiki.php.net/rfc/curl-file-upload) - -- Functions in the socket extension now do not emit warnings when the - errno is EAGAIN, EWOULDBLOCK or EINPROGRESS. - -- Since 5.5.2, spl_autoload_functions() returns different names for - different lambda functions registered via spl_autoload_register(). - -- Since 5.5.3, DOMDocument::schemaValidateSource() and - DOMDocument::schemaValidate() accept flag parameter. Only flag - available now is LIBXML_SCHEMA_CREATE. Default is 0. - -- Since 5.5.4, fputcsv() has fifth parameter escape_char, allowing to - specify escape char. +- cURL: + CURLOPT_SAFE_UPLOAD is now turned on by default and uploads with @file + do not work unless it is explicitly set to false. + +- Crypt: + crypt() will now raise an E_NOTICE error if the salt parameter is omitted. + See: https://wiki.php.net/rfc/crypt_function_salt + +- XMLReader: + XMLReader::getAttributeNs and XMLReader::getAttributeNo now return NULL if + the attribute could not be found, just like XMLReader::getAttribute. ======================================== 5. New Functions ======================================== -- Core: - - array_column() - - boolval() - - password_get_info() - - password_hash() - - password_needs_rehash() - - password_verify() +- Openssl: + Added string openssl_x509_fingerprint($x509, $type, $binary). -- cURL: - - curl_file_create - -- GD - - imageflip - - imagecrop - - imagecropauto - - imagesetinterpolation - - imageaffine - - imageaffinematrixget - - imageaffinematrixconcat - - imagescale - -- Hash: - - hash_pbkdf2() - -- Intl: - - datefmt_format_object() - - datefmt_get_calendar_object() - - datefmt_get_timezone() - - datefmt_set_timezone() - - datefmt_get_calendar_object() - - intlcal_create_instance() - - intlcal_get_keyword_values_for_locale() - - intlcal_get_now() - - intlcal_get_available_locales() - - intlcal_get() - - intlcal_get_time() - - intlcal_set_time() - - intlcal_add() - - intlcal_set_time_zone() - - intlcal_after() - - intlcal_before() - - intlcal_set() - - intlcal_roll() - - intlcal_clear() - - intlcal_field_difference() - - intlcal_get_actual_maximum() - - intlcal_get_actual_minimum() - - intlcal_get_day_of_week_type() - - intlcal_get_first_day_of_week() - - intlcal_get_greatest_minimum() - - intlcal_get_least_maximum() - - intlcal_get_locale() - - intlcal_get_maximum() - - intlcal_get_minimal_days_in_first_week() - - intlcal_get_minimum() - - intlcal_get_time_zone() - - intlcal_get_type() - - intlcal_get_weekend_transition() - - intlcal_in_daylight_time() - - intlcal_is_equivalent_to() - - intlcal_is_lenient() - - intlcal_is_set() - - intlcal_is_weekend() - - intlcal_set_first_day_of_week() - - intlcal_set_lenient() - - intlcal_equals() - - intlcal_get_repeated_wall_time_option() - - intlcal_get_skipped_wall_time_option() - - intlcal_set_repeated_wall_time_option() - - intlcal_set_skipped_wall_time_option() - - intlcal_from_date_time() - - intlcal_to_date_time() - - intlcal_get_error_code() - - intlcal_get_error_message() - - intlgregcal_create_instance() - - intlgregcal_set_gregorian_change() - - intlgregcal_get_gregorian_change() - - intlgregcal_is_leap_year() - - intltz_create_time_zone() - - intltz_create_default() - - intltz_get_id() - - intltz_get_gmt() - - intltz_get_unknown() - - intltz_create_enumeration() - - intltz_count_equivalent_ids() - - intltz_create_time_zone_id_enumeration() - - intltz_get_canonical_id() - - intltz_get_region() - - intltz_get_tz_data_version() - - intltz_get_equivalent_id() - - intltz_use_daylight_time() - - intltz_get_offset() - - intltz_get_raw_offset() - - intltz_has_same_rules() - - intltz_get_display_name() - - intltz_get_dst_savings() - - intltz_from_date_time_zone() - - intltz_to_date_time_zone() - - intltz_get_error_code() - - intltz_get_error_message() - - - IntlDateFormatter::formatObject() - - IntlDateFormatter::getCalendarObject() - - IntlDateFormatter::getTimeZone() - - IntlDateFormatter::setTimeZone() - -- Sockets: - - socket_sendmsg() - - socket_recvmsg() - - socket_cmsg_space() - -- SPL: - - SplFixedArray::__wakeup() - - SplDoublyLinkedList::add() - - RecursiveTreeIterator::getPostfix() (5.5.2) - - RecursiveTreeIterator::setPostfix() (5.5.2) - -- Zend OPcache: - - opcache_get_configuration() - - opcache_get_status() - - opcache_reset() +- LDAP: + Added ldap_escape($value, $ignore = "", $flags = 0). + +- Zip: + Added ZipArchive::setPassword($password) ======================================== 6. New Classes and Interfaces ======================================== -- Intl: - - IntlCalendar - - IntlGregorianCalendar - - IntlTimeZone - - IntlBreakIterator - - IntlRuleBasedBreakIterator - - IntlCodePointBreakIterator - - UConverter - -- cURL: - - CURLFile ======================================== 7. Removed Extensions ======================================== -None ======================================== 8. Other Changes to Extensions ======================================== -- Intl: - - This extension now requires ICU 4.0+. -- Phar: - - Added ability of resolving alias created by Phar::map +- GMP: + The GMP extension now uses objects as the underlying data structure, rather + than resources. GMP instances now support dumping, serialization, cloning, + casts to primitive types and have overloaded operators. + (RFC: https://wiki.php.net/rfc/operator_overloading_gmp) + +- OCI8: + - Added Implicit Result Set support for Oracle Database 12c with a + new oci_get_implicit_resultset() function. + - Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no longer + unnecessarily initiates an internal ROLLBACK during connection + close. + - Added DTrace probes enabled with PHP's generic --enable-dtrace + - The oci_internal_debug() function is now a no-op. + - The phpinfo() output format for OCI8 has changed. ======================================== 9. New Global Constants ======================================== -- mysqli: - - Added MYSQLI_SERVER_PUBLIC_KEY constant to be used with mysqli_options() - -- cURL: - - Added CURLOPT_SAFE_UPLOAD to be used with curl_setopt(). - - Added CURL_WRAPPERS_ENABLED to reflect --with-curlwrappers. - -- GD - - Added constants for imageflip: - . IMG_FLIP_HORIZONTAL - . IMG_FLIP_VERTICAL - . IMG_FLIP_BOTH - - Added constants for imagecrop - . IMG_CROP_DEFAULT - . IMG_CROP_TRANSPARENT - . IMG_CROP_BLACK - . IMG_CROP_WHITE - . IMG_CROP_SIDES - . IMG_CROP_THRESHOLD - - Added constants for imagesetinterpolation, used by imagescale - imagerotate and imageaffine: - . IMG_BELL - . IMG_BESSEL - . IMG_BILINEAR_FIXED - . IMG_BICUBIC - . IMG_BICUBIC_FIXED - . IMG_BLACKMAN - . IMG_BOX - . IMG_BSPLINE - . IMG_CATMULLROM - . IMG_GAUSSIAN - . IMG_GENERALIZED_CUBIC - . IMG_HERMITE - . IMG_HAMMING - . IMG_HANNING - . IMG_MITCHELL - . IMG_POWER - . IMG_QUADRATIC - . IMG_SINC - . IMG_NEAREST_NEIGHBOUR - . IMG_WEIGHTED4 - . IMG_TRIANGLE - - Added constants for imageaffinematrixget - . IMG_AFFINE_TRANSLATE - . IMG_AFFINE_SCALE - . IMG_AFFINE_ROTATE - . IMG_AFFINE_SHEAR_HORIZONTAL - . IMG_AFFINE_SHEAR_VERTICAL +- LDAP: + LDAP_ESCAPE_FILTER int(1) + LDAP_ESCAPE_DN int(2) ======================================== 10. Changes to INI File Handling ======================================== - Core: - - Added sys_temp_dir INI directive, for specifying temporary - directory. - -- Intl: - - Added intl.use_exceptions INI directive, which controls what - happens when global errors are set together with intl.error_level. - -- MSSQL: - - mssql.compatability_mode renamed to mssql.compatibility_mode in 5.5.2, - old directive still supported for BC reasons. - -- mysqlnd: - - Added mysqlnd.sha256_server_public_key INI PERDIR setting that - affects all APIs which use(are built) for mysqlnd. This allows - ext/mysqli to be used with the new auth protocol, although at - coarser level. - -- Sessions: - - Added session.use_strict_mode in 5.5.3, which prevents session - fixation attacks and session collisions. - See also https://wiki.php.net/rfc/strict_sessions - -- Zend OPcache (See http://php.net/manual/en/book.opcache.php) - - Added the following directives: - - opcache.enable (default "1") - - opcache.memory_consumption (default "64") - - opcache.interned_strings_buffer (default "4") - - opcache.max_accelerated_files (default "2000") - - opcache.max_wasted_percentage (default "5") - - opcache.use_cwd (default "1") - - opcache.validate_timestamps (default "1") - - opcache.revalidate_freq (default "2") - - opcache.revalidate_path (default "0") - - opcache.save_comments (default "1") - - opcache.load_comments (default "1") - - opcache.fast_shutdown (default "0") - - opcache.enable_file_override (default "0") - - opcache.optimization_level (default "0xffffffff") - - opcache.inherited_hack (default "1") - - opcache.blacklist_filename (default "") - - opcache.max_file_size (default "0") - - opcache.consistency_checks (default "0") - - opcache.force_restart_timeout (default "180") - - opcache.error_log (default "" which means stderr) - - opcache.log_verbosity_level (default "1") - - opcache.preferred_memory_model (default "") - - opcache.protect_memory (default "0") - - opcache.mmap_base (Windows-only) - -======================================== -11. Windows Support -======================================== - -- The Apache 2.4 handler is supported as of PHP 5.5.0 - -- OPcache: Errors like 'unable to reattach to base address' could - happen in many common setups. It is due to some technical and - design restriction in the engine and could not be fixed easily - before 5.5.0 was released. - - A possible fix is to tweak the opcache.mmap_base INI setting by - forcing the first address to be tried. - - For x86 version, the following addreses can be tried: - . 0x20000000, 0x21000000, 0x30000000, 0x31000000, 0x50000000 - and for x64 (still experimental): - . 0x0000100000000000, 0x0000200000000000, 0x0000300000000000, 0x0000700000000000 + Removed always_populate_raw_post_data. ======================================== -12. Other Changes +11. Other Changes ======================================== -- If the APC or WinCache user cache APIs were used before, consider - these alternatives for PHP 5.5: +- File upload: + Uploads equal or greater than 2GB in size are now accepted. - - APCu - - all supported OSes: http://pecl.php.net/package/APCu - - Windows: http://windows.php.net/downloads/pecl/releases/apcu/ +- HTTP stream wrapper: + HTTP 1.1 requests now include a Connection: close header unless explicitly + overridden by setting a Connection header via the header context option. - - WinCache, Windows only: http://pecl.php.net/package/WinCache +- Zip: + New --with-libzip option allow to use system libzip. Version > 0.11 required. diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index bdc2a43ab9ce2..d1aca29dc4533 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -3,11 +3,10 @@ $Id$ UPGRADE NOTES - PHP X.Y 1. Internal API changes - a. Executor changes - b. Streams pooling API - c. Lowercasing and locales - d. zend_qsort_r - e. get_current_key + a. Addition of do_operation and compare object handlers + b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros + c. POST data handling + d. Arginfo changes 2. Build system changes a. Unix build system changes @@ -18,103 +17,108 @@ UPGRADE NOTES - PHP X.Y 1. Internal API changes ======================== - a. Executor changes - - * extensions can't override zend_execute() any more, they should override - zend_execute_ex() instead. The EG(current_execute_data) is already - initialized in zend_execute_ex(), so for compatibility extensions - may need to use EG(current_execute_data)->prev_execute_data instead. - * removed EG(arg_types_stack), EX(fbc), EX(called_scope), EX(current_object) - * added op_array->nested_calls. It's calculated at compile time. - * added EX(call_slots). It is an array to store information about syntaticaly - nested calls (e.g. foo(bar())). It's preallocated together with execute_data. - * added EX(call) - pointer to a current calling function. Actually an - element of EX(call_slots) - * opcodes INIT_METHOD_CALL, ZEND_INIT_STATIC_METHOD_CALL, - ZEND_INIT_FCALL_BY_NAME, ZEND_INIT_NS_FCALL_BY_NAME use result.num as - an index in EX(call_slots) - * opcode ZEND_NEW uses extended_vallue as an index in EX(call_slots) - * opcoes ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME use op2.num as - an index in EX(call_slots) - * added op_array->used_stack. It's calculated at compile time and the - corresponding stack space is preallocated together with execute_data. - ZEND_SEND* and ZEND_DO_FCALL* don't need to check for stack overflow - anymore. - * Removed execute_data->Ts field. The VM temporary variables always allocated - immediately before execute_data structure. Now they are accessed by offset - from the execute_data base pointer (instead of execute_data->Ts). Compiler - stores new offsets in op_array->opcodes[*].op?.num. You can use macros - EX_TMP_VAR() and EX_TMP_VAR_NUM() to access temp_variable by offset or - number. You can convert number to offset using EX_TMP_VAR_NUM(0, num) or - offset to number (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)). - * Removed execute_data->CVs field. The VM compiled variables always allocated - immediately after execute_data structure. Now they are accessed by offset - from the execute_data base pointer (instead of execute_data->CVs). You can - use macros EX_CV_NUM() to access compiled variables by number. - - b. Streams pooling API - -The streams pooling API has been removed. The following functions no longer -exist: - -PHPAPI int php_stream_context_get_link(php_stream_context *context, - const char *hostent, php_stream **stream); -PHPAPI int php_stream_context_set_link(php_stream_context *context, - const char *hostent, php_stream *stream); -PHPAPI int php_stream_context_del_link(php_stream_context *context, - php_stream *stream); - - c. Lowercasing and locales - -The lowercasing functions in zend_operators.c were split into those that do -lowercasing according to locale rules and those that do ASCII lowercasing. -ASCII: - - zend_str_tolower_copy - zend_str_tolower_dup - zend_str_tolower - zend_binary_strcasecmp - zend_binary_strncasecmp - -Locale-based: - zend_binary_strncasecmp_l - zend_binary_strcasecmp_l - zend_binary_zval_strcasecmp - zend_binary_zval_strncasecmp - string_compare_function_ex - string_case_compare_function - -Internal engine lowercasing will be using ASCII-only rules. User-facing functions, -such as strcasecmp, will be using locale rules. - -Two new functions - zend_binary_strncasecmp_l and zend_binary_strcasecmp_l - added as -locale-based counterparts to zend_binary_strcasecmp and zend_binary_strncasecmp. - - d. zend_qsort_r - -Added the function zend_qsort_r(): - -typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *); -void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC); - -The extra argument it has (relatively to zend_qsort()) is passed to the -comparison function. - - e. get_current_key - -The signature of the get_current_key iteration handler has been changed to: - -void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC); - -The key should be written into the zval* using the ZVAL_* macros. + a. Addition of do_operation and compare object handlers + + Two new object handlers have been added: + + do_operation: + typedef int (*zend_object_do_operation_t)( + zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC + ); + + compare: + typedef int (*zend_object_compare_zvals_t)( + zval *result, zval *op1, zval *op2 TSRMLS_DC + ); + + The first handler is used to overload arithmetic operations. The first + argument specifies the opcode of the operator, result is the target zval, + op1 the first operand and op2 the second operand. For unary operations + op2 is NULL. If the handler returns FAILURE PHP falls back to the default + behavior for the operation. + + The second handler is used to perform comparison operations with + non-objects. The value written into result must be an IS_LONG with value + -1 (smaller), 0 (equal) or 1 (greater). The return value is a SUCCESS/FAILURE + return code. The difference between this handler and compare_objects is + that it will be triggered for comparisons with non-objects and objects of + different types. It takes precedence over compare_objects. + + Further docs in the RFC: https://wiki.php.net/rfc/operator_overloading_gmp + + b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros + + The return_value_ptr argument to internal functions is now always set. + Previously it was only available for functions returning by-reference. + return_value_ptr can now be used to return zvals without copying them. + For this purpose two new macros are provided: + + RETVAL_ZVAL_FAST(zv); /* analog to RETVAL_ZVAL(zv, 1, 0) */ + RETURN_ZVAL_FAST(zv); /* analog to RETURN_ZVAL(zv, 1, 0) */ + + The macros behave similarly to the non-FAST variants with copy=1 and + dtor=0, but will try to return the zval without making a copy by utilizing + return_value_ptr. + + c. POST data handling + + The sapi_request_info's members post_data, post_data_len and raw_post_data as + well as raw_post_data_len have been replaced with a temp PHP stream + request_body. + + The recommended way to access raw POST data is to open and use a php://input + stream wrapper. It is safe to be used concurrently and more than once. + + d. Arginfo changes + + The pass_rest_by_reference argument of the ZEND_BEGIN_ARG_INFO and + ZEND_BEGIN_ARG_INFO_EX() is no longer used. The value passed to it is ignored. + + Instead a variadic argument is created using ZEND_ARG_VARIADIC_INFO(): + + ZEND_ARG_VARIADIC_INFO(0, name) /* pass rest by value */ + ZEND_ARG_VARIADIC_INFO(1, name) /* pass rest by reference */ + ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, name) + /* pass rest by prefer-ref */ + + ZEND_ARG_VARIADIC_INFO() should only be used for the last argument. + + The following changes were applied to the zend_arg_info struct: + + typedef struct _zend_arg_info { + const char *class_name; + zend_uint class_name_len; + zend_uchar type_hint; + + zend_uchar pass_by_reference; + zend_bool allow_null; + - zend_bool pass_by_reference; + + zend_bool is_variadic; + } zend_arg_info; + + The following changes were applied to the zend_internal_function_info struct: + + typedef struct _zend_internal_function_info { + zend_uint required_num_args; + zend_uchar _type_hint; + zend_bool return_reference; + - zend_bool pass_rest_by_reference; + + zend_bool _allow_null; + + zend_bool _is_variadic; + } zend_internal_function_info; + + The CHECK_ARG_SEND_TYPE(), ARG_MUST_BE_SENT_BY_REF(), + ARG_SHOULD_BE_SENT_BY_REF() and ARG_MAY_BE_SENT_BY_REF() macros now assume + that the argument passed to them is a zend_function* and that it is non-NULL. ======================== 2. Build system changes ======================== a. Unix build system changes - - + - The bison version check is now a blacklist instead of a whitelist. + - The bison binary can be specified through the YACC environment/configure + variable. Previously `bison` was assumed to be in $PATH. b. Windows build system changes - - Drop Windows XP and 2003 support. + - diff --git a/Zend/Makefile.am b/Zend/Makefile.am index 6417f3eb141ed..924a00daebb39 100644 --- a/Zend/Makefile.am +++ b/Zend/Makefile.am @@ -18,7 +18,7 @@ libZend_la_SOURCES=\ zend_default_classes.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c \ zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \ - zend_generators.c + zend_generators.c zend_virtual_cwd.c libZend_la_LDFLAGS = libZend_la_LIBADD = @ZEND_EXTRA_LIBS@ diff --git a/Zend/RFCs/003.txt b/Zend/RFCs/003.txt index 30fb4cec4912f..ac042183d426c 100644 --- a/Zend/RFCs/003.txt +++ b/Zend/RFCs/003.txt @@ -9,11 +9,11 @@ Modified: 2001-09-17 1. Background/Need ================== -Many internal function of PHP will reject parameters because of their +Many internal functions of PHP will reject parameters because of their type (the array and variable function come to mind). For userland this is not an easy task as there is no uniform way to do it. An addition to the engine for requiring loose types would allow -delevopers to know that the data passed to their functions is of the +developers to know that the data passed to their functions are of the correct type and reduce the need for duplicating the same code in every function to check for the type of data. @@ -57,7 +57,7 @@ function foo (array $var){ =========== Mis-matches in type should be reported as fatal errors and should halt -the execution of a script as that function can not be run and code +the execution of a script as that function cannot be run and code following could not reliably run. diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp index 23ebd4532b5e7..d1b3b8903004d 100644 --- a/Zend/Zend.dsp +++ b/Zend/Zend.dsp @@ -429,6 +429,10 @@ SOURCE=.\zend_ts_hash.h SOURCE=.\zend_variables.h # End Source File +# Begin Source File + +SOURCE=.\zend_virtual_cwd.c +# End Source File # End Group # Begin Group "Parsers" diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4 index 5a521dc98c7d9..7fa8c99940596 100644 --- a/Zend/acinclude.m4 +++ b/Zend/acinclude.m4 @@ -3,8 +3,13 @@ dnl dnl This file contains local autoconf functions. AC_DEFUN([LIBZEND_BISON_CHECK],[ - # we only support certain bison versions - bison_version_list="2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7" + # we only support certain bison versions; + # min: 2.4 (i.e. 204, major * 100 + minor for easier comparison) + bison_version_min="204" + # non-working versions, e.g. "3.0 3.2"; + # remove "none" when introducing the first incompatible bison version an + # separate any following additions by spaces + bison_version_exclude="3.0" # for standalone build of Zend Engine test -z "$SED" && SED=sed @@ -17,18 +22,22 @@ AC_DEFUN([LIBZEND_BISON_CHECK],[ if test -n "$bison_version_vars"; then set $bison_version_vars bison_version="${1}.${2}" - for bison_check_version in $bison_version_list; do - if test "$bison_version" = "$bison_check_version"; then - php_cv_bison_version="$bison_check_version (ok)" - break - fi - done + bison_version_num="`expr ${1} \* 100 + ${2}`" + if test $bison_version_num -ge $bison_version_min; then + php_cv_bison_version="$bison_version (ok)" + for bison_check_version in $bison_version_exclude; do + if test "$bison_version" = "$bison_check_version"; then + php_cv_bison_version=invalid + break + fi + done + fi fi ]) fi case $php_cv_bison_version in ""|invalid[)] - bison_msg="bison versions supported for regeneration of the Zend/PHP parsers: $bison_version_list (found: $bison_version)." + bison_msg="This bison version is not supported for regeneration of the Zend/PHP parsers (found: $bison_version, min: $bison_version_min, excluded: $bison_version_exclude)." AC_MSG_WARN([$bison_msg]) YACC="exit 0;" ;; diff --git a/Zend/tests/bug30820.phpt b/Zend/tests/bug30820.phpt index 97e46e9287b56..a0f71e72a7a11 100644 --- a/Zend/tests/bug30820.phpt +++ b/Zend/tests/bug30820.phpt @@ -2,6 +2,7 @@ Bug #30820 (static member conflict with $this->member silently ignored) --INI-- error_reporting=4095 +opcache.optimization_level=0 --FILE-- bar(); + +?> +--EXPECTF-- +Deprecated: Non-static method A::foo() should not be called statically, assuming $this from incompatible context in %s on line %d +string(1) "B" diff --git a/Zend/tests/use_const/alias.phpt b/Zend/tests/use_const/alias.phpt new file mode 100644 index 0000000000000..f179393006bef --- /dev/null +++ b/Zend/tests/use_const/alias.phpt @@ -0,0 +1,26 @@ +--TEST-- +aliasing imported constants to resolve naming conflicts +--FILE-- + +--EXPECT-- +int(42) +int(43) +Done diff --git a/Zend/tests/use_const/basic.phpt b/Zend/tests/use_const/basic.phpt new file mode 100644 index 0000000000000..6eaed7f27d379 --- /dev/null +++ b/Zend/tests/use_const/basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +import namespaced constant +--FILE-- + +--EXPECT-- +int(42) +int(43) +Done diff --git a/Zend/tests/use_const/case_sensivity.phpt b/Zend/tests/use_const/case_sensivity.phpt new file mode 100644 index 0000000000000..1977daa93bb9a --- /dev/null +++ b/Zend/tests/use_const/case_sensivity.phpt @@ -0,0 +1,12 @@ +--TEST-- +importing const with same name but different case +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_const/conflicting_use.phpt b/Zend/tests/use_const/conflicting_use.phpt new file mode 100644 index 0000000000000..3b3c4b3262e79 --- /dev/null +++ b/Zend/tests/use_const/conflicting_use.phpt @@ -0,0 +1,21 @@ +--TEST-- +use const statements with conflicting names +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use const bar\baz as baz because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/conflicting_use_alias.phpt b/Zend/tests/use_const/conflicting_use_alias.phpt new file mode 100644 index 0000000000000..8b563a4ca975e --- /dev/null +++ b/Zend/tests/use_const/conflicting_use_alias.phpt @@ -0,0 +1,18 @@ +--TEST-- +use and use const with the same alias +--FILE-- + +--EXPECT-- +string(3) "foo" diff --git a/Zend/tests/use_const/define_imported.phpt b/Zend/tests/use_const/define_imported.phpt new file mode 100644 index 0000000000000..5eb44be64a058 --- /dev/null +++ b/Zend/tests/use_const/define_imported.phpt @@ -0,0 +1,14 @@ +--TEST-- +defining const with same name as imported should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot declare const bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/define_imported_before.phpt b/Zend/tests/use_const/define_imported_before.phpt new file mode 100644 index 0000000000000..f674ce81e8ec2 --- /dev/null +++ b/Zend/tests/use_const/define_imported_before.phpt @@ -0,0 +1,18 @@ +--TEST-- +using const with same name as defined should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use const foo\bar as bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/includes/foo_bar.php b/Zend/tests/use_const/includes/foo_bar.php new file mode 100644 index 0000000000000..90ed451f364d0 --- /dev/null +++ b/Zend/tests/use_const/includes/foo_bar.php @@ -0,0 +1,5 @@ + +--EXPECTF-- +Notice: Use of undefined constant baz - assumed 'baz' in %s on line %d +string(3) "baz" diff --git a/Zend/tests/use_const/self_parent.phpt b/Zend/tests/use_const/self_parent.phpt new file mode 100644 index 0000000000000..b71f2ecc81fee --- /dev/null +++ b/Zend/tests/use_const/self_parent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Allow self and parent in use const statement +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_const/shadow_core.phpt b/Zend/tests/use_const/shadow_core.phpt new file mode 100644 index 0000000000000..7d8bcbd1892f4 --- /dev/null +++ b/Zend/tests/use_const/shadow_core.phpt @@ -0,0 +1,16 @@ +--TEST-- +shadowing a global core constant with a local version +--FILE-- + +--EXPECTF-- +int(42) +Done diff --git a/Zend/tests/use_const/shadow_global.phpt b/Zend/tests/use_const/shadow_global.phpt new file mode 100644 index 0000000000000..930cc9f0b8778 --- /dev/null +++ b/Zend/tests/use_const/shadow_global.phpt @@ -0,0 +1,25 @@ +--TEST-- +shadowing a global constant with a local version +--FILE-- + +--EXPECT-- +string(10) "global bar" +string(9) "local bar" +Done diff --git a/Zend/tests/use_function/alias.phpt b/Zend/tests/use_function/alias.phpt new file mode 100644 index 0000000000000..5f7e97fff87f0 --- /dev/null +++ b/Zend/tests/use_function/alias.phpt @@ -0,0 +1,30 @@ +--TEST-- +aliasing imported functions to resolve naming conflicts +--FILE-- + +--EXPECT-- +string(7) "foo.baz" +string(7) "bar.baz" +Done diff --git a/Zend/tests/use_function/basic.phpt b/Zend/tests/use_function/basic.phpt new file mode 100644 index 0000000000000..513a96620c17b --- /dev/null +++ b/Zend/tests/use_function/basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +import namespaced function +--FILE-- + +--EXPECT-- +string(11) "foo.bar.baz" +string(11) "foo.bar.baz" +Done diff --git a/Zend/tests/use_function/case_insensivity.phpt b/Zend/tests/use_function/case_insensivity.phpt new file mode 100644 index 0000000000000..ba6e3a7e4b1b5 --- /dev/null +++ b/Zend/tests/use_function/case_insensivity.phpt @@ -0,0 +1,13 @@ +--TEST-- +importing function with same name but different case should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function foo\BAR as BAR because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/conditional_function_declaration.phpt b/Zend/tests/use_function/conditional_function_declaration.phpt new file mode 100644 index 0000000000000..ccfb96103a6b6 --- /dev/null +++ b/Zend/tests/use_function/conditional_function_declaration.phpt @@ -0,0 +1,17 @@ +--TEST-- +function that is conditionally defined at runtime should not cause compiler error +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/use_function/conflicting_use.phpt b/Zend/tests/use_function/conflicting_use.phpt new file mode 100644 index 0000000000000..0221fbdebb38a --- /dev/null +++ b/Zend/tests/use_function/conflicting_use.phpt @@ -0,0 +1,25 @@ +--TEST-- +use function statements with conflicting names +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function bar\baz as baz because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/conflicting_use_alias.phpt b/Zend/tests/use_function/conflicting_use_alias.phpt new file mode 100644 index 0000000000000..2870512014de0 --- /dev/null +++ b/Zend/tests/use_function/conflicting_use_alias.phpt @@ -0,0 +1,20 @@ +--TEST-- +use and use function with the same alias +--FILE-- + +--EXPECT-- +string(3) "foo" diff --git a/Zend/tests/use_function/conflicting_use_const_alias.phpt b/Zend/tests/use_function/conflicting_use_const_alias.phpt new file mode 100644 index 0000000000000..2e0faf0da21a6 --- /dev/null +++ b/Zend/tests/use_function/conflicting_use_const_alias.phpt @@ -0,0 +1,23 @@ +--TEST-- +use const and use function with the same alias +--FILE-- + +--EXPECT-- +string(9) "foo.const" +string(12) "foo.function" diff --git a/Zend/tests/use_function/define_imported.phpt b/Zend/tests/use_function/define_imported.phpt new file mode 100644 index 0000000000000..c542a4d5494b9 --- /dev/null +++ b/Zend/tests/use_function/define_imported.phpt @@ -0,0 +1,14 @@ +--TEST-- +defining function with same name as imported should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot declare function bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/define_imported_before.phpt b/Zend/tests/use_function/define_imported_before.phpt new file mode 100644 index 0000000000000..91974e0783d15 --- /dev/null +++ b/Zend/tests/use_function/define_imported_before.phpt @@ -0,0 +1,18 @@ +--TEST-- +using function with same name as defined should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function foo\bar as bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/ignore_constants.phpt b/Zend/tests/use_function/ignore_constants.phpt new file mode 100644 index 0000000000000..c50ff7357af17 --- /dev/null +++ b/Zend/tests/use_function/ignore_constants.phpt @@ -0,0 +1,23 @@ +--TEST-- +use function should ignore namespaced constants +--FILE-- + +--EXPECT-- +int(43) +Done diff --git a/Zend/tests/use_function/includes/foo_bar.php b/Zend/tests/use_function/includes/foo_bar.php new file mode 100644 index 0000000000000..6d2f8cab45fb4 --- /dev/null +++ b/Zend/tests/use_function/includes/foo_bar.php @@ -0,0 +1,7 @@ + +--EXPECTF-- +Fatal error: Call to undefined function foo\bar\baz() in %s on line %d diff --git a/Zend/tests/use_function/no_global_fallback2.phpt b/Zend/tests/use_function/no_global_fallback2.phpt new file mode 100644 index 0000000000000..5d012c10e5912 --- /dev/null +++ b/Zend/tests/use_function/no_global_fallback2.phpt @@ -0,0 +1,18 @@ +--TEST-- +non-existent imported functions should not be looked up in the global table +--FILE-- + +--EXPECTF-- +Fatal error: Call to undefined function bar\test() in %s on line %d diff --git a/Zend/tests/use_function/self_parent.phpt b/Zend/tests/use_function/self_parent.phpt new file mode 100644 index 0000000000000..f1e1fa84f1de1 --- /dev/null +++ b/Zend/tests/use_function/self_parent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Allow self and parent in use function statement +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_function/shadow_core.phpt b/Zend/tests/use_function/shadow_core.phpt new file mode 100644 index 0000000000000..8f92ff1e1be86 --- /dev/null +++ b/Zend/tests/use_function/shadow_core.phpt @@ -0,0 +1,16 @@ +--TEST-- +shadowing a global core function with a local version +--FILE-- + +--EXPECT-- +int(4) +Done diff --git a/Zend/tests/use_function/shadow_global.phpt b/Zend/tests/use_function/shadow_global.phpt new file mode 100644 index 0000000000000..791bcdf4d50d6 --- /dev/null +++ b/Zend/tests/use_function/shadow_global.phpt @@ -0,0 +1,25 @@ +--TEST-- +shadowing a global function with a local version +--FILE-- + +--EXPECT-- +string(10) "global bar" +string(9) "local bar" +Done diff --git a/Zend/tests/variadic/adding_additional_optional_parameter.phpt b/Zend/tests/variadic/adding_additional_optional_parameter.phpt new file mode 100644 index 0000000000000..b4e797803dcf2 --- /dev/null +++ b/Zend/tests/variadic/adding_additional_optional_parameter.phpt @@ -0,0 +1,17 @@ +--TEST-- +It's possible to add additional optional arguments with matching signature +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt b/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt new file mode 100644 index 0000000000000..2f31d47dc6969 --- /dev/null +++ b/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Additional optional parameters must have a matching prototype +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d diff --git a/Zend/tests/variadic/basic.phpt b/Zend/tests/variadic/basic.phpt new file mode 100644 index 0000000000000..810d4756aa087 --- /dev/null +++ b/Zend/tests/variadic/basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +Basic variadic function +--FILE-- + +--EXPECT-- +array(0) { +} +array(1) { + [0]=> + int(1) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +int(1) +int(2) +array(0) { +} +int(1) +int(2) +array(1) { + [0]=> + int(3) +} +int(1) +int(2) +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} diff --git a/Zend/tests/variadic/by_ref.phpt b/Zend/tests/variadic/by_ref.phpt new file mode 100644 index 0000000000000..e1635f4ecf20a --- /dev/null +++ b/Zend/tests/variadic/by_ref.phpt @@ -0,0 +1,24 @@ +--TEST-- +Variadic arguments with by-reference passing +--FILE-- + +--EXPECT-- +int(0) +int(0) +int(1) +int(2) diff --git a/Zend/tests/variadic/by_ref_error.phpt b/Zend/tests/variadic/by_ref_error.phpt new file mode 100644 index 0000000000000..7f21014146406 --- /dev/null +++ b/Zend/tests/variadic/by_ref_error.phpt @@ -0,0 +1,12 @@ +--TEST-- +By-ref variadics enforce the reference +--FILE-- + +--EXPECTF-- +Fatal error: Only variables can be passed by reference in %s on line %d diff --git a/Zend/tests/variadic/no_default_error.phpt b/Zend/tests/variadic/no_default_error.phpt new file mode 100644 index 0000000000000..427ebed0289a9 --- /dev/null +++ b/Zend/tests/variadic/no_default_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variadic argument cannot have a default value +--FILE-- + +--EXPECTF-- +Fatal error: Variadic parameter cannot have a default value in %s on line %d diff --git a/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt b/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt new file mode 100644 index 0000000000000..f447837ca4afb --- /dev/null +++ b/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +It's not possible to turn a variadic function into a non-variadic one +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d diff --git a/Zend/tests/variadic/only_last_error.phpt b/Zend/tests/variadic/only_last_error.phpt new file mode 100644 index 0000000000000..ee6ff3f777c46 --- /dev/null +++ b/Zend/tests/variadic/only_last_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Only the last argument can be variadic +--FILE-- + +--EXPECTF-- +Fatal error: Only the last parameter can be variadic in %s on line %d diff --git a/Zend/tests/variadic/optional_params.phpt b/Zend/tests/variadic/optional_params.phpt new file mode 100644 index 0000000000000..ba965e538c4f9 --- /dev/null +++ b/Zend/tests/variadic/optional_params.phpt @@ -0,0 +1,49 @@ +--TEST-- +Optional parameter before variadic parameter +--FILE-- + +--EXPECT-- +int(1) +NULL +array(0) { +} +int(1) +int(2) +array(0) { +} +int(1) +int(2) +array(1) { + [0]=> + int(3) +} +int(1) +int(2) +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +int(1) +int(2) +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} diff --git a/Zend/tests/variadic/removing_parameter_error.phpt b/Zend/tests/variadic/removing_parameter_error.phpt new file mode 100644 index 0000000000000..a189e5cf094b7 --- /dev/null +++ b/Zend/tests/variadic/removing_parameter_error.phpt @@ -0,0 +1,20 @@ +--TEST-- +It's not possible to remove required parameter before a variadic parameter +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d diff --git a/Zend/tests/variadic/typehint_error.phpt b/Zend/tests/variadic/typehint_error.phpt new file mode 100644 index 0000000000000..3006b999576c6 --- /dev/null +++ b/Zend/tests/variadic/typehint_error.phpt @@ -0,0 +1,36 @@ +--TEST-- +Variadic arguments enforce typehints +--FILE-- + +--EXPECTF-- +array(0) { +} +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } +} + +Catchable fatal error: Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d diff --git a/Zend/tests/variadic/typehint_suppressed_error.phpt b/Zend/tests/variadic/typehint_suppressed_error.phpt new file mode 100644 index 0000000000000..5048e1c1bb5ab --- /dev/null +++ b/Zend/tests/variadic/typehint_suppressed_error.phpt @@ -0,0 +1,33 @@ +--TEST-- +Error suppression for typehints on variadic arguments works +--FILE-- + +--EXPECTF-- +string(%d) "Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d and defined" +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + int(2) +} diff --git a/Zend/tests/variadic/variadic_changed_byref_error.phpt b/Zend/tests/variadic/variadic_changed_byref_error.phpt new file mode 100644 index 0000000000000..14fb6ae5eb0d9 --- /dev/null +++ b/Zend/tests/variadic/variadic_changed_byref_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Variadic arguments must have compatible passing modes +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, &...$params) in %s on line %d diff --git a/Zend/tests/variadic/variadic_changed_typehint_error.phpt b/Zend/tests/variadic/variadic_changed_typehint_error.phpt new file mode 100644 index 0000000000000..00df33a0424a4 --- /dev/null +++ b/Zend/tests/variadic/variadic_changed_typehint_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Typehints for variadic arguments have to be compatible +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d diff --git a/Zend/tests/variadic/variadic_implements_non_variadic.phpt b/Zend/tests/variadic/variadic_implements_non_variadic.phpt new file mode 100644 index 0000000000000..a66ec280b8626 --- /dev/null +++ b/Zend/tests/variadic/variadic_implements_non_variadic.phpt @@ -0,0 +1,17 @@ +--TEST-- +A non-variadic function can be turned into a variadic one +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/zend_signed_multiply-32bit.phpt b/Zend/tests/zend_signed_multiply-32bit.phpt new file mode 100644 index 0000000000000..3f37cbac19908 --- /dev/null +++ b/Zend/tests/zend_signed_multiply-32bit.phpt @@ -0,0 +1,14 @@ +--TEST-- +Zend signed multiply 32-bit +--SKIPIF-- + 0) print "skip Running on 64-bit target"; ?> +--FILE-- + +--EXPECTF-- +int(-2147450880) +int(2147483646) +float(-2147516415) diff --git a/Zend/tests/zend_signed_multiply-64bit.phpt b/Zend/tests/zend_signed_multiply-64bit.phpt new file mode 100644 index 0000000000000..94a6e035fac3f --- /dev/null +++ b/Zend/tests/zend_signed_multiply-64bit.phpt @@ -0,0 +1,14 @@ +--TEST-- +Zend signed multiply 64-bit +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +int(-9223372034707292160) +int(9223372036854775806) +float(-9.2233720390023E+18) diff --git a/Zend/zend.c b/Zend/zend.c index 11baf34c93566..a5ed953cd0de0 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -30,6 +30,7 @@ #include "zend_ini.h" #include "zend_vm.h" #include "zend_dtrace.h" +#include "zend_virtual_cwd.h" #ifdef ZTS # define GLOBAL_FUNCTION_TABLE global_function_table @@ -652,6 +653,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS start_memory_manager(TSRMLS_C); + virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */ + #if defined(__FreeBSD__) || defined(__DragonFly__) /* FreeBSD and DragonFly floating point precision fix */ fpsetmask(0); @@ -802,9 +805,14 @@ void zend_post_startup(TSRMLS_D) /* {{{ */ compiler_globals_ctor(compiler_globals, tsrm_ls); } free(EG(zend_constants)); + + virtual_cwd_deactivate(TSRMLS_C); + executor_globals_ctor(executor_globals, tsrm_ls); global_persistent_list = &EG(persistent_list); zend_copy_ini_directives(TSRMLS_C); +#else + virtual_cwd_deactivate(TSRMLS_C); #endif } /* }}} */ @@ -820,6 +828,9 @@ void zend_shutdown(TSRMLS_D) /* {{{ */ zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); zend_destroy_modules(); + virtual_cwd_deactivate(TSRMLS_C); + virtual_cwd_shutdown(); + zend_hash_destroy(GLOBAL_FUNCTION_TABLE); zend_hash_destroy(GLOBAL_CLASS_TABLE); @@ -910,6 +921,9 @@ ZEND_API char *get_zend_version(void) /* {{{ */ void zend_activate(TSRMLS_D) /* {{{ */ { +#ifdef ZTS + virtual_cwd_activate(TSRMLS_C); +#endif gc_reset(TSRMLS_C); init_compiler(TSRMLS_C); init_executor(TSRMLS_C); diff --git a/Zend/zend.h b/Zend/zend.h index af653b15eb5b1..5ac884455d4d0 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -22,7 +22,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "2.5.0" +#define ZEND_VERSION "2.6.0-dev" #define ZEND_ENGINE_2 @@ -193,7 +193,7 @@ char *alloca (); #endif #define restrict __restrict__ -#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) +#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) # define ZEND_ALLOCA_MAX_SIZE (32 * 1024) # define ALLOCA_FLAG(name) \ zend_bool name; @@ -670,8 +670,8 @@ END_EXTERN_C() /* FIXME: Check if we can save if (ptr) too */ -#define STR_FREE(ptr) if (ptr && !IS_INTERNED(ptr)) { efree(ptr); } -#define STR_FREE_REL(ptr) if (ptr && !IS_INTERNED(ptr)) { efree_rel(ptr); } +#define STR_FREE(ptr) if (ptr) { str_efree(ptr); } +#define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); } #define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b59faab28458d..5fa7fb908e500 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2029,7 +2029,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio const zend_function_entry *ptr = functions; zend_function function, *reg_function; zend_internal_function *internal_function = (zend_internal_function *)&function; - int count=0, unload=0, result=0; + int count=0, unload=0; HashTable *target_function_table = function_table; int error_type; zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL; @@ -2037,6 +2037,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio int fname_len; const char *lc_class_name = NULL; int class_name_len = 0; + zend_ulong hash; if (type==MODULE_PERSISTENT) { error_type = E_CORE_WARNING; @@ -2089,16 +2090,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } else { internal_function->required_num_args = info->required_num_args; } - if (info->pass_rest_by_reference) { - if (info->pass_rest_by_reference == ZEND_SEND_PREFER_REF) { - internal_function->fn_flags |= ZEND_ACC_PASS_REST_PREFER_REF; - } else { - internal_function->fn_flags |= ZEND_ACC_PASS_REST_BY_REFERENCE; - } - } if (info->return_reference) { internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE; } + if (ptr->arg_info[ptr->num_args].is_variadic) { + internal_function->fn_flags |= ZEND_ACC_VARIADIC; + } } else { internal_function->arg_info = NULL; internal_function->num_args = 0; @@ -2135,12 +2132,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } fname_len = strlen(ptr->fname); lowercase_name = zend_new_interned_string(zend_str_tolower_dup(ptr->fname, fname_len), fname_len + 1, 1 TSRMLS_CC); - if (IS_INTERNED(lowercase_name)) { - result = zend_hash_quick_add(target_function_table, lowercase_name, fname_len+1, INTERNED_HASH(lowercase_name), &function, sizeof(zend_function), (void**)®_function); - } else { - result = zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)®_function); - } - if (result == FAILURE) { + hash = str_hash(lowercase_name, fname_len); + if (zend_hash_quick_add(target_function_table, lowercase_name, fname_len+1, hash, &function, sizeof(zend_function), (void**)®_function) == FAILURE) { unload=1; str_efree(lowercase_name); break; @@ -2493,6 +2486,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class { zend_class_entry *class_entry = malloc(sizeof(zend_class_entry)); char *lowercase_name = emalloc(orig_class_entry->name_length + 1); + zend_ulong hash; *class_entry = *orig_class_entry; class_entry->type = ZEND_INTERNAL_CLASS; @@ -2506,11 +2500,8 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class zend_str_tolower_copy(lowercase_name, orig_class_entry->name, class_entry->name_length); lowercase_name = (char*)zend_new_interned_string(lowercase_name, class_entry->name_length + 1, 1 TSRMLS_CC); - if (IS_INTERNED(lowercase_name)) { - zend_hash_quick_update(CG(class_table), lowercase_name, class_entry->name_length+1, INTERNED_HASH(lowercase_name), &class_entry, sizeof(zend_class_entry *), NULL); - } else { - zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, &class_entry, sizeof(zend_class_entry *), NULL); - } + hash = str_hash(lowercase_name, class_entry->name_length); + zend_hash_quick_update(CG(class_table), lowercase_name, class_entry->name_length+1, hash, &class_entry, sizeof(zend_class_entry *), NULL); str_efree(lowercase_name); return class_entry; } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ecc8d9acd9f43..007d9896092be 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -98,16 +98,18 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FE_END { NULL, NULL, NULL, 0, 0 } -#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref}, -#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref}, -#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref}, -#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref}, -#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref}, -#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ +#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 1 }, + +#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \ static const zend_arg_info name[] = { \ - { NULL, 0, NULL, required_num_args, 0, return_reference, pass_rest_by_reference}, -#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \ - ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1) + { NULL, 0, NULL, required_num_args, 0, return_reference, 0, 0 }, +#define ZEND_BEGIN_ARG_INFO(name, _unused) \ + ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1) #define ZEND_END_ARG_INFO() }; /* Name macros */ @@ -594,22 +596,20 @@ END_EXTERN_C() Z_TYPE_P(__z) = IS_STRING; \ } while (0) -#define ZVAL_ZVAL(z, zv, copy, dtor) { \ - zend_uchar is_ref = Z_ISREF_P(z); \ - zend_uint refcount = Z_REFCOUNT_P(z); \ - ZVAL_COPY_VALUE(z, zv); \ +#define ZVAL_ZVAL(z, zv, copy, dtor) do { \ + zval *__z = (z); \ + zval *__zv = (zv); \ + ZVAL_COPY_VALUE(__z, __zv); \ if (copy) { \ - zval_copy_ctor(z); \ + zval_copy_ctor(__z); \ } \ if (dtor) { \ if (!copy) { \ - ZVAL_NULL(zv); \ + ZVAL_NULL(__zv); \ } \ - zval_ptr_dtor(&zv); \ + zval_ptr_dtor(&__zv); \ } \ - Z_SET_ISREF_TO_P(z, is_ref); \ - Z_SET_REFCOUNT_P(z, refcount); \ - } + } while (0) #define ZVAL_FALSE(z) ZVAL_BOOL(z, 0) #define ZVAL_TRUE(z) ZVAL_BOOL(z, 1) @@ -638,6 +638,18 @@ END_EXTERN_C() #define RETURN_FALSE { RETVAL_FALSE; return; } #define RETURN_TRUE { RETVAL_TRUE; return; } +#define RETVAL_ZVAL_FAST(z) do { \ + zval *_z = (z); \ + if (Z_ISREF_P(_z)) { \ + RETVAL_ZVAL(_z, 1, 0); \ + } else { \ + zval_ptr_dtor(&return_value); \ + Z_ADDREF_P(_z); \ + *return_value_ptr = _z; \ + } \ +} while (0) +#define RETURN_ZVAL_FAST(z) { RETVAL_ZVAL_FAST(z); return; } + #define SET_VAR_STRING(n, v) { \ { \ zval *var; \ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6cbe0bc6872a5..55e5f34e83aab 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -435,9 +435,7 @@ ZEND_FUNCTION(func_get_arg) } arg = *(p-(arg_count-requested_offset)); - *return_value = *arg; - zval_copy_ctor(return_value); - INIT_PZVAL(return_value); + RETURN_ZVAL_FAST(arg); } /* }}} */ @@ -711,7 +709,7 @@ ZEND_FUNCTION(define) zval_ptr_dtor(&val_free); } c.flags = case_sensitive; /* non persistent */ - c.name = IS_INTERNED(name) ? name : zend_strndup(name, name_len); + c.name = str_strndup(name, name_len); if(c.name == NULL) { RETURN_FALSE; } @@ -1393,12 +1391,11 @@ ZEND_FUNCTION(function_exists) Creates an alias for user defined class */ ZEND_FUNCTION(class_alias) { - char *class_name, *lc_name, *alias_name; + char *class_name, *alias_name; zend_class_entry **ce; int class_name_len, alias_name_len; int found; zend_bool autoload = 1; - ALLOCA_FLAG(use_heap) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) { return; diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 5faefbd2241a4..fcad86f171058 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -59,14 +59,8 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */ } else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) { RETVAL_FALSE; } else if (closure_result_ptr) { - if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) { - if (return_value) { - zval_ptr_dtor(&return_value); - } - *return_value_ptr = closure_result_ptr; - } else { - RETVAL_ZVAL(closure_result_ptr, 1, 1); - } + zval_ptr_dtor(&return_value); + *return_value_ptr = closure_result_ptr; } efree(arguments); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 60b9e3e653c04..3b61ab28ecc4a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -26,7 +26,7 @@ #include "zend_llist.h" #include "zend_API.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_multibyte.h" #include "zend_language_scanner.h" @@ -61,11 +61,8 @@ } while (0) #define CALCULATE_LITERAL_HASH(num) do { \ - if (IS_INTERNED(Z_STRVAL(CONSTANT(num)))) { \ - Z_HASH_P(&CONSTANT(num)) = INTERNED_HASH(Z_STRVAL(CONSTANT(num))); \ - } else { \ - Z_HASH_P(&CONSTANT(num)) = zend_hash_func(Z_STRVAL(CONSTANT(num)), Z_STRLEN(CONSTANT(num))+1); \ - } \ + zval *c = &CONSTANT(num); \ + Z_HASH_P(c) = str_hash(Z_STRVAL_P(c), Z_STRLEN_P(c)); \ } while (0) #define GET_CACHE_SLOT(literal) do { \ @@ -107,9 +104,7 @@ ZEND_API zend_executor_globals executor_globals; static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */ { - if (!IS_INTERNED(property_info->name)) { - property_info->name = estrndup(property_info->name, property_info->name_length); - } + property_info->name = str_estrndup(property_info->name, property_info->name_length); if (property_info->doc_comment) { property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len); } @@ -118,9 +113,7 @@ static void zend_duplicate_property_info(zend_property_info *property_info) /* { static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */ { - if (!IS_INTERNED(property_info->name)) { - property_info->name = zend_strndup(property_info->name, property_info->name_length); - } + property_info->name = str_strndup(property_info->name, property_info->name_length); } /* }}} */ @@ -153,12 +146,12 @@ static void build_runtime_defined_function_key(zval *result, const char *name, i } /* NULL, name length, filename length, last accepting char position length */ - result->value.str.len = 1+name_length+strlen(filename)+char_pos_len; + Z_STRLEN_P(result) = 1+name_length+strlen(filename)+char_pos_len; /* must be binary safe */ - result->value.str.val = (char *) safe_emalloc(result->value.str.len, 1, 1); - result->value.str.val[0] = '\0'; - sprintf(result->value.str.val+1, "%s%s%s", name, filename, char_pos_buf); + Z_STRVAL_P(result) = (char *) safe_emalloc(Z_STRLEN_P(result), 1, 1); + Z_STRVAL_P(result)[0] = '\0'; + sprintf(Z_STRVAL_P(result)+1, "%s%s%s", name, filename, char_pos_buf); result->type = IS_STRING; Z_SET_REFCOUNT_P(result, 1); @@ -204,6 +197,10 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */ CG(in_namespace) = 0; CG(has_bracketed_namespaces) = 0; CG(current_import) = NULL; + CG(current_import_function) = NULL; + CG(current_import_const) = NULL; + zend_hash_init(&CG(function_filenames), 0, NULL, NULL, 0); + zend_hash_init(&CG(const_filenames), 0, NULL, NULL, 0); init_compiler_declarables(TSRMLS_C); zend_stack_init(&CG(context_stack)); @@ -242,6 +239,8 @@ void shutdown_compiler(TSRMLS_D) /* {{{ */ zend_stack_destroy(&CG(list_stack)); zend_hash_destroy(&CG(filenames_table)); zend_llist_destroy(&CG(open_files)); + zend_hash_destroy(&CG(function_filenames)); + zend_hash_destroy(&CG(const_filenames)); zend_stack_destroy(&CG(context_stack)); } /* }}} */ @@ -424,12 +423,16 @@ int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); CALCULATE_LITERAL_HASH(lc_literal); - ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)) + 1; - lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv)); - lc_name = zend_str_tolower_dup(ns_separator, lc_len); - ZVAL_STRINGL(&c, lc_name, lc_len, 0); - lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); - CALCULATE_LITERAL_HASH(lc_literal); + ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)); + + if (ns_separator != NULL) { + ns_separator += 1; + lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv)); + lc_name = zend_str_tolower_dup(ns_separator, lc_len); + ZVAL_STRINGL(&c, lc_name, lc_len, 0); + lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); + CALCULATE_LITERAL_HASH(lc_literal); + } return ret; } @@ -657,21 +660,21 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar zend_llist *fetch_list_ptr; if (varname->op_type == IS_CONST) { - ulong hash = 0; + ulong hash; if (Z_TYPE(varname->u.constant) != IS_STRING) { convert_to_string(&varname->u.constant); - } else if (IS_INTERNED(Z_STRVAL(varname->u.constant))) { - hash = INTERNED_HASH(Z_STRVAL(varname->u.constant)); } - if (!zend_is_auto_global_quick(varname->u.constant.value.str.val, varname->u.constant.value.str.len, hash TSRMLS_CC) && - !(varname->u.constant.value.str.len == (sizeof("this")-1) && - !memcmp(varname->u.constant.value.str.val, "this", sizeof("this"))) && + + hash = str_hash(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)); + if (!zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), hash TSRMLS_CC) && + !(Z_STRLEN(varname->u.constant) == (sizeof("this")-1) && + !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this"))) && (CG(active_op_array)->last == 0 || CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) { result->op_type = IS_CV; - result->u.op.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len, hash TSRMLS_CC); - varname->u.constant.value.str.val = (char*)CG(active_op_array)->vars[result->u.op.var].name; + result->u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), hash TSRMLS_CC); + Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[result->u.op.var].name; result->EA = 0; return; } @@ -694,7 +697,7 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar if (varname->op_type == IS_CONST) { CALCULATE_LITERAL_HASH(opline_ptr->op1.constant); - if (zend_is_auto_global_quick(varname->u.constant.value.str.val, varname->u.constant.value.str.len, Z_HASH_P(&CONSTANT(opline_ptr->op1.constant)) TSRMLS_CC)) { + if (zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), Z_HASH_P(&CONSTANT(opline_ptr->op1.constant)) TSRMLS_CC)) { opline_ptr->extended_value = ZEND_FETCH_GLOBAL; } } @@ -723,7 +726,7 @@ void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* if (class_name->op_type == IS_CONST && ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { - zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); class_node = *class_name; } else { zend_do_fetch_class(&class_node, class_name TSRMLS_CC); @@ -882,9 +885,9 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const method_type = "Abstract"; } - if (modifiers->u.constant.value.lval & ZEND_ACC_ABSTRACT) { - if(modifiers->u.constant.value.lval & ZEND_ACC_PRIVATE) { - zend_error(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private", method_type, CG(active_class_entry)->name, function_name->u.constant.value.str.val); + if (Z_LVAL(modifiers->u.constant) & ZEND_ACC_ABSTRACT) { + if(Z_LVAL(modifiers->u.constant) & ZEND_ACC_PRIVATE) { + zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -894,11 +897,11 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const SET_UNUSED(opline->op2); } else { /* we had code in the function body */ - zend_error(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body", method_type, CG(active_class_entry)->name, function_name->u.constant.value.str.val); + zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } } else { - if (body->u.constant.value.lval == ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body", CG(active_class_entry)->name, function_name->u.constant.value.str.val); + if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) { + zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } } } @@ -958,7 +961,7 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* { if (variable->op_type == IS_CV) { if (variable->u.op.var == CG(active_op_array)->this_var) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } else if (variable->op_type == IS_VAR) { int n = 0; @@ -1004,7 +1007,7 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* { GET_NODE(result, last_op->result); return; } else if (opline_is_fetch_this(last_op TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } else { break; } @@ -1028,7 +1031,7 @@ void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRM if (lvar->op_type == IS_CV) { if (lvar->u.op.var == CG(active_op_array)->this_var) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } else if (lvar->op_type == IS_VAR) { int last_op_number = get_next_op_number(CG(active_op_array)); @@ -1036,7 +1039,7 @@ void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRM if (last_op_number > 0) { opline = &CG(active_op_array)->opcodes[last_op_number-1]; if (opline_is_fetch_this(opline TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } } @@ -1278,10 +1281,10 @@ void zend_check_writable_variable(const znode *variable) /* {{{ */ zend_uint type = variable->EA; if (type & ZEND_PARSED_METHOD_CALL) { - zend_error(E_COMPILE_ERROR, "Can't use method return value in write context"); + zend_error_noreturn(E_COMPILE_ERROR, "Can't use method return value in write context"); } if (type == ZEND_PARSED_FUNCTION_CALL) { - zend_error(E_COMPILE_ERROR, "Can't use function return value in write context"); + zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context"); } } /* }}} */ @@ -1354,7 +1357,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS switch (type) { case BP_VAR_R: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } opline->opcode -= 3; break; @@ -1365,7 +1368,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS break; case BP_VAR_IS: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } opline->opcode += 6; /* 3+3 */ break; @@ -1375,7 +1378,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS break; case BP_VAR_UNSET: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for unsetting"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for unsetting"); } opline->opcode += 12; /* 3+3+3+3 */ break; @@ -1503,22 +1506,22 @@ int zend_do_verify_access_types(const znode *current_access_type, const znode *n { if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_ABSTRACT) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_STATIC) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_STATIC)) { - zend_error(E_COMPILE_ERROR, "Multiple static modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple static modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_FINAL) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_FINAL)) { - zend_error(E_COMPILE_ERROR, "Multiple final modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed"); } if (((Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)) & (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) == (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) { - zend_error(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member"); } return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)); } @@ -1527,8 +1530,8 @@ int zend_do_verify_access_types(const znode *current_access_type, const znode *n void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */ { zend_op_array op_array; - char *name = function_name->u.constant.value.str.val; - int name_len = function_name->u.constant.value.str.len; + char *name = Z_STRVAL(function_name->u.constant); + int name_len = Z_STRLEN(function_name->u.constant); int function_begin_line = function_token->u.op.opline_num; zend_uint fn_flags; const char *lcname; @@ -1538,7 +1541,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n if (is_method) { if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) { - zend_error(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, function_name->u.constant.value.str.val); + zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */ } @@ -1569,17 +1572,12 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); if (is_method) { - int result; + zend_ulong hash; lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC); - - if (IS_INTERNED(lcname)) { - result = zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, INTERNED_HASH(lcname), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); - } else { - result = zend_hash_add(&CG(active_class_entry)->function_table, lcname, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); - } - if (result == FAILURE) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name); + hash = str_hash(lcname, name_len); + if (zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, hash, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name); } zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); @@ -1696,6 +1694,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n } else { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zval key; + zval **ns_name; if (CG(current_namespace)) { /* Prefix function name with current namespace name */ @@ -1711,6 +1710,19 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n lcname = zend_str_tolower_dup(name, name_len); } + /* Function name must not conflict with import names */ + if (CG(current_import_function) && + zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) { + + char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name)); + + if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) || + memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) { + zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant)); + } + efree(tmp); + } + opline->opcode = ZEND_DECLARE_FUNCTION; opline->op1_type = IS_CONST; build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC); @@ -1721,6 +1733,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n CALCULATE_LITERAL_HASH(opline->op2.constant); opline->extended_value = ZEND_DECLARE_FUNCTION; zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); + zend_hash_add(&CG(function_filenames), lcname, strlen(lcname)+1, CG(compiled_filename), strlen(CG(compiled_filename))+1, NULL); zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); zend_init_compiler_context(TSRMLS_C); } @@ -1820,7 +1833,7 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1)); lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */ if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) { - zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); + zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); } } @@ -1834,26 +1847,17 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* } /* }}} */ -void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */ +void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_uchar pass_by_reference, zend_bool is_variadic TSRMLS_DC) /* {{{ */ { zend_op *opline; zend_arg_info *cur_arg_info; znode var; - if (class_type->op_type == IS_CONST && - Z_TYPE(class_type->u.constant) == IS_STRING && - Z_STRLEN(class_type->u.constant) == 0) { - /* Usage of namespace as class name not in namespace */ - zval_dtor(&class_type->u.constant); - zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name"); - return; - } - - if (zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant)); + if (zend_is_auto_global(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant) TSRMLS_CC)) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant)); } else { var.op_type = IS_CV; - var.u.op.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len, 0 TSRMLS_CC); + var.u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC); Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name; var.EA = 0; if (CG(active_op_array)->vars[var.u.op.var].hash_value == THIS_HASHVAL && @@ -1861,30 +1865,47 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-1)) { if (CG(active_op_array)->scope && (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } CG(active_op_array)->this_var = var.u.op.var; } } + if (CG(active_op_array)->fn_flags & ZEND_ACC_VARIADIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic"); + } + + if (is_variadic) { + if (op == ZEND_RECV_INIT) { + zend_error_noreturn(E_COMPILE_ERROR, "Variadic parameter cannot have a default value"); + } + + op = ZEND_RECV_VARIADIC; + CG(active_op_array)->fn_flags |= ZEND_ACC_VARIADIC; + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); CG(active_op_array)->num_args++; opline->opcode = op; SET_NODE(opline->result, &var); - SET_NODE(opline->op1, offset); + opline->op1_type = IS_UNUSED; + opline->op1.num = CG(active_op_array)->num_args; if (op == ZEND_RECV_INIT) { SET_NODE(opline->op2, initialization); } else { - CG(active_op_array)->required_num_args = CG(active_op_array)->num_args; SET_UNUSED(opline->op2); + if (!is_variadic) { + CG(active_op_array)->required_num_args = CG(active_op_array)->num_args; + } } CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args)); cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; - cur_arg_info->name = zend_new_interned_string(estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len), varname->u.constant.value.str.len + 1, 1 TSRMLS_CC); - cur_arg_info->name_len = varname->u.constant.value.str.len; + cur_arg_info->name = zend_new_interned_string(estrndup(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)), Z_STRLEN(varname->u.constant) + 1, 1 TSRMLS_CC); + cur_arg_info->name_len = Z_STRLEN(varname->u.constant); cur_arg_info->type_hint = 0; - cur_arg_info->allow_null = 1; cur_arg_info->pass_by_reference = pass_by_reference; + cur_arg_info->allow_null = 1; + cur_arg_info->is_variadic = is_variadic; cur_arg_info->class_name = NULL; cur_arg_info->class_name_len = 0; @@ -1898,7 +1919,7 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { cur_arg_info->allow_null = 1; } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); } } } else if (class_type->u.constant.type == IS_CALLABLE) { @@ -1907,22 +1928,22 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { cur_arg_info->allow_null = 1; } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL"); } } } else { cur_arg_info->type_hint = IS_OBJECT; if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) { - zend_resolve_class_name(class_type, opline->extended_value, 1 TSRMLS_CC); + zend_resolve_class_name(class_type TSRMLS_CC); } - Z_STRVAL(class_type->u.constant) = (char*)zend_new_interned_string(class_type->u.constant.value.str.val, class_type->u.constant.value.str.len + 1, 1 TSRMLS_CC); - cur_arg_info->class_name = class_type->u.constant.value.str.val; - cur_arg_info->class_name_len = class_type->u.constant.value.str.len; + Z_STRVAL(class_type->u.constant) = (char*)zend_new_interned_string(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant) + 1, 1 TSRMLS_CC); + cur_arg_info->class_name = Z_STRVAL(class_type->u.constant); + cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); if (op == ZEND_RECV_INIT) { if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { cur_arg_info->allow_null = 1; } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); } } } @@ -1937,7 +1958,7 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace char *lcname; char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant)); - zend_resolve_non_class_name(function_name, check_namespace TSRMLS_CC); + zend_resolve_function_name(function_name, &check_namespace TSRMLS_CC); if (check_namespace && CG(current_namespace) && !is_compound) { /* We assume we call function from the current namespace @@ -1949,16 +1970,16 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace return 1; } - lcname = zend_str_tolower_dup(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len); - if ((zend_hash_find(CG(function_table), lcname, function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) || + lcname = zend_str_tolower_dup(Z_STRVAL(function_name->u.constant), Z_STRLEN(function_name->u.constant)); + if ((zend_hash_find(CG(function_table), lcname, Z_STRLEN(function_name->u.constant)+1, (void **) &function)==FAILURE) || ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS) && (function->type == ZEND_INTERNAL_FUNCTION))) { zend_do_begin_dynamic_function_call(function_name, 0 TSRMLS_CC); efree(lcname); return 1; /* Dynamic */ } - efree(function_name->u.constant.value.str.val); - function_name->u.constant.value.str.val = lcname; + efree(Z_STRVAL(function_name->u.constant)); + Z_STRVAL(function_name->u.constant) = lcname; zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *)); if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) { @@ -1983,7 +2004,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */ if ((last_op->op2_type == IS_CONST) && (Z_TYPE(CONSTANT(last_op->op2.constant)) == IS_STRING) && (Z_STRLEN(CONSTANT(last_op->op2.constant)) == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !zend_binary_strcasecmp(Z_STRVAL(CONSTANT(last_op->op2.constant)), Z_STRLEN(CONSTANT(last_op->op2.constant)), ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1)) { - zend_error(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead"); } if (last_op->opcode == ZEND_FETCH_OBJ_R) { @@ -1991,11 +2012,9 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */ zval name; name = CONSTANT(last_op->op2.constant); if (Z_TYPE(name) != IS_STRING) { - zend_error(E_COMPILE_ERROR, "Method name must be a string"); - } - if (!IS_INTERNED(Z_STRVAL(name))) { - Z_STRVAL(name) = estrndup(Z_STRVAL(name), Z_STRLEN(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string"); } + Z_STRVAL(name) = str_estrndup(Z_STRVAL(name), Z_STRLEN(name)); FREE_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant); last_op->op2.constant = zend_add_func_name_literal(CG(active_op_array), &name TSRMLS_CC); @@ -2076,12 +2095,12 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML } /* }}} */ -void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */ +void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC) /* {{{ */ { znode tmp; int len; zval **ns; - char *lcname, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant)); + char *lookup_name, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant)); if (Z_STRVAL(element_name->u.constant)[0] == '\\') { /* name starts with \ so it is known and unambiguos, nothing to do here but shorten it */ @@ -2090,15 +2109,35 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace return; } - if(!check_namespace) { + if(!*check_namespace) { return; } + if (current_import_sub) { + len = Z_STRLEN(element_name->u.constant)+1; + if (case_sensitive) { + lookup_name = estrndup(Z_STRVAL(element_name->u.constant), len); + } else { + lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); + } + /* Check if function/const matches imported name */ + if (zend_hash_find(current_import_sub, lookup_name, len, (void**)&ns) == SUCCESS) { + zval_dtor(&element_name->u.constant); + element_name->u.constant = **ns; + zval_copy_ctor(&element_name->u.constant); + efree(lookup_name); + *check_namespace = 0; + return; + } + efree(lookup_name); + } + if (compound && CG(current_import)) { len = compound - Z_STRVAL(element_name->u.constant); - lcname = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); + /* namespace is always lowercase */ + lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); /* Check if first part of compound name is an import name */ - if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) { + if (zend_hash_find(CG(current_import), lookup_name, len+1, (void**)&ns) == SUCCESS) { /* Substitute import name */ tmp.op_type = IS_CONST; tmp.u.constant = **ns; @@ -2108,10 +2147,11 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+len, Z_STRLEN(element_name->u.constant)+1); zend_do_build_namespace_name(&tmp, &tmp, element_name TSRMLS_CC); *element_name = tmp; - efree(lcname); + efree(lookup_name); + *check_namespace = 0; return; } - efree(lcname); + efree(lookup_name); } if (CG(current_namespace)) { @@ -2121,24 +2161,36 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace memcpy(Z_STRVAL(tmp.u.constant), Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); memcpy(&(Z_STRVAL(tmp.u.constant)[Z_STRLEN_P(CG(current_namespace))]), "\\", sizeof("\\")-1); memcpy(&(Z_STRVAL(tmp.u.constant)[Z_STRLEN_P(CG(current_namespace)) + sizeof("\\")-1]), Z_STRVAL(element_name->u.constant), Z_STRLEN(element_name->u.constant)+1); - STR_FREE(Z_STRVAL(element_name->u.constant)); + str_efree(Z_STRVAL(element_name->u.constant)); *element_name = tmp; } } /* }}} */ +void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */ +{ + zend_resolve_non_class_name(element_name, check_namespace, 0, CG(current_import_function) TSRMLS_CC); +} +/* }}} */ + +void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */ +{ + zend_resolve_non_class_name(element_name, check_namespace, 1, CG(current_import_const) TSRMLS_CC); +} +/* }}} */ + void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC) /* {{{ */ { char *lcname; int lctype; znode constant_name; - lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), class_name->u.constant.value.str.len); + lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant)); lctype = zend_get_class_fetch_type(lcname, strlen(lcname)); switch (lctype) { case ZEND_FETCH_CLASS_SELF: if (!CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active"); } zval_dtor(&class_name->u.constant); class_name->op_type = IS_CONST; @@ -2148,13 +2200,13 @@ void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static case ZEND_FETCH_CLASS_STATIC: case ZEND_FETCH_CLASS_PARENT: if (is_static) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "%s::class cannot be used for compile-time class name resolution", lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent" ); } if (!CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Cannot access %s::class when no class scope is active", lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent" ); @@ -2164,7 +2216,7 @@ void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static zend_do_fetch_constant(result, class_name, &constant_name, ZEND_RT, 1 TSRMLS_CC); break; case ZEND_FETCH_CLASS_DEFAULT: - zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); *result = *class_name; break; } @@ -2174,7 +2226,7 @@ void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static } /* }}} */ -void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_name TSRMLS_DC) /* {{{ */ +void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */ { char *compound; char *lcname; @@ -2194,7 +2246,7 @@ void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_n Z_STRLEN(class_name->u.constant) + 1); if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { - zend_error(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant)); } } else { if (CG(current_import)) { @@ -2253,26 +2305,17 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ long fetch_class_op_number; zend_op *opline; - if (class_name->op_type == IS_CONST && - Z_TYPE(class_name->u.constant) == IS_STRING && - Z_STRLEN(class_name->u.constant) == 0) { - /* Usage of namespace as class name not in namespace */ - zval_dtor(&class_name->u.constant); - zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name"); - return; - } - fetch_class_op_number = get_next_op_number(CG(active_op_array)); opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_FETCH_CLASS; SET_UNUSED(opline->op1); - opline->extended_value = ZEND_FETCH_CLASS_GLOBAL; + opline->extended_value = ZEND_FETCH_CLASS_DEFAULT; CG(catch_begin) = fetch_class_op_number; if (class_name->op_type == IS_CONST) { int fetch_type; - fetch_type = zend_get_class_fetch_type(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); + fetch_type = zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant)); switch (fetch_type) { case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: @@ -2282,7 +2325,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ zval_dtor(&class_name->u.constant); break; default: - zend_resolve_class_name(class_name, opline->extended_value, 0 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &class_name->u.constant TSRMLS_CC); @@ -2311,7 +2354,7 @@ void zend_do_label(znode *label TSRMLS_DC) /* {{{ */ dest.opline_num = get_next_op_number(CG(active_op_array)); if (zend_hash_add(CG(context).labels, Z_STRVAL(label->u.constant), Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == FAILURE) { - zend_error(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant)); } /* Done with label now */ @@ -2337,7 +2380,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 CG(in_compilation) = 1; CG(active_op_array) = op_array; CG(zend_lineno) = opline->lineno; - zend_error(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label)); + zend_error_noreturn(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label)); } else { /* Label is not defined. Delay to pass 2. */ INC_BPC(op_array); @@ -2358,7 +2401,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 CG(active_op_array) = op_array; CG(zend_lineno) = opline->lineno; } - zend_error(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed"); + zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed"); } current = op_array->brk_cont_array[current].parent; } @@ -2419,19 +2462,19 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c } if (is_class_member) { - length = sizeof("::")-1 + result->u.constant.value.str.len + name->u.constant.value.str.len; - result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1); - memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], "::", sizeof("::")-1); - memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len + sizeof("::")-1], name->u.constant.value.str.val, name->u.constant.value.str.len+1); - STR_FREE(name->u.constant.value.str.val); - result->u.constant.value.str.len = length; + length = sizeof("::")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant); + Z_STRVAL(result->u.constant) = erealloc(Z_STRVAL(result->u.constant), length+1); + memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "::", sizeof("::")-1); + memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("::")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); + str_efree(Z_STRVAL(name->u.constant)); + Z_STRLEN(result->u.constant) = length; } else { - length = sizeof("\\")-1 + result->u.constant.value.str.len + name->u.constant.value.str.len; - result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1); - memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], "\\", sizeof("\\")-1); - memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len + sizeof("\\")-1], name->u.constant.value.str.val, name->u.constant.value.str.len+1); - STR_FREE(name->u.constant.value.str.val); - result->u.constant.value.str.len = length; + length = sizeof("\\")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant); + Z_STRVAL(result->u.constant) = erealloc(Z_STRVAL(result->u.constant), length+1); + memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "\\", sizeof("\\")-1); + memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("\\")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); + str_efree(Z_STRVAL(name->u.constant)); + Z_STRLEN(result->u.constant) = length; } } /* }}} */ @@ -2445,7 +2488,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na if (method_name->op_type == IS_CONST) { char *lcname; if (Z_TYPE(method_name->u.constant) != IS_STRING) { - zend_error(E_COMPILE_ERROR, "Method name must be a string"); + zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string"); } lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant)); if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) && @@ -2458,7 +2501,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na if (class_name->op_type == IS_CONST && ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { - zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); class_node = *class_name; opline = get_next_op(CG(active_op_array) TSRMLS_CC); } else { @@ -2554,12 +2597,12 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ function_ptr->common.function_name && function_ptr->common.type == ZEND_USER_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed; " "If you would like to pass argument by reference, modify the declaration of %s().", function_ptr->common.function_name); } else { - zend_error(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed"); + zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed"); } return; } @@ -2600,7 +2643,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ op = ZEND_SEND_REF; break; default: - zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference"); + zend_error_noreturn(E_COMPILE_ERROR, "Only variables can be passed by reference"); break; } } @@ -2749,7 +2792,7 @@ void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_v zend_op *opline; if (!CG(active_op_array)->function_name) { - zend_error(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function"); + zend_error_noreturn(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function"); } CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR; @@ -2886,10 +2929,10 @@ void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var if (class_name->op_type == IS_CONST && ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { - zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); catch_class = *class_name; } else { - zend_error(E_COMPILE_ERROR, "Bad class name in the catch statement"); + zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement"); } catch_op_number = get_next_op_number(CG(active_op_array)); @@ -2902,7 +2945,7 @@ void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var opline->op1_type = IS_CONST; opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), &catch_class.u.constant TSRMLS_CC); opline->op2_type = IS_CV; - opline->op2.var = lookup_cv(CG(active_op_array), catch_var->u.constant.value.str.val, catch_var->u.constant.value.str.len, 0 TSRMLS_CC); + opline->op2.var = lookup_cv(CG(active_op_array), Z_STRVAL(catch_var->u.constant), Z_STRLEN(catch_var->u.constant), 0 TSRMLS_CC); Z_STRVAL(catch_var->u.constant) = (char*)CG(active_op_array)->vars[opline->op2.var].name; opline->result.num = 0; /* 1 means it's the last catch in the block */ @@ -2938,7 +2981,7 @@ void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ * void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */ { if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally"); } if (finally_token->op_type != IS_UNUSED) { zend_op *opline; @@ -3105,7 +3148,7 @@ static void do_inherit_method(zend_function *function) /* {{{ */ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto TSRMLS_DC) /* {{{ */ { - zend_uint i; + zend_uint i, num_args; /* If it's a user function then arg_info == NULL means we don't have any parameters but * we still need to do the arg number checks. We are only willing to ignore this for internal @@ -3135,48 +3178,66 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c return 0; } - if (fe->common.type != ZEND_USER_FUNCTION - && (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) != 0 - && (fe->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) == 0) { - return 0; - } - /* by-ref constraints on return values are covariant */ if ((proto->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) && !(fe->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { return 0; } - for (i=0; i < proto->common.num_args; i++) { - if (ZEND_LOG_XOR(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)) { + if ((proto->common.fn_flags & ZEND_ACC_VARIADIC) + && !(fe->common.fn_flags & ZEND_ACC_VARIADIC)) { + return 0; + } + + /* For variadic functions any additional (optional) arguments that were added must be + * checked against the signature of the variadic argument, so in this case we have to + * go through all the parameters of the function and not just those present in the + * prototype. */ + num_args = proto->common.num_args; + if ((fe->common.fn_flags & ZEND_ACC_VARIADIC) + && fe->common.num_args > proto->common.num_args) { + num_args = fe->common.num_args; + } + + for (i = 0; i < num_args; i++) { + zend_arg_info *fe_arg_info = &fe->common.arg_info[i]; + + zend_arg_info *proto_arg_info; + if (i < proto->common.num_args) { + proto_arg_info = &proto->common.arg_info[i]; + } else { + proto_arg_info = &proto->common.arg_info[proto->common.num_args-1]; + } + + if (ZEND_LOG_XOR(fe_arg_info->class_name, proto_arg_info->class_name)) { /* Only one has a type hint and the other one doesn't */ return 0; } - if (fe->common.arg_info[i].class_name) { + if (fe_arg_info->class_name) { const char *fe_class_name, *proto_class_name; zend_uint fe_class_name_len, proto_class_name_len; - if (!strcasecmp(fe->common.arg_info[i].class_name, "parent") && proto->common.scope) { + if (!strcasecmp(fe_arg_info->class_name, "parent") && proto->common.scope) { fe_class_name = proto->common.scope->name; fe_class_name_len = proto->common.scope->name_length; - } else if (!strcasecmp(fe->common.arg_info[i].class_name, "self") && fe->common.scope) { + } else if (!strcasecmp(fe_arg_info->class_name, "self") && fe->common.scope) { fe_class_name = fe->common.scope->name; fe_class_name_len = fe->common.scope->name_length; } else { - fe_class_name = fe->common.arg_info[i].class_name; - fe_class_name_len = fe->common.arg_info[i].class_name_len; + fe_class_name = fe_arg_info->class_name; + fe_class_name_len = fe_arg_info->class_name_len; } - if (!strcasecmp(proto->common.arg_info[i].class_name, "parent") && proto->common.scope && proto->common.scope->parent) { + if (!strcasecmp(proto_arg_info->class_name, "parent") && proto->common.scope && proto->common.scope->parent) { proto_class_name = proto->common.scope->parent->name; proto_class_name_len = proto->common.scope->parent->name_length; - } else if (!strcasecmp(proto->common.arg_info[i].class_name, "self") && proto->common.scope) { + } else if (!strcasecmp(proto_arg_info->class_name, "self") && proto->common.scope) { proto_class_name = proto->common.scope->name; proto_class_name_len = proto->common.scope->name_length; } else { - proto_class_name = proto->common.arg_info[i].class_name; - proto_class_name_len = proto->common.arg_info[i].class_name_len; + proto_class_name = proto_arg_info->class_name; + proto_class_name_len = proto_arg_info->class_name_len; } if (strcasecmp(fe_class_name, proto_class_name)!=0) { @@ -3203,24 +3264,17 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c } } } - if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { + if (fe_arg_info->type_hint != proto_arg_info->type_hint) { /* Incompatible type hint */ return 0; } /* by-ref constraints on arguments are invariant */ - if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) { + if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) { return 0; } } - if (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) { - for (i=proto->common.num_args; i < fe->common.num_args; i++) { - if (!fe->common.arg_info[i].pass_by_reference) { - return 0; - } - } - } return 1; } /* }}} */ @@ -3293,6 +3347,13 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ if (arg_info->pass_by_reference) { *(offset++) = '&'; } + + if (arg_info->is_variadic) { + *(offset++) = '.'; + *(offset++) = '.'; + *(offset++) = '.'; + } + *(offset++) = '$'; if (arg_info->name) { @@ -3308,7 +3369,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ idx /= 10; } while (idx > 0); } - if (i >= required) { + if (i >= required && !arg_info->is_variadic) { *(offset++) = ' '; *(offset++) = '='; *(offset++) = ' '; @@ -3403,14 +3464,14 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * && parent->common.fn_flags & ZEND_ACC_ABSTRACT && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope) && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", + zend_error_noreturn(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", parent->common.scope->name, child->common.function_name, child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name); } if (parent_flags & ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name); } child_flags = child->common.fn_flags; @@ -3418,15 +3479,15 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * */ if ((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC)) { if (child->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } else { - zend_error(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } } /* Disallow making an inherited method abstract. */ if ((child_flags & ZEND_ACC_ABSTRACT) && !(parent_flags & ZEND_ACC_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } if (parent_flags & ZEND_ACC_CHANGED) { @@ -3435,7 +3496,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * /* Prevent derived classes from restricting access that was available in parent classes */ if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK)) && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) { child->common.fn_flags |= ZEND_ACC_CHANGED; @@ -3454,7 +3515,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) { if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC)); + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC)); } } else if (EG(error_reporting) & E_STRICT || EG(user_error_handler)) { /* Check E_STRICT (or custom error handler) before the check so that we save some time */ if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) { @@ -3508,7 +3569,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) { if ((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC)) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s", (parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey, (child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey); @@ -3519,7 +3580,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro } if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) { zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset])); ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset]; @@ -3604,10 +3665,10 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent if ((ce->ce_flags & ZEND_ACC_INTERFACE) && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name); } if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) { - zend_error(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name); } ce->parent = parent_ce; @@ -3729,7 +3790,7 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, con if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) { if (*old_constant != *parent_constant) { - zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name); } return 0; } @@ -3761,7 +3822,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry if (i < parent_iface_num) { ignore = 1; } else { - zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name); } } } @@ -3834,7 +3895,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint ce->clone = fe; fe->common.fn_flags |= ZEND_ACC_CLONE; } else if (!strncmp(mname, ZEND_CONSTRUCTOR_FUNC_NAME, mname_len)) { if (ce->constructor) { - zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; } else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME, mname_len)) { @@ -3859,7 +3920,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint lowercase_name = (char*)zend_new_interned_string(lowercase_name, ce->name_length + 1, 1 TSRMLS_CC); if (!memcmp(mname, lowercase_name, mname_len)) { if (ce->constructor) { - zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; @@ -3883,14 +3944,14 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, const if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } @@ -3906,25 +3967,25 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, const } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } return; } else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - /* two trais can't define the same non-abstract method */ + /* two traits can't define the same non-abstract method */ #if 1 - zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s", + zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s", name, ce->name); -#else /* TODO: better errot message */ - zend_error(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s", +#else /* TODO: better error message */ + zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s", fn->common.scope->name, fn->common.function_name, ce->name, name, existing_fn->common.scope->name, existing_fn->common.function_name); @@ -4007,7 +4068,7 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, } } - lcname = hash_key->arKey; + lcname = (char *) hash_key->arKey; if (exclude_table == NULL || zend_hash_find(exclude_table, lcname, fnname_len, &dummy) == FAILURE) { /* is not in hashtable, thus, function is not to be excluded */ @@ -4048,7 +4109,7 @@ static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait zend_uint i; if ((trait->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name); } for (i = 0; i < ce->num_traits; i++) { @@ -4056,7 +4117,7 @@ static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait return; } } - zend_error(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name); } /* }}} */ @@ -4077,7 +4138,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* cur_method_ref = cur_precedence->trait_method; if (!(cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); } zend_check_trait_usage(ce, cur_precedence->trait_method->ce TSRMLS_CC); @@ -4089,7 +4150,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* cur_method_ref->mname_len + 1); efree(lcname); if (!method_exists) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "A precedence rule was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); @@ -4107,14 +4168,14 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* zend_uint name_length = strlen(class_name); if (!(cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", class_name); } zend_check_trait_usage(ce, cur_precedence->exclude_from_classes[j] TSRMLS_CC); /* make sure that the trait method is not from a class mentioned in exclude_from_classes, for consistency */ if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Inconsistent insteadof definition. " "The method %s is to be used from %s, but %s is also on the exclude list", cur_method_ref->method_name, @@ -4137,7 +4198,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* if (ce->trait_aliases[i]->trait_method->class_name) { cur_method_ref = ce->trait_aliases[i]->trait_method; if (!(cur_method_ref->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); } zend_check_trait_usage(ce, cur_method_ref->ce TSRMLS_CC); @@ -4149,7 +4210,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* efree(lcname); if (!method_exists) { - zend_error(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); + zend_error_noreturn(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); } } i++; @@ -4175,7 +4236,7 @@ static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_tra if (zend_hash_add(exclude_table, lcname, lcname_len, NULL, 0, NULL) == FAILURE) { efree(lcname); - zend_error(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name); + zend_error_noreturn(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name); } efree(lcname); } @@ -4300,7 +4361,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { } if (not_compatible) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed", find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name, property_info->ce->name, @@ -4349,7 +4410,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce if (!cur_alias->trait_method->ce) { if (cur_alias->alias) { /** Plain old inconsistency/typo/bug */ - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "An alias (%s) was defined for method %s(), but this method does not exist", cur_alias->alias, cur_alias->trait_method->method_name); @@ -4368,12 +4429,12 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce lc_method_name, cur_alias->trait_method->mname_len+1)) { efree(lc_method_name); - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error", cur_alias->trait_method->method_name); } else { efree(lc_method_name); - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "The modifiers of the trait method %s() are changed, but this method does not exist. Error", cur_alias->trait_method->method_name); @@ -4460,7 +4521,7 @@ void zend_prepare_reference(znode *result, znode *class_name, znode *method_name /* REM: There should not be a need for copying, zend_do_begin_class_declaration is also just using that string */ if (class_name) { - zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); + zend_resolve_class_name(class_name TSRMLS_CC); method_ref->class_name = Z_STRVAL(class_name->u.constant); method_ref->cname_len = Z_STRLEN(class_name->u.constant); } else { @@ -4482,13 +4543,13 @@ void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alia zend_trait_alias *trait_alias; if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Cannot use 'static' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as method modifier"); return; } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier"); return; } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot use 'final' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as method modifier"); return; } @@ -4530,7 +4591,7 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze op2 = opline->op2.zv; } if (zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1)); + zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1)); return NULL; } else { ce = *pce; @@ -4544,7 +4605,7 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze * so we shut up about it. This allows the if (!defined('FOO')) { return; } * approach to work. */ - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); } return NULL; } else { @@ -4579,7 +4640,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array * so we shut up about it. This allows the if (!defined('FOO')) { return; } * approach to work. */ - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2)); } return NULL; } else { @@ -4587,9 +4648,9 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array } if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name); } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name); } zend_do_inheritance(ce, parent_ce TSRMLS_CC); @@ -4598,7 +4659,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array /* Register the derived class */ if (zend_hash_quick_add(class_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), pce, sizeof(zend_class_entry *), NULL)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); } return ce; } @@ -4667,7 +4728,7 @@ void zend_do_early_binding(TSRMLS_D) /* {{{ */ /* Classes with traits are handled exactly the same, no early-bind here */ return; default: - zend_error(E_COMPILE_ERROR, "Invalid binding type"); + zend_error_noreturn(E_COMPILE_ERROR, "Invalid binding type"); return; } @@ -4798,9 +4859,9 @@ void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */ SET_UNUSED(opline->op1); if (expr) { if (expr->op_type != IS_CONST) { - zend_error(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue"); + zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue"); } else if (Z_TYPE(expr->u.constant) != IS_LONG || Z_LVAL(expr->u.constant) < 1) { - zend_error(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue"); + zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue"); } SET_NODE(opline->op2, expr); } else { @@ -4959,15 +5020,15 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name zval **ns_name, key; if (CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, "Class declarations may not be nested"); + zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); return; } - lcname = zend_str_tolower_dup(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); + lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant)); if (!(strcmp(lcname, "self") && strcmp(lcname, "parent"))) { efree(lcname); - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant)); } /* Class name must not conflict with import names */ @@ -4994,7 +5055,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (Z_STRLEN_PP(ns_name) != Z_STRLEN(class_name->u.constant) || memcmp(tmp, lcname, Z_STRLEN(class_name->u.constant))) { - zend_error(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant)); } efree(tmp); } @@ -5012,13 +5073,13 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (parent_class_name && parent_class_name->op_type != IS_UNUSED) { switch (parent_class_name->EA) { case ZEND_FETCH_CLASS_SELF: - zend_error(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved"); break; case ZEND_FETCH_CLASS_PARENT: - zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved"); break; case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved"); break; default: break; @@ -5037,7 +5098,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (doing_inheritance) { /* Make sure a trait does not try to extend a class */ if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); + zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); } opline->extended_value = parent_class_name->u.op.var; @@ -5082,19 +5143,19 @@ void zend_do_end_class_declaration(const znode *class_token, const znode *parent if (ce->constructor) { ce->constructor->common.fn_flags |= ZEND_ACC_CTOR; if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name); } } if (ce->destructor) { ce->destructor->common.fn_flags |= ZEND_ACC_DTOR; if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name); } } if (ce->clone) { ce->clone->common.fn_flags |= ZEND_ACC_CLONE; if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name); } } @@ -5143,7 +5204,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ /* Traits can not implement interfaces */ if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait", Z_STRVAL(interface_name->u.constant), CG(active_class_entry)->name); } @@ -5152,7 +5213,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant)); break; default: break; @@ -5161,7 +5222,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_ADD_INTERFACE; SET_NODE(opline->op1, &CG(implementing_class)); - zend_resolve_class_name(interface_name, opline->extended_value, 0 TSRMLS_CC); + zend_resolve_class_name(interface_name TSRMLS_CC); opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE; opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &interface_name->u.constant TSRMLS_CC); @@ -5174,7 +5235,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ zend_op *opline; if ((CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use traits inside of interfaces. %s is used in %s", Z_STRVAL(trait_name->u.constant), CG(active_class_entry)->name); } @@ -5184,7 +5245,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant)); break; default: break; @@ -5193,7 +5254,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_ADD_TRAIT; SET_NODE(opline->op1, &CG(implementing_class)); - zend_resolve_class_name(trait_name, opline->extended_value, 0 TSRMLS_CC); + zend_resolve_class_name(trait_name TSRMLS_CC); opline->extended_value = ZEND_FETCH_CLASS_TRAIT; opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC); @@ -5273,20 +5334,20 @@ void zend_do_declare_property(const znode *var_name, const znode *value, zend_ui int comment_len = 0; if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_COMPILE_ERROR, "Interfaces may not include member variables"); + zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables"); } if (access_type & ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Properties cannot be declared abstract"); + zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract"); } if (access_type & ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes", - CG(active_class_entry)->name, var_name->u.constant.value.str.val); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes", + CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } - if (zend_hash_find(&CG(active_class_entry)->properties_info, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, (void **) &existing_property_info)==SUCCESS) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val); + if (zend_hash_find(&CG(active_class_entry)->properties_info, Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant)+1, (void **) &existing_property_info)==SUCCESS) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } ALLOC_ZVAL(property); @@ -5304,8 +5365,8 @@ void zend_do_declare_property(const znode *var_name, const znode *value, zend_ui CG(doc_comment_len) = 0; } - zend_declare_property_ex(CG(active_class_entry), zend_new_interned_string(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len + 1, 0 TSRMLS_CC), var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC); - efree(var_name->u.constant.value.str.val); + zend_declare_property_ex(CG(active_class_entry), zend_new_interned_string(Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant) + 1, 0 TSRMLS_CC), Z_STRLEN(var_name->u.constant), property, access_type, comment, comment_len TSRMLS_CC); + efree(Z_STRVAL(var_name->u.constant)); } /* }}} */ @@ -5313,30 +5374,25 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D { zval *property; const char *cname = NULL; - int result; + zend_ulong hash; if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); return; } if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Traits cannot have constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; } ALLOC_ZVAL(property); *property = value->u.constant; - cname = zend_new_interned_string(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, 0 TSRMLS_CC); - - if (IS_INTERNED(cname)) { - result = zend_hash_quick_add(&CG(active_class_entry)->constants_table, cname, var_name->u.constant.value.str.len+1, INTERNED_HASH(cname), &property, sizeof(zval *), NULL); - } else { - result = zend_hash_add(&CG(active_class_entry)->constants_table, cname, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); - } - if (result == FAILURE) { + cname = zend_new_interned_string(Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant)+1, 0 TSRMLS_CC); + hash = str_hash(cname, Z_STRLEN(var_name->u.constant)); + if (zend_hash_quick_add(&CG(active_class_entry)->constants_table, cname, Z_STRLEN(var_name->u.constant)+1, hash, &property, sizeof(zval *), NULL) == FAILURE) { FREE_ZVAL(property); - zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } FREE_PNODE(var_name); @@ -5430,7 +5486,7 @@ void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */ int len, clen; if (CG(has_bracketed_namespaces) && CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); + zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } cfilename = zend_get_compiled_filename(TSRMLS_C); @@ -5572,7 +5628,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con if (ZEND_FETCH_CLASS_STATIC == type) { zend_error(E_ERROR, "\"static::\" is not allowed in compile-time constants"); } else if (ZEND_FETCH_CLASS_DEFAULT == type) { - zend_resolve_class_name(constant_container, fetch_type, 1 TSRMLS_CC); + zend_resolve_class_name(constant_container TSRMLS_CC); } zend_do_build_full_name(NULL, constant_container, constant_name, 1 TSRMLS_CC); *result = *constant_container; @@ -5581,7 +5637,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con case ZEND_RT: if (constant_container->op_type == IS_CONST && ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant))) { - zend_resolve_class_name(constant_container, fetch_type, 1 TSRMLS_CC); + zend_resolve_class_name(constant_container TSRMLS_CC); } else { zend_do_fetch_class(&tmp, constant_container TSRMLS_CC); constant_container = &tmp; @@ -5619,7 +5675,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con break; } - zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC); + zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC); if(!compound) { fetch_type |= IS_CONSTANT_UNQUALIFIED; @@ -5631,7 +5687,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con case ZEND_RT: compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant)); - zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC); + zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC); if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) { break; @@ -5781,11 +5837,11 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3); Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant); Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0; - zend_symtable_update(result->u.constant.value.ht, Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL); zval_dtor(&offset->u.constant); break; case IS_STRING: - zend_symtable_update(result->u.constant.value.ht, offset->u.constant.value.str.val, offset->u.constant.value.str.len+1, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+1, &element, sizeof(zval *), NULL); zval_dtor(&offset->u.constant); break; case IS_NULL: @@ -5962,7 +6018,7 @@ void zend_do_fetch_static_variable(znode *varname, const znode *static_assignmen ALLOC_HASHTABLE(CG(active_op_array)->static_variables); zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0); } - zend_hash_update(CG(active_op_array)->static_variables, varname->u.constant.value.str.val, varname->u.constant.value.str.len+1, &tmp, sizeof(zval *), NULL); + zend_hash_update(CG(active_op_array)->static_variables, Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)+1, &tmp, sizeof(zval *), NULL); if (varname->op_type == IS_CONST) { if (Z_TYPE(varname->u.constant) != IS_STRING) { @@ -6006,7 +6062,7 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) if (Z_STRLEN(varname->u.constant) == sizeof("this") - 1 && memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1) == 0) { - zend_error(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); return; } @@ -6091,7 +6147,7 @@ void zend_do_indirect_references(znode *result, const znode *num_references, zno int i; zend_do_end_variable_parse(variable, BP_VAR_R, 0 TSRMLS_CC); - for (i=1; iu.constant.value.lval; i++) { + for (i=1; iu.constant); i++) { fetch_simple_variable_ex(result, variable, 0, ZEND_FETCH_R TSRMLS_CC); *variable = *result; } @@ -6150,7 +6206,7 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC /* empty(func()) can be transformed to !func() */ zend_do_unary_op(ZEND_BOOL_NOT, result, variable TSRMLS_CC); } else { - zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)"); } return; @@ -6198,7 +6254,7 @@ void zend_do_instanceof(znode *result, const znode *expr, const znode *class_zno } if (expr->op_type == IS_CONST) { - zend_error(E_COMPILE_ERROR, "instanceof expects an object instance, constant given"); + zend_error_noreturn(E_COMPILE_ERROR, "instanceof expects an object instance, constant given"); } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -6289,10 +6345,10 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token if ((key->op_type != IS_UNUSED)) { if (key->EA & ZEND_PARSED_REFERENCE_VARIABLE) { - zend_error(E_COMPILE_ERROR, "Key element cannot be a reference"); + zend_error_noreturn(E_COMPILE_ERROR, "Key element cannot be a reference"); } if (key->EA & ZEND_PARSED_LIST_EXPR) { - zend_error(E_COMPILE_ERROR, "Cannot use list as key element"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use list as key element"); } } @@ -6311,7 +6367,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token while (fetch != end) { --fetch; if (fetch->opcode == ZEND_FETCH_DIM_W && fetch->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } if (fetch->opcode == ZEND_SEPARATE) { MAKE_NOP(fetch); @@ -6325,7 +6381,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token if (value->EA & ZEND_PARSED_LIST_EXPR) { if (!CG(list_llist).head) { - zend_error(E_COMPILE_ERROR, "Cannot use empty list"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list"); } zend_do_list_end(&dummy, &value_node TSRMLS_CC); zend_do_free(&dummy TSRMLS_CC); @@ -6388,12 +6444,12 @@ void zend_do_declare_begin(TSRMLS_D) /* {{{ */ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ { - if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "ticks", sizeof("ticks")-1)) { + if (!zend_binary_strcasecmp(Z_STRVAL(var->u.constant), Z_STRLEN(var->u.constant), "ticks", sizeof("ticks")-1)) { convert_to_long(&val->u.constant); CG(declarables).ticks = val->u.constant; - } else if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "encoding", sizeof("encoding")-1)) { + } else if (!zend_binary_strcasecmp(Z_STRVAL(var->u.constant), Z_STRLEN(var->u.constant), "encoding", sizeof("encoding")-1)) { if ((Z_TYPE(val->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { - zend_error(E_COMPILE_ERROR, "Cannot use constants as encoding"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use constants as encoding"); } /* @@ -6412,7 +6468,7 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ } if (num > 0) { - zend_error(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script"); + zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script"); } } @@ -6423,9 +6479,9 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ CG(encoding_declared) = 1; convert_to_string(&val->u.constant); - new_encoding = zend_multibyte_fetch_encoding(val->u.constant.value.str.val TSRMLS_CC); + new_encoding = zend_multibyte_fetch_encoding(Z_STRVAL(val->u.constant) TSRMLS_CC); if (!new_encoding) { - zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", val->u.constant.value.str.val); + zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", Z_STRVAL(val->u.constant)); } else { old_input_filter = LANG_SCNG(input_filter); old_encoding = LANG_SCNG(script_encoding); @@ -6442,7 +6498,7 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ } zval_dtor(&val->u.constant); } else { - zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", var->u.constant.value.str.val); + zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", Z_STRVAL(var->u.constant)); zval_dtor(&val->u.constant); } zval_dtor(&var->u.constant); @@ -6682,10 +6738,9 @@ void zend_do_ticks(TSRMLS_D) /* {{{ */ } /* }}} */ -zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC) /* {{{ */ +zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hash TSRMLS_DC) /* {{{ */ { zend_auto_global *auto_global; - ulong hash = hashval ? hashval : zend_hash_func(name, name_len+1); if (zend_hash_quick_find(CG(auto_globals), name, name_len+1, hash, (void **) &auto_global)==SUCCESS) { if (auto_global->armed) { @@ -6699,7 +6754,7 @@ zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashv zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) /* {{{ */ { - return zend_is_auto_global_quick(name, name_len, 0 TSRMLS_CC); + return zend_is_auto_global_quick(name, name_len, zend_hash_func(name, name_len+1) TSRMLS_CC); } /* }}} */ @@ -6909,15 +6964,15 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC if (CG(current_namespace)) { /* previous namespace declarations were unbracketed */ if (with_bracket) { - zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); } } } else { /* previous namespace declarations were bracketed */ if (!with_bracket) { - zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); } else if (CG(current_namespace) || CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "Namespace declarations cannot be nested"); + zend_error_noreturn(E_COMPILE_ERROR, "Namespace declarations cannot be nested"); } } @@ -6930,7 +6985,7 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC --num; } if (num > 0) { - zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); + zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); } } @@ -6945,7 +7000,7 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC !memcmp(lcname, "self", sizeof("self")-1)) || ((Z_STRLEN(name->u.constant) == sizeof("parent")-1) && !memcmp(lcname, "parent", sizeof("parent")-1))) { - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant)); } efree(lcname); @@ -6969,6 +7024,18 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC CG(current_import) = NULL; } + if (CG(current_import_function)) { + zend_hash_destroy(CG(current_import_function)); + efree(CG(current_import_function)); + CG(current_import_function) = NULL; + } + + if (CG(current_import_const)) { + zend_hash_destroy(CG(current_import_const)); + efree(CG(current_import_const)); + CG(current_import_const) = NULL; + } + if (CG(doc_comment)) { efree(CG(doc_comment)); CG(doc_comment) = NULL; @@ -7015,7 +7082,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ !memcmp(lcname, "self", sizeof("self")-1)) || ((Z_STRLEN_P(name) == sizeof("parent")-1) && !memcmp(lcname, "parent", sizeof("parent")-1))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); } if (CG(current_namespace)) { @@ -7030,7 +7097,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } efree(tmp2); } @@ -7042,17 +7109,17 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } efree(c_tmp); } if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } if (warn) { if (!strcmp(Z_STRVAL_P(name), "strict")) { - zend_error(E_COMPILE_ERROR, "You seem to be trying to use a different language..."); + zend_error_noreturn(E_COMPILE_ERROR, "You seem to be trying to use a different language..."); } zend_error(E_WARNING, "The use statement with non-compound name '%s' has no effect", Z_STRVAL_P(name)); } @@ -7061,16 +7128,110 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ } /* }}} */ +void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, const char *type, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC) /* {{{ */ +{ + char *lookup_name; + char *filename; + zval *name, *ns, tmp; + zend_bool warn = 0; + + ALLOC_ZVAL(ns); + *ns = ns_name->u.constant; + if (new_name) { + name = &new_name->u.constant; + } else { + const char *p; + + /* The form "use A\B" is eqivalent to "use A\B as B". + So we extract the last part of compound name to use as a new_name */ + name = &tmp; + p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns)); + if (p) { + ZVAL_STRING(name, p+1, 1); + } else { + *name = *ns; + zval_copy_ctor(name); + warn = !is_global && !CG(current_namespace); + } + } + + if (case_sensitive) { + lookup_name = estrndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + } else { + lookup_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + } + + if (CG(current_namespace)) { + /* Prefix import name with current namespace name to avoid conflicts with functions/consts */ + char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1); + + zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); + c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\'; + memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lookup_name, Z_STRLEN_P(name)+1); + if (zend_hash_exists(lookup_table, c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) { + char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + + if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || + memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) { + zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", type, Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + efree(tmp2); + } + efree(c_ns_name); + } else if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **)&filename) == SUCCESS && strcmp(filename, CG(compiled_filename)) == 0) { + char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + + if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || + memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) { + zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", type, Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + efree(c_tmp); + } + + if (zend_hash_add(current_import_sub, lookup_name, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { + zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", type, Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + if (warn) { + zend_error(E_WARNING, "The use %s statement with non-compound name '%s' has no effect", type, Z_STRVAL_P(name)); + } + efree(lookup_name); + zval_dtor(name); +} +/* }}} */ + +void zend_do_use_function(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */ +{ + if (!CG(current_import_function)) { + CG(current_import_function) = emalloc(sizeof(HashTable)); + zend_hash_init(CG(current_import_function), 0, NULL, ZVAL_PTR_DTOR, 0); + } + + zend_do_use_non_class(ns_name, new_name, is_global, "function", 0, CG(current_import_function), &CG(function_filenames) TSRMLS_CC); +} +/* }}} */ + +void zend_do_use_const(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */ +{ + if (!CG(current_import_const)) { + CG(current_import_const) = emalloc(sizeof(HashTable)); + zend_hash_init(CG(current_import_const), 0, NULL, ZVAL_PTR_DTOR, 0); + } + + zend_do_use_non_class(ns_name, new_name, is_global, "const", 1, CG(current_import_const), &CG(const_filenames) TSRMLS_CC); +} +/* }}} */ + void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ { zend_op *opline; + zval **ns_name; if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Arrays are not allowed as constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants"); } if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); } if (CG(current_namespace)) { @@ -7084,18 +7245,33 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ *name = tmp; } + /* Constant name must not conflict with import names */ + if (CG(current_import_const) && + zend_hash_find(CG(current_import_const), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, (void**)&ns_name) == SUCCESS) { + + char *tmp = estrndup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name)); + + if (Z_STRLEN_PP(ns_name) != Z_STRLEN(name->u.constant) || + memcmp(tmp, Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant))) { + zend_error(E_COMPILE_ERROR, "Cannot declare const %s because the name is already in use", Z_STRVAL(name->u.constant)); + } + efree(tmp); + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_DECLARE_CONST; SET_UNUSED(opline->result); SET_NODE(opline->op1, name); SET_NODE(opline->op2, value); + + zend_hash_add(&CG(const_filenames), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, CG(compiled_filename), strlen(CG(compiled_filename))+1, NULL); } /* }}} */ void zend_verify_namespace(TSRMLS_D) /* {{{ */ { if (CG(has_bracketed_namespaces) && !CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "No code may exist outside of namespace {}"); + zend_error_noreturn(E_COMPILE_ERROR, "No code may exist outside of namespace {}"); } } /* }}} */ @@ -7113,6 +7289,16 @@ void zend_do_end_namespace(TSRMLS_D) /* {{{ */ efree(CG(current_import)); CG(current_import) = NULL; } + if (CG(current_import_function)) { + zend_hash_destroy(CG(current_import_function)); + efree(CG(current_import_function)); + CG(current_import_function) = NULL; + } + if (CG(current_import_const)) { + zend_hash_destroy(CG(current_import_const)); + efree(CG(current_import_const)); + CG(current_import_const) = NULL; + } } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 9c55b5ebe8812..d4ebdffcd2f2c 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -74,7 +74,7 @@ typedef struct _zend_literal { #define Z_HASH_P(zv) \ (((zend_literal*)(zv))->hash_value) -typedef union _znode_op { +typedef union _znode_op { zend_uint constant; zend_uint var; zend_uint num; @@ -86,7 +86,7 @@ typedef union _znode_op { void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */ } znode_op; -typedef struct _znode { /* used only during compilation */ +typedef struct _znode { /* used only during compilation */ int op_type; union { znode_op op; @@ -207,8 +207,7 @@ typedef struct _zend_try_catch_element { /* disable inline caching */ #define ZEND_ACC_NEVER_CACHE 0x400000 -#define ZEND_ACC_PASS_REST_BY_REFERENCE 0x1000000 -#define ZEND_ACC_PASS_REST_PREFER_REF 0x2000000 +#define ZEND_ACC_VARIADIC 0x1000000 #define ZEND_ACC_RETURN_REFERENCE 0x4000000 #define ZEND_ACC_DONE_PASS_TWO 0x8000000 @@ -234,12 +233,13 @@ typedef struct _zend_arg_info { const char *class_name; zend_uint class_name_len; zend_uchar type_hint; + zend_uchar pass_by_reference; zend_bool allow_null; - zend_bool pass_by_reference; + zend_bool is_variadic; } zend_arg_info; /* the following structure repeats the layout of zend_arg_info, - * but its fields have different meaning. It's used as the first element of + * but its fields have different meaning. It's used as the first element of * arg_info array to define properties of internal functions. */ typedef struct _zend_internal_function_info { @@ -249,7 +249,8 @@ typedef struct _zend_internal_function_info { zend_uint required_num_args; zend_uchar _type_hint; zend_bool return_reference; - zend_bool pass_rest_by_reference; + zend_bool _allow_null; + zend_bool _is_variadic; } zend_internal_function_info; typedef struct _zend_compiled_variable { @@ -261,7 +262,7 @@ typedef struct _zend_compiled_variable { struct _zend_op_array { /* Common elements */ zend_uchar type; - const char *function_name; + const char *function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; @@ -437,8 +438,10 @@ ZEND_API char *zend_get_compiled_filename(TSRMLS_D); ZEND_API int zend_get_compiled_lineno(TSRMLS_D); ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D); -void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC); -void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_name TSRMLS_DC); +void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC); +void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC); +void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC); +void zend_resolve_class_name(znode *class_name TSRMLS_DC); ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len); #ifdef ZTS @@ -500,7 +503,7 @@ void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRM int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier); void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC); void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC); -void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_bool pass_by_reference TSRMLS_DC); +void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC); int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC); void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC); void zend_do_clone(znode *result, const znode *expr TSRMLS_DC); @@ -636,6 +639,9 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_brackets TSRMLS_D void zend_do_end_namespace(TSRMLS_D); void zend_verify_namespace(TSRMLS_D); void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC); +void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, const char *type, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC); +void zend_do_use_function(znode *name, znode *new_name, int is_global TSRMLS_DC); +void zend_do_use_const(znode *name, znode *new_name, int is_global TSRMLS_DC); void zend_do_end_compilation(TSRMLS_D); void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC); @@ -674,7 +680,7 @@ void zend_class_add_ref(zend_class_entry **ce); ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal); #define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \ - zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL) + zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL) ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len); #define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor @@ -726,8 +732,8 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); #define ZEND_FETCH_CLASS_DEFAULT 0 #define ZEND_FETCH_CLASS_SELF 1 #define ZEND_FETCH_CLASS_PARENT 2 -#define ZEND_FETCH_CLASS_MAIN 3 -#define ZEND_FETCH_CLASS_GLOBAL 4 +#define ZEND_FETCH_CLASS_MAIN 3 /* unused */ +#define ZEND_FETCH_CLASS_GLOBAL 4 /* unused */ #define ZEND_FETCH_CLASS_AUTO 5 #define ZEND_FETCH_CLASS_INTERFACE 6 #define ZEND_FETCH_CLASS_STATIC 7 @@ -817,21 +823,21 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); #define ZEND_SEND_BY_REF 1 #define ZEND_SEND_PREFER_REF 2 -#define CHECK_ARG_SEND_TYPE(zf, arg_num, m1, m2) \ - ((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 & (m1)) : \ - (((zend_function *)(zf))->common.fn_flags & (m2)))) +#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \ + ((zf)->common.arg_info && \ + (arg_num <= (zf)->common.num_args \ + ? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \ + : ((zf)->common.fn_flags & ZEND_ACC_VARIADIC) \ + ? ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m)) : 0)) #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF, ZEND_ACC_PASS_REST_BY_REFERENCE) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF) #define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_BY_REFERENCE|ZEND_ACC_PASS_REST_PREFER_REF) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF) #define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_PREFER_REF) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF) #define ZEND_RETURN_VAL 0 #define ZEND_RETURN_REF 1 diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 21580d3d5f607..a53af497cc8d4 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -25,7 +25,7 @@ #include "zend_variables.h" #include "zend_operators.h" #include "zend_globals.h" - +#include "zend_API.h" void free_zend_constant(zend_constant *c) { @@ -38,9 +38,7 @@ void free_zend_constant(zend_constant *c) void copy_zend_constant(zend_constant *c) { - if (!IS_INTERNED(c->name)) { - c->name = zend_strndup(c->name, c->name_len - 1); - } + c->name = str_strndup(c->name, c->name_len - 1); if (!(c->flags & CONST_PERSISTENT)) { zval_copy_ctor(&c->value); } @@ -119,42 +117,12 @@ void zend_register_standard_constants(TSRMLS_D) REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS); /* true/false constants */ { - zend_constant c; - - c.flags = CONST_PERSISTENT | CONST_CT_SUBST; - c.module_number = 0; - - c.name = zend_strndup(ZEND_STRL("TRUE")); - c.name_len = sizeof("TRUE"); - c.value.value.lval = 1; - c.value.type = IS_BOOL; - zend_register_constant(&c TSRMLS_CC); - - c.name = zend_strndup(ZEND_STRL("FALSE")); - c.name_len = sizeof("FALSE"); - c.value.value.lval = 0; - c.value.type = IS_BOOL; - zend_register_constant(&c TSRMLS_CC); - - c.name = zend_strndup(ZEND_STRL("NULL")); - c.name_len = sizeof("NULL"); - c.value.type = IS_NULL; - zend_register_constant(&c TSRMLS_CC); - - c.flags = CONST_PERSISTENT | CONST_CS; - - c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE")); - c.name_len = sizeof("ZEND_THREAD_SAFE"); - c.value.value.lval = ZTS_V; - c.value.type = IS_BOOL; - zend_register_constant(&c TSRMLS_CC); - - c.name = zend_strndup(ZEND_STRL("ZEND_DEBUG_BUILD")); - c.name_len = sizeof("ZEND_DEBUG_BUILD"); - c.value.value.lval = ZEND_DEBUG; - c.value.type = IS_BOOL; - zend_register_constant(&c TSRMLS_CC); + REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST); + REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS); } + REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST); } @@ -175,13 +143,35 @@ void clean_non_persistent_constants(TSRMLS_D) } } +ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC) +{ + zend_constant c; + + ZVAL_NULL(&c.value); + c.flags = flags; + c.name = zend_strndup(name, name_len-1); + c.name_len = name_len; + c.module_number = module_number; + zend_register_constant(&c TSRMLS_CC); +} + +ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC) +{ + zend_constant c; + + ZVAL_BOOL(&c.value, bval); + c.flags = flags; + c.name = zend_strndup(name, name_len-1); + c.name_len = name_len; + c.module_number = module_number; + zend_register_constant(&c TSRMLS_CC); +} ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC) { zend_constant c; - c.value.type = IS_LONG; - c.value.value.lval = lval; + ZVAL_LONG(&c.value, lval); c.flags = flags; c.name = zend_strndup(name, name_len-1); c.name_len = name_len; @@ -194,8 +184,7 @@ ZEND_API void zend_register_double_constant(const char *name, uint name_len, dou { zend_constant c; - c.value.type = IS_DOUBLE; - c.value.value.dval = dval; + ZVAL_DOUBLE(&c.value, dval); c.flags = flags; c.name = zend_strndup(name, name_len-1); c.name_len = name_len; @@ -208,9 +197,7 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch { zend_constant c; - c.value.type = IS_STRING; - c.value.value.str.val = strval; - c.value.value.str.len = strlen; + ZVAL_STRINGL(&c.value, strval, strlen, 0); c.flags = flags; c.name = zend_strndup(name, name_len-1); c.name_len = name_len; @@ -485,7 +472,7 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) char *lowercase_name = NULL; char *name; int ret = SUCCESS; - ulong chash = 0; + ulong chash; #if 0 printf("Registering constant for module %d\n", c->module_number); @@ -497,23 +484,18 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) zend_str_tolower(lowercase_name, c->name_len-1); lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC); name = lowercase_name; - chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0; } else { char *slash = strrchr(c->name, '\\'); - if(slash) { + if (slash) { lowercase_name = estrndup(c->name, c->name_len-1); zend_str_tolower(lowercase_name, slash-c->name); lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC); name = lowercase_name; - - chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0; } else { name = c->name; } } - if (chash == 0) { - chash = zend_hash_func(name, c->name_len); - } + chash = str_hash(name, c->name_len-1); /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */ if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__") @@ -532,8 +514,8 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) } ret = FAILURE; } - if (lowercase_name && !IS_INTERNED(lowercase_name)) { - efree(lowercase_name); + if (lowercase_name) { + str_efree(lowercase_name); } return ret; } diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index c7261946c826f..718c173cc7b96 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -38,16 +38,22 @@ typedef struct _zend_constant { int module_number; } zend_constant; +#define REGISTER_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), module_number TSRMLS_CC) +#define REGISTER_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), module_number TSRMLS_CC) #define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), module_number TSRMLS_CC) #define REGISTER_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), module_number TSRMLS_CC) #define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC) #define REGISTER_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_NULL_CONSTANT(ns, name, flags) zend_register_null_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_BOOL_CONSTANT(ns, name, bval, flags) zend_register_bool_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (bval), (flags), module_number TSRMLS_CC) #define REGISTER_NS_LONG_CONSTANT(ns, name, lval, flags) zend_register_long_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (lval), (flags), module_number TSRMLS_CC) #define REGISTER_NS_DOUBLE_CONSTANT(ns, name, dval, flags) zend_register_double_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (dval), (flags), module_number TSRMLS_CC) #define REGISTER_NS_STRING_CONSTANT(ns, name, str, flags) zend_register_string_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (flags), module_number TSRMLS_CC) #define REGISTER_NS_STRINGL_CONSTANT(ns, name, str, len, flags) zend_register_stringl_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (len), (flags), module_number TSRMLS_CC) +#define REGISTER_MAIN_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), 0 TSRMLS_CC) +#define REGISTER_MAIN_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), 0 TSRMLS_CC) #define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), 0 TSRMLS_CC) #define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), 0 TSRMLS_CC) #define REGISTER_MAIN_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), 0 TSRMLS_CC) @@ -62,6 +68,8 @@ void zend_register_standard_constants(TSRMLS_D); void clean_non_persistent_constants(TSRMLS_D); ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC); ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC); +ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC); +ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC); ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC); ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC); ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a65f5331de43f..77e67e6cbbfc9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -40,7 +40,7 @@ #include "zend_dtrace.h" /* Virtual current working directory support */ -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #define _CONST_CODE 0 #define _TMP_CODE 1 @@ -79,7 +79,6 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) { Z_UNSET_ISREF_P(z); } - GC_ZVAL_CHECK_POSSIBLE_ROOT(z); } } @@ -94,7 +93,8 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC) } #undef zval_ptr_dtor -#define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC) +#define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC) +#define zval_ptr_dtor_nogc(pzv) i_zval_ptr_dtor_nogc(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC) #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC) #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC) @@ -125,18 +125,18 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC) if ((zend_uintptr_t)should_free.var & 1L) { \ zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \ } else { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } \ } #define FREE_OP_IF_VAR(should_free) \ if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } #define FREE_OP_VAR_PTR(should_free) \ if (should_free.var) { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } #define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L) @@ -183,8 +183,7 @@ static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const zend_exec { zval *ptr = EX_T(var).var.ptr; - PZVAL_UNLOCK(ptr, should_free); - return ptr; + return should_free->var = ptr; } static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC) @@ -386,6 +385,19 @@ static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const zend return ptr_ptr; } +static zend_always_inline zval **_get_zval_ptr_ptr_var_fast(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC) +{ + zval** ptr_ptr = EX_T(var).var.ptr_ptr; + + if (EXPECTED(ptr_ptr != NULL)) { + should_free->var = *ptr_ptr; + } else { + /* string offset */ + should_free->var = EX_T(var).str_offset.str; + } + return ptr_ptr; +} + static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC) { zval ***ptr = EX_CV_NUM(EG(current_execute_data), var); @@ -604,12 +616,17 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva char *need_msg; zend_class_entry *ce; - if (!zf->common.arg_info - || arg_num>zf->common.num_args) { + if (!zf->common.arg_info) { return 1; } - cur_arg_info = &zf->common.arg_info[arg_num-1]; + if (arg_num <= zf->common.num_args) { + cur_arg_info = &zf->common.arg_info[arg_num-1]; + } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) { + cur_arg_info = &zf->common.arg_info[zf->common.num_args-1]; + } else { + return 1; + } if (cur_arg_info->class_name) { const char *class_name; @@ -755,32 +772,21 @@ static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC) { - if (Z_TYPE_P(T->str_offset.str) == IS_STRING) { - - if (((int)T->str_offset.offset < 0)) { - zend_error(E_WARNING, "Illegal string offset: %d", T->str_offset.offset); + zval *str = T->str_offset.str; + zend_uint offset = T->str_offset.offset; + if (Z_TYPE_P(str) == IS_STRING) { + if ((int)offset < 0) { + zend_error(E_WARNING, "Illegal string offset: %d", offset); return 0; } - if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) { - if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) { - char *tmp = (char *) emalloc(T->str_offset.offset+1+1); - - memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str)+1); - Z_STRVAL_P(T->str_offset.str) = tmp; - } else { - Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1); - } - memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str), - ' ', - T->str_offset.offset - Z_STRLEN_P(T->str_offset.str)); - Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0; - Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1; - } else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) { - char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1); - - memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1); - Z_STRVAL_P(T->str_offset.str) = tmp; + if (offset >= Z_STRLEN_P(str)) { + Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), offset+1+1); + memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), ' ', offset - Z_STRLEN_P(str)); + Z_STRVAL_P(str)[offset+1] = 0; + Z_STRLEN_P(str) = offset+1; + } else if (IS_INTERNED(Z_STRVAL_P(str))) { + Z_STRVAL_P(str) = estrndup(Z_STRVAL_P(str), Z_STRLEN_P(str)); } if (Z_TYPE_P(value) != IS_STRING) { @@ -791,15 +797,15 @@ static inline int zend_assign_to_string_offset(const temp_variable *T, const zva zval_copy_ctor(&tmp); } convert_to_string(&tmp); - Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0]; - STR_FREE(Z_STRVAL(tmp)); + Z_STRVAL_P(str)[offset] = Z_STRVAL(tmp)[0]; + str_efree(Z_STRVAL(tmp)); } else { - Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0]; + Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0]; if (value_type == IS_TMP_VAR) { /* we can safely free final_value here * because separation is done only * in case value_type == IS_VAR */ - STR_FREE(Z_STRVAL_P(value)); + str_efree(Z_STRVAL_P(value)); } } /* @@ -909,7 +915,7 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value } else { /* we need to split */ Z_DELREF_P(variable_ptr); GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); - if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) { + if (PZVAL_IS_REF(value)) { ALLOC_ZVAL(variable_ptr); *variable_ptr_ptr = variable_ptr; INIT_PZVAL_COPY(variable_ptr, value); @@ -918,7 +924,6 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value } else { *variable_ptr_ptr = value; Z_ADDREF_P(value); - Z_UNSET_ISREF_P(value); return value; } } @@ -1013,11 +1018,7 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zva hval = Z_HASH_P(dim); } else { ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index); - if (IS_INTERNED(offset_key)) { - hval = INTERNED_HASH(offset_key); - } else { - hval = zend_hash_func(offset_key, offset_key_length+1); - } + hval = str_hash(offset_key, offset_key_length); } fetch_string_dim: if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) { @@ -1476,15 +1477,17 @@ ZEND_API opcode_handler_t *zend_opcode_handlers; ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) { - if(fci != NULL) { - ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(fci->param_count, - *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); - + if (fci != NULL) { + execute_data_ptr->function_state.function->internal_function.handler( + fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, + fci->object_ptr, 1 TSRMLS_CC + ); } else { zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr; - ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, - (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, - execute_data_ptr->object, return_value_used TSRMLS_CC); + execute_data_ptr->function_state.function->internal_function.handler( + execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr, + execute_data_ptr->object, return_value_used TSRMLS_CC + ); } } @@ -1502,7 +1505,7 @@ void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC) /* {{{ } /* }}} */ -static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ +static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { zval ***cv = EX_CV_NUM(execute_data, 0); zval ***end = cv + EX(op_array)->last_var; @@ -1515,9 +1518,9 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec } /* }}} */ -void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ +void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { - i_free_compiled_variables(execute_data); + i_free_compiled_variables(execute_data TSRMLS_CC); } /* }}} */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index ff0758772e48b..5c900e5ceced5 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -71,18 +71,14 @@ ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC); ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC); -static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) +static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC) { if (!Z_DELREF_P(zval_ptr)) { - TSRMLS_FETCH(); - ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval)); GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr); zval_dtor(zval_ptr); efree_rel(zval_ptr); } else { - TSRMLS_FETCH(); - if (Z_REFCOUNT_P(zval_ptr) == 1) { Z_UNSET_ISREF_P(zval_ptr); } @@ -91,6 +87,20 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) } } +static zend_always_inline void i_zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC) +{ + if (!Z_DELREF_P(zval_ptr)) { + ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval)); + GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr); + zval_dtor(zval_ptr); + efree_rel(zval_ptr); + } else { + if (Z_REFCOUNT_P(zval_ptr) == 1) { + Z_UNSET_ISREF_P(zval_ptr); + } + } +} + static zend_always_inline int i_zend_is_true(zval *op) { int result; @@ -295,7 +305,7 @@ static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC while (p != end) { zval *q = (zval *) *(--p); *p = NULL; - i_zval_ptr_dtor(q ZEND_FILE_LINE_CC); + i_zval_ptr_dtor(q ZEND_FILE_LINE_CC TSRMLS_CC); } if (nested) { EG(argument_stack)->top = p; @@ -394,7 +404,7 @@ ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const z ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS); void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC); -void zend_free_compiled_variables(zend_execute_data *execute_data); +void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC); #define CACHED_PTR(num) \ EG(active_op_array)->run_time_cache[(num)] diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 83c221798416f..779e6d886fa4d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -423,7 +423,8 @@ ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */ ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { - i_zval_ptr_dtor(*zval_ptr ZEND_FILE_LINE_RELAY_CC); + TSRMLS_FETCH(); + i_zval_ptr_dtor(*zval_ptr ZEND_FILE_LINE_RELAY_CC TSRMLS_CC); } /* }}} */ @@ -533,13 +534,13 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco if (fix_save) { save--; } - if (inline_change && !IS_INTERNED(save)) { - efree(save); + if (inline_change) { + str_efree(save); } save = NULL; } - if (inline_change && save && save != actual && !IS_INTERNED(save)) { - efree(save); + if (inline_change && save && save != actual) { + str_efree(save); } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); p->type = IS_STRING; @@ -551,7 +552,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } } else { if (inline_change) { - STR_FREE(Z_STRVAL_P(p)); + str_efree(Z_STRVAL_P(p)); } *p = const_value; } @@ -952,9 +953,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } - if(EXPECTED(zend_execute_internal == NULL)) { + if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ - ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + EX(function_state).function->internal_function.handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); } else { zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC); } diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 83cad7f38d648..e7f289a656097 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -28,7 +28,7 @@ /* The first number is the engine version and the rest is the date. * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 220121212 +#define ZEND_EXTENSION_API_NO 220131106 typedef struct _zend_extension_version_info { int zend_extension_api_no; diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 0af20f4593fcb..e8b1be4445e2e 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -46,7 +46,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished zend_op_array *op_array = execute_data->op_array; if (!execute_data->symbol_table) { - zend_free_compiled_variables(execute_data); + zend_free_compiled_variables(execute_data TSRMLS_CC); } else { zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC); } @@ -456,7 +456,7 @@ ZEND_METHOD(Generator, current) zend_generator_ensure_initialized(generator TSRMLS_CC); if (generator->value) { - RETURN_ZVAL(generator->value, 1, 0); + RETURN_ZVAL_FAST(generator->value); } } /* }}} */ @@ -476,7 +476,7 @@ ZEND_METHOD(Generator, key) zend_generator_ensure_initialized(generator TSRMLS_CC); if (generator->key) { - RETURN_ZVAL(generator->key, 1, 0); + RETURN_ZVAL_FAST(generator->key); } } /* }}} */ @@ -525,7 +525,7 @@ ZEND_METHOD(Generator, send) zend_generator_resume(generator TSRMLS_CC); if (generator->value) { - RETURN_ZVAL(generator->value, 1, 0); + RETURN_ZVAL_FAST(generator->value); } } /* }}} */ @@ -558,7 +558,7 @@ ZEND_METHOD(Generator, throw) zend_generator_resume(generator TSRMLS_CC); if (generator->value) { - RETURN_ZVAL(generator->value, 1, 0); + RETURN_ZVAL_FAST(generator->value); } } else { /* If the generator is already closed throw the exception in the diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index b9a5b39914a6c..19c29c68f324e 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -131,9 +131,14 @@ struct _zend_compiler_globals { zval *current_namespace; HashTable *current_import; + HashTable *current_import_function; + HashTable *current_import_const; zend_bool in_namespace; zend_bool has_bracketed_namespaces; + HashTable function_filenames; + HashTable const_filenames; + zend_compiler_context context; zend_stack context_stack; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 96c3f3d7b57d3..ae7d8402f4bdd 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -96,7 +96,7 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin zend_hash_do_resize(ht); \ } -static int zend_hash_do_resize(HashTable *ht); +static void zend_hash_do_resize(HashTable *ht); ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength) { @@ -128,10 +128,6 @@ ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength) (p)->pData = &(p)->pDataPtr; \ } else { \ (p)->pData = (void *) pemalloc_rel(nDataSize, (ht)->persistent);\ - if (!(p)->pData) { \ - pefree_rel(p, (ht)->persistent); \ - return FAILURE; \ - } \ memcpy((p)->pData, pData, nDataSize); \ (p)->pDataPtr=NULL; \ } @@ -245,15 +241,9 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe if (IS_INTERNED(arKey)) { p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); - if (!p) { - return FAILURE; - } p->arKey = arKey; } else { p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); - if (!p) { - return FAILURE; - } p->arKey = (const char*)(p + 1); memcpy((char*)p->arKey, arKey, nKeyLength); } @@ -322,15 +312,9 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui if (IS_INTERNED(arKey)) { p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent); - if (!p) { - return FAILURE; - } p->arKey = arKey; } else { p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent); - if (!p) { - return FAILURE; - } p->arKey = (const char*)(p + 1); memcpy((char*)p->arKey, arKey, nKeyLength); } @@ -410,9 +394,6 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void p = p->pNext; } p = (Bucket *) pemalloc_rel(sizeof(Bucket), ht->persistent); - if (!p) { - return FAILURE; - } p->arKey = NULL; p->nKeyLength = 0; /* Numeric indices are marked by making the nKeyLength == 0 */ p->h = h; @@ -437,7 +418,7 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void } -static int zend_hash_do_resize(HashTable *ht) +static void zend_hash_do_resize(HashTable *ht) { Bucket **t; #ifdef ZEND_SIGNALS @@ -447,19 +428,14 @@ static int zend_hash_do_resize(HashTable *ht) IS_CONSISTENT(ht); if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */ - t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); - if (t) { - HANDLE_BLOCK_INTERRUPTIONS(); - ht->arBuckets = t; - ht->nTableSize = (ht->nTableSize << 1); - ht->nTableMask = ht->nTableSize - 1; - zend_hash_rehash(ht); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return SUCCESS; - } - return FAILURE; + t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent); + HANDLE_BLOCK_INTERRUPTIONS(); + ht->arBuckets = t; + ht->nTableSize = (ht->nTableSize << 1); + ht->nTableMask = ht->nTableSize - 1; + zend_hash_rehash(ht); + HANDLE_UNBLOCK_INTERRUPTIONS(); } - return SUCCESS; } ZEND_API int zend_hash_rehash(HashTable *ht) @@ -1449,9 +1425,6 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, return SUCCESS; } arTmp = (Bucket **) pemalloc(ht->nNumOfElements * sizeof(Bucket *), ht->persistent); - if (!arTmp) { - return FAILURE; - } p = ht->pListHead; i = 0; while (p) { diff --git a/Zend/zend_ini_scanner.c b/Zend/zend_ini_scanner.c index 87ba664312712..a3ecdef4949ac 100644 --- a/Zend/zend_ini_scanner.c +++ b/Zend/zend_ini_scanner.c @@ -1,4663 +1,4663 @@ -/* Generated by re2c 0.13.5 */ -#line 1 "Zend/zend_ini_scanner.l" -/* - +----------------------------------------------------------------------+ - | Zend Engine | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Zeev Suraski | - | Jani Taskinen | - | Marcus Boerger | - | Nuno Lopes | - | Scott MacVicar | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#include -#include "zend.h" -#include "zend_globals.h" -#include -#include "zend_ini_scanner.h" - -#if 0 -# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) -#else -# define YYDEBUG(s, c) -#endif - -#include "zend_ini_scanner_defs.h" - -#define YYCTYPE unsigned char -/* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD) - * so that if will be able to terminate to match the current token (e.g. non-enclosed string) */ -#define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; } -#define YYCURSOR SCNG(yy_cursor) -#define YYLIMIT SCNG(yy_limit) -#define YYMARKER SCNG(yy_marker) - -#define YYGETCONDITION() SCNG(yy_state) -#define YYSETCONDITION(s) SCNG(yy_state) = s - -#define STATE(name) yyc##name - -/* emulate flex constructs */ -#define BEGIN(state) YYSETCONDITION(STATE(state)) -#define YYSTATE YYGETCONDITION() -#define yytext ((char*)SCNG(yy_text)) -#define yyleng SCNG(yy_leng) -#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ - yyleng = (unsigned int)x; } while(0) - -/* #define yymore() goto yymore_restart */ - -/* perform sanity check. If this message is triggered you should - increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */ -#define YYMAXFILL 6 -#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1) -# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL -#endif - - -/* How it works (for the core ini directives): - * =========================================== - * - * 1. Scanner scans file for tokens and passes them to parser. - * 2. Parser parses the tokens and passes the name/value pairs to the callback - * function which stores them in the configuration hash table. - * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual - * registering of ini entries and uses zend_get_configuration_directive() - * to fetch the previously stored name/value pair from configuration hash table - * and registers the static ini entries which match the name to the value - * into EG(ini_directives) hash table. - * 4. PATH section entries are used per-request from down to top, each overriding - * previous if one exists. zend_alter_ini_entry() is called for each entry. - * Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the - * php_admin_* directives used within Apache httpd.conf when PHP is compiled as - * module for Apache. - * 5. User defined ini files (like .htaccess for apache) are parsed for each request and - * stored in separate hash defined by SAPI. - */ - -/* TODO: (ordered by importance :-) - * =============================================================================== - * - * - Separate constant lookup totally from plain strings (using CONSTANT pattern) - * - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators - * - Add #include "some.ini" - * - Allow variables to refer to options also when using parse_ini_file() - * - */ - -/* Globals Macros */ -#define SCNG INI_SCNG -#ifdef ZTS -ZEND_API ts_rsrc_id ini_scanner_globals_id; -#else -ZEND_API zend_ini_scanner_globals ini_scanner_globals; -#endif - -/* Eat leading whitespace */ -#define EAT_LEADING_WHITESPACE() \ - while (yytext[0]) { \ - if (yytext[0] == ' ' || yytext[0] == '\t') { \ - SCNG(yy_text)++; \ - yyleng--; \ - } else { \ - break; \ - } \ - } - -/* Eat trailing whitespace + extra char */ -#define EAT_TRAILING_WHITESPACE_EX(ch) \ - while (yyleng > 0 && ( \ - (ch != 'X' && yytext[yyleng - 1] == ch) || \ - yytext[yyleng - 1] == '\n' || \ - yytext[yyleng - 1] == '\r' || \ - yytext[yyleng - 1] == '\t' || \ - yytext[yyleng - 1] == ' ') \ - ) { \ - yyleng--; \ - } - -/* Eat trailing whitespace */ -#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') - -#define zend_ini_copy_value(retval, str, len) { \ - Z_STRVAL_P(retval) = zend_strndup(str, len); \ - Z_STRLEN_P(retval) = len; \ - Z_TYPE_P(retval) = IS_STRING; \ -} - -#define RETURN_TOKEN(type, str, len) { \ - zend_ini_copy_value(ini_lval, str, len); \ - return type; \ -} - -static void _yy_push_state(int new_state TSRMLS_DC) -{ - zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int)); - YYSETCONDITION(new_state); -} - -#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm) - -static void yy_pop_state(TSRMLS_D) -{ - int *stack_state; - zend_stack_top(&SCNG(state_stack), (void **) &stack_state); - YYSETCONDITION(*stack_state); - zend_stack_del_top(&SCNG(state_stack)); -} - -static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) -{ - YYCURSOR = (YYCTYPE*)str; - SCNG(yy_start) = YYCURSOR; - YYLIMIT = YYCURSOR + len; -} - -#define ini_filename SCNG(filename) - -/* {{{ init_ini_scanner() -*/ -static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) -{ - /* Sanity check */ - if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { - zend_error(E_WARNING, "Invalid scanner mode"); - return FAILURE; - } - - SCNG(lineno) = 1; - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = fh; - - if (fh != NULL) { - ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); - } else { - ini_filename = NULL; - } - - zend_stack_init(&SCNG(state_stack)); - BEGIN(INITIAL); - - return SUCCESS; -} -/* }}} */ - -/* {{{ shutdown_ini_scanner() -*/ -void shutdown_ini_scanner(TSRMLS_D) -{ - zend_stack_destroy(&SCNG(state_stack)); - if (ini_filename) { - free(ini_filename); - } -} -/* }}} */ - -/* {{{ zend_ini_scanner_get_lineno() -*/ -int zend_ini_scanner_get_lineno(TSRMLS_D) -{ - return SCNG(lineno); -} -/* }}} */ - -/* {{{ zend_ini_scanner_get_filename() -*/ -char *zend_ini_scanner_get_filename(TSRMLS_D) -{ - return ini_filename ? ini_filename : "Unknown"; -} -/* }}} */ - -/* {{{ zend_ini_open_file_for_scanning() -*/ -int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC) -{ - char *buf; - size_t size; - - if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { - return FAILURE; - } - - if (init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE) { - zend_file_handle_dtor(fh TSRMLS_CC); - return FAILURE; - } - - yy_scan_buffer(buf, size TSRMLS_CC); - - return SUCCESS; -} -/* }}} */ - -/* {{{ zend_ini_prepare_string_for_scanning() -*/ -int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) -{ - int len = strlen(str); - - if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { - return FAILURE; - } - - yy_scan_buffer(str, len TSRMLS_CC); - - return SUCCESS; -} -/* }}} */ - -/* {{{ zend_ini_escape_string() - */ -static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC) -{ - register char *s, *t; - char *end; - - zend_ini_copy_value(lval, str, len); - - /* convert escape sequences */ - s = t = Z_STRVAL_P(lval); - end = s + Z_STRLEN_P(lval); - - while (s < end) { - if (*s == '\\') { - s++; - if (s >= end) { - *t++ = '\\'; - continue; - } - switch (*s) { - case '"': - if (*s != quote_type) { - *t++ = '\\'; - *t++ = *s; - break; - } - case '\\': - case '$': - *t++ = *s; - Z_STRLEN_P(lval)--; - break; - default: - *t++ = '\\'; - *t++ = *s; - break; - } - } else { - *t++ = *s; - } - if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { - SCNG(lineno)++; - } - s++; - } - *t = 0; -} -/* }}} */ - -int ini_lex(zval *ini_lval TSRMLS_DC) -{ -restart: - SCNG(yy_text) = YYCURSOR; - -/* yymore_restart: */ - /* detect EOF */ - if (YYCURSOR >= YYLIMIT) { - if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) { - BEGIN(INITIAL); - return END_OF_LINE; - } - return 0; - } - - /* Eat any UTF-8 BOM we find in the first 3 bytes */ - if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) { - if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) { - YYCURSOR += 3; - goto restart; - } - } - -#line 337 "Zend/zend_ini_scanner.c" -{ - YYCTYPE yych; - unsigned int yyaccept = 0; - if (YYGETCONDITION() < 4) { - if (YYGETCONDITION() < 2) { - if (YYGETCONDITION() < 1) { - goto yyc_INITIAL; - } else { - goto yyc_ST_OFFSET; - } - } else { - if (YYGETCONDITION() < 3) { - goto yyc_ST_SECTION_VALUE; - } else { - goto yyc_ST_VALUE; - } - } - } else { - if (YYGETCONDITION() < 6) { - if (YYGETCONDITION() < 5) { - goto yyc_ST_SECTION_RAW; - } else { - goto yyc_ST_DOUBLE_QUOTES; - } - } else { - if (YYGETCONDITION() < 7) { - goto yyc_ST_VARNAME; - } else { - goto yyc_ST_RAW; - } - } - } -/* *********************************** */ -yyc_INITIAL: - { - static const unsigned char yybm[] = { - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 160, 0, 144, 144, 0, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 240, 128, 128, 144, 128, 144, 128, 144, - 128, 128, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 144, 128, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 144, 144, 128, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 128, 128, 128, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - }; - - YYDEBUG(0, *YYCURSOR); - YYFILL(5); - yych = *YYCURSOR; - YYDEBUG(-1, yych); - switch (yych) { - case '\t': goto yy4; - case '\n': goto yy6; - case '\r': goto yy8; - case ' ': goto yy9; - case '!': - case '"': - case '$': - case '&': - case '(': - case ')': - case '^': - case '{': - case '|': - case '}': - case '~': goto yy10; - case '#': goto yy12; - case '%': - case '\'': - case '*': - case '+': - case ',': - case '-': - case '.': - case '/': - case ':': - case '<': - case '>': - case '?': - case '@': - case ']': goto yy13; - case ';': goto yy14; - case '=': goto yy16; - case 'F': - case 'f': goto yy18; - case 'N': - case 'n': goto yy19; - case 'O': - case 'o': goto yy20; - case 'T': - case 't': goto yy21; - case 'Y': - case 'y': goto yy22; - case '[': goto yy23; - default: goto yy2; - } -yy2: - YYDEBUG(2, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy26; -yy3: - YYDEBUG(3, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 429 "Zend/zend_ini_scanner.l" - { /* Get option name */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace */ - EAT_TRAILING_WHITESPACE(); - - RETURN_TOKEN(TC_LABEL, yytext, yyleng); -} -#line 476 "Zend/zend_ini_scanner.c" -yy4: - YYDEBUG(4, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy68; -yy5: - YYDEBUG(5, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 575 "Zend/zend_ini_scanner.l" - { - /* eat whitespace */ - goto restart; -} -#line 490 "Zend/zend_ini_scanner.c" -yy6: - YYDEBUG(6, *YYCURSOR); - ++YYCURSOR; -yy7: - YYDEBUG(7, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 580 "Zend/zend_ini_scanner.l" - { - SCNG(lineno)++; - return END_OF_LINE; -} -#line 502 "Zend/zend_ini_scanner.c" -yy8: - YYDEBUG(8, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy71; - goto yy7; -yy9: - YYDEBUG(9, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy26; - if (yych <= '\t') goto yy67; - goto yy71; - } else { - if (yych == '\r') goto yy72; - if (yych <= 0x1F) goto yy26; - goto yy69; - } - } else { - if (yych <= ':') { - if (yych == '#') goto yy58; - goto yy26; - } else { - if (yych <= ';') goto yy53; - if (yych == '=') goto yy51; - goto yy26; - } - } -yy10: - YYDEBUG(10, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(11, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 503 "Zend/zend_ini_scanner.l" - { /* Disallow these chars outside option values */ - return yytext[0]; -} -#line 541 "Zend/zend_ini_scanner.c" -yy12: - YYDEBUG(12, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy59; -yy13: - YYDEBUG(13, *YYCURSOR); - yych = *++YYCURSOR; - goto yy26; -yy14: - YYDEBUG(14, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - goto yy54; - YYDEBUG(15, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 562 "Zend/zend_ini_scanner.c" -yy16: - YYDEBUG(16, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy52; -yy17: - YYDEBUG(17, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 439 "Zend/zend_ini_scanner.l" - { /* Start option value */ - if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { - yy_push_state(ST_RAW TSRMLS_CC); - } else { - yy_push_state(ST_VALUE TSRMLS_CC); - } - return '='; -} -#line 580 "Zend/zend_ini_scanner.c" -yy18: - YYDEBUG(18, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy48; - if (yych == 'a') goto yy48; - goto yy26; -yy19: - YYDEBUG(19, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= 'U') { - if (yych == 'O') goto yy44; - if (yych <= 'T') goto yy26; - goto yy45; - } else { - if (yych <= 'o') { - if (yych <= 'n') goto yy26; - goto yy44; - } else { - if (yych == 'u') goto yy45; - goto yy26; - } - } -yy20: - YYDEBUG(20, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= 'N') { - if (yych == 'F') goto yy38; - if (yych <= 'M') goto yy26; - goto yy31; - } else { - if (yych <= 'f') { - if (yych <= 'e') goto yy26; - goto yy38; - } else { - if (yych == 'n') goto yy31; - goto yy26; - } - } -yy21: - YYDEBUG(21, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'R') goto yy36; - if (yych == 'r') goto yy36; - goto yy26; -yy22: - YYDEBUG(22, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy27; - if (yych == 'e') goto yy27; - goto yy26; -yy23: - YYDEBUG(23, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(24, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 358 "Zend/zend_ini_scanner.l" - { /* Section start */ - /* Enter section data lookup state */ - if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { - yy_push_state(ST_SECTION_RAW TSRMLS_CC); - } else { - yy_push_state(ST_SECTION_VALUE TSRMLS_CC); - } - return TC_SECTION; -} -#line 646 "Zend/zend_ini_scanner.c" -yy25: - YYDEBUG(25, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy26: - YYDEBUG(26, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy25; - } - if (yych == '[') goto yy28; - goto yy3; -yy27: - YYDEBUG(27, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy31; - if (yych == 's') goto yy31; - goto yy26; -yy28: - YYDEBUG(28, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(29, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy28; - } - YYDEBUG(30, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 383 "Zend/zend_ini_scanner.l" - { /* Start of option with offset */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace and [ */ - EAT_TRAILING_WHITESPACE_EX('['); - - /* Enter offset lookup state */ - yy_push_state(ST_OFFSET TSRMLS_CC); - - RETURN_TOKEN(TC_OFFSET, yytext, yyleng); -} -#line 689 "Zend/zend_ini_scanner.c" -yy31: - YYDEBUG(31, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(32, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy31; - } - if (yych <= '\'') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy34; - } else { - if (yych != '\r') goto yy25; - } - } else { - if (yych <= '$') { - if (yych == '#') goto yy25; - } else { - if (yych != '&') goto yy25; - } - } - } else { - if (yych <= 'Z') { - if (yych <= ';') { - if (yych <= ')') goto yy33; - if (yych <= ':') goto yy25; - } else { - if (yych != '=') goto yy25; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy28; - if (yych <= ']') goto yy25; - } else { - if (yych <= 'z') goto yy25; - if (yych >= 0x7F) goto yy25; - } - } - } -yy33: - YYDEBUG(33, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" - { /* TRUE value (when used outside option value/offset this causes parse error!) */ - RETURN_TOKEN(BOOL_TRUE, "1", 1); -} -#line 739 "Zend/zend_ini_scanner.c" -yy34: - YYDEBUG(34, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(35, *YYCURSOR); - if (yych == '\t') goto yy34; - if (yych == ' ') goto yy34; - goto yy33; -yy36: - YYDEBUG(36, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'U') goto yy37; - if (yych != 'u') goto yy26; -yy37: - YYDEBUG(37, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy31; - if (yych == 'e') goto yy31; - goto yy26; -yy38: - YYDEBUG(38, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'F') goto yy39; - if (yych != 'f') goto yy26; -yy39: - YYDEBUG(39, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(40, *YYCURSOR); - if (yych <= '&') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy42; - } else { - if (yych != '\r') goto yy25; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy39; - if (yych >= '#') goto yy25; - } else { - if (yych == '%') goto yy25; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '\'') goto yy25; - if (yych >= '*') goto yy25; - } else { - if (yych == '<') goto yy25; - } - } else { - if (yych <= ']') { - if (yych == '[') goto yy28; - goto yy25; - } else { - if (yych <= '^') goto yy41; - if (yych <= 'z') goto yy25; - if (yych >= 0x7F) goto yy25; - } - } - } -yy41: - YYDEBUG(41, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" - { /* FALSE value (when used outside option value/offset this causes parse error!)*/ - RETURN_TOKEN(BOOL_FALSE, "", 0); -} -#line 813 "Zend/zend_ini_scanner.c" -yy42: - YYDEBUG(42, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(43, *YYCURSOR); - if (yych == '\t') goto yy42; - if (yych == ' ') goto yy42; - goto yy41; -yy44: - YYDEBUG(44, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\'') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy26; - if (yych <= '\t') goto yy42; - goto yy41; - } else { - if (yych == '\r') goto yy41; - goto yy26; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy39; - if (yych <= '"') goto yy41; - goto yy26; - } else { - if (yych == '%') goto yy26; - if (yych <= '&') goto yy41; - goto yy26; - } - } - } else { - if (yych <= 'N') { - if (yych <= ';') { - if (yych <= ')') goto yy41; - if (yych <= ':') goto yy26; - goto yy41; - } else { - if (yych == '=') goto yy41; - if (yych <= 'M') goto yy26; - goto yy47; - } - } else { - if (yych <= 'm') { - if (yych == '^') goto yy41; - goto yy26; - } else { - if (yych <= 'n') goto yy47; - if (yych <= 'z') goto yy26; - if (yych <= '~') goto yy41; - goto yy26; - } - } - } -yy45: - YYDEBUG(45, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy46; - if (yych != 'l') goto yy26; -yy46: - YYDEBUG(46, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy39; - if (yych == 'l') goto yy39; - goto yy26; -yy47: - YYDEBUG(47, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy39; - if (yych == 'e') goto yy39; - goto yy26; -yy48: - YYDEBUG(48, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy49; - if (yych != 'l') goto yy26; -yy49: - YYDEBUG(49, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy50; - if (yych != 's') goto yy26; -yy50: - YYDEBUG(50, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy39; - if (yych == 'e') goto yy39; - goto yy26; -yy51: - YYDEBUG(51, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy52: - YYDEBUG(52, *YYCURSOR); - if (yych == '\t') goto yy51; - if (yych == ' ') goto yy51; - goto yy17; -yy53: - YYDEBUG(53, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy54: - YYDEBUG(54, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy53; - } - if (yych >= '\r') goto yy57; -yy55: - YYDEBUG(55, *YYCURSOR); - ++YYCURSOR; -yy56: - YYDEBUG(56, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 936 "Zend/zend_ini_scanner.c" -yy57: - YYDEBUG(57, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy55; - goto yy56; -yy58: - YYDEBUG(58, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy59: - YYDEBUG(59, *YYCURSOR); - if (yych <= '\'') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy58; - if (yych >= '\n') goto yy64; - } else { - if (yych == '\r') goto yy66; - goto yy58; - } - } else { - if (yych <= '$') { - if (yych == '#') goto yy58; - } else { - if (yych != '&') goto yy58; - } - } - } else { - if (yych <= 'Z') { - if (yych <= ';') { - if (yych <= ')') goto yy60; - if (yych <= ':') goto yy58; - } else { - if (yych != '=') goto yy58; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy62; - if (yych <= ']') goto yy58; - } else { - if (yych <= 'z') goto yy58; - if (yych >= 0x7F) goto yy58; - } - } - } -yy60: - YYDEBUG(60, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(61, *YYCURSOR); - if (yych == '\n') goto yy64; - if (yych == '\r') goto yy66; - goto yy60; -yy62: - YYDEBUG(62, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(63, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy60; - if (yych <= '\t') goto yy62; - if (yych >= '\v') goto yy60; - } else { - if (yych <= '\r') goto yy66; - if (yych == ' ') goto yy62; - goto yy60; - } -yy64: - YYDEBUG(64, *YYCURSOR); - ++YYCURSOR; -yy65: - YYDEBUG(65, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 591 "Zend/zend_ini_scanner.l" - { /* #Comment */ - zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno)); - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 1022 "Zend/zend_ini_scanner.c" -yy66: - YYDEBUG(66, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy64; - goto yy65; -yy67: - YYDEBUG(67, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy68: - YYDEBUG(68, *YYCURSOR); - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy5; - if (yych <= '\t') goto yy67; - goto yy71; - } else { - if (yych == '\r') goto yy72; - if (yych <= 0x1F) goto yy5; - goto yy67; - } - } else { - if (yych <= ':') { - if (yych == '#') goto yy60; - goto yy5; - } else { - if (yych <= ';') goto yy53; - if (yych == '=') goto yy51; - goto yy5; - } - } -yy69: - YYDEBUG(69, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(70, *YYCURSOR); - if (yych <= '&') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy67; - } else { - if (yych == '\r') goto yy72; - goto yy25; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy69; - if (yych <= '"') goto yy3; - goto yy58; - } else { - if (yych == '%') goto yy25; - goto yy3; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '\'') goto yy25; - if (yych <= ')') goto yy3; - goto yy25; - } else { - if (yych <= ';') goto yy53; - if (yych <= '<') goto yy25; - goto yy51; - } - } else { - if (yych <= ']') { - if (yych == '[') goto yy28; - goto yy25; - } else { - if (yych <= '^') goto yy3; - if (yych <= 'z') goto yy25; - if (yych <= '~') goto yy3; - goto yy25; - } - } - } -yy71: - YYDEBUG(71, *YYCURSOR); - yych = *++YYCURSOR; - goto yy7; -yy72: - YYDEBUG(72, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy71; - goto yy7; - } -/* *********************************** */ -yyc_ST_DOUBLE_QUOTES: - { - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - YYDEBUG(73, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych == '"') goto yy77; - if (yych == '$') goto yy79; - YYDEBUG(75, *YYCURSOR); - ++YYCURSOR; -yy76: - YYDEBUG(76, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 535 "Zend/zend_ini_scanner.l" - { /* Escape double quoted string contents */ - if (YYCURSOR > YYLIMIT) { - return 0; - } - - while (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR++) { - case '"': - if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { - continue; - } - break; - case '$': - if (*YYCURSOR == '{') { - break; - } - continue; - case '\\': - if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { - YYCURSOR++; - } - /* fall through */ - default: - continue; - } - - YYCURSOR--; - break; - } - - yyleng = YYCURSOR - SCNG(yy_text); - - zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); - return TC_QUOTED_STRING; -} -#line 1198 "Zend/zend_ini_scanner.c" -yy77: - YYDEBUG(77, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy83; -yy78: - YYDEBUG(78, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 530 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string ends */ - yy_pop_state(TSRMLS_C); - return '"'; -} -#line 1212 "Zend/zend_ini_scanner.c" -yy79: - YYDEBUG(79, *YYCURSOR); - yych = *++YYCURSOR; - if (yych != '{') goto yy76; - YYDEBUG(80, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(81, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 1226 "Zend/zend_ini_scanner.c" -yy82: - YYDEBUG(82, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy83: - YYDEBUG(83, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy82; - } - goto yy78; - } -/* *********************************** */ -yyc_ST_OFFSET: - { - static const unsigned char yybm[] = { - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 194, 64, 66, 66, 64, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 194, 66, 64, 66, 68, 66, 66, 0, - 66, 66, 66, 66, 66, 66, 66, 66, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 66, 64, 66, 66, 66, 66, - 66, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 66, 72, 64, 66, 82, - 66, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - }; - YYDEBUG(84, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych <= '-') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy86; - if (yych <= '\t') goto yy88; - goto yy89; - } else { - if (yych == '\r') goto yy89; - if (yych >= ' ') goto yy88; - } - } else { - if (yych <= '$') { - if (yych == '"') goto yy91; - if (yych >= '$') goto yy93; - } else { - if (yych == '\'') goto yy94; - if (yych >= '-') goto yy95; - } - } - } else { - if (yych <= 'Z') { - if (yych <= '9') { - if (yych <= '.') goto yy96; - if (yych >= '0') goto yy97; - } else { - if (yych == ';') goto yy89; - if (yych >= 'A') goto yy99; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy86; - if (yych <= '\\') goto yy101; - if (yych <= ']') goto yy102; - } else { - if (yych == '`') goto yy86; - if (yych <= 'z') goto yy99; - } - } - } -yy86: - YYDEBUG(86, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy105; -yy87: - YYDEBUG(87, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 521 "Zend/zend_ini_scanner.l" - { /* Get rest as section/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 1330 "Zend/zend_ini_scanner.c" -yy88: - YYDEBUG(88, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy131; - } - if (yych == '"') goto yy133; - if (yych == ']') goto yy134; - goto yy105; -yy89: - YYDEBUG(89, *YYCURSOR); - ++YYCURSOR; -yy90: - YYDEBUG(90, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 1351 "Zend/zend_ini_scanner.c" -yy91: - YYDEBUG(91, *YYCURSOR); - ++YYCURSOR; -yy92: - YYDEBUG(92, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 1363 "Zend/zend_ini_scanner.c" -yy93: - YYDEBUG(93, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy90; - if (yych <= '[') goto yy104; - goto yy109; - } else { - if (yych == '{') goto yy129; - goto yy104; - } -yy94: - YYDEBUG(94, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy125; - } - goto yy90; -yy95: - YYDEBUG(95, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy123; - goto yy105; -yy96: - YYDEBUG(96, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy121; - goto yy105; -yy97: - YYDEBUG(97, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\'') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy105; - } else { - if (yych == '"') goto yy98; - if (yych <= '&') goto yy105; - } - } else { - if (yych <= '9') { - if (yych == '.') goto yy117; - if (yych <= '/') goto yy105; - goto yy119; - } else { - if (yych <= ';') { - if (yych <= ':') goto yy105; - } else { - if (yych != ']') goto yy105; - } - } - } -yy98: - YYDEBUG(98, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 1429 "Zend/zend_ini_scanner.c" -yy99: - YYDEBUG(99, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy115; - } - if (yych <= '"') { - if (yych <= '\f') { - if (yych != '\n') goto yy105; - } else { - if (yych <= '\r') goto yy100; - if (yych <= '!') goto yy105; - } - } else { - if (yych <= ':') { - if (yych != '\'') goto yy105; - } else { - if (yych <= ';') goto yy100; - if (yych != ']') goto yy105; - } - } -yy100: - YYDEBUG(100, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 1459 "Zend/zend_ini_scanner.c" -yy101: - YYDEBUG(101, *YYCURSOR); - yych = *++YYCURSOR; - goto yy104; -yy102: - YYDEBUG(102, *YYCURSOR); - ++YYCURSOR; -yy103: - YYDEBUG(103, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 396 "Zend/zend_ini_scanner.l" - { /* End of section or an option offset */ - BEGIN(INITIAL); - return ']'; -} -#line 1475 "Zend/zend_ini_scanner.c" -yy104: - YYDEBUG(104, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy105: - YYDEBUG(105, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy104; - } - if (yych == '$') goto yy107; - if (yych != '\\') goto yy87; -yy106: - YYDEBUG(106, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - goto yy104; -yy107: - YYDEBUG(107, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy108; - if (yych <= '[') goto yy104; - goto yy109; - } else { - if (yych != '{') goto yy104; - } -yy108: - YYDEBUG(108, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy87; - } else { - goto yy90; - } - } else { - if (yyaccept <= 2) { - goto yy98; - } else { - goto yy100; - } - } -yy109: - YYDEBUG(109, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy110: - YYDEBUG(110, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(111, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy114; - goto yy104; -yy112: - YYDEBUG(112, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(113, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy114: - YYDEBUG(114, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy115: - YYDEBUG(115, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(116, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy115; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy100; - if (yych <= '\f') goto yy104; - goto yy100; - } else { - if (yych == '"') goto yy100; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy100; - if (yych <= ':') goto yy104; - goto yy100; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy100; - goto yy104; - } - } -yy117: - YYDEBUG(117, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(118, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy117; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych == '"') goto yy98; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy98; - if (yych <= ':') goto yy104; - goto yy98; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } -yy119: - YYDEBUG(119, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(120, *YYCURSOR); - if (yych <= '\'') { - if (yych <= '!') { - if (yych <= '\n') { - if (yych <= '\t') goto yy104; - goto yy98; - } else { - if (yych == '\r') goto yy98; - goto yy104; - } - } else { - if (yych <= '#') { - if (yych <= '"') goto yy98; - goto yy104; - } else { - if (yych <= '$') goto yy107; - if (yych <= '&') goto yy104; - goto yy98; - } - } - } else { - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy104; - goto yy117; - } else { - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy119; - goto yy104; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy121: - YYDEBUG(121, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(122, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy104; - goto yy98; - } else { - if (yych == '$') goto yy107; - goto yy104; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy98; - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy121; - goto yy104; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy123: - YYDEBUG(123, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(124, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy104; - goto yy98; - } else { - if (yych == '$') goto yy107; - goto yy104; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy98; - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy123; - goto yy104; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy125: - YYDEBUG(125, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(126, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy125; - } - YYDEBUG(127, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(128, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 1774 "Zend/zend_ini_scanner.c" -yy129: - YYDEBUG(129, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(130, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 1785 "Zend/zend_ini_scanner.c" -yy131: - YYDEBUG(131, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(132, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy131; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy87; - if (yych <= '\f') goto yy104; - goto yy87; - } else { - if (yych == '"') goto yy133; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy87; - if (yych <= ':') goto yy104; - goto yy87; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy134; - goto yy104; - } - } -yy133: - YYDEBUG(133, *YYCURSOR); - yych = *++YYCURSOR; - goto yy92; -yy134: - YYDEBUG(134, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy103; - } -/* *********************************** */ -yyc_ST_RAW: - { - static const unsigned char yybm[] = { - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 192, 0, 64, 64, 0, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - YYDEBUG(135, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy139; - } else { - if (yych <= '\t') goto yy141; - if (yych <= '\n') goto yy142; - goto yy139; - } - } else { - if (yych <= ' ') { - if (yych <= '\r') goto yy144; - if (yych <= 0x1F) goto yy139; - goto yy141; - } else { - if (yych == ';') goto yy145; - goto yy139; - } - } - YYDEBUG(137, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(138, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 598 "Zend/zend_ini_scanner.l" - { /* End of option value (if EOF is reached before EOL */ - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 1895 "Zend/zend_ini_scanner.c" -yy139: - YYDEBUG(139, *YYCURSOR); - ++YYCURSOR; -yy140: - YYDEBUG(140, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 448 "Zend/zend_ini_scanner.l" - { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ - char *sc = NULL; - while (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR) { - case '\n': - case '\r': - goto end_raw_value_chars; - break; - case ';': - if (sc == NULL) { - sc = YYCURSOR; - } - /* no break */ - default: - YYCURSOR++; - break; - } - } -end_raw_value_chars: - yyleng = YYCURSOR - SCNG(yy_text); - - /* Eat trailing semicolons */ - while (yytext[yyleng - 1] == ';') { - yyleng--; - } - - /* Eat leading and trailing double quotes */ - if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } else if (sc) { - YYCURSOR = sc; - yyleng = YYCURSOR - SCNG(yy_text); - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 1939 "Zend/zend_ini_scanner.c" -yy141: - YYDEBUG(141, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\r') { - if (yych <= 0x08) goto yy140; - if (yych <= '\n') goto yy153; - if (yych <= '\f') goto yy140; - goto yy153; - } else { - if (yych <= ' ') { - if (yych <= 0x1F) goto yy140; - goto yy153; - } else { - if (yych == ';') goto yy153; - goto yy140; - } - } -yy142: - YYDEBUG(142, *YYCURSOR); - ++YYCURSOR; -yy143: - YYDEBUG(143, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 489 "Zend/zend_ini_scanner.l" - { /* End of option value */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 1970 "Zend/zend_ini_scanner.c" -yy144: - YYDEBUG(144, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy151; - goto yy143; -yy145: - YYDEBUG(145, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy147; -yy146: - YYDEBUG(146, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy147: - YYDEBUG(147, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy146; - } - if (yych >= '\r') goto yy150; -yy148: - YYDEBUG(148, *YYCURSOR); - ++YYCURSOR; -yy149: - YYDEBUG(149, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 2004 "Zend/zend_ini_scanner.c" -yy150: - YYDEBUG(150, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy148; - goto yy149; -yy151: - YYDEBUG(151, *YYCURSOR); - yych = *++YYCURSOR; - goto yy143; -yy152: - YYDEBUG(152, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy153: - YYDEBUG(153, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy152; - } - if (yych <= '\f') { - if (yych == '\n') goto yy151; - } else { - if (yych <= '\r') goto yy155; - if (yych == ';') goto yy146; - } - YYDEBUG(154, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 575 "Zend/zend_ini_scanner.l" - { - /* eat whitespace */ - goto restart; -} -#line 2038 "Zend/zend_ini_scanner.c" -yy155: - YYDEBUG(155, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy151; - goto yy143; - } -/* *********************************** */ -yyc_ST_SECTION_RAW: - { - static const unsigned char yybm[] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 192, 0, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 192, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - }; - YYDEBUG(156, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '\f') { - if (yych == '\n') goto yy160; - } else { - if (yych <= '\r') goto yy160; - if (yych == ']') goto yy162; - } - YYDEBUG(158, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy169; -yy159: - YYDEBUG(159, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 485 "Zend/zend_ini_scanner.l" - { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 2102 "Zend/zend_ini_scanner.c" -yy160: - YYDEBUG(160, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(161, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 2112 "Zend/zend_ini_scanner.c" -yy162: - YYDEBUG(162, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy165; -yy163: - YYDEBUG(163, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 377 "Zend/zend_ini_scanner.l" - { /* End of section */ - BEGIN(INITIAL); - SCNG(lineno)++; - return ']'; -} -#line 2127 "Zend/zend_ini_scanner.c" -yy164: - YYDEBUG(164, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy165: - YYDEBUG(165, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy164; - } - if (yych == '\n') goto yy166; - if (yych == '\r') goto yy167; - goto yy163; -yy166: - YYDEBUG(166, *YYCURSOR); - yych = *++YYCURSOR; - goto yy163; -yy167: - YYDEBUG(167, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy166; - goto yy163; -yy168: - YYDEBUG(168, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy169: - YYDEBUG(169, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy168; - } - goto yy159; - } -/* *********************************** */ -yyc_ST_SECTION_VALUE: - { - static const unsigned char yybm[] = { - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 134, 128, 132, 132, 128, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 134, 132, 128, 132, 136, 132, 132, 0, - 132, 132, 132, 132, 132, 132, 132, 132, - 228, 228, 228, 228, 228, 228, 228, 228, - 228, 228, 132, 128, 132, 132, 132, 132, - 132, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 132, 144, 128, 132, 164, - 132, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - }; - YYDEBUG(170, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '-') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy172; - if (yych <= '\t') goto yy174; - goto yy175; - } else { - if (yych == '\r') goto yy175; - if (yych >= ' ') goto yy174; - } - } else { - if (yych <= '$') { - if (yych == '"') goto yy177; - if (yych >= '$') goto yy179; - } else { - if (yych == '\'') goto yy180; - if (yych >= '-') goto yy181; - } - } - } else { - if (yych <= 'Z') { - if (yych <= '9') { - if (yych <= '.') goto yy182; - if (yych >= '0') goto yy183; - } else { - if (yych == ';') goto yy175; - if (yych >= 'A') goto yy185; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy172; - if (yych <= '\\') goto yy187; - if (yych <= ']') goto yy188; - } else { - if (yych == '`') goto yy172; - if (yych <= 'z') goto yy185; - } - } - } -yy172: - YYDEBUG(172, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy195; -yy173: - YYDEBUG(173, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 521 "Zend/zend_ini_scanner.l" - { /* Get rest as section/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 2253 "Zend/zend_ini_scanner.c" -yy174: - YYDEBUG(174, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x1F) { - if (yych == '\t') goto yy221; - goto yy195; - } else { - if (yych <= ' ') goto yy221; - if (yych == '"') goto yy223; - goto yy195; - } -yy175: - YYDEBUG(175, *YYCURSOR); - ++YYCURSOR; -yy176: - YYDEBUG(176, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 2276 "Zend/zend_ini_scanner.c" -yy177: - YYDEBUG(177, *YYCURSOR); - ++YYCURSOR; -yy178: - YYDEBUG(178, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 2288 "Zend/zend_ini_scanner.c" -yy179: - YYDEBUG(179, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy176; - if (yych <= '[') goto yy194; - goto yy199; - } else { - if (yych == '{') goto yy219; - goto yy194; - } -yy180: - YYDEBUG(180, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy215; - } - goto yy176; -yy181: - YYDEBUG(181, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy195; - if (yych <= '9') goto yy213; - goto yy195; -yy182: - YYDEBUG(182, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy195; - if (yych <= '9') goto yy211; - goto yy195; -yy183: - YYDEBUG(183, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\'') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy195; - } else { - if (yych == '"') goto yy184; - if (yych <= '&') goto yy195; - } - } else { - if (yych <= '9') { - if (yych == '.') goto yy207; - if (yych <= '/') goto yy195; - goto yy209; - } else { - if (yych <= ';') { - if (yych <= ':') goto yy195; - } else { - if (yych != ']') goto yy195; - } - } - } -yy184: - YYDEBUG(184, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 2354 "Zend/zend_ini_scanner.c" -yy185: - YYDEBUG(185, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy205; - } - if (yych <= '"') { - if (yych <= '\f') { - if (yych != '\n') goto yy195; - } else { - if (yych <= '\r') goto yy186; - if (yych <= '!') goto yy195; - } - } else { - if (yych <= ':') { - if (yych != '\'') goto yy195; - } else { - if (yych <= ';') goto yy186; - if (yych != ']') goto yy195; - } - } -yy186: - YYDEBUG(186, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 2384 "Zend/zend_ini_scanner.c" -yy187: - YYDEBUG(187, *YYCURSOR); - yych = *++YYCURSOR; - goto yy194; -yy188: - YYDEBUG(188, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy191; -yy189: - YYDEBUG(189, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 377 "Zend/zend_ini_scanner.l" - { /* End of section */ - BEGIN(INITIAL); - SCNG(lineno)++; - return ']'; -} -#line 2403 "Zend/zend_ini_scanner.c" -yy190: - YYDEBUG(190, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy191: - YYDEBUG(191, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy190; - } - if (yych == '\n') goto yy192; - if (yych == '\r') goto yy193; - goto yy189; -yy192: - YYDEBUG(192, *YYCURSOR); - yych = *++YYCURSOR; - goto yy189; -yy193: - YYDEBUG(193, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy192; - goto yy189; -yy194: - YYDEBUG(194, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy195: - YYDEBUG(195, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy194; - } - if (yych == '$') goto yy197; - if (yych != '\\') goto yy173; -yy196: - YYDEBUG(196, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - goto yy194; -yy197: - YYDEBUG(197, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy198; - if (yych <= '[') goto yy194; - goto yy199; - } else { - if (yych != '{') goto yy194; - } -yy198: - YYDEBUG(198, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy173; - } else { - goto yy176; - } - } else { - if (yyaccept <= 2) { - goto yy184; - } else { - goto yy186; - } - } -yy199: - YYDEBUG(199, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy200: - YYDEBUG(200, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(201, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy204; - goto yy194; -yy202: - YYDEBUG(202, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(203, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy204: - YYDEBUG(204, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy205: - YYDEBUG(205, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(206, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy205; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy186; - if (yych <= '\f') goto yy194; - goto yy186; - } else { - if (yych == '"') goto yy186; - if (yych <= '#') goto yy194; - goto yy197; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy186; - if (yych <= ':') goto yy194; - goto yy186; - } else { - if (yych <= '[') goto yy194; - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy186; - goto yy194; - } - } -yy207: - YYDEBUG(207, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(208, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy207; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych == '"') goto yy184; - if (yych <= '#') goto yy194; - goto yy197; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy184; - if (yych <= ':') goto yy194; - goto yy184; - } else { - if (yych <= '[') goto yy194; - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } -yy209: - YYDEBUG(209, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(210, *YYCURSOR); - if (yych <= '\'') { - if (yych <= '!') { - if (yych <= '\n') { - if (yych <= '\t') goto yy194; - goto yy184; - } else { - if (yych == '\r') goto yy184; - goto yy194; - } - } else { - if (yych <= '#') { - if (yych <= '"') goto yy184; - goto yy194; - } else { - if (yych <= '$') goto yy197; - if (yych <= '&') goto yy194; - goto yy184; - } - } - } else { - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy194; - goto yy207; - } else { - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy209; - goto yy194; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy211: - YYDEBUG(211, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(212, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy194; - goto yy184; - } else { - if (yych == '$') goto yy197; - goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy184; - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy211; - goto yy194; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy213: - YYDEBUG(213, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(214, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy194; - goto yy184; - } else { - if (yych == '$') goto yy197; - goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy184; - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy213; - goto yy194; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy215: - YYDEBUG(215, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(216, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy215; - } - YYDEBUG(217, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(218, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 2724 "Zend/zend_ini_scanner.c" -yy219: - YYDEBUG(219, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(220, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 2735 "Zend/zend_ini_scanner.c" -yy221: - YYDEBUG(221, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(222, *YYCURSOR); - if (yych <= '"') { - if (yych <= '\f') { - if (yych <= 0x08) goto yy194; - if (yych <= '\t') goto yy221; - if (yych <= '\n') goto yy173; - goto yy194; - } else { - if (yych <= 0x1F) { - if (yych <= '\r') goto yy173; - goto yy194; - } else { - if (yych <= ' ') goto yy221; - if (yych <= '!') goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '$') { - if (yych <= '#') goto yy194; - goto yy197; - } else { - if (yych == '\'') goto yy173; - goto yy194; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy173; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy173; - goto yy194; - } - } - } -yy223: - YYDEBUG(223, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy178; - } -/* *********************************** */ -yyc_ST_VALUE: - { - static const unsigned char yybm[] = { - 160, 162, 162, 162, 162, 162, 162, 162, - 162, 176, 128, 162, 162, 128, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 176, 160, 160, 162, 168, 162, 160, 32, - 160, 160, 162, 162, 162, 162, 162, 162, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 162, 160, 162, 160, 162, 162, - 162, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 162, 162, 162, 160, 166, - 162, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 162, 160, 162, 160, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - }; - YYDEBUG(224, *YYCURSOR); - YYFILL(6); - yych = *YYCURSOR; - YYDEBUG(-1, yych); - switch (yych) { - case 0x00: goto yy226; - case '\t': - case ' ': goto yy230; - case '\n': goto yy232; - case '\r': goto yy234; - case '!': - case '&': - case '(': - case ')': - case '^': - case '|': - case '~': goto yy235; - case '"': goto yy237; - case '$': goto yy239; - case '\'': goto yy240; - case '-': goto yy241; - case '.': goto yy242; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy243; - case ';': goto yy245; - case '=': goto yy246; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'p': - case 'q': - case 'r': - case 's': - case 'u': - case 'v': - case 'w': - case 'x': - case 'z': goto yy248; - case 'F': - case 'f': goto yy250; - case 'N': - case 'n': goto yy251; - case 'O': - case 'o': goto yy252; - case 'T': - case 't': goto yy253; - case 'Y': - case 'y': goto yy254; - default: goto yy228; - } -yy226: - YYDEBUG(226, *YYCURSOR); - ++YYCURSOR; -yy227: - YYDEBUG(227, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 598 "Zend/zend_ini_scanner.l" - { /* End of option value (if EOF is reached before EOL */ - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 2921 "Zend/zend_ini_scanner.c" -yy228: - YYDEBUG(228, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy256; -yy229: - YYDEBUG(229, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 517 "Zend/zend_ini_scanner.l" - { /* Get everything else as option/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 2934 "Zend/zend_ini_scanner.c" -yy230: - YYDEBUG(230, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy306; -yy231: - YYDEBUG(231, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 571 "Zend/zend_ini_scanner.l" - { - RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); -} -#line 2947 "Zend/zend_ini_scanner.c" -yy232: - YYDEBUG(232, *YYCURSOR); - ++YYCURSOR; -yy233: - YYDEBUG(233, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 489 "Zend/zend_ini_scanner.l" - { /* End of option value */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 2960 "Zend/zend_ini_scanner.c" -yy234: - YYDEBUG(234, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy304; - goto yy233; -yy235: - YYDEBUG(235, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy303; -yy236: - YYDEBUG(236, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 507 "Zend/zend_ini_scanner.l" - { /* Boolean operators */ - return yytext[0]; -} -#line 2978 "Zend/zend_ini_scanner.c" -yy237: - YYDEBUG(237, *YYCURSOR); - ++YYCURSOR; -yy238: - YYDEBUG(238, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 2990 "Zend/zend_ini_scanner.c" -yy239: - YYDEBUG(239, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy227; - if (yych <= '[') goto yy255; - goto yy262; - } else { - if (yych == '{') goto yy300; - goto yy255; - } -yy240: - YYDEBUG(240, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy296; - } - goto yy227; -yy241: - YYDEBUG(241, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy294; - goto yy256; -yy242: - YYDEBUG(242, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy292; - goto yy256; -yy243: - YYDEBUG(243, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy256; - } else { - if (yych != '\r') goto yy256; - } - } else { - if (yych <= ')') { - if (yych <= '"') goto yy244; - if (yych <= '%') goto yy256; - } else { - if (yych == '.') goto yy288; - goto yy256; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy290; - if (yych <= ':') goto yy256; - } else { - if (yych != '=') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy244: - YYDEBUG(244, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 3069 "Zend/zend_ini_scanner.c" -yy245: - YYDEBUG(245, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - goto yy284; -yy246: - YYDEBUG(246, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(247, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 511 "Zend/zend_ini_scanner.l" - { /* Make = used in option value to trigger error */ - yyless(0); - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 3086 "Zend/zend_ini_scanner.c" -yy248: - YYDEBUG(248, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ':') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy256; - } else { - if (yych <= '\n') goto yy249; - if (yych <= '\f') goto yy256; - } - } else { - if (yych <= '"') { - if (yych <= 0x1F) goto yy256; - } else { - if (yych <= '%') goto yy256; - if (yych >= '*') goto yy256; - } - } - } else { - if (yych <= '^') { - if (yych <= '<') { - if (yych >= '<') goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= ']') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy249: - YYDEBUG(249, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 3133 "Zend/zend_ini_scanner.c" -yy250: - YYDEBUG(250, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '<') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '/') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - goto yy256; - } else { - if (yych <= '9') goto yy257; - if (yych == ';') goto yy249; - goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= 'A') { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy280; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - goto yy257; - } - } else { - if (yych <= '{') { - if (yych <= '`') goto yy256; - if (yych <= 'a') goto yy280; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy251: - YYDEBUG(251, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'N') { - if (yych <= '%') { - if (yych <= '\f') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - if (yych <= '\n') goto yy249; - goto yy256; - } else { - if (yych <= '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - if (yych <= '"') goto yy249; - goto yy256; - } - } else { - if (yych <= ':') { - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - goto yy256; - } else { - if (yych <= '<') { - if (yych <= ';') goto yy249; - goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy257; - } - } - } - } else { - if (yych <= 'n') { - if (yych <= 'Z') { - if (yych <= 'O') goto yy276; - if (yych == 'U') goto yy277; - goto yy257; - } else { - if (yych <= '^') { - if (yych <= ']') goto yy256; - goto yy249; - } else { - if (yych == '`') goto yy256; - goto yy257; - } - } - } else { - if (yych <= 'z') { - if (yych <= 'o') goto yy276; - if (yych == 'u') goto yy277; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy256; - } - } - } - } -yy252: - YYDEBUG(252, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'E') { - if (yych <= '%') { - if (yych <= '\f') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - if (yych <= '\n') goto yy249; - goto yy256; - } else { - if (yych <= '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - if (yych <= '"') goto yy249; - goto yy256; - } - } else { - if (yych <= ':') { - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - goto yy256; - } else { - if (yych <= '<') { - if (yych <= ';') goto yy249; - goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy257; - } - } - } - } else { - if (yych <= 'e') { - if (yych <= 'Z') { - if (yych <= 'F') goto yy271; - if (yych == 'N') goto yy265; - goto yy257; - } else { - if (yych <= '^') { - if (yych <= ']') goto yy256; - goto yy249; - } else { - if (yych == '`') goto yy256; - goto yy257; - } - } - } else { - if (yych <= 'z') { - if (yych <= 'f') goto yy271; - if (yych == 'n') goto yy265; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy256; - } - } - } - } -yy253: - YYDEBUG(253, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'R') goto yy269; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'r') goto yy269; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy254: - YYDEBUG(254, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy259; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy259; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy255: - YYDEBUG(255, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy256: - YYDEBUG(256, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy255; - } - if (yych == '$') goto yy260; - goto yy229; -yy257: - YYDEBUG(257, *YYCURSOR); - yyaccept = 4; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(258, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ')') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych <= 0x00) goto yy249; - goto yy255; - } else { - if (yych <= '\n') goto yy249; - if (yych <= '\f') goto yy255; - goto yy249; - } - } else { - if (yych <= '#') { - if (yych <= 0x1F) goto yy255; - if (yych <= '"') goto yy249; - goto yy255; - } else { - if (yych <= '$') goto yy260; - if (yych <= '%') goto yy255; - goto yy249; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy255; - goto yy249; - } else { - if (yych == '=') goto yy249; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy249; - if (yych <= '{') goto yy255; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy255; - } - } - } -yy259: - YYDEBUG(259, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'S') goto yy265; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 's') goto yy265; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy260: - YYDEBUG(260, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy261; - if (yych <= '[') goto yy255; - goto yy262; - } else { - if (yych != '{') goto yy255; - } -yy261: - YYDEBUG(261, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 3) { - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy229; - } else { - goto yy231; - } - } else { - if (yyaccept <= 2) { - goto yy227; - } else { - goto yy244; - } - } - } else { - if (yyaccept <= 5) { - if (yyaccept <= 4) { - goto yy249; - } else { - goto yy266; - } - } else { - goto yy273; - } - } -yy262: - YYDEBUG(262, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy263; - } - goto yy255; -yy263: - YYDEBUG(263, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(264, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy263; - } - if (yych <= 0x00) goto yy229; - if (yych == '\\') goto yy262; - goto yy255; -yy265: - YYDEBUG(265, *YYCURSOR); - yyaccept = 5; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy267; - } - if (yych <= ';') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy266; - if (yych <= '\t') goto yy256; - } else { - if (yych != '\r') goto yy256; - } - } else { - if (yych <= ')') { - if (yych <= '"') goto yy266; - if (yych <= '%') goto yy256; - } else { - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - if (yych <= ':') goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= '@') { - if (yych != '=') goto yy256; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych >= '_') goto yy257; - } - } else { - if (yych <= '{') { - if (yych <= '`') goto yy256; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych >= 0x7F) goto yy256; - } - } - } -yy266: - YYDEBUG(266, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" - { /* TRUE value (when used outside option value/offset this causes parse error!) */ - RETURN_TOKEN(BOOL_TRUE, "1", 1); -} -#line 3645 "Zend/zend_ini_scanner.c" -yy267: - YYDEBUG(267, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(268, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy267; - } - goto yy266; -yy269: - YYDEBUG(269, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'U') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'u') goto yy270; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy270: - YYDEBUG(270, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy265; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy265; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy271: - YYDEBUG(271, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'F') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'f') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy272: - YYDEBUG(272, *YYCURSOR); - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ')') { - if (yych <= '\f') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy256; - } else { - if (yych <= '\t') goto yy274; - if (yych >= '\v') goto yy256; - } - } else { - if (yych <= ' ') { - if (yych <= '\r') goto yy273; - if (yych <= 0x1F) goto yy256; - goto yy274; - } else { - if (yych <= '"') goto yy273; - if (yych <= '%') goto yy256; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy256; - } else { - if (yych != '=') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy273; - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy273: - YYDEBUG(273, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" - { /* FALSE value (when used outside option value/offset this causes parse error!)*/ - RETURN_TOKEN(BOOL_FALSE, "", 0); -} -#line 3855 "Zend/zend_ini_scanner.c" -yy274: - YYDEBUG(274, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(275, *YYCURSOR); - if (yych == '\t') goto yy274; - if (yych == ' ') goto yy274; - goto yy273; -yy276: - YYDEBUG(276, *YYCURSOR); - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '<') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy273; - if (yych <= 0x08) goto yy256; - if (yych <= '\t') goto yy274; - goto yy273; - } else { - if (yych == '\r') goto yy273; - if (yych <= 0x1F) goto yy256; - goto yy274; - } - } else { - if (yych <= '/') { - if (yych <= '"') goto yy273; - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy273; - goto yy256; - } else { - if (yych <= '9') goto yy257; - if (yych == ';') goto yy273; - goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= 'N') { - if (yych <= '=') goto yy273; - if (yych <= '@') goto yy256; - if (yych <= 'M') goto yy257; - goto yy279; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy273; - goto yy257; - } - } else { - if (yych <= 'z') { - if (yych <= '`') goto yy256; - if (yych == 'n') goto yy279; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy273; - } else { - if (yych == '~') goto yy273; - goto yy256; - } - } - } - } -yy277: - YYDEBUG(277, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'L') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy278; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy278: - YYDEBUG(278, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'L') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy279: - YYDEBUG(279, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy280: - YYDEBUG(280, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'L') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy281; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy281: - YYDEBUG(281, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'S') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 's') goto yy282; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy282: - YYDEBUG(282, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy283: - YYDEBUG(283, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy284: - YYDEBUG(284, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy283; - } - if (yych >= '\r') goto yy287; -yy285: - YYDEBUG(285, *YYCURSOR); - ++YYCURSOR; -yy286: - YYDEBUG(286, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 4248 "Zend/zend_ini_scanner.c" -yy287: - YYDEBUG(287, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy285; - goto yy286; -yy288: - YYDEBUG(288, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(289, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy288; - } - if (yych <= ')') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych <= 0x00) goto yy244; - goto yy255; - } else { - if (yych <= '\n') goto yy244; - if (yych <= '\f') goto yy255; - goto yy244; - } - } else { - if (yych <= '#') { - if (yych <= 0x1F) goto yy255; - if (yych <= '"') goto yy244; - goto yy255; - } else { - if (yych <= '$') goto yy260; - if (yych <= '%') goto yy255; - goto yy244; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy290: - YYDEBUG(290, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(291, *YYCURSOR); - if (yych <= '.') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - if (yych <= '-') goto yy255; - goto yy288; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '/') goto yy255; - if (yych <= '9') goto yy290; - goto yy255; - } else { - if (yych == '<') goto yy255; - goto yy244; - } - } else { - if (yych <= '{') { - if (yych == '^') goto yy244; - goto yy255; - } else { - if (yych == '}') goto yy255; - if (yych <= '~') goto yy244; - goto yy255; - } - } - } -yy292: - YYDEBUG(292, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(293, *YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - goto yy255; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy292; - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy294: - YYDEBUG(294, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(295, *YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - goto yy255; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy294; - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy296: - YYDEBUG(296, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(297, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy296; - } - YYDEBUG(298, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(299, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 4475 "Zend/zend_ini_scanner.c" -yy300: - YYDEBUG(300, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(301, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 4486 "Zend/zend_ini_scanner.c" -yy302: - YYDEBUG(302, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy303: - YYDEBUG(303, *YYCURSOR); - if (yych == '\t') goto yy302; - if (yych == ' ') goto yy302; - goto yy236; -yy304: - YYDEBUG(304, *YYCURSOR); - yych = *++YYCURSOR; - goto yy233; -yy305: - YYDEBUG(305, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy306: - YYDEBUG(306, *YYCURSOR); - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy231; - if (yych <= '\t') goto yy305; - goto yy304; - } else { - if (yych == '\r') goto yy308; - goto yy231; - } - } else { - if (yych <= '"') { - if (yych <= ' ') goto yy305; - if (yych <= '!') goto yy231; - } else { - if (yych == ';') goto yy283; - goto yy231; - } - } - YYDEBUG(307, *YYCURSOR); - yych = *++YYCURSOR; - goto yy238; -yy308: - YYDEBUG(308, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy304; - goto yy233; - } -/* *********************************** */ -yyc_ST_VARNAME: - { - static const unsigned char yybm[] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 0, 0, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 0, 0, 128, 0, 128, 0, 128, - 0, 0, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 128, 128, 0, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 0, 0, 0, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - }; - YYDEBUG(309, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych <= ')') { - if (yych <= '"') { - if (yych <= '\f') { - if (yych <= 0x08) goto yy311; - if (yych <= '\n') goto yy313; - } else { - if (yych <= '\r') goto yy313; - if (yych >= '!') goto yy313; - } - } else { - if (yych <= '%') { - if (yych == '$') goto yy313; - } else { - if (yych != '\'') goto yy313; - } - } - } else { - if (yych <= '[') { - if (yych <= '<') { - if (yych == ';') goto yy313; - } else { - if (yych <= '=') goto yy313; - if (yych >= '[') goto yy313; - } - } else { - if (yych <= 'z') { - if (yych == '^') goto yy313; - } else { - if (yych == '}') goto yy315; - if (yych <= '~') goto yy313; - } - } - } -yy311: - YYDEBUG(311, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy318; -yy312: - YYDEBUG(312, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 406 "Zend/zend_ini_scanner.l" - { /* Variable name */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace */ - EAT_TRAILING_WHITESPACE(); - - RETURN_TOKEN(TC_VARNAME, yytext, yyleng); -} -#line 4627 "Zend/zend_ini_scanner.c" -yy313: - YYDEBUG(313, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(314, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 4637 "Zend/zend_ini_scanner.c" -yy315: - YYDEBUG(315, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(316, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 416 "Zend/zend_ini_scanner.l" - { /* Variable end */ - yy_pop_state(TSRMLS_C); - return '}'; -} -#line 4648 "Zend/zend_ini_scanner.c" -yy317: - YYDEBUG(317, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy318: - YYDEBUG(318, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy317; - } - goto yy312; - } -} -#line 607 "Zend/zend_ini_scanner.l" - -} +/* Generated by re2c 0.13.5 */ +#line 1 "Zend/zend_ini_scanner.l" +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski | + | Jani Taskinen | + | Marcus Boerger | + | Nuno Lopes | + | Scott MacVicar | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include +#include "zend.h" +#include "zend_globals.h" +#include +#include "zend_ini_scanner.h" + +#if 0 +# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) +#else +# define YYDEBUG(s, c) +#endif + +#include "zend_ini_scanner_defs.h" + +#define YYCTYPE unsigned char +/* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD) + * so that if will be able to terminate to match the current token (e.g. non-enclosed string) */ +#define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; } +#define YYCURSOR SCNG(yy_cursor) +#define YYLIMIT SCNG(yy_limit) +#define YYMARKER SCNG(yy_marker) + +#define YYGETCONDITION() SCNG(yy_state) +#define YYSETCONDITION(s) SCNG(yy_state) = s + +#define STATE(name) yyc##name + +/* emulate flex constructs */ +#define BEGIN(state) YYSETCONDITION(STATE(state)) +#define YYSTATE YYGETCONDITION() +#define yytext ((char*)SCNG(yy_text)) +#define yyleng SCNG(yy_leng) +#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ + yyleng = (unsigned int)x; } while(0) + +/* #define yymore() goto yymore_restart */ + +/* perform sanity check. If this message is triggered you should + increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */ +#define YYMAXFILL 6 +#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1) +# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL +#endif + + +/* How it works (for the core ini directives): + * =========================================== + * + * 1. Scanner scans file for tokens and passes them to parser. + * 2. Parser parses the tokens and passes the name/value pairs to the callback + * function which stores them in the configuration hash table. + * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual + * registering of ini entries and uses zend_get_configuration_directive() + * to fetch the previously stored name/value pair from configuration hash table + * and registers the static ini entries which match the name to the value + * into EG(ini_directives) hash table. + * 4. PATH section entries are used per-request from down to top, each overriding + * previous if one exists. zend_alter_ini_entry() is called for each entry. + * Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the + * php_admin_* directives used within Apache httpd.conf when PHP is compiled as + * module for Apache. + * 5. User defined ini files (like .htaccess for apache) are parsed for each request and + * stored in separate hash defined by SAPI. + */ + +/* TODO: (ordered by importance :-) + * =============================================================================== + * + * - Separate constant lookup totally from plain strings (using CONSTANT pattern) + * - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators + * - Add #include "some.ini" + * - Allow variables to refer to options also when using parse_ini_file() + * + */ + +/* Globals Macros */ +#define SCNG INI_SCNG +#ifdef ZTS +ZEND_API ts_rsrc_id ini_scanner_globals_id; +#else +ZEND_API zend_ini_scanner_globals ini_scanner_globals; +#endif + +/* Eat leading whitespace */ +#define EAT_LEADING_WHITESPACE() \ + while (yytext[0]) { \ + if (yytext[0] == ' ' || yytext[0] == '\t') { \ + SCNG(yy_text)++; \ + yyleng--; \ + } else { \ + break; \ + } \ + } + +/* Eat trailing whitespace + extra char */ +#define EAT_TRAILING_WHITESPACE_EX(ch) \ + while (yyleng > 0 && ( \ + (ch != 'X' && yytext[yyleng - 1] == ch) || \ + yytext[yyleng - 1] == '\n' || \ + yytext[yyleng - 1] == '\r' || \ + yytext[yyleng - 1] == '\t' || \ + yytext[yyleng - 1] == ' ') \ + ) { \ + yyleng--; \ + } + +/* Eat trailing whitespace */ +#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') + +#define zend_ini_copy_value(retval, str, len) { \ + Z_STRVAL_P(retval) = zend_strndup(str, len); \ + Z_STRLEN_P(retval) = len; \ + Z_TYPE_P(retval) = IS_STRING; \ +} + +#define RETURN_TOKEN(type, str, len) { \ + zend_ini_copy_value(ini_lval, str, len); \ + return type; \ +} + +static void _yy_push_state(int new_state TSRMLS_DC) +{ + zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int)); + YYSETCONDITION(new_state); +} + +#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm) + +static void yy_pop_state(TSRMLS_D) +{ + int *stack_state; + zend_stack_top(&SCNG(state_stack), (void **) &stack_state); + YYSETCONDITION(*stack_state); + zend_stack_del_top(&SCNG(state_stack)); +} + +static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) +{ + YYCURSOR = (YYCTYPE*)str; + SCNG(yy_start) = YYCURSOR; + YYLIMIT = YYCURSOR + len; +} + +#define ini_filename SCNG(filename) + +/* {{{ init_ini_scanner() +*/ +static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) +{ + /* Sanity check */ + if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { + zend_error(E_WARNING, "Invalid scanner mode"); + return FAILURE; + } + + SCNG(lineno) = 1; + SCNG(scanner_mode) = scanner_mode; + SCNG(yy_in) = fh; + + if (fh != NULL) { + ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + } else { + ini_filename = NULL; + } + + zend_stack_init(&SCNG(state_stack)); + BEGIN(INITIAL); + + return SUCCESS; +} +/* }}} */ + +/* {{{ shutdown_ini_scanner() +*/ +void shutdown_ini_scanner(TSRMLS_D) +{ + zend_stack_destroy(&SCNG(state_stack)); + if (ini_filename) { + free(ini_filename); + } +} +/* }}} */ + +/* {{{ zend_ini_scanner_get_lineno() +*/ +int zend_ini_scanner_get_lineno(TSRMLS_D) +{ + return SCNG(lineno); +} +/* }}} */ + +/* {{{ zend_ini_scanner_get_filename() +*/ +char *zend_ini_scanner_get_filename(TSRMLS_D) +{ + return ini_filename ? ini_filename : "Unknown"; +} +/* }}} */ + +/* {{{ zend_ini_open_file_for_scanning() +*/ +int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC) +{ + char *buf; + size_t size; + + if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { + return FAILURE; + } + + if (init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE) { + zend_file_handle_dtor(fh TSRMLS_CC); + return FAILURE; + } + + yy_scan_buffer(buf, size TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ zend_ini_prepare_string_for_scanning() +*/ +int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) +{ + int len = strlen(str); + + if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { + return FAILURE; + } + + yy_scan_buffer(str, len TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ zend_ini_escape_string() + */ +static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC) +{ + register char *s, *t; + char *end; + + zend_ini_copy_value(lval, str, len); + + /* convert escape sequences */ + s = t = Z_STRVAL_P(lval); + end = s + Z_STRLEN_P(lval); + + while (s < end) { + if (*s == '\\') { + s++; + if (s >= end) { + *t++ = '\\'; + continue; + } + switch (*s) { + case '"': + if (*s != quote_type) { + *t++ = '\\'; + *t++ = *s; + break; + } + case '\\': + case '$': + *t++ = *s; + Z_STRLEN_P(lval)--; + break; + default: + *t++ = '\\'; + *t++ = *s; + break; + } + } else { + *t++ = *s; + } + if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { + SCNG(lineno)++; + } + s++; + } + *t = 0; +} +/* }}} */ + +int ini_lex(zval *ini_lval TSRMLS_DC) +{ +restart: + SCNG(yy_text) = YYCURSOR; + +/* yymore_restart: */ + /* detect EOF */ + if (YYCURSOR >= YYLIMIT) { + if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) { + BEGIN(INITIAL); + return END_OF_LINE; + } + return 0; + } + + /* Eat any UTF-8 BOM we find in the first 3 bytes */ + if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) { + if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) { + YYCURSOR += 3; + goto restart; + } + } + +#line 337 "Zend/zend_ini_scanner.c" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if (YYGETCONDITION() < 4) { + if (YYGETCONDITION() < 2) { + if (YYGETCONDITION() < 1) { + goto yyc_INITIAL; + } else { + goto yyc_ST_OFFSET; + } + } else { + if (YYGETCONDITION() < 3) { + goto yyc_ST_SECTION_VALUE; + } else { + goto yyc_ST_VALUE; + } + } + } else { + if (YYGETCONDITION() < 6) { + if (YYGETCONDITION() < 5) { + goto yyc_ST_SECTION_RAW; + } else { + goto yyc_ST_DOUBLE_QUOTES; + } + } else { + if (YYGETCONDITION() < 7) { + goto yyc_ST_VARNAME; + } else { + goto yyc_ST_RAW; + } + } + } +/* *********************************** */ +yyc_INITIAL: + { + static const unsigned char yybm[] = { + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 160, 0, 144, 144, 0, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 240, 128, 128, 144, 128, 144, 128, 144, + 128, 128, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 144, 128, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 144, 144, 128, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 128, 128, 128, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + }; + + YYDEBUG(0, *YYCURSOR); + YYFILL(5); + yych = *YYCURSOR; + YYDEBUG(-1, yych); + switch (yych) { + case '\t': goto yy4; + case '\n': goto yy6; + case '\r': goto yy8; + case ' ': goto yy9; + case '!': + case '"': + case '$': + case '&': + case '(': + case ')': + case '^': + case '{': + case '|': + case '}': + case '~': goto yy10; + case '#': goto yy12; + case '%': + case '\'': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ':': + case '<': + case '>': + case '?': + case '@': + case ']': goto yy13; + case ';': goto yy14; + case '=': goto yy16; + case 'F': + case 'f': goto yy18; + case 'N': + case 'n': goto yy19; + case 'O': + case 'o': goto yy20; + case 'T': + case 't': goto yy21; + case 'Y': + case 'y': goto yy22; + case '[': goto yy23; + default: goto yy2; + } +yy2: + YYDEBUG(2, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy26; +yy3: + YYDEBUG(3, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 429 "Zend/zend_ini_scanner.l" + { /* Get option name */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace */ + EAT_TRAILING_WHITESPACE(); + + RETURN_TOKEN(TC_LABEL, yytext, yyleng); +} +#line 476 "Zend/zend_ini_scanner.c" +yy4: + YYDEBUG(4, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy68; +yy5: + YYDEBUG(5, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 575 "Zend/zend_ini_scanner.l" + { + /* eat whitespace */ + goto restart; +} +#line 490 "Zend/zend_ini_scanner.c" +yy6: + YYDEBUG(6, *YYCURSOR); + ++YYCURSOR; +yy7: + YYDEBUG(7, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 580 "Zend/zend_ini_scanner.l" + { + SCNG(lineno)++; + return END_OF_LINE; +} +#line 502 "Zend/zend_ini_scanner.c" +yy8: + YYDEBUG(8, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy71; + goto yy7; +yy9: + YYDEBUG(9, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy26; + if (yych <= '\t') goto yy67; + goto yy71; + } else { + if (yych == '\r') goto yy72; + if (yych <= 0x1F) goto yy26; + goto yy69; + } + } else { + if (yych <= ':') { + if (yych == '#') goto yy58; + goto yy26; + } else { + if (yych <= ';') goto yy53; + if (yych == '=') goto yy51; + goto yy26; + } + } +yy10: + YYDEBUG(10, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(11, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 503 "Zend/zend_ini_scanner.l" + { /* Disallow these chars outside option values */ + return yytext[0]; +} +#line 541 "Zend/zend_ini_scanner.c" +yy12: + YYDEBUG(12, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy59; +yy13: + YYDEBUG(13, *YYCURSOR); + yych = *++YYCURSOR; + goto yy26; +yy14: + YYDEBUG(14, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + goto yy54; + YYDEBUG(15, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 562 "Zend/zend_ini_scanner.c" +yy16: + YYDEBUG(16, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy52; +yy17: + YYDEBUG(17, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 439 "Zend/zend_ini_scanner.l" + { /* Start option value */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_RAW TSRMLS_CC); + } else { + yy_push_state(ST_VALUE TSRMLS_CC); + } + return '='; +} +#line 580 "Zend/zend_ini_scanner.c" +yy18: + YYDEBUG(18, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy48; + if (yych == 'a') goto yy48; + goto yy26; +yy19: + YYDEBUG(19, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= 'U') { + if (yych == 'O') goto yy44; + if (yych <= 'T') goto yy26; + goto yy45; + } else { + if (yych <= 'o') { + if (yych <= 'n') goto yy26; + goto yy44; + } else { + if (yych == 'u') goto yy45; + goto yy26; + } + } +yy20: + YYDEBUG(20, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= 'N') { + if (yych == 'F') goto yy38; + if (yych <= 'M') goto yy26; + goto yy31; + } else { + if (yych <= 'f') { + if (yych <= 'e') goto yy26; + goto yy38; + } else { + if (yych == 'n') goto yy31; + goto yy26; + } + } +yy21: + YYDEBUG(21, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'R') goto yy36; + if (yych == 'r') goto yy36; + goto yy26; +yy22: + YYDEBUG(22, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy27; + if (yych == 'e') goto yy27; + goto yy26; +yy23: + YYDEBUG(23, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(24, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 358 "Zend/zend_ini_scanner.l" + { /* Section start */ + /* Enter section data lookup state */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_SECTION_RAW TSRMLS_CC); + } else { + yy_push_state(ST_SECTION_VALUE TSRMLS_CC); + } + return TC_SECTION; +} +#line 646 "Zend/zend_ini_scanner.c" +yy25: + YYDEBUG(25, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy26: + YYDEBUG(26, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy25; + } + if (yych == '[') goto yy28; + goto yy3; +yy27: + YYDEBUG(27, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy31; + if (yych == 's') goto yy31; + goto yy26; +yy28: + YYDEBUG(28, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(29, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy28; + } + YYDEBUG(30, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 383 "Zend/zend_ini_scanner.l" + { /* Start of option with offset */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace and [ */ + EAT_TRAILING_WHITESPACE_EX('['); + + /* Enter offset lookup state */ + yy_push_state(ST_OFFSET TSRMLS_CC); + + RETURN_TOKEN(TC_OFFSET, yytext, yyleng); +} +#line 689 "Zend/zend_ini_scanner.c" +yy31: + YYDEBUG(31, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(32, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy31; + } + if (yych <= '\'') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy34; + } else { + if (yych != '\r') goto yy25; + } + } else { + if (yych <= '$') { + if (yych == '#') goto yy25; + } else { + if (yych != '&') goto yy25; + } + } + } else { + if (yych <= 'Z') { + if (yych <= ';') { + if (yych <= ')') goto yy33; + if (yych <= ':') goto yy25; + } else { + if (yych != '=') goto yy25; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy28; + if (yych <= ']') goto yy25; + } else { + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } + } +yy33: + YYDEBUG(33, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 421 "Zend/zend_ini_scanner.l" + { /* TRUE value (when used outside option value/offset this causes parse error!) */ + RETURN_TOKEN(BOOL_TRUE, "1", 1); +} +#line 739 "Zend/zend_ini_scanner.c" +yy34: + YYDEBUG(34, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(35, *YYCURSOR); + if (yych == '\t') goto yy34; + if (yych == ' ') goto yy34; + goto yy33; +yy36: + YYDEBUG(36, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'U') goto yy37; + if (yych != 'u') goto yy26; +yy37: + YYDEBUG(37, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy31; + if (yych == 'e') goto yy31; + goto yy26; +yy38: + YYDEBUG(38, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'F') goto yy39; + if (yych != 'f') goto yy26; +yy39: + YYDEBUG(39, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(40, *YYCURSOR); + if (yych <= '&') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy42; + } else { + if (yych != '\r') goto yy25; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy39; + if (yych >= '#') goto yy25; + } else { + if (yych == '%') goto yy25; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '\'') goto yy25; + if (yych >= '*') goto yy25; + } else { + if (yych == '<') goto yy25; + } + } else { + if (yych <= ']') { + if (yych == '[') goto yy28; + goto yy25; + } else { + if (yych <= '^') goto yy41; + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } + } +yy41: + YYDEBUG(41, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 425 "Zend/zend_ini_scanner.l" + { /* FALSE value (when used outside option value/offset this causes parse error!)*/ + RETURN_TOKEN(BOOL_FALSE, "", 0); +} +#line 813 "Zend/zend_ini_scanner.c" +yy42: + YYDEBUG(42, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(43, *YYCURSOR); + if (yych == '\t') goto yy42; + if (yych == ' ') goto yy42; + goto yy41; +yy44: + YYDEBUG(44, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\'') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy26; + if (yych <= '\t') goto yy42; + goto yy41; + } else { + if (yych == '\r') goto yy41; + goto yy26; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy39; + if (yych <= '"') goto yy41; + goto yy26; + } else { + if (yych == '%') goto yy26; + if (yych <= '&') goto yy41; + goto yy26; + } + } + } else { + if (yych <= 'N') { + if (yych <= ';') { + if (yych <= ')') goto yy41; + if (yych <= ':') goto yy26; + goto yy41; + } else { + if (yych == '=') goto yy41; + if (yych <= 'M') goto yy26; + goto yy47; + } + } else { + if (yych <= 'm') { + if (yych == '^') goto yy41; + goto yy26; + } else { + if (yych <= 'n') goto yy47; + if (yych <= 'z') goto yy26; + if (yych <= '~') goto yy41; + goto yy26; + } + } + } +yy45: + YYDEBUG(45, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy46; + if (yych != 'l') goto yy26; +yy46: + YYDEBUG(46, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy39; + if (yych == 'l') goto yy39; + goto yy26; +yy47: + YYDEBUG(47, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy39; + if (yych == 'e') goto yy39; + goto yy26; +yy48: + YYDEBUG(48, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy49; + if (yych != 'l') goto yy26; +yy49: + YYDEBUG(49, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy50; + if (yych != 's') goto yy26; +yy50: + YYDEBUG(50, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy39; + if (yych == 'e') goto yy39; + goto yy26; +yy51: + YYDEBUG(51, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy52: + YYDEBUG(52, *YYCURSOR); + if (yych == '\t') goto yy51; + if (yych == ' ') goto yy51; + goto yy17; +yy53: + YYDEBUG(53, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy54: + YYDEBUG(54, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy53; + } + if (yych >= '\r') goto yy57; +yy55: + YYDEBUG(55, *YYCURSOR); + ++YYCURSOR; +yy56: + YYDEBUG(56, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 936 "Zend/zend_ini_scanner.c" +yy57: + YYDEBUG(57, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy55; + goto yy56; +yy58: + YYDEBUG(58, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy59: + YYDEBUG(59, *YYCURSOR); + if (yych <= '\'') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy58; + if (yych >= '\n') goto yy64; + } else { + if (yych == '\r') goto yy66; + goto yy58; + } + } else { + if (yych <= '$') { + if (yych == '#') goto yy58; + } else { + if (yych != '&') goto yy58; + } + } + } else { + if (yych <= 'Z') { + if (yych <= ';') { + if (yych <= ')') goto yy60; + if (yych <= ':') goto yy58; + } else { + if (yych != '=') goto yy58; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy62; + if (yych <= ']') goto yy58; + } else { + if (yych <= 'z') goto yy58; + if (yych >= 0x7F) goto yy58; + } + } + } +yy60: + YYDEBUG(60, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(61, *YYCURSOR); + if (yych == '\n') goto yy64; + if (yych == '\r') goto yy66; + goto yy60; +yy62: + YYDEBUG(62, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(63, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy60; + if (yych <= '\t') goto yy62; + if (yych >= '\v') goto yy60; + } else { + if (yych <= '\r') goto yy66; + if (yych == ' ') goto yy62; + goto yy60; + } +yy64: + YYDEBUG(64, *YYCURSOR); + ++YYCURSOR; +yy65: + YYDEBUG(65, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 591 "Zend/zend_ini_scanner.l" + { /* #Comment */ + zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno)); + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 1022 "Zend/zend_ini_scanner.c" +yy66: + YYDEBUG(66, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy64; + goto yy65; +yy67: + YYDEBUG(67, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy68: + YYDEBUG(68, *YYCURSOR); + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy5; + if (yych <= '\t') goto yy67; + goto yy71; + } else { + if (yych == '\r') goto yy72; + if (yych <= 0x1F) goto yy5; + goto yy67; + } + } else { + if (yych <= ':') { + if (yych == '#') goto yy60; + goto yy5; + } else { + if (yych <= ';') goto yy53; + if (yych == '=') goto yy51; + goto yy5; + } + } +yy69: + YYDEBUG(69, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(70, *YYCURSOR); + if (yych <= '&') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy67; + } else { + if (yych == '\r') goto yy72; + goto yy25; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy69; + if (yych <= '"') goto yy3; + goto yy58; + } else { + if (yych == '%') goto yy25; + goto yy3; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '\'') goto yy25; + if (yych <= ')') goto yy3; + goto yy25; + } else { + if (yych <= ';') goto yy53; + if (yych <= '<') goto yy25; + goto yy51; + } + } else { + if (yych <= ']') { + if (yych == '[') goto yy28; + goto yy25; + } else { + if (yych <= '^') goto yy3; + if (yych <= 'z') goto yy25; + if (yych <= '~') goto yy3; + goto yy25; + } + } + } +yy71: + YYDEBUG(71, *YYCURSOR); + yych = *++YYCURSOR; + goto yy7; +yy72: + YYDEBUG(72, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy71; + goto yy7; + } +/* *********************************** */ +yyc_ST_DOUBLE_QUOTES: + { + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + YYDEBUG(73, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych == '"') goto yy77; + if (yych == '$') goto yy79; + YYDEBUG(75, *YYCURSOR); + ++YYCURSOR; +yy76: + YYDEBUG(76, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 535 "Zend/zend_ini_scanner.l" + { /* Escape double quoted string contents */ + if (YYCURSOR > YYLIMIT) { + return 0; + } + + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR++) { + case '"': + if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { + continue; + } + break; + case '$': + if (*YYCURSOR == '{') { + break; + } + continue; + case '\\': + if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { + YYCURSOR++; + } + /* fall through */ + default: + continue; + } + + YYCURSOR--; + break; + } + + yyleng = YYCURSOR - SCNG(yy_text); + + zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); + return TC_QUOTED_STRING; +} +#line 1198 "Zend/zend_ini_scanner.c" +yy77: + YYDEBUG(77, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy83; +yy78: + YYDEBUG(78, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 530 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string ends */ + yy_pop_state(TSRMLS_C); + return '"'; +} +#line 1212 "Zend/zend_ini_scanner.c" +yy79: + YYDEBUG(79, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '{') goto yy76; + YYDEBUG(80, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(81, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 1226 "Zend/zend_ini_scanner.c" +yy82: + YYDEBUG(82, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy83: + YYDEBUG(83, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy82; + } + goto yy78; + } +/* *********************************** */ +yyc_ST_OFFSET: + { + static const unsigned char yybm[] = { + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 194, 64, 66, 66, 64, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 194, 66, 64, 66, 68, 66, 66, 0, + 66, 66, 66, 66, 66, 66, 66, 66, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 66, 64, 66, 66, 66, 66, + 66, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 66, 72, 64, 66, 82, + 66, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + }; + YYDEBUG(84, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy86; + if (yych <= '\t') goto yy88; + goto yy89; + } else { + if (yych == '\r') goto yy89; + if (yych >= ' ') goto yy88; + } + } else { + if (yych <= '$') { + if (yych == '"') goto yy91; + if (yych >= '$') goto yy93; + } else { + if (yych == '\'') goto yy94; + if (yych >= '-') goto yy95; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '.') goto yy96; + if (yych >= '0') goto yy97; + } else { + if (yych == ';') goto yy89; + if (yych >= 'A') goto yy99; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy86; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy102; + } else { + if (yych == '`') goto yy86; + if (yych <= 'z') goto yy99; + } + } + } +yy86: + YYDEBUG(86, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy105; +yy87: + YYDEBUG(87, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 521 "Zend/zend_ini_scanner.l" + { /* Get rest as section/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 1330 "Zend/zend_ini_scanner.c" +yy88: + YYDEBUG(88, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy131; + } + if (yych == '"') goto yy133; + if (yych == ']') goto yy134; + goto yy105; +yy89: + YYDEBUG(89, *YYCURSOR); + ++YYCURSOR; +yy90: + YYDEBUG(90, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 1351 "Zend/zend_ini_scanner.c" +yy91: + YYDEBUG(91, *YYCURSOR); + ++YYCURSOR; +yy92: + YYDEBUG(92, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 1363 "Zend/zend_ini_scanner.c" +yy93: + YYDEBUG(93, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy90; + if (yych <= '[') goto yy104; + goto yy109; + } else { + if (yych == '{') goto yy129; + goto yy104; + } +yy94: + YYDEBUG(94, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy125; + } + goto yy90; +yy95: + YYDEBUG(95, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy123; + goto yy105; +yy96: + YYDEBUG(96, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy121; + goto yy105; +yy97: + YYDEBUG(97, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\'') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy105; + } else { + if (yych == '"') goto yy98; + if (yych <= '&') goto yy105; + } + } else { + if (yych <= '9') { + if (yych == '.') goto yy117; + if (yych <= '/') goto yy105; + goto yy119; + } else { + if (yych <= ';') { + if (yych <= ':') goto yy105; + } else { + if (yych != ']') goto yy105; + } + } + } +yy98: + YYDEBUG(98, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 1429 "Zend/zend_ini_scanner.c" +yy99: + YYDEBUG(99, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy115; + } + if (yych <= '"') { + if (yych <= '\f') { + if (yych != '\n') goto yy105; + } else { + if (yych <= '\r') goto yy100; + if (yych <= '!') goto yy105; + } + } else { + if (yych <= ':') { + if (yych != '\'') goto yy105; + } else { + if (yych <= ';') goto yy100; + if (yych != ']') goto yy105; + } + } +yy100: + YYDEBUG(100, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 1459 "Zend/zend_ini_scanner.c" +yy101: + YYDEBUG(101, *YYCURSOR); + yych = *++YYCURSOR; + goto yy104; +yy102: + YYDEBUG(102, *YYCURSOR); + ++YYCURSOR; +yy103: + YYDEBUG(103, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 396 "Zend/zend_ini_scanner.l" + { /* End of section or an option offset */ + BEGIN(INITIAL); + return ']'; +} +#line 1475 "Zend/zend_ini_scanner.c" +yy104: + YYDEBUG(104, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy105: + YYDEBUG(105, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy104; + } + if (yych == '$') goto yy107; + if (yych != '\\') goto yy87; +yy106: + YYDEBUG(106, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + goto yy104; +yy107: + YYDEBUG(107, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy108; + if (yych <= '[') goto yy104; + goto yy109; + } else { + if (yych != '{') goto yy104; + } +yy108: + YYDEBUG(108, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy87; + } else { + goto yy90; + } + } else { + if (yyaccept <= 2) { + goto yy98; + } else { + goto yy100; + } + } +yy109: + YYDEBUG(109, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy110: + YYDEBUG(110, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(111, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy114; + goto yy104; +yy112: + YYDEBUG(112, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(113, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy114: + YYDEBUG(114, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy115: + YYDEBUG(115, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(116, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy115; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy100; + if (yych <= '\f') goto yy104; + goto yy100; + } else { + if (yych == '"') goto yy100; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy100; + if (yych <= ':') goto yy104; + goto yy100; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy100; + goto yy104; + } + } +yy117: + YYDEBUG(117, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(118, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy117; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych == '"') goto yy98; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy98; + if (yych <= ':') goto yy104; + goto yy98; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } +yy119: + YYDEBUG(119, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(120, *YYCURSOR); + if (yych <= '\'') { + if (yych <= '!') { + if (yych <= '\n') { + if (yych <= '\t') goto yy104; + goto yy98; + } else { + if (yych == '\r') goto yy98; + goto yy104; + } + } else { + if (yych <= '#') { + if (yych <= '"') goto yy98; + goto yy104; + } else { + if (yych <= '$') goto yy107; + if (yych <= '&') goto yy104; + goto yy98; + } + } + } else { + if (yych <= ':') { + if (yych <= '.') { + if (yych <= '-') goto yy104; + goto yy117; + } else { + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy119; + goto yy104; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy121: + YYDEBUG(121, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(122, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy104; + goto yy98; + } else { + if (yych == '$') goto yy107; + goto yy104; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy98; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy121; + goto yy104; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy123: + YYDEBUG(123, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(124, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy104; + goto yy98; + } else { + if (yych == '$') goto yy107; + goto yy104; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy98; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy123; + goto yy104; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy125: + YYDEBUG(125, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(126, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy125; + } + YYDEBUG(127, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(128, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 1774 "Zend/zend_ini_scanner.c" +yy129: + YYDEBUG(129, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(130, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 1785 "Zend/zend_ini_scanner.c" +yy131: + YYDEBUG(131, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(132, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy131; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy87; + if (yych <= '\f') goto yy104; + goto yy87; + } else { + if (yych == '"') goto yy133; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy87; + if (yych <= ':') goto yy104; + goto yy87; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy134; + goto yy104; + } + } +yy133: + YYDEBUG(133, *YYCURSOR); + yych = *++YYCURSOR; + goto yy92; +yy134: + YYDEBUG(134, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy103; + } +/* *********************************** */ +yyc_ST_RAW: + { + static const unsigned char yybm[] = { + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 192, 0, 64, 64, 0, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; + YYDEBUG(135, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy139; + } else { + if (yych <= '\t') goto yy141; + if (yych <= '\n') goto yy142; + goto yy139; + } + } else { + if (yych <= ' ') { + if (yych <= '\r') goto yy144; + if (yych <= 0x1F) goto yy139; + goto yy141; + } else { + if (yych == ';') goto yy145; + goto yy139; + } + } + YYDEBUG(137, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(138, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 598 "Zend/zend_ini_scanner.l" + { /* End of option value (if EOF is reached before EOL */ + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 1895 "Zend/zend_ini_scanner.c" +yy139: + YYDEBUG(139, *YYCURSOR); + ++YYCURSOR; +yy140: + YYDEBUG(140, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 448 "Zend/zend_ini_scanner.l" + { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + char *sc = NULL; + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR) { + case '\n': + case '\r': + goto end_raw_value_chars; + break; + case ';': + if (sc == NULL) { + sc = YYCURSOR; + } + /* no break */ + default: + YYCURSOR++; + break; + } + } +end_raw_value_chars: + yyleng = YYCURSOR - SCNG(yy_text); + + /* Eat trailing semicolons */ + while (yytext[yyleng - 1] == ';') { + yyleng--; + } + + /* Eat leading and trailing double quotes */ + if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } else if (sc) { + YYCURSOR = sc; + yyleng = YYCURSOR - SCNG(yy_text); + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 1939 "Zend/zend_ini_scanner.c" +yy141: + YYDEBUG(141, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\r') { + if (yych <= 0x08) goto yy140; + if (yych <= '\n') goto yy153; + if (yych <= '\f') goto yy140; + goto yy153; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy140; + goto yy153; + } else { + if (yych == ';') goto yy153; + goto yy140; + } + } +yy142: + YYDEBUG(142, *YYCURSOR); + ++YYCURSOR; +yy143: + YYDEBUG(143, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 489 "Zend/zend_ini_scanner.l" + { /* End of option value */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 1970 "Zend/zend_ini_scanner.c" +yy144: + YYDEBUG(144, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy151; + goto yy143; +yy145: + YYDEBUG(145, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy147; +yy146: + YYDEBUG(146, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy147: + YYDEBUG(147, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy146; + } + if (yych >= '\r') goto yy150; +yy148: + YYDEBUG(148, *YYCURSOR); + ++YYCURSOR; +yy149: + YYDEBUG(149, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 2004 "Zend/zend_ini_scanner.c" +yy150: + YYDEBUG(150, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy148; + goto yy149; +yy151: + YYDEBUG(151, *YYCURSOR); + yych = *++YYCURSOR; + goto yy143; +yy152: + YYDEBUG(152, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy153: + YYDEBUG(153, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy152; + } + if (yych <= '\f') { + if (yych == '\n') goto yy151; + } else { + if (yych <= '\r') goto yy155; + if (yych == ';') goto yy146; + } + YYDEBUG(154, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 575 "Zend/zend_ini_scanner.l" + { + /* eat whitespace */ + goto restart; +} +#line 2038 "Zend/zend_ini_scanner.c" +yy155: + YYDEBUG(155, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy151; + goto yy143; + } +/* *********************************** */ +yyc_ST_SECTION_RAW: + { + static const unsigned char yybm[] = { + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 192, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 192, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + YYDEBUG(156, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '\f') { + if (yych == '\n') goto yy160; + } else { + if (yych <= '\r') goto yy160; + if (yych == ']') goto yy162; + } + YYDEBUG(158, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy169; +yy159: + YYDEBUG(159, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 485 "Zend/zend_ini_scanner.l" + { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 2102 "Zend/zend_ini_scanner.c" +yy160: + YYDEBUG(160, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(161, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 2112 "Zend/zend_ini_scanner.c" +yy162: + YYDEBUG(162, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy165; +yy163: + YYDEBUG(163, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 377 "Zend/zend_ini_scanner.l" + { /* End of section */ + BEGIN(INITIAL); + SCNG(lineno)++; + return ']'; +} +#line 2127 "Zend/zend_ini_scanner.c" +yy164: + YYDEBUG(164, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy165: + YYDEBUG(165, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy164; + } + if (yych == '\n') goto yy166; + if (yych == '\r') goto yy167; + goto yy163; +yy166: + YYDEBUG(166, *YYCURSOR); + yych = *++YYCURSOR; + goto yy163; +yy167: + YYDEBUG(167, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy166; + goto yy163; +yy168: + YYDEBUG(168, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy169: + YYDEBUG(169, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy168; + } + goto yy159; + } +/* *********************************** */ +yyc_ST_SECTION_VALUE: + { + static const unsigned char yybm[] = { + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 134, 128, 132, 132, 128, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 134, 132, 128, 132, 136, 132, 132, 0, + 132, 132, 132, 132, 132, 132, 132, 132, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 132, 128, 132, 132, 132, 132, + 132, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 132, 144, 128, 132, 164, + 132, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + }; + YYDEBUG(170, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy172; + if (yych <= '\t') goto yy174; + goto yy175; + } else { + if (yych == '\r') goto yy175; + if (yych >= ' ') goto yy174; + } + } else { + if (yych <= '$') { + if (yych == '"') goto yy177; + if (yych >= '$') goto yy179; + } else { + if (yych == '\'') goto yy180; + if (yych >= '-') goto yy181; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '.') goto yy182; + if (yych >= '0') goto yy183; + } else { + if (yych == ';') goto yy175; + if (yych >= 'A') goto yy185; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy172; + if (yych <= '\\') goto yy187; + if (yych <= ']') goto yy188; + } else { + if (yych == '`') goto yy172; + if (yych <= 'z') goto yy185; + } + } + } +yy172: + YYDEBUG(172, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy195; +yy173: + YYDEBUG(173, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 521 "Zend/zend_ini_scanner.l" + { /* Get rest as section/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 2253 "Zend/zend_ini_scanner.c" +yy174: + YYDEBUG(174, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x1F) { + if (yych == '\t') goto yy221; + goto yy195; + } else { + if (yych <= ' ') goto yy221; + if (yych == '"') goto yy223; + goto yy195; + } +yy175: + YYDEBUG(175, *YYCURSOR); + ++YYCURSOR; +yy176: + YYDEBUG(176, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 2276 "Zend/zend_ini_scanner.c" +yy177: + YYDEBUG(177, *YYCURSOR); + ++YYCURSOR; +yy178: + YYDEBUG(178, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 2288 "Zend/zend_ini_scanner.c" +yy179: + YYDEBUG(179, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy176; + if (yych <= '[') goto yy194; + goto yy199; + } else { + if (yych == '{') goto yy219; + goto yy194; + } +yy180: + YYDEBUG(180, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy215; + } + goto yy176; +yy181: + YYDEBUG(181, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy195; + if (yych <= '9') goto yy213; + goto yy195; +yy182: + YYDEBUG(182, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy195; + if (yych <= '9') goto yy211; + goto yy195; +yy183: + YYDEBUG(183, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\'') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy195; + } else { + if (yych == '"') goto yy184; + if (yych <= '&') goto yy195; + } + } else { + if (yych <= '9') { + if (yych == '.') goto yy207; + if (yych <= '/') goto yy195; + goto yy209; + } else { + if (yych <= ';') { + if (yych <= ':') goto yy195; + } else { + if (yych != ']') goto yy195; + } + } + } +yy184: + YYDEBUG(184, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 2354 "Zend/zend_ini_scanner.c" +yy185: + YYDEBUG(185, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy205; + } + if (yych <= '"') { + if (yych <= '\f') { + if (yych != '\n') goto yy195; + } else { + if (yych <= '\r') goto yy186; + if (yych <= '!') goto yy195; + } + } else { + if (yych <= ':') { + if (yych != '\'') goto yy195; + } else { + if (yych <= ';') goto yy186; + if (yych != ']') goto yy195; + } + } +yy186: + YYDEBUG(186, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 2384 "Zend/zend_ini_scanner.c" +yy187: + YYDEBUG(187, *YYCURSOR); + yych = *++YYCURSOR; + goto yy194; +yy188: + YYDEBUG(188, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy191; +yy189: + YYDEBUG(189, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 377 "Zend/zend_ini_scanner.l" + { /* End of section */ + BEGIN(INITIAL); + SCNG(lineno)++; + return ']'; +} +#line 2403 "Zend/zend_ini_scanner.c" +yy190: + YYDEBUG(190, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy191: + YYDEBUG(191, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy190; + } + if (yych == '\n') goto yy192; + if (yych == '\r') goto yy193; + goto yy189; +yy192: + YYDEBUG(192, *YYCURSOR); + yych = *++YYCURSOR; + goto yy189; +yy193: + YYDEBUG(193, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy192; + goto yy189; +yy194: + YYDEBUG(194, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy195: + YYDEBUG(195, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy194; + } + if (yych == '$') goto yy197; + if (yych != '\\') goto yy173; +yy196: + YYDEBUG(196, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + goto yy194; +yy197: + YYDEBUG(197, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy198; + if (yych <= '[') goto yy194; + goto yy199; + } else { + if (yych != '{') goto yy194; + } +yy198: + YYDEBUG(198, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy173; + } else { + goto yy176; + } + } else { + if (yyaccept <= 2) { + goto yy184; + } else { + goto yy186; + } + } +yy199: + YYDEBUG(199, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy200: + YYDEBUG(200, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(201, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy204; + goto yy194; +yy202: + YYDEBUG(202, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(203, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy204: + YYDEBUG(204, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy205: + YYDEBUG(205, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(206, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy205; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy186; + if (yych <= '\f') goto yy194; + goto yy186; + } else { + if (yych == '"') goto yy186; + if (yych <= '#') goto yy194; + goto yy197; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy186; + if (yych <= ':') goto yy194; + goto yy186; + } else { + if (yych <= '[') goto yy194; + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy186; + goto yy194; + } + } +yy207: + YYDEBUG(207, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(208, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy207; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych == '"') goto yy184; + if (yych <= '#') goto yy194; + goto yy197; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy184; + if (yych <= ':') goto yy194; + goto yy184; + } else { + if (yych <= '[') goto yy194; + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } +yy209: + YYDEBUG(209, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(210, *YYCURSOR); + if (yych <= '\'') { + if (yych <= '!') { + if (yych <= '\n') { + if (yych <= '\t') goto yy194; + goto yy184; + } else { + if (yych == '\r') goto yy184; + goto yy194; + } + } else { + if (yych <= '#') { + if (yych <= '"') goto yy184; + goto yy194; + } else { + if (yych <= '$') goto yy197; + if (yych <= '&') goto yy194; + goto yy184; + } + } + } else { + if (yych <= ':') { + if (yych <= '.') { + if (yych <= '-') goto yy194; + goto yy207; + } else { + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy209; + goto yy194; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy211: + YYDEBUG(211, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(212, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy194; + goto yy184; + } else { + if (yych == '$') goto yy197; + goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy184; + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy211; + goto yy194; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy213: + YYDEBUG(213, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(214, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy194; + goto yy184; + } else { + if (yych == '$') goto yy197; + goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy184; + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy213; + goto yy194; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy215: + YYDEBUG(215, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(216, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy215; + } + YYDEBUG(217, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(218, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 2724 "Zend/zend_ini_scanner.c" +yy219: + YYDEBUG(219, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(220, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 2735 "Zend/zend_ini_scanner.c" +yy221: + YYDEBUG(221, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(222, *YYCURSOR); + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy194; + if (yych <= '\t') goto yy221; + if (yych <= '\n') goto yy173; + goto yy194; + } else { + if (yych <= 0x1F) { + if (yych <= '\r') goto yy173; + goto yy194; + } else { + if (yych <= ' ') goto yy221; + if (yych <= '!') goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '$') { + if (yych <= '#') goto yy194; + goto yy197; + } else { + if (yych == '\'') goto yy173; + goto yy194; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy173; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy173; + goto yy194; + } + } + } +yy223: + YYDEBUG(223, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy178; + } +/* *********************************** */ +yyc_ST_VALUE: + { + static const unsigned char yybm[] = { + 160, 162, 162, 162, 162, 162, 162, 162, + 162, 176, 128, 162, 162, 128, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 176, 160, 160, 162, 168, 162, 160, 32, + 160, 160, 162, 162, 162, 162, 162, 162, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 162, 160, 162, 160, 162, 162, + 162, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 162, 162, 162, 160, 166, + 162, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 162, 160, 162, 160, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + }; + YYDEBUG(224, *YYCURSOR); + YYFILL(6); + yych = *YYCURSOR; + YYDEBUG(-1, yych); + switch (yych) { + case 0x00: goto yy226; + case '\t': + case ' ': goto yy230; + case '\n': goto yy232; + case '\r': goto yy234; + case '!': + case '&': + case '(': + case ')': + case '^': + case '|': + case '~': goto yy235; + case '"': goto yy237; + case '$': goto yy239; + case '\'': goto yy240; + case '-': goto yy241; + case '.': goto yy242; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy243; + case ';': goto yy245; + case '=': goto yy246; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Z': + case '_': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'p': + case 'q': + case 'r': + case 's': + case 'u': + case 'v': + case 'w': + case 'x': + case 'z': goto yy248; + case 'F': + case 'f': goto yy250; + case 'N': + case 'n': goto yy251; + case 'O': + case 'o': goto yy252; + case 'T': + case 't': goto yy253; + case 'Y': + case 'y': goto yy254; + default: goto yy228; + } +yy226: + YYDEBUG(226, *YYCURSOR); + ++YYCURSOR; +yy227: + YYDEBUG(227, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 598 "Zend/zend_ini_scanner.l" + { /* End of option value (if EOF is reached before EOL */ + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 2921 "Zend/zend_ini_scanner.c" +yy228: + YYDEBUG(228, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy256; +yy229: + YYDEBUG(229, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 517 "Zend/zend_ini_scanner.l" + { /* Get everything else as option/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 2934 "Zend/zend_ini_scanner.c" +yy230: + YYDEBUG(230, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy306; +yy231: + YYDEBUG(231, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 571 "Zend/zend_ini_scanner.l" + { + RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); +} +#line 2947 "Zend/zend_ini_scanner.c" +yy232: + YYDEBUG(232, *YYCURSOR); + ++YYCURSOR; +yy233: + YYDEBUG(233, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 489 "Zend/zend_ini_scanner.l" + { /* End of option value */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 2960 "Zend/zend_ini_scanner.c" +yy234: + YYDEBUG(234, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy304; + goto yy233; +yy235: + YYDEBUG(235, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy303; +yy236: + YYDEBUG(236, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 507 "Zend/zend_ini_scanner.l" + { /* Boolean operators */ + return yytext[0]; +} +#line 2978 "Zend/zend_ini_scanner.c" +yy237: + YYDEBUG(237, *YYCURSOR); + ++YYCURSOR; +yy238: + YYDEBUG(238, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 2990 "Zend/zend_ini_scanner.c" +yy239: + YYDEBUG(239, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy227; + if (yych <= '[') goto yy255; + goto yy262; + } else { + if (yych == '{') goto yy300; + goto yy255; + } +yy240: + YYDEBUG(240, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy296; + } + goto yy227; +yy241: + YYDEBUG(241, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy294; + goto yy256; +yy242: + YYDEBUG(242, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy292; + goto yy256; +yy243: + YYDEBUG(243, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy256; + } else { + if (yych != '\r') goto yy256; + } + } else { + if (yych <= ')') { + if (yych <= '"') goto yy244; + if (yych <= '%') goto yy256; + } else { + if (yych == '.') goto yy288; + goto yy256; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy290; + if (yych <= ':') goto yy256; + } else { + if (yych != '=') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy244: + YYDEBUG(244, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 3069 "Zend/zend_ini_scanner.c" +yy245: + YYDEBUG(245, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + goto yy284; +yy246: + YYDEBUG(246, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(247, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 511 "Zend/zend_ini_scanner.l" + { /* Make = used in option value to trigger error */ + yyless(0); + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 3086 "Zend/zend_ini_scanner.c" +yy248: + YYDEBUG(248, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ':') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy256; + } else { + if (yych <= '\n') goto yy249; + if (yych <= '\f') goto yy256; + } + } else { + if (yych <= '"') { + if (yych <= 0x1F) goto yy256; + } else { + if (yych <= '%') goto yy256; + if (yych >= '*') goto yy256; + } + } + } else { + if (yych <= '^') { + if (yych <= '<') { + if (yych >= '<') goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= ']') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy249: + YYDEBUG(249, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 3133 "Zend/zend_ini_scanner.c" +yy250: + YYDEBUG(250, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '<') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '/') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + goto yy256; + } else { + if (yych <= '9') goto yy257; + if (yych == ';') goto yy249; + goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= 'A') { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy280; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + goto yy257; + } + } else { + if (yych <= '{') { + if (yych <= '`') goto yy256; + if (yych <= 'a') goto yy280; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy251: + YYDEBUG(251, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 'N') { + if (yych <= '%') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + if (yych <= '\n') goto yy249; + goto yy256; + } else { + if (yych <= '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + if (yych <= '"') goto yy249; + goto yy256; + } + } else { + if (yych <= ':') { + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + goto yy256; + } else { + if (yych <= '<') { + if (yych <= ';') goto yy249; + goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy257; + } + } + } + } else { + if (yych <= 'n') { + if (yych <= 'Z') { + if (yych <= 'O') goto yy276; + if (yych == 'U') goto yy277; + goto yy257; + } else { + if (yych <= '^') { + if (yych <= ']') goto yy256; + goto yy249; + } else { + if (yych == '`') goto yy256; + goto yy257; + } + } + } else { + if (yych <= 'z') { + if (yych <= 'o') goto yy276; + if (yych == 'u') goto yy277; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy256; + } + } + } + } +yy252: + YYDEBUG(252, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 'E') { + if (yych <= '%') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + if (yych <= '\n') goto yy249; + goto yy256; + } else { + if (yych <= '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + if (yych <= '"') goto yy249; + goto yy256; + } + } else { + if (yych <= ':') { + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + goto yy256; + } else { + if (yych <= '<') { + if (yych <= ';') goto yy249; + goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy257; + } + } + } + } else { + if (yych <= 'e') { + if (yych <= 'Z') { + if (yych <= 'F') goto yy271; + if (yych == 'N') goto yy265; + goto yy257; + } else { + if (yych <= '^') { + if (yych <= ']') goto yy256; + goto yy249; + } else { + if (yych == '`') goto yy256; + goto yy257; + } + } + } else { + if (yych <= 'z') { + if (yych <= 'f') goto yy271; + if (yych == 'n') goto yy265; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy256; + } + } + } + } +yy253: + YYDEBUG(253, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'R') goto yy269; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'r') goto yy269; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy254: + YYDEBUG(254, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy259; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy259; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy255: + YYDEBUG(255, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy256: + YYDEBUG(256, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy255; + } + if (yych == '$') goto yy260; + goto yy229; +yy257: + YYDEBUG(257, *YYCURSOR); + yyaccept = 4; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(258, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ')') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy249; + goto yy255; + } else { + if (yych <= '\n') goto yy249; + if (yych <= '\f') goto yy255; + goto yy249; + } + } else { + if (yych <= '#') { + if (yych <= 0x1F) goto yy255; + if (yych <= '"') goto yy249; + goto yy255; + } else { + if (yych <= '$') goto yy260; + if (yych <= '%') goto yy255; + goto yy249; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy255; + goto yy249; + } else { + if (yych == '=') goto yy249; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy249; + if (yych <= '{') goto yy255; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy255; + } + } + } +yy259: + YYDEBUG(259, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'S') goto yy265; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 's') goto yy265; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy260: + YYDEBUG(260, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy261; + if (yych <= '[') goto yy255; + goto yy262; + } else { + if (yych != '{') goto yy255; + } +yy261: + YYDEBUG(261, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 3) { + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy229; + } else { + goto yy231; + } + } else { + if (yyaccept <= 2) { + goto yy227; + } else { + goto yy244; + } + } + } else { + if (yyaccept <= 5) { + if (yyaccept <= 4) { + goto yy249; + } else { + goto yy266; + } + } else { + goto yy273; + } + } +yy262: + YYDEBUG(262, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy263; + } + goto yy255; +yy263: + YYDEBUG(263, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(264, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy263; + } + if (yych <= 0x00) goto yy229; + if (yych == '\\') goto yy262; + goto yy255; +yy265: + YYDEBUG(265, *YYCURSOR); + yyaccept = 5; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy267; + } + if (yych <= ';') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy266; + if (yych <= '\t') goto yy256; + } else { + if (yych != '\r') goto yy256; + } + } else { + if (yych <= ')') { + if (yych <= '"') goto yy266; + if (yych <= '%') goto yy256; + } else { + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + if (yych <= ':') goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= '@') { + if (yych != '=') goto yy256; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych >= '_') goto yy257; + } + } else { + if (yych <= '{') { + if (yych <= '`') goto yy256; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych >= 0x7F) goto yy256; + } + } + } +yy266: + YYDEBUG(266, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 421 "Zend/zend_ini_scanner.l" + { /* TRUE value (when used outside option value/offset this causes parse error!) */ + RETURN_TOKEN(BOOL_TRUE, "1", 1); +} +#line 3645 "Zend/zend_ini_scanner.c" +yy267: + YYDEBUG(267, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(268, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy267; + } + goto yy266; +yy269: + YYDEBUG(269, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'U') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'u') goto yy270; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy270: + YYDEBUG(270, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy265; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy265; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy271: + YYDEBUG(271, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'F') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'f') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy272: + YYDEBUG(272, *YYCURSOR); + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ')') { + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy256; + } else { + if (yych <= '\t') goto yy274; + if (yych >= '\v') goto yy256; + } + } else { + if (yych <= ' ') { + if (yych <= '\r') goto yy273; + if (yych <= 0x1F) goto yy256; + goto yy274; + } else { + if (yych <= '"') goto yy273; + if (yych <= '%') goto yy256; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy256; + } else { + if (yych != '=') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy273; + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy273: + YYDEBUG(273, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 425 "Zend/zend_ini_scanner.l" + { /* FALSE value (when used outside option value/offset this causes parse error!)*/ + RETURN_TOKEN(BOOL_FALSE, "", 0); +} +#line 3855 "Zend/zend_ini_scanner.c" +yy274: + YYDEBUG(274, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(275, *YYCURSOR); + if (yych == '\t') goto yy274; + if (yych == ' ') goto yy274; + goto yy273; +yy276: + YYDEBUG(276, *YYCURSOR); + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '<') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy273; + if (yych <= 0x08) goto yy256; + if (yych <= '\t') goto yy274; + goto yy273; + } else { + if (yych == '\r') goto yy273; + if (yych <= 0x1F) goto yy256; + goto yy274; + } + } else { + if (yych <= '/') { + if (yych <= '"') goto yy273; + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy273; + goto yy256; + } else { + if (yych <= '9') goto yy257; + if (yych == ';') goto yy273; + goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= 'N') { + if (yych <= '=') goto yy273; + if (yych <= '@') goto yy256; + if (yych <= 'M') goto yy257; + goto yy279; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy273; + goto yy257; + } + } else { + if (yych <= 'z') { + if (yych <= '`') goto yy256; + if (yych == 'n') goto yy279; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy273; + } else { + if (yych == '~') goto yy273; + goto yy256; + } + } + } + } +yy277: + YYDEBUG(277, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'L') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy278; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy278: + YYDEBUG(278, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'L') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy279: + YYDEBUG(279, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy280: + YYDEBUG(280, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'L') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy281; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy281: + YYDEBUG(281, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'S') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 's') goto yy282; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy282: + YYDEBUG(282, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy283: + YYDEBUG(283, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy284: + YYDEBUG(284, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy283; + } + if (yych >= '\r') goto yy287; +yy285: + YYDEBUG(285, *YYCURSOR); + ++YYCURSOR; +yy286: + YYDEBUG(286, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 4248 "Zend/zend_ini_scanner.c" +yy287: + YYDEBUG(287, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy285; + goto yy286; +yy288: + YYDEBUG(288, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(289, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy288; + } + if (yych <= ')') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy244; + goto yy255; + } else { + if (yych <= '\n') goto yy244; + if (yych <= '\f') goto yy255; + goto yy244; + } + } else { + if (yych <= '#') { + if (yych <= 0x1F) goto yy255; + if (yych <= '"') goto yy244; + goto yy255; + } else { + if (yych <= '$') goto yy260; + if (yych <= '%') goto yy255; + goto yy244; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy290: + YYDEBUG(290, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(291, *YYCURSOR); + if (yych <= '.') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + if (yych <= '-') goto yy255; + goto yy288; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '/') goto yy255; + if (yych <= '9') goto yy290; + goto yy255; + } else { + if (yych == '<') goto yy255; + goto yy244; + } + } else { + if (yych <= '{') { + if (yych == '^') goto yy244; + goto yy255; + } else { + if (yych == '}') goto yy255; + if (yych <= '~') goto yy244; + goto yy255; + } + } + } +yy292: + YYDEBUG(292, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(293, *YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + goto yy255; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy292; + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy294: + YYDEBUG(294, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(295, *YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + goto yy255; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy294; + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy296: + YYDEBUG(296, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(297, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy296; + } + YYDEBUG(298, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(299, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 4475 "Zend/zend_ini_scanner.c" +yy300: + YYDEBUG(300, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(301, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 4486 "Zend/zend_ini_scanner.c" +yy302: + YYDEBUG(302, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy303: + YYDEBUG(303, *YYCURSOR); + if (yych == '\t') goto yy302; + if (yych == ' ') goto yy302; + goto yy236; +yy304: + YYDEBUG(304, *YYCURSOR); + yych = *++YYCURSOR; + goto yy233; +yy305: + YYDEBUG(305, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy306: + YYDEBUG(306, *YYCURSOR); + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy231; + if (yych <= '\t') goto yy305; + goto yy304; + } else { + if (yych == '\r') goto yy308; + goto yy231; + } + } else { + if (yych <= '"') { + if (yych <= ' ') goto yy305; + if (yych <= '!') goto yy231; + } else { + if (yych == ';') goto yy283; + goto yy231; + } + } + YYDEBUG(307, *YYCURSOR); + yych = *++YYCURSOR; + goto yy238; +yy308: + YYDEBUG(308, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy304; + goto yy233; + } +/* *********************************** */ +yyc_ST_VARNAME: + { + static const unsigned char yybm[] = { + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 0, 128, 0, 128, 0, 128, + 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 128, 0, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + YYDEBUG(309, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych <= ')') { + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy311; + if (yych <= '\n') goto yy313; + } else { + if (yych <= '\r') goto yy313; + if (yych >= '!') goto yy313; + } + } else { + if (yych <= '%') { + if (yych == '$') goto yy313; + } else { + if (yych != '\'') goto yy313; + } + } + } else { + if (yych <= '[') { + if (yych <= '<') { + if (yych == ';') goto yy313; + } else { + if (yych <= '=') goto yy313; + if (yych >= '[') goto yy313; + } + } else { + if (yych <= 'z') { + if (yych == '^') goto yy313; + } else { + if (yych == '}') goto yy315; + if (yych <= '~') goto yy313; + } + } + } +yy311: + YYDEBUG(311, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy318; +yy312: + YYDEBUG(312, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 406 "Zend/zend_ini_scanner.l" + { /* Variable name */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace */ + EAT_TRAILING_WHITESPACE(); + + RETURN_TOKEN(TC_VARNAME, yytext, yyleng); +} +#line 4627 "Zend/zend_ini_scanner.c" +yy313: + YYDEBUG(313, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(314, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 4637 "Zend/zend_ini_scanner.c" +yy315: + YYDEBUG(315, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(316, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 416 "Zend/zend_ini_scanner.l" + { /* Variable end */ + yy_pop_state(TSRMLS_C); + return '}'; +} +#line 4648 "Zend/zend_ini_scanner.c" +yy317: + YYDEBUG(317, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy318: + YYDEBUG(318, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy317; + } + goto yy312; + } +} +#line 607 "Zend/zend_ini_scanner.l" + +} diff --git a/Zend/zend_ini_scanner_defs.h b/Zend/zend_ini_scanner_defs.h index 287d7bc1fbb9f..57239549783be 100644 --- a/Zend/zend_ini_scanner_defs.h +++ b/Zend/zend_ini_scanner_defs.h @@ -1,13 +1,13 @@ -/* Generated by re2c 0.13.5 */ -#line 3 "Zend/zend_ini_scanner_defs.h" - -enum YYCONDTYPE { - yycINITIAL, - yycST_OFFSET, - yycST_SECTION_VALUE, - yycST_VALUE, - yycST_SECTION_RAW, - yycST_DOUBLE_QUOTES, - yycST_VARNAME, - yycST_RAW, -}; +/* Generated by re2c 0.13.5 */ +#line 3 "Zend/zend_ini_scanner_defs.h" + +enum YYCONDTYPE { + yycINITIAL, + yycST_OFFSET, + yycST_SECTION_VALUE, + yycST_VALUE, + yycST_SECTION_RAW, + yycST_DOUBLE_QUOTES, + yycST_VARNAME, + yycST_RAW, +}; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 6a9a24a87ea72..7f46663c39c1a 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -212,6 +212,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_NS_C "__NAMESPACE__ (T_NS_C)" %token T_DIR "__DIR__ (T_DIR)" %token T_NS_SEPARATOR "\\ (T_NS_SEPARATOR)" +%token T_ELLIPSIS "... (T_ELLIPSIS)" %% /* Rules */ @@ -240,6 +241,8 @@ top_statement: | T_NAMESPACE '{' { zend_do_begin_namespace(NULL, 1 TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); } | T_USE use_declarations ';' { zend_verify_namespace(TSRMLS_C); } + | T_USE T_FUNCTION use_function_declarations ';' { zend_verify_namespace(TSRMLS_C); } + | T_USE T_CONST use_const_declarations ';' { zend_verify_namespace(TSRMLS_C); } | constant_declaration ';' { zend_verify_namespace(TSRMLS_C); } ; @@ -255,6 +258,30 @@ use_declaration: | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use(&$2, &$4, 1 TSRMLS_CC); } ; +use_function_declarations: + use_function_declarations ',' use_function_declaration + | use_function_declaration +; + +use_function_declaration: + namespace_name { zend_do_use_function(&$1, NULL, 0 TSRMLS_CC); } + | namespace_name T_AS T_STRING { zend_do_use_function(&$1, &$3, 0 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name { zend_do_use_function(&$2, NULL, 1 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_function(&$2, &$4, 1 TSRMLS_CC); } +; + +use_const_declarations: + use_const_declarations ',' use_const_declaration + | use_const_declaration +; + +use_const_declaration: + namespace_name { zend_do_use_const(&$1, NULL, 0 TSRMLS_CC); } + | namespace_name T_AS T_STRING { zend_do_use_const(&$1, &$3, 0 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name { zend_do_use_const(&$2, NULL, 1 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_const(&$2, &$4, 1 TSRMLS_CC); } +; + constant_declaration: constant_declaration ',' T_STRING '=' static_scalar { zend_do_declare_constant(&$3, &$5 TSRMLS_CC); } | T_CONST T_STRING '=' static_scalar { zend_do_declare_constant(&$2, &$4 TSRMLS_CC); } @@ -270,7 +297,7 @@ inner_statement: statement | function_declaration_statement | class_declaration_statement - | T_HALT_COMPILER '(' ')' ';' { zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } + | T_HALT_COMPILER '(' ')' ';' { zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } ; @@ -371,10 +398,14 @@ class_declaration_statement: ; is_reference: - /* empty */ { $$.op_type = ZEND_RETURN_VAL; } - | '&' { $$.op_type = ZEND_RETURN_REF; } + /* empty */ { $$.op_type = 0; } + | '&' { $$.op_type = 1; } ; +is_variadic: + /* empty */ { $$.op_type = 0; } + | T_ELLIPSIS { $$.op_type = 1; } +; unticked_function_declaration_statement: function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); } @@ -523,14 +554,15 @@ parameter_list: non_empty_parameter_list: - optional_class_type T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV, &$2, &$$, NULL, &$1, 0 TSRMLS_CC); } - | optional_class_type '&' T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV, &$3, &$$, NULL, &$1, 1 TSRMLS_CC); } - | optional_class_type '&' T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV_INIT, &$3, &$$, &$5, &$1, 1 TSRMLS_CC); } - | optional_class_type T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV_INIT, &$2, &$$, &$4, &$1, 0 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type T_VARIABLE { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$4, &$$, NULL, &$3, 0 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$5, &$$, NULL, &$3, 1 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' static_scalar { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$5, &$$, &$7, &$3, 1 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$4, &$$, &$6, &$3, 0 TSRMLS_CC); } + parameter + | non_empty_parameter_list ',' parameter +; + +parameter: + optional_class_type is_reference is_variadic T_VARIABLE + { zend_do_receive_param(ZEND_RECV, &$4, NULL, &$1, $2.op_type, $3.op_type TSRMLS_CC); } + | optional_class_type is_reference is_variadic T_VARIABLE '=' static_scalar + { zend_do_receive_param(ZEND_RECV_INIT, &$4, &$6, &$1, $2.op_type, $3.op_type TSRMLS_CC); } ; @@ -629,8 +661,8 @@ trait_precedence: ; trait_reference_list: - fully_qualified_class_name { zend_resolve_class_name(&$1, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); zend_init_list(&$$.u.op.ptr, Z_STRVAL($1.u.constant) TSRMLS_CC); } - | trait_reference_list ',' fully_qualified_class_name { zend_resolve_class_name(&$3, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC); zend_add_to_list(&$1.u.op.ptr, Z_STRVAL($3.u.constant) TSRMLS_CC); $$ = $1; } + fully_qualified_class_name { zend_resolve_class_name(&$1 TSRMLS_CC); zend_init_list(&$$.u.op.ptr, Z_STRVAL($1.u.constant) TSRMLS_CC); } + | trait_reference_list ',' fully_qualified_class_name { zend_resolve_class_name(&$3 TSRMLS_CC); zend_add_to_list(&$1.u.op.ptr, Z_STRVAL($3.u.constant) TSRMLS_CC); $$ = $1; } ; trait_method_reference: @@ -1196,7 +1228,7 @@ isset_variables: isset_variable: variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); } - | expr_without_variable { zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of an expression (you can use \"null !== expression\" instead)"); } + | expr_without_variable { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of an expression (you can use \"null !== expression\" instead)"); } ; class_constant: diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index deb799ab763b2..76e3e5645129a 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -49,7 +49,7 @@ #include "zend_API.h" #include "zend_strtod.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "tsrm_config_common.h" #define YYCTYPE unsigned char @@ -564,10 +564,8 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR zend_bool original_in_compilation = CG(in_compilation); retval_znode.op_type = IS_CONST; - retval_znode.u.constant.type = IS_LONG; - retval_znode.u.constant.value.lval = 1; - Z_UNSET_ISREF(retval_znode.u.constant); - Z_SET_REFCOUNT(retval_znode.u.constant, 1); + INIT_PZVAL(&retval_znode.u.constant); + ZVAL_LONG(&retval_znode.u.constant, 1); zend_save_lexical_state(&original_lex_state TSRMLS_CC); @@ -624,7 +622,7 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) convert_to_string(&tmp); filename = &tmp; } - file_handle.filename = filename->value.str.val; + file_handle.filename = Z_STRVAL_P(filename); file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; @@ -635,7 +633,7 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) int dummy = 1; if (!file_handle.opened_path) { - file_handle.opened_path = opened_path = estrndup(filename->value.str.val, filename->value.str.len); + file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename)); } zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL); @@ -657,22 +655,15 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D char *buf; size_t size; - /* enforce two trailing NULLs for flex... */ - if (IS_INTERNED(str->value.str.val)) { - char *tmp = safe_emalloc(1, str->value.str.len, ZEND_MMAP_AHEAD); - memcpy(tmp, str->value.str.val, str->value.str.len + ZEND_MMAP_AHEAD); - str->value.str.val = tmp; - } else { - str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD); - } - - memset(str->value.str.val + str->value.str.len, 0, ZEND_MMAP_AHEAD); + /* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */ + Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), Z_STRLEN_P(str) + ZEND_MMAP_AHEAD); + memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), 0, ZEND_MMAP_AHEAD); SCNG(yy_in) = NULL; SCNG(yy_start) = NULL; - buf = str->value.str.val; - size = str->value.str.len; + buf = Z_STRVAL_P(str); + size = Z_STRLEN_P(str); if (CG(multibyte)) { SCNG(script_org) = (unsigned char*)buf; @@ -733,7 +724,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC) int compiler_result; zend_bool original_in_compilation = CG(in_compilation); - if (source_string->value.str.len==0) { + if (Z_STRLEN_P(source_string)==0) { efree(op_array); return NULL; } @@ -871,11 +862,11 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter # define zend_copy_value(zendlval, yytext, yyleng) \ if (SCNG(output_filter)) { \ size_t sz = 0; \ - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \ - zendlval->value.str.len = sz; \ + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \ + Z_STRLEN_P(zendlval) = sz; \ } else { \ - zendlval->value.str.val = (char *) estrndup(yytext, yyleng); \ - zendlval->value.str.len = yyleng; \ + Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); \ + Z_STRLEN_P(zendlval) = yyleng; \ } static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC) @@ -886,8 +877,8 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo ZVAL_STRINGL(zendlval, str, len, 1); /* convert escape sequences */ - s = t = zendlval->value.str.val; - end = s+zendlval->value.str.len; + s = t = Z_STRVAL_P(zendlval); + end = s+Z_STRLEN_P(zendlval); while (svalue.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'r': *t++ = '\r'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 't': *t++ = '\t'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'f': *t++ = '\f'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'v': *t++ = '\v'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'e': #ifdef PHP_WIN32 @@ -923,7 +914,7 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo #else *t++ = '\e'; #endif - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case '"': case '`': @@ -935,20 +926,20 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo case '\\': case '$': *t++ = *s; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'x': case 'X': if (ZEND_IS_HEX(*(s+1))) { char hex_buf[3] = { 0, 0, 0 }; - zendlval->value.str.len--; /* for the 'x' */ + Z_STRLEN_P(zendlval)--; /* for the 'x' */ hex_buf[0] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_HEX(*(s+1))) { hex_buf[1] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; } *t++ = (char) strtol(hex_buf, NULL, 16); } else { @@ -962,13 +953,13 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo char octal_buf[4] = { 0, 0, 0, 0 }; octal_buf[0] = *s; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_OCT(*(s+1))) { octal_buf[1] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_OCT(*(s+1))) { octal_buf[2] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; } } *t++ = (char) strtol(octal_buf, NULL, 8); @@ -990,9 +981,9 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo *t = 0; if (SCNG(output_filter)) { size_t sz = 0; - s = zendlval->value.str.val; - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC); - zendlval->value.str.len = sz; + s = Z_STRVAL_P(zendlval); + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; efree(s); } } @@ -1006,7 +997,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yymore_restart: -#line 1010 "Zend/zend_language_scanner.c" +#line 1001 "Zend/zend_language_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1105,7 +1096,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy3: YYDEBUG(3, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1807 "Zend/zend_language_scanner.l" +#line 1741 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -1152,20 +1143,20 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (SCNG(output_filter)) { int readsize; size_t sz = 0; - readsize = SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); - zendlval->value.str.len = sz; + readsize = SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; if (readsize < yyleng) { yyless(readsize); } } else { - zendlval->value.str.val = (char *) estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; + Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); + Z_STRLEN_P(zendlval) = yyleng; } zendlval->type = IS_STRING; HANDLE_NEWLINES(yytext, yyleng); return T_INLINE_HTML; } -#line 1169 "Zend/zend_language_scanner.c" +#line 1160 "Zend/zend_language_scanner.c" yy4: YYDEBUG(4, *YYCURSOR); yych = *++YYCURSOR; @@ -1183,38 +1174,34 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy6: YYDEBUG(6, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1795 "Zend/zend_language_scanner.l" +#line 1731 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } else { goto inline_char_handler; } } -#line 1199 "Zend/zend_language_scanner.c" +#line 1188 "Zend/zend_language_scanner.c" yy7: YYDEBUG(7, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '=') goto yy43; YYDEBUG(8, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1772 "Zend/zend_language_scanner.l" +#line 1712 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } else { goto inline_char_handler; } } -#line 1218 "Zend/zend_language_scanner.c" +#line 1205 "Zend/zend_language_scanner.c" yy9: YYDEBUG(9, *YYCURSOR); yych = *++YYCURSOR; @@ -1400,7 +1387,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(38, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1732 "Zend/zend_language_scanner.l" +#line 1678 "Zend/zend_language_scanner.l" { YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1)); @@ -1411,13 +1398,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) } HANDLE_NEWLINES(yytext, yyleng); - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } -#line 1421 "Zend/zend_language_scanner.c" +#line 1406 "Zend/zend_language_scanner.c" yy39: YYDEBUG(39, *YYCURSOR); yych = *++YYCURSOR; @@ -1444,33 +1429,29 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(44, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1750 "Zend/zend_language_scanner.l" +#line 1694 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG_WITH_ECHO; } else { goto inline_char_handler; } } -#line 1460 "Zend/zend_language_scanner.c" +#line 1443 "Zend/zend_language_scanner.c" yy45: YYDEBUG(45, *YYCURSOR); ++YYCURSOR; YYDEBUG(46, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1763 "Zend/zend_language_scanner.l" +#line 1705 "Zend/zend_language_scanner.l" { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG_WITH_ECHO; } -#line 1474 "Zend/zend_language_scanner.c" +#line 1455 "Zend/zend_language_scanner.c" yy47: YYDEBUG(47, *YYCURSOR); yych = *++YYCURSOR; @@ -1497,16 +1478,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy51: YYDEBUG(51, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1785 "Zend/zend_language_scanner.l" +#line 1723 "Zend/zend_language_scanner.l" { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } -#line 1510 "Zend/zend_language_scanner.c" +#line 1489 "Zend/zend_language_scanner.c" yy52: YYDEBUG(52, *YYCURSOR); ++YYCURSOR; @@ -1577,7 +1556,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy56: YYDEBUG(56, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2258 "Zend/zend_language_scanner.l" +#line 2186 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -1618,7 +1597,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } -#line 1622 "Zend/zend_language_scanner.c" +#line 1601 "Zend/zend_language_scanner.c" yy57: YYDEBUG(57, *YYCURSOR); yych = *++YYCURSOR; @@ -1629,12 +1608,12 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(59, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2202 "Zend/zend_language_scanner.l" +#line 2130 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); return '`'; } -#line 1638 "Zend/zend_language_scanner.c" +#line 1617 "Zend/zend_language_scanner.c" yy60: YYDEBUG(60, *YYCURSOR); yych = *++YYCURSOR; @@ -1644,14 +1623,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(62, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2189 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { - zendlval->value.lval = (long) '{'; + Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); yyless(1); return T_CURLY_OPEN; } -#line 1655 "Zend/zend_language_scanner.c" +#line 1634 "Zend/zend_language_scanner.c" yy63: YYDEBUG(63, *YYCURSOR); yyaccept = 0; @@ -1667,24 +1646,24 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy65: YYDEBUG(65, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1889 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1677 "Zend/zend_language_scanner.c" +#line 1656 "Zend/zend_language_scanner.c" yy66: YYDEBUG(66, *YYCURSOR); ++YYCURSOR; YYDEBUG(67, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; } -#line 1688 "Zend/zend_language_scanner.c" +#line 1667 "Zend/zend_language_scanner.c" yy68: YYDEBUG(68, *YYCURSOR); yych = *++YYCURSOR; @@ -1698,7 +1677,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(71, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1881 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -1706,7 +1685,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1710 "Zend/zend_language_scanner.c" +#line 1689 "Zend/zend_language_scanner.c" yy72: YYDEBUG(72, *YYCURSOR); yych = *++YYCURSOR; @@ -1724,7 +1703,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(74, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -1732,7 +1711,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1736 "Zend/zend_language_scanner.c" +#line 1715 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: @@ -1800,7 +1779,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy78: YYDEBUG(78, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2208 "Zend/zend_language_scanner.l" +#line 2136 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -1849,7 +1828,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } -#line 1853 "Zend/zend_language_scanner.c" +#line 1832 "Zend/zend_language_scanner.c" yy79: YYDEBUG(79, *YYCURSOR); yych = *++YYCURSOR; @@ -1860,12 +1839,12 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(81, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2197 "Zend/zend_language_scanner.l" +#line 2125 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); return '"'; } -#line 1869 "Zend/zend_language_scanner.c" +#line 1848 "Zend/zend_language_scanner.c" yy82: YYDEBUG(82, *YYCURSOR); yych = *++YYCURSOR; @@ -1875,14 +1854,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(84, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2189 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { - zendlval->value.lval = (long) '{'; + Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); yyless(1); return T_CURLY_OPEN; } -#line 1886 "Zend/zend_language_scanner.c" +#line 1865 "Zend/zend_language_scanner.c" yy85: YYDEBUG(85, *YYCURSOR); yyaccept = 0; @@ -1898,24 +1877,24 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy87: YYDEBUG(87, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1889 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1908 "Zend/zend_language_scanner.c" +#line 1887 "Zend/zend_language_scanner.c" yy88: YYDEBUG(88, *YYCURSOR); ++YYCURSOR; YYDEBUG(89, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; } -#line 1919 "Zend/zend_language_scanner.c" +#line 1898 "Zend/zend_language_scanner.c" yy90: YYDEBUG(90, *YYCURSOR); yych = *++YYCURSOR; @@ -1929,7 +1908,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1881 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -1937,7 +1916,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1941 "Zend/zend_language_scanner.c" +#line 1920 "Zend/zend_language_scanner.c" yy94: YYDEBUG(94, *YYCURSOR); yych = *++YYCURSOR; @@ -1955,7 +1934,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(96, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -1963,7 +1942,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 1967 "Zend/zend_language_scanner.c" +#line 1946 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_END_HEREDOC: @@ -1974,7 +1953,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(100, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2175 "Zend/zend_language_scanner.l" +#line 2103 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); @@ -1987,7 +1966,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) BEGIN(ST_IN_SCRIPTING); return T_END_HEREDOC; } -#line 1991 "Zend/zend_language_scanner.c" +#line 1970 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_HEREDOC: { @@ -2049,7 +2028,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy104: YYDEBUG(104, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2300 "Zend/zend_language_scanner.l" +#line 2228 "Zend/zend_language_scanner.l" { int newline = 0; @@ -2122,7 +2101,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } -#line 2126 "Zend/zend_language_scanner.c" +#line 2105 "Zend/zend_language_scanner.c" yy105: YYDEBUG(105, *YYCURSOR); yych = *++YYCURSOR; @@ -2137,14 +2116,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(108, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2189 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { - zendlval->value.lval = (long) '{'; + Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); yyless(1); return T_CURLY_OPEN; } -#line 2148 "Zend/zend_language_scanner.c" +#line 2127 "Zend/zend_language_scanner.c" yy109: YYDEBUG(109, *YYCURSOR); yyaccept = 0; @@ -2160,24 +2139,24 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy111: YYDEBUG(111, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1889 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 2170 "Zend/zend_language_scanner.c" +#line 2149 "Zend/zend_language_scanner.c" yy112: YYDEBUG(112, *YYCURSOR); ++YYCURSOR; YYDEBUG(113, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; } -#line 2181 "Zend/zend_language_scanner.c" +#line 2160 "Zend/zend_language_scanner.c" yy114: YYDEBUG(114, *YYCURSOR); yych = *++YYCURSOR; @@ -2191,7 +2170,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(117, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1881 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -2199,7 +2178,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 2203 "Zend/zend_language_scanner.c" +#line 2182 "Zend/zend_language_scanner.c" yy118: YYDEBUG(118, *YYCURSOR); yych = *++YYCURSOR; @@ -2217,7 +2196,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(120, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -2225,7 +2204,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_VARIABLE; } -#line 2229 "Zend/zend_language_scanner.c" +#line 2208 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_IN_SCRIPTING: @@ -2302,14 +2281,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '\n': case '\r': case ' ': goto yy140; - case '!': goto yy153; + case '!': goto yy154; case '"': goto yy180; case '#': goto yy176; case '$': goto yy165; case '%': goto yy159; case '&': goto yy160; case '\'': goto yy178; - case '(': goto yy147; + case '(': goto yy148; case ')': case ',': case ';': @@ -2317,11 +2296,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '[': case ']': case '~': goto yy166; - case '*': goto yy156; - case '+': goto yy152; + case '*': goto yy157; + case '+': goto yy153; case '-': goto yy138; - case '.': goto yy158; - case '/': goto yy157; + case '.': goto yy145; + case '/': goto yy158; case '0': goto yy172; case '1': case '2': @@ -2333,9 +2312,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '8': case '9': goto yy174; case ':': goto yy142; - case '<': goto yy154; - case '=': goto yy150; - case '>': goto yy155; + case '<': goto yy155; + case '=': goto yy151; + case '>': goto yy156; case '?': goto yy167; case 'A': case 'a': goto yy133; @@ -2354,9 +2333,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'I': case 'i': goto yy131; case 'L': - case 'l': goto yy151; + case 'l': goto yy152; case 'N': - case 'n': goto yy145; + case 'n': goto yy146; case 'O': case 'o': goto yy163; case 'P': @@ -2368,9 +2347,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'T': case 't': goto yy130; case 'U': - case 'u': goto yy148; + case 'u': goto yy149; case 'V': - case 'v': goto yy146; + case 'v': goto yy147; case 'W': case 'w': goto yy132; case 'X': @@ -2379,7 +2358,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'y': goto yy129; case '\\': goto yy143; case '^': goto yy162; - case '_': goto yy149; + case '_': goto yy150; case '`': goto yy182; case '{': goto yy168; case '|': goto yy161; @@ -2392,48 +2371,48 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(-1, yych); switch ((yych = *YYCURSOR)) { case 'C': - case 'c': goto yy735; + case 'c': goto yy738; case 'L': - case 'l': goto yy736; + case 'l': goto yy739; case 'M': - case 'm': goto yy737; + case 'm': goto yy740; case 'N': - case 'n': goto yy738; + case 'n': goto yy741; case 'V': - case 'v': goto yy739; + case 'v': goto yy742; case 'X': - case 'x': goto yy740; + case 'x': goto yy743; default: goto yy187; } yy124: YYDEBUG(124, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1912 "Zend/zend_language_scanner.l" +#line 1846 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; return T_STRING; } -#line 2418 "Zend/zend_language_scanner.c" +#line 2397 "Zend/zend_language_scanner.c" yy125: YYDEBUG(125, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { if (yych <= 'H') { - if (yych == 'E') goto yy717; + if (yych == 'E') goto yy720; goto yy187; } else { - if (yych <= 'I') goto yy718; + if (yych <= 'I') goto yy721; if (yych <= 'N') goto yy187; - goto yy719; + goto yy722; } } else { if (yych <= 'h') { - if (yych == 'e') goto yy717; + if (yych == 'e') goto yy720; goto yy187; } else { - if (yych <= 'i') goto yy718; - if (yych == 'o') goto yy719; + if (yych <= 'i') goto yy721; + if (yych == 'o') goto yy722; goto yy187; } } @@ -2442,20 +2421,20 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'U') { if (yych <= 'N') { - if (yych == 'I') goto yy693; + if (yych == 'I') goto yy696; goto yy187; } else { - if (yych <= 'O') goto yy694; + if (yych <= 'O') goto yy697; if (yych <= 'T') goto yy187; - goto yy695; + goto yy698; } } else { if (yych <= 'n') { - if (yych == 'i') goto yy693; + if (yych == 'i') goto yy696; goto yy187; } else { - if (yych <= 'o') goto yy694; - if (yych == 'u') goto yy695; + if (yych <= 'o') goto yy697; + if (yych == 'u') goto yy698; goto yy187; } } @@ -2464,48 +2443,48 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'O') { if (yych <= 'K') { - if (yych == 'A') goto yy658; + if (yych == 'A') goto yy661; goto yy187; } else { - if (yych <= 'L') goto yy659; + if (yych <= 'L') goto yy662; if (yych <= 'N') goto yy187; - goto yy660; + goto yy663; } } else { if (yych <= 'k') { - if (yych == 'a') goto yy658; + if (yych == 'a') goto yy661; goto yy187; } else { - if (yych <= 'l') goto yy659; - if (yych == 'o') goto yy660; + if (yych <= 'l') goto yy662; + if (yych == 'o') goto yy663; goto yy187; } } yy128: YYDEBUG(128, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy640; - if (yych == 'e') goto yy640; + if (yych == 'E') goto yy643; + if (yych == 'e') goto yy643; goto yy187; yy129: YYDEBUG(129, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy635; - if (yych == 'i') goto yy635; + if (yych == 'I') goto yy638; + if (yych == 'i') goto yy638; goto yy187; yy130: YYDEBUG(130, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'R') { - if (yych == 'H') goto yy623; + if (yych == 'H') goto yy626; if (yych <= 'Q') goto yy187; - goto yy624; + goto yy627; } else { if (yych <= 'h') { if (yych <= 'g') goto yy187; - goto yy623; + goto yy626; } else { - if (yych == 'r') goto yy624; + if (yych == 'r') goto yy627; goto yy187; } } @@ -2514,53 +2493,53 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'S') { if (yych <= 'L') { - if (yych == 'F') goto yy570; + if (yych == 'F') goto yy573; goto yy187; } else { - if (yych <= 'M') goto yy572; - if (yych <= 'N') goto yy573; + if (yych <= 'M') goto yy575; + if (yych <= 'N') goto yy576; if (yych <= 'R') goto yy187; - goto yy574; + goto yy577; } } else { if (yych <= 'm') { - if (yych == 'f') goto yy570; + if (yych == 'f') goto yy573; if (yych <= 'l') goto yy187; - goto yy572; + goto yy575; } else { - if (yych <= 'n') goto yy573; - if (yych == 's') goto yy574; + if (yych <= 'n') goto yy576; + if (yych == 's') goto yy577; goto yy187; } } yy132: YYDEBUG(132, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy565; - if (yych == 'h') goto yy565; + if (yych == 'H') goto yy568; + if (yych == 'h') goto yy568; goto yy187; yy133: YYDEBUG(133, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'S') { if (yych <= 'M') { - if (yych == 'B') goto yy547; + if (yych == 'B') goto yy550; goto yy187; } else { - if (yych <= 'N') goto yy548; + if (yych <= 'N') goto yy551; if (yych <= 'Q') goto yy187; - if (yych <= 'R') goto yy549; - goto yy550; + if (yych <= 'R') goto yy552; + goto yy553; } } else { if (yych <= 'n') { - if (yych == 'b') goto yy547; + if (yych == 'b') goto yy550; if (yych <= 'm') goto yy187; - goto yy548; + goto yy551; } else { if (yych <= 'q') goto yy187; - if (yych <= 'r') goto yy549; - if (yych <= 's') goto yy550; + if (yych <= 'r') goto yy552; + if (yych <= 's') goto yy553; goto yy187; } } @@ -2568,15 +2547,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(134, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'W') { - if (yych == 'T') goto yy535; + if (yych == 'T') goto yy538; if (yych <= 'V') goto yy187; - goto yy536; + goto yy539; } else { if (yych <= 't') { if (yych <= 's') goto yy187; - goto yy535; + goto yy538; } else { - if (yych == 'w') goto yy536; + if (yych == 'w') goto yy539; goto yy187; } } @@ -2587,18 +2566,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (yych <= ';') { if (yych <= '"') { if (yych <= '!') goto yy187; - goto yy527; + goto yy530; } else { - if (yych == '\'') goto yy528; + if (yych == '\'') goto yy531; goto yy187; } } else { if (yych <= 'R') { - if (yych <= '<') goto yy526; + if (yych <= '<') goto yy529; if (yych <= 'Q') goto yy187; - goto yy529; + goto yy532; } else { - if (yych == 'r') goto yy529; + if (yych == 'r') goto yy532; goto yy187; } } @@ -2606,15 +2585,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(136, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'L') goto yy516; + if (yych == 'L') goto yy519; if (yych <= 'N') goto yy187; - goto yy517; + goto yy520; } else { if (yych <= 'l') { if (yych <= 'k') goto yy187; - goto yy516; + goto yy519; } else { - if (yych == 'o') goto yy517; + if (yych == 'o') goto yy520; goto yy187; } } @@ -2622,15 +2601,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(137, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'U') { - if (yych == 'R') goto yy492; + if (yych == 'R') goto yy495; if (yych <= 'T') goto yy187; - goto yy493; + goto yy496; } else { if (yych <= 'r') { if (yych <= 'q') goto yy187; - goto yy492; + goto yy495; } else { - if (yych == 'u') goto yy493; + if (yych == 'u') goto yy496; goto yy187; } } @@ -2638,214 +2617,217 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(138, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '<') { - if (yych == '-') goto yy488; + if (yych == '-') goto yy491; } else { - if (yych <= '=') goto yy486; - if (yych <= '>') goto yy490; + if (yych <= '=') goto yy489; + if (yych <= '>') goto yy493; } yy139: YYDEBUG(139, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1454 "Zend/zend_language_scanner.l" +#line 1446 "Zend/zend_language_scanner.l" { return yytext[0]; } -#line 2654 "Zend/zend_language_scanner.c" +#line 2633 "Zend/zend_language_scanner.c" yy140: YYDEBUG(140, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy485; + goto yy488; yy141: YYDEBUG(141, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1185 "Zend/zend_language_scanner.l" +#line 1175 "Zend/zend_language_scanner.l" { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINES(yytext, yyleng); return T_WHITESPACE; } -#line 2671 "Zend/zend_language_scanner.c" +#line 2648 "Zend/zend_language_scanner.c" yy142: YYDEBUG(142, *YYCURSOR); yych = *++YYCURSOR; - if (yych == ':') goto yy482; + if (yych == ':') goto yy485; goto yy139; yy143: YYDEBUG(143, *YYCURSOR); ++YYCURSOR; YYDEBUG(144, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1214 "Zend/zend_language_scanner.l" +#line 1202 "Zend/zend_language_scanner.l" { return T_NS_SEPARATOR; } -#line 2686 "Zend/zend_language_scanner.c" +#line 2663 "Zend/zend_language_scanner.c" yy145: YYDEBUG(145, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') { + if (yych == '.') goto yy482; + goto yy139; + } else { + if (yych <= '9') goto yy478; + if (yych == '=') goto yy480; + goto yy139; + } +yy146: + YYDEBUG(146, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'E') { - if (yych == 'A') goto yy470; + if (yych == 'A') goto yy466; if (yych <= 'D') goto yy187; - goto yy471; + goto yy467; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy470; + goto yy466; } else { - if (yych == 'e') goto yy471; + if (yych == 'e') goto yy467; goto yy187; } } -yy146: - YYDEBUG(146, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy467; - if (yych == 'a') goto yy467; - goto yy187; yy147: YYDEBUG(147, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy463; + if (yych == 'a') goto yy463; + goto yy187; +yy148: + YYDEBUG(148, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'S') { if (yych <= 'D') { if (yych <= ' ') { - if (yych == '\t') goto yy392; + if (yych == '\t') goto yy388; if (yych <= 0x1F) goto yy139; - goto yy392; + goto yy388; } else { if (yych <= '@') goto yy139; if (yych == 'C') goto yy139; - goto yy392; + goto yy388; } } else { if (yych <= 'I') { - if (yych == 'F') goto yy392; + if (yych == 'F') goto yy388; if (yych <= 'H') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'O') goto yy392; + if (yych == 'O') goto yy388; if (yych <= 'Q') goto yy139; - goto yy392; + goto yy388; } } } else { if (yych <= 'f') { if (yych <= 'b') { - if (yych == 'U') goto yy392; + if (yych == 'U') goto yy388; if (yych <= '`') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'd') goto yy392; + if (yych == 'd') goto yy388; if (yych <= 'e') goto yy139; - goto yy392; + goto yy388; } } else { if (yych <= 'o') { - if (yych == 'i') goto yy392; + if (yych == 'i') goto yy388; if (yych <= 'n') goto yy139; - goto yy392; + goto yy388; } else { if (yych <= 's') { if (yych <= 'q') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'u') goto yy392; + if (yych == 'u') goto yy388; goto yy139; } } } } -yy148: - YYDEBUG(148, *YYCURSOR); +yy149: + YYDEBUG(149, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'S') { - if (yych == 'N') goto yy383; + if (yych == 'N') goto yy379; if (yych <= 'R') goto yy187; - goto yy384; + goto yy380; } else { if (yych <= 'n') { if (yych <= 'm') goto yy187; - goto yy383; + goto yy379; } else { - if (yych == 's') goto yy384; + if (yych == 's') goto yy380; goto yy187; } } -yy149: - YYDEBUG(149, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '_') goto yy301; - goto yy187; yy150: YYDEBUG(150, *YYCURSOR); yych = *++YYCURSOR; - if (yych <= '<') goto yy139; - if (yych <= '=') goto yy295; - if (yych <= '>') goto yy297; - goto yy139; + if (yych == '_') goto yy297; + goto yy187; yy151: YYDEBUG(151, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy291; - if (yych == 'i') goto yy291; - goto yy187; + if (yych <= '<') goto yy139; + if (yych <= '=') goto yy291; + if (yych <= '>') goto yy293; + goto yy139; yy152: YYDEBUG(152, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '+') goto yy289; - if (yych == '=') goto yy287; - goto yy139; + if (yych == 'I') goto yy287; + if (yych == 'i') goto yy287; + goto yy187; yy153: YYDEBUG(153, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '=') goto yy284; + if (yych == '+') goto yy285; + if (yych == '=') goto yy283; goto yy139; yy154: YYDEBUG(154, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '=') goto yy280; + goto yy139; +yy155: + YYDEBUG(155, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yych <= ';') { - if (yych == '/') goto yy256; + if (yych == '/') goto yy252; goto yy139; } else { - if (yych <= '<') goto yy254; - if (yych <= '=') goto yy257; - if (yych <= '>') goto yy259; + if (yych <= '<') goto yy250; + if (yych <= '=') goto yy253; + if (yych <= '>') goto yy255; goto yy139; } -yy155: - YYDEBUG(155, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '<') goto yy139; - if (yych <= '=') goto yy250; - if (yych <= '>') goto yy248; - goto yy139; yy156: YYDEBUG(156, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '=') goto yy246; + if (yych <= '<') goto yy139; + if (yych <= '=') goto yy246; + if (yych <= '>') goto yy244; goto yy139; yy157: YYDEBUG(157, *YYCURSOR); yych = *++YYCURSOR; + if (yych == '=') goto yy242; + goto yy139; +yy158: + YYDEBUG(158, *YYCURSOR); + yych = *++YYCURSOR; if (yych <= '.') { - if (yych == '*') goto yy238; + if (yych == '*') goto yy234; goto yy139; } else { - if (yych <= '/') goto yy240; - if (yych == '=') goto yy241; + if (yych <= '/') goto yy236; + if (yych == '=') goto yy237; goto yy139; } -yy158: - YYDEBUG(158, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '/') goto yy139; - if (yych <= '9') goto yy234; - if (yych == '=') goto yy236; - goto yy139; yy159: YYDEBUG(159, *YYCURSOR); yych = *++YYCURSOR; @@ -2910,18 +2892,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(169, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1459 "Zend/zend_language_scanner.l" +#line 1451 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return '{'; } -#line 2919 "Zend/zend_language_scanner.c" +#line 2901 "Zend/zend_language_scanner.c" yy170: YYDEBUG(170, *YYCURSOR); ++YYCURSOR; YYDEBUG(171, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1471 "Zend/zend_language_scanner.l" +#line 1463 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -2929,7 +2911,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return '}'; } -#line 2933 "Zend/zend_language_scanner.c" +#line 2915 "Zend/zend_language_scanner.c" yy172: YYDEBUG(172, *YYCURSOR); yyaccept = 2; @@ -2957,18 +2939,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy173: YYDEBUG(173, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1522 "Zend/zend_language_scanner.l" +#line 1513 "Zend/zend_language_scanner.l" { if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ - zendlval->value.lval = strtol(yytext, NULL, 0); + Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0); } else { errno = 0; - zendlval->value.lval = strtol(yytext, NULL, 0); + Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0); if (errno == ERANGE) { /* Overflow */ if (yytext[0] == '0') { /* octal overflow */ - zendlval->value.dval = zend_oct_strtod(yytext, NULL); + Z_DVAL_P(zendlval) = zend_oct_strtod(yytext, NULL); } else { - zendlval->value.dval = zend_strtod(yytext, NULL); + Z_DVAL_P(zendlval) = zend_strtod(yytext, NULL); } zendlval->type = IS_DOUBLE; return T_DNUMBER; @@ -2978,7 +2960,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_LONG; return T_LNUMBER; } -#line 2982 "Zend/zend_language_scanner.c" +#line 2964 "Zend/zend_language_scanner.c" yy174: YYDEBUG(174, *YYCURSOR); yyaccept = 2; @@ -3006,7 +2988,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy177: YYDEBUG(177, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 1853 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -3040,14 +3022,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_COMMENT; } -#line 3044 "Zend/zend_language_scanner.c" +#line 3026 "Zend/zend_language_scanner.c" yy178: YYDEBUG(178, *YYCURSOR); ++YYCURSOR; yy179: YYDEBUG(179, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2010 "Zend/zend_language_scanner.l" +#line 1940 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -3073,13 +3055,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) } } - zendlval->value.str.val = estrndup(yytext+bprefix+1, yyleng-bprefix-2); - zendlval->value.str.len = yyleng-bprefix-2; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext+bprefix+1, yyleng-bprefix-2, 1); /* convert escape sequences */ - s = t = zendlval->value.str.val; - end = s+zendlval->value.str.len; + s = t = Z_STRVAL_P(zendlval); + end = s+Z_STRLEN_P(zendlval); while (svalue.str.len--; + Z_STRLEN_P(zendlval)--; break; default: *t++ = '\\'; @@ -3108,21 +3088,21 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (SCNG(output_filter)) { size_t sz = 0; - s = zendlval->value.str.val; - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC); - zendlval->value.str.len = sz; + s = Z_STRVAL_P(zendlval); + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; efree(s); } return T_CONSTANT_ENCAPSED_STRING; } -#line 3119 "Zend/zend_language_scanner.c" +#line 3099 "Zend/zend_language_scanner.c" yy180: YYDEBUG(180, *YYCURSOR); ++YYCURSOR; yy181: YYDEBUG(181, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2079 "Zend/zend_language_scanner.l" +#line 2007 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -3163,24 +3143,24 @@ int lex_scan(zval *zendlval TSRMLS_DC) BEGIN(ST_DOUBLE_QUOTES); return '"'; } -#line 3167 "Zend/zend_language_scanner.c" +#line 3147 "Zend/zend_language_scanner.c" yy182: YYDEBUG(182, *YYCURSOR); ++YYCURSOR; YYDEBUG(183, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2169 "Zend/zend_language_scanner.l" +#line 2097 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); return '`'; } -#line 3178 "Zend/zend_language_scanner.c" +#line 3158 "Zend/zend_language_scanner.c" yy184: YYDEBUG(184, *YYCURSOR); ++YYCURSOR; YYDEBUG(185, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2432 "Zend/zend_language_scanner.l" +#line 2360 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -3189,7 +3169,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 3193 "Zend/zend_language_scanner.c" +#line 3173 "Zend/zend_language_scanner.c" yy186: YYDEBUG(186, *YYCURSOR); ++YYCURSOR; @@ -3216,13 +3196,12 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy190: YYDEBUG(190, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1587 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { - zendlval->value.dval = zend_strtod(yytext, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_strtod(yytext, NULL)); return T_DNUMBER; } -#line 3226 "Zend/zend_language_scanner.c" +#line 3205 "Zend/zend_language_scanner.c" yy191: YYDEBUG(191, *YYCURSOR); yyaccept = 2; @@ -3269,10 +3248,10 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (yyaccept <= 3) { goto yy190; } else { - goto yy239; + goto yy235; } } else { - goto yy255; + goto yy251; } } yy195: @@ -3314,7 +3293,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(202, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1497 "Zend/zend_language_scanner.l" +#line 1489 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -3327,19 +3306,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (len < SIZEOF_LONG * 8) { if (len == 0) { - zendlval->value.lval = 0; + Z_LVAL_P(zendlval) = 0; } else { - zendlval->value.lval = strtol(bin, NULL, 2); + Z_LVAL_P(zendlval) = strtol(bin, NULL, 2); } zendlval->type = IS_LONG; return T_LNUMBER; } else { - zendlval->value.dval = zend_bin_strtod(bin, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_bin_strtod(bin, NULL)); return T_DNUMBER; } } -#line 3343 "Zend/zend_language_scanner.c" +#line 3321 "Zend/zend_language_scanner.c" yy203: YYDEBUG(203, *YYCURSOR); ++YYCURSOR; @@ -3351,7 +3329,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(205, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1543 "Zend/zend_language_scanner.l" +#line 1534 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -3364,19 +3342,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (len < SIZEOF_LONG * 2 || (len == SIZEOF_LONG * 2 && *hex <= '7')) { if (len == 0) { - zendlval->value.lval = 0; + Z_LVAL_P(zendlval) = 0; } else { - zendlval->value.lval = strtol(hex, NULL, 16); + Z_LVAL_P(zendlval) = strtol(hex, NULL, 16); } zendlval->type = IS_LONG; return T_LNUMBER; } else { - zendlval->value.dval = zend_hex_strtod(hex, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_hex_strtod(hex, NULL)); return T_DNUMBER; } } -#line 3380 "Zend/zend_language_scanner.c" +#line 3357 "Zend/zend_language_scanner.c" yy206: YYDEBUG(206, *YYCURSOR); ++YYCURSOR; @@ -3385,15 +3362,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy207: YYDEBUG(207, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1987 "Zend/zend_language_scanner.l" +#line 1921 "Zend/zend_language_scanner.l" { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(INITIAL); return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } -#line 3397 "Zend/zend_language_scanner.c" +#line 3372 "Zend/zend_language_scanner.c" yy208: YYDEBUG(208, *YYCURSOR); yych = *++YYCURSOR; @@ -3427,13 +3402,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy212: YYDEBUG(212, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1889 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 3437 "Zend/zend_language_scanner.c" +#line 3412 "Zend/zend_language_scanner.c" yy213: YYDEBUG(213, *YYCURSOR); yych = *++YYCURSOR; @@ -3447,11 +3422,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(215, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1442 "Zend/zend_language_scanner.l" +#line 1434 "Zend/zend_language_scanner.l" { return T_LOGICAL_XOR; } -#line 3455 "Zend/zend_language_scanner.c" +#line 3430 "Zend/zend_language_scanner.c" yy216: YYDEBUG(216, *YYCURSOR); ++YYCURSOR; @@ -3460,61 +3435,61 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(217, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1434 "Zend/zend_language_scanner.l" +#line 1426 "Zend/zend_language_scanner.l" { return T_LOGICAL_OR; } -#line 3468 "Zend/zend_language_scanner.c" +#line 3443 "Zend/zend_language_scanner.c" yy218: YYDEBUG(218, *YYCURSOR); ++YYCURSOR; YYDEBUG(219, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1422 "Zend/zend_language_scanner.l" +#line 1414 "Zend/zend_language_scanner.l" { return T_XOR_EQUAL; } -#line 3478 "Zend/zend_language_scanner.c" +#line 3453 "Zend/zend_language_scanner.c" yy220: YYDEBUG(220, *YYCURSOR); ++YYCURSOR; YYDEBUG(221, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1426 "Zend/zend_language_scanner.l" +#line 1418 "Zend/zend_language_scanner.l" { return T_BOOLEAN_OR; } -#line 3488 "Zend/zend_language_scanner.c" +#line 3463 "Zend/zend_language_scanner.c" yy222: YYDEBUG(222, *YYCURSOR); ++YYCURSOR; YYDEBUG(223, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1418 "Zend/zend_language_scanner.l" +#line 1410 "Zend/zend_language_scanner.l" { return T_OR_EQUAL; } -#line 3498 "Zend/zend_language_scanner.c" +#line 3473 "Zend/zend_language_scanner.c" yy224: YYDEBUG(224, *YYCURSOR); ++YYCURSOR; YYDEBUG(225, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1430 "Zend/zend_language_scanner.l" +#line 1422 "Zend/zend_language_scanner.l" { return T_BOOLEAN_AND; } -#line 3508 "Zend/zend_language_scanner.c" +#line 3483 "Zend/zend_language_scanner.c" yy226: YYDEBUG(226, *YYCURSOR); ++YYCURSOR; YYDEBUG(227, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1414 "Zend/zend_language_scanner.l" +#line 1406 "Zend/zend_language_scanner.l" { return T_AND_EQUAL; } -#line 3518 "Zend/zend_language_scanner.c" +#line 3493 "Zend/zend_language_scanner.c" yy228: YYDEBUG(228, *YYCURSOR); ++YYCURSOR; @@ -3523,30 +3498,28 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy229: YYDEBUG(229, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1996 "Zend/zend_language_scanner.l" +#line 1928 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { BEGIN(INITIAL); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; - zendlval->value.str.val = yytext; /* no copying - intentional */ + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } else { yyless(1); return yytext[0]; } } -#line 3540 "Zend/zend_language_scanner.c" +#line 3513 "Zend/zend_language_scanner.c" yy230: YYDEBUG(230, *YYCURSOR); ++YYCURSOR; YYDEBUG(231, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1402 "Zend/zend_language_scanner.l" +#line 1394 "Zend/zend_language_scanner.l" { return T_MOD_EQUAL; } -#line 3550 "Zend/zend_language_scanner.c" +#line 3523 "Zend/zend_language_scanner.c" yy232: YYDEBUG(232, *YYCURSOR); yych = *++YYCURSOR; @@ -3558,39 +3531,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) goto yy229; yy234: YYDEBUG(234, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(3); - yych = *YYCURSOR; - YYDEBUG(235, *YYCURSOR); - if (yych <= 'D') { - if (yych <= '/') goto yy190; - if (yych <= '9') goto yy234; - goto yy190; - } else { - if (yych <= 'E') goto yy193; - if (yych == 'e') goto yy193; - goto yy190; - } -yy236: - YYDEBUG(236, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(237, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1398 "Zend/zend_language_scanner.l" - { - return T_CONCAT_EQUAL; -} -#line 3585 "Zend/zend_language_scanner.c" -yy238: - YYDEBUG(238, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '*') goto yy243; -yy239: - YYDEBUG(239, *YYCURSOR); + if (yych == '*') goto yy239; +yy235: + YYDEBUG(235, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1953 "Zend/zend_language_scanner.l" +#line 1887 "Zend/zend_language_scanner.l" { int doc_com; @@ -3624,281 +3571,281 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_COMMENT; } -#line 3628 "Zend/zend_language_scanner.c" -yy240: - YYDEBUG(240, *YYCURSOR); +#line 3575 "Zend/zend_language_scanner.c" +yy236: + YYDEBUG(236, *YYCURSOR); yych = *++YYCURSOR; goto yy177; -yy241: - YYDEBUG(241, *YYCURSOR); +yy237: + YYDEBUG(237, *YYCURSOR); ++YYCURSOR; - YYDEBUG(242, *YYCURSOR); + YYDEBUG(238, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1394 "Zend/zend_language_scanner.l" +#line 1386 "Zend/zend_language_scanner.l" { return T_DIV_EQUAL; } -#line 3642 "Zend/zend_language_scanner.c" -yy243: - YYDEBUG(243, *YYCURSOR); +#line 3589 "Zend/zend_language_scanner.c" +yy239: + YYDEBUG(239, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 64) { - goto yy244; + goto yy240; } goto yy194; -yy244: - YYDEBUG(244, *YYCURSOR); +yy240: + YYDEBUG(240, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(245, *YYCURSOR); + YYDEBUG(241, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy244; + goto yy240; } - goto yy239; -yy246: - YYDEBUG(246, *YYCURSOR); + goto yy235; +yy242: + YYDEBUG(242, *YYCURSOR); ++YYCURSOR; - YYDEBUG(247, *YYCURSOR); + YYDEBUG(243, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1390 "Zend/zend_language_scanner.l" +#line 1382 "Zend/zend_language_scanner.l" { return T_MUL_EQUAL; } -#line 3669 "Zend/zend_language_scanner.c" -yy248: - YYDEBUG(248, *YYCURSOR); +#line 3616 "Zend/zend_language_scanner.c" +yy244: + YYDEBUG(244, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '=') goto yy252; - YYDEBUG(249, *YYCURSOR); + if ((yych = *YYCURSOR) == '=') goto yy248; + YYDEBUG(245, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1450 "Zend/zend_language_scanner.l" +#line 1442 "Zend/zend_language_scanner.l" { return T_SR; } -#line 3680 "Zend/zend_language_scanner.c" -yy250: - YYDEBUG(250, *YYCURSOR); +#line 3627 "Zend/zend_language_scanner.c" +yy246: + YYDEBUG(246, *YYCURSOR); ++YYCURSOR; - YYDEBUG(251, *YYCURSOR); + YYDEBUG(247, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1378 "Zend/zend_language_scanner.l" +#line 1370 "Zend/zend_language_scanner.l" { return T_IS_GREATER_OR_EQUAL; } -#line 3690 "Zend/zend_language_scanner.c" -yy252: - YYDEBUG(252, *YYCURSOR); +#line 3637 "Zend/zend_language_scanner.c" +yy248: + YYDEBUG(248, *YYCURSOR); ++YYCURSOR; - YYDEBUG(253, *YYCURSOR); + YYDEBUG(249, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1410 "Zend/zend_language_scanner.l" +#line 1402 "Zend/zend_language_scanner.l" { return T_SR_EQUAL; } -#line 3700 "Zend/zend_language_scanner.c" -yy254: - YYDEBUG(254, *YYCURSOR); +#line 3647 "Zend/zend_language_scanner.c" +yy250: + YYDEBUG(250, *YYCURSOR); yyaccept = 5; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= ';') goto yy255; - if (yych <= '<') goto yy270; - if (yych <= '=') goto yy268; -yy255: - YYDEBUG(255, *YYCURSOR); + if (yych <= ';') goto yy251; + if (yych <= '<') goto yy266; + if (yych <= '=') goto yy264; +yy251: + YYDEBUG(251, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1446 "Zend/zend_language_scanner.l" +#line 1438 "Zend/zend_language_scanner.l" { return T_SL; } -#line 3715 "Zend/zend_language_scanner.c" -yy256: - YYDEBUG(256, *YYCURSOR); +#line 3662 "Zend/zend_language_scanner.c" +yy252: + YYDEBUG(252, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy261; - if (yych == 's') goto yy261; + if (yych == 'S') goto yy257; + if (yych == 's') goto yy257; goto yy194; -yy257: - YYDEBUG(257, *YYCURSOR); +yy253: + YYDEBUG(253, *YYCURSOR); ++YYCURSOR; - YYDEBUG(258, *YYCURSOR); + YYDEBUG(254, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1374 "Zend/zend_language_scanner.l" +#line 1366 "Zend/zend_language_scanner.l" { return T_IS_SMALLER_OR_EQUAL; } -#line 3731 "Zend/zend_language_scanner.c" -yy259: - YYDEBUG(259, *YYCURSOR); +#line 3678 "Zend/zend_language_scanner.c" +yy255: + YYDEBUG(255, *YYCURSOR); ++YYCURSOR; -yy260: - YYDEBUG(260, *YYCURSOR); +yy256: + YYDEBUG(256, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1370 "Zend/zend_language_scanner.l" +#line 1362 "Zend/zend_language_scanner.l" { return T_IS_NOT_EQUAL; } -#line 3742 "Zend/zend_language_scanner.c" -yy261: - YYDEBUG(261, *YYCURSOR); +#line 3689 "Zend/zend_language_scanner.c" +yy257: + YYDEBUG(257, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy262; + if (yych == 'C') goto yy258; if (yych != 'c') goto yy194; -yy262: - YYDEBUG(262, *YYCURSOR); +yy258: + YYDEBUG(258, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy263; + if (yych == 'R') goto yy259; if (yych != 'r') goto yy194; -yy263: - YYDEBUG(263, *YYCURSOR); +yy259: + YYDEBUG(259, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy264; + if (yych == 'I') goto yy260; if (yych != 'i') goto yy194; -yy264: - YYDEBUG(264, *YYCURSOR); +yy260: + YYDEBUG(260, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy265; + if (yych == 'P') goto yy261; if (yych != 'p') goto yy194; -yy265: - YYDEBUG(265, *YYCURSOR); +yy261: + YYDEBUG(261, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy266; + if (yych == 'T') goto yy262; if (yych != 't') goto yy194; -yy266: - YYDEBUG(266, *YYCURSOR); +yy262: + YYDEBUG(262, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(267, *YYCURSOR); + YYDEBUG(263, *YYCURSOR); if (yych <= '\r') { if (yych <= 0x08) goto yy194; - if (yych <= '\n') goto yy266; + if (yych <= '\n') goto yy262; if (yych <= '\f') goto yy194; - goto yy266; + goto yy262; } else { if (yych <= ' ') { if (yych <= 0x1F) goto yy194; - goto yy266; + goto yy262; } else { if (yych == '>') goto yy206; goto yy194; } } -yy268: - YYDEBUG(268, *YYCURSOR); +yy264: + YYDEBUG(264, *YYCURSOR); ++YYCURSOR; - YYDEBUG(269, *YYCURSOR); + YYDEBUG(265, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1406 "Zend/zend_language_scanner.l" +#line 1398 "Zend/zend_language_scanner.l" { return T_SL_EQUAL; } -#line 3797 "Zend/zend_language_scanner.c" -yy270: - YYDEBUG(270, *YYCURSOR); +#line 3744 "Zend/zend_language_scanner.c" +yy266: + YYDEBUG(266, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(271, *YYCURSOR); + YYDEBUG(267, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy270; + goto yy266; } if (yych <= 'Z') { if (yych <= '&') { - if (yych == '"') goto yy275; + if (yych == '"') goto yy271; goto yy194; } else { - if (yych <= '\'') goto yy274; + if (yych <= '\'') goto yy270; if (yych <= '@') goto yy194; } } else { if (yych <= '`') { if (yych != '_') goto yy194; } else { - if (yych <= 'z') goto yy272; + if (yych <= 'z') goto yy268; if (yych <= '~') goto yy194; } } -yy272: - YYDEBUG(272, *YYCURSOR); +yy268: + YYDEBUG(268, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(273, *YYCURSOR); + YYDEBUG(269, *YYCURSOR); if (yych <= '@') { if (yych <= '\f') { - if (yych == '\n') goto yy279; + if (yych == '\n') goto yy275; goto yy194; } else { - if (yych <= '\r') goto yy281; + if (yych <= '\r') goto yy277; if (yych <= '/') goto yy194; - if (yych <= '9') goto yy272; + if (yych <= '9') goto yy268; goto yy194; } } else { if (yych <= '_') { - if (yych <= 'Z') goto yy272; + if (yych <= 'Z') goto yy268; if (yych <= '^') goto yy194; - goto yy272; + goto yy268; } else { if (yych <= '`') goto yy194; - if (yych <= 'z') goto yy272; + if (yych <= 'z') goto yy268; if (yych <= '~') goto yy194; - goto yy272; + goto yy268; } } -yy274: - YYDEBUG(274, *YYCURSOR); +yy270: + YYDEBUG(270, *YYCURSOR); yych = *++YYCURSOR; if (yych == '\'') goto yy194; - if (yych <= '/') goto yy283; + if (yych <= '/') goto yy279; if (yych <= '9') goto yy194; - goto yy283; -yy275: - YYDEBUG(275, *YYCURSOR); + goto yy279; +yy271: + YYDEBUG(271, *YYCURSOR); yych = *++YYCURSOR; if (yych == '"') goto yy194; - if (yych <= '/') goto yy277; + if (yych <= '/') goto yy273; if (yych <= '9') goto yy194; - goto yy277; -yy276: - YYDEBUG(276, *YYCURSOR); + goto yy273; +yy272: + YYDEBUG(272, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy277: - YYDEBUG(277, *YYCURSOR); +yy273: + YYDEBUG(273, *YYCURSOR); if (yych <= 'Z') { if (yych <= '/') { if (yych != '"') goto yy194; } else { - if (yych <= '9') goto yy276; + if (yych <= '9') goto yy272; if (yych <= '@') goto yy194; - goto yy276; + goto yy272; } } else { if (yych <= '`') { - if (yych == '_') goto yy276; + if (yych == '_') goto yy272; goto yy194; } else { - if (yych <= 'z') goto yy276; + if (yych <= 'z') goto yy272; if (yych <= '~') goto yy194; - goto yy276; + goto yy272; } } -yy278: - YYDEBUG(278, *YYCURSOR); +yy274: + YYDEBUG(274, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy279; - if (yych == '\r') goto yy281; + if (yych == '\n') goto yy275; + if (yych == '\r') goto yy277; goto yy194; -yy279: - YYDEBUG(279, *YYCURSOR); +yy275: + YYDEBUG(275, *YYCURSOR); ++YYCURSOR; -yy280: - YYDEBUG(280, *YYCURSOR); +yy276: + YYDEBUG(276, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2121 "Zend/zend_language_scanner.l" +#line 2049 "Zend/zend_language_scanner.l" { char *s; int bprefix = (yytext[0] != '<') ? 1 : 0; @@ -3945,255 +3892,255 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_START_HEREDOC; } -#line 3949 "Zend/zend_language_scanner.c" -yy281: - YYDEBUG(281, *YYCURSOR); +#line 3896 "Zend/zend_language_scanner.c" +yy277: + YYDEBUG(277, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy279; - goto yy280; -yy282: - YYDEBUG(282, *YYCURSOR); + if (yych == '\n') goto yy275; + goto yy276; +yy278: + YYDEBUG(278, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy283: - YYDEBUG(283, *YYCURSOR); +yy279: + YYDEBUG(279, *YYCURSOR); if (yych <= 'Z') { if (yych <= '/') { - if (yych == '\'') goto yy278; + if (yych == '\'') goto yy274; goto yy194; } else { - if (yych <= '9') goto yy282; + if (yych <= '9') goto yy278; if (yych <= '@') goto yy194; - goto yy282; + goto yy278; } } else { if (yych <= '`') { - if (yych == '_') goto yy282; + if (yych == '_') goto yy278; goto yy194; } else { - if (yych <= 'z') goto yy282; + if (yych <= 'z') goto yy278; if (yych <= '~') goto yy194; - goto yy282; + goto yy278; } } -yy284: - YYDEBUG(284, *YYCURSOR); +yy280: + YYDEBUG(280, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '=') goto yy260; - YYDEBUG(285, *YYCURSOR); + if (yych != '=') goto yy256; + YYDEBUG(281, *YYCURSOR); ++YYCURSOR; - YYDEBUG(286, *YYCURSOR); + YYDEBUG(282, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1362 "Zend/zend_language_scanner.l" +#line 1354 "Zend/zend_language_scanner.l" { return T_IS_NOT_IDENTICAL; } -#line 3993 "Zend/zend_language_scanner.c" -yy287: - YYDEBUG(287, *YYCURSOR); +#line 3940 "Zend/zend_language_scanner.c" +yy283: + YYDEBUG(283, *YYCURSOR); ++YYCURSOR; - YYDEBUG(288, *YYCURSOR); + YYDEBUG(284, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1382 "Zend/zend_language_scanner.l" +#line 1374 "Zend/zend_language_scanner.l" { return T_PLUS_EQUAL; } -#line 4003 "Zend/zend_language_scanner.c" -yy289: - YYDEBUG(289, *YYCURSOR); +#line 3950 "Zend/zend_language_scanner.c" +yy285: + YYDEBUG(285, *YYCURSOR); ++YYCURSOR; - YYDEBUG(290, *YYCURSOR); + YYDEBUG(286, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1350 "Zend/zend_language_scanner.l" +#line 1342 "Zend/zend_language_scanner.l" { return T_INC; } -#line 4013 "Zend/zend_language_scanner.c" -yy291: - YYDEBUG(291, *YYCURSOR); +#line 3960 "Zend/zend_language_scanner.c" +yy287: + YYDEBUG(287, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy292; + if (yych == 'S') goto yy288; if (yych != 's') goto yy187; -yy292: - YYDEBUG(292, *YYCURSOR); +yy288: + YYDEBUG(288, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy293; + if (yych == 'T') goto yy289; if (yych != 't') goto yy187; -yy293: - YYDEBUG(293, *YYCURSOR); +yy289: + YYDEBUG(289, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(294, *YYCURSOR); + YYDEBUG(290, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1338 "Zend/zend_language_scanner.l" +#line 1330 "Zend/zend_language_scanner.l" { return T_LIST; } -#line 4036 "Zend/zend_language_scanner.c" -yy295: - YYDEBUG(295, *YYCURSOR); +#line 3983 "Zend/zend_language_scanner.c" +yy291: + YYDEBUG(291, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '=') goto yy299; - YYDEBUG(296, *YYCURSOR); + if ((yych = *YYCURSOR) == '=') goto yy295; + YYDEBUG(292, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1366 "Zend/zend_language_scanner.l" +#line 1358 "Zend/zend_language_scanner.l" { return T_IS_EQUAL; } -#line 4047 "Zend/zend_language_scanner.c" -yy297: - YYDEBUG(297, *YYCURSOR); +#line 3994 "Zend/zend_language_scanner.c" +yy293: + YYDEBUG(293, *YYCURSOR); ++YYCURSOR; - YYDEBUG(298, *YYCURSOR); + YYDEBUG(294, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1334 "Zend/zend_language_scanner.l" +#line 1326 "Zend/zend_language_scanner.l" { return T_DOUBLE_ARROW; } -#line 4057 "Zend/zend_language_scanner.c" -yy299: - YYDEBUG(299, *YYCURSOR); +#line 4004 "Zend/zend_language_scanner.c" +yy295: + YYDEBUG(295, *YYCURSOR); ++YYCURSOR; - YYDEBUG(300, *YYCURSOR); + YYDEBUG(296, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1358 "Zend/zend_language_scanner.l" +#line 1350 "Zend/zend_language_scanner.l" { return T_IS_IDENTICAL; } -#line 4067 "Zend/zend_language_scanner.c" -yy301: - YYDEBUG(301, *YYCURSOR); +#line 4014 "Zend/zend_language_scanner.c" +yy297: + YYDEBUG(297, *YYCURSOR); yych = *++YYCURSOR; YYDEBUG(-1, yych); switch (yych) { case 'C': - case 'c': goto yy303; + case 'c': goto yy299; case 'D': - case 'd': goto yy308; + case 'd': goto yy304; case 'F': - case 'f': goto yy305; + case 'f': goto yy301; case 'H': - case 'h': goto yy302; + case 'h': goto yy298; case 'L': - case 'l': goto yy307; + case 'l': goto yy303; case 'M': - case 'm': goto yy306; + case 'm': goto yy302; case 'N': - case 'n': goto yy309; + case 'n': goto yy305; case 'T': - case 't': goto yy304; + case 't': goto yy300; default: goto yy187; } -yy302: - YYDEBUG(302, *YYCURSOR); +yy298: + YYDEBUG(298, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy370; - if (yych == 'a') goto yy370; + if (yych == 'A') goto yy366; + if (yych == 'a') goto yy366; goto yy187; -yy303: - YYDEBUG(303, *YYCURSOR); +yy299: + YYDEBUG(299, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy363; - if (yych == 'l') goto yy363; + if (yych == 'L') goto yy359; + if (yych == 'l') goto yy359; goto yy187; -yy304: - YYDEBUG(304, *YYCURSOR); +yy300: + YYDEBUG(300, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy356; - if (yych == 'r') goto yy356; + if (yych == 'R') goto yy352; + if (yych == 'r') goto yy352; goto yy187; -yy305: - YYDEBUG(305, *YYCURSOR); +yy301: + YYDEBUG(301, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'U') { - if (yych == 'I') goto yy340; + if (yych == 'I') goto yy336; if (yych <= 'T') goto yy187; - goto yy341; + goto yy337; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; - goto yy340; + goto yy336; } else { - if (yych == 'u') goto yy341; + if (yych == 'u') goto yy337; goto yy187; } } +yy302: + YYDEBUG(302, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy328; + if (yych == 'e') goto yy328; + goto yy187; +yy303: + YYDEBUG(303, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy322; + if (yych == 'i') goto yy322; + goto yy187; +yy304: + YYDEBUG(304, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy317; + if (yych == 'i') goto yy317; + goto yy187; +yy305: + YYDEBUG(305, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy306; + if (yych != 'a') goto yy187; yy306: YYDEBUG(306, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy332; - if (yych == 'e') goto yy332; - goto yy187; + if (yych == 'M') goto yy307; + if (yych != 'm') goto yy187; yy307: YYDEBUG(307, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy326; - if (yych == 'i') goto yy326; - goto yy187; + if (yych == 'E') goto yy308; + if (yych != 'e') goto yy187; yy308: YYDEBUG(308, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy321; - if (yych == 'i') goto yy321; - goto yy187; + if (yych == 'S') goto yy309; + if (yych != 's') goto yy187; yy309: YYDEBUG(309, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy310; - if (yych != 'a') goto yy187; + if (yych == 'P') goto yy310; + if (yych != 'p') goto yy187; yy310: YYDEBUG(310, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy311; - if (yych != 'm') goto yy187; + if (yych == 'A') goto yy311; + if (yych != 'a') goto yy187; yy311: YYDEBUG(311, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy312; - if (yych != 'e') goto yy187; + if (yych == 'C') goto yy312; + if (yych != 'c') goto yy187; yy312: YYDEBUG(312, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy313; - if (yych != 's') goto yy187; + if (yych == 'E') goto yy313; + if (yych != 'e') goto yy187; yy313: YYDEBUG(313, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy314; - if (yych != 'p') goto yy187; -yy314: - YYDEBUG(314, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy315; - if (yych != 'a') goto yy187; -yy315: - YYDEBUG(315, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'C') goto yy316; - if (yych != 'c') goto yy187; -yy316: - YYDEBUG(316, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy317; - if (yych != 'e') goto yy187; -yy317: - YYDEBUG(317, *YYCURSOR); - yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(318, *YYCURSOR); + YYDEBUG(314, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(319, *YYCURSOR); + YYDEBUG(315, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(320, *YYCURSOR); + YYDEBUG(316, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1722 "Zend/zend_language_scanner.l" +#line 1668 "Zend/zend_language_scanner.l" { if (CG(current_namespace)) { *zendlval = *CG(current_namespace); @@ -4203,27 +4150,27 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_NS_C; } -#line 4207 "Zend/zend_language_scanner.c" -yy321: - YYDEBUG(321, *YYCURSOR); +#line 4154 "Zend/zend_language_scanner.c" +yy317: + YYDEBUG(317, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy322; + if (yych == 'R') goto yy318; if (yych != 'r') goto yy187; -yy322: - YYDEBUG(322, *YYCURSOR); +yy318: + YYDEBUG(318, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(323, *YYCURSOR); + YYDEBUG(319, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(324, *YYCURSOR); + YYDEBUG(320, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(325, *YYCURSOR); + YYDEBUG(321, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1695 "Zend/zend_language_scanner.l" +#line 1643 "Zend/zend_language_scanner.l" { char *filename = zend_get_compiled_filename(TSRMLS_C); const size_t filename_len = strlen(filename); @@ -4245,91 +4192,80 @@ int lex_scan(zval *zendlval TSRMLS_DC) #endif } - zendlval->value.str.len = strlen(dirname); - zendlval->value.str.val = dirname; - zendlval->type = IS_STRING; + ZVAL_STRING(zendlval, dirname, 0); return T_DIR; } -#line 4254 "Zend/zend_language_scanner.c" -yy326: - YYDEBUG(326, *YYCURSOR); +#line 4199 "Zend/zend_language_scanner.c" +yy322: + YYDEBUG(322, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy327; + if (yych == 'N') goto yy323; if (yych != 'n') goto yy187; -yy327: - YYDEBUG(327, *YYCURSOR); +yy323: + YYDEBUG(323, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy328; + if (yych == 'E') goto yy324; if (yych != 'e') goto yy187; -yy328: - YYDEBUG(328, *YYCURSOR); +yy324: + YYDEBUG(324, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(329, *YYCURSOR); + YYDEBUG(325, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(330, *YYCURSOR); + YYDEBUG(326, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(331, *YYCURSOR); + YYDEBUG(327, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1677 "Zend/zend_language_scanner.l" +#line 1628 "Zend/zend_language_scanner.l" { - zendlval->value.lval = CG(zend_lineno); - zendlval->type = IS_LONG; + ZVAL_LONG(zendlval, CG(zend_lineno)); return T_LINE; } -#line 4285 "Zend/zend_language_scanner.c" -yy332: - YYDEBUG(332, *YYCURSOR); +#line 4229 "Zend/zend_language_scanner.c" +yy328: + YYDEBUG(328, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy333; + if (yych == 'T') goto yy329; if (yych != 't') goto yy187; -yy333: - YYDEBUG(333, *YYCURSOR); +yy329: + YYDEBUG(329, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy334; + if (yych == 'H') goto yy330; if (yych != 'h') goto yy187; -yy334: - YYDEBUG(334, *YYCURSOR); +yy330: + YYDEBUG(330, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy335; + if (yych == 'O') goto yy331; if (yych != 'o') goto yy187; -yy335: - YYDEBUG(335, *YYCURSOR); +yy331: + YYDEBUG(331, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy336; + if (yych == 'D') goto yy332; if (yych != 'd') goto yy187; -yy336: - YYDEBUG(336, *YYCURSOR); +yy332: + YYDEBUG(332, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(337, *YYCURSOR); + YYDEBUG(333, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(338, *YYCURSOR); + YYDEBUG(334, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(339, *YYCURSOR); + YYDEBUG(335, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1656 "Zend/zend_language_scanner.l" +#line 1615 "Zend/zend_language_scanner.l" { const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL; const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL; - size_t len = 0; - if (class_name) { - len += strlen(class_name) + 2; - } - if (func_name) { - len += strlen(func_name); - } - - zendlval->value.str.len = zend_spprintf(&zendlval->value.str.val, 0, "%s%s%s", + Z_STRLEN_P(zendlval) = zend_spprintf(&Z_STRVAL_P(zendlval), 0, "%s%s%s", class_name ? class_name : "", class_name && func_name ? "::" : "", func_name ? func_name : "" @@ -4337,266 +4273,263 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_METHOD_C; } -#line 4341 "Zend/zend_language_scanner.c" -yy340: - YYDEBUG(340, *YYCURSOR); +#line 4277 "Zend/zend_language_scanner.c" +yy336: + YYDEBUG(336, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy351; - if (yych == 'l') goto yy351; + if (yych == 'L') goto yy347; + if (yych == 'l') goto yy347; goto yy187; -yy341: - YYDEBUG(341, *YYCURSOR); +yy337: + YYDEBUG(337, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy342; + if (yych == 'N') goto yy338; if (yych != 'n') goto yy187; -yy342: - YYDEBUG(342, *YYCURSOR); +yy338: + YYDEBUG(338, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy343; + if (yych == 'C') goto yy339; if (yych != 'c') goto yy187; -yy343: - YYDEBUG(343, *YYCURSOR); +yy339: + YYDEBUG(339, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy344; + if (yych == 'T') goto yy340; if (yych != 't') goto yy187; -yy344: - YYDEBUG(344, *YYCURSOR); +yy340: + YYDEBUG(340, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy345; + if (yych == 'I') goto yy341; if (yych != 'i') goto yy187; -yy345: - YYDEBUG(345, *YYCURSOR); +yy341: + YYDEBUG(341, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy346; + if (yych == 'O') goto yy342; if (yych != 'o') goto yy187; -yy346: - YYDEBUG(346, *YYCURSOR); +yy342: + YYDEBUG(342, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy347; + if (yych == 'N') goto yy343; if (yych != 'n') goto yy187; -yy347: - YYDEBUG(347, *YYCURSOR); +yy343: + YYDEBUG(343, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(348, *YYCURSOR); + YYDEBUG(344, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(349, *YYCURSOR); + YYDEBUG(345, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(350, *YYCURSOR); + YYDEBUG(346, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1640 "Zend/zend_language_scanner.l" +#line 1605 "Zend/zend_language_scanner.l" { - const char *func_name = NULL; - - if (CG(active_op_array)) { - func_name = CG(active_op_array)->function_name; - } - - if (!func_name) { - func_name = ""; + zend_op_array *op_array = CG(active_op_array); + if (op_array && op_array->function_name) { + ZVAL_STRING(zendlval, op_array->function_name, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); } - zendlval->value.str.len = strlen(func_name); - zendlval->value.str.val = estrndup(func_name, zendlval->value.str.len); - zendlval->type = IS_STRING; return T_FUNC_C; } -#line 4408 "Zend/zend_language_scanner.c" -yy351: - YYDEBUG(351, *YYCURSOR); +#line 4338 "Zend/zend_language_scanner.c" +yy347: + YYDEBUG(347, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy352; + if (yych == 'E') goto yy348; if (yych != 'e') goto yy187; -yy352: - YYDEBUG(352, *YYCURSOR); +yy348: + YYDEBUG(348, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(353, *YYCURSOR); + YYDEBUG(349, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(354, *YYCURSOR); + YYDEBUG(350, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(355, *YYCURSOR); + YYDEBUG(351, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1683 "Zend/zend_language_scanner.l" +#line 1633 "Zend/zend_language_scanner.l" { char *filename = zend_get_compiled_filename(TSRMLS_C); if (!filename) { filename = ""; } - zendlval->value.str.len = strlen(filename); - zendlval->value.str.val = estrndup(filename, zendlval->value.str.len); - zendlval->type = IS_STRING; + ZVAL_STRING(zendlval, filename, 1); return T_FILE; } -#line 4440 "Zend/zend_language_scanner.c" -yy356: - YYDEBUG(356, *YYCURSOR); +#line 4368 "Zend/zend_language_scanner.c" +yy352: + YYDEBUG(352, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy357; + if (yych == 'A') goto yy353; if (yych != 'a') goto yy187; -yy357: - YYDEBUG(357, *YYCURSOR); +yy353: + YYDEBUG(353, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy358; + if (yych == 'I') goto yy354; if (yych != 'i') goto yy187; -yy358: - YYDEBUG(358, *YYCURSOR); +yy354: + YYDEBUG(354, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy359; + if (yych == 'T') goto yy355; if (yych != 't') goto yy187; -yy359: - YYDEBUG(359, *YYCURSOR); +yy355: + YYDEBUG(355, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(360, *YYCURSOR); + YYDEBUG(356, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(361, *YYCURSOR); + YYDEBUG(357, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(362, *YYCURSOR); + YYDEBUG(358, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1620 "Zend/zend_language_scanner.l" +#line 1595 "Zend/zend_language_scanner.l" { - const char *trait_name = NULL; - - if (CG(active_class_entry) - && (ZEND_ACC_TRAIT == - (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) { - trait_name = CG(active_class_entry)->name; - } - - if (!trait_name) { - trait_name = ""; + zend_class_entry *ce = CG(active_class_entry); + if (ce && ce->name && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { + ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); } - - zendlval->value.str.len = strlen(trait_name); - zendlval->value.str.val = estrndup(trait_name, zendlval->value.str.len); - zendlval->type = IS_STRING; - return T_TRAIT_C; } -#line 4490 "Zend/zend_language_scanner.c" -yy363: - YYDEBUG(363, *YYCURSOR); +#line 4408 "Zend/zend_language_scanner.c" +yy359: + YYDEBUG(359, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy364; + if (yych == 'A') goto yy360; if (yych != 'a') goto yy187; -yy364: - YYDEBUG(364, *YYCURSOR); +yy360: + YYDEBUG(360, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy365; + if (yych == 'S') goto yy361; if (yych != 's') goto yy187; -yy365: - YYDEBUG(365, *YYCURSOR); +yy361: + YYDEBUG(361, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy366; + if (yych == 'S') goto yy362; if (yych != 's') goto yy187; -yy366: - YYDEBUG(366, *YYCURSOR); +yy362: + YYDEBUG(362, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(367, *YYCURSOR); + YYDEBUG(363, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(368, *YYCURSOR); + YYDEBUG(364, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(369, *YYCURSOR); + YYDEBUG(365, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1593 "Zend/zend_language_scanner.l" +#line 1577 "Zend/zend_language_scanner.l" { - const char *class_name = NULL; - - if (CG(active_class_entry) - && (ZEND_ACC_TRAIT == - (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) { + zend_class_entry *ce = CG(active_class_entry); + if (ce && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { /* We create a special __CLASS__ constant that is going to be resolved at run-time */ - zendlval->value.str.len = sizeof("__CLASS__")-1; - zendlval->value.str.val = estrndup("__CLASS__", zendlval->value.str.len); + Z_STRLEN_P(zendlval) = sizeof("__CLASS__")-1; + Z_STRVAL_P(zendlval) = estrndup("__CLASS__", Z_STRLEN_P(zendlval)); zendlval->type = IS_CONSTANT; } else { - if (CG(active_class_entry)) { - class_name = CG(active_class_entry)->name; - } - - if (!class_name) { - class_name = ""; + if (ce && ce->name) { + ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); } - - zendlval->value.str.len = strlen(class_name); - zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len); - zendlval->type = IS_STRING; } return T_CLASS_C; } -#line 4547 "Zend/zend_language_scanner.c" +#line 4456 "Zend/zend_language_scanner.c" +yy366: + YYDEBUG(366, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy367; + if (yych != 'l') goto yy187; +yy367: + YYDEBUG(367, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy368; + if (yych != 't') goto yy187; +yy368: + YYDEBUG(368, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '_') goto yy187; + YYDEBUG(369, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'C') goto yy370; + if (yych != 'c') goto yy187; yy370: YYDEBUG(370, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy371; - if (yych != 'l') goto yy187; + if (yych == 'O') goto yy371; + if (yych != 'o') goto yy187; yy371: YYDEBUG(371, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy372; - if (yych != 't') goto yy187; + if (yych == 'M') goto yy372; + if (yych != 'm') goto yy187; yy372: YYDEBUG(372, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '_') goto yy187; + if (yych == 'P') goto yy373; + if (yych != 'p') goto yy187; +yy373: YYDEBUG(373, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy374; - if (yych != 'c') goto yy187; + if (yych == 'I') goto yy374; + if (yych != 'i') goto yy187; yy374: YYDEBUG(374, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy375; - if (yych != 'o') goto yy187; + if (yych == 'L') goto yy375; + if (yych != 'l') goto yy187; yy375: YYDEBUG(375, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy376; - if (yych != 'm') goto yy187; + if (yych == 'E') goto yy376; + if (yych != 'e') goto yy187; yy376: YYDEBUG(376, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy377; - if (yych != 'p') goto yy187; + if (yych == 'R') goto yy377; + if (yych != 'r') goto yy187; yy377: YYDEBUG(377, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'I') goto yy378; - if (yych != 'i') goto yy187; -yy378: + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 4) { + goto yy186; + } YYDEBUG(378, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy379; - if (yych != 'l') goto yy187; + yyleng = YYCURSOR - SCNG(yy_text); +#line 1294 "Zend/zend_language_scanner.l" + { + return T_HALT_COMPILER; +} +#line 4522 "Zend/zend_language_scanner.c" yy379: YYDEBUG(379, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy380; - if (yych != 'e') goto yy187; + if (yych == 'S') goto yy383; + if (yych == 's') goto yy383; + goto yy187; yy380: YYDEBUG(380, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy381; - if (yych != 'r') goto yy187; + if (yych == 'E') goto yy381; + if (yych != 'e') goto yy187; yy381: YYDEBUG(381, *YYCURSOR); ++YYCURSOR; @@ -4605,22 +4538,21 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(382, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1302 "Zend/zend_language_scanner.l" +#line 1274 "Zend/zend_language_scanner.l" { - return T_HALT_COMPILER; + return T_USE; } -#line 4613 "Zend/zend_language_scanner.c" +#line 4546 "Zend/zend_language_scanner.c" yy383: YYDEBUG(383, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy387; - if (yych == 's') goto yy387; - goto yy187; + if (yych == 'E') goto yy384; + if (yych != 'e') goto yy187; yy384: YYDEBUG(384, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy385; - if (yych != 'e') goto yy187; + if (yych == 'T') goto yy385; + if (yych != 't') goto yy187; yy385: YYDEBUG(385, *YYCURSOR); ++YYCURSOR; @@ -4629,742 +4561,743 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(386, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1282 "Zend/zend_language_scanner.l" +#line 1322 "Zend/zend_language_scanner.l" { - return T_USE; + return T_UNSET; } -#line 4637 "Zend/zend_language_scanner.c" +#line 4569 "Zend/zend_language_scanner.c" yy387: YYDEBUG(387, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy388; - if (yych != 'e') goto yy187; -yy388: - YYDEBUG(388, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy389; - if (yych != 't') goto yy187; -yy389: - YYDEBUG(389, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 4) { - goto yy186; - } - YYDEBUG(390, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1330 "Zend/zend_language_scanner.l" - { - return T_UNSET; -} -#line 4660 "Zend/zend_language_scanner.c" -yy391: - YYDEBUG(391, *YYCURSOR); ++YYCURSOR; YYFILL(7); yych = *YYCURSOR; -yy392: - YYDEBUG(392, *YYCURSOR); +yy388: + YYDEBUG(388, *YYCURSOR); if (yych <= 'S') { if (yych <= 'D') { if (yych <= ' ') { - if (yych == '\t') goto yy391; + if (yych == '\t') goto yy387; if (yych <= 0x1F) goto yy194; - goto yy391; + goto yy387; } else { if (yych <= 'A') { if (yych <= '@') goto yy194; - goto yy396; + goto yy392; } else { - if (yych <= 'B') goto yy394; + if (yych <= 'B') goto yy390; if (yych <= 'C') goto yy194; - goto yy399; + goto yy395; } } } else { if (yych <= 'I') { - if (yych == 'F') goto yy400; + if (yych == 'F') goto yy396; if (yych <= 'H') goto yy194; - goto yy401; + goto yy397; } else { if (yych <= 'O') { if (yych <= 'N') goto yy194; - goto yy395; + goto yy391; } else { if (yych <= 'Q') goto yy194; - if (yych <= 'R') goto yy398; - goto yy397; + if (yych <= 'R') goto yy394; + goto yy393; } } } } else { if (yych <= 'f') { if (yych <= 'a') { - if (yych == 'U') goto yy393; + if (yych == 'U') goto yy389; if (yych <= '`') goto yy194; - goto yy396; + goto yy392; } else { if (yych <= 'c') { - if (yych <= 'b') goto yy394; + if (yych <= 'b') goto yy390; goto yy194; } else { - if (yych <= 'd') goto yy399; + if (yych <= 'd') goto yy395; if (yych <= 'e') goto yy194; - goto yy400; + goto yy396; } } } else { if (yych <= 'q') { if (yych <= 'i') { if (yych <= 'h') goto yy194; - goto yy401; + goto yy397; } else { - if (yych == 'o') goto yy395; + if (yych == 'o') goto yy391; goto yy194; } } else { if (yych <= 's') { - if (yych <= 'r') goto yy398; - goto yy397; + if (yych <= 'r') goto yy394; + goto yy393; } else { if (yych != 'u') goto yy194; } } } } -yy393: - YYDEBUG(393, *YYCURSOR); +yy389: + YYDEBUG(389, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy460; - if (yych == 'n') goto yy460; + if (yych == 'N') goto yy456; + if (yych == 'n') goto yy456; goto yy194; -yy394: - YYDEBUG(394, *YYCURSOR); +yy390: + YYDEBUG(390, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'I') goto yy447; + if (yych == 'I') goto yy443; if (yych <= 'N') goto yy194; - goto yy448; + goto yy444; } else { if (yych <= 'i') { if (yych <= 'h') goto yy194; - goto yy447; + goto yy443; } else { - if (yych == 'o') goto yy448; + if (yych == 'o') goto yy444; goto yy194; } } +yy391: + YYDEBUG(391, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'B') goto yy435; + if (yych == 'b') goto yy435; + goto yy194; +yy392: + YYDEBUG(392, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'R') goto yy428; + if (yych == 'r') goto yy428; + goto yy194; +yy393: + YYDEBUG(393, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy420; + if (yych == 't') goto yy420; + goto yy194; +yy394: + YYDEBUG(394, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy418; + if (yych == 'e') goto yy418; + goto yy194; yy395: YYDEBUG(395, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy439; - if (yych == 'b') goto yy439; + if (yych == 'O') goto yy414; + if (yych == 'o') goto yy414; goto yy194; yy396: YYDEBUG(396, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy432; - if (yych == 'r') goto yy432; + if (yych == 'L') goto yy407; + if (yych == 'l') goto yy407; goto yy194; yy397: YYDEBUG(397, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy424; - if (yych == 't') goto yy424; - goto yy194; + if (yych == 'N') goto yy398; + if (yych != 'n') goto yy194; yy398: YYDEBUG(398, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy422; - if (yych == 'e') goto yy422; - goto yy194; + if (yych == 'T') goto yy399; + if (yych != 't') goto yy194; yy399: YYDEBUG(399, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy418; - if (yych == 'o') goto yy418; - goto yy194; + if (yych == 'E') goto yy400; + if (yych != 'e') goto yy402; yy400: YYDEBUG(400, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy411; - if (yych == 'l') goto yy411; + if (yych == 'G') goto yy405; + if (yych == 'g') goto yy405; goto yy194; yy401: YYDEBUG(401, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'N') goto yy402; - if (yych != 'n') goto yy194; -yy402: - YYDEBUG(402, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy403; - if (yych != 't') goto yy194; -yy403: - YYDEBUG(403, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy404; - if (yych != 'e') goto yy406; -yy404: - YYDEBUG(404, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'G') goto yy409; - if (yych == 'g') goto yy409; - goto yy194; -yy405: - YYDEBUG(405, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy406: - YYDEBUG(406, *YYCURSOR); +yy402: + YYDEBUG(402, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy405; + if (yych == '\t') goto yy401; goto yy194; } else { - if (yych <= ' ') goto yy405; + if (yych <= ' ') goto yy401; if (yych != ')') goto yy194; } - YYDEBUG(407, *YYCURSOR); + YYDEBUG(403, *YYCURSOR); ++YYCURSOR; - YYDEBUG(408, *YYCURSOR); + YYDEBUG(404, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1230 "Zend/zend_language_scanner.l" +#line 1222 "Zend/zend_language_scanner.l" { return T_INT_CAST; } -#line 4836 "Zend/zend_language_scanner.c" -yy409: - YYDEBUG(409, *YYCURSOR); +#line 4745 "Zend/zend_language_scanner.c" +yy405: + YYDEBUG(405, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy410; + if (yych == 'E') goto yy406; if (yych != 'e') goto yy194; -yy410: - YYDEBUG(410, *YYCURSOR); +yy406: + YYDEBUG(406, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy405; - if (yych == 'r') goto yy405; + if (yych == 'R') goto yy401; + if (yych == 'r') goto yy401; goto yy194; -yy411: - YYDEBUG(411, *YYCURSOR); +yy407: + YYDEBUG(407, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy412; + if (yych == 'O') goto yy408; if (yych != 'o') goto yy194; -yy412: - YYDEBUG(412, *YYCURSOR); +yy408: + YYDEBUG(408, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy413; + if (yych == 'A') goto yy409; if (yych != 'a') goto yy194; -yy413: - YYDEBUG(413, *YYCURSOR); +yy409: + YYDEBUG(409, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy414; + if (yych == 'T') goto yy410; if (yych != 't') goto yy194; -yy414: - YYDEBUG(414, *YYCURSOR); +yy410: + YYDEBUG(410, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(415, *YYCURSOR); + YYDEBUG(411, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy414; + if (yych == '\t') goto yy410; goto yy194; } else { - if (yych <= ' ') goto yy414; + if (yych <= ' ') goto yy410; if (yych != ')') goto yy194; } - YYDEBUG(416, *YYCURSOR); + YYDEBUG(412, *YYCURSOR); ++YYCURSOR; - YYDEBUG(417, *YYCURSOR); + YYDEBUG(413, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1234 "Zend/zend_language_scanner.l" +#line 1226 "Zend/zend_language_scanner.l" { return T_DOUBLE_CAST; } -#line 4884 "Zend/zend_language_scanner.c" -yy418: - YYDEBUG(418, *YYCURSOR); +#line 4793 "Zend/zend_language_scanner.c" +yy414: + YYDEBUG(414, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy419; + if (yych == 'U') goto yy415; if (yych != 'u') goto yy194; -yy419: - YYDEBUG(419, *YYCURSOR); +yy415: + YYDEBUG(415, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy420; + if (yych == 'B') goto yy416; if (yych != 'b') goto yy194; -yy420: - YYDEBUG(420, *YYCURSOR); +yy416: + YYDEBUG(416, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy421; + if (yych == 'L') goto yy417; if (yych != 'l') goto yy194; -yy421: - YYDEBUG(421, *YYCURSOR); +yy417: + YYDEBUG(417, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy414; - if (yych == 'e') goto yy414; + if (yych == 'E') goto yy410; + if (yych == 'e') goto yy410; goto yy194; -yy422: - YYDEBUG(422, *YYCURSOR); +yy418: + YYDEBUG(418, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy423; + if (yych == 'A') goto yy419; if (yych != 'a') goto yy194; -yy423: - YYDEBUG(423, *YYCURSOR); +yy419: + YYDEBUG(419, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy414; - if (yych == 'l') goto yy414; + if (yych == 'L') goto yy410; + if (yych == 'l') goto yy410; goto yy194; -yy424: - YYDEBUG(424, *YYCURSOR); +yy420: + YYDEBUG(420, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy425; + if (yych == 'R') goto yy421; if (yych != 'r') goto yy194; -yy425: - YYDEBUG(425, *YYCURSOR); +yy421: + YYDEBUG(421, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy426; + if (yych == 'I') goto yy422; if (yych != 'i') goto yy194; -yy426: - YYDEBUG(426, *YYCURSOR); +yy422: + YYDEBUG(422, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy427; + if (yych == 'N') goto yy423; if (yych != 'n') goto yy194; -yy427: - YYDEBUG(427, *YYCURSOR); +yy423: + YYDEBUG(423, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'G') goto yy428; + if (yych == 'G') goto yy424; if (yych != 'g') goto yy194; -yy428: - YYDEBUG(428, *YYCURSOR); +yy424: + YYDEBUG(424, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(429, *YYCURSOR); + YYDEBUG(425, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy428; + if (yych == '\t') goto yy424; goto yy194; } else { - if (yych <= ' ') goto yy428; + if (yych <= ' ') goto yy424; if (yych != ')') goto yy194; } - YYDEBUG(430, *YYCURSOR); + YYDEBUG(426, *YYCURSOR); ++YYCURSOR; - YYDEBUG(431, *YYCURSOR); + YYDEBUG(427, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1238 "Zend/zend_language_scanner.l" +#line 1230 "Zend/zend_language_scanner.l" { return T_STRING_CAST; } -#line 4958 "Zend/zend_language_scanner.c" -yy432: - YYDEBUG(432, *YYCURSOR); +#line 4867 "Zend/zend_language_scanner.c" +yy428: + YYDEBUG(428, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy433; + if (yych == 'R') goto yy429; if (yych != 'r') goto yy194; -yy433: - YYDEBUG(433, *YYCURSOR); +yy429: + YYDEBUG(429, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy434; + if (yych == 'A') goto yy430; if (yych != 'a') goto yy194; -yy434: - YYDEBUG(434, *YYCURSOR); +yy430: + YYDEBUG(430, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy435; + if (yych == 'Y') goto yy431; if (yych != 'y') goto yy194; -yy435: - YYDEBUG(435, *YYCURSOR); +yy431: + YYDEBUG(431, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(436, *YYCURSOR); + YYDEBUG(432, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy435; + if (yych == '\t') goto yy431; goto yy194; } else { - if (yych <= ' ') goto yy435; + if (yych <= ' ') goto yy431; if (yych != ')') goto yy194; } - YYDEBUG(437, *YYCURSOR); + YYDEBUG(433, *YYCURSOR); ++YYCURSOR; - YYDEBUG(438, *YYCURSOR); + YYDEBUG(434, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1242 "Zend/zend_language_scanner.l" +#line 1234 "Zend/zend_language_scanner.l" { return T_ARRAY_CAST; } -#line 4995 "Zend/zend_language_scanner.c" -yy439: - YYDEBUG(439, *YYCURSOR); +#line 4904 "Zend/zend_language_scanner.c" +yy435: + YYDEBUG(435, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'J') goto yy440; + if (yych == 'J') goto yy436; if (yych != 'j') goto yy194; -yy440: - YYDEBUG(440, *YYCURSOR); +yy436: + YYDEBUG(436, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy441; + if (yych == 'E') goto yy437; if (yych != 'e') goto yy194; -yy441: - YYDEBUG(441, *YYCURSOR); +yy437: + YYDEBUG(437, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy442; + if (yych == 'C') goto yy438; if (yych != 'c') goto yy194; -yy442: - YYDEBUG(442, *YYCURSOR); +yy438: + YYDEBUG(438, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy443; + if (yych == 'T') goto yy439; if (yych != 't') goto yy194; -yy443: - YYDEBUG(443, *YYCURSOR); +yy439: + YYDEBUG(439, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(444, *YYCURSOR); + YYDEBUG(440, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy443; + if (yych == '\t') goto yy439; goto yy194; } else { - if (yych <= ' ') goto yy443; + if (yych <= ' ') goto yy439; if (yych != ')') goto yy194; } - YYDEBUG(445, *YYCURSOR); + YYDEBUG(441, *YYCURSOR); ++YYCURSOR; - YYDEBUG(446, *YYCURSOR); + YYDEBUG(442, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1246 "Zend/zend_language_scanner.l" +#line 1238 "Zend/zend_language_scanner.l" { return T_OBJECT_CAST; } -#line 5037 "Zend/zend_language_scanner.c" -yy447: - YYDEBUG(447, *YYCURSOR); +#line 4946 "Zend/zend_language_scanner.c" +yy443: + YYDEBUG(443, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy457; - if (yych == 'n') goto yy457; + if (yych == 'N') goto yy453; + if (yych == 'n') goto yy453; goto yy194; -yy448: - YYDEBUG(448, *YYCURSOR); +yy444: + YYDEBUG(444, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy449; + if (yych == 'O') goto yy445; if (yych != 'o') goto yy194; -yy449: - YYDEBUG(449, *YYCURSOR); +yy445: + YYDEBUG(445, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy450; + if (yych == 'L') goto yy446; if (yych != 'l') goto yy194; -yy450: - YYDEBUG(450, *YYCURSOR); +yy446: + YYDEBUG(446, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy455; - if (yych == 'e') goto yy455; - goto yy452; -yy451: - YYDEBUG(451, *YYCURSOR); + if (yych == 'E') goto yy451; + if (yych == 'e') goto yy451; + goto yy448; +yy447: + YYDEBUG(447, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy452: - YYDEBUG(452, *YYCURSOR); +yy448: + YYDEBUG(448, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy451; + if (yych == '\t') goto yy447; goto yy194; } else { - if (yych <= ' ') goto yy451; + if (yych <= ' ') goto yy447; if (yych != ')') goto yy194; } - YYDEBUG(453, *YYCURSOR); + YYDEBUG(449, *YYCURSOR); ++YYCURSOR; - YYDEBUG(454, *YYCURSOR); + YYDEBUG(450, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1250 "Zend/zend_language_scanner.l" +#line 1242 "Zend/zend_language_scanner.l" { return T_BOOL_CAST; } -#line 5082 "Zend/zend_language_scanner.c" -yy455: - YYDEBUG(455, *YYCURSOR); +#line 4991 "Zend/zend_language_scanner.c" +yy451: + YYDEBUG(451, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy456; + if (yych == 'A') goto yy452; if (yych != 'a') goto yy194; -yy456: - YYDEBUG(456, *YYCURSOR); +yy452: + YYDEBUG(452, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy451; - if (yych == 'n') goto yy451; + if (yych == 'N') goto yy447; + if (yych == 'n') goto yy447; goto yy194; -yy457: - YYDEBUG(457, *YYCURSOR); +yy453: + YYDEBUG(453, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy458; + if (yych == 'A') goto yy454; if (yych != 'a') goto yy194; -yy458: - YYDEBUG(458, *YYCURSOR); +yy454: + YYDEBUG(454, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy459; + if (yych == 'R') goto yy455; if (yych != 'r') goto yy194; -yy459: - YYDEBUG(459, *YYCURSOR); +yy455: + YYDEBUG(455, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy428; - if (yych == 'y') goto yy428; + if (yych == 'Y') goto yy424; + if (yych == 'y') goto yy424; goto yy194; -yy460: - YYDEBUG(460, *YYCURSOR); +yy456: + YYDEBUG(456, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy461; + if (yych == 'S') goto yy457; if (yych != 's') goto yy194; -yy461: - YYDEBUG(461, *YYCURSOR); +yy457: + YYDEBUG(457, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy462; + if (yych == 'E') goto yy458; if (yych != 'e') goto yy194; -yy462: - YYDEBUG(462, *YYCURSOR); +yy458: + YYDEBUG(458, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy463; + if (yych == 'T') goto yy459; if (yych != 't') goto yy194; -yy463: - YYDEBUG(463, *YYCURSOR); +yy459: + YYDEBUG(459, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(464, *YYCURSOR); + YYDEBUG(460, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy463; + if (yych == '\t') goto yy459; goto yy194; } else { - if (yych <= ' ') goto yy463; + if (yych <= ' ') goto yy459; if (yych != ')') goto yy194; } - YYDEBUG(465, *YYCURSOR); + YYDEBUG(461, *YYCURSOR); ++YYCURSOR; - YYDEBUG(466, *YYCURSOR); + YYDEBUG(462, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1254 "Zend/zend_language_scanner.l" +#line 1246 "Zend/zend_language_scanner.l" { return T_UNSET_CAST; } -#line 5146 "Zend/zend_language_scanner.c" -yy467: - YYDEBUG(467, *YYCURSOR); +#line 5055 "Zend/zend_language_scanner.c" +yy463: + YYDEBUG(463, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy468; + if (yych == 'R') goto yy464; if (yych != 'r') goto yy187; -yy468: - YYDEBUG(468, *YYCURSOR); +yy464: + YYDEBUG(464, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(469, *YYCURSOR); + YYDEBUG(465, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1226 "Zend/zend_language_scanner.l" +#line 1218 "Zend/zend_language_scanner.l" { return T_VAR; } -#line 5164 "Zend/zend_language_scanner.c" -yy470: - YYDEBUG(470, *YYCURSOR); +#line 5073 "Zend/zend_language_scanner.c" +yy466: + YYDEBUG(466, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy474; - if (yych == 'm') goto yy474; + if (yych == 'M') goto yy470; + if (yych == 'm') goto yy470; goto yy187; -yy471: - YYDEBUG(471, *YYCURSOR); +yy467: + YYDEBUG(467, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy472; + if (yych == 'W') goto yy468; if (yych != 'w') goto yy187; -yy472: - YYDEBUG(472, *YYCURSOR); +yy468: + YYDEBUG(468, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(473, *YYCURSOR); + YYDEBUG(469, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1218 "Zend/zend_language_scanner.l" +#line 1210 "Zend/zend_language_scanner.l" { return T_NEW; } -#line 5188 "Zend/zend_language_scanner.c" -yy474: - YYDEBUG(474, *YYCURSOR); +#line 5097 "Zend/zend_language_scanner.c" +yy470: + YYDEBUG(470, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy475; + if (yych == 'E') goto yy471; if (yych != 'e') goto yy187; -yy475: - YYDEBUG(475, *YYCURSOR); +yy471: + YYDEBUG(471, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy476; + if (yych == 'S') goto yy472; if (yych != 's') goto yy187; -yy476: - YYDEBUG(476, *YYCURSOR); +yy472: + YYDEBUG(472, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy477; + if (yych == 'P') goto yy473; if (yych != 'p') goto yy187; -yy477: - YYDEBUG(477, *YYCURSOR); +yy473: + YYDEBUG(473, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy478; + if (yych == 'A') goto yy474; if (yych != 'a') goto yy187; -yy478: - YYDEBUG(478, *YYCURSOR); +yy474: + YYDEBUG(474, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy479; + if (yych == 'C') goto yy475; if (yych != 'c') goto yy187; -yy479: - YYDEBUG(479, *YYCURSOR); +yy475: + YYDEBUG(475, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy480; + if (yych == 'E') goto yy476; if (yych != 'e') goto yy187; -yy480: - YYDEBUG(480, *YYCURSOR); +yy476: + YYDEBUG(476, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(481, *YYCURSOR); + YYDEBUG(477, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1278 "Zend/zend_language_scanner.l" +#line 1270 "Zend/zend_language_scanner.l" { return T_NAMESPACE; } -#line 5231 "Zend/zend_language_scanner.c" +#line 5140 "Zend/zend_language_scanner.c" +yy478: + YYDEBUG(478, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(479, *YYCURSOR); + if (yych <= 'D') { + if (yych <= '/') goto yy190; + if (yych <= '9') goto yy478; + goto yy190; + } else { + if (yych <= 'E') goto yy193; + if (yych == 'e') goto yy193; + goto yy190; + } +yy480: + YYDEBUG(480, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(481, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 1390 "Zend/zend_language_scanner.l" + { + return T_CONCAT_EQUAL; +} +#line 5166 "Zend/zend_language_scanner.c" yy482: YYDEBUG(482, *YYCURSOR); - ++YYCURSOR; + yych = *++YYCURSOR; + if (yych != '.') goto yy194; YYDEBUG(483, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(484, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1210 "Zend/zend_language_scanner.l" +#line 1206 "Zend/zend_language_scanner.l" + { + return T_ELLIPSIS; +} +#line 5179 "Zend/zend_language_scanner.c" +yy485: + YYDEBUG(485, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(486, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 1198 "Zend/zend_language_scanner.l" { return T_PAAMAYIM_NEKUDOTAYIM; } -#line 5241 "Zend/zend_language_scanner.c" -yy484: - YYDEBUG(484, *YYCURSOR); +#line 5189 "Zend/zend_language_scanner.c" +yy487: + YYDEBUG(487, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy485: - YYDEBUG(485, *YYCURSOR); +yy488: + YYDEBUG(488, *YYCURSOR); if (yych <= '\f') { if (yych <= 0x08) goto yy141; - if (yych <= '\n') goto yy484; + if (yych <= '\n') goto yy487; goto yy141; } else { - if (yych <= '\r') goto yy484; - if (yych == ' ') goto yy484; + if (yych <= '\r') goto yy487; + if (yych == ' ') goto yy487; goto yy141; } -yy486: - YYDEBUG(486, *YYCURSOR); +yy489: + YYDEBUG(489, *YYCURSOR); ++YYCURSOR; - YYDEBUG(487, *YYCURSOR); + YYDEBUG(490, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1386 "Zend/zend_language_scanner.l" +#line 1378 "Zend/zend_language_scanner.l" { return T_MINUS_EQUAL; } -#line 5267 "Zend/zend_language_scanner.c" -yy488: - YYDEBUG(488, *YYCURSOR); +#line 5215 "Zend/zend_language_scanner.c" +yy491: + YYDEBUG(491, *YYCURSOR); ++YYCURSOR; - YYDEBUG(489, *YYCURSOR); + YYDEBUG(492, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1354 "Zend/zend_language_scanner.l" +#line 1346 "Zend/zend_language_scanner.l" { return T_DEC; } -#line 5277 "Zend/zend_language_scanner.c" -yy490: - YYDEBUG(490, *YYCURSOR); +#line 5225 "Zend/zend_language_scanner.c" +yy493: + YYDEBUG(493, *YYCURSOR); ++YYCURSOR; - YYDEBUG(491, *YYCURSOR); + YYDEBUG(494, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1180 "Zend/zend_language_scanner.l" +#line 1170 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); return T_OBJECT_OPERATOR; } -#line 5288 "Zend/zend_language_scanner.c" -yy492: - YYDEBUG(492, *YYCURSOR); +#line 5236 "Zend/zend_language_scanner.c" +yy495: + YYDEBUG(495, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'I') goto yy499; + if (yych == 'I') goto yy502; if (yych <= 'N') goto yy187; - goto yy500; + goto yy503; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; - goto yy499; + goto yy502; } else { - if (yych == 'o') goto yy500; + if (yych == 'o') goto yy503; goto yy187; } } -yy493: - YYDEBUG(493, *YYCURSOR); +yy496: + YYDEBUG(496, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy494; + if (yych == 'B') goto yy497; if (yych != 'b') goto yy187; -yy494: - YYDEBUG(494, *YYCURSOR); +yy497: + YYDEBUG(497, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy495; + if (yych == 'L') goto yy498; if (yych != 'l') goto yy187; -yy495: - YYDEBUG(495, *YYCURSOR); +yy498: + YYDEBUG(498, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy496; + if (yych == 'I') goto yy499; if (yych != 'i') goto yy187; -yy496: - YYDEBUG(496, *YYCURSOR); +yy499: + YYDEBUG(499, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy497; + if (yych == 'C') goto yy500; if (yych != 'c') goto yy187; -yy497: - YYDEBUG(497, *YYCURSOR); +yy500: + YYDEBUG(500, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(498, *YYCURSOR); + YYDEBUG(501, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1326 "Zend/zend_language_scanner.l" +#line 1318 "Zend/zend_language_scanner.l" { return T_PUBLIC; } -#line 5337 "Zend/zend_language_scanner.c" -yy499: - YYDEBUG(499, *YYCURSOR); +#line 5285 "Zend/zend_language_scanner.c" +yy502: + YYDEBUG(502, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'V') { - if (yych == 'N') goto yy508; + if (yych == 'N') goto yy511; if (yych <= 'U') goto yy187; - goto yy509; + goto yy512; } else { if (yych <= 'n') { if (yych <= 'm') goto yy187; - goto yy508; + goto yy511; } else { - if (yych == 'v') goto yy509; + if (yych == 'v') goto yy512; goto yy187; } } -yy500: - YYDEBUG(500, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy501; - if (yych != 't') goto yy187; -yy501: - YYDEBUG(501, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy502; - if (yych != 'e') goto yy187; -yy502: - YYDEBUG(502, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'C') goto yy503; - if (yych != 'c') goto yy187; yy503: YYDEBUG(503, *YYCURSOR); yych = *++YYCURSOR; @@ -5378,1112 +5311,1112 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy505: YYDEBUG(505, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy506; - if (yych != 'd') goto yy187; + if (yych == 'C') goto yy506; + if (yych != 'c') goto yy187; yy506: YYDEBUG(506, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy507; + if (yych != 't') goto yy187; +yy507: + YYDEBUG(507, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy508; + if (yych != 'e') goto yy187; +yy508: + YYDEBUG(508, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'D') goto yy509; + if (yych != 'd') goto yy187; +yy509: + YYDEBUG(509, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(507, *YYCURSOR); + YYDEBUG(510, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1322 "Zend/zend_language_scanner.l" +#line 1314 "Zend/zend_language_scanner.l" { return T_PROTECTED; } -#line 5396 "Zend/zend_language_scanner.c" -yy508: - YYDEBUG(508, *YYCURSOR); +#line 5344 "Zend/zend_language_scanner.c" +yy511: + YYDEBUG(511, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy514; - if (yych == 't') goto yy514; + if (yych == 'T') goto yy517; + if (yych == 't') goto yy517; goto yy187; -yy509: - YYDEBUG(509, *YYCURSOR); +yy512: + YYDEBUG(512, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy510; + if (yych == 'A') goto yy513; if (yych != 'a') goto yy187; -yy510: - YYDEBUG(510, *YYCURSOR); +yy513: + YYDEBUG(513, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy511; + if (yych == 'T') goto yy514; if (yych != 't') goto yy187; -yy511: - YYDEBUG(511, *YYCURSOR); +yy514: + YYDEBUG(514, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy512; + if (yych == 'E') goto yy515; if (yych != 'e') goto yy187; -yy512: - YYDEBUG(512, *YYCURSOR); +yy515: + YYDEBUG(515, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(513, *YYCURSOR); + YYDEBUG(516, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1318 "Zend/zend_language_scanner.l" +#line 1310 "Zend/zend_language_scanner.l" { return T_PRIVATE; } -#line 5430 "Zend/zend_language_scanner.c" -yy514: - YYDEBUG(514, *YYCURSOR); +#line 5378 "Zend/zend_language_scanner.c" +yy517: + YYDEBUG(517, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(515, *YYCURSOR); + YYDEBUG(518, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1156 "Zend/zend_language_scanner.l" +#line 1146 "Zend/zend_language_scanner.l" { return T_PRINT; } -#line 5443 "Zend/zend_language_scanner.c" -yy516: - YYDEBUG(516, *YYCURSOR); +#line 5391 "Zend/zend_language_scanner.c" +yy519: + YYDEBUG(519, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy521; - if (yych == 'o') goto yy521; + if (yych == 'O') goto yy524; + if (yych == 'o') goto yy524; goto yy187; -yy517: - YYDEBUG(517, *YYCURSOR); +yy520: + YYDEBUG(520, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy518; + if (yych == 'T') goto yy521; if (yych != 't') goto yy187; -yy518: - YYDEBUG(518, *YYCURSOR); +yy521: + YYDEBUG(521, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy519; + if (yych == 'O') goto yy522; if (yych != 'o') goto yy187; -yy519: - YYDEBUG(519, *YYCURSOR); +yy522: + YYDEBUG(522, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(520, *YYCURSOR); + YYDEBUG(523, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1148 "Zend/zend_language_scanner.l" +#line 1138 "Zend/zend_language_scanner.l" { return T_GOTO; } -#line 5472 "Zend/zend_language_scanner.c" -yy521: - YYDEBUG(521, *YYCURSOR); +#line 5420 "Zend/zend_language_scanner.c" +yy524: + YYDEBUG(524, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy522; + if (yych == 'B') goto yy525; if (yych != 'b') goto yy187; -yy522: - YYDEBUG(522, *YYCURSOR); +yy525: + YYDEBUG(525, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy523; + if (yych == 'A') goto yy526; if (yych != 'a') goto yy187; -yy523: - YYDEBUG(523, *YYCURSOR); +yy526: + YYDEBUG(526, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy524; + if (yych == 'L') goto yy527; if (yych != 'l') goto yy187; -yy524: - YYDEBUG(524, *YYCURSOR); +yy527: + YYDEBUG(527, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(525, *YYCURSOR); + YYDEBUG(528, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1290 "Zend/zend_language_scanner.l" +#line 1282 "Zend/zend_language_scanner.l" { return T_GLOBAL; } -#line 5500 "Zend/zend_language_scanner.c" -yy526: - YYDEBUG(526, *YYCURSOR); +#line 5448 "Zend/zend_language_scanner.c" +yy529: + YYDEBUG(529, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '<') goto yy534; + if (yych == '<') goto yy537; goto yy194; -yy527: - YYDEBUG(527, *YYCURSOR); +yy530: + YYDEBUG(530, *YYCURSOR); yych = *++YYCURSOR; goto yy181; -yy528: - YYDEBUG(528, *YYCURSOR); +yy531: + YYDEBUG(531, *YYCURSOR); yych = *++YYCURSOR; goto yy179; -yy529: - YYDEBUG(529, *YYCURSOR); +yy532: + YYDEBUG(532, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy530; + if (yych == 'E') goto yy533; if (yych != 'e') goto yy187; -yy530: - YYDEBUG(530, *YYCURSOR); +yy533: + YYDEBUG(533, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy531; + if (yych == 'A') goto yy534; if (yych != 'a') goto yy187; -yy531: - YYDEBUG(531, *YYCURSOR); +yy534: + YYDEBUG(534, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'K') goto yy532; + if (yych == 'K') goto yy535; if (yych != 'k') goto yy187; -yy532: - YYDEBUG(532, *YYCURSOR); +yy535: + YYDEBUG(535, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(533, *YYCURSOR); + YYDEBUG(536, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1140 "Zend/zend_language_scanner.l" +#line 1130 "Zend/zend_language_scanner.l" { return T_BREAK; } -#line 5541 "Zend/zend_language_scanner.c" -yy534: - YYDEBUG(534, *YYCURSOR); +#line 5489 "Zend/zend_language_scanner.c" +yy537: + YYDEBUG(537, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '<') goto yy270; + if (yych == '<') goto yy266; goto yy194; -yy535: - YYDEBUG(535, *YYCURSOR); +yy538: + YYDEBUG(538, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy542; - if (yych == 'a') goto yy542; + if (yych == 'A') goto yy545; + if (yych == 'a') goto yy545; goto yy187; -yy536: - YYDEBUG(536, *YYCURSOR); +yy539: + YYDEBUG(539, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy537; + if (yych == 'I') goto yy540; if (yych != 'i') goto yy187; -yy537: - YYDEBUG(537, *YYCURSOR); +yy540: + YYDEBUG(540, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy538; + if (yych == 'T') goto yy541; if (yych != 't') goto yy187; -yy538: - YYDEBUG(538, *YYCURSOR); +yy541: + YYDEBUG(541, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy539; + if (yych == 'C') goto yy542; if (yych != 'c') goto yy187; -yy539: - YYDEBUG(539, *YYCURSOR); +yy542: + YYDEBUG(542, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy540; + if (yych == 'H') goto yy543; if (yych != 'h') goto yy187; -yy540: - YYDEBUG(540, *YYCURSOR); +yy543: + YYDEBUG(543, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(541, *YYCURSOR); + YYDEBUG(544, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1124 "Zend/zend_language_scanner.l" +#line 1114 "Zend/zend_language_scanner.l" { return T_SWITCH; } -#line 5585 "Zend/zend_language_scanner.c" -yy542: - YYDEBUG(542, *YYCURSOR); +#line 5533 "Zend/zend_language_scanner.c" +yy545: + YYDEBUG(545, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy543; + if (yych == 'T') goto yy546; if (yych != 't') goto yy187; -yy543: - YYDEBUG(543, *YYCURSOR); +yy546: + YYDEBUG(546, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy544; + if (yych == 'I') goto yy547; if (yych != 'i') goto yy187; -yy544: - YYDEBUG(544, *YYCURSOR); +yy547: + YYDEBUG(547, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy545; + if (yych == 'C') goto yy548; if (yych != 'c') goto yy187; -yy545: - YYDEBUG(545, *YYCURSOR); +yy548: + YYDEBUG(548, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(546, *YYCURSOR); + YYDEBUG(549, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1306 "Zend/zend_language_scanner.l" +#line 1298 "Zend/zend_language_scanner.l" { return T_STATIC; } -#line 5613 "Zend/zend_language_scanner.c" -yy547: - YYDEBUG(547, *YYCURSOR); +#line 5561 "Zend/zend_language_scanner.c" +yy550: + YYDEBUG(550, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy558; - if (yych == 's') goto yy558; + if (yych == 'S') goto yy561; + if (yych == 's') goto yy561; goto yy187; -yy548: - YYDEBUG(548, *YYCURSOR); +yy551: + YYDEBUG(551, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy556; - if (yych == 'd') goto yy556; + if (yych == 'D') goto yy559; + if (yych == 'd') goto yy559; goto yy187; -yy549: - YYDEBUG(549, *YYCURSOR); +yy552: + YYDEBUG(552, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy552; - if (yych == 'r') goto yy552; + if (yych == 'R') goto yy555; + if (yych == 'r') goto yy555; goto yy187; -yy550: - YYDEBUG(550, *YYCURSOR); +yy553: + YYDEBUG(553, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(551, *YYCURSOR); + YYDEBUG(554, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1120 "Zend/zend_language_scanner.l" +#line 1110 "Zend/zend_language_scanner.l" { return T_AS; } -#line 5644 "Zend/zend_language_scanner.c" -yy552: - YYDEBUG(552, *YYCURSOR); +#line 5592 "Zend/zend_language_scanner.c" +yy555: + YYDEBUG(555, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy553; + if (yych == 'A') goto yy556; if (yych != 'a') goto yy187; -yy553: - YYDEBUG(553, *YYCURSOR); +yy556: + YYDEBUG(556, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy554; + if (yych == 'Y') goto yy557; if (yych != 'y') goto yy187; -yy554: - YYDEBUG(554, *YYCURSOR); +yy557: + YYDEBUG(557, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(555, *YYCURSOR); + YYDEBUG(558, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1342 "Zend/zend_language_scanner.l" +#line 1334 "Zend/zend_language_scanner.l" { return T_ARRAY; } -#line 5667 "Zend/zend_language_scanner.c" -yy556: - YYDEBUG(556, *YYCURSOR); +#line 5615 "Zend/zend_language_scanner.c" +yy559: + YYDEBUG(559, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(557, *YYCURSOR); + YYDEBUG(560, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1438 "Zend/zend_language_scanner.l" +#line 1430 "Zend/zend_language_scanner.l" { return T_LOGICAL_AND; } -#line 5680 "Zend/zend_language_scanner.c" -yy558: - YYDEBUG(558, *YYCURSOR); +#line 5628 "Zend/zend_language_scanner.c" +yy561: + YYDEBUG(561, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy559; + if (yych == 'T') goto yy562; if (yych != 't') goto yy187; -yy559: - YYDEBUG(559, *YYCURSOR); +yy562: + YYDEBUG(562, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy560; + if (yych == 'R') goto yy563; if (yych != 'r') goto yy187; -yy560: - YYDEBUG(560, *YYCURSOR); +yy563: + YYDEBUG(563, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy561; + if (yych == 'A') goto yy564; if (yych != 'a') goto yy187; -yy561: - YYDEBUG(561, *YYCURSOR); +yy564: + YYDEBUG(564, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy562; + if (yych == 'C') goto yy565; if (yych != 'c') goto yy187; -yy562: - YYDEBUG(562, *YYCURSOR); +yy565: + YYDEBUG(565, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy563; + if (yych == 'T') goto yy566; if (yych != 't') goto yy187; -yy563: - YYDEBUG(563, *YYCURSOR); +yy566: + YYDEBUG(566, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(564, *YYCURSOR); + YYDEBUG(567, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1310 "Zend/zend_language_scanner.l" +#line 1302 "Zend/zend_language_scanner.l" { return T_ABSTRACT; } -#line 5718 "Zend/zend_language_scanner.c" -yy565: - YYDEBUG(565, *YYCURSOR); +#line 5666 "Zend/zend_language_scanner.c" +yy568: + YYDEBUG(568, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy566; + if (yych == 'I') goto yy569; if (yych != 'i') goto yy187; -yy566: - YYDEBUG(566, *YYCURSOR); +yy569: + YYDEBUG(569, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy567; + if (yych == 'L') goto yy570; if (yych != 'l') goto yy187; -yy567: - YYDEBUG(567, *YYCURSOR); +yy570: + YYDEBUG(570, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy568; + if (yych == 'E') goto yy571; if (yych != 'e') goto yy187; -yy568: - YYDEBUG(568, *YYCURSOR); +yy571: + YYDEBUG(571, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(569, *YYCURSOR); + YYDEBUG(572, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1080 "Zend/zend_language_scanner.l" +#line 1070 "Zend/zend_language_scanner.l" { return T_WHILE; } -#line 5746 "Zend/zend_language_scanner.c" -yy570: - YYDEBUG(570, *YYCURSOR); +#line 5694 "Zend/zend_language_scanner.c" +yy573: + YYDEBUG(573, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(571, *YYCURSOR); + YYDEBUG(574, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1064 "Zend/zend_language_scanner.l" +#line 1054 "Zend/zend_language_scanner.l" { return T_IF; } -#line 5759 "Zend/zend_language_scanner.c" -yy572: - YYDEBUG(572, *YYCURSOR); +#line 5707 "Zend/zend_language_scanner.c" +yy575: + YYDEBUG(575, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy614; - if (yych == 'p') goto yy614; + if (yych == 'P') goto yy617; + if (yych == 'p') goto yy617; goto yy187; -yy573: - YYDEBUG(573, *YYCURSOR); +yy576: + YYDEBUG(576, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'C') { if (yych <= 'B') goto yy187; - goto yy581; + goto yy584; } else { if (yych <= 'R') goto yy187; - if (yych <= 'S') goto yy579; - goto yy580; + if (yych <= 'S') goto yy582; + goto yy583; } } else { if (yych <= 'r') { - if (yych == 'c') goto yy581; + if (yych == 'c') goto yy584; goto yy187; } else { - if (yych <= 's') goto yy579; - if (yych <= 't') goto yy580; + if (yych <= 's') goto yy582; + if (yych <= 't') goto yy583; goto yy187; } } -yy574: - YYDEBUG(574, *YYCURSOR); +yy577: + YYDEBUG(577, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy575; + if (yych == 'S') goto yy578; if (yych != 's') goto yy187; -yy575: - YYDEBUG(575, *YYCURSOR); +yy578: + YYDEBUG(578, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy576; + if (yych == 'E') goto yy579; if (yych != 'e') goto yy187; -yy576: - YYDEBUG(576, *YYCURSOR); +yy579: + YYDEBUG(579, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy577; + if (yych == 'T') goto yy580; if (yych != 't') goto yy187; -yy577: - YYDEBUG(577, *YYCURSOR); +yy580: + YYDEBUG(580, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(578, *YYCURSOR); + YYDEBUG(581, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1294 "Zend/zend_language_scanner.l" +#line 1286 "Zend/zend_language_scanner.l" { return T_ISSET; } -#line 5815 "Zend/zend_language_scanner.c" -yy579: - YYDEBUG(579, *YYCURSOR); +#line 5763 "Zend/zend_language_scanner.c" +yy582: + YYDEBUG(582, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy600; - if (yych == 't') goto yy600; + if (yych == 'T') goto yy603; + if (yych == 't') goto yy603; goto yy187; -yy580: - YYDEBUG(580, *YYCURSOR); +yy583: + YYDEBUG(583, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy593; - if (yych == 'e') goto yy593; + if (yych == 'E') goto yy596; + if (yych == 'e') goto yy596; goto yy187; -yy581: - YYDEBUG(581, *YYCURSOR); +yy584: + YYDEBUG(584, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy582; + if (yych == 'L') goto yy585; if (yych != 'l') goto yy187; -yy582: - YYDEBUG(582, *YYCURSOR); +yy585: + YYDEBUG(585, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy583; + if (yych == 'U') goto yy586; if (yych != 'u') goto yy187; -yy583: - YYDEBUG(583, *YYCURSOR); +yy586: + YYDEBUG(586, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy584; + if (yych == 'D') goto yy587; if (yych != 'd') goto yy187; -yy584: - YYDEBUG(584, *YYCURSOR); +yy587: + YYDEBUG(587, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy585; + if (yych == 'E') goto yy588; if (yych != 'e') goto yy187; -yy585: - YYDEBUG(585, *YYCURSOR); +yy588: + YYDEBUG(588, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '9') { if (yych >= '0') goto yy186; } else { - if (yych <= '@') goto yy586; + if (yych <= '@') goto yy589; if (yych <= 'Z') goto yy186; } } else { if (yych <= '`') { - if (yych <= '_') goto yy587; + if (yych <= '_') goto yy590; } else { if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy586: - YYDEBUG(586, *YYCURSOR); +yy589: + YYDEBUG(589, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1262 "Zend/zend_language_scanner.l" +#line 1254 "Zend/zend_language_scanner.l" { return T_INCLUDE; } -#line 5873 "Zend/zend_language_scanner.c" -yy587: - YYDEBUG(587, *YYCURSOR); +#line 5821 "Zend/zend_language_scanner.c" +yy590: + YYDEBUG(590, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy588; + if (yych == 'O') goto yy591; if (yych != 'o') goto yy187; -yy588: - YYDEBUG(588, *YYCURSOR); +yy591: + YYDEBUG(591, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy589; + if (yych == 'N') goto yy592; if (yych != 'n') goto yy187; -yy589: - YYDEBUG(589, *YYCURSOR); +yy592: + YYDEBUG(592, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy590; + if (yych == 'C') goto yy593; if (yych != 'c') goto yy187; -yy590: - YYDEBUG(590, *YYCURSOR); +yy593: + YYDEBUG(593, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy591; + if (yych == 'E') goto yy594; if (yych != 'e') goto yy187; -yy591: - YYDEBUG(591, *YYCURSOR); +yy594: + YYDEBUG(594, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(592, *YYCURSOR); + YYDEBUG(595, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1266 "Zend/zend_language_scanner.l" +#line 1258 "Zend/zend_language_scanner.l" { return T_INCLUDE_ONCE; } -#line 5906 "Zend/zend_language_scanner.c" -yy593: - YYDEBUG(593, *YYCURSOR); +#line 5854 "Zend/zend_language_scanner.c" +yy596: + YYDEBUG(596, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy594; + if (yych == 'R') goto yy597; if (yych != 'r') goto yy187; -yy594: - YYDEBUG(594, *YYCURSOR); +yy597: + YYDEBUG(597, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy595; + if (yych == 'F') goto yy598; if (yych != 'f') goto yy187; -yy595: - YYDEBUG(595, *YYCURSOR); +yy598: + YYDEBUG(598, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy596; + if (yych == 'A') goto yy599; if (yych != 'a') goto yy187; -yy596: - YYDEBUG(596, *YYCURSOR); +yy599: + YYDEBUG(599, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy597; + if (yych == 'C') goto yy600; if (yych != 'c') goto yy187; -yy597: - YYDEBUG(597, *YYCURSOR); +yy600: + YYDEBUG(600, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy598; + if (yych == 'E') goto yy601; if (yych != 'e') goto yy187; -yy598: - YYDEBUG(598, *YYCURSOR); +yy601: + YYDEBUG(601, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(599, *YYCURSOR); + YYDEBUG(602, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1164 "Zend/zend_language_scanner.l" +#line 1154 "Zend/zend_language_scanner.l" { return T_INTERFACE; } -#line 5944 "Zend/zend_language_scanner.c" -yy600: - YYDEBUG(600, *YYCURSOR); +#line 5892 "Zend/zend_language_scanner.c" +yy603: + YYDEBUG(603, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'E') { - if (yych == 'A') goto yy601; + if (yych == 'A') goto yy604; if (yych <= 'D') goto yy187; - goto yy602; + goto yy605; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; } else { - if (yych == 'e') goto yy602; + if (yych == 'e') goto yy605; goto yy187; } } -yy601: - YYDEBUG(601, *YYCURSOR); +yy604: + YYDEBUG(604, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy608; - if (yych == 'n') goto yy608; + if (yych == 'N') goto yy611; + if (yych == 'n') goto yy611; goto yy187; -yy602: - YYDEBUG(602, *YYCURSOR); +yy605: + YYDEBUG(605, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy603; + if (yych == 'A') goto yy606; if (yych != 'a') goto yy187; -yy603: - YYDEBUG(603, *YYCURSOR); +yy606: + YYDEBUG(606, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy604; + if (yych == 'D') goto yy607; if (yych != 'd') goto yy187; -yy604: - YYDEBUG(604, *YYCURSOR); +yy607: + YYDEBUG(607, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy605; + if (yych == 'O') goto yy608; if (yych != 'o') goto yy187; -yy605: - YYDEBUG(605, *YYCURSOR); +yy608: + YYDEBUG(608, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy606; + if (yych == 'F') goto yy609; if (yych != 'f') goto yy187; -yy606: - YYDEBUG(606, *YYCURSOR); +yy609: + YYDEBUG(609, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(607, *YYCURSOR); + YYDEBUG(610, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1286 "Zend/zend_language_scanner.l" +#line 1278 "Zend/zend_language_scanner.l" { return T_INSTEADOF; } -#line 5998 "Zend/zend_language_scanner.c" -yy608: - YYDEBUG(608, *YYCURSOR); +#line 5946 "Zend/zend_language_scanner.c" +yy611: + YYDEBUG(611, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy609; + if (yych == 'C') goto yy612; if (yych != 'c') goto yy187; -yy609: - YYDEBUG(609, *YYCURSOR); +yy612: + YYDEBUG(612, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy610; + if (yych == 'E') goto yy613; if (yych != 'e') goto yy187; -yy610: - YYDEBUG(610, *YYCURSOR); +yy613: + YYDEBUG(613, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy611; + if (yych == 'O') goto yy614; if (yych != 'o') goto yy187; -yy611: - YYDEBUG(611, *YYCURSOR); +yy614: + YYDEBUG(614, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy612; + if (yych == 'F') goto yy615; if (yych != 'f') goto yy187; -yy612: - YYDEBUG(612, *YYCURSOR); +yy615: + YYDEBUG(615, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(613, *YYCURSOR); + YYDEBUG(616, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1116 "Zend/zend_language_scanner.l" +#line 1106 "Zend/zend_language_scanner.l" { return T_INSTANCEOF; } -#line 6031 "Zend/zend_language_scanner.c" -yy614: - YYDEBUG(614, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy615; - if (yych != 'l') goto yy187; -yy615: - YYDEBUG(615, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy616; - if (yych != 'e') goto yy187; -yy616: - YYDEBUG(616, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'M') goto yy617; - if (yych != 'm') goto yy187; +#line 5979 "Zend/zend_language_scanner.c" yy617: YYDEBUG(617, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy618; - if (yych != 'e') goto yy187; + if (yych == 'L') goto yy618; + if (yych != 'l') goto yy187; yy618: YYDEBUG(618, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy619; - if (yych != 'n') goto yy187; + if (yych == 'E') goto yy619; + if (yych != 'e') goto yy187; yy619: YYDEBUG(619, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy620; - if (yych != 't') goto yy187; + if (yych == 'M') goto yy620; + if (yych != 'm') goto yy187; yy620: YYDEBUG(620, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy621; - if (yych != 's') goto yy187; + if (yych == 'E') goto yy621; + if (yych != 'e') goto yy187; yy621: YYDEBUG(621, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'N') goto yy622; + if (yych != 'n') goto yy187; +yy622: + YYDEBUG(622, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy623; + if (yych != 't') goto yy187; +yy623: + YYDEBUG(623, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy624; + if (yych != 's') goto yy187; +yy624: + YYDEBUG(624, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(622, *YYCURSOR); + YYDEBUG(625, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1176 "Zend/zend_language_scanner.l" +#line 1166 "Zend/zend_language_scanner.l" { return T_IMPLEMENTS; } -#line 6079 "Zend/zend_language_scanner.c" -yy623: - YYDEBUG(623, *YYCURSOR); +#line 6027 "Zend/zend_language_scanner.c" +yy626: + YYDEBUG(626, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy631; - if (yych == 'r') goto yy631; + if (yych == 'R') goto yy634; + if (yych == 'r') goto yy634; goto yy187; -yy624: - YYDEBUG(624, *YYCURSOR); +yy627: + YYDEBUG(627, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'Y') { - if (yych == 'A') goto yy627; + if (yych == 'A') goto yy630; if (yych <= 'X') goto yy187; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy627; + goto yy630; } else { if (yych != 'y') goto yy187; } } - YYDEBUG(625, *YYCURSOR); + YYDEBUG(628, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(626, *YYCURSOR); + YYDEBUG(629, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1048 "Zend/zend_language_scanner.l" +#line 1038 "Zend/zend_language_scanner.l" { return T_TRY; } -#line 6111 "Zend/zend_language_scanner.c" -yy627: - YYDEBUG(627, *YYCURSOR); +#line 6059 "Zend/zend_language_scanner.c" +yy630: + YYDEBUG(630, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy628; + if (yych == 'I') goto yy631; if (yych != 'i') goto yy187; -yy628: - YYDEBUG(628, *YYCURSOR); +yy631: + YYDEBUG(631, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy629; + if (yych == 'T') goto yy632; if (yych != 't') goto yy187; -yy629: - YYDEBUG(629, *YYCURSOR); +yy632: + YYDEBUG(632, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(630, *YYCURSOR); + YYDEBUG(633, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1168 "Zend/zend_language_scanner.l" +#line 1158 "Zend/zend_language_scanner.l" { return T_TRAIT; } -#line 6134 "Zend/zend_language_scanner.c" -yy631: - YYDEBUG(631, *YYCURSOR); +#line 6082 "Zend/zend_language_scanner.c" +yy634: + YYDEBUG(634, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy632; + if (yych == 'O') goto yy635; if (yych != 'o') goto yy187; -yy632: - YYDEBUG(632, *YYCURSOR); +yy635: + YYDEBUG(635, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy633; + if (yych == 'W') goto yy636; if (yych != 'w') goto yy187; -yy633: - YYDEBUG(633, *YYCURSOR); +yy636: + YYDEBUG(636, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(634, *YYCURSOR); + YYDEBUG(637, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1060 "Zend/zend_language_scanner.l" +#line 1050 "Zend/zend_language_scanner.l" { return T_THROW; } -#line 6157 "Zend/zend_language_scanner.c" -yy635: - YYDEBUG(635, *YYCURSOR); +#line 6105 "Zend/zend_language_scanner.c" +yy638: + YYDEBUG(638, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy636; + if (yych == 'E') goto yy639; if (yych != 'e') goto yy187; -yy636: - YYDEBUG(636, *YYCURSOR); +yy639: + YYDEBUG(639, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy637; + if (yych == 'L') goto yy640; if (yych != 'l') goto yy187; -yy637: - YYDEBUG(637, *YYCURSOR); +yy640: + YYDEBUG(640, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy638; + if (yych == 'D') goto yy641; if (yych != 'd') goto yy187; -yy638: - YYDEBUG(638, *YYCURSOR); +yy641: + YYDEBUG(641, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(639, *YYCURSOR); + YYDEBUG(642, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1044 "Zend/zend_language_scanner.l" +#line 1034 "Zend/zend_language_scanner.l" { return T_YIELD; } -#line 6185 "Zend/zend_language_scanner.c" -yy640: - YYDEBUG(640, *YYCURSOR); +#line 6133 "Zend/zend_language_scanner.c" +yy643: + YYDEBUG(643, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { - if (yych == 'Q') goto yy642; + if (yych == 'Q') goto yy645; if (yych <= 'S') goto yy187; } else { if (yych <= 'q') { if (yych <= 'p') goto yy187; - goto yy642; + goto yy645; } else { if (yych != 't') goto yy187; } } - YYDEBUG(641, *YYCURSOR); + YYDEBUG(644, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy654; - if (yych == 'u') goto yy654; + if (yych == 'U') goto yy657; + if (yych == 'u') goto yy657; goto yy187; -yy642: - YYDEBUG(642, *YYCURSOR); +yy645: + YYDEBUG(645, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy643; + if (yych == 'U') goto yy646; if (yych != 'u') goto yy187; -yy643: - YYDEBUG(643, *YYCURSOR); +yy646: + YYDEBUG(646, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy644; + if (yych == 'I') goto yy647; if (yych != 'i') goto yy187; -yy644: - YYDEBUG(644, *YYCURSOR); +yy647: + YYDEBUG(647, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy645; + if (yych == 'R') goto yy648; if (yych != 'r') goto yy187; -yy645: - YYDEBUG(645, *YYCURSOR); +yy648: + YYDEBUG(648, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy646; + if (yych == 'E') goto yy649; if (yych != 'e') goto yy187; -yy646: - YYDEBUG(646, *YYCURSOR); +yy649: + YYDEBUG(649, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '9') { if (yych >= '0') goto yy186; } else { - if (yych <= '@') goto yy647; + if (yych <= '@') goto yy650; if (yych <= 'Z') goto yy186; } } else { if (yych <= '`') { - if (yych <= '_') goto yy648; + if (yych <= '_') goto yy651; } else { if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy647: - YYDEBUG(647, *YYCURSOR); +yy650: + YYDEBUG(650, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1270 "Zend/zend_language_scanner.l" +#line 1262 "Zend/zend_language_scanner.l" { return T_REQUIRE; } -#line 6250 "Zend/zend_language_scanner.c" -yy648: - YYDEBUG(648, *YYCURSOR); +#line 6198 "Zend/zend_language_scanner.c" +yy651: + YYDEBUG(651, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy649; + if (yych == 'O') goto yy652; if (yych != 'o') goto yy187; -yy649: - YYDEBUG(649, *YYCURSOR); +yy652: + YYDEBUG(652, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy650; + if (yych == 'N') goto yy653; if (yych != 'n') goto yy187; -yy650: - YYDEBUG(650, *YYCURSOR); +yy653: + YYDEBUG(653, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy651; + if (yych == 'C') goto yy654; if (yych != 'c') goto yy187; -yy651: - YYDEBUG(651, *YYCURSOR); +yy654: + YYDEBUG(654, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy652; + if (yych == 'E') goto yy655; if (yych != 'e') goto yy187; -yy652: - YYDEBUG(652, *YYCURSOR); +yy655: + YYDEBUG(655, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(653, *YYCURSOR); + YYDEBUG(656, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1274 "Zend/zend_language_scanner.l" +#line 1266 "Zend/zend_language_scanner.l" { return T_REQUIRE_ONCE; } -#line 6283 "Zend/zend_language_scanner.c" -yy654: - YYDEBUG(654, *YYCURSOR); +#line 6231 "Zend/zend_language_scanner.c" +yy657: + YYDEBUG(657, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy655; + if (yych == 'R') goto yy658; if (yych != 'r') goto yy187; -yy655: - YYDEBUG(655, *YYCURSOR); +yy658: + YYDEBUG(658, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy656; + if (yych == 'N') goto yy659; if (yych != 'n') goto yy187; -yy656: - YYDEBUG(656, *YYCURSOR); +yy659: + YYDEBUG(659, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(657, *YYCURSOR); + YYDEBUG(660, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1040 "Zend/zend_language_scanner.l" +#line 1030 "Zend/zend_language_scanner.l" { return T_RETURN; } -#line 6306 "Zend/zend_language_scanner.c" -yy658: - YYDEBUG(658, *YYCURSOR); +#line 6254 "Zend/zend_language_scanner.c" +yy661: + YYDEBUG(661, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'L') { if (yych <= 'K') goto yy187; - goto yy681; + goto yy684; } else { if (yych <= 'R') goto yy187; - if (yych <= 'S') goto yy680; - goto yy679; + if (yych <= 'S') goto yy683; + goto yy682; } } else { if (yych <= 'r') { - if (yych == 'l') goto yy681; + if (yych == 'l') goto yy684; goto yy187; } else { - if (yych <= 's') goto yy680; - if (yych <= 't') goto yy679; + if (yych <= 's') goto yy683; + if (yych <= 't') goto yy682; goto yy187; } } -yy659: - YYDEBUG(659, *YYCURSOR); +yy662: + YYDEBUG(662, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'A') goto yy671; + if (yych == 'A') goto yy674; if (yych <= 'N') goto yy187; - goto yy672; + goto yy675; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy671; + goto yy674; } else { - if (yych == 'o') goto yy672; + if (yych == 'o') goto yy675; goto yy187; } } -yy660: - YYDEBUG(660, *YYCURSOR); +yy663: + YYDEBUG(663, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy661; + if (yych == 'N') goto yy664; if (yych != 'n') goto yy187; -yy661: - YYDEBUG(661, *YYCURSOR); +yy664: + YYDEBUG(664, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'R') goto yy187; - if (yych >= 'T') goto yy663; + if (yych >= 'T') goto yy666; } else { if (yych <= 'r') goto yy187; - if (yych <= 's') goto yy662; - if (yych <= 't') goto yy663; + if (yych <= 's') goto yy665; + if (yych <= 't') goto yy666; goto yy187; } -yy662: - YYDEBUG(662, *YYCURSOR); +yy665: + YYDEBUG(665, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy669; - if (yych == 't') goto yy669; + if (yych == 'T') goto yy672; + if (yych == 't') goto yy672; goto yy187; -yy663: - YYDEBUG(663, *YYCURSOR); +yy666: + YYDEBUG(666, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy664; + if (yych == 'I') goto yy667; if (yych != 'i') goto yy187; -yy664: - YYDEBUG(664, *YYCURSOR); +yy667: + YYDEBUG(667, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy665; + if (yych == 'N') goto yy668; if (yych != 'n') goto yy187; -yy665: - YYDEBUG(665, *YYCURSOR); +yy668: + YYDEBUG(668, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy666; + if (yych == 'U') goto yy669; if (yych != 'u') goto yy187; -yy666: - YYDEBUG(666, *YYCURSOR); +yy669: + YYDEBUG(669, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy667; + if (yych == 'E') goto yy670; if (yych != 'e') goto yy187; -yy667: - YYDEBUG(667, *YYCURSOR); +yy670: + YYDEBUG(670, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(668, *YYCURSOR); + YYDEBUG(671, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1144 "Zend/zend_language_scanner.l" +#line 1134 "Zend/zend_language_scanner.l" { return T_CONTINUE; } -#line 6400 "Zend/zend_language_scanner.c" -yy669: - YYDEBUG(669, *YYCURSOR); +#line 6348 "Zend/zend_language_scanner.c" +yy672: + YYDEBUG(672, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(670, *YYCURSOR); + YYDEBUG(673, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1036 "Zend/zend_language_scanner.l" +#line 1026 "Zend/zend_language_scanner.l" { return T_CONST; } -#line 6413 "Zend/zend_language_scanner.c" -yy671: - YYDEBUG(671, *YYCURSOR); +#line 6361 "Zend/zend_language_scanner.c" +yy674: + YYDEBUG(674, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy676; - if (yych == 's') goto yy676; + if (yych == 'S') goto yy679; + if (yych == 's') goto yy679; goto yy187; -yy672: - YYDEBUG(672, *YYCURSOR); +yy675: + YYDEBUG(675, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy673; + if (yych == 'N') goto yy676; if (yych != 'n') goto yy187; -yy673: - YYDEBUG(673, *YYCURSOR); +yy676: + YYDEBUG(676, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy674; + if (yych == 'E') goto yy677; if (yych != 'e') goto yy187; -yy674: - YYDEBUG(674, *YYCURSOR); +yy677: + YYDEBUG(677, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(675, *YYCURSOR); + YYDEBUG(678, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1222 "Zend/zend_language_scanner.l" +#line 1214 "Zend/zend_language_scanner.l" { return T_CLONE; } -#line 6442 "Zend/zend_language_scanner.c" -yy676: - YYDEBUG(676, *YYCURSOR); +#line 6390 "Zend/zend_language_scanner.c" +yy679: + YYDEBUG(679, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy677; + if (yych == 'S') goto yy680; if (yych != 's') goto yy187; -yy677: - YYDEBUG(677, *YYCURSOR); +yy680: + YYDEBUG(680, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(678, *YYCURSOR); + YYDEBUG(681, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1160 "Zend/zend_language_scanner.l" +#line 1150 "Zend/zend_language_scanner.l" { return T_CLASS; } -#line 6460 "Zend/zend_language_scanner.c" -yy679: - YYDEBUG(679, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'C') goto yy690; - if (yych == 'c') goto yy690; - goto yy187; -yy680: - YYDEBUG(680, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy688; - if (yych == 'e') goto yy688; - goto yy187; -yy681: - YYDEBUG(681, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy682; - if (yych != 'l') goto yy187; +#line 6408 "Zend/zend_language_scanner.c" yy682: YYDEBUG(682, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy683; - if (yych != 'a') goto yy187; + if (yych == 'C') goto yy693; + if (yych == 'c') goto yy693; + goto yy187; yy683: YYDEBUG(683, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy684; - if (yych != 'b') goto yy187; + if (yych == 'E') goto yy691; + if (yych == 'e') goto yy691; + goto yy187; yy684: YYDEBUG(684, *YYCURSOR); yych = *++YYCURSOR; @@ -6492,39 +6425,36 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy685: YYDEBUG(685, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy686; - if (yych != 'e') goto yy187; + if (yych == 'A') goto yy686; + if (yych != 'a') goto yy187; yy686: YYDEBUG(686, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 4) { - goto yy186; - } + yych = *++YYCURSOR; + if (yych == 'B') goto yy687; + if (yych != 'b') goto yy187; +yy687: YYDEBUG(687, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1346 "Zend/zend_language_scanner.l" - { - return T_CALLABLE; -} -#line 6510 "Zend/zend_language_scanner.c" + yych = *++YYCURSOR; + if (yych == 'L') goto yy688; + if (yych != 'l') goto yy187; yy688: YYDEBUG(688, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy689; + if (yych != 'e') goto yy187; +yy689: + YYDEBUG(689, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(689, *YYCURSOR); + YYDEBUG(690, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1132 "Zend/zend_language_scanner.l" +#line 1338 "Zend/zend_language_scanner.l" { - return T_CASE; + return T_CALLABLE; } -#line 6523 "Zend/zend_language_scanner.c" -yy690: - YYDEBUG(690, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'H') goto yy691; - if (yych != 'h') goto yy187; +#line 6458 "Zend/zend_language_scanner.c" yy691: YYDEBUG(691, *YYCURSOR); ++YYCURSOR; @@ -6533,719 +6463,737 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(692, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1052 "Zend/zend_language_scanner.l" +#line 1122 "Zend/zend_language_scanner.l" { - return T_CATCH; + return T_CASE; } -#line 6541 "Zend/zend_language_scanner.c" +#line 6471 "Zend/zend_language_scanner.c" yy693: YYDEBUG(693, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy710; - if (yych == 'n') goto yy710; - goto yy187; + if (yych == 'H') goto yy694; + if (yych != 'h') goto yy187; yy694: YYDEBUG(694, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'R') goto yy703; - if (yych == 'r') goto yy703; - goto yy187; -yy695: + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 4) { + goto yy186; + } YYDEBUG(695, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'N') goto yy696; - if (yych != 'n') goto yy187; + yyleng = YYCURSOR - SCNG(yy_text); +#line 1042 "Zend/zend_language_scanner.l" + { + return T_CATCH; +} +#line 6489 "Zend/zend_language_scanner.c" yy696: YYDEBUG(696, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy697; - if (yych != 'c') goto yy187; + if (yych == 'N') goto yy713; + if (yych == 'n') goto yy713; + goto yy187; yy697: YYDEBUG(697, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy698; - if (yych != 't') goto yy187; + if (yych == 'R') goto yy706; + if (yych == 'r') goto yy706; + goto yy187; yy698: YYDEBUG(698, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy699; - if (yych != 'i') goto yy187; + if (yych == 'N') goto yy699; + if (yych != 'n') goto yy187; yy699: YYDEBUG(699, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy700; - if (yych != 'o') goto yy187; + if (yych == 'C') goto yy700; + if (yych != 'c') goto yy187; yy700: YYDEBUG(700, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy701; + if (yych == 'T') goto yy701; + if (yych != 't') goto yy187; +yy701: + YYDEBUG(701, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy702; + if (yych != 'i') goto yy187; +yy702: + YYDEBUG(702, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'O') goto yy703; + if (yych != 'o') goto yy187; +yy703: + YYDEBUG(703, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'N') goto yy704; if (yych != 'n') goto yy187; -yy701: - YYDEBUG(701, *YYCURSOR); +yy704: + YYDEBUG(704, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(702, *YYCURSOR); + YYDEBUG(705, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1032 "Zend/zend_language_scanner.l" +#line 1022 "Zend/zend_language_scanner.l" { return T_FUNCTION; } -#line 6596 "Zend/zend_language_scanner.c" -yy703: - YYDEBUG(703, *YYCURSOR); +#line 6544 "Zend/zend_language_scanner.c" +yy706: + YYDEBUG(706, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy704; + if (yych <= '/') goto yy707; if (yych <= '9') goto yy186; } else { - if (yych == 'E') goto yy705; + if (yych == 'E') goto yy708; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'd') { if (yych != '`') goto yy186; } else { - if (yych <= 'e') goto yy705; + if (yych <= 'e') goto yy708; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy704: - YYDEBUG(704, *YYCURSOR); +yy707: + YYDEBUG(707, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1092 "Zend/zend_language_scanner.l" +#line 1082 "Zend/zend_language_scanner.l" { return T_FOR; } -#line 6624 "Zend/zend_language_scanner.c" -yy705: - YYDEBUG(705, *YYCURSOR); +#line 6572 "Zend/zend_language_scanner.c" +yy708: + YYDEBUG(708, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy706; + if (yych == 'A') goto yy709; if (yych != 'a') goto yy187; -yy706: - YYDEBUG(706, *YYCURSOR); +yy709: + YYDEBUG(709, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy707; + if (yych == 'C') goto yy710; if (yych != 'c') goto yy187; -yy707: - YYDEBUG(707, *YYCURSOR); +yy710: + YYDEBUG(710, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy708; + if (yych == 'H') goto yy711; if (yych != 'h') goto yy187; -yy708: - YYDEBUG(708, *YYCURSOR); +yy711: + YYDEBUG(711, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(709, *YYCURSOR); + YYDEBUG(712, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1100 "Zend/zend_language_scanner.l" +#line 1090 "Zend/zend_language_scanner.l" { return T_FOREACH; } -#line 6652 "Zend/zend_language_scanner.c" -yy710: - YYDEBUG(710, *YYCURSOR); +#line 6600 "Zend/zend_language_scanner.c" +yy713: + YYDEBUG(713, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy711; + if (yych == 'A') goto yy714; if (yych != 'a') goto yy187; -yy711: - YYDEBUG(711, *YYCURSOR); +yy714: + YYDEBUG(714, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy712; + if (yych == 'L') goto yy715; if (yych != 'l') goto yy187; -yy712: - YYDEBUG(712, *YYCURSOR); +yy715: + YYDEBUG(715, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy713; + if (yych <= '/') goto yy716; if (yych <= '9') goto yy186; } else { - if (yych == 'L') goto yy714; + if (yych == 'L') goto yy717; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'k') { if (yych != '`') goto yy186; } else { - if (yych <= 'l') goto yy714; + if (yych <= 'l') goto yy717; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy713: - YYDEBUG(713, *YYCURSOR); +yy716: + YYDEBUG(716, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1314 "Zend/zend_language_scanner.l" +#line 1306 "Zend/zend_language_scanner.l" { return T_FINAL; } -#line 6690 "Zend/zend_language_scanner.c" -yy714: - YYDEBUG(714, *YYCURSOR); +#line 6638 "Zend/zend_language_scanner.c" +yy717: + YYDEBUG(717, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy715; + if (yych == 'Y') goto yy718; if (yych != 'y') goto yy187; -yy715: - YYDEBUG(715, *YYCURSOR); +yy718: + YYDEBUG(718, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(716, *YYCURSOR); + YYDEBUG(719, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1056 "Zend/zend_language_scanner.l" +#line 1046 "Zend/zend_language_scanner.l" { return T_FINALLY; } -#line 6708 "Zend/zend_language_scanner.c" -yy717: - YYDEBUG(717, *YYCURSOR); +#line 6656 "Zend/zend_language_scanner.c" +yy720: + YYDEBUG(720, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'F') { - if (yych == 'C') goto yy723; + if (yych == 'C') goto yy726; if (yych <= 'E') goto yy187; - goto yy724; + goto yy727; } else { if (yych <= 'c') { if (yych <= 'b') goto yy187; - goto yy723; + goto yy726; } else { - if (yych == 'f') goto yy724; + if (yych == 'f') goto yy727; goto yy187; } } -yy718: - YYDEBUG(718, *YYCURSOR); +yy721: + YYDEBUG(721, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy721; - if (yych == 'e') goto yy721; + if (yych == 'E') goto yy724; + if (yych == 'e') goto yy724; goto yy187; -yy719: - YYDEBUG(719, *YYCURSOR); +yy722: + YYDEBUG(722, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(720, *YYCURSOR); + YYDEBUG(723, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1088 "Zend/zend_language_scanner.l" +#line 1078 "Zend/zend_language_scanner.l" { return T_DO; } -#line 6743 "Zend/zend_language_scanner.c" -yy721: - YYDEBUG(721, *YYCURSOR); +#line 6691 "Zend/zend_language_scanner.c" +yy724: + YYDEBUG(724, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(722, *YYCURSOR); + YYDEBUG(725, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1028 "Zend/zend_language_scanner.l" +#line 1018 "Zend/zend_language_scanner.l" { return T_EXIT; } -#line 6756 "Zend/zend_language_scanner.c" -yy723: - YYDEBUG(723, *YYCURSOR); +#line 6704 "Zend/zend_language_scanner.c" +yy726: + YYDEBUG(726, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy730; - if (yych == 'l') goto yy730; + if (yych == 'L') goto yy733; + if (yych == 'l') goto yy733; goto yy187; -yy724: - YYDEBUG(724, *YYCURSOR); +yy727: + YYDEBUG(727, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy725; + if (yych == 'A') goto yy728; if (yych != 'a') goto yy187; -yy725: - YYDEBUG(725, *YYCURSOR); +yy728: + YYDEBUG(728, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy726; + if (yych == 'U') goto yy729; if (yych != 'u') goto yy187; -yy726: - YYDEBUG(726, *YYCURSOR); +yy729: + YYDEBUG(729, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy727; + if (yych == 'L') goto yy730; if (yych != 'l') goto yy187; -yy727: - YYDEBUG(727, *YYCURSOR); +yy730: + YYDEBUG(730, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy728; + if (yych == 'T') goto yy731; if (yych != 't') goto yy187; -yy728: - YYDEBUG(728, *YYCURSOR); +yy731: + YYDEBUG(731, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(729, *YYCURSOR); + YYDEBUG(732, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1136 "Zend/zend_language_scanner.l" +#line 1126 "Zend/zend_language_scanner.l" { return T_DEFAULT; } -#line 6795 "Zend/zend_language_scanner.c" -yy730: - YYDEBUG(730, *YYCURSOR); +#line 6743 "Zend/zend_language_scanner.c" +yy733: + YYDEBUG(733, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy731; + if (yych == 'A') goto yy734; if (yych != 'a') goto yy187; -yy731: - YYDEBUG(731, *YYCURSOR); +yy734: + YYDEBUG(734, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy732; + if (yych == 'R') goto yy735; if (yych != 'r') goto yy187; -yy732: - YYDEBUG(732, *YYCURSOR); +yy735: + YYDEBUG(735, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy733; + if (yych == 'E') goto yy736; if (yych != 'e') goto yy187; -yy733: - YYDEBUG(733, *YYCURSOR); +yy736: + YYDEBUG(736, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(734, *YYCURSOR); + YYDEBUG(737, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1108 "Zend/zend_language_scanner.l" +#line 1098 "Zend/zend_language_scanner.l" { return T_DECLARE; } -#line 6823 "Zend/zend_language_scanner.c" -yy735: - YYDEBUG(735, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'H') goto yy797; - if (yych == 'h') goto yy797; - goto yy187; -yy736: - YYDEBUG(736, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy791; - if (yych == 's') goto yy791; - goto yy187; -yy737: - YYDEBUG(737, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'P') goto yy787; - if (yych == 'p') goto yy787; - goto yy187; +#line 6771 "Zend/zend_language_scanner.c" yy738: YYDEBUG(738, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy753; - if (yych == 'd') goto yy753; + if (yych == 'H') goto yy800; + if (yych == 'h') goto yy800; goto yy187; yy739: YYDEBUG(739, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy750; - if (yych == 'a') goto yy750; + if (yych == 'S') goto yy794; + if (yych == 's') goto yy794; goto yy187; yy740: YYDEBUG(740, *YYCURSOR); yych = *++YYCURSOR; + if (yych == 'P') goto yy790; + if (yych == 'p') goto yy790; + goto yy187; +yy741: + YYDEBUG(741, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'D') goto yy756; + if (yych == 'd') goto yy756; + goto yy187; +yy742: + YYDEBUG(742, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy753; + if (yych == 'a') goto yy753; + goto yy187; +yy743: + YYDEBUG(743, *YYCURSOR); + yych = *++YYCURSOR; if (yych <= 'T') { - if (yych == 'I') goto yy741; + if (yych == 'I') goto yy744; if (yych <= 'S') goto yy187; - goto yy742; + goto yy745; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; } else { - if (yych == 't') goto yy742; + if (yych == 't') goto yy745; goto yy187; } } -yy741: - YYDEBUG(741, *YYCURSOR); +yy744: + YYDEBUG(744, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy748; - if (yych == 't') goto yy748; + if (yych == 'T') goto yy751; + if (yych == 't') goto yy751; goto yy187; -yy742: - YYDEBUG(742, *YYCURSOR); +yy745: + YYDEBUG(745, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy743; + if (yych == 'E') goto yy746; if (yych != 'e') goto yy187; -yy743: - YYDEBUG(743, *YYCURSOR); +yy746: + YYDEBUG(746, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy744; + if (yych == 'N') goto yy747; if (yych != 'n') goto yy187; -yy744: - YYDEBUG(744, *YYCURSOR); +yy747: + YYDEBUG(747, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy745; + if (yych == 'D') goto yy748; if (yych != 'd') goto yy187; -yy745: - YYDEBUG(745, *YYCURSOR); +yy748: + YYDEBUG(748, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy746; + if (yych == 'S') goto yy749; if (yych != 's') goto yy187; -yy746: - YYDEBUG(746, *YYCURSOR); +yy749: + YYDEBUG(749, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(747, *YYCURSOR); + YYDEBUG(750, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1172 "Zend/zend_language_scanner.l" +#line 1162 "Zend/zend_language_scanner.l" { return T_EXTENDS; } -#line 6907 "Zend/zend_language_scanner.c" -yy748: - YYDEBUG(748, *YYCURSOR); +#line 6855 "Zend/zend_language_scanner.c" +yy751: + YYDEBUG(751, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(749, *YYCURSOR); + YYDEBUG(752, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1024 "Zend/zend_language_scanner.l" +#line 1014 "Zend/zend_language_scanner.l" { return T_EXIT; } -#line 6920 "Zend/zend_language_scanner.c" -yy750: - YYDEBUG(750, *YYCURSOR); +#line 6868 "Zend/zend_language_scanner.c" +yy753: + YYDEBUG(753, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy751; + if (yych == 'L') goto yy754; if (yych != 'l') goto yy187; -yy751: - YYDEBUG(751, *YYCURSOR); +yy754: + YYDEBUG(754, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(752, *YYCURSOR); + YYDEBUG(755, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1258 "Zend/zend_language_scanner.l" +#line 1250 "Zend/zend_language_scanner.l" { return T_EVAL; } -#line 6938 "Zend/zend_language_scanner.c" -yy753: - YYDEBUG(753, *YYCURSOR); +#line 6886 "Zend/zend_language_scanner.c" +yy756: + YYDEBUG(756, *YYCURSOR); yych = *++YYCURSOR; YYDEBUG(-1, yych); switch (yych) { case 'D': - case 'd': goto yy754; + case 'd': goto yy757; case 'F': - case 'f': goto yy755; + case 'f': goto yy758; case 'I': - case 'i': goto yy756; + case 'i': goto yy759; case 'S': - case 's': goto yy757; + case 's': goto yy760; case 'W': - case 'w': goto yy758; + case 'w': goto yy761; default: goto yy187; } -yy754: - YYDEBUG(754, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy780; - if (yych == 'e') goto yy780; - goto yy187; -yy755: - YYDEBUG(755, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'O') goto yy772; - if (yych == 'o') goto yy772; - goto yy187; -yy756: - YYDEBUG(756, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'F') goto yy770; - if (yych == 'f') goto yy770; - goto yy187; yy757: YYDEBUG(757, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy764; - if (yych == 'w') goto yy764; + if (yych == 'E') goto yy783; + if (yych == 'e') goto yy783; goto yy187; yy758: YYDEBUG(758, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy759; - if (yych != 'h') goto yy187; + if (yych == 'O') goto yy775; + if (yych == 'o') goto yy775; + goto yy187; yy759: YYDEBUG(759, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy760; - if (yych != 'i') goto yy187; + if (yych == 'F') goto yy773; + if (yych == 'f') goto yy773; + goto yy187; yy760: YYDEBUG(760, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy761; - if (yych != 'l') goto yy187; + if (yych == 'W') goto yy767; + if (yych == 'w') goto yy767; + goto yy187; yy761: YYDEBUG(761, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy762; - if (yych != 'e') goto yy187; + if (yych == 'H') goto yy762; + if (yych != 'h') goto yy187; yy762: YYDEBUG(762, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy763; + if (yych != 'i') goto yy187; +yy763: + YYDEBUG(763, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy764; + if (yych != 'l') goto yy187; +yy764: + YYDEBUG(764, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy765; + if (yych != 'e') goto yy187; +yy765: + YYDEBUG(765, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(763, *YYCURSOR); + YYDEBUG(766, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1084 "Zend/zend_language_scanner.l" +#line 1074 "Zend/zend_language_scanner.l" { return T_ENDWHILE; } -#line 7012 "Zend/zend_language_scanner.c" -yy764: - YYDEBUG(764, *YYCURSOR); +#line 6960 "Zend/zend_language_scanner.c" +yy767: + YYDEBUG(767, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy765; + if (yych == 'I') goto yy768; if (yych != 'i') goto yy187; -yy765: - YYDEBUG(765, *YYCURSOR); +yy768: + YYDEBUG(768, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy766; + if (yych == 'T') goto yy769; if (yych != 't') goto yy187; -yy766: - YYDEBUG(766, *YYCURSOR); +yy769: + YYDEBUG(769, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy767; + if (yych == 'C') goto yy770; if (yych != 'c') goto yy187; -yy767: - YYDEBUG(767, *YYCURSOR); +yy770: + YYDEBUG(770, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy768; + if (yych == 'H') goto yy771; if (yych != 'h') goto yy187; -yy768: - YYDEBUG(768, *YYCURSOR); +yy771: + YYDEBUG(771, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(769, *YYCURSOR); + YYDEBUG(772, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1128 "Zend/zend_language_scanner.l" +#line 1118 "Zend/zend_language_scanner.l" { return T_ENDSWITCH; } -#line 7045 "Zend/zend_language_scanner.c" -yy770: - YYDEBUG(770, *YYCURSOR); +#line 6993 "Zend/zend_language_scanner.c" +yy773: + YYDEBUG(773, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(771, *YYCURSOR); + YYDEBUG(774, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1072 "Zend/zend_language_scanner.l" +#line 1062 "Zend/zend_language_scanner.l" { return T_ENDIF; } -#line 7058 "Zend/zend_language_scanner.c" -yy772: - YYDEBUG(772, *YYCURSOR); +#line 7006 "Zend/zend_language_scanner.c" +yy775: + YYDEBUG(775, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy773; + if (yych == 'R') goto yy776; if (yych != 'r') goto yy187; -yy773: - YYDEBUG(773, *YYCURSOR); +yy776: + YYDEBUG(776, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy774; + if (yych <= '/') goto yy777; if (yych <= '9') goto yy186; } else { - if (yych == 'E') goto yy775; + if (yych == 'E') goto yy778; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'd') { if (yych != '`') goto yy186; } else { - if (yych <= 'e') goto yy775; + if (yych <= 'e') goto yy778; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy774: - YYDEBUG(774, *YYCURSOR); +yy777: + YYDEBUG(777, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1096 "Zend/zend_language_scanner.l" +#line 1086 "Zend/zend_language_scanner.l" { return T_ENDFOR; } -#line 7091 "Zend/zend_language_scanner.c" -yy775: - YYDEBUG(775, *YYCURSOR); +#line 7039 "Zend/zend_language_scanner.c" +yy778: + YYDEBUG(778, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy776; + if (yych == 'A') goto yy779; if (yych != 'a') goto yy187; -yy776: - YYDEBUG(776, *YYCURSOR); +yy779: + YYDEBUG(779, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy777; + if (yych == 'C') goto yy780; if (yych != 'c') goto yy187; -yy777: - YYDEBUG(777, *YYCURSOR); +yy780: + YYDEBUG(780, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy778; + if (yych == 'H') goto yy781; if (yych != 'h') goto yy187; -yy778: - YYDEBUG(778, *YYCURSOR); +yy781: + YYDEBUG(781, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(779, *YYCURSOR); + YYDEBUG(782, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1104 "Zend/zend_language_scanner.l" +#line 1094 "Zend/zend_language_scanner.l" { return T_ENDFOREACH; } -#line 7119 "Zend/zend_language_scanner.c" -yy780: - YYDEBUG(780, *YYCURSOR); +#line 7067 "Zend/zend_language_scanner.c" +yy783: + YYDEBUG(783, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy781; + if (yych == 'C') goto yy784; if (yych != 'c') goto yy187; -yy781: - YYDEBUG(781, *YYCURSOR); +yy784: + YYDEBUG(784, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy782; + if (yych == 'L') goto yy785; if (yych != 'l') goto yy187; -yy782: - YYDEBUG(782, *YYCURSOR); +yy785: + YYDEBUG(785, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy783; + if (yych == 'A') goto yy786; if (yych != 'a') goto yy187; -yy783: - YYDEBUG(783, *YYCURSOR); +yy786: + YYDEBUG(786, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy784; + if (yych == 'R') goto yy787; if (yych != 'r') goto yy187; -yy784: - YYDEBUG(784, *YYCURSOR); +yy787: + YYDEBUG(787, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy785; + if (yych == 'E') goto yy788; if (yych != 'e') goto yy187; -yy785: - YYDEBUG(785, *YYCURSOR); +yy788: + YYDEBUG(788, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(786, *YYCURSOR); + YYDEBUG(789, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1112 "Zend/zend_language_scanner.l" +#line 1102 "Zend/zend_language_scanner.l" { return T_ENDDECLARE; } -#line 7157 "Zend/zend_language_scanner.c" -yy787: - YYDEBUG(787, *YYCURSOR); +#line 7105 "Zend/zend_language_scanner.c" +yy790: + YYDEBUG(790, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy788; + if (yych == 'T') goto yy791; if (yych != 't') goto yy187; -yy788: - YYDEBUG(788, *YYCURSOR); +yy791: + YYDEBUG(791, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy789; + if (yych == 'Y') goto yy792; if (yych != 'y') goto yy187; -yy789: - YYDEBUG(789, *YYCURSOR); +yy792: + YYDEBUG(792, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(790, *YYCURSOR); + YYDEBUG(793, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1298 "Zend/zend_language_scanner.l" +#line 1290 "Zend/zend_language_scanner.l" { return T_EMPTY; } -#line 7180 "Zend/zend_language_scanner.c" -yy791: - YYDEBUG(791, *YYCURSOR); +#line 7128 "Zend/zend_language_scanner.c" +yy794: + YYDEBUG(794, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy792; + if (yych == 'E') goto yy795; if (yych != 'e') goto yy187; -yy792: - YYDEBUG(792, *YYCURSOR); +yy795: + YYDEBUG(795, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy793; + if (yych <= '/') goto yy796; if (yych <= '9') goto yy186; } else { - if (yych == 'I') goto yy794; + if (yych == 'I') goto yy797; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'h') { if (yych != '`') goto yy186; } else { - if (yych <= 'i') goto yy794; + if (yych <= 'i') goto yy797; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy793: - YYDEBUG(793, *YYCURSOR); +yy796: + YYDEBUG(796, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1076 "Zend/zend_language_scanner.l" +#line 1066 "Zend/zend_language_scanner.l" { return T_ELSE; } -#line 7213 "Zend/zend_language_scanner.c" -yy794: - YYDEBUG(794, *YYCURSOR); +#line 7161 "Zend/zend_language_scanner.c" +yy797: + YYDEBUG(797, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy795; + if (yych == 'F') goto yy798; if (yych != 'f') goto yy187; -yy795: - YYDEBUG(795, *YYCURSOR); +yy798: + YYDEBUG(798, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(796, *YYCURSOR); + YYDEBUG(799, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1068 "Zend/zend_language_scanner.l" +#line 1058 "Zend/zend_language_scanner.l" { return T_ELSEIF; } -#line 7231 "Zend/zend_language_scanner.c" -yy797: - YYDEBUG(797, *YYCURSOR); +#line 7179 "Zend/zend_language_scanner.c" +yy800: + YYDEBUG(800, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy798; + if (yych == 'O') goto yy801; if (yych != 'o') goto yy187; -yy798: - YYDEBUG(798, *YYCURSOR); +yy801: + YYDEBUG(801, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(799, *YYCURSOR); + YYDEBUG(802, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1152 "Zend/zend_language_scanner.l" +#line 1142 "Zend/zend_language_scanner.l" { return T_ECHO; } -#line 7249 "Zend/zend_language_scanner.c" +#line 7197 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -7284,115 +7232,113 @@ int lex_scan(zval *zendlval TSRMLS_DC) 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, }; - YYDEBUG(800, *YYCURSOR); + YYDEBUG(803, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yych <= '-') { if (yych <= '\r') { - if (yych <= 0x08) goto yy808; - if (yych <= '\n') goto yy802; - if (yych <= '\f') goto yy808; + if (yych <= 0x08) goto yy811; + if (yych <= '\n') goto yy805; + if (yych <= '\f') goto yy811; } else { - if (yych == ' ') goto yy802; - if (yych <= ',') goto yy808; - goto yy804; + if (yych == ' ') goto yy805; + if (yych <= ',') goto yy811; + goto yy807; } } else { if (yych <= '_') { - if (yych <= '@') goto yy808; - if (yych <= 'Z') goto yy806; - if (yych <= '^') goto yy808; - goto yy806; + if (yych <= '@') goto yy811; + if (yych <= 'Z') goto yy809; + if (yych <= '^') goto yy811; + goto yy809; } else { - if (yych <= '`') goto yy808; - if (yych <= 'z') goto yy806; - if (yych <= '~') goto yy808; - goto yy806; + if (yych <= '`') goto yy811; + if (yych <= 'z') goto yy809; + if (yych <= '~') goto yy811; + goto yy809; } } -yy802: - YYDEBUG(802, *YYCURSOR); +yy805: + YYDEBUG(805, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy814; -yy803: - YYDEBUG(803, *YYCURSOR); + goto yy817; +yy806: + YYDEBUG(806, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1185 "Zend/zend_language_scanner.l" +#line 1175 "Zend/zend_language_scanner.l" { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINES(yytext, yyleng); return T_WHITESPACE; } -#line 7330 "Zend/zend_language_scanner.c" -yy804: - YYDEBUG(804, *YYCURSOR); +#line 7276 "Zend/zend_language_scanner.c" +yy807: + YYDEBUG(807, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '>') goto yy811; -yy805: - YYDEBUG(805, *YYCURSOR); + if ((yych = *YYCURSOR) == '>') goto yy814; +yy808: + YYDEBUG(808, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1204 "Zend/zend_language_scanner.l" +#line 1192 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(TSRMLS_C); goto restart; } -#line 7344 "Zend/zend_language_scanner.c" -yy806: - YYDEBUG(806, *YYCURSOR); +#line 7290 "Zend/zend_language_scanner.c" +yy809: + YYDEBUG(809, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy810; -yy807: - YYDEBUG(807, *YYCURSOR); + goto yy813; +yy810: + YYDEBUG(810, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1197 "Zend/zend_language_scanner.l" +#line 1185 "Zend/zend_language_scanner.l" { yy_pop_state(TSRMLS_C); zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; return T_STRING; } -#line 7360 "Zend/zend_language_scanner.c" -yy808: - YYDEBUG(808, *YYCURSOR); +#line 7306 "Zend/zend_language_scanner.c" +yy811: + YYDEBUG(811, *YYCURSOR); yych = *++YYCURSOR; - goto yy805; -yy809: - YYDEBUG(809, *YYCURSOR); + goto yy808; +yy812: + YYDEBUG(812, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy810: - YYDEBUG(810, *YYCURSOR); +yy813: + YYDEBUG(813, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy809; + goto yy812; } - goto yy807; -yy811: - YYDEBUG(811, *YYCURSOR); + goto yy810; +yy814: + YYDEBUG(814, *YYCURSOR); ++YYCURSOR; - YYDEBUG(812, *YYCURSOR); + YYDEBUG(815, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1193 "Zend/zend_language_scanner.l" +#line 1181 "Zend/zend_language_scanner.l" { return T_OBJECT_OPERATOR; } -#line 7385 "Zend/zend_language_scanner.c" -yy813: - YYDEBUG(813, *YYCURSOR); +#line 7331 "Zend/zend_language_scanner.c" +yy816: + YYDEBUG(816, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy814: - YYDEBUG(814, *YYCURSOR); +yy817: + YYDEBUG(817, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy813; + goto yy816; } - goto yy803; + goto yy806; } /* *********************************** */ yyc_ST_LOOKING_FOR_VARNAME: @@ -7431,74 +7377,74 @@ int lex_scan(zval *zendlval TSRMLS_DC) 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; - YYDEBUG(815, *YYCURSOR); + YYDEBUG(818, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yych <= '_') { - if (yych <= '@') goto yy819; - if (yych <= 'Z') goto yy817; - if (yych <= '^') goto yy819; + if (yych <= '@') goto yy822; + if (yych <= 'Z') goto yy820; + if (yych <= '^') goto yy822; } else { - if (yych <= '`') goto yy819; - if (yych <= 'z') goto yy817; - if (yych <= '~') goto yy819; + if (yych <= '`') goto yy822; + if (yych <= 'z') goto yy820; + if (yych <= '~') goto yy822; } -yy817: - YYDEBUG(817, *YYCURSOR); +yy820: + YYDEBUG(820, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '_') { if (yych <= '@') { - if (yych <= '/') goto yy818; - if (yych <= '9') goto yy821; + if (yych <= '/') goto yy821; + if (yych <= '9') goto yy824; } else { - if (yych <= '[') goto yy821; - if (yych >= '_') goto yy821; + if (yych <= '[') goto yy824; + if (yych >= '_') goto yy824; } } else { if (yych <= '|') { - if (yych <= '`') goto yy818; - if (yych <= 'z') goto yy821; + if (yych <= '`') goto yy821; + if (yych <= 'z') goto yy824; } else { - if (yych != '~') goto yy821; + if (yych != '~') goto yy824; } } -yy818: - YYDEBUG(818, *YYCURSOR); +yy821: + YYDEBUG(821, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1490 "Zend/zend_language_scanner.l" +#line 1482 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(TSRMLS_C); yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); goto restart; } -#line 7477 "Zend/zend_language_scanner.c" -yy819: - YYDEBUG(819, *YYCURSOR); +#line 7423 "Zend/zend_language_scanner.c" +yy822: + YYDEBUG(822, *YYCURSOR); yych = *++YYCURSOR; - goto yy818; -yy820: - YYDEBUG(820, *YYCURSOR); + goto yy821; +yy823: + YYDEBUG(823, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy821: - YYDEBUG(821, *YYCURSOR); +yy824: + YYDEBUG(824, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy820; + goto yy823; } - if (yych == '[') goto yy823; - if (yych == '}') goto yy823; - YYDEBUG(822, *YYCURSOR); + if (yych == '[') goto yy826; + if (yych == '}') goto yy826; + YYDEBUG(825, *YYCURSOR); YYCURSOR = YYMARKER; - goto yy818; -yy823: - YYDEBUG(823, *YYCURSOR); + goto yy821; +yy826: + YYDEBUG(826, *YYCURSOR); ++YYCURSOR; - YYDEBUG(824, *YYCURSOR); + YYDEBUG(827, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1480 "Zend/zend_language_scanner.l" +#line 1472 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); zend_copy_value(zendlval, yytext, yyleng); @@ -7507,18 +7453,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return T_STRING_VARNAME; } -#line 7511 "Zend/zend_language_scanner.c" +#line 7457 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_NOWDOC: - YYDEBUG(825, *YYCURSOR); + YYDEBUG(828, *YYCURSOR); YYFILL(1); yych = *YYCURSOR; - YYDEBUG(827, *YYCURSOR); + YYDEBUG(830, *YYCURSOR); ++YYCURSOR; - YYDEBUG(828, *YYCURSOR); + YYDEBUG(831, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2374 "Zend/zend_language_scanner.l" +#line 2302 "Zend/zend_language_scanner.l" { int newline = 0; @@ -7575,7 +7521,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) HANDLE_NEWLINES(yytext, yyleng - newline); return T_ENCAPSED_AND_WHITESPACE; } -#line 7579 "Zend/zend_language_scanner.c" +#line 7525 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_VAR_OFFSET: { @@ -7613,162 +7559,159 @@ int lex_scan(zval *zendlval TSRMLS_DC) 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, }; - YYDEBUG(829, *YYCURSOR); + YYDEBUG(832, *YYCURSOR); YYFILL(3); yych = *YYCURSOR; if (yych <= '/') { if (yych <= ' ') { if (yych <= '\f') { - if (yych <= 0x08) goto yy843; - if (yych <= '\n') goto yy839; - goto yy843; + if (yych <= 0x08) goto yy846; + if (yych <= '\n') goto yy842; + goto yy846; } else { - if (yych <= '\r') goto yy839; - if (yych <= 0x1F) goto yy843; - goto yy839; + if (yych <= '\r') goto yy842; + if (yych <= 0x1F) goto yy846; + goto yy842; } } else { if (yych <= '$') { - if (yych <= '"') goto yy838; - if (yych <= '#') goto yy839; - goto yy834; + if (yych <= '"') goto yy841; + if (yych <= '#') goto yy842; + goto yy837; } else { - if (yych == '\'') goto yy839; - goto yy838; + if (yych == '\'') goto yy842; + goto yy841; } } } else { if (yych <= '\\') { if (yych <= '@') { - if (yych <= '0') goto yy831; - if (yych <= '9') goto yy833; - goto yy838; + if (yych <= '0') goto yy834; + if (yych <= '9') goto yy836; + goto yy841; } else { - if (yych <= 'Z') goto yy841; - if (yych <= '[') goto yy838; - goto yy839; + if (yych <= 'Z') goto yy844; + if (yych <= '[') goto yy841; + goto yy842; } } else { if (yych <= '_') { - if (yych <= ']') goto yy836; - if (yych <= '^') goto yy838; - goto yy841; + if (yych <= ']') goto yy839; + if (yych <= '^') goto yy841; + goto yy844; } else { - if (yych <= '`') goto yy838; - if (yych <= 'z') goto yy841; - if (yych <= '~') goto yy838; - goto yy841; + if (yych <= '`') goto yy841; + if (yych <= 'z') goto yy844; + if (yych <= '~') goto yy841; + goto yy844; } } } -yy831: - YYDEBUG(831, *YYCURSOR); +yy834: + YYDEBUG(834, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'W') { if (yych <= '9') { - if (yych >= '0') goto yy855; + if (yych >= '0') goto yy858; } else { - if (yych == 'B') goto yy852; + if (yych == 'B') goto yy855; } } else { if (yych <= 'b') { - if (yych <= 'X') goto yy854; - if (yych >= 'b') goto yy852; + if (yych <= 'X') goto yy857; + if (yych >= 'b') goto yy855; } else { - if (yych == 'x') goto yy854; + if (yych == 'x') goto yy857; } } -yy832: - YYDEBUG(832, *YYCURSOR); +yy835: + YYDEBUG(835, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1568 "Zend/zend_language_scanner.l" +#line 1558 "Zend/zend_language_scanner.l" { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { - zendlval->value.lval = strtol(yytext, NULL, 10); - zendlval->type = IS_LONG; + ZVAL_LONG(zendlval, strtol(yytext, NULL, 10)); } else { - zendlval->value.str.val = (char *)estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 1); } return T_NUM_STRING; } -#line 7698 "Zend/zend_language_scanner.c" -yy833: - YYDEBUG(833, *YYCURSOR); +#line 7641 "Zend/zend_language_scanner.c" +yy836: + YYDEBUG(836, *YYCURSOR); yych = *++YYCURSOR; - goto yy851; -yy834: - YYDEBUG(834, *YYCURSOR); + goto yy854; +yy837: + YYDEBUG(837, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '_') { - if (yych <= '@') goto yy835; - if (yych <= 'Z') goto yy847; - if (yych >= '_') goto yy847; + if (yych <= '@') goto yy838; + if (yych <= 'Z') goto yy850; + if (yych >= '_') goto yy850; } else { - if (yych <= '`') goto yy835; - if (yych <= 'z') goto yy847; - if (yych >= 0x7F) goto yy847; + if (yych <= '`') goto yy838; + if (yych <= 'z') goto yy850; + if (yych >= 0x7F) goto yy850; } -yy835: - YYDEBUG(835, *YYCURSOR); +yy838: + YYDEBUG(838, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1900 "Zend/zend_language_scanner.l" +#line 1834 "Zend/zend_language_scanner.l" { /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */ return yytext[0]; } -#line 7723 "Zend/zend_language_scanner.c" -yy836: - YYDEBUG(836, *YYCURSOR); +#line 7666 "Zend/zend_language_scanner.c" +yy839: + YYDEBUG(839, *YYCURSOR); ++YYCURSOR; - YYDEBUG(837, *YYCURSOR); + YYDEBUG(840, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1895 "Zend/zend_language_scanner.l" +#line 1829 "Zend/zend_language_scanner.l" { yy_pop_state(TSRMLS_C); return ']'; } -#line 7734 "Zend/zend_language_scanner.c" -yy838: - YYDEBUG(838, *YYCURSOR); +#line 7677 "Zend/zend_language_scanner.c" +yy841: + YYDEBUG(841, *YYCURSOR); yych = *++YYCURSOR; - goto yy835; -yy839: - YYDEBUG(839, *YYCURSOR); + goto yy838; +yy842: + YYDEBUG(842, *YYCURSOR); ++YYCURSOR; - YYDEBUG(840, *YYCURSOR); + YYDEBUG(843, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1905 "Zend/zend_language_scanner.l" +#line 1839 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); yy_pop_state(TSRMLS_C); return T_ENCAPSED_AND_WHITESPACE; } -#line 7751 "Zend/zend_language_scanner.c" -yy841: - YYDEBUG(841, *YYCURSOR); +#line 7694 "Zend/zend_language_scanner.c" +yy844: + YYDEBUG(844, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy846; -yy842: - YYDEBUG(842, *YYCURSOR); + goto yy849; +yy845: + YYDEBUG(845, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1912 "Zend/zend_language_scanner.l" +#line 1846 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; return T_STRING; } -#line 7766 "Zend/zend_language_scanner.c" -yy843: - YYDEBUG(843, *YYCURSOR); +#line 7709 "Zend/zend_language_scanner.c" +yy846: + YYDEBUG(846, *YYCURSOR); ++YYCURSOR; - YYDEBUG(844, *YYCURSOR); + YYDEBUG(847, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2432 "Zend/zend_language_scanner.l" +#line 2360 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -7777,118 +7720,116 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 7781 "Zend/zend_language_scanner.c" -yy845: - YYDEBUG(845, *YYCURSOR); +#line 7724 "Zend/zend_language_scanner.c" +yy848: + YYDEBUG(848, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy846: - YYDEBUG(846, *YYCURSOR); +yy849: + YYDEBUG(849, *YYCURSOR); if (yybm[0+yych] & 16) { - goto yy845; + goto yy848; } - goto yy842; -yy847: - YYDEBUG(847, *YYCURSOR); + goto yy845; +yy850: + YYDEBUG(850, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(848, *YYCURSOR); + YYDEBUG(851, *YYCURSOR); if (yych <= '^') { if (yych <= '9') { - if (yych >= '0') goto yy847; + if (yych >= '0') goto yy850; } else { - if (yych <= '@') goto yy849; - if (yych <= 'Z') goto yy847; + if (yych <= '@') goto yy852; + if (yych <= 'Z') goto yy850; } } else { if (yych <= '`') { - if (yych <= '_') goto yy847; + if (yych <= '_') goto yy850; } else { - if (yych <= 'z') goto yy847; - if (yych >= 0x7F) goto yy847; + if (yych <= 'z') goto yy850; + if (yych >= 0x7F) goto yy850; } } -yy849: - YYDEBUG(849, *YYCURSOR); +yy852: + YYDEBUG(852, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1889 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 7823 "Zend/zend_language_scanner.c" -yy850: - YYDEBUG(850, *YYCURSOR); +#line 7766 "Zend/zend_language_scanner.c" +yy853: + YYDEBUG(853, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy851: - YYDEBUG(851, *YYCURSOR); +yy854: + YYDEBUG(854, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy850; + goto yy853; } - goto yy832; -yy852: - YYDEBUG(852, *YYCURSOR); + goto yy835; +yy855: + YYDEBUG(855, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 128) { - goto yy860; + goto yy863; } -yy853: - YYDEBUG(853, *YYCURSOR); +yy856: + YYDEBUG(856, *YYCURSOR); YYCURSOR = YYMARKER; - goto yy832; -yy854: - YYDEBUG(854, *YYCURSOR); + goto yy835; +yy857: + YYDEBUG(857, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 64) { - goto yy858; + goto yy861; } - goto yy853; -yy855: - YYDEBUG(855, *YYCURSOR); + goto yy856; +yy858: + YYDEBUG(858, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(856, *YYCURSOR); - if (yych <= '/') goto yy857; - if (yych <= '9') goto yy855; -yy857: - YYDEBUG(857, *YYCURSOR); + YYDEBUG(859, *YYCURSOR); + if (yych <= '/') goto yy860; + if (yych <= '9') goto yy858; +yy860: + YYDEBUG(860, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1580 "Zend/zend_language_scanner.l" +#line 1567 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ - zendlval->value.str.val = (char *)estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 1); return T_NUM_STRING; } -#line 7870 "Zend/zend_language_scanner.c" -yy858: - YYDEBUG(858, *YYCURSOR); +#line 7811 "Zend/zend_language_scanner.c" +yy861: + YYDEBUG(861, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(859, *YYCURSOR); + YYDEBUG(862, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy858; + goto yy861; } - goto yy857; -yy860: - YYDEBUG(860, *YYCURSOR); + goto yy860; +yy863: + YYDEBUG(863, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(861, *YYCURSOR); + YYDEBUG(864, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy860; + goto yy863; } - goto yy857; + goto yy860; } } -#line 2441 "Zend/zend_language_scanner.l" +#line 2369 "Zend/zend_language_scanner.l" } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index d2e7243bb2da1..736d7712d5ab8 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -47,7 +47,7 @@ #include "zend_API.h" #include "zend_strtod.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "tsrm_config_common.h" #define YYCTYPE unsigned char @@ -562,10 +562,8 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR zend_bool original_in_compilation = CG(in_compilation); retval_znode.op_type = IS_CONST; - retval_znode.u.constant.type = IS_LONG; - retval_znode.u.constant.value.lval = 1; - Z_UNSET_ISREF(retval_znode.u.constant); - Z_SET_REFCOUNT(retval_znode.u.constant, 1); + INIT_PZVAL(&retval_znode.u.constant); + ZVAL_LONG(&retval_znode.u.constant, 1); zend_save_lexical_state(&original_lex_state TSRMLS_CC); @@ -622,7 +620,7 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) convert_to_string(&tmp); filename = &tmp; } - file_handle.filename = filename->value.str.val; + file_handle.filename = Z_STRVAL_P(filename); file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; @@ -633,7 +631,7 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) int dummy = 1; if (!file_handle.opened_path) { - file_handle.opened_path = opened_path = estrndup(filename->value.str.val, filename->value.str.len); + file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename)); } zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL); @@ -655,22 +653,15 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D char *buf; size_t size; - /* enforce two trailing NULLs for flex... */ - if (IS_INTERNED(str->value.str.val)) { - char *tmp = safe_emalloc(1, str->value.str.len, ZEND_MMAP_AHEAD); - memcpy(tmp, str->value.str.val, str->value.str.len + ZEND_MMAP_AHEAD); - str->value.str.val = tmp; - } else { - str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD); - } - - memset(str->value.str.val + str->value.str.len, 0, ZEND_MMAP_AHEAD); + /* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */ + Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), Z_STRLEN_P(str) + ZEND_MMAP_AHEAD); + memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), 0, ZEND_MMAP_AHEAD); SCNG(yy_in) = NULL; SCNG(yy_start) = NULL; - buf = str->value.str.val; - size = str->value.str.len; + buf = Z_STRVAL_P(str); + size = Z_STRLEN_P(str); if (CG(multibyte)) { SCNG(script_org) = (unsigned char*)buf; @@ -731,7 +722,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC) int compiler_result; zend_bool original_in_compilation = CG(in_compilation); - if (source_string->value.str.len==0) { + if (Z_STRLEN_P(source_string)==0) { efree(op_array); return NULL; } @@ -869,11 +860,11 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter # define zend_copy_value(zendlval, yytext, yyleng) \ if (SCNG(output_filter)) { \ size_t sz = 0; \ - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \ - zendlval->value.str.len = sz; \ + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \ + Z_STRLEN_P(zendlval) = sz; \ } else { \ - zendlval->value.str.val = (char *) estrndup(yytext, yyleng); \ - zendlval->value.str.len = yyleng; \ + Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); \ + Z_STRLEN_P(zendlval) = yyleng; \ } static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC) @@ -884,8 +875,8 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo ZVAL_STRINGL(zendlval, str, len, 1); /* convert escape sequences */ - s = t = zendlval->value.str.val; - end = s+zendlval->value.str.len; + s = t = Z_STRVAL_P(zendlval); + end = s+Z_STRLEN_P(zendlval); while (svalue.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'r': *t++ = '\r'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 't': *t++ = '\t'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'f': *t++ = '\f'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'v': *t++ = '\v'; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'e': #ifdef PHP_WIN32 @@ -921,7 +912,7 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo #else *t++ = '\e'; #endif - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case '"': case '`': @@ -933,20 +924,20 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo case '\\': case '$': *t++ = *s; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; break; case 'x': case 'X': if (ZEND_IS_HEX(*(s+1))) { char hex_buf[3] = { 0, 0, 0 }; - zendlval->value.str.len--; /* for the 'x' */ + Z_STRLEN_P(zendlval)--; /* for the 'x' */ hex_buf[0] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_HEX(*(s+1))) { hex_buf[1] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; } *t++ = (char) strtol(hex_buf, NULL, 16); } else { @@ -960,13 +951,13 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo char octal_buf[4] = { 0, 0, 0, 0 }; octal_buf[0] = *s; - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_OCT(*(s+1))) { octal_buf[1] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; if (ZEND_IS_OCT(*(s+1))) { octal_buf[2] = *(++s); - zendlval->value.str.len--; + Z_STRLEN_P(zendlval)--; } } *t++ = (char) strtol(octal_buf, NULL, 8); @@ -988,9 +979,9 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo *t = 0; if (SCNG(output_filter)) { size_t sz = 0; - s = zendlval->value.str.val; - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC); - zendlval->value.str.len = sz; + s = Z_STRVAL_P(zendlval); + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; efree(s); } } @@ -1020,7 +1011,6 @@ NEWLINE ("\r"|"\n"|"\r\n") /* compute yyleng before each rule */ := yyleng = YYCURSOR - SCNG(yy_text); - "exit" { return T_EXIT; } @@ -1183,9 +1173,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } {WHITESPACE}+ { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINES(yytext, yyleng); return T_WHITESPACE; } @@ -1215,6 +1203,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_NS_SEPARATOR; } +"..." { + return T_ELLIPSIS; +} + "new" { return T_NEW; } @@ -1506,30 +1498,29 @@ NEWLINE ("\r"|"\n"|"\r\n") if (len < SIZEOF_LONG * 8) { if (len == 0) { - zendlval->value.lval = 0; + Z_LVAL_P(zendlval) = 0; } else { - zendlval->value.lval = strtol(bin, NULL, 2); + Z_LVAL_P(zendlval) = strtol(bin, NULL, 2); } zendlval->type = IS_LONG; return T_LNUMBER; } else { - zendlval->value.dval = zend_bin_strtod(bin, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_bin_strtod(bin, NULL)); return T_DNUMBER; } } {LNUM} { if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ - zendlval->value.lval = strtol(yytext, NULL, 0); + Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0); } else { errno = 0; - zendlval->value.lval = strtol(yytext, NULL, 0); + Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0); if (errno == ERANGE) { /* Overflow */ if (yytext[0] == '0') { /* octal overflow */ - zendlval->value.dval = zend_oct_strtod(yytext, NULL); + Z_DVAL_P(zendlval) = zend_oct_strtod(yytext, NULL); } else { - zendlval->value.dval = zend_strtod(yytext, NULL); + Z_DVAL_P(zendlval) = zend_strtod(yytext, NULL); } zendlval->type = IS_DOUBLE; return T_DNUMBER; @@ -1552,120 +1543,80 @@ NEWLINE ("\r"|"\n"|"\r\n") if (len < SIZEOF_LONG * 2 || (len == SIZEOF_LONG * 2 && *hex <= '7')) { if (len == 0) { - zendlval->value.lval = 0; + Z_LVAL_P(zendlval) = 0; } else { - zendlval->value.lval = strtol(hex, NULL, 16); + Z_LVAL_P(zendlval) = strtol(hex, NULL, 16); } zendlval->type = IS_LONG; return T_LNUMBER; } else { - zendlval->value.dval = zend_hex_strtod(hex, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_hex_strtod(hex, NULL)); return T_DNUMBER; } } [0]|([1-9][0-9]*) { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { - zendlval->value.lval = strtol(yytext, NULL, 10); - zendlval->type = IS_LONG; + ZVAL_LONG(zendlval, strtol(yytext, NULL, 10)); } else { - zendlval->value.str.val = (char *)estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 1); } return T_NUM_STRING; } {LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */ - zendlval->value.str.val = (char *)estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 1); return T_NUM_STRING; } {DNUM}|{EXPONENT_DNUM} { - zendlval->value.dval = zend_strtod(yytext, NULL); - zendlval->type = IS_DOUBLE; + ZVAL_DOUBLE(zendlval, zend_strtod(yytext, NULL)); return T_DNUMBER; } "__CLASS__" { - const char *class_name = NULL; - - if (CG(active_class_entry) - && (ZEND_ACC_TRAIT == - (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) { + zend_class_entry *ce = CG(active_class_entry); + if (ce && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { /* We create a special __CLASS__ constant that is going to be resolved at run-time */ - zendlval->value.str.len = sizeof("__CLASS__")-1; - zendlval->value.str.val = estrndup("__CLASS__", zendlval->value.str.len); + Z_STRLEN_P(zendlval) = sizeof("__CLASS__")-1; + Z_STRVAL_P(zendlval) = estrndup("__CLASS__", Z_STRLEN_P(zendlval)); zendlval->type = IS_CONSTANT; } else { - if (CG(active_class_entry)) { - class_name = CG(active_class_entry)->name; - } - - if (!class_name) { - class_name = ""; + if (ce && ce->name) { + ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); } - - zendlval->value.str.len = strlen(class_name); - zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len); - zendlval->type = IS_STRING; } return T_CLASS_C; } "__TRAIT__" { - const char *trait_name = NULL; - - if (CG(active_class_entry) - && (ZEND_ACC_TRAIT == - (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) { - trait_name = CG(active_class_entry)->name; - } - - if (!trait_name) { - trait_name = ""; - } - - zendlval->value.str.len = strlen(trait_name); - zendlval->value.str.val = estrndup(trait_name, zendlval->value.str.len); - zendlval->type = IS_STRING; - + zend_class_entry *ce = CG(active_class_entry); + if (ce && ce->name && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { + ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); + } return T_TRAIT_C; } "__FUNCTION__" { - const char *func_name = NULL; - - if (CG(active_op_array)) { - func_name = CG(active_op_array)->function_name; - } - - if (!func_name) { - func_name = ""; + zend_op_array *op_array = CG(active_op_array); + if (op_array && op_array->function_name) { + ZVAL_STRING(zendlval, op_array->function_name, 1); + } else { + ZVAL_EMPTY_STRING(zendlval); } - zendlval->value.str.len = strlen(func_name); - zendlval->value.str.val = estrndup(func_name, zendlval->value.str.len); - zendlval->type = IS_STRING; return T_FUNC_C; } "__METHOD__" { const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL; const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL; - size_t len = 0; - - if (class_name) { - len += strlen(class_name) + 2; - } - if (func_name) { - len += strlen(func_name); - } - zendlval->value.str.len = zend_spprintf(&zendlval->value.str.val, 0, "%s%s%s", + Z_STRLEN_P(zendlval) = zend_spprintf(&Z_STRVAL_P(zendlval), 0, "%s%s%s", class_name ? class_name : "", class_name && func_name ? "::" : "", func_name ? func_name : "" @@ -1675,8 +1626,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } "__LINE__" { - zendlval->value.lval = CG(zend_lineno); - zendlval->type = IS_LONG; + ZVAL_LONG(zendlval, CG(zend_lineno)); return T_LINE; } @@ -1686,9 +1636,7 @@ NEWLINE ("\r"|"\n"|"\r\n") if (!filename) { filename = ""; } - zendlval->value.str.len = strlen(filename); - zendlval->value.str.val = estrndup(filename, zendlval->value.str.len); - zendlval->type = IS_STRING; + ZVAL_STRING(zendlval, filename, 1); return T_FILE; } @@ -1713,9 +1661,7 @@ NEWLINE ("\r"|"\n"|"\r\n") #endif } - zendlval->value.str.len = strlen(dirname); - zendlval->value.str.val = dirname; - zendlval->type = IS_STRING; + ZVAL_STRING(zendlval, dirname, 0); return T_DIR; } @@ -1739,9 +1685,7 @@ NEWLINE ("\r"|"\n"|"\r\n") } HANDLE_NEWLINES(yytext, yyleng); - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } @@ -1749,9 +1693,7 @@ NEWLINE ("\r"|"\n"|"\r\n") "<%=" { if (CG(asp_tags)) { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG_WITH_ECHO; } else { @@ -1761,9 +1703,7 @@ NEWLINE ("\r"|"\n"|"\r\n") "value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG_WITH_ECHO; } @@ -1771,9 +1711,7 @@ NEWLINE ("\r"|"\n"|"\r\n") "<%" { if (CG(asp_tags)) { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } else { @@ -1783,9 +1721,7 @@ NEWLINE ("\r"|"\n"|"\r\n") "value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; @@ -1794,9 +1730,7 @@ NEWLINE ("\r"|"\n"|"\r\n") "value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); return T_OPEN_TAG; } else { @@ -1850,14 +1784,14 @@ inline_html: if (SCNG(output_filter)) { int readsize; size_t sz = 0; - readsize = SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); - zendlval->value.str.len = sz; + readsize = SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; if (readsize < yyleng) { yyless(readsize); } } else { - zendlval->value.str.val = (char *) estrndup(yytext, yyleng); - zendlval->value.str.len = yyleng; + Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); + Z_STRLEN_P(zendlval) = yyleng; } zendlval->type = IS_STRING; HANDLE_NEWLINES(yytext, yyleng); @@ -1985,9 +1919,7 @@ inline_html: } ("?>"|""){NEWLINE}? { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(INITIAL); return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } @@ -1996,9 +1928,7 @@ inline_html: "%>"{NEWLINE}? { if (CG(asp_tags)) { BEGIN(INITIAL); - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; - zendlval->value.str.val = yytext; /* no copying - intentional */ + ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } else { yyless(1); @@ -2032,13 +1962,11 @@ inline_html: } } - zendlval->value.str.val = estrndup(yytext+bprefix+1, yyleng-bprefix-2); - zendlval->value.str.len = yyleng-bprefix-2; - zendlval->type = IS_STRING; + ZVAL_STRINGL(zendlval, yytext+bprefix+1, yyleng-bprefix-2, 1); /* convert escape sequences */ - s = t = zendlval->value.str.val; - end = s+zendlval->value.str.len; + s = t = Z_STRVAL_P(zendlval); + end = s+Z_STRLEN_P(zendlval); while (svalue.str.len--; + Z_STRLEN_P(zendlval)--; break; default: *t++ = '\\'; @@ -2067,9 +1995,9 @@ inline_html: if (SCNG(output_filter)) { size_t sz = 0; - s = zendlval->value.str.val; - SCNG(output_filter)((unsigned char **)&(zendlval->value.str.val), &sz, (unsigned char *)s, (size_t)zendlval->value.str.len TSRMLS_CC); - zendlval->value.str.len = sz; + s = Z_STRVAL_P(zendlval); + SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC); + Z_STRLEN_P(zendlval) = sz; efree(s); } return T_CONSTANT_ENCAPSED_STRING; @@ -2187,7 +2115,7 @@ inline_html: "{$" { - zendlval->value.lval = (long) '{'; + Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); yyless(1); return T_CURLY_OPEN; diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index d4adcf5aac982..00209a0ddc81d 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -33,7 +33,7 @@ #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC -#define ZEND_MODULE_API_NO 20121212 +#define ZEND_MODULE_API_NO 20131106 #ifdef ZTS #define USING_ZTS 1 #else diff --git a/Zend/zend_multibyte.c b/Zend/zend_multibyte.c index dafcf18393578..a75d074936ec8 100644 --- a/Zend/zend_multibyte.c +++ b/Zend/zend_multibyte.c @@ -53,7 +53,7 @@ static size_t dummy_encoding_converter(unsigned char **to, size_t *to_length, co static int dummy_encoding_list_parser(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, int persistent TSRMLS_DC) { *return_list = pemalloc(0, persistent); - return_size = 0; + *return_size = 0; return SUCCESS; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index f7be37036fce9..8beacdfd352b4 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -896,11 +896,8 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ zend_call_method_with_2_params(&this_ptr, ce, &ce->__call, ZEND_CALL_FUNC_NAME, &method_result_ptr, method_name_ptr, method_args_ptr); if (method_result_ptr) { - if (Z_ISREF_P(method_result_ptr) || Z_REFCOUNT_P(method_result_ptr) > 1) { - RETVAL_ZVAL(method_result_ptr, 1, 1); - } else { - RETVAL_ZVAL(method_result_ptr, 0, 1); - } + RETVAL_ZVAL_FAST(method_result_ptr); + zval_ptr_dtor(&method_result_ptr); } /* now destruct all auxiliaries */ @@ -1113,11 +1110,8 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ zend_call_method_with_2_params(NULL, ce, &ce->__callstatic, ZEND_CALLSTATIC_FUNC_NAME, &method_result_ptr, method_name_ptr, method_args_ptr); if (method_result_ptr) { - if (Z_ISREF_P(method_result_ptr) || Z_REFCOUNT_P(method_result_ptr) > 1) { - RETVAL_ZVAL(method_result_ptr, 1, 1); - } else { - RETVAL_ZVAL(method_result_ptr, 0, 1); - } + RETVAL_ZVAL_FAST(method_result_ptr); + zval_ptr_dtor(&method_result_ptr); } /* now destruct all auxiliaries */ @@ -1651,6 +1645,8 @@ ZEND_API zend_object_handlers std_object_handlers = { NULL, /* get_debug_info */ zend_std_get_closure, /* get_closure */ zend_std_get_gc, /* get_gc */ + NULL, /* do_operation */ + NULL, /* compare */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 3ea6008350d2f..07428737ff193 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -100,6 +100,7 @@ typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC); typedef zend_class_entry *(*zend_object_get_class_entry_t)(const zval *object TSRMLS_DC); typedef int (*zend_object_get_class_name_t)(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC); typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC); +typedef int (*zend_object_compare_zvals_t)(zval *resul, zval *op1, zval *op2 TSRMLS_DC); /* Cast an object to some other type */ @@ -113,6 +114,8 @@ typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, u typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval ***table, int *n TSRMLS_DC); +typedef int (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC); + struct _zend_object_handlers { /* general object functions */ zend_object_add_ref_t add_ref; @@ -142,6 +145,8 @@ struct _zend_object_handlers { zend_object_get_debug_info_t get_debug_info; zend_object_get_closure_t get_closure; zend_object_get_gc_t get_gc; + zend_object_do_operation_t do_operation; + zend_object_compare_zvals_t compare; }; extern ZEND_API zend_object_handlers std_object_handlers; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 41b4bd25710fd..ad0879888426c 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -499,7 +499,7 @@ static void zend_check_finally_breakout(zend_op_array *op_array, zend_uint op_nu CG(in_compilation) = 1; CG(active_op_array) = op_array; CG(zend_lineno) = op_array->opcodes[op_num].lineno; - zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); + zend_error_noreturn(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); } } } @@ -710,7 +710,7 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC) if (op_array->fn_flags & ZEND_ACC_GENERATOR) { if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) { CG(zend_lineno) = opline->lineno; - zend_error(E_COMPILE_ERROR, "Generators cannot return values using \"return\""); + zend_error_noreturn(E_COMPILE_ERROR, "Generators cannot return values using \"return\""); } opline->opcode = ZEND_GENERATOR_RETURN; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 5c84deb26850b..e8629291e545a 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -192,7 +192,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */ if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) { ZVAL_LONG(op, 0); } - STR_FREE(strval); + str_efree(strval); break; } case IS_BOOL: @@ -391,7 +391,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */ char *strval = Z_STRVAL_P(op); Z_LVAL_P(op) = strtol(strval, NULL, base); - STR_FREE(strval); + str_efree(strval); } break; case IS_ARRAY: @@ -451,7 +451,7 @@ ZEND_API void convert_to_double(zval *op) /* {{{ */ char *strval = Z_STRVAL_P(op); Z_DVAL_P(op) = zend_strtod(strval, NULL); - STR_FREE(strval); + str_efree(strval); } break; case IS_ARRAY: @@ -540,7 +540,7 @@ ZEND_API void convert_to_boolean(zval *op) /* {{{ */ } else { Z_LVAL_P(op) = 1; } - STR_FREE(strval); + str_efree(strval); } break; case IS_ARRAY: @@ -857,6 +857,8 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * default: if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD); + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result); converted = 1; @@ -904,6 +906,8 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * default: if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB); + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result); converted = 1; @@ -945,6 +949,8 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * default: if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL); + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result); converted = 1; @@ -1010,6 +1016,8 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * default: if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV); + zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result); converted = 1; @@ -1027,9 +1035,15 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ * zval op1_copy, op2_copy; long op1_lval; - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MOD); + + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } if (Z_LVAL_P(op2) == 0) { zend_error(E_WARNING, "Division by zero"); @@ -1053,9 +1067,16 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) zval op1_copy, op2_copy; long op1_lval; - zendi_convert_to_boolean(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_boolean(op2, op2_copy, result); + if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_XOR); + + zendi_convert_to_boolean(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_boolean(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } + ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2)); return SUCCESS; } @@ -1065,7 +1086,12 @@ ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */ { zval op1_copy; - zendi_convert_to_boolean(op1, op1_copy, result); + if (Z_TYPE_P(op1) != IS_BOOL) { + ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT); + + zendi_convert_to_boolean(op1, op1_copy, result); + } + ZVAL_BOOL(result, !Z_LVAL_P(op1)); return SUCCESS; } @@ -1073,29 +1099,32 @@ ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */ ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */ { - zval op1_copy = *op1; - - op1 = &op1_copy; - if (Z_TYPE_P(op1) == IS_LONG) { - ZVAL_LONG(result, ~Z_LVAL_P(op1)); - return SUCCESS; - } else if (Z_TYPE_P(op1) == IS_DOUBLE) { - ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1))); - return SUCCESS; - } else if (Z_TYPE_P(op1) == IS_STRING) { - int i; - - Z_TYPE_P(result) = IS_STRING; - Z_STRVAL_P(result) = estrndup(Z_STRVAL_P(op1), Z_STRLEN_P(op1)); - Z_STRLEN_P(result) = Z_STRLEN_P(op1); - for (i = 0; i < Z_STRLEN_P(op1); i++) { - Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i]; + switch (Z_TYPE_P(op1)) { + case IS_LONG: + ZVAL_LONG(result, ~Z_LVAL_P(op1)); + return SUCCESS; + case IS_DOUBLE: + ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1))); + return SUCCESS; + case IS_STRING: { + int i; + zval op1_copy = *op1; + + Z_TYPE_P(result) = IS_STRING; + Z_STRVAL_P(result) = estrndup(Z_STRVAL(op1_copy), Z_STRLEN(op1_copy)); + Z_STRLEN_P(result) = Z_STRLEN(op1_copy); + for (i = 0; i < Z_STRLEN(op1_copy); i++) { + Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i]; + } + return SUCCESS; } - return SUCCESS; + default: + ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT); + + zend_error(E_ERROR, "Unsupported operand types"); + return FAILURE; } - zend_error(E_ERROR, "Unsupported operand types"); - return FAILURE; /* unknown datatype */ } /* }}} */ @@ -1124,15 +1153,22 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) / result_str[i] |= Z_STRVAL_P(shorter)[i]; } if (result==op1) { - STR_FREE(Z_STRVAL_P(result)); + str_efree(Z_STRVAL_P(result)); } Z_STRVAL_P(result) = result_str; Z_STRLEN_P(result) = result_len; return SUCCESS; } - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_OR); + + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2)); return SUCCESS; @@ -1164,17 +1200,22 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) result_str[i] &= Z_STRVAL_P(longer)[i]; } if (result==op1) { - STR_FREE(Z_STRVAL_P(result)); + str_efree(Z_STRVAL_P(result)); } Z_STRVAL_P(result) = result_str; Z_STRLEN_P(result) = result_len; return SUCCESS; } + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_AND); - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2)); return SUCCESS; @@ -1206,16 +1247,22 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) result_str[i] ^= Z_STRVAL_P(longer)[i]; } if (result==op1) { - STR_FREE(Z_STRVAL_P(result)); + str_efree(Z_STRVAL_P(result)); } Z_STRVAL_P(result) = result_str; Z_STRLEN_P(result) = result_len; return SUCCESS; } - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_XOR); + + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2)); return SUCCESS; @@ -1227,9 +1274,16 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) / zval op1_copy, op2_copy; long op1_lval; - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SL); + + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } + ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2)); return SUCCESS; } @@ -1240,9 +1294,16 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) zval op1_copy, op2_copy; long op1_lval; - zendi_convert_to_long(op1, op1_copy, result); - op1_lval = Z_LVAL_P(op1); - zendi_convert_to_long(op2, op2_copy, result); + if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SR); + + zendi_convert_to_long(op1, op1_copy, result); + op1_lval = Z_LVAL_P(op1); + zendi_convert_to_long(op2, op2_copy, result); + } else { + op1_lval = Z_LVAL_P(op1); + } + ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2)); return SUCCESS; } @@ -1252,14 +1313,8 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */ { int length = Z_STRLEN_P(op1) + 1; - char *buf; + char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1); - if (IS_INTERNED(Z_STRVAL_P(op1))) { - buf = (char *) emalloc(length + 1); - memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); - } else { - buf = (char *) erealloc(Z_STRVAL_P(op1), length + 1); - } buf[length - 1] = (char) Z_LVAL_P(op2); buf[length] = 0; ZVAL_STRINGL(result, buf, length, 0); @@ -1271,14 +1326,8 @@ ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */ { int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); - char *buf; + char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1); - if (IS_INTERNED(Z_STRVAL_P(op1))) { - buf = (char *) emalloc(length+1); - memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); - } else { - buf = (char *) erealloc(Z_STRVAL_P(op1), length+1); - } memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); buf[length] = 0; ZVAL_STRINGL(result, buf, length, 0); @@ -1291,11 +1340,15 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{ zval op1_copy, op2_copy; int use_copy1 = 0, use_copy2 = 0; - if (Z_TYPE_P(op1) != IS_STRING) { - zend_make_printable_zval(op1, &op1_copy, &use_copy1); - } - if (Z_TYPE_P(op2) != IS_STRING) { - zend_make_printable_zval(op2, &op2_copy, &use_copy2); + if (Z_TYPE_P(op1) != IS_STRING || Z_TYPE_P(op2) != IS_STRING) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT); + + if (Z_TYPE_P(op1) != IS_STRING) { + zend_make_printable_zval(op1, &op1_copy, &use_copy1); + } + if (Z_TYPE_P(op2) != IS_STRING) { + zend_make_printable_zval(op2, &op2_copy, &use_copy2); + } } if (use_copy1) { @@ -1526,20 +1579,24 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* { ZVAL_LONG(result, -1); return SUCCESS; - case TYPE_PAIR(IS_OBJECT, IS_OBJECT): - /* If both are objects sharing the same comparision handler then use is */ - if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) { + default: + if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) { + return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2 TSRMLS_CC); + } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) { + return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2 TSRMLS_CC); + } + + if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) { if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) { /* object handles are identical, apparently this is the same object */ ZVAL_LONG(result, 0); return SUCCESS; } - ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC)); - return SUCCESS; + if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) { + ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2 TSRMLS_CC)); + return SUCCESS; + } } - /* break missing intentionally */ - - default: if (Z_TYPE_P(op1) == IS_OBJECT) { if (Z_OBJ_HT_P(op1)->get) { op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC); @@ -1773,16 +1830,14 @@ static void increment_string(zval *str) /* {{{ */ int ch; if (Z_STRLEN_P(str) == 0) { - STR_FREE(Z_STRVAL_P(str)); + str_efree(Z_STRVAL_P(str)); Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1); Z_STRLEN_P(str) = 1; return; } if (IS_INTERNED(s)) { - s = (char*) emalloc(Z_STRLEN_P(str) + 1); - memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1); - Z_STRVAL_P(str) = s; + Z_STRVAL_P(str) = s = estrndup(s, Z_STRLEN_P(str)); } while (pos >= 0) { @@ -1840,7 +1895,7 @@ static void increment_string(zval *str) /* {{{ */ t[0] = 'a'; break; } - STR_FREE(Z_STRVAL_P(str)); + str_efree(Z_STRVAL_P(str)); Z_STRVAL_P(str) = t; } } @@ -1890,6 +1945,20 @@ ZEND_API int increment_function(zval *op1) /* {{{ */ } } break; + case IS_OBJECT: + if (Z_OBJ_HANDLER_P(op1, do_operation)) { + zval *op2; + int res; + TSRMLS_FETCH(); + + MAKE_STD_ZVAL(op2); + ZVAL_LONG(op2, 1); + res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, op2 TSRMLS_CC); + zval_ptr_dtor(&op2); + + return res; + } + return FAILURE; default: return FAILURE; } @@ -1916,13 +1985,13 @@ ZEND_API int decrement_function(zval *op1) /* {{{ */ break; case IS_STRING: /* Like perl we only support string increment */ if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */ - STR_FREE(Z_STRVAL_P(op1)); + str_efree(Z_STRVAL_P(op1)); ZVAL_LONG(op1, -1); break; } switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) { case IS_LONG: - STR_FREE(Z_STRVAL_P(op1)); + str_efree(Z_STRVAL_P(op1)); if (lval == LONG_MIN) { double d = (double)lval; ZVAL_DOUBLE(op1, d-1); @@ -1931,11 +2000,25 @@ ZEND_API int decrement_function(zval *op1) /* {{{ */ } break; case IS_DOUBLE: - STR_FREE(Z_STRVAL_P(op1)); + str_efree(Z_STRVAL_P(op1)); ZVAL_DOUBLE(op1, dval - 1); break; } break; + case IS_OBJECT: + if (Z_OBJ_HANDLER_P(op1, do_operation)) { + zval *op2; + int res; + TSRMLS_FETCH(); + + MAKE_STD_ZVAL(op2); + ZVAL_LONG(op2, 1); + res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, op2 TSRMLS_CC); + zval_ptr_dtor(&op2); + + return res; + } + return FAILURE; default: return FAILURE; } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 6e7c1c01df3f7..15ad79e4dbfc5 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -269,11 +269,11 @@ static inline zend_uchar is_numeric_string(const char *str, int length, long *lv return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL); } -static inline char * -zend_memnstr(char *haystack, char *needle, int needle_len, char *end) +static inline const char * +zend_memnstr(const char *haystack, const char *needle, int needle_len, char *end) { - char *p = haystack; - char ne = needle[needle_len-1]; + const char *p = haystack; + const char ne = needle[needle_len-1]; if (needle_len == 1) { return (char *)memchr(p, *needle, (end-p)); @@ -945,6 +945,24 @@ static zend_always_inline int fast_is_smaller_or_equal_function(zval *result, zv return Z_LVAL_P(result) <= 0; } +#define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode) \ + if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation)) { \ + if (SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \ + return SUCCESS; \ + } \ + } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, do_operation)) { \ + if (SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC)) { \ + return SUCCESS; \ + } \ + } + +#define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode) \ + if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, do_operation) \ + && SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC) \ + ) { \ + return SUCCESS; \ + } + #endif /* diff --git a/Zend/zend_string.h b/Zend/zend_string.h index ebf8c816c11ff..27ba50be3d642 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -56,12 +56,39 @@ END_EXTERN_C() } \ } while (0) +#define str_efree_rel(s) do { \ + if (!IS_INTERNED(s)) { \ + efree_rel((char *)s); \ + } \ + } while (0) + #define str_free(s) do { \ if (!IS_INTERNED(s)) { \ free((char*)s); \ } \ } while (0) +#define str_erealloc(str, new_len) \ + (IS_INTERNED(str) \ + ? _str_erealloc(str, new_len, INTERNED_LEN(str)) \ + : erealloc(str, new_len)) + +static inline char *_str_erealloc(char *str, size_t new_len, size_t old_len) { + char *buf = (char *) emalloc(new_len); + memcpy(buf, str, old_len); + return buf; +} + +#define str_estrndup(str, len) \ + (IS_INTERNED(str) ? (str) : estrndup((str), (len))) + +#define str_strndup(str, len) \ + (IS_INTERNED(str) ? (str) : zend_strndup((str), (len))); + +#define str_hash(str, len) \ + (IS_INTERNED(str) ? INTERNED_HASH(str) : zend_hash_func((str), (len)+1)) + + #endif /* ZEND_STRING_H */ /* diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index c0e1849eefa13..d82e1642e78b0 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -33,7 +33,7 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC) case IS_STRING: case IS_CONSTANT: CHECK_ZVAL_STRING_REL(zvalue); - STR_FREE_REL(zvalue->value.str.val); + str_efree_rel(zvalue->value.str.val); break; case IS_ARRAY: case IS_CONSTANT_ARRAY: { diff --git a/TSRM/tsrm_virtual_cwd.c b/Zend/zend_virtual_cwd.c similarity index 92% rename from TSRM/tsrm_virtual_cwd.c rename to Zend/zend_virtual_cwd.c index 3e211fa54f9a2..d9da5cf4c0c8e 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -30,7 +30,8 @@ #include #include -#include "tsrm_virtual_cwd.h" +#include "zend.h" +#include "zend_virtual_cwd.h" #include "tsrm_strtok_r.h" #ifdef TSRM_WIN32 @@ -126,7 +127,6 @@ static int php_check_dots(const char *element, int n) #define TOKENIZER_STRING "/" #endif - /* default macros */ #ifndef IS_DIRECTORY_UP @@ -149,11 +149,21 @@ static int php_check_dots(const char *element, int n) #define CWD_STATE_COPY(d, s) \ (d)->cwd_length = (s)->cwd_length; \ - (d)->cwd = (char *) malloc((s)->cwd_length+1); \ + (d)->cwd = (char *) emalloc((s)->cwd_length+1); \ memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1); #define CWD_STATE_FREE(s) \ - free((s)->cwd); + efree((s)->cwd); + +#ifdef TSRM_WIN32 +# define CWD_STATE_FREE_ERR(state) do { \ + DWORD last_error = GetLastError(); \ + CWD_STATE_FREE(state); \ + SetLastError(last_error); \ + } while (0) +#else +# define CWD_STATE_FREE_ERR(state) CWD_STATE_FREE(state) +#endif #ifdef TSRM_WIN32 @@ -286,6 +296,7 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ WIN32_FILE_ATTRIBUTE_DATA data; __int64 t; const size_t path_len = strlen(path); + ALLOCA_FLAG(use_heap_large); if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) { return stat(path, buf); @@ -337,16 +348,15 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; unsigned int retlength = 0; - TSRM_ALLOCA_FLAG(use_heap_large); hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hLink == INVALID_HANDLE_VALUE) { return -1; } - pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); + pbuffer = (REPARSE_DATA_BUFFER *)do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); CloseHandle(hLink); return -1; } @@ -363,7 +373,7 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ buf->st_mode |=; } #endif - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); } else { buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); @@ -429,7 +439,6 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */ static void cwd_globals_dtor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */ { - CWD_STATE_FREE(&cwd_g->cwd); realpath_cache_clean(TSRMLS_C); } /* }}} */ @@ -490,6 +499,25 @@ CWD_API void virtual_cwd_shutdown(void) /* {{{ */ } /* }}} */ +CWD_API int virtual_cwd_activate(TSRMLS_D) /* {{{ */ +{ + if (CWDG(cwd).cwd == NULL) { + CWD_STATE_COPY(&CWDG(cwd), &main_cwd_state); + } + return 0; +} +/* }}} */ + +CWD_API int virtual_cwd_deactivate(TSRMLS_D) /* {{{ */ +{ + if (CWDG(cwd).cwd != NULL) { + CWD_STATE_FREE(&CWDG(cwd)); + CWDG(cwd).cwd = NULL; + } + return 0; +} +/* }}} */ + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ { cwd_state *state; @@ -500,7 +528,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ char *retval; *length = 1; - retval = (char *) malloc(2); + retval = (char *) emalloc(2); if (retval == NULL) { return NULL; } @@ -515,7 +543,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ char *retval; *length = state->cwd_length+1; - retval = (char *) malloc(*length+1); + retval = (char *) emalloc(*length+1); if (retval == NULL) { return NULL; } @@ -527,7 +555,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ } #endif *length = state->cwd_length; - return strdup(state->cwd); + return estrdup(state->cwd); } /* }}} */ @@ -543,12 +571,12 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC) /* {{{ */ return cwd; } if (length > size-1) { - free(cwd); + efree(cwd); errno = ERANGE; /* Is this OK? */ return NULL; } memcpy(buf, cwd, length+1); - free(cwd); + efree(cwd); return buf; } /* }}} */ @@ -754,13 +782,13 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #ifdef TSRM_WIN32 WIN32_FIND_DATA data; HANDLE hFind; - TSRM_ALLOCA_FLAG(use_heap_large) + ALLOCA_FLAG(use_heap_large) #else struct stat st; #endif realpath_cache_bucket *bucket; char *tmp; - TSRM_ALLOCA_FLAG(use_heap) + ALLOCA_FLAG(use_heap) while (1) { if (len <= start) { @@ -860,7 +888,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i FindClose(hFind); } - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); if(save && @@ -887,12 +915,12 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i return -1; } - pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); + pbuffer = (REPARSE_DATA_BUFFER *)do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); if (pbuffer == NULL) { return -1; } if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); CloseHandle(hLink); return -1; } @@ -908,7 +936,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i printname_len + 1, printname, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); @@ -920,7 +948,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i substitutename_len + 1, substitutename, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; substitutename[substitutename_len] = 0; @@ -934,7 +962,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i printname_len + 1, printname, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0; @@ -945,7 +973,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i substitutename_len + 1, substitutename, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; substitutename[substitutename_len] = 0; @@ -955,7 +983,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i memcpy(substitutename, path, len + 1); substitutename_len = len; } else { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; } @@ -999,21 +1027,21 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i fprintf(stderr, "sub: %s ", substitutename); fprintf(stderr, "resolved: %s ", path); #endif - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); if(isabsolute == 1) { if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { /* use_realpath is 0 in the call below coz path is absolute*/ j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC); if(j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } } else { if(i + j >= MAXPATHLEN - 1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } @@ -1022,7 +1050,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if(j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1043,7 +1071,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #elif defined(NETWARE) save = 0; - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); #else if (save && php_sys_lstat(path, &st) < 0) { @@ -1055,25 +1083,25 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i save = 0; } - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); if (save && S_ISLNK(st.st_mode)) { if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) { /* too many links or broken symlinks */ - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } path[j] = 0; if (IS_ABSOLUTE_PATH(path, j)) { j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if (j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } else { if (i + j >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; /* buffer overflow */ } memmove(path+i, path, j+1); @@ -1081,7 +1109,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if (j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1096,7 +1124,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } if (is_dir && !directory) { /* not a directory */ - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1112,7 +1140,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } #ifdef TSRM_WIN32 if (j < 0 || j + len - i >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } if (save) { @@ -1127,7 +1155,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } #else if (j < 0 || j + len - i >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } memcpy(path+j, tmp+i, len-i+1); @@ -1140,7 +1168,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i realpath_cache_add(tmp, len, path, j, directory, *t TSRMLS_CC); } - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return j; } } @@ -1316,7 +1344,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func CWD_STATE_COPY(&old_state, state); state->cwd_length = path_length; - tmp = realloc(state->cwd, state->cwd_length+1); + tmp = erealloc(state->cwd, state->cwd_length+1); if (tmp == NULL) { #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Out of memory\n"); @@ -1336,7 +1364,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func } } else { state->cwd_length = path_length; - tmp = realloc(state->cwd, state->cwd_length+1); + tmp = erealloc(state->cwd, state->cwd_length+1); if (tmp == NULL) { #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Out of memory\n"); @@ -1367,7 +1395,7 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path int length = strlen(path); char *temp; int retval; - TSRM_ALLOCA_FLAG(use_heap) + ALLOCA_FLAG(use_heap) if (length == 0) { return 1; /* Can't cd to empty string */ @@ -1384,14 +1412,14 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */ length++; } - temp = (char *) tsrm_do_alloca(length+1, use_heap); + temp = (char *) do_alloca(length+1, use_heap); memcpy(temp, path, length); temp[length] = 0; #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Changing directory to %s\n", temp); #endif retval = p_chdir(temp TSRMLS_CC); - tsrm_free_alloca(temp, use_heap); + free_alloca(temp, use_heap); return retval; } /* }}} */ @@ -1404,7 +1432,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* { /* realpath("") returns CWD */ if (!*path) { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { retval = NULL; goto end; @@ -1417,7 +1445,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* { } else if (!IS_ABSOLUTE_PATH(path, strlen(path))) { CWD_STATE_COPY(&new_state, &CWDG(cwd)); } else { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { retval = NULL; goto end; @@ -1474,13 +1502,14 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC) /* {{{ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return NULL; } f = fopen(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); + return f; } /* }}} */ @@ -1492,7 +1521,7 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1502,7 +1531,7 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ ret = access(new_state.cwd, mode); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } @@ -1565,7 +1594,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) / CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1575,7 +1604,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) / ret = utime(new_state.cwd, buf); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1588,13 +1617,13 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } ret = chmod(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1607,7 +1636,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1621,7 +1650,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li ret = chown(new_state.cwd, owner, group); } - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1634,7 +1663,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1650,7 +1679,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */ } else { f = open(new_state.cwd, flags); } - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return f; } /* }}} */ @@ -1662,18 +1691,18 @@ CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } f = creat(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return f; } /* }}} */ -CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */ +CWD_API int virtual_rename(const char *oldname, const char *newname TSRMLS_DC) /* {{{ */ { cwd_state old_state; cwd_state new_state; @@ -1681,15 +1710,15 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&old_state, &CWDG(cwd)); if (virtual_file_ex(&old_state, oldname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&old_state); + CWD_STATE_FREE_ERR(&old_state); return -1; } oldname = old_state.cwd; CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, newname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&old_state); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&old_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } newname = new_state.cwd; @@ -1703,8 +1732,8 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */ retval = rename(oldname, newname); #endif - CWD_STATE_FREE(&old_state); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&old_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } @@ -1717,13 +1746,13 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = php_sys_stat(new_state.cwd, buf); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1735,13 +1764,13 @@ CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ * CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = php_sys_lstat(new_state.cwd, buf); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1753,13 +1782,13 @@ CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = unlink(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1771,7 +1800,7 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1780,7 +1809,7 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) /* {{{ */ #else retval = mkdir(new_state.cwd, mode); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1792,13 +1821,13 @@ CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = rmdir(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1814,13 +1843,13 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return NULL; } retval = opendir(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1882,7 +1911,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /* dir_length = CWDG(cwd).cwd_length; dir = CWDG(cwd).cwd; - ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); + ptr = command_line = (char *) emalloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); if (!command_line) { return NULL; } @@ -1916,7 +1945,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /* memcpy(ptr, command, command_length+1); retval = popen(command_line, type); - free(command_line); + efree(command_line); return retval; } /* }}} */ @@ -1929,7 +1958,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ /* realpath("") returns CWD */ if (!*path) { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { return NULL; } @@ -1940,10 +1969,10 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ } } else if (!IS_ABSOLUTE_PATH(path, strlen(path)) && VCWD_GETCWD(cwd, MAXPATHLEN)) { - new_state.cwd = strdup(cwd); + new_state.cwd = estrdup(cwd); new_state.cwd_length = strlen(cwd); } else { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { return NULL; } @@ -1952,7 +1981,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ } if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - free(new_state.cwd); + efree(new_state.cwd); return NULL; } @@ -1960,7 +1989,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; memcpy(real_path, new_state.cwd, copy_len); real_path[copy_len] = '\0'; - free(new_state.cwd); + efree(new_state.cwd); return real_path; } else { return new_state.cwd; diff --git a/TSRM/tsrm_virtual_cwd.h b/Zend/zend_virtual_cwd.h similarity index 98% rename from TSRM/tsrm_virtual_cwd.h rename to Zend/zend_virtual_cwd.h index 8aac4aa2671ec..a6ac0aeef7162 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -151,6 +151,8 @@ typedef int (*verify_path_func)(const cwd_state *); CWD_API void virtual_cwd_startup(void); CWD_API void virtual_cwd_shutdown(void); +CWD_API int virtual_cwd_activate(TSRMLS_D); +CWD_API int virtual_cwd_deactivate(TSRMLS_D); CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC); CWD_API int virtual_chdir(const char *path TSRMLS_DC); @@ -161,7 +163,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC); CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC); CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...); CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC); -CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC); +CWD_API int virtual_rename(const char *oldname, const char *newname TSRMLS_DC); CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC); CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC); CWD_API int virtual_unlink(const char *path TSRMLS_DC); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c2c3ae52195fb..572aac5a20706 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1052,10 +1052,8 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| */ if (OP1_TYPE == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -1170,22 +1168,18 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - OP1_TYPE != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) { zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); FREE_OP2(); FREE_OP1(); } else { - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); + container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); FREE_OP2(); - FREE_OP1_VAR_PTR(); + if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + FREE_OP1_VAR_PTR_FAST(); + } } CHECK_EXCEPTION(); @@ -1255,10 +1249,10 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV) zval **container; SAVE_OPLINE(); - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS); + container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_IS); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC); FREE_OP2(); - FREE_OP1_VAR_PTR(); + FREE_OP1_VAR_PTR_FAST(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1280,15 +1274,17 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV) if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + FREE_OP2(); + FREE_OP1_VAR_PTR(); } else { if (OP2_TYPE == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); + container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); + FREE_OP2(); + FREE_OP1_VAR_PTR_FAST(); } - FREE_OP2(); - FREE_OP1_VAR_PTR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1832,7 +1828,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) EG(current_execute_data) = EX(prev_execute_data); EG(opline_ptr) = NULL; if (!EG(active_symbol_table)) { - i_free_compiled_variables(execute_data); + i_free_compiled_variables(execute_data TSRMLS_CC); } zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); @@ -1923,14 +1919,15 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) { if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) { zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); /* Never reached */ } if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", fbc->common.scope ? fbc->common.scope->name : "", fbc->common.scope ? "::" : "", fbc->common.function_name); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } } if (fbc->common.scope && @@ -1940,6 +1937,9 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { /* FIXME: output identifiers properly */ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } else { /* FIXME: output identifiers properly */ /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ @@ -1983,7 +1983,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) if (!zend_execute_internal) { /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + fbc->internal_function.handler(opline->extended_value, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } @@ -2602,7 +2602,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -2677,7 +2677,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) if (call->object) { Z_ADDREF_P(call->object); } - if (OP2_TYPE == IS_VAR && OP2_FREE && + if (OP2_TYPE == IS_VAR && OP2_FREE && Z_REFCOUNT_P(function_name) == 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; @@ -2837,9 +2837,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); if (!EG(return_value_ptr_ptr)) { - if (OP1_TYPE == IS_TMP_VAR) { - FREE_OP1(); - } + FREE_OP1(); } else { if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR || @@ -2852,18 +2850,23 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; + FREE_OP1_IF_VAR(); } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; + if (OP1_TYPE == IS_VAR) { + Z_DELREF_P(retval_ptr); + } ALLOC_INIT_ZVAL(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; - Z_ADDREF_P(retval_ptr); + if (OP1_TYPE == IS_CV) { + Z_ADDREF_P(retval_ptr); + } } } - FREE_OP1_IF_VAR(); ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } @@ -2934,7 +2937,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) } } while (0); - FREE_OP1_IF_VAR(); + FREE_OP1_VAR_PTR(); ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } @@ -3077,21 +3080,26 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); if (varptr == &EG(uninitialized_zval)) { - ALLOC_ZVAL(varptr); - INIT_ZVAL(*varptr); - Z_SET_REFCOUNT_P(varptr, 0); + if (OP1_TYPE == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); } else if (PZVAL_IS_REF(varptr)) { - zval *original_var = varptr; + if (OP1_TYPE == IS_CV || + (OP1_TYPE == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; - ALLOC_ZVAL(varptr); - ZVAL_COPY_VALUE(varptr, original_var); - Z_UNSET_ISREF_P(varptr); - Z_SET_REFCOUNT_P(varptr, 0); - zval_copy_ctor(varptr); + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + FREE_OP1(); + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (OP1_TYPE == IS_CV) { + Z_ADDREF_P(varptr); } - Z_ADDREF_P(varptr); zend_vm_stack_push(varptr TSRMLS_CC); - FREE_OP1(); /* for string offsets */ CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -3112,22 +3120,15 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); } - if (OP1_TYPE == IS_VAR && - (opline->extended_value & ZEND_ARG_SEND_FUNCTION) && - EX_T(opline->op1.var).var.fcall_returned_reference && - EX_T(opline->op1.var).var.ptr) { - varptr = EX_T(opline->op1.var).var.ptr; - PZVAL_UNLOCK_EX(varptr, &free_op1, 0); - } else { - varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); - } + varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || EX_T(opline->op1.var).var.fcall_returned_reference) && varptr != &EG(uninitialized_zval) && - (PZVAL_IS_REF(varptr) || - (Z_REFCOUNT_P(varptr) == 1 && (OP1_TYPE == IS_CV || free_op1.var)))) { + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { Z_SET_ISREF_P(varptr); - Z_ADDREF_P(varptr); + if (OP1_TYPE == IS_CV) { + Z_ADDREF_P(varptr); + } zend_vm_stack_push(varptr TSRMLS_CC); } else { zval *valptr; @@ -3142,9 +3143,9 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) if (!IS_OP1_TMP_FREE()) { zval_copy_ctor(valptr); } + FREE_OP1_IF_VAR(); zend_vm_stack_push(valptr TSRMLS_CC); } - FREE_OP1_IF_VAR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3273,6 +3274,37 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) +{ + USE_OPLINE + zend_uint arg_num = opline->op1.num; + zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C); + zval **var_ptr, *params; + + SAVE_OPLINE(); + + var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); + Z_DELREF_PP(var_ptr); + MAKE_STD_ZVAL(params); + *var_ptr = params; + + if (arg_num <= arg_count) { + array_init_size(params, arg_count - arg_num + 1); + } else { + array_init(params); + } + + for (; arg_num <= arg_count; ++arg_num) { + zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); + zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC); + zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL); + Z_ADDREF_PP(param); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY) { USE_OPLINE @@ -3343,9 +3375,6 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) zend_free_op free_op1, free_op2; SAVE_OPLINE(); - if (OP1_TYPE==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, GET_OP1_ZVAL_PTR(BP_VAR_R), GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); @@ -3609,7 +3638,8 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + FREE_OP1_IF_VAR(); + } else if (OP1_TYPE == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -3634,11 +3664,7 @@ ZEND_VM_C_LABEL(num_index): hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index)); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -3657,8 +3683,6 @@ ZEND_VM_C_LABEL(num_index): } if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) { FREE_OP1_VAR_PTR(); - } else { - FREE_OP1_IF_VAR(); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -3988,11 +4012,7 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV) hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_dim)); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -4147,19 +4167,27 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { - Z_ADDREF_P(array_ptr); + if (OP1_TYPE == IS_CV) { + Z_ADDREF_P(array_ptr); + } } } else if (OP1_TYPE == IS_CONST || - ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && + (OP1_TYPE == IS_CV && !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1)) { + Z_REFCOUNT_P(array_ptr) > 1) || + (OP1_TYPE == IS_VAR && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 2)) { zval *tmp; + if (OP1_TYPE == IS_VAR) { + Z_DELREF_P(array_ptr); + } ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); zval_copy_ctor(tmp); array_ptr = tmp; - } else { + } else if (OP1_TYPE == IS_CV) { Z_ADDREF_P(array_ptr); } } @@ -4167,10 +4195,15 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); + if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { + FREE_OP1_IF_VAR(); + } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - FREE_OP1_IF_VAR(); + if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + FREE_OP1_VAR_PTR(); + } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -4187,14 +4220,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); - FREE_OP1_IF_VAR(); + if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + FREE_OP1_VAR_PTR(); + } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); - FREE_OP1_IF_VAR(); + if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + FREE_OP1_VAR_PTR(); + } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -4224,7 +4261,9 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) is_empty = 1; } - FREE_OP1_IF_VAR(); + if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + FREE_OP1_VAR_PTR(); + } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -4461,7 +4500,6 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST| SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -4488,11 +4526,7 @@ ZEND_VM_C_LABEL(num_index_prop): hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop)); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -4585,7 +4619,7 @@ ZEND_VM_C_LABEL(num_index_prop): Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - FREE_OP1_VAR_PTR(); + FREE_OP1_IF_VAR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5169,7 +5203,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) zval_copy_ctor(&c.value); } c.flags = CONST_CS; /* non persistent, case sensetive */ - c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + c.name = str_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); c.name_len = Z_STRLEN_P(name)+1; c.module_number = PHP_USER_CONSTANT; @@ -5287,14 +5321,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE generator->value = *value_ptr; } - FREE_OP1_IF_VAR(); + FREE_OP1_VAR_PTR(); } } else { zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R); /* Consts, temporary variables and references need copying */ if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -5307,12 +5341,13 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE } generator->value = copy; + FREE_OP1_IF_VAR(); } else { - Z_ADDREF_P(value); + if (OP1_TYPE == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - FREE_OP1_IF_VAR(); } } else { /* If no value was specified yield null */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b21f6bf895101..7ad7dcf463f51 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -396,7 +396,7 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) EG(current_execute_data) = EX(prev_execute_data); EG(opline_ptr) = NULL; if (!EG(active_symbol_table)) { - i_free_compiled_variables(execute_data); + i_free_compiled_variables(execute_data TSRMLS_CC); } zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC); @@ -487,14 +487,15 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) { if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) { zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); /* Never reached */ } if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", fbc->common.scope ? fbc->common.scope->name : "", fbc->common.scope ? "::" : "", fbc->common.function_name); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } } if (fbc->common.scope && @@ -504,6 +505,9 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { /* FIXME: output identifiers properly */ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } else { /* FIXME: output identifiers properly */ /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ @@ -547,7 +551,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR if (!zend_execute_internal) { /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + fbc->internal_function.handler(opline->extended_value, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } @@ -738,6 +742,37 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_uint arg_num = opline->op1.num; + zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C); + zval **var_ptr, *params; + + SAVE_OPLINE(); + + var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); + Z_DELREF_PP(var_ptr); + MAKE_STD_ZVAL(params); + *var_ptr = params; + + if (arg_num <= arg_count) { + array_init_size(params, arg_count - arg_num + 1); + } else { + array_init(params); + } + + for (; arg_num <= arg_count; ++arg_num) { + zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); + zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC); + zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL); + Z_ADDREF_PP(param); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -1270,7 +1305,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE if (call->object) { Z_ADDREF_P(call->object); } - if (IS_CONST == IS_VAR && 0 && + if (IS_CONST == IS_VAR && 0 && Z_REFCOUNT_P(function_name) == 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; @@ -1595,7 +1630,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H if (call->object) { Z_ADDREF_P(call->object); } - if (IS_TMP_VAR == IS_VAR && 1 && + if (IS_TMP_VAR == IS_VAR && 1 && Z_REFCOUNT_P(function_name) == 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; @@ -1719,7 +1754,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1768,7 +1803,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); } efree(lcname); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); call->object = NULL; call->called_scope = NULL; call->is_ctor_call = 0; @@ -1782,12 +1817,12 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H if (call->object) { Z_ADDREF_P(call->object); } - if (IS_VAR == IS_VAR && (free_op2.var != NULL) && + if (IS_VAR == IS_VAR && (free_op2.var != NULL) && Z_REFCOUNT_P(function_name) == 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } call->is_ctor_call = 0; EX(call) = call; @@ -1858,7 +1893,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } call->is_ctor_call = 0; EX(call) = call; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -2007,7 +2042,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA if (call->object) { Z_ADDREF_P(call->object); } - if (IS_CV == IS_VAR && 0 && + if (IS_CV == IS_VAR && 0 && Z_REFCOUNT_P(function_name) == 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; @@ -2339,9 +2374,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG retval_ptr = opline->op1.zv; if (!EG(return_value_ptr_ptr)) { - if (IS_CONST == IS_TMP_VAR) { - } } else { if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR || @@ -2354,18 +2387,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; + } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; + if (IS_CONST == IS_VAR) { + Z_DELREF_P(retval_ptr); + } ALLOC_INIT_ZVAL(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; - Z_ADDREF_P(retval_ptr); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(retval_ptr); + } } } - return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -2828,19 +2866,27 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { - Z_ADDREF_P(array_ptr); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(array_ptr); + } } } else if (IS_CONST == IS_CONST || - ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && + (IS_CONST == IS_CV && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1) || + (IS_CONST == IS_VAR && !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1)) { + Z_REFCOUNT_P(array_ptr) > 2)) { zval *tmp; + if (IS_CONST == IS_VAR) { + Z_DELREF_P(array_ptr); + } ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); zval_copy_ctor(tmp); array_ptr = tmp; - } else { + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(array_ptr); } } @@ -2848,10 +2894,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); + if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { + + } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { + if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -2868,14 +2919,18 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -2905,6 +2960,9 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A is_empty = 1; } + if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + + } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -3370,10 +3428,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type */ if (IS_CONST == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -3487,12 +3543,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CONST != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { zval *container = opline->op1.zv; zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); @@ -3502,7 +3552,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -3638,7 +3690,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -3662,9 +3714,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); - if (IS_CONST==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, opline->op2.zv TSRMLS_CC); @@ -3801,7 +3850,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -3826,11 +3876,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -3849,8 +3895,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O } if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -4061,7 +4105,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD zval_copy_ctor(&c.value); } c.flags = CONST_CS; /* non persistent, case sensetive */ - c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + c.name = str_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); c.name_len = Z_STRLEN_P(name)+1; c.module_number = PHP_USER_CONSTANT; @@ -4145,7 +4189,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -4158,11 +4202,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -4510,12 +4556,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CONST != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { zval *container = opline->op1.zv; zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); @@ -4525,7 +4565,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); + if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -4637,7 +4679,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -4661,9 +4703,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op2; SAVE_OPLINE(); - if (IS_CONST==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); @@ -4704,7 +4743,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -4729,11 +4769,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -4752,8 +4788,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC } if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -4845,7 +4879,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -4858,11 +4892,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -4936,7 +4972,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4951,7 +4987,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4966,7 +5002,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4981,7 +5017,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4996,7 +5032,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5011,7 +5047,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5026,7 +5062,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5041,7 +5077,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5056,7 +5092,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5073,7 +5109,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCO _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5089,7 +5125,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5105,7 +5141,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5121,7 +5157,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAN opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5137,7 +5173,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_O opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5152,7 +5188,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5167,7 +5203,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5182,7 +5218,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5197,7 +5233,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5257,10 +5293,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, */ if (IS_CONST == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -5374,22 +5408,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CONST != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { zval *container = opline->op1.zv; zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -5480,7 +5510,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } if (IS_VAR != IS_CONST) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -5501,7 +5531,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -5525,14 +5555,11 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op2; SAVE_OPLINE(); - if (IS_CONST==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5568,7 +5595,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -5593,11 +5621,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -5610,14 +5634,12 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC /* do nothing */ break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5872,7 +5894,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -5885,11 +5907,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -5928,7 +5952,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -6009,10 +6033,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ */ if (IS_CONST == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -6223,7 +6245,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -6272,7 +6294,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -6297,11 +6320,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -6320,8 +6339,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ } if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6594,7 +6611,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -6607,11 +6624,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -6959,12 +6978,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CONST != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { zval *container = opline->op1.zv; zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); @@ -6974,7 +6987,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -7086,7 +7101,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -7170,9 +7185,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); - if (IS_CONST==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); @@ -7212,7 +7224,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CONST == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -7237,11 +7250,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -7260,8 +7269,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO } if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -7353,7 +7360,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -7366,11 +7373,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CONST == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -7667,9 +7676,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { - if (IS_TMP_VAR == IS_TMP_VAR) { - zval_dtor(free_op1.var); - } + zval_dtor(free_op1.var); } else { if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR || @@ -7682,18 +7689,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; + } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; + if (IS_TMP_VAR == IS_VAR) { + Z_DELREF_P(retval_ptr); + } ALLOC_INIT_ZVAL(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; - Z_ADDREF_P(retval_ptr); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(retval_ptr); + } } } - return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -8157,19 +8169,27 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { - Z_ADDREF_P(array_ptr); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(array_ptr); + } } } else if (IS_TMP_VAR == IS_CONST || - ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && + (IS_TMP_VAR == IS_CV && !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1)) { + Z_REFCOUNT_P(array_ptr) > 1) || + (IS_TMP_VAR == IS_VAR && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 2)) { zval *tmp; + if (IS_TMP_VAR == IS_VAR) { + Z_DELREF_P(array_ptr); + } ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); zval_copy_ctor(tmp); array_ptr = tmp; - } else { + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(array_ptr); } } @@ -8177,10 +8197,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); + if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { + + } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { + if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -8197,14 +8222,18 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -8234,6 +8263,9 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG is_empty = 1; } + if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + + } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -8751,10 +8783,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, */ if (IS_TMP_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -8868,12 +8898,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_TMP_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); @@ -8883,7 +8907,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -9045,9 +9071,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op1; SAVE_OPLINE(); - if (IS_TMP_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); @@ -9087,7 +9110,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -9112,11 +9136,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -9135,8 +9155,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC } if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -9391,7 +9409,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -9404,11 +9422,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -9756,12 +9776,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_TMP_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); @@ -9771,7 +9785,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); + if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -9909,9 +9925,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1, free_op2; SAVE_OPLINE(); - if (IS_TMP_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); @@ -9952,7 +9965,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -9977,11 +9991,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -10000,8 +10010,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD } if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10093,7 +10101,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -10106,11 +10114,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -10184,7 +10194,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10199,7 +10209,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10214,7 +10224,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10229,7 +10239,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10244,7 +10254,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10259,7 +10269,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10274,7 +10284,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10289,7 +10299,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10304,7 +10314,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10321,7 +10331,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10337,7 +10347,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10353,7 +10363,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10369,7 +10379,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10385,7 +10395,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPC _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10400,7 +10410,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10415,7 +10425,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10430,7 +10440,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10445,7 +10455,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10505,10 +10515,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE */ if (IS_TMP_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -10622,22 +10630,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_TMP_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); zval_dtor(free_op1.var); } else { container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -10683,7 +10687,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10741,7 +10745,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE } } else { if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -10763,7 +10767,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE call->is_ctor_call = 0; EX(call) = call; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10775,14 +10779,11 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1, free_op2; SAVE_OPLINE(); - if (IS_TMP_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10818,7 +10819,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -10843,11 +10845,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -10860,14 +10858,12 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD /* do nothing */ break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -11122,7 +11118,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -11135,11 +11131,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -11178,7 +11176,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -11259,10 +11257,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, */ if (IS_TMP_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -11399,7 +11395,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -11424,11 +11421,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -11447,8 +11440,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP } if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -11703,7 +11694,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -11716,11 +11707,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -12068,12 +12061,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_TMP_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); @@ -12083,7 +12070,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL container = NULL; zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -12219,9 +12208,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_free_op free_op1; SAVE_OPLINE(); - if (IS_TMP_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); @@ -12261,7 +12247,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_TMP_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -12286,11 +12273,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -12309,8 +12292,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE } if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -12402,7 +12383,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -12415,11 +12396,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_TMP_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -12491,7 +12474,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); bitwise_not_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12504,7 +12487,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); boolean_not_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12526,7 +12509,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12551,7 +12534,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12573,7 +12556,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12598,7 +12581,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12617,7 +12600,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { ZVAL_NULL(&EX_T(opline->result.var).tmp_var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12641,7 +12624,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG fast_increment_function(*var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12660,7 +12643,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { ZVAL_NULL(&EX_T(opline->result.var).tmp_var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12684,7 +12667,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG fast_decrement_function(*var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12703,7 +12686,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } zend_print_variable(z); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12730,7 +12713,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ret = Z_LVAL_P(val); } else { ret = i_zend_is_true(val); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12760,7 +12743,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ret = Z_LVAL_P(val); } else { ret = i_zend_is_true(val); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12790,7 +12773,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval = Z_LVAL_P(val); } else { retval = i_zend_is_true(val); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12824,7 +12807,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS retval = Z_LVAL_P(val); } else { retval = i_zend_is_true(val); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12855,7 +12838,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG retval = Z_LVAL_P(val); } else { retval = i_zend_is_true(val); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12896,9 +12879,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { - if (IS_VAR == IS_TMP_VAR) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR || @@ -12911,18 +12892,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; + zval_ptr_dtor_nogc(&free_op1.var); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; + if (IS_VAR == IS_VAR) { + Z_DELREF_P(retval_ptr); + } ALLOC_INIT_ZVAL(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; - Z_ADDREF_P(retval_ptr); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(retval_ptr); + } } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -12943,7 +12929,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { if (IS_VAR == IS_TMP_VAR) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } } else if (!0) { /* Not a temp var */ zval *ret; @@ -12993,7 +12979,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } } while (0); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -13024,7 +13010,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_throw_exception_object(exception TSRMLS_CC); zend_exception_restore(TSRMLS_C); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } @@ -13036,21 +13022,26 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (varptr == &EG(uninitialized_zval)) { - ALLOC_ZVAL(varptr); - INIT_ZVAL(*varptr); - Z_SET_REFCOUNT_P(varptr, 0); + if (IS_VAR == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); } else if (PZVAL_IS_REF(varptr)) { - zval *original_var = varptr; + if (IS_VAR == IS_CV || + (IS_VAR == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; - ALLOC_ZVAL(varptr); - ZVAL_COPY_VALUE(varptr, original_var); - Z_UNSET_ISREF_P(varptr); - Z_SET_REFCOUNT_P(varptr, 0); - zval_copy_ctor(varptr); + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); + zval_ptr_dtor_nogc(&free_op1.var); + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); } - Z_ADDREF_P(varptr); zend_vm_stack_push(varptr TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; /* for string offsets */ CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13071,22 +13062,15 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - if (IS_VAR == IS_VAR && - (opline->extended_value & ZEND_ARG_SEND_FUNCTION) && - EX_T(opline->op1.var).var.fcall_returned_reference && - EX_T(opline->op1.var).var.ptr) { - varptr = EX_T(opline->op1.var).var.ptr; - PZVAL_UNLOCK_EX(varptr, &free_op1, 0); - } else { - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - } + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || EX_T(opline->op1.var).var.fcall_returned_reference) && varptr != &EG(uninitialized_zval) && - (PZVAL_IS_REF(varptr) || - (Z_REFCOUNT_P(varptr) == 1 && (IS_VAR == IS_CV || free_op1.var)))) { + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { Z_SET_ISREF_P(varptr); - Z_ADDREF_P(varptr); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(varptr); + } zend_vm_stack_push(varptr TSRMLS_CC); } else { zval *valptr; @@ -13101,9 +13085,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if (!0) { zval_copy_ctor(valptr); } + zval_ptr_dtor_nogc(&free_op1.var); zend_vm_stack_push(valptr TSRMLS_CC); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13140,7 +13124,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF_P(varptr); zend_vm_stack_push(varptr TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13166,7 +13150,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC))); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13243,7 +13227,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) AI_SET_PTR(&EX_T(opline->result.var), retval); } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13285,7 +13269,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (use_copy) { ZVAL_COPY_VALUE(result, &var_copy); if (0) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } } else { ZVAL_COPY_VALUE(result, expr); @@ -13302,7 +13286,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) convert_to_object(result); break; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13391,7 +13375,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if (tmp_inc_filename) { zval_ptr_dtor(&tmp_inc_filename); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } else if (EXPECTED(new_op_array != NULL)) { @@ -13498,19 +13482,27 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { - Z_ADDREF_P(array_ptr); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(array_ptr); + } } } else if (IS_VAR == IS_CONST || - ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && + (IS_VAR == IS_CV && !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1)) { + Z_REFCOUNT_P(array_ptr) > 1) || + (IS_VAR == IS_VAR && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 2)) { zval *tmp; + if (IS_VAR == IS_VAR) { + Z_DELREF_P(array_ptr); + } ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); zval_copy_ctor(tmp); array_ptr = tmp; - } else { + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(array_ptr); } } @@ -13518,10 +13510,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); + if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { + zval_ptr_dtor_nogc(&free_op1.var); + } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -13538,14 +13535,18 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -13575,7 +13576,9 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG is_empty = 1; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -13730,7 +13733,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { zend_print_variable(ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } #endif zend_bailout(); @@ -13751,14 +13754,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (!0) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.opline_num); #endif ZEND_VM_JMP(opline->op2.jmp_addr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13786,14 +13789,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ zval_copy_ctor(EX_T(opline->result.var).var.ptr); } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.opline_num); #endif ZEND_VM_JMP(opline->op2.jmp_addr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13811,7 +13814,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR if (!0) { zval_copy_ctor(&EX_T(opline->result.var).tmp_var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13839,7 +13842,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13860,7 +13863,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A result = 0; } ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, result); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13874,7 +13877,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13889,7 +13892,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13904,7 +13907,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13919,7 +13922,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13934,7 +13937,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13949,7 +13952,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13964,7 +13967,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13979,7 +13982,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13994,7 +13997,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14011,7 +14014,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14027,7 +14030,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14043,7 +14046,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14059,7 +14062,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14075,7 +14078,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_O ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14090,7 +14093,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14105,7 +14108,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14120,7 +14123,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14135,7 +14138,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14246,7 +14249,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -14301,7 +14304,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -14332,11 +14335,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -14426,7 +14429,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14486,7 +14489,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14527,7 +14530,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14588,7 +14591,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14637,7 +14640,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14647,7 +14650,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -14658,10 +14661,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, */ if (IS_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -14686,11 +14687,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -14775,22 +14776,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); + } } CHECK_EXCEPTION(); @@ -14814,7 +14811,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -14848,7 +14845,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14860,10 +14857,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval **container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14885,15 +14882,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14920,7 +14919,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -14977,7 +14976,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST( } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15014,7 +15013,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -15057,7 +15056,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15099,7 +15098,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15133,7 +15132,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -15172,7 +15171,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -15207,7 +15206,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -15287,7 +15286,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -15341,7 +15340,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -15423,7 +15422,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO call->is_ctor_call = 0; EX(call) = call; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15534,7 +15533,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -15558,9 +15557,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op1; SAVE_OPLINE(); - if (IS_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); @@ -15697,7 +15693,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + zval_ptr_dtor_nogc(&free_op1.var); + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -15722,11 +15719,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -15744,9 +15737,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15815,7 +15806,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -15839,7 +15830,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15883,11 +15874,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -15938,7 +15925,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15979,7 +15966,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16049,7 +16036,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -16082,7 +16069,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = opline->op2.zv; if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -16109,11 +16095,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -16206,7 +16188,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16288,14 +16270,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -16308,12 +16290,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + zval_ptr_dtor_nogc(&free_op1.var); } else { - Z_ADDREF_P(value); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } } else { /* If no value was specified yield null */ @@ -16386,7 +16369,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16401,7 +16384,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16416,7 +16399,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16431,7 +16414,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16446,7 +16429,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16461,7 +16444,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16476,7 +16459,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16491,7 +16474,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16506,7 +16489,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16523,7 +16506,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16539,7 +16522,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16555,7 +16538,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16571,7 +16554,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16587,7 +16570,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPC ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16602,7 +16585,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16617,7 +16600,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16632,7 +16615,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16647,7 +16630,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16758,7 +16741,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -16813,7 +16796,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -16845,11 +16828,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -16939,7 +16922,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16999,7 +16982,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17040,7 +17023,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_dtor(free_op2.var); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17101,7 +17084,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17124,22 +17107,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); + } } CHECK_EXCEPTION(); @@ -17163,7 +17142,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -17197,7 +17176,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17209,10 +17188,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval **container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC); zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17234,15 +17213,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + zval_dtor(free_op2.var); + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); } - zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17269,7 +17250,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -17326,7 +17307,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17363,7 +17344,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -17406,7 +17387,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17448,7 +17429,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17482,7 +17463,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -17521,7 +17502,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -17556,7 +17537,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -17637,7 +17618,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -17691,7 +17672,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -17774,7 +17755,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE EX(call) = call; zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17885,7 +17866,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -17909,9 +17890,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1, free_op2; SAVE_OPLINE(); - if (IS_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); @@ -17952,7 +17930,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + zval_ptr_dtor_nogc(&free_op1.var); + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -17977,11 +17956,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -17999,9 +17974,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18060,11 +18033,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -18115,7 +18084,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18156,7 +18125,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18174,7 +18143,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -18201,11 +18169,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -18298,7 +18262,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18380,14 +18344,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -18400,12 +18364,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; + zval_ptr_dtor_nogc(&free_op1.var); } else { - Z_ADDREF_P(value); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } } else { /* If no value was specified yield null */ @@ -18478,8 +18443,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18493,8 +18458,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18508,8 +18473,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18523,8 +18488,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18538,8 +18503,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18553,8 +18518,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18568,8 +18533,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18583,8 +18548,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18598,8 +18563,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18615,8 +18580,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18631,8 +18596,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18647,8 +18612,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18663,8 +18628,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18679,8 +18644,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPC ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18694,8 +18659,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18709,8 +18674,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18724,8 +18689,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18739,8 +18704,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18764,7 +18729,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -18845,12 +18810,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -18904,8 +18869,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -18932,16 +18897,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ PZVAL_LOCK(*var_ptr); AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -19026,12 +18991,12 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19089,9 +19054,9 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19130,9 +19095,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19191,9 +19156,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19242,7 +19207,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19252,7 +19217,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -19263,10 +19228,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE */ if (IS_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -19291,11 +19254,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -19380,22 +19343,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); + } } CHECK_EXCEPTION(); @@ -19415,11 +19374,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -19449,11 +19408,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19465,10 +19424,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval **container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19490,15 +19449,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + zval_ptr_dtor_nogc(&free_op2.var); + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19521,11 +19482,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -19561,7 +19522,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -19578,11 +19539,11 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19614,12 +19575,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -19657,12 +19618,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19683,7 +19644,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -19700,11 +19661,11 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19733,12 +19694,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -19772,12 +19733,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -19810,9 +19771,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property_name); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -19842,7 +19803,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property_name); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -19851,7 +19812,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval **variable_ptr_ptr; zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); @@ -19893,7 +19854,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -19947,10 +19908,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -19976,7 +19937,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -20003,8 +19964,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20062,7 +20023,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE } } else { if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -20084,8 +20045,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE call->is_ctor_call = 0; EX(call) = call; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20175,7 +20136,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } if (IS_VAR != IS_CONST) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -20196,7 +20157,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -20220,14 +20181,11 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1, free_op2; SAVE_OPLINE(); - if (IS_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20263,7 +20221,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + zval_ptr_dtor_nogc(&free_op1.var); + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -20288,11 +20247,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -20305,14 +20260,12 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD /* do nothing */ break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20381,7 +20334,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -20405,7 +20358,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20449,11 +20402,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -20477,7 +20426,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_error(E_WARNING, "Illegal offset type in unset"); break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -20491,20 +20440,20 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20537,15 +20486,15 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20615,7 +20564,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -20648,7 +20597,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -20675,11 +20623,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -20708,7 +20652,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in result = 1; } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); @@ -20731,7 +20675,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; @@ -20760,9 +20704,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in } } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -20772,7 +20716,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20854,14 +20798,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -20874,12 +20818,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; + zval_ptr_dtor_nogc(&free_op1.var); } else { - Z_ADDREF_P(value); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } } else { /* If no value was specified yield null */ @@ -20918,7 +20863,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -21049,7 +20994,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -21104,7 +21049,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -21135,11 +21080,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -21234,7 +21179,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21244,7 +21189,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -21255,10 +21200,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, */ if (IS_VAR == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -21283,11 +21226,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -21381,7 +21324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -21415,7 +21358,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21437,15 +21380,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC); - } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21523,7 +21468,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -21635,7 +21580,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -21684,7 +21629,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + zval_ptr_dtor_nogc(&free_op1.var); + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -21709,11 +21655,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -21731,9 +21673,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -21802,7 +21742,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -21826,7 +21766,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21895,7 +21835,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -22003,14 +21943,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -22023,12 +21963,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } generator->value = copy; + zval_ptr_dtor_nogc(&free_op1.var); } else { - Z_ADDREF_P(value); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } } else { /* If no value was specified yield null */ @@ -22101,7 +22042,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22116,7 +22057,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22131,7 +22072,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22146,7 +22087,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22161,7 +22102,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22176,7 +22117,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22191,7 +22132,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22206,7 +22147,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22221,7 +22162,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22238,7 +22179,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22254,7 +22195,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22270,7 +22211,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22286,7 +22227,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22302,7 +22243,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCO ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22317,7 +22258,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22332,7 +22273,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22347,7 +22288,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22362,7 +22303,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22473,7 +22414,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -22528,7 +22469,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -22559,11 +22500,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -22653,7 +22594,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22713,7 +22654,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22754,7 +22695,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22815,7 +22756,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22838,22 +22779,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_VAR != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); } else { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); + } } CHECK_EXCEPTION(); @@ -22877,7 +22814,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -22911,7 +22848,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22923,10 +22860,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval **container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22948,15 +22885,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22983,7 +22922,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -23040,7 +22979,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23077,7 +23016,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -23120,7 +23059,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23162,7 +23101,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23196,7 +23135,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -23235,7 +23174,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -23270,7 +23209,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -23350,7 +23289,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -23404,7 +23343,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -23459,7 +23398,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23539,7 +23478,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ call->is_ctor_call = 0; EX(call) = call; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23650,7 +23589,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ /* We are calling method of the other (incompatible) class, but passing $this. This is done for compatibility with php-4. */ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); + zend_error(E_DEPRECATED, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name); @@ -23674,9 +23613,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_free_op free_op1; SAVE_OPLINE(); - if (IS_VAR==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); @@ -23716,7 +23652,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + zval_ptr_dtor_nogc(&free_op1.var); + } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -23741,11 +23678,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -23763,9 +23696,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23824,11 +23755,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -23879,7 +23806,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23920,7 +23847,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23938,7 +23865,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -23965,11 +23891,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -24062,7 +23984,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -24144,14 +24066,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -24164,12 +24086,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } generator->value = copy; + zval_ptr_dtor_nogc(&free_op1.var); } else { - Z_ADDREF_P(value); + if (IS_VAR == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } } else { /* If no value was specified yield null */ @@ -25328,11 +25251,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -25440,7 +25359,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - offset = opline->op2.zv; if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -25467,11 +25385,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -25650,7 +25564,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL /* Consts, temporary variables and references need copying */ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -25663,11 +25577,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_UNUSED == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -26642,11 +26558,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -26754,7 +26666,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -26781,11 +26692,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -26964,7 +26871,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER /* Consts, temporary variables and references need copying */ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -26977,11 +26884,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_UNUSED == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -27064,7 +26973,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -27145,7 +27054,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } @@ -27203,7 +27112,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -27231,7 +27140,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina PZVAL_LOCK(*var_ptr); AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); @@ -27325,7 +27234,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); @@ -27388,7 +27297,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27429,7 +27338,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -27490,7 +27399,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27524,7 +27433,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -27541,7 +27450,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -27576,7 +27485,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27618,7 +27527,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27644,7 +27553,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -27661,7 +27570,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -27693,7 +27602,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27732,7 +27641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27769,7 +27678,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA if (0) { zval_ptr_dtor(&property_name); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } /* assign_obj has two opcodes! */ @@ -27817,7 +27726,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -27875,7 +27784,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC } } else { if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -27897,7 +27806,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC call->is_ctor_call = 0; EX(call) = call; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -27956,11 +27865,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -27984,7 +27889,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN zend_error(E_WARNING, "Illegal offset type in unset"); break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -27998,18 +27903,18 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -28043,13 +27948,13 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -28068,7 +27973,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -28095,11 +27999,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -28128,7 +28028,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR result = 1; } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); @@ -28151,7 +28051,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; @@ -28180,9 +28080,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR } } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -28278,7 +28178,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER /* Consts, temporary variables and references need copying */ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -28291,11 +28191,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_UNUSED == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -28334,7 +28236,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -28701,7 +28603,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND /* Consts, temporary variables and references need copying */ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -28714,11 +28616,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_UNUSED == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -29690,11 +29594,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -29802,7 +29702,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -29829,11 +29728,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -30012,7 +29907,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ /* Consts, temporary variables and references need copying */ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -30025,11 +29920,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_UNUSED == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -30487,9 +30384,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { - if (IS_CV == IS_TMP_VAR) { - } } else { if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR || @@ -30502,18 +30397,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; + } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; + if (IS_CV == IS_VAR) { + Z_DELREF_P(retval_ptr); + } ALLOC_INIT_ZVAL(ret); *EG(return_value_ptr_ptr) = ret; } else { *EG(return_value_ptr_ptr) = retval_ptr; - Z_ADDREF_P(retval_ptr); + if (IS_CV == IS_CV) { + Z_ADDREF_P(retval_ptr); + } } } - return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -30626,21 +30526,26 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (varptr == &EG(uninitialized_zval)) { - ALLOC_ZVAL(varptr); - INIT_ZVAL(*varptr); - Z_SET_REFCOUNT_P(varptr, 0); + if (IS_CV == IS_VAR) { + Z_DELREF_P(varptr); + } + ALLOC_INIT_ZVAL(varptr); } else if (PZVAL_IS_REF(varptr)) { - zval *original_var = varptr; + if (IS_CV == IS_CV || + (IS_CV == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { + zval *original_var = varptr; + + ALLOC_ZVAL(varptr); + INIT_PZVAL_COPY(varptr, original_var); + zval_copy_ctor(varptr); - ALLOC_ZVAL(varptr); - ZVAL_COPY_VALUE(varptr, original_var); - Z_UNSET_ISREF_P(varptr); - Z_SET_REFCOUNT_P(varptr, 0); - zval_copy_ctor(varptr); + } else { + Z_UNSET_ISREF_P(varptr); + } + } else if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); } - Z_ADDREF_P(varptr); zend_vm_stack_push(varptr TSRMLS_CC); - ; /* for string offsets */ CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30649,7 +30554,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zval *varptr; SAVE_OPLINE(); @@ -30661,22 +30566,15 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - if (IS_CV == IS_VAR && - (opline->extended_value & ZEND_ARG_SEND_FUNCTION) && - EX_T(opline->op1.var).var.fcall_returned_reference && - EX_T(opline->op1.var).var.ptr) { - varptr = EX_T(opline->op1.var).var.ptr; - PZVAL_UNLOCK_EX(varptr, &free_op1, 0); - } else { - varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - } + varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || EX_T(opline->op1.var).var.fcall_returned_reference) && varptr != &EG(uninitialized_zval) && - (PZVAL_IS_REF(varptr) || - (Z_REFCOUNT_P(varptr) == 1 && (IS_CV == IS_CV || free_op1.var)))) { + (PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { Z_SET_ISREF_P(varptr); - Z_ADDREF_P(varptr); + if (IS_CV == IS_CV) { + Z_ADDREF_P(varptr); + } zend_vm_stack_push(varptr TSRMLS_CC); } else { zval *valptr; @@ -30691,9 +30589,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL if (!0) { zval_copy_ctor(valptr); } + zend_vm_stack_push(valptr TSRMLS_CC); } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -31076,19 +30974,27 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { - Z_ADDREF_P(array_ptr); + if (IS_CV == IS_CV) { + Z_ADDREF_P(array_ptr); + } } } else if (IS_CV == IS_CONST || - ((IS_CV == IS_CV || IS_CV == IS_VAR) && + (IS_CV == IS_CV && !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1)) { + Z_REFCOUNT_P(array_ptr) > 1) || + (IS_CV == IS_VAR && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 2)) { zval *tmp; + if (IS_CV == IS_VAR) { + Z_DELREF_P(array_ptr); + } ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); zval_copy_ctor(tmp); array_ptr = tmp; - } else { + } else if (IS_CV == IS_CV) { Z_ADDREF_P(array_ptr); } } @@ -31096,10 +31002,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); + if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { + + } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { + if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); } @@ -31116,14 +31027,18 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS iter->funcs->rewind(iter TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } } is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); + if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } HANDLE_EXCEPTION(); } iter->index = -1; /* will be set to 0 before using next handler */ @@ -31153,6 +31068,9 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS is_empty = 1; } + if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + + } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); } else { @@ -32100,10 +32018,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z */ if (IS_CV == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -32217,12 +32133,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CV != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); @@ -32232,7 +32142,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -32326,15 +32238,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + } else { if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - } + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -32869,9 +32783,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); - if (IS_CV==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), opline->op2.zv TSRMLS_CC); @@ -32911,7 +32822,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CV == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -32936,11 +32848,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -32959,8 +32867,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO } if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -33097,11 +33003,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -33294,7 +33196,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = opline->op2.zv; if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -33321,11 +33222,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -33504,7 +33401,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A /* Consts, temporary variables and references need copying */ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -33517,11 +33414,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CV == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -34331,12 +34230,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CV != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); @@ -34346,7 +34239,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); + if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -34440,15 +34335,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + zval_dtor(free_op2.var); + } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - } - zval_dtor(free_op2.var); + zval_dtor(free_op2.var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -34985,9 +34882,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_free_op free_op2; SAVE_OPLINE(); - if (IS_CV==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); @@ -35028,7 +34922,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CV == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -35053,11 +34948,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -35076,8 +34967,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE } if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -35136,11 +35025,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -35248,7 +35133,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -35275,11 +35159,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -35458,7 +35338,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Consts, temporary variables and references need copying */ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -35471,11 +35351,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CV == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -35549,7 +35431,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35564,7 +35446,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35579,7 +35461,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35594,7 +35476,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35609,7 +35491,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35624,7 +35506,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35639,7 +35521,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35654,7 +35536,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35669,7 +35551,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35686,7 +35568,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35702,7 +35584,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35718,7 +35600,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35734,7 +35616,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35750,7 +35632,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCO _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35765,7 +35647,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35780,7 +35662,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35795,7 +35677,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35810,7 +35692,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35834,7 +35716,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -35915,7 +35797,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } @@ -35973,7 +35855,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -36001,7 +35883,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o PZVAL_LOCK(*var_ptr); AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); @@ -36095,7 +35977,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); @@ -36158,7 +36040,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -36199,7 +36081,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -36260,7 +36142,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -36332,10 +36214,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN */ if (IS_CV == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -36449,22 +36329,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CV != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -36484,7 +36360,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36517,7 +36393,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36535,7 +36411,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -36558,15 +36434,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + zval_ptr_dtor_nogc(&free_op2.var); + } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36589,7 +36467,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36629,7 +36507,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -36646,7 +36524,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -36681,7 +36559,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36723,7 +36601,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36749,7 +36627,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -36766,7 +36644,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -36798,7 +36676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36837,7 +36715,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H if (0) { zval_ptr_dtor(&property); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36874,7 +36752,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&property_name); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } /* assign_obj has two opcodes! */ @@ -36906,7 +36784,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&property_name); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -36915,7 +36793,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE zval **variable_ptr_ptr; zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); @@ -37012,7 +36890,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } /* zend_assign_to_variable() always takes care of op2, never free it! */ - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37038,7 +36916,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -37065,7 +36943,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37123,7 +37001,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ } } else { if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -37145,7 +37023,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ call->is_ctor_call = 0; EX(call) = call; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37157,14 +37035,11 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_free_op free_op2; SAVE_OPLINE(); - if (IS_CV==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -37200,7 +37075,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CV == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -37225,11 +37101,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -37242,14 +37114,12 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE /* do nothing */ break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37386,11 +37256,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -37414,7 +37280,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_WARNING, "Illegal offset type in unset"); break; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -37428,18 +37294,18 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -37473,13 +37339,13 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -37583,7 +37449,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -37610,11 +37475,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -37643,7 +37504,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int result = 1; } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); @@ -37666,7 +37527,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int if (0) { zval_ptr_dtor(&offset); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; @@ -37695,9 +37556,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int } } } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -37793,7 +37654,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Consts, temporary variables and references need copying */ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -37806,11 +37667,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CV == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -37849,7 +37712,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -38185,10 +38048,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, */ if (IS_CV == IS_CONST) { hash_value = Z_HASH_P(varname); - } else if (IS_INTERNED(Z_STRVAL_P(varname))) { - hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); } else { - hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); + hash_value = str_hash(Z_STRVAL_P(varname), Z_STRLEN_P(varname)); } if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { @@ -38366,15 +38227,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + } else { if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC); - } + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38490,7 +38353,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CV == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -38515,11 +38379,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -38538,8 +38398,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC } if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -38794,7 +38652,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ /* Consts, temporary variables and references need copying */ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -38807,11 +38665,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CV == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -39620,12 +39480,6 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && - IS_CV != IS_CV && - EX_T(opline->op1.var).var.ptr_ptr) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - } - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); @@ -39635,7 +39489,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + } } CHECK_EXCEPTION(); @@ -39729,15 +39585,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } + + } else { if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - } + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -40324,9 +40182,6 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); - if (IS_CV==IS_VAR) { - PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); - } is_equal_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); @@ -40366,7 +40221,8 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - } else { + + } else if (IS_CV == IS_CV) { Z_ADDREF_P(expr_ptr); } } @@ -40391,11 +40247,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); break; @@ -40414,8 +40266,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ } if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) { - } else { - } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -40474,11 +40324,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_dim); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (ht == &EG(symbol_table)) { zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); @@ -40586,7 +40432,6 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { @@ -40613,11 +40458,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int hval = Z_HASH_P(offset); } else { ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - if (IS_INTERNED(Z_STRVAL_P(offset))) { - hval = INTERNED_HASH(Z_STRVAL_P(offset)); - } else { - hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - } + hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { isset = 1; @@ -40796,7 +40637,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS /* Consts, temporary variables and references need copying */ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR - || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) + || PZVAL_IS_REF(value) ) { zval *copy; @@ -40809,11 +40650,13 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } generator->value = copy; + } else { - Z_ADDREF_P(value); + if (IS_CV == IS_CV) { + Z_ADDREF_P(value); + } generator->value = value; } - } } else { /* If no value was specified yield null */ @@ -44987,6 +44830,31 @@ void zend_init_opcodes_handlers(void) ZEND_FAST_RET_SPEC_HANDLER, ZEND_FAST_RET_SPEC_HANDLER, ZEND_FAST_RET_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 9b2877b9968f9..a0546460d0e44 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -143,6 +143,8 @@ "UNUSED" => "NULL", "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", ); +$op1_get_zval_ptr_ptr_fast = $op1_get_zval_ptr_ptr; +$op1_get_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)"; $op2_get_zval_ptr_ptr = array( "ANY" => "get_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", @@ -152,6 +154,8 @@ "UNUSED" => "NULL", "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); +$op2_get_zval_ptr_ptr_fast = $op2_get_zval_ptr_ptr; +$op2_get_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)"; $op1_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", @@ -179,6 +183,8 @@ "UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)", "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", ); +$op1_get_obj_zval_ptr_ptr_fast = $op1_get_obj_zval_ptr_ptr; +$op1_get_obj_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)"; $op2_get_obj_zval_ptr_ptr = array( "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", @@ -188,6 +194,8 @@ "UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)", "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); +$op2_get_obj_zval_ptr_ptr_fast = $op2_get_obj_zval_ptr_ptr; +$op2_get_obj_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)"; $op1_is_tmp_free = array( "ANY" => "IS_TMP_FREE(free_op1)", @@ -210,7 +218,7 @@ $op1_free_op = array( "ANY" => "FREE_OP(free_op1)", "TMP" => "zval_dtor(free_op1.var)", - "VAR" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "VAR" => "zval_ptr_dtor_nogc(&free_op1.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -219,7 +227,7 @@ $op2_free_op = array( "ANY" => "FREE_OP(free_op2)", "TMP" => "zval_dtor(free_op2.var)", - "VAR" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "VAR" => "zval_ptr_dtor_nogc(&free_op2.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -228,7 +236,7 @@ $op1_free_op_if_var = array( "ANY" => "FREE_OP_IF_VAR(free_op1)", "TMP" => "", - "VAR" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "VAR" => "zval_ptr_dtor_nogc(&free_op1.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -237,29 +245,33 @@ $op2_free_op_if_var = array( "ANY" => "FREE_OP_IF_VAR(free_op2)", "TMP" => "", - "VAR" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "VAR" => "zval_ptr_dtor_nogc(&free_op2.var)", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op1_free_op_var_ptr = array( - "ANY" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "ANY" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}", "TMP" => "", - "VAR" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "VAR" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}", "CONST" => "", "UNUSED" => "", "CV" => "", ); +$op1_free_op_var_ptr_fast = $op1_free_op_var_ptr; +$op1_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op1.var)"; $op2_free_op_var_ptr = array( - "ANY" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "ANY" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}", "TMP" => "", - "VAR" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "VAR" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}", "CONST" => "", "UNUSED" => "", "CV" => "", ); +$op2_free_op_var_ptr_fast = $op2_free_op_var_ptr; +$op2_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op2.var)"; $list = array(); // list of opcode handlers and helpers in original order $opcodes = array(); // opcode handlers by code @@ -311,7 +323,10 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr, $op1_is_tmp_free, $op2_is_tmp_free, $op1_free, $op2_free, $op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var, - $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix; + $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix, + $op1_get_zval_ptr_ptr_fast, $op2_get_zval_ptr_ptr_fast, + $op1_get_obj_zval_ptr_ptr_fast, $op2_get_obj_zval_ptr_ptr_fast, + $op1_free_op_var_ptr_fast, $op2_free_op_var_ptr_fast; // Specializing $code = preg_replace( @@ -336,6 +351,12 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { "/FREE_OP2_IF_VAR\(\)/", "/FREE_OP1_VAR_PTR\(\)/", "/FREE_OP2_VAR_PTR\(\)/", + "/GET_OP1_ZVAL_PTR_PTR_FAST\(([^)]*)\)/", + "/GET_OP2_ZVAL_PTR_PTR_FAST\(([^)]*)\)/", + "/GET_OP1_OBJ_ZVAL_PTR_PTR_FAST\(([^)]*)\)/", + "/GET_OP2_OBJ_ZVAL_PTR_PTR_FAST\(([^)]*)\)/", + "/FREE_OP1_VAR_PTR_FAST\(\)/", + "/FREE_OP2_VAR_PTR_FAST\(\)/", "/^#ifdef\s+ZEND_VM_SPEC\s*\n/m", "/^#ifndef\s+ZEND_VM_SPEC\s*\n/m", "/\!defined\(ZEND_VM_SPEC\)/m", @@ -368,6 +389,12 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $op2_free_op_if_var[$op2], $op1_free_op_var_ptr[$op1], $op2_free_op_var_ptr[$op2], + $op1_get_zval_ptr_ptr_fast[$op1], + $op2_get_zval_ptr_ptr_fast[$op2], + $op1_get_obj_zval_ptr_ptr_fast[$op1], + $op2_get_obj_zval_ptr_ptr_fast[$op2], + $op1_free_op_var_ptr_fast[$op1], + $op2_free_op_var_ptr_fast[$op2], ($op1!="ANY"||$op2!="ANY")?"#if 1\n":"#if 0\n", ($op1!="ANY"||$op2!="ANY")?"#if 0\n":"#if 1\n", ($op1!="ANY"||$op2!="ANY")?"0":"1", diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 859258a440bef..7624ec192d7e6 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -164,3 +164,4 @@ #define ZEND_GENERATOR_RETURN 161 #define ZEND_FAST_CALL 162 #define ZEND_FAST_RET 163 +#define ZEND_RECV_VARIADIC 164 diff --git a/acinclude.m4 b/acinclude.m4 index 3284978804fa4..c25e59eef08d7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2686,14 +2686,14 @@ EOF fi for arg in $ac_configure_args; do if test `expr -- $arg : "'.*"` = 0; then - if test `expr -- $arg : "--.*"` = 0; then - break; + if test `expr -- $arg : "-.*"` = 0 && test `expr -- $arg : ".*=.*"` = 0; then + continue; fi echo "'[$]arg' \\" >> $1 CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS '[$]arg'" else - if test `expr -- $arg : "'--.*"` = 0; then - break; + if test `expr -- $arg : "'-.*"` = 0 && test `expr -- $arg : "'.*=.*"` = 0; then + continue; fi echo "[$]arg \\" >> $1 CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS [$]arg" @@ -3012,3 +3012,22 @@ EOF ;; esac ]) + +dnl +dnl PHP_CHECK_STDINT_TYPES +dnl +AC_DEFUN([PHP_CHECK_STDINT_TYPES], [ + AC_CHECK_SIZEOF([short], 2) + AC_CHECK_SIZEOF([int], 4) + AC_CHECK_SIZEOF([long], 4) + AC_CHECK_SIZEOF([long long], 8) + AC_CHECK_TYPES([int8, int16, int32, int64, int8_t, int16_t, int32_t, int64_t, uint8, uint16, uint32, uint64, uint8_t, uint16_t, uint32_t, uint64_t, u_int8_t, u_int16_t, u_int32_t, u_int64_t], [], [], [ +#if HAVE_STDINT_H +# include +#endif +#if HAVE_SYS_TYPES_H +# include +#endif + ]) + AC_DEFINE([PHP_HAVE_STDINT_TYPES], [1], [Checked for stdint types]) +]) diff --git a/configure.in b/configure.in index 7e444b0ac4a03..805aa48f5940f 100644 --- a/configure.in +++ b/configure.in @@ -118,8 +118,8 @@ int zend_sprintf(char *buffer, const char *format, ...); ]) PHP_MAJOR_VERSION=5 -PHP_MINOR_VERSION=5 -PHP_RELEASE_VERSION=6 +PHP_MINOR_VERSION=6 +PHP_RELEASE_VERSION=0 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` @@ -572,6 +572,9 @@ PHP_CHECK_SIZEOF(intmax_t, 0) PHP_CHECK_SIZEOF(ssize_t, 8) PHP_CHECK_SIZEOF(ptrdiff_t, 8) +dnl Check stdint types (must be after header check) +PHP_CHECK_STDINT_TYPES + dnl Check for members of the stat structure AC_STRUCT_ST_BLKSIZE dnl AC_STRUCT_ST_BLOCKS will screw QNX because fileblocks.o does not exists @@ -1437,7 +1440,7 @@ PHP_SUBST(install_binary_targets) PHP_INSTALL_HEADERS([Zend/ TSRM/ include/ main/ main/streams/]) -PHP_ADD_SOURCES(TSRM, TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c) +PHP_ADD_SOURCES(TSRM, TSRM.c tsrm_strtok_r.c) PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c php_sprintf.c \ fopen_wrappers.c alloca.c php_scandir.c \ @@ -1472,7 +1475,8 @@ PHP_ADD_SOURCES(Zend, \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ - zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c) + zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ + zend_virtual_cwd.c) if test -r "$abs_srcdir/Zend/zend_objects.c"; then PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c) diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index abe84fc31605f..4adaa47fa9873 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -192,7 +192,7 @@ php_stream_ops php_stream_bz2io_ops = { /* {{{ Bzip2 stream openers */ PHP_BZ2_API php_stream *_php_stream_bz2open_from_BZFILE(BZFILE *bz, - char *mode, php_stream *innerstream STREAMS_DC TSRMLS_DC) + const char *mode, php_stream *innerstream STREAMS_DC TSRMLS_DC) { struct php_bz2_stream_data_t *self; @@ -205,8 +205,8 @@ PHP_BZ2_API php_stream *_php_stream_bz2open_from_BZFILE(BZFILE *bz, } PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper, - char *path, - char *mode, + const char *path, + const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) diff --git a/ext/bz2/php_bz2.h b/ext/bz2/php_bz2.h index 8b12eca357d99..7bcffc1831e53 100644 --- a/ext/bz2/php_bz2.h +++ b/ext/bz2/php_bz2.h @@ -47,8 +47,8 @@ extern zend_module_entry bz2_module_entry; # define PHP_BZ2_API #endif -PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -PHP_BZ2_API php_stream *_php_stream_bz2open_from_BZFILE(BZFILE *bz, char *mode, php_stream *innerstream STREAMS_DC TSRMLS_DC); +PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +PHP_BZ2_API php_stream *_php_stream_bz2open_from_BZFILE(BZFILE *bz, const char *mode, php_stream *innerstream STREAMS_DC TSRMLS_DC); #define php_stream_bz2open_from_BZFILE(bz, mode, innerstream) _php_stream_bz2open_from_BZFILE((bz), (mode), (innerstream) STREAMS_CC TSRMLS_CC) #define php_stream_bz2open(wrapper, path, mode, options, opened_path) _php_stream_bz2open((wrapper), (path), (mode), (options), (opened_path), NULL STREAMS_CC TSRMLS_CC) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 9fdb57cc4e68f..591315973ce20 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1791,7 +1791,7 @@ static void alloc_curl_handle(php_curl **ch) zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0); zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0); - (*ch)->safe_upload = 0; /* for now, for BC reason we allow unsafe API */ + (*ch)->safe_upload = 1; /* for now, for BC reason we allow unsafe API */ (*ch)->to_free->slist = emalloc(sizeof(HashTable)); zend_hash_init((*ch)->to_free->slist, 4, NULL, curl_free_slist, 0); @@ -2504,6 +2504,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu case CURLOPT_FOLLOWLOCATION: convert_to_long_ex(zvalue); +#if LIBCURL_VERSION_NUM < 0x071304 if (PG(open_basedir) && *PG(open_basedir)) { if (Z_LVAL_PP(zvalue) != 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set"); @@ -2511,6 +2512,7 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu return 1; } } +#endif error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue)); break; diff --git a/ext/curl/tests/bug65646.phpt b/ext/curl/tests/bug65646.phpt new file mode 100644 index 0000000000000..f244f7238fc7d --- /dev/null +++ b/ext/curl/tests/bug65646.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir or safe_mode): open_basedir disabled +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/curl/tests/bug65646_open_basedir_new.phpt b/ext/curl/tests/bug65646_open_basedir_new.phpt new file mode 100644 index 0000000000000..991c4a2b8a562 --- /dev/null +++ b/ext/curl/tests/bug65646_open_basedir_new.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir or safe_mode): open_basedir enabled; curl >= 7.19.4 +--INI-- +open_basedir=. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) + +Warning: curl_setopt(): CURLPROTO_FILE cannot be activated when an open_basedir is set in %s on line %d +bool(false) + +Warning: curl_setopt(): CURLPROTO_FILE cannot be activated when an open_basedir is set in %s on line %d +bool(false) diff --git a/ext/curl/tests/bug65646_open_basedir_old.phpt b/ext/curl/tests/bug65646_open_basedir_old.phpt new file mode 100644 index 0000000000000..cf11d21a200a2 --- /dev/null +++ b/ext/curl/tests/bug65646_open_basedir_old.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir or safe_mode): open_basedir enabled; curl < 7.19.4 +--INI-- +open_basedir=. +--SKIPIF-- +=')) exit("skip curl version is too new"); +?> +--FILE-- + +--EXPECTF-- +Warning: curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set in %s on line %d +bool(false) diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt deleted file mode 100644 index 7a778f36924db..0000000000000 --- a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -CURLOPT_FOLLOWLOCATION case check open_basedir ---CREDITS-- -WHITE new media architects - Dennis ---INI-- -open_basedir = DIRECTORY_SEPARATOR."tmp"; ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Warning: curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set in %s.php on line %d -bool(false) - diff --git a/ext/date/config0.m4 b/ext/date/config0.m4 index f403104a8afbe..0b46c6803a7fd 100644 --- a/ext/date/config0.m4 +++ b/ext/date/config0.m4 @@ -22,4 +22,5 @@ cat > $ext_builddir/lib/timelib_config.h < #endif +#include EOF diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index a3d7793447b72..cc12eb38a6f04 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -23,37 +23,7 @@ #include "timelib_config.h" -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#if defined(HAVE_INTTYPES_H) -#include -#elif defined(HAVE_STDINT_H) -#include -#endif - -#ifdef PHP_WIN32 -/* TODO: Remove these hacks/defs once we have the int definitions in main/ - rathen than in each 2nd extension and win32/ */ -# include "win32/php_stdint.h" -#else -# ifndef HAVE_INT32_T -# if SIZEOF_INT == 4 -typedef int int32_t; -# elif SIZEOF_LONG == 4 -typedef long int int32_t; -# endif -# endif - -# ifndef HAVE_UINT32_T -# if SIZEOF_INT == 4 -typedef unsigned int uint32_t; -# elif SIZEOF_LONG == 4 -typedef unsigned long int uint32_t; -# endif -# endif -#endif +#include "php_stdint.h" #include diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 2fe54f7b31c3c..f886bb4fea783 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -40,16 +40,6 @@ #include "php.h" #include "ext/standard/file.h" -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef PHP_WIN32 -# include "win32/php_stdint.h" -#endif - #if HAVE_EXIF /* When EXIF_DEBUG is defined the module generates a lot of debug messages diff --git a/ext/ext_skel b/ext/ext_skel index 2492bf73da33e..061e78d6493f1 100755 --- a/ext/ext_skel +++ b/ext/ext_skel @@ -12,7 +12,7 @@ echo "" echo " --extname=module module is the name of your extension" echo " --proto=file file contains prototypes of functions to create" echo " --stubs=file generate only function stubs in file" -echo " --xml generate xml documentation to be added to phpdoc-cvs" +echo " --xml generate xml documentation to be added to phpdoc-svn" echo " --skel=dir path to the skeleton directory" echo " --full-xml generate xml documentation for a self-contained extension" echo " (not yet implemented)" @@ -187,11 +187,43 @@ if (PHP_$EXTNAME != "no") { eof -$ECHO_N " .svnignore$ECHO_C" -cat >.svnignore <.gitignore <interpolation_id == GD_WEIGHTED4) { return getPixelInterpolateWeight(im, x, y, bgColor); } @@ -1711,6 +1709,7 @@ gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, co gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor) { float _angle = ((float) (-degrees / 180.0f) * (float)M_PI); + const int angle_rounded = (int)floor(degrees * 100); const int src_w = gdImageSX(src); const int src_h = gdImageSY(src); const unsigned int new_width = (unsigned int)(abs((int)(src_w * cos(_angle))) + abs((int)(src_h * sin(_angle))) + 0.5f); @@ -1733,6 +1732,10 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b : 0; + if (bgColor < 0) { + return NULL; + } + dst = gdImageCreateTrueColor(new_width, new_height); if (!dst) { return NULL; diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index e3a3563aaca4f..af9c73afa2b0a 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -24,6 +24,10 @@ #include "php_ini.h" #include "php_gmp.h" #include "ext/standard/info.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_smart_str_public.h" +#include "zend_exceptions.h" +#include "zend_interfaces.h" #if HAVE_GMP @@ -34,9 +38,6 @@ #include "ext/standard/php_lcg.h" #define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) -/* True global resources - no need for thread safety here */ -static int le_gmp; - /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_init, 0, 0, 1) ZEND_ARG_INFO(0, number) @@ -308,9 +309,18 @@ zend_module_entry gmp_module_entry = { ZEND_GET_MODULE(gmp) #endif -static void _php_gmpnum_free(zend_rsrc_list_entry *rsrc TSRMLS_DC); +zend_class_entry *gmp_ce; +static zend_object_handlers gmp_object_handlers; + +typedef struct _gmp_object { + zend_object std; + mpz_t num; +} gmp_object; -#define GMP_RESOURCE_NAME "GMP integer" +typedef struct _gmp_temp { + mpz_t num; + zend_bool is_used; +} gmp_temp_t; #define GMP_ROUND_ZERO 0 #define GMP_ROUND_PLUSINF 1 @@ -324,6 +334,123 @@ static void _php_gmpnum_free(zend_rsrc_list_entry *rsrc TSRMLS_DC); # define MAX_BASE 36 #endif +#define IS_GMP(zval) \ + (Z_TYPE_P(zval) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zval), gmp_ce TSRMLS_CC)) + +#define GET_GMP_FROM_ZVAL(zval) \ + (((gmp_object *) zend_object_store_get_object((zval) TSRMLS_CC))->num) + +/* The FETCH_GMP_ZVAL_* family of macros is used to fetch a gmp number + * (mpz_ptr) from a zval. If the zval is not a GMP instance, then we + * try to convert the value to a temporary gmp number using convert_to_gmp. + * This temporary number is stored in the temp argument, which is of type + * gmp_temp_t. This temporary value needs to be freed lateron using the + * FREE_GMP_TEMP macro. + * + * If the conversion to a gmp number fails, the macros return false. + * The _DEP / _DEP_DEP variants additionally free the temporary values + * passed in the last / last two arguments. + * + * If one zval can sometimes be fetched as a long you have to set the + * is_used member of the corresponding gmp_temp_t value to 0, otherwise + * the FREE_GMP_TEMP and *_DEP macros will not work properly. + * + * The three FETCH_GMP_ZVAL_* macros below are mostly copy & paste code + * as I couldn't find a way to combine them. + */ + +#define FREE_GMP_TEMP(temp) \ + if (temp.is_used) { \ + mpz_clear(temp.num); \ + } + +#define FETCH_GMP_ZVAL_DEP_DEP(gmpnumber, zval, temp, dep1, dep2) \ +if (IS_GMP(zval)) { \ + gmpnumber = GET_GMP_FROM_ZVAL(zval); \ + temp.is_used = 0; \ +} else { \ + mpz_init(temp.num); \ + if (convert_to_gmp(temp.num, zval, 0 TSRMLS_CC) == FAILURE) { \ + mpz_clear(temp.num); \ + FREE_GMP_TEMP(dep1); \ + FREE_GMP_TEMP(dep2); \ + RETURN_FALSE; \ + } \ + temp.is_used = 1; \ + gmpnumber = temp.num; \ +} + +#define FETCH_GMP_ZVAL_DEP(gmpnumber, zval, temp, dep) \ +if (IS_GMP(zval)) { \ + gmpnumber = GET_GMP_FROM_ZVAL(zval); \ + temp.is_used = 0; \ +} else { \ + mpz_init(temp.num); \ + if (convert_to_gmp(temp.num, zval, 0 TSRMLS_CC) == FAILURE) { \ + mpz_clear(temp.num); \ + FREE_GMP_TEMP(dep); \ + RETURN_FALSE; \ + } \ + temp.is_used = 1; \ + gmpnumber = temp.num; \ +} + +#define FETCH_GMP_ZVAL(gmpnumber, zval, temp) \ +if (IS_GMP(zval)) { \ + gmpnumber = GET_GMP_FROM_ZVAL(zval); \ + temp.is_used = 0; \ +} else { \ + mpz_init(temp.num); \ + if (convert_to_gmp(temp.num, zval, 0 TSRMLS_CC) == FAILURE) { \ + mpz_clear(temp.num); \ + RETURN_FALSE; \ + } \ + temp.is_used = 1; \ + gmpnumber = temp.num; \ +} + +#define INIT_GMP_RETVAL(gmpnumber) \ + gmp_create_ex(return_value, &gmpnumber TSRMLS_CC) + +static void gmp_strval(zval *result, mpz_t gmpnum, long base); +static int convert_to_gmp(mpz_t gmpnumber, zval *val, int base TSRMLS_DC); +static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg TSRMLS_DC); + +/* + * The gmp_*_op functions provide an implementation for several common types + * of GMP functions. The gmp_zval_(unary|binary)_*_op functions have to be manually + * passed zvals to work on, whereas the gmp_(unary|binary)_*_op macros already + * include parameter parsing. + */ +typedef void (*gmp_unary_op_t)(mpz_ptr, mpz_srcptr); +typedef int (*gmp_unary_opl_t)(mpz_srcptr); + +typedef void (*gmp_unary_ui_op_t)(mpz_ptr, unsigned long); + +typedef void (*gmp_binary_op_t)(mpz_ptr, mpz_srcptr, mpz_srcptr); +typedef int (*gmp_binary_opl_t)(mpz_srcptr, mpz_srcptr); + +typedef void (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, unsigned long); +typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); +typedef void (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long); + +static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int check_b_zero TSRMLS_DC); +static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int check_b_zero TSRMLS_DC); +static inline void gmp_zval_unary_op(zval *return_value, zval *a_arg, gmp_unary_op_t gmp_op TSRMLS_DC); +static inline void gmp_zval_unary_ui_op(zval *return_value, zval *a_arg, gmp_unary_ui_op_t gmp_op TSRMLS_DC); + +/* Binary operations */ +#define gmp_binary_ui_op(op, uop) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop, 0) +#define gmp_binary_op(op) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, NULL, 0) +#define gmp_binary_opl(op) _gmp_binary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) +#define gmp_binary_ui_op_no_zero(op, uop) \ + _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop, 1) + +/* Unary operations */ +#define gmp_unary_op(op) _gmp_unary_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) +#define gmp_unary_opl(op) _gmp_unary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) +#define gmp_unary_ui_op(op) _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) + /* {{{ gmp_emalloc */ static void *gmp_emalloc(size_t size) @@ -348,6 +475,310 @@ static void gmp_efree(void *ptr, size_t size) } /* }}} */ +static inline long gmp_get_long(zval *zv) /* {{{ */ +{ + if (Z_TYPE_P(zv) == IS_LONG) { + return Z_LVAL_P(zv); + } else { + zval tmp_zv; + MAKE_COPY_ZVAL(&zv, &tmp_zv); + convert_to_long(&tmp_zv); + return Z_LVAL(tmp_zv); + } +} +/* }}} */ + +static void gmp_free_object_storage(gmp_object *intern TSRMLS_DC) /* {{{ */ +{ + mpz_clear(intern->num); + + zend_object_std_dtor(&intern->std TSRMLS_CC); + efree(intern); +} +/* }}} */ + +static inline zend_object_value gmp_create_object_ex(zend_class_entry *ce, mpz_ptr *gmpnum_target TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + gmp_object *intern = emalloc(sizeof(gmp_object)); + + zend_object_std_init(&intern->std, ce TSRMLS_CC); + object_properties_init(&intern->std, ce); + + mpz_init(intern->num); + *gmpnum_target = intern->num; + + retval.handle = zend_objects_store_put( + intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, + (zend_objects_free_object_storage_t) gmp_free_object_storage, + NULL TSRMLS_CC + ); + retval.handlers = &gmp_object_handlers; + + return retval; +} +/* }}} */ + +static zend_object_value gmp_create_object(zend_class_entry *ce TSRMLS_DC) /* {{{ */ +{ + mpz_ptr gmpnum_dummy; + return gmp_create_object_ex(ce, &gmpnum_dummy TSRMLS_CC); +} +/* }}} */ + +static inline void gmp_create_ex(zval *target, mpz_ptr *gmpnum_target TSRMLS_DC) /* {{{ */ +{ + Z_TYPE_P(target) = IS_OBJECT; + Z_OBJVAL_P(target) = gmp_create_object_ex(gmp_ce, gmpnum_target TSRMLS_CC); +} +/* }}} */ + +static zval *gmp_create(mpz_ptr *gmpnum_target TSRMLS_DC) /* {{{ */ +{ + zval *obj; + MAKE_STD_ZVAL(obj); + gmp_create_ex(obj, gmpnum_target TSRMLS_CC); + return obj; +} +/* }}} */ + +static int gmp_cast_object(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* {{{ */ +{ + mpz_ptr gmpnum; + switch (type) { + case IS_STRING: + gmpnum = GET_GMP_FROM_ZVAL(readobj); + INIT_PZVAL(writeobj); + gmp_strval(writeobj, gmpnum, 10); + return SUCCESS; + case IS_LONG: + gmpnum = GET_GMP_FROM_ZVAL(readobj); + INIT_PZVAL(writeobj); + ZVAL_LONG(writeobj, mpz_get_si(gmpnum)); + return SUCCESS; + case IS_DOUBLE: + gmpnum = GET_GMP_FROM_ZVAL(readobj); + INIT_PZVAL(writeobj); + ZVAL_DOUBLE(writeobj, mpz_get_d(gmpnum)); + return SUCCESS; + default: + return FAILURE; + } +} +/* }}} */ + +static HashTable *gmp_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ +{ + HashTable *ht, *props = zend_std_get_properties(obj TSRMLS_CC); + mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(obj); + zval *zv; + + *is_temp = 1; + ALLOC_HASHTABLE(ht); + ZEND_INIT_SYMTABLE_EX(ht, zend_hash_num_elements(props) + 1, 0); + zend_hash_copy(ht, props, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + + MAKE_STD_ZVAL(zv); + gmp_strval(zv, gmpnum, 10); + zend_hash_update(ht, "num", sizeof("num"), &zv, sizeof(zval *), NULL); + + return ht; +} +/* }}} */ + +static zend_object_value gmp_clone_obj(zval *obj TSRMLS_DC) /* {{{ */ +{ + gmp_object *old_object = zend_object_store_get_object(obj TSRMLS_CC); + zend_object_value new_object_val = gmp_create_object(Z_OBJCE_P(obj) TSRMLS_CC); + gmp_object *new_object = zend_object_store_get_object_by_handle( + new_object_val.handle TSRMLS_CC + ); + + zend_objects_clone_members( + &new_object->std, new_object_val, + &old_object->std, Z_OBJ_HANDLE_P(obj) TSRMLS_CC + ); + + mpz_set(new_object->num, old_object->num); + + return new_object_val; +} +/* }}} */ + +static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2 TSRMLS_DC) { + zval op2_copy; + if (Z_TYPE_P(op2) != IS_LONG) { + op2_copy = *op2; + zval_copy_ctor(&op2_copy); + convert_to_long(&op2_copy); + op2 = &op2_copy; + } + + if (Z_LVAL_P(op2) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Shift cannot be negative"); + RETVAL_FALSE; + } else { + mpz_ptr gmpnum_op, gmpnum_result; + gmp_temp_t temp; + + FETCH_GMP_ZVAL(gmpnum_op, op1, temp); + INIT_GMP_RETVAL(gmpnum_result); + op(gmpnum_result, gmpnum_op, (unsigned long) Z_LVAL_P(op2)); + FREE_GMP_TEMP(temp); + } +} + +#define DO_BINARY_UI_OP_EX(op, uop, check_b_zero) \ + gmp_zval_binary_ui_op( \ + result, op1, op2, op, (gmp_binary_ui_op_t) uop, \ + check_b_zero TSRMLS_CC \ + ); \ + return SUCCESS; + +#define DO_BINARY_UI_OP(op) DO_BINARY_UI_OP_EX(op, op ## _ui, 0) +#define DO_BINARY_OP(op) DO_BINARY_UI_OP_EX(op, NULL, 0) + +#define DO_UNARY_OP(op) \ + gmp_zval_unary_op(result, op1, op TSRMLS_CC); \ + return SUCCESS; + +static int gmp_do_operation(zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ +{ + switch (opcode) { + case ZEND_ADD: + DO_BINARY_UI_OP(mpz_add); + case ZEND_SUB: + DO_BINARY_UI_OP(mpz_sub); + case ZEND_MUL: + DO_BINARY_UI_OP(mpz_mul); + case ZEND_DIV: + DO_BINARY_UI_OP_EX(mpz_tdiv_q, mpz_tdiv_q_ui, 1); + case ZEND_MOD: + DO_BINARY_UI_OP_EX(mpz_mod, mpz_mod_ui, 1); + case ZEND_SL: + shift_operator_helper(mpz_mul_2exp, result, op1, op2 TSRMLS_CC); + return SUCCESS; + case ZEND_SR: + shift_operator_helper(mpz_fdiv_q_2exp, result, op1, op2 TSRMLS_CC); + return SUCCESS; + case ZEND_BW_OR: + DO_BINARY_OP(mpz_ior); + case ZEND_BW_AND: + DO_BINARY_OP(mpz_and); + case ZEND_BW_XOR: + DO_BINARY_OP(mpz_xor); + case ZEND_BW_NOT: + DO_UNARY_OP(mpz_com); + + default: + return FAILURE; + } +} +/* }}} */ + +static int gmp_compare(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ +{ + gmp_cmp(result, op1, op2 TSRMLS_CC); + if (Z_TYPE_P(result) == IS_BOOL) { + ZVAL_LONG(result, 1); + } + return SUCCESS; +} +/* }}} */ + +PHP_METHOD(GMP, serialize) /* {{{ */ +{ + mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(getThis()); + smart_str buf = {0}; + php_serialize_data_t var_hash; + zval zv, *zv_ptr = &zv; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + PHP_VAR_SERIALIZE_INIT(var_hash); + + INIT_PZVAL(zv_ptr); + + gmp_strval(zv_ptr, gmpnum, 10); + php_var_serialize(&buf, &zv_ptr, &var_hash TSRMLS_CC); + zval_dtor(zv_ptr); + + Z_ARRVAL_P(zv_ptr) = zend_std_get_properties(getThis() TSRMLS_CC); + Z_TYPE_P(zv_ptr) = IS_ARRAY; + php_var_serialize(&buf, &zv_ptr, &var_hash TSRMLS_CC); + + PHP_VAR_SERIALIZE_DESTROY(var_hash); + + if (buf.c) { + RETURN_STRINGL(buf.c, buf.len, 0); + } +} +/* }}} */ + +PHP_METHOD(GMP, unserialize) /* {{{ */ +{ + mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(getThis()); + char *str; + int str_len; + php_unserialize_data_t var_hash; + const unsigned char *p, *max; + zval zv, *zv_ptr = &zv; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { + return; + } + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + + p = (unsigned char *) str; + max = (unsigned char *) str + str_len; + + INIT_ZVAL(zv); + if (!php_var_unserialize(&zv_ptr, &p, max, &var_hash TSRMLS_CC) + || Z_TYPE_P(zv_ptr) != IS_STRING + || convert_to_gmp(gmpnum, zv_ptr, 10 TSRMLS_CC) == FAILURE + ) { + zend_throw_exception(NULL, "Could not unserialize number", 0 TSRMLS_CC); + goto exit; + } + zval_dtor(&zv); + + INIT_ZVAL(zv); + if (!php_var_unserialize(&zv_ptr, &p, max, &var_hash TSRMLS_CC) + || Z_TYPE_P(zv_ptr) != IS_ARRAY + ) { + zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC); + goto exit; + } + + if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) { + zend_hash_copy( + zend_std_get_properties(getThis() TSRMLS_CC), Z_ARRVAL_P(zv_ptr), + (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) + ); + } + +exit: + zval_dtor(&zv); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); +} +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(arginfo_serialize, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_unserialize, 0, 0, 1) +ZEND_ARG_INFO(0, serialized) +ZEND_END_ARG_INFO() + +const zend_function_entry gmp_methods[] = { + PHP_ME(GMP, serialize, arginfo_serialize, ZEND_ACC_PUBLIC) + PHP_ME(GMP, unserialize, arginfo_unserialize, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + /* {{{ ZEND_GINIT_FUNCTION */ static ZEND_GINIT_FUNCTION(gmp) @@ -358,9 +789,21 @@ static ZEND_GINIT_FUNCTION(gmp) /* {{{ ZEND_MINIT_FUNCTION */ -ZEND_MODULE_STARTUP_D(gmp) +ZEND_MINIT_FUNCTION(gmp) { - le_gmp = zend_register_list_destructors_ex(_php_gmpnum_free, NULL, GMP_RESOURCE_NAME, module_number); + zend_class_entry tmp_ce; + INIT_CLASS_ENTRY(tmp_ce, "GMP", gmp_methods); + gmp_ce = zend_register_internal_class(&tmp_ce TSRMLS_CC); + zend_class_implements(gmp_ce TSRMLS_CC, 1, zend_ce_serializable); + gmp_ce->create_object = gmp_create_object; + + memcpy(&gmp_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + gmp_object_handlers.cast_object = gmp_cast_object; + gmp_object_handlers.get_debug_info = gmp_get_debug_info; + gmp_object_handlers.clone_obj = gmp_clone_obj; + gmp_object_handlers.do_operation = gmp_do_operation; + gmp_object_handlers.compare = gmp_compare; + REGISTER_LONG_CONSTANT("GMP_ROUND_ZERO", GMP_ROUND_ZERO, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GMP_ROUND_PLUSINF", GMP_ROUND_PLUSINF, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("GMP_ROUND_MINUSINF", GMP_ROUND_MINUSINF, CONST_CS | CONST_PERSISTENT); @@ -403,246 +846,211 @@ ZEND_MODULE_INFO_D(gmp) } /* }}} */ -/* Fetch zval to be GMP number. - Initially, zval can be also number or string */ -#define FETCH_GMP_ZVAL(gmpnumber, zval, tmp_resource) \ -if (Z_TYPE_PP(zval) == IS_RESOURCE) { \ - ZEND_FETCH_RESOURCE(gmpnumber, mpz_t *, zval, -1, GMP_RESOURCE_NAME, le_gmp); \ - tmp_resource = 0; \ -} else { \ - if (convert_to_gmp(&gmpnumber, zval, 0 TSRMLS_CC) == FAILURE) { \ - RETURN_FALSE; \ - } \ - tmp_resource = ZEND_REGISTER_RESOURCE(NULL, gmpnumber, le_gmp); \ -} - -#define FREE_GMP_TEMP(tmp_resource) \ - if(tmp_resource) { \ - zend_list_delete(tmp_resource); \ - } - - -/* create a new initialized GMP number */ -#define INIT_GMP_NUM(gmpnumber) { gmpnumber=emalloc(sizeof(mpz_t)); mpz_init(*gmpnumber); } -#define FREE_GMP_NUM(gmpnumber) { mpz_clear(*gmpnumber); efree(gmpnumber); } /* {{{ convert_to_gmp * Convert zval to be gmp number */ -static int convert_to_gmp(mpz_t * *gmpnumber, zval **val, int base TSRMLS_DC) +static int convert_to_gmp(mpz_t gmpnumber, zval *val, int base TSRMLS_DC) { - int ret = 0; - int skip_lead = 0; - - *gmpnumber = emalloc(sizeof(mpz_t)); - - switch (Z_TYPE_PP(val)) { + switch (Z_TYPE_P(val)) { case IS_LONG: case IS_BOOL: - case IS_CONSTANT: - { - convert_to_long_ex(val); - mpz_init_set_si(**gmpnumber, Z_LVAL_PP(val)); - } - break; - case IS_STRING: - { - char *numstr = Z_STRVAL_PP(val); - - if (Z_STRLEN_PP(val) > 2) { - if (numstr[0] == '0') { - if (numstr[1] == 'x' || numstr[1] == 'X') { - base = 16; - skip_lead = 1; - } else if (base != 16 && (numstr[1] == 'b' || numstr[1] == 'B')) { - base = 2; - skip_lead = 1; - } + case IS_CONSTANT: { + mpz_set_si(gmpnumber, gmp_get_long(val)); + return SUCCESS; + } + case IS_STRING: { + char *numstr = Z_STRVAL_P(val); + int skip_lead = 0; + + if (Z_STRLEN_P(val) > 2) { + if (numstr[0] == '0') { + if (numstr[1] == 'x' || numstr[1] == 'X') { + base = 16; + skip_lead = 1; + } else if (base != 16 && (numstr[1] == 'b' || numstr[1] == 'B')) { + base = 2; + skip_lead = 1; } } - ret = mpz_init_set_str(**gmpnumber, (skip_lead ? &numstr[2] : numstr), base); } - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to convert variable to GMP - wrong type"); - efree(*gmpnumber); - return FAILURE; - } - if (ret) { - FREE_GMP_NUM(*gmpnumber); + return mpz_set_str(gmpnumber, (skip_lead ? &numstr[2] : numstr), base); + } + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert variable to GMP - wrong type"); return FAILURE; } - - return SUCCESS; } /* }}} */ -/* {{{ typedefs - */ -typedef void (*gmp_unary_op_t)(mpz_ptr, mpz_srcptr); -typedef int (*gmp_unary_opl_t)(mpz_srcptr); +static void gmp_strval(zval *result, mpz_t gmpnum, long base) /* {{{ */ +{ + int num_len; + char *out_string; -typedef void (*gmp_unary_ui_op_t)(mpz_ptr, unsigned long); + num_len = mpz_sizeinbase(gmpnum, abs(base)); + if (mpz_sgn(gmpnum) < 0) { + num_len++; + } -typedef void (*gmp_binary_op_t)(mpz_ptr, mpz_srcptr, mpz_srcptr); -typedef int (*gmp_binary_opl_t)(mpz_srcptr, mpz_srcptr); + out_string = emalloc(num_len + 1); + mpz_get_str(out_string, base, gmpnum); + + /* + * From GMP documentation for mpz_sizeinbase(): + * The returned value will be exact or 1 too big. If base is a power of + * 2, the returned value will always be exact. + * + * So let's check to see if we already have a \0 byte... + */ + + if (out_string[num_len - 1] == '\0') { + num_len--; + } else { + out_string[num_len] = '\0'; + } -typedef unsigned long (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, unsigned long); -typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); -typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long); + ZVAL_STRINGL(result, out_string, num_len, 0); +} /* }}} */ -#define gmp_zval_binary_ui_op(r, a, b, o, u) gmp_zval_binary_ui_op_ex(r, a, b, o, u, 0, 0, 0 TSRMLS_CC) -#define gmp_zval_binary_ui_op2(r, a, b, o, u) gmp_zval_binary_ui_op2_ex(r, a, b, o, u, 0, 0, 0 TSRMLS_CC) +static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg TSRMLS_DC) /* {{{ */ +{ + mpz_ptr gmpnum_a, gmpnum_b; + gmp_temp_t temp_a, temp_b; + zend_bool use_si = 0; + long res; -#define gmp_binary_ui_op(op, uop) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop) -#define gmp_binary_op(op) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, NULL) -#define gmp_binary_opl(op) _gmp_binary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); -/* Unary operations */ -#define gmp_unary_op(op) _gmp_unary_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) -#define gmp_unary_opl(op) _gmp_unary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) -#define gmp_unary_ui_op(op) _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) + if (Z_TYPE_P(b_arg) == IS_LONG) { + use_si = 1; + temp_b.is_used = 0; + } else { + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); + } -/* {{{ gmp_zval_binary_ui_op_ex + if (use_si) { + res = mpz_cmp_si(gmpnum_a, Z_LVAL_P(b_arg)); + } else { + res = mpz_cmp(gmpnum_a, gmpnum_b); + } + + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); + + RETURN_LONG(res); +} +/* }}} */ + +/* {{{ gmp_zval_binary_ui_op Execute GMP binary operation. - May return GMP resource or long if operation allows this */ -static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return, int check_b_zero, int use_sign TSRMLS_DC) +static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int check_b_zero TSRMLS_DC) { - mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result; - unsigned long long_result = 0; + mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result; int use_ui = 0; - int arga_tmp = 0, argb_tmp = 0; + gmp_temp_t temp_a, temp_b; - FETCH_GMP_ZVAL(gmpnum_a, a_arg, arga_tmp); + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - if (gmp_ui_op && Z_TYPE_PP(b_arg) == IS_LONG && Z_LVAL_PP(b_arg) >= 0) { + if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) { use_ui = 1; + temp_b.is_used = 0; } else { - FETCH_GMP_ZVAL(gmpnum_b, b_arg, argb_tmp); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); } - if(check_b_zero) { + if (check_b_zero) { int b_is_zero = 0; - if(use_ui) { - b_is_zero = (Z_LVAL_PP(b_arg) == 0); + if (use_ui) { + b_is_zero = (Z_LVAL_P(b_arg) == 0); } else { - b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0); + b_is_zero = !mpz_cmp_ui(gmpnum_b, 0); } - if(b_is_zero) { + if (b_is_zero) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed"); - FREE_GMP_TEMP(arga_tmp); - FREE_GMP_TEMP(argb_tmp); + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); RETURN_FALSE; } } - INIT_GMP_NUM(gmpnum_result); + INIT_GMP_RETVAL(gmpnum_result); - if (use_ui && gmp_ui_op) { - if (allow_ui_return) { - long_result = gmp_ui_op(*gmpnum_result, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg)); - if (use_sign && mpz_sgn(*gmpnum_a) == -1) { - long_result = -long_result; - } - } else { - gmp_ui_op(*gmpnum_result, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg)); - } + if (use_ui) { + gmp_ui_op(gmpnum_result, gmpnum_a, (unsigned long) Z_LVAL_P(b_arg)); } else { - gmp_op(*gmpnum_result, *gmpnum_a, *gmpnum_b); + gmp_op(gmpnum_result, gmpnum_a, gmpnum_b); } - FREE_GMP_TEMP(arga_tmp); - FREE_GMP_TEMP(argb_tmp); - - if (use_ui && allow_ui_return) { - FREE_GMP_NUM(gmpnum_result); - RETURN_LONG((long)long_result); - } else { - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); - } + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); } /* }}} */ -/* {{{ gmp_zval_binary_ui_op2_ex +/* {{{ gmp_zval_binary_ui_op2 Execute GMP binary operation which returns 2 values. - May return GMP resources or longs if operation allows this. */ -static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC) +static inline void gmp_zval_binary_ui_op2(zval *return_value, zval *a_arg, zval *b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int check_b_zero TSRMLS_DC) { - mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result1, *gmpnum_result2; - zval r; + mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result1, gmpnum_result2; int use_ui = 0; - unsigned long long_result = 0; - int arga_tmp = 0, argb_tmp = 0; + gmp_temp_t temp_a, temp_b; - FETCH_GMP_ZVAL(gmpnum_a, a_arg, arga_tmp); + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - if (gmp_ui_op && Z_TYPE_PP(b_arg) == IS_LONG && Z_LVAL_PP(b_arg) >= 0) { + if (gmp_ui_op && Z_TYPE_P(b_arg) == IS_LONG && Z_LVAL_P(b_arg) >= 0) { /* use _ui function */ use_ui = 1; + temp_b.is_used = 0; } else { - FETCH_GMP_ZVAL(gmpnum_b, b_arg, argb_tmp); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); } - if(check_b_zero) { + if (check_b_zero) { int b_is_zero = 0; - if(use_ui) { - b_is_zero = (Z_LVAL_PP(b_arg) == 0); + if (use_ui) { + b_is_zero = (Z_LVAL_P(b_arg) == 0); } else { - b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0); + b_is_zero = !mpz_cmp_ui(gmpnum_b, 0); } - if(b_is_zero) { + if (b_is_zero) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed"); - FREE_GMP_TEMP(arga_tmp); - FREE_GMP_TEMP(argb_tmp); + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); RETURN_FALSE; } } - INIT_GMP_NUM(gmpnum_result1); - INIT_GMP_NUM(gmpnum_result2); + array_init(return_value); + add_index_zval(return_value, 0, gmp_create(&gmpnum_result1 TSRMLS_CC)); + add_index_zval(return_value, 1, gmp_create(&gmpnum_result2 TSRMLS_CC)); - if (use_ui && gmp_ui_op) { - if (allow_ui_return) { - long_result = gmp_ui_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg)); - } else { - gmp_ui_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, (unsigned long)Z_LVAL_PP(b_arg)); - } + if (use_ui) { + gmp_ui_op(gmpnum_result1, gmpnum_result2, gmpnum_a, (unsigned long) Z_LVAL_P(b_arg)); } else { - gmp_op(*gmpnum_result1, *gmpnum_result2, *gmpnum_a, *gmpnum_b); + gmp_op(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b); } - FREE_GMP_TEMP(arga_tmp); - FREE_GMP_TEMP(argb_tmp); - - array_init(return_value); - ZEND_REGISTER_RESOURCE(&r, gmpnum_result1, le_gmp); - add_index_resource(return_value, 0, Z_LVAL(r)); - if (use_ui && allow_ui_return) { - mpz_clear(*gmpnum_result2); - add_index_long(return_value, 1, long_result); - } else { - ZEND_REGISTER_RESOURCE(&r, gmpnum_result2, le_gmp); - add_index_resource(return_value, 1, Z_LVAL(r)); - } + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); } /* }}} */ /* {{{ _gmp_binary_ui_op */ -static inline void _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op) +static inline void _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int check_b_zero) { - zval **a_arg, **b_arg; + zval *a_arg, *b_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } - gmp_zval_binary_ui_op(return_value, a_arg, b_arg, gmp_op, gmp_ui_op); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, gmp_op, gmp_ui_op, check_b_zero TSRMLS_CC); } /* }}} */ @@ -650,33 +1058,28 @@ static inline void _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_op /* {{{ gmp_zval_unary_op */ -static inline void gmp_zval_unary_op(zval *return_value, zval **a_arg, gmp_unary_op_t gmp_op TSRMLS_DC) +static inline void gmp_zval_unary_op(zval *return_value, zval *a_arg, gmp_unary_op_t gmp_op TSRMLS_DC) { - mpz_t *gmpnum_a, *gmpnum_result; - int temp_a; + mpz_ptr gmpnum_a, gmpnum_result; + gmp_temp_t temp_a; FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - INIT_GMP_NUM(gmpnum_result); - gmp_op(*gmpnum_result, *gmpnum_a); + INIT_GMP_RETVAL(gmpnum_result); + gmp_op(gmpnum_result, gmpnum_a); FREE_GMP_TEMP(temp_a); - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); } /* }}} */ /* {{{ gmp_zval_unary_ui_op */ -static inline void gmp_zval_unary_ui_op(zval *return_value, zval **a_arg, gmp_unary_ui_op_t gmp_op TSRMLS_DC) +static inline void gmp_zval_unary_ui_op(zval *return_value, zval *a_arg, gmp_unary_ui_op_t gmp_op TSRMLS_DC) { - mpz_t *gmpnum_result; - - convert_to_long_ex(a_arg); - - INIT_GMP_NUM(gmpnum_result); - gmp_op(*gmpnum_result, Z_LVAL_PP(a_arg)); + mpz_ptr gmpnum_result; - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); + INIT_GMP_RETVAL(gmpnum_result); + gmp_op(gmpnum_result, gmp_get_long(a_arg)); } /* }}} */ @@ -685,9 +1088,9 @@ static inline void gmp_zval_unary_ui_op(zval *return_value, zval **a_arg, gmp_un */ static inline void _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_ui_op_t gmp_op) { - zval **a_arg; + zval *a_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } @@ -699,9 +1102,9 @@ static inline void _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_ui_o */ static inline void _gmp_unary_op(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_op_t gmp_op) { - zval **a_arg; + zval *a_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } @@ -713,16 +1116,16 @@ static inline void _gmp_unary_op(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_op_t gm */ static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t gmp_op) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - RETVAL_LONG(gmp_op(*gmpnum_a)); + RETVAL_LONG(gmp_op(gmpnum_a)); FREE_GMP_TEMP(temp_a); } /* }}} */ @@ -731,33 +1134,33 @@ static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t */ static inline void _gmp_binary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_opl_t gmp_op) { - zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b; - int temp_a, temp_b; + zval *a_arg, *b_arg; + mpz_ptr gmpnum_a, gmpnum_b; + gmp_temp_t temp_a, temp_b; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - RETVAL_LONG(gmp_op(*gmpnum_a, *gmpnum_b)); + RETVAL_LONG(gmp_op(gmpnum_a, gmpnum_b)); FREE_GMP_TEMP(temp_a); FREE_GMP_TEMP(temp_b); } /* }}} */ -/* {{{ proto resource gmp_init(mixed number [, int base]) +/* {{{ proto GMP gmp_init(mixed number [, int base]) Initializes GMP number */ ZEND_FUNCTION(gmp_init) { - zval **number_arg; - mpz_t * gmpnumber; - long base=0; + zval *number_arg; + mpz_ptr gmpnumber; + long base = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &number_arg, &base) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &number_arg, &base) == FAILURE) { return; } @@ -766,48 +1169,42 @@ ZEND_FUNCTION(gmp_init) RETURN_FALSE; } - if (convert_to_gmp(&gmpnumber, number_arg, base TSRMLS_CC) == FAILURE) { + INIT_GMP_RETVAL(gmpnumber); + if (convert_to_gmp(gmpnumber, number_arg, base TSRMLS_CC) == FAILURE) { + zval_dtor(return_value); RETURN_FALSE; } - - /* Write your own code here to handle argument number. */ - ZEND_REGISTER_RESOURCE(return_value, gmpnumber, le_gmp); } /* }}} */ -/* {{{ proto int gmp_intval(resource gmpnumber) +/* {{{ proto int gmp_intval(mixed gmpnumber) Gets signed long value of GMP number */ ZEND_FUNCTION(gmp_intval) { - zval **gmpnumber_arg; - mpz_t * gmpnum; + zval *gmpnumber_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &gmpnumber_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &gmpnumber_arg) == FAILURE){ return; } - if (Z_TYPE_PP(gmpnumber_arg) == IS_RESOURCE) { - ZEND_FETCH_RESOURCE(gmpnum, mpz_t *, gmpnumber_arg, -1, GMP_RESOURCE_NAME, le_gmp); - RETVAL_LONG(mpz_get_si(*gmpnum)); + if (IS_GMP(gmpnumber_arg)) { + RETVAL_LONG(mpz_get_si(GET_GMP_FROM_ZVAL(gmpnumber_arg))); } else { - convert_to_long_ex(gmpnumber_arg); - RETVAL_LONG(Z_LVAL_PP(gmpnumber_arg)); + RETVAL_LONG(gmp_get_long(gmpnumber_arg)); } } /* }}} */ -/* {{{ proto string gmp_strval(resource gmpnumber [, int base]) +/* {{{ proto string gmp_strval(mixed gmpnumber [, int base]) Gets string representation of GMP number */ ZEND_FUNCTION(gmp_strval) { - zval **gmpnumber_arg; - int num_len; + zval *gmpnumber_arg; long base = 10; - mpz_t * gmpnum; - char *out_string; - int temp_a; + mpz_ptr gmpnum; + gmp_temp_t temp_a; - if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &gmpnumber_arg, &base ) == FAILURE ) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &gmpnumber_arg, &base) == FAILURE) { return; } @@ -825,162 +1222,138 @@ ZEND_FUNCTION(gmp_strval) FETCH_GMP_ZVAL(gmpnum, gmpnumber_arg, temp_a); - num_len = mpz_sizeinbase(*gmpnum, abs(base)); - out_string = emalloc(num_len+2); - if (mpz_sgn(*gmpnum) < 0) { - num_len++; - } - mpz_get_str(out_string, base, *gmpnum); - - FREE_GMP_TEMP(temp_a); - - /* - From GMP documentation for mpz_sizeinbase(): - The returned value will be exact or 1 too big. If base is a power of - 2, the returned value will always be exact. + gmp_strval(return_value, gmpnum, base); - So let's check to see if we already have a \0 byte... - */ - - if (out_string[num_len-1] == '\0') { - num_len--; - } else { - out_string[num_len] = '\0'; - } - RETVAL_STRINGL(out_string, num_len, 0); + FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto resource gmp_add(resource a, resource b) +/* {{{ proto GMP gmp_add(mixed a, mixed b) Add a and b */ ZEND_FUNCTION(gmp_add) { - gmp_binary_ui_op(mpz_add, (gmp_binary_ui_op_t)mpz_add_ui); + gmp_binary_ui_op(mpz_add, mpz_add_ui); } /* }}} */ -/* {{{ proto resource gmp_sub(resource a, resource b) +/* {{{ proto GMP gmp_sub(mixed a, mixed b) Subtract b from a */ ZEND_FUNCTION(gmp_sub) { - gmp_binary_ui_op(mpz_sub, (gmp_binary_ui_op_t)mpz_sub_ui); + gmp_binary_ui_op(mpz_sub, mpz_sub_ui); } /* }}} */ -/* {{{ proto resource gmp_mul(resource a, resource b) +/* {{{ proto GMP gmp_mul(mixed a, mixed b) Multiply a and b */ ZEND_FUNCTION(gmp_mul) { - gmp_binary_ui_op(mpz_mul, (gmp_binary_ui_op_t)mpz_mul_ui); + gmp_binary_ui_op(mpz_mul, mpz_mul_ui); } /* }}} */ -/* {{{ proto array gmp_div_qr(resource a, resource b [, int round]) +/* {{{ proto array gmp_div_qr(mixed a, mixed b [, int round]) Divide a by b, returns quotient and reminder */ ZEND_FUNCTION(gmp_div_qr) { - zval **a_arg, **b_arg; + zval *a_arg, *b_arg; long round = GMP_ROUND_ZERO; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|l", &a_arg, &b_arg, &round) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &a_arg, &b_arg, &round) == FAILURE) { return; } switch (round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t)mpz_tdiv_qr_ui, 0, 1 TSRMLS_CC); + gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t) mpz_tdiv_qr_ui, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t)mpz_cdiv_qr_ui, 0, 1 TSRMLS_CC); + gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t) mpz_cdiv_qr_ui, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t)mpz_fdiv_qr_ui, 0, 1 TSRMLS_CC); + gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t) mpz_fdiv_qr_ui, 1 TSRMLS_CC); break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid rounding mode"); + RETURN_FALSE; } - } /* }}} */ -/* {{{ proto resource gmp_div_r(resource a, resource b [, int round]) +/* {{{ proto GMP gmp_div_r(mixed a, mixed b [, int round]) Divide a by b, returns reminder only */ ZEND_FUNCTION(gmp_div_r) { - zval **a_arg, **b_arg; + zval *a_arg, *b_arg; long round = GMP_ROUND_ZERO; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|l", &a_arg, &b_arg, &round) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &a_arg, &b_arg, &round) == FAILURE) { return; } switch (round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t)mpz_tdiv_r_ui, 1, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t) mpz_tdiv_r_ui, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t)mpz_cdiv_r_ui, 1, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t) mpz_cdiv_r_ui, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t)mpz_fdiv_r_ui, 1, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t) mpz_fdiv_r_ui, 1 TSRMLS_CC); break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid rounding mode"); + RETURN_FALSE; } } /* }}} */ -/* {{{ proto resource gmp_div_q(resource a, resource b [, int round]) +/* {{{ proto GMP gmp_div_q(mixed a, mixed b [, int round]) Divide a by b, returns quotient only */ ZEND_FUNCTION(gmp_div_q) { - zval **a_arg, **b_arg; + zval *a_arg, *b_arg; long round = GMP_ROUND_ZERO; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|l", &a_arg, &b_arg, &round) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &a_arg, &b_arg, &round) == FAILURE) { return; } switch (round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t)mpz_tdiv_q_ui, 0, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t) mpz_tdiv_q_ui, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t)mpz_cdiv_q_ui, 0, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t) mpz_cdiv_q_ui, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t)mpz_fdiv_q_ui, 0, 1, 1 TSRMLS_CC); + gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t) mpz_fdiv_q_ui, 1 TSRMLS_CC); break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid rounding mode"); + RETURN_FALSE; } } /* }}} */ -/* {{{ proto resource gmp_mod(resource a, resource b) +/* {{{ proto GMP gmp_mod(mixed a, mixed b) Computes a modulo b */ ZEND_FUNCTION(gmp_mod) { - zval **a_arg, **b_arg; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ - return; - } - - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_mod, (gmp_binary_ui_op_t)mpz_mod_ui, 1, 1, 0 TSRMLS_CC); + gmp_binary_ui_op_no_zero(mpz_mod, (gmp_binary_ui_op_t) mpz_mod_ui); } /* }}} */ -/* {{{ proto resource gmp_divexact(resource a, resource b) +/* {{{ proto GMP gmp_divexact(mixed a, mixed b) Divide a by b using exact division algorithm */ ZEND_FUNCTION(gmp_divexact) { - zval **a_arg, **b_arg; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ - return; - } - - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_divexact, NULL, 0, 1, 1 TSRMLS_CC); + gmp_binary_ui_op_no_zero(mpz_divexact, NULL); } /* }}} */ -/* {{{ proto resource gmp_neg(resource a) +/* {{{ proto GMP gmp_neg(mixed a) Negates a number */ ZEND_FUNCTION(gmp_neg) { @@ -988,7 +1361,7 @@ ZEND_FUNCTION(gmp_neg) } /* }}} */ -/* {{{ proto resource gmp_abs(resource a) +/* {{{ proto GMP gmp_abs(mixed a) Calculates absolute value */ ZEND_FUNCTION(gmp_abs) { @@ -996,99 +1369,92 @@ ZEND_FUNCTION(gmp_abs) } /* }}} */ -/* {{{ proto resource gmp_fact(int a) +/* {{{ proto GMP gmp_fact(int a) Calculates factorial function */ ZEND_FUNCTION(gmp_fact) { - zval **a_arg; - mpz_t *gmpnum_tmp; - int temp_a; + zval *a_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } - if (Z_TYPE_PP(a_arg) == IS_RESOURCE) { - FETCH_GMP_ZVAL(gmpnum_tmp, a_arg, temp_a); /* no need to free this since it's IS_RESOURCE */ - if (mpz_sgn(*gmpnum_tmp) < 0) { + if (IS_GMP(a_arg)) { + mpz_ptr gmpnum_tmp = GET_GMP_FROM_ZVAL(a_arg); + if (mpz_sgn(gmpnum_tmp) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number has to be greater than or equal to 0"); RETURN_FALSE; } } else { - convert_to_long_ex(a_arg); - if (Z_LVAL_PP(a_arg) < 0) { + if (gmp_get_long(a_arg) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number has to be greater than or equal to 0"); RETURN_FALSE; } } - + gmp_zval_unary_ui_op(return_value, a_arg, mpz_fac_ui TSRMLS_CC); } /* }}} */ -/* {{{ proto resource gmp_pow(resource base, int exp) +/* {{{ proto GMP gmp_pow(mixed base, int exp) Raise base to power exp */ ZEND_FUNCTION(gmp_pow) { - zval **base_arg; - mpz_t *gmpnum_result, *gmpnum_base; - int use_ui = 0; - int temp_base; + zval *base_arg; + mpz_ptr gmpnum_result, gmpnum_base; + gmp_temp_t temp_base; long exp; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &base_arg, &exp) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &base_arg, &exp) == FAILURE) { return; } - if (Z_TYPE_PP(base_arg) == IS_LONG && Z_LVAL_PP(base_arg) >= 0) { - use_ui = 1; - } else { - FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base); - } - if (exp < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Negative exponent not supported"); RETURN_FALSE; } - INIT_GMP_NUM(gmpnum_result); - if (use_ui) { - mpz_ui_pow_ui(*gmpnum_result, Z_LVAL_PP(base_arg), exp); + INIT_GMP_RETVAL(gmpnum_result); + if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) { + mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp); } else { - mpz_pow_ui(*gmpnum_result, *gmpnum_base, exp); + FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base); + mpz_pow_ui(gmpnum_result, gmpnum_base, exp); FREE_GMP_TEMP(temp_base); } - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); } /* }}} */ -/* {{{ proto resource gmp_powm(resource base, resource exp, resource mod) +/* {{{ proto GMP gmp_powm(mixed base, mixed exp, mixed mod) Raise base to power exp and take result modulo mod */ ZEND_FUNCTION(gmp_powm) { - zval **base_arg, **exp_arg, **mod_arg; - mpz_t *gmpnum_base, *gmpnum_exp, *gmpnum_mod, *gmpnum_result; + zval *base_arg, *exp_arg, *mod_arg; + mpz_ptr gmpnum_base, gmpnum_exp, gmpnum_mod, gmpnum_result; int use_ui = 0; - int temp_base = 0, temp_exp = 0, temp_mod; + gmp_temp_t temp_base, temp_exp, temp_mod; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ", &base_arg, &exp_arg, &mod_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &base_arg, &exp_arg, &mod_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base); - if (Z_TYPE_PP(exp_arg) == IS_LONG && Z_LVAL_PP(exp_arg) >= 0) { + if (Z_TYPE_P(exp_arg) == IS_LONG && Z_LVAL_P(exp_arg) >= 0) { use_ui = 1; + temp_exp.is_used = 0; } else { - FETCH_GMP_ZVAL(gmpnum_exp, exp_arg, temp_exp); - if (mpz_sgn(*gmpnum_exp) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Second parameter cannot be less than 0"); + FETCH_GMP_ZVAL_DEP(gmpnum_exp, exp_arg, temp_exp, temp_base); + if (mpz_sgn(gmpnum_exp) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second parameter cannot be less than 0"); + FREE_GMP_TEMP(temp_base); + FREE_GMP_TEMP(temp_exp); RETURN_FALSE; } } - FETCH_GMP_ZVAL(gmpnum_mod, mod_arg, temp_mod); + FETCH_GMP_ZVAL_DEP_DEP(gmpnum_mod, mod_arg, temp_mod, temp_exp, temp_base); - if (!mpz_cmp_ui(*gmpnum_mod, 0)) { + if (!mpz_cmp_ui(gmpnum_mod, 0)) { FREE_GMP_TEMP(temp_base); if (use_ui) { FREE_GMP_TEMP(temp_exp); @@ -1097,202 +1463,175 @@ ZEND_FUNCTION(gmp_powm) RETURN_FALSE; } - INIT_GMP_NUM(gmpnum_result); + INIT_GMP_RETVAL(gmpnum_result); if (use_ui) { - mpz_powm_ui(*gmpnum_result, *gmpnum_base, (unsigned long)Z_LVAL_PP(exp_arg), *gmpnum_mod); + mpz_powm_ui(gmpnum_result, gmpnum_base, (unsigned long) Z_LVAL_P(exp_arg), gmpnum_mod); } else { - mpz_powm(*gmpnum_result, *gmpnum_base, *gmpnum_exp, *gmpnum_mod); + mpz_powm(gmpnum_result, gmpnum_base, gmpnum_exp, gmpnum_mod); FREE_GMP_TEMP(temp_exp); } FREE_GMP_TEMP(temp_base); FREE_GMP_TEMP(temp_mod); - - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); - } /* }}} */ -/* {{{ proto resource gmp_sqrt(resource a) +/* {{{ proto GMP gmp_sqrt(mixed a) Takes integer part of square root of a */ ZEND_FUNCTION(gmp_sqrt) { - zval **a_arg; - mpz_t *gmpnum_a, *gmpnum_result; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a, gmpnum_result; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - if (mpz_sgn(*gmpnum_a) < 0) { + if (mpz_sgn(gmpnum_a) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number has to be greater than or equal to 0"); FREE_GMP_TEMP(temp_a); RETURN_FALSE; } - - INIT_GMP_NUM(gmpnum_result); - mpz_sqrt(*gmpnum_result, *gmpnum_a); - FREE_GMP_TEMP(temp_a); - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); + INIT_GMP_RETVAL(gmpnum_result); + mpz_sqrt(gmpnum_result, gmpnum_a); + FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto array gmp_sqrtrem(resource a) +/* {{{ proto array gmp_sqrtrem(mixed a) Square root with remainder */ ZEND_FUNCTION(gmp_sqrtrem) { - zval **a_arg; - mpz_t *gmpnum_a, *gmpnum_result1, *gmpnum_result2; - zval r; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a, gmpnum_result1, gmpnum_result2; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - - if (mpz_sgn(*gmpnum_a) < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0"); + + if (mpz_sgn(gmpnum_a) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number has to be greater than or equal to 0"); + FREE_GMP_TEMP(temp_a); RETURN_FALSE; } - INIT_GMP_NUM(gmpnum_result1); - INIT_GMP_NUM(gmpnum_result2); + array_init(return_value); + add_index_zval(return_value, 0, gmp_create(&gmpnum_result1 TSRMLS_CC)); + add_index_zval(return_value, 1, gmp_create(&gmpnum_result2 TSRMLS_CC)); - mpz_sqrtrem(*gmpnum_result1, *gmpnum_result2, *gmpnum_a); + mpz_sqrtrem(gmpnum_result1, gmpnum_result2, gmpnum_a); FREE_GMP_TEMP(temp_a); - - array_init(return_value); - ZEND_REGISTER_RESOURCE(&r, gmpnum_result1, le_gmp); - add_index_resource(return_value, 0, Z_LVAL(r)); - ZEND_REGISTER_RESOURCE(&r, gmpnum_result2, le_gmp); - add_index_resource(return_value, 1, Z_LVAL(r)); } /* }}} */ -/* {{{ proto bool gmp_perfect_square(resource a) +/* {{{ proto bool gmp_perfect_square(mixed a) Checks if a is an exact square */ ZEND_FUNCTION(gmp_perfect_square) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - RETVAL_BOOL((mpz_perfect_square_p(*gmpnum_a)!=0)); + RETVAL_BOOL((mpz_perfect_square_p(gmpnum_a) != 0)); FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto int gmp_prob_prime(resource a[, int reps]) +/* {{{ proto int gmp_prob_prime(mixed a[, int reps]) Checks if a is "probably prime" */ ZEND_FUNCTION(gmp_prob_prime) { - zval **gmpnumber_arg; - mpz_t *gmpnum_a; + zval *gmpnumber_arg; + mpz_ptr gmpnum_a; long reps = 10; - int temp_a; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|l", &gmpnumber_arg, &reps) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &gmpnumber_arg, &reps) == FAILURE) { return; } FETCH_GMP_ZVAL(gmpnum_a, gmpnumber_arg, temp_a); - RETVAL_LONG(mpz_probab_prime_p(*gmpnum_a, reps)); + RETVAL_LONG(mpz_probab_prime_p(gmpnum_a, reps)); FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto resource gmp_gcd(resource a, resource b) +/* {{{ proto GMP gmp_gcd(mixed a, mixed b) Computes greatest common denominator (gcd) of a and b */ ZEND_FUNCTION(gmp_gcd) { - zval **a_arg, **b_arg; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ - return; - } - - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 0, 0, 1 TSRMLS_CC); + gmp_binary_ui_op(mpz_gcd, (gmp_binary_ui_op_t) mpz_gcd_ui); } /* }}} */ -/* {{{ proto array gmp_gcdext(resource a, resource b) +/* {{{ proto array gmp_gcdext(mixed a, mixed b) Computes G, S, and T, such that AS + BT = G = `gcd' (A, B) */ ZEND_FUNCTION(gmp_gcdext) { - zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_t, *gmpnum_s, *gmpnum_g; - zval r; - int temp_a, temp_b; + zval *a_arg, *b_arg; + mpz_ptr gmpnum_a, gmpnum_b, gmpnum_t, gmpnum_s, gmpnum_g; + gmp_temp_t temp_a, temp_b; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - INIT_GMP_NUM(gmpnum_g); - INIT_GMP_NUM(gmpnum_s); - INIT_GMP_NUM(gmpnum_t); + array_init(return_value); + add_assoc_zval(return_value, "g", gmp_create(&gmpnum_g TSRMLS_CC)); + add_assoc_zval(return_value, "s", gmp_create(&gmpnum_s TSRMLS_CC)); + add_assoc_zval(return_value, "t", gmp_create(&gmpnum_t TSRMLS_CC)); - mpz_gcdext(*gmpnum_g, *gmpnum_s, *gmpnum_t, *gmpnum_a, *gmpnum_b); + mpz_gcdext(gmpnum_g, gmpnum_s, gmpnum_t, gmpnum_a, gmpnum_b); FREE_GMP_TEMP(temp_a); FREE_GMP_TEMP(temp_b); - - array_init(return_value); - - ZEND_REGISTER_RESOURCE(&r, gmpnum_g, le_gmp); - add_assoc_resource(return_value, "g", Z_LVAL(r)); - ZEND_REGISTER_RESOURCE(&r, gmpnum_s, le_gmp); - add_assoc_resource(return_value, "s", Z_LVAL(r)); - ZEND_REGISTER_RESOURCE(&r, gmpnum_t, le_gmp); - add_assoc_resource(return_value, "t", Z_LVAL(r)); } /* }}} */ -/* {{{ proto resource gmp_invert(resource a, resource b) +/* {{{ proto GMP gmp_invert(mixed a, mixed b) Computes the inverse of a modulo b */ ZEND_FUNCTION(gmp_invert) { - zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result; - int temp_a, temp_b; + zval *a_arg, *b_arg; + mpz_ptr gmpnum_a, gmpnum_b, gmpnum_result; + gmp_temp_t temp_a, temp_b; int res; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - INIT_GMP_NUM(gmpnum_result); - res=mpz_invert(*gmpnum_result, *gmpnum_a, *gmpnum_b); + INIT_GMP_RETVAL(gmpnum_result); + res = mpz_invert(gmpnum_result, gmpnum_a, gmpnum_b); FREE_GMP_TEMP(temp_a); FREE_GMP_TEMP(temp_b); - if (res) { - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); - } else { - FREE_GMP_NUM(gmpnum_result); + if (!res) { + zval_dtor(return_value); RETURN_FALSE; } } /* }}} */ -/* {{{ proto int gmp_jacobi(resource a, resource b) +/* {{{ proto int gmp_jacobi(mixed a, mixed b) Computes Jacobi symbol */ ZEND_FUNCTION(gmp_jacobi) { @@ -1300,7 +1639,7 @@ ZEND_FUNCTION(gmp_jacobi) } /* }}} */ -/* {{{ proto int gmp_legendre(resource a, resource b) +/* {{{ proto int gmp_legendre(mixed a, mixed b) Computes Legendre symbol */ ZEND_FUNCTION(gmp_legendre) { @@ -1308,70 +1647,51 @@ ZEND_FUNCTION(gmp_legendre) } /* }}} */ -/* {{{ proto int gmp_cmp(resource a, resource b) +/* {{{ proto int gmp_cmp(mixed a, mixed b) Compares two numbers */ ZEND_FUNCTION(gmp_cmp) { - zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b; - int use_si = 0, res; - int temp_a, temp_b; + zval *a_arg, *b_arg; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - - if (Z_TYPE_PP(b_arg) == IS_LONG) { - use_si = 1; - } else { - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); - } - - if (use_si) { - res = mpz_cmp_si(*gmpnum_a, Z_LVAL_PP(b_arg)); - } else { - res = mpz_cmp(*gmpnum_a, *gmpnum_b); - FREE_GMP_TEMP(temp_b); - } - FREE_GMP_TEMP(temp_a); - - RETURN_LONG(res); + gmp_cmp(return_value, a_arg, b_arg TSRMLS_CC); } /* }}} */ -/* {{{ proto int gmp_sign(resource a) +/* {{{ proto int gmp_sign(mixed a) Gets the sign of the number */ ZEND_FUNCTION(gmp_sign) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - RETVAL_LONG(mpz_sgn(*gmpnum_a)); + RETVAL_LONG(mpz_sgn(gmpnum_a)); FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto resource gmp_random([int limiter]) +/* {{{ proto GMP gmp_random([int limiter]) Gets random number */ ZEND_FUNCTION(gmp_random) { long limiter = 20; - mpz_t *gmpnum_result; + mpz_ptr gmpnum_result; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &limiter) == FAILURE) { return; } - INIT_GMP_NUM(gmpnum_result); + INIT_GMP_RETVAL(gmpnum_result); if (!GMPG(rand_initialized)) { /* Initialize */ @@ -1383,15 +1703,14 @@ ZEND_FUNCTION(gmp_random) GMPG(rand_initialized) = 1; } #ifdef GMP_LIMB_BITS - mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * GMP_LIMB_BITS); + mpz_urandomb(gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * GMP_LIMB_BITS); #else - mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * __GMP_BITS_PER_MP_LIMB); + mpz_urandomb(gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * __GMP_BITS_PER_MP_LIMB); #endif - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); } /* }}} */ -/* {{{ proto resource gmp_and(resource a, resource b) +/* {{{ proto GMP gmp_and(mixed a, mixed b) Calculates logical AND of a and b */ ZEND_FUNCTION(gmp_and) { @@ -1399,7 +1718,7 @@ ZEND_FUNCTION(gmp_and) } /* }}} */ -/* {{{ proto resource gmp_or(resource a, resource b) +/* {{{ proto GMP gmp_or(mixed a, mixed b) Calculates logical OR of a and b */ ZEND_FUNCTION(gmp_or) { @@ -1407,7 +1726,7 @@ ZEND_FUNCTION(gmp_or) } /* }}} */ -/* {{{ proto resource gmp_com(resource a) +/* {{{ proto GMP gmp_com(mixed a) Calculates one's complement of a */ ZEND_FUNCTION(gmp_com) { @@ -1415,7 +1734,7 @@ ZEND_FUNCTION(gmp_com) } /* }}} */ -/* {{{ proto resource gmp_nextprime(resource a) +/* {{{ proto GMP gmp_nextprime(mixed a) Finds next prime of a */ ZEND_FUNCTION(gmp_nextprime) { @@ -1423,21 +1742,22 @@ ZEND_FUNCTION(gmp_nextprime) } /* }}} */ -/* {{{ proto resource gmp_xor(resource a, resource b) +/* {{{ proto GMP gmp_xor(mixed a, mixed b) Calculates logical exclusive OR of a and b */ ZEND_FUNCTION(gmp_xor) { - /* use formula: a^b = (a|b)&^(a&b) */ - zval **a_arg, **b_arg; + gmp_binary_op(mpz_xor); + /* use formula: a^b = (a|b)&~(a&b) */ + /*zval **a_arg, **b_arg; mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result, *gmpnum_t; - int temp_a, temp_b; + gmp_temp_t temp_a, temp_b; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); INIT_GMP_NUM(gmpnum_result); INIT_GMP_NUM(gmpnum_t); @@ -1452,183 +1772,169 @@ ZEND_FUNCTION(gmp_xor) FREE_GMP_TEMP(temp_a); FREE_GMP_TEMP(temp_b); - ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp); + RETVAL_GMP(gmpnum_result);*/ } /* }}} */ -/* {{{ proto void gmp_setbit(resource &a, int index[, bool set_clear]) +/* {{{ proto void gmp_setbit(GMP &a, int index[, bool set_clear]) Sets or clear bit in a */ ZEND_FUNCTION(gmp_setbit) { - zval **a_arg; + zval *a_arg; long index; zend_bool set = 1; - mpz_t *gmpnum_a; + mpz_ptr gmpnum_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl|b", &a_arg, &index, &set) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol|b", &a_arg, gmp_ce, &index, &set) == FAILURE) { return; } - ZEND_FETCH_RESOURCE(gmpnum_a, mpz_t *, a_arg, -1, GMP_RESOURCE_NAME, le_gmp); - if (index < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Index must be greater than or equal to zero"); return; } + gmpnum_a = GET_GMP_FROM_ZVAL(a_arg); + if (set) { - mpz_setbit(*gmpnum_a, index); + mpz_setbit(gmpnum_a, index); } else { - mpz_clrbit(*gmpnum_a, index); + mpz_clrbit(gmpnum_a, index); } } /* }}} */ -/* {{{ proto void gmp_clrbit(resource &a, int index) +/* {{{ proto void gmp_clrbit(GMP &a, int index) Clears bit in a */ ZEND_FUNCTION(gmp_clrbit) { - zval **a_arg; + zval *a_arg; long index; - mpz_t *gmpnum_a; + mpz_ptr gmpnum_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &a_arg, &index) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &a_arg, gmp_ce, &index) == FAILURE){ return; } - ZEND_FETCH_RESOURCE(gmpnum_a, mpz_t *, a_arg, -1, GMP_RESOURCE_NAME, le_gmp); - if (index < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Index must be greater than or equal to zero"); return; } - mpz_clrbit(*gmpnum_a, index); + gmpnum_a = GET_GMP_FROM_ZVAL(a_arg); + mpz_clrbit(gmpnum_a, index); } /* }}} */ -/* {{{ proto bool gmp_testbit(resource a, int index) +/* {{{ proto bool gmp_testbit(mixed a, int index) Tests if bit is set in a */ ZEND_FUNCTION(gmp_testbit) { - zval **a_arg; + zval *a_arg; long index; - mpz_t *gmpnum_a; + mpz_ptr gmpnum_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &a_arg, &index) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, &index) == FAILURE){ return; } - ZEND_FETCH_RESOURCE(gmpnum_a, mpz_t *, a_arg, -1, GMP_RESOURCE_NAME, le_gmp); - if (index < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Index must be greater than or equal to zero"); RETURN_FALSE; } - if (mpz_tstbit(*gmpnum_a, index)) { - RETURN_TRUE; - } - RETURN_FALSE; + gmpnum_a = GET_GMP_FROM_ZVAL(a_arg); + RETURN_BOOL(mpz_tstbit(gmpnum_a, index)); } /* }}} */ -/* {{{ proto int gmp_popcount(resource a) +/* {{{ proto int gmp_popcount(mixed a) Calculates the population count of a */ ZEND_FUNCTION(gmp_popcount) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &a_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - RETVAL_LONG(mpz_popcount(*gmpnum_a)); + RETVAL_LONG(mpz_popcount(gmpnum_a)); FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto int gmp_hamdist(resource a, resource b) +/* {{{ proto int gmp_hamdist(mixed a, mixed b) Calculates hamming distance between a and b */ ZEND_FUNCTION(gmp_hamdist) { - zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b; - int temp_a, temp_b; + zval *a_arg, *b_arg; + mpz_ptr gmpnum_a, gmpnum_b; + gmp_temp_t temp_a, temp_b; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ return; } FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL(gmpnum_b, b_arg, temp_b); + FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - RETVAL_LONG(mpz_hamdist(*gmpnum_a, *gmpnum_b)); + RETVAL_LONG(mpz_hamdist(gmpnum_a, gmpnum_b)); FREE_GMP_TEMP(temp_a); FREE_GMP_TEMP(temp_b); } /* }}} */ -/* {{{ proto int gmp_scan0(resource a, int start) +/* {{{ proto int gmp_scan0(mixed a, int start) Finds first zero bit */ ZEND_FUNCTION(gmp_scan0) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; long start; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &a_arg, &start) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, &start) == FAILURE){ return; } - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - if (start < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Starting index must be greater than or equal to zero"); RETURN_FALSE; } - RETVAL_LONG(mpz_scan0(*gmpnum_a, start)); + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); + + RETVAL_LONG(mpz_scan0(gmpnum_a, start)); FREE_GMP_TEMP(temp_a); } /* }}} */ -/* {{{ proto int gmp_scan1(resource a, int start) +/* {{{ proto int gmp_scan1(mixed a, int start) Finds first non-zero bit */ ZEND_FUNCTION(gmp_scan1) { - zval **a_arg; - mpz_t *gmpnum_a; - int temp_a; + zval *a_arg; + mpz_ptr gmpnum_a; + gmp_temp_t temp_a; long start; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &a_arg, &start) == FAILURE){ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, &start) == FAILURE){ return; } - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); if (start < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Starting index must be greater than or equal to zero"); RETURN_FALSE; } - RETVAL_LONG(mpz_scan1(*gmpnum_a, start)); - FREE_GMP_TEMP(temp_a); -} -/* }}} */ - -/* {{{ _php_gmpnum_free - */ -static void _php_gmpnum_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - mpz_t *gmpnum = (mpz_t *)rsrc->ptr; + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FREE_GMP_NUM(gmpnum); + RETVAL_LONG(mpz_scan1(gmpnum_a, start)); + FREE_GMP_TEMP(temp_a); } /* }}} */ diff --git a/ext/gmp/tests/004.phpt b/ext/gmp/tests/004.phpt index a0fa1cd133c91..088dd08fd8ee4 100644 --- a/ext/gmp/tests/004.phpt +++ b/ext/gmp/tests/004.phpt @@ -38,8 +38,6 @@ int(2342344) Notice: Object of class stdClass could not be converted to int in %s on line %d int(1) int(0) - -Warning: gmp_intval(): supplied resource is not a valid GMP integer resource in %s on line %d -bool(false) +int(%d) int(12345678) Done diff --git a/ext/gmp/tests/005.phpt b/ext/gmp/tests/005.phpt index 7907ffbf53e94..4ae0cb750a415 100644 --- a/ext/gmp/tests/005.phpt +++ b/ext/gmp/tests/005.phpt @@ -47,7 +47,7 @@ bool(false) Warning: gmp_strval() expects parameter 2 to be long, string given in %s on line %d NULL -Warning: gmp_strval(): supplied resource is not a valid GMP integer resource in %s on line %d +Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) string(7) "9765456" diff --git a/ext/gmp/tests/006.phpt b/ext/gmp/tests/006.phpt index dedbcd04726a6..740760631d4e6 100644 --- a/ext/gmp/tests/006.phpt +++ b/ext/gmp/tests/006.phpt @@ -35,9 +35,15 @@ NULL Warning: gmp_sub(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(2) "-1" +} string(2) "-1" -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(5) "10001" +} string(5) "10001" Warning: gmp_sub(): Unable to convert variable to GMP - wrong type in %s on line %d diff --git a/ext/gmp/tests/007.phpt b/ext/gmp/tests/007.phpt index 4d4a993a1729a..e391c121f8d1d 100644 --- a/ext/gmp/tests/007.phpt +++ b/ext/gmp/tests/007.phpt @@ -8,34 +8,16 @@ gmp_div_qr() tests var_dump(gmp_div_qr()); var_dump(gmp_div_qr("")); -var_dump($r = gmp_div_qr(0,1)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1,0)); -var_dump($r = gmp_div_qr(12653,23482734)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(12653,23482734, 10)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123, 1)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123, 2)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123, GMP_ROUND_ZERO)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123, GMP_ROUND_PLUSINF)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); -var_dump($r = gmp_div_qr(1123123,123, GMP_ROUND_MINUSINF)); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); +var_dump(gmp_div_qr(0,1)); +var_dump(gmp_div_qr(1,0)); +var_dump(gmp_div_qr(12653,23482734)); +var_dump(gmp_div_qr(12653,23482734, 10)); +var_dump(gmp_div_qr(1123123,123)); +var_dump(gmp_div_qr(1123123,123, 1)); +var_dump(gmp_div_qr(1123123,123, 2)); +var_dump(gmp_div_qr(1123123,123, GMP_ROUND_ZERO)); +var_dump(gmp_div_qr(1123123,123, GMP_ROUND_PLUSINF)); +var_dump(gmp_div_qr(1123123,123, GMP_ROUND_MINUSINF)); $fp = fopen(__FILE__, 'r'); @@ -52,80 +34,108 @@ Warning: gmp_div_qr() expects at least 2 parameters, 1 given in %s on line %d NULL array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(1) "0" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(1) "0" + } } -string(1) "0" -string(1) "0" Warning: gmp_div_qr(): Zero operand not allowed in %s on line %d bool(false) array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(1) "0" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(5) "12653" + } } -string(1) "0" -string(5) "12653" -NULL - -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d -bool(false) -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d +Warning: gmp_div_qr(): Invalid rounding mode in %s on line %d bool(false) array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(2) "10" + } } -string(4) "9131" -string(2) "10" array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9132" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "-113" + } } -string(4) "9132" -string(4) "-113" array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(2) "10" + } } -string(4) "9131" -string(2) "10" array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(2) "10" + } } -string(4) "9131" -string(2) "10" array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9132" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "-113" + } } -string(4) "9132" -string(4) "-113" array(2) { [0]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" + } [1]=> - resource(%d) of type (GMP integer) + object(GMP)#%d (1) { + ["num"]=> + string(2) "10" + } } -string(4) "9131" -string(2) "10" -Warning: gmp_div_qr(): supplied resource is not a valid GMP integer resource in %s on line %d +Warning: gmp_div_qr(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) Warning: gmp_div_qr(): Unable to convert variable to GMP - wrong type in %s on line %d diff --git a/ext/gmp/tests/008.phpt b/ext/gmp/tests/008.phpt index 4e44ec10bf884..c1874c86f901f 100644 --- a/ext/gmp/tests/008.phpt +++ b/ext/gmp/tests/008.phpt @@ -9,24 +9,15 @@ var_dump(gmp_div_r()); var_dump(gmp_div_r("")); var_dump($r = gmp_div_r(0,1)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1,0)); var_dump($r = gmp_div_r(12653,23482734)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(12653,23482734, 10)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123, 1)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123, 2)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123, GMP_ROUND_ZERO)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123, GMP_ROUND_PLUSINF)); -var_dump(gmp_strval($r)); var_dump($r = gmp_div_r(1123123,123, GMP_ROUND_MINUSINF)); -var_dump(gmp_strval($r)); $fp = fopen(__FILE__, 'r'); @@ -41,31 +32,46 @@ NULL Warning: gmp_div_r() expects at least 2 parameters, 1 given in %s on line %d NULL -int(0) -string(1) "0" +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} Warning: gmp_div_r(): Zero operand not allowed in %s on line %d bool(false) -int(12653) -string(5) "12653" -NULL +object(GMP)#%d (1) { + ["num"]=> + string(5) "12653" +} -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d +Warning: gmp_div_r(): Invalid rounding mode in %s on line %d bool(false) -int(10) -string(2) "10" -int(113) -string(3) "113" -int(10) -string(2) "10" -int(10) -string(2) "10" -int(113) -string(3) "113" -int(10) -string(2) "10" +object(GMP)#%d (1) { + ["num"]=> + string(2) "10" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "-113" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "10" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "10" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "-113" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "10" +} -Warning: gmp_div_r(): supplied resource is not a valid GMP integer resource in %s on line %d +Warning: gmp_div_r(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) Warning: gmp_div_r(): Unable to convert variable to GMP - wrong type in %s on line %d diff --git a/ext/gmp/tests/009.phpt b/ext/gmp/tests/009.phpt index 745a4ef638419..3b75a48e1825b 100644 --- a/ext/gmp/tests/009.phpt +++ b/ext/gmp/tests/009.phpt @@ -8,25 +8,16 @@ gmp_div_q() tests var_dump(gmp_div_q()); var_dump(gmp_div_q("")); -var_dump($r = gmp_div_q(0,1)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1,0)); -var_dump($r = gmp_div_q(12653,23482734)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(12653,23482734, 10)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123, 1)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123, 2)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123, GMP_ROUND_ZERO)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123, GMP_ROUND_PLUSINF)); -var_dump(gmp_strval($r)); -var_dump($r = gmp_div_q(1123123,123, GMP_ROUND_MINUSINF)); -var_dump(gmp_strval($r)); +var_dump(gmp_div_q(0,1)); +var_dump(gmp_div_q(1,0)); +var_dump(gmp_div_q(12653,23482734)); +var_dump(gmp_div_q(12653,23482734, 10)); +var_dump(gmp_div_q(1123123,123)); +var_dump(gmp_div_q(1123123,123, 1)); +var_dump(gmp_div_q(1123123,123, 2)); +var_dump(gmp_div_q(1123123,123, GMP_ROUND_ZERO)); +var_dump(gmp_div_q(1123123,123, GMP_ROUND_PLUSINF)); +var_dump(gmp_div_q(1123123,123, GMP_ROUND_MINUSINF)); $fp = fopen(__FILE__, 'r'); @@ -41,31 +32,46 @@ NULL Warning: gmp_div_q() expects at least 2 parameters, 1 given in %s on line %d NULL -resource(%d) of type (GMP integer) -string(1) "0" +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} Warning: gmp_div_q(): Zero operand not allowed in %s on line %d bool(false) -resource(%d) of type (GMP integer) -string(1) "0" -NULL +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d +Warning: gmp_div_q(): Invalid rounding mode %s on line %d bool(false) -resource(%d) of type (GMP integer) -string(4) "9131" -resource(%d) of type (GMP integer) -string(4) "9132" -resource(%d) of type (GMP integer) -string(4) "9131" -resource(%d) of type (GMP integer) -string(4) "9131" -resource(%d) of type (GMP integer) -string(4) "9132" -resource(%d) of type (GMP integer) -string(4) "9131" +object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "9132" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "9132" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "9131" +} -Warning: gmp_div_q(): supplied resource is not a valid GMP integer resource in %s on line %d +Warning: gmp_div_q(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) Warning: gmp_div_q(): Unable to convert variable to GMP - wrong type in %s on line %d diff --git a/ext/gmp/tests/010.phpt b/ext/gmp/tests/010.phpt index 293a2a0bf20ce..e3f85ec44f1ec 100644 --- a/ext/gmp/tests/010.phpt +++ b/ext/gmp/tests/010.phpt @@ -28,13 +28,22 @@ NULL Warning: gmp_mod() expects exactly 2 parameters, 1 given in %s on line %d NULL bool(false) -int(0) -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} Warning: gmp_mod(): Zero operand not allowed in %s on line %d bool(false) Warning: gmp_mod(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(5) "31161" +} Done diff --git a/ext/gmp/tests/014.phpt b/ext/gmp/tests/014.phpt index 40e10c6fbe031..6afccaf936cc0 100644 --- a/ext/gmp/tests/014.phpt +++ b/ext/gmp/tests/014.phpt @@ -43,7 +43,7 @@ string(19) "2432902008176640000" string(65) "30414093201713378043612608166064768844377641568960512000000000000" string(7) "3628800" string(1) "1" -string(11) "87178291200" +string(9) "479001600" Warning: gmp_fact(): Number has to be greater than or equal to 0 in %s on line %d string(1) "0" @@ -53,6 +53,9 @@ NULL Warning: gmp_fact() expects exactly 1 parameter, 2 given in %s on line %d NULL -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(1) "1" +} string(1) "1" Done diff --git a/ext/gmp/tests/016.phpt b/ext/gmp/tests/016.phpt index 44360865ca8ab..8a0b34458fe39 100644 --- a/ext/gmp/tests/016.phpt +++ b/ext/gmp/tests/016.phpt @@ -69,5 +69,8 @@ NULL Warning: gmp_powm(): Second parameter cannot be less than 0 in %s on line %d bool(false) -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(1) "1" +} Done diff --git a/ext/gmp/tests/033.phpt b/ext/gmp/tests/033.phpt index 38ff5be5bf947..99848959d52df 100644 --- a/ext/gmp/tests/033.phpt +++ b/ext/gmp/tests/033.phpt @@ -52,13 +52,13 @@ string(12) "100008388608" string(12) "100000000000" string(12) "100000000008" -Warning: gmp_setbit(): supplied argument is not a valid GMP integer resource in %s on line %d +Warning: gmp_setbit() expects parameter 1 to be GMP, string given in %s on line %d Warning: gmp_setbit() expects at least 2 parameters, 1 given in %s on line %d Warning: gmp_setbit() expects at most 3 parameters, 4 given in %s on line %d -Warning: gmp_setbit() expects parameter 2 to be long, array given in %s on line %d +Warning: gmp_setbit() expects parameter 1 to be GMP, string given in %s on line %d -Warning: gmp_setbit() expects parameter 2 to be long, array given in %s on line %d +Warning: gmp_setbit() expects parameter 1 to be GMP, array given in %s on line %d Done diff --git a/ext/gmp/tests/034.phpt b/ext/gmp/tests/034.phpt index 6011029905579..079d5d669f37b 100644 --- a/ext/gmp/tests/034.phpt +++ b/ext/gmp/tests/034.phpt @@ -46,7 +46,7 @@ string(7) "1000000" string(7) "1000000" string(30) "238462734628347239571822592658" -Warning: gmp_clrbit(): supplied argument is not a valid GMP integer resource in %s on line %d +Warning: gmp_clrbit() expects parameter 1 to be GMP, array given in %s on line %d Warning: gmp_clrbit() expects exactly 2 parameters, 3 given in %s on line %d diff --git a/ext/gmp/tests/040.phpt b/ext/gmp/tests/040.phpt index 3af18cce59aaf..9cc497edc6c1d 100644 --- a/ext/gmp/tests/040.phpt +++ b/ext/gmp/tests/040.phpt @@ -18,7 +18,10 @@ var_dump(gmp_strval(gmp_init("993247326237679187178",3))); echo "Done\n"; ?> --EXPECTF-- -resource(%d) of type (GMP integer) +object(GMP)#%d (1) { + ["num"]=> + string(8) "98765678" +} string(8) "98765678" Warning: gmp_init() expects at least 1 parameter, 0 given in %s on line %d diff --git a/ext/gmp/tests/bug659967.phpt b/ext/gmp/tests/bug659967.phpt new file mode 100644 index 0000000000000..6ba220274c4f7 --- /dev/null +++ b/ext/gmp/tests/bug659967.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #65997: Leak when using gc_collect_cycles with new GMP implementation +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/gmp/tests/cast.phpt b/ext/gmp/tests/cast.phpt new file mode 100644 index 0000000000000..eb1832c4dd918 --- /dev/null +++ b/ext/gmp/tests/cast.phpt @@ -0,0 +1,22 @@ +--TEST-- +GMP casting using casting operators +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +42 +string(2) "42" +int(42) +float(42) + +Catchable fatal error: Object of class GMP could not be converted to boolean in %s on line %d diff --git a/ext/gmp/tests/clone.phpt b/ext/gmp/tests/clone.phpt new file mode 100644 index 0000000000000..56b5ca3dfeeee --- /dev/null +++ b/ext/gmp/tests/clone.phpt @@ -0,0 +1,22 @@ +--TEST-- +Cloning GMP instances +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +object(GMP)#1 (1) { + ["num"]=> + string(1) "2" +} +object(GMP)#2 (1) { + ["num"]=> + string(1) "3" +} diff --git a/ext/gmp/tests/comparison.phpt b/ext/gmp/tests/comparison.phpt new file mode 100644 index 0000000000000..1f3a423267ee6 --- /dev/null +++ b/ext/gmp/tests/comparison.phpt @@ -0,0 +1,37 @@ +--TEST-- +Overloaded GMP comparison in sort() etc +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + int(-3) + [1]=> + object(GMP)#1 (1) { + ["num"]=> + string(1) "0" + } + [2]=> + int(1) + [3]=> + object(GMP)#2 (1) { + ["num"]=> + string(1) "2" + } +} +object(GMP)#3 (1) { + ["num"]=> + string(1) "3" +} +int(4) diff --git a/ext/gmp/tests/overloading.phpt b/ext/gmp/tests/overloading.phpt new file mode 100644 index 0000000000000..18e0bb2aa9df9 --- /dev/null +++ b/ext/gmp/tests/overloading.phpt @@ -0,0 +1,259 @@ +--TEST-- +GMP operator overloading +--SKIPIF-- + +--FILE-- +> 2); +var_dump(-$a >> 2); + +var_dump(~$a); +var_dump(-$a); +var_dump(+$a); + +var_dump($a == $b); +var_dump($a != $b); +var_dump($a < $b); +var_dump($a <= $b); +var_dump($a > $b); +var_dump($a >= $b); + +var_dump($a == $a); +var_dump($a != $a); + +var_dump($a == 42); +var_dump($a != 42); +var_dump($a < 42); +var_dump($a <= 42); +var_dump($a > 42); +var_dump($a >= 42); + +var_dump($a == new stdClass); + +$a += 1; +var_dump($a); +$a -= 1; +var_dump($a); + +var_dump(++$a); +var_dump($a++); +var_dump($a); + +var_dump(--$a); +var_dump($a--); +var_dump($a); + +?> +--EXPECTF-- +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "25" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "25" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "25" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "2" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "2" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "2" +} + +Warning: main(): Zero operand not allowed in %s on line %d +bool(false) +object(GMP)#%d (1) { + ["num"]=> + string(1) "8" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "8" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "8" +} + +Warning: main(): Zero operand not allowed in %s on line %d +bool(false) +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#%d (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "59" +} +object(GMP)#%d (1) { + ["num"]=> + string(7) "5505024" +} +object(GMP)#%d (1) { + ["num"]=> + string(7) "5505024" +} +object(GMP)#%d (1) { + ["num"]=> + string(7) "5505024" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "10" +} +object(GMP)#%d (1) { + ["num"]=> + string(3) "-11" +} +object(GMP)#%d (1) { + ["num"]=> + string(3) "-43" +} +object(GMP)#%d (1) { + ["num"]=> + string(3) "-42" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "42" +} +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) + +Warning: main(): Unable to convert variable to GMP - wrong type in %s on line %d +bool(false) +object(GMP)#%d (1) { + ["num"]=> + string(2) "43" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "42" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "43" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "43" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "44" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "43" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "43" +} +object(GMP)#%d (1) { + ["num"]=> + string(2) "42" +} + diff --git a/ext/gmp/tests/serialize.phpt b/ext/gmp/tests/serialize.phpt new file mode 100644 index 0000000000000..208e0e98001e7 --- /dev/null +++ b/ext/gmp/tests/serialize.phpt @@ -0,0 +1,42 @@ +--TEST-- +GMP serialization and unserialization +--SKIPIF-- + +--FILE-- +foo = "bar"; +var_dump(unserialize(serialize($n))); + +try { + unserialize('C:3:"GMP":0:{}'); +} catch (Exception $e) { var_dump($e->getMessage()); } + +try { + unserialize('C:3:"GMP":8:{s:2:"42"}'); +} catch (Exception $e) { var_dump($e->getMessage()); } + +?> +--EXPECTF-- +object(GMP)#%d (1) { + ["num"]=> + string(2) "42" +} +string(30) "C:3:"GMP":15:{s:2:"42";a:0:{}}" +object(GMP)#%d (1) { + ["num"]=> + string(2) "42" +} +object(GMP)#%d (2) { + ["foo"]=> + string(3) "bar" + ["num"]=> + string(2) "13" +} +string(28) "Could not unserialize number" +string(32) "Could not unserialize properties" diff --git a/ext/hash/config.m4 b/ext/hash/config.m4 index 44c6d267bc4b1..5174db3b71fa9 100644 --- a/ext/hash/config.m4 +++ b/ext/hash/config.m4 @@ -31,7 +31,7 @@ if test "$PHP_HASH" != "no"; then EXT_HASH_HEADERS="php_hash.h php_hash_md.h php_hash_sha.h php_hash_ripemd.h \ php_hash_haval.h php_hash_tiger.h php_hash_gost.h php_hash_snefru.h \ php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h \ - php_hash_fnv.h php_hash_joaat.h php_hash_types.h" + php_hash_fnv.h php_hash_joaat.h" PHP_NEW_EXTENSION(hash, $EXT_HASH_SOURCES, $ext_shared) ifdef([PHP_INSTALL_HEADERS], [ diff --git a/ext/hash/config.w32 b/ext/hash/config.w32 index abe8675f30639..8e9d4c3d48c9d 100644 --- a/ext/hash/config.w32 +++ b/ext/hash/config.w32 @@ -19,7 +19,6 @@ if (PHP_HASH != "no") { PHP_INSTALL_HEADERS("ext/hash/", "php_hash.h php_hash_md.h php_hash_sha.h php_hash_ripemd.h " + "php_hash_haval.h php_hash_tiger.h php_hash_gost.h php_hash_snefru.h " + - "php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h " + - "php_hash_types.h"); + "php_hash_whirlpool.h php_hash_adler32.h php_hash_crc32.h"); } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 117221484e363..87f19c5cacb1e 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -986,6 +986,7 @@ PHP_MINIT_FUNCTION(hash) php_hash_register_algo("snefru", &php_hash_snefru_ops); php_hash_register_algo("snefru256", &php_hash_snefru_ops); php_hash_register_algo("gost", &php_hash_gost_ops); + php_hash_register_algo("gost-crypto", &php_hash_gost_crypto_ops); php_hash_register_algo("adler32", &php_hash_adler32_ops); php_hash_register_algo("crc32", &php_hash_crc32_ops); php_hash_register_algo("crc32b", &php_hash_crc32b_ops); diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 3961c4f2d5c36..da65bb5903e62 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -27,7 +27,7 @@ * derived from gost_compress() by Markku-Juhani Saarinen */ -#define round(k1, k2) \ +#define round(tables, k1, k2) \ t = (k1) + r; \ l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \ tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \ @@ -35,25 +35,25 @@ r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \ tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; -#define R(key, h, i, t, l, r) \ +#define R(tables, key, h, i, t, l, r) \ r = h[i]; \ l = h[i + 1]; \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[7], key[6]) \ - round(key[5], key[4]) \ - round(key[3], key[2]) \ - round(key[1], key[0]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[7], key[6]) \ + round(tables, key[5], key[4]) \ + round(tables, key[3], key[2]) \ + round(tables, key[1], key[0]) \ t = r; \ r = l; \ l = t; \ @@ -194,10 +194,10 @@ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7]; -#define PASS \ +#define PASS(tables) \ X(w, u, v); \ P(key, w); \ - R(key, h, i, t, l, r); \ + R((tables), key, h, i, t, l, r); \ S(s, l, r); \ if (i != 6) { \ A(u, l, r); \ @@ -207,16 +207,16 @@ AA(v, l, r); \ } -static inline void Gost(php_hash_uint32 state[8], php_hash_uint32 data[8]) +static inline void Gost(PHP_GOST_CTX *context, php_hash_uint32 data[8]) { int i; - php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = state, *m = data; + php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = context->state, *m = data; - memcpy(u, state, sizeof(u)); + memcpy(u, context->state, sizeof(u)); memcpy(v, data, sizeof(v)); for (i = 0; i < 8; i += 2) { - PASS; + PASS(*context->tables); } SHIFT12(u, m, s); SHIFT16(h, v, u); @@ -237,12 +237,19 @@ static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char inpu temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0; } - Gost(context->state, data); + Gost(context, data); } PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context) { memset(context, 0, sizeof(*context)); + context->tables = &tables_test; +} + +PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context) +{ + PHP_GOSTInit(context); + context->tables = &tables_crypto; } static const php_hash_uint32 MAX32 = 0xffffffffLU; @@ -288,9 +295,9 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context) } memcpy(l, context->count, sizeof(context->count)); - Gost(context->state, l); + Gost(context, l); memcpy(l, &context->state[8], sizeof(l)); - Gost(context->state, l); + Gost(context, l); for (i = 0, j = 0; j < 32; i++, j += 4) { digest[j] = (unsigned char) (context->state[i] & 0xff); @@ -312,6 +319,16 @@ const php_hash_ops php_hash_gost_ops = { sizeof(PHP_GOST_CTX) }; +const php_hash_ops php_hash_gost_crypto_ops = { + (php_hash_init_func_t) PHP_GOSTInitCrypto, + (php_hash_update_func_t) PHP_GOSTUpdate, + (php_hash_final_func_t) PHP_GOSTFinal, + (php_hash_copy_func_t) php_hash_copy, + 32, + 32, + sizeof(PHP_GOST_CTX) +}; + /* * Local variables: * tab-width: 4 diff --git a/ext/hash/package.xml b/ext/hash/package.xml index 119cdd673daa8..25a598a4a1522 100644 --- a/ext/hash/package.xml +++ b/ext/hash/package.xml @@ -42,7 +42,6 @@ Supported Algorithms: - diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 4bfddbacd9c45..e92572216aea4 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -22,7 +22,6 @@ #define PHP_HASH_H #include "php.h" -#include "php_hash_types.h" #define PHP_HASH_EXTNAME "hash" #define PHP_HASH_EXTVER "1.0" @@ -30,6 +29,12 @@ #define PHP_HASH_HMAC 0x0001 +#define L64 INT64_C +#define php_hash_int32 int32_t +#define php_hash_uint32 uint32_t +#define php_hash_int64 int64_t +#define php_hash_uint64 uint64_t + typedef void (*php_hash_init_func_t)(void *context); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, unsigned int count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); @@ -75,6 +80,7 @@ extern const php_hash_ops php_hash_4tiger160_ops; extern const php_hash_ops php_hash_4tiger192_ops; extern const php_hash_ops php_hash_snefru_ops; extern const php_hash_ops php_hash_gost_ops; +extern const php_hash_ops php_hash_gost_crypto_ops; extern const php_hash_ops php_hash_adler32_ops; extern const php_hash_ops php_hash_crc32_ops; extern const php_hash_ops php_hash_crc32b_ops; diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 6a4af310dc64c..a9c137530c4ae 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -29,6 +29,7 @@ typedef struct { php_hash_uint32 count[2]; unsigned char length; unsigned char buffer[32]; + const php_hash_uint32 (*tables)[4][256]; } PHP_GOST_CTX; PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *); diff --git a/ext/hash/php_hash_gost_tables.h b/ext/hash/php_hash_gost_tables.h index 5d05e593cb13a..a00d8b74907d2 100644 --- a/ext/hash/php_hash_gost_tables.h +++ b/ext/hash/php_hash_gost_tables.h @@ -1,4 +1,4 @@ -static const php_hash_uint32 tables[4][256] = { +static const php_hash_uint32 tables_test[4][256] = { { /* table 1 */ 0x00072000LU, 0x00075000LU, 0x00074800LU, 0x00071000LU, 0x00076800LU, 0x00074000LU, 0x00070000LU, 0x00077000LU, 0x00073000LU, 0x00075800LU, 0x00070800LU, 0x00076000LU, 0x00073800LU, 0x00077800LU, 0x00072800LU, 0x00071800LU, @@ -136,3 +136,142 @@ static const php_hash_uint32 tables[4][256] = { 0x00000600LU, 0x00000650LU, 0x00000670LU, 0x00000638LU, 0x00000630LU, 0x00000640LU, 0x00000610LU, 0x00000660LU, }, }; + +static const php_hash_uint32 tables_crypto[4][256] = { + { /* table 1 */ + 0x0002d000LU, 0x0002a000LU, 0x0002a800LU, 0x0002b000LU, 0x0002c000LU, 0x00028800LU, 0x00029800LU, 0x0002b800LU, + 0x0002e800LU, 0x0002e000LU, 0x0002f000LU, 0x00028000LU, 0x0002c800LU, 0x00029000LU, 0x0002d800LU, 0x0002f800LU, + 0x0007d000LU, 0x0007a000LU, 0x0007a800LU, 0x0007b000LU, 0x0007c000LU, 0x00078800LU, 0x00079800LU, 0x0007b800LU, + 0x0007e800LU, 0x0007e000LU, 0x0007f000LU, 0x00078000LU, 0x0007c800LU, 0x00079000LU, 0x0007d800LU, 0x0007f800LU, + 0x00025000LU, 0x00022000LU, 0x00022800LU, 0x00023000LU, 0x00024000LU, 0x00020800LU, 0x00021800LU, 0x00023800LU, + 0x00026800LU, 0x00026000LU, 0x00027000LU, 0x00020000LU, 0x00024800LU, 0x00021000LU, 0x00025800LU, 0x00027800LU, + 0x00005000LU, 0x00002000LU, 0x00002800LU, 0x00003000LU, 0x00004000LU, 0x00000800LU, 0x00001800LU, 0x00003800LU, + 0x00006800LU, 0x00006000LU, 0x00007000LU, 0x00000000LU, 0x00004800LU, 0x00001000LU, 0x00005800LU, 0x00007800LU, + 0x00015000LU, 0x00012000LU, 0x00012800LU, 0x00013000LU, 0x00014000LU, 0x00010800LU, 0x00011800LU, 0x00013800LU, + 0x00016800LU, 0x00016000LU, 0x00017000LU, 0x00010000LU, 0x00014800LU, 0x00011000LU, 0x00015800LU, 0x00017800LU, + 0x0006d000LU, 0x0006a000LU, 0x0006a800LU, 0x0006b000LU, 0x0006c000LU, 0x00068800LU, 0x00069800LU, 0x0006b800LU, + 0x0006e800LU, 0x0006e000LU, 0x0006f000LU, 0x00068000LU, 0x0006c800LU, 0x00069000LU, 0x0006d800LU, 0x0006f800LU, + 0x0005d000LU, 0x0005a000LU, 0x0005a800LU, 0x0005b000LU, 0x0005c000LU, 0x00058800LU, 0x00059800LU, 0x0005b800LU, + 0x0005e800LU, 0x0005e000LU, 0x0005f000LU, 0x00058000LU, 0x0005c800LU, 0x00059000LU, 0x0005d800LU, 0x0005f800LU, + 0x0004d000LU, 0x0004a000LU, 0x0004a800LU, 0x0004b000LU, 0x0004c000LU, 0x00048800LU, 0x00049800LU, 0x0004b800LU, + 0x0004e800LU, 0x0004e000LU, 0x0004f000LU, 0x00048000LU, 0x0004c800LU, 0x00049000LU, 0x0004d800LU, 0x0004f800LU, + 0x0000d000LU, 0x0000a000LU, 0x0000a800LU, 0x0000b000LU, 0x0000c000LU, 0x00008800LU, 0x00009800LU, 0x0000b800LU, + 0x0000e800LU, 0x0000e000LU, 0x0000f000LU, 0x00008000LU, 0x0000c800LU, 0x00009000LU, 0x0000d800LU, 0x0000f800LU, + 0x0003d000LU, 0x0003a000LU, 0x0003a800LU, 0x0003b000LU, 0x0003c000LU, 0x00038800LU, 0x00039800LU, 0x0003b800LU, + 0x0003e800LU, 0x0003e000LU, 0x0003f000LU, 0x00038000LU, 0x0003c800LU, 0x00039000LU, 0x0003d800LU, 0x0003f800LU, + 0x00035000LU, 0x00032000LU, 0x00032800LU, 0x00033000LU, 0x00034000LU, 0x00030800LU, 0x00031800LU, 0x00033800LU, + 0x00036800LU, 0x00036000LU, 0x00037000LU, 0x00030000LU, 0x00034800LU, 0x00031000LU, 0x00035800LU, 0x00037800LU, + 0x0001d000LU, 0x0001a000LU, 0x0001a800LU, 0x0001b000LU, 0x0001c000LU, 0x00018800LU, 0x00019800LU, 0x0001b800LU, + 0x0001e800LU, 0x0001e000LU, 0x0001f000LU, 0x00018000LU, 0x0001c800LU, 0x00019000LU, 0x0001d800LU, 0x0001f800LU, + 0x00065000LU, 0x00062000LU, 0x00062800LU, 0x00063000LU, 0x00064000LU, 0x00060800LU, 0x00061800LU, 0x00063800LU, + 0x00066800LU, 0x00066000LU, 0x00067000LU, 0x00060000LU, 0x00064800LU, 0x00061000LU, 0x00065800LU, 0x00067800LU, + 0x00075000LU, 0x00072000LU, 0x00072800LU, 0x00073000LU, 0x00074000LU, 0x00070800LU, 0x00071800LU, 0x00073800LU, + 0x00076800LU, 0x00076000LU, 0x00077000LU, 0x00070000LU, 0x00074800LU, 0x00071000LU, 0x00075800LU, 0x00077800LU, + 0x00055000LU, 0x00052000LU, 0x00052800LU, 0x00053000LU, 0x00054000LU, 0x00050800LU, 0x00051800LU, 0x00053800LU, + 0x00056800LU, 0x00056000LU, 0x00057000LU, 0x00050000LU, 0x00054800LU, 0x00051000LU, 0x00055800LU, 0x00057800LU, + 0x00045000LU, 0x00042000LU, 0x00042800LU, 0x00043000LU, 0x00044000LU, 0x00040800LU, 0x00041800LU, 0x00043800LU, + 0x00046800LU, 0x00046000LU, 0x00047000LU, 0x00040000LU, 0x00044800LU, 0x00041000LU, 0x00045800LU, 0x00047800LU, + }, + { /* table 2 */ + 0x02380000LU, 0x02780000LU, 0x02600000LU, 0x02700000LU, 0x02480000LU, 0x02200000LU, 0x02080000LU, 0x02000000LU, + 0x02180000LU, 0x02580000LU, 0x02280000LU, 0x02100000LU, 0x02300000LU, 0x02500000LU, 0x02400000LU, 0x02680000LU, + 0x05380000LU, 0x05780000LU, 0x05600000LU, 0x05700000LU, 0x05480000LU, 0x05200000LU, 0x05080000LU, 0x05000000LU, + 0x05180000LU, 0x05580000LU, 0x05280000LU, 0x05100000LU, 0x05300000LU, 0x05500000LU, 0x05400000LU, 0x05680000LU, + 0x03b80000LU, 0x03f80000LU, 0x03e00000LU, 0x03f00000LU, 0x03c80000LU, 0x03a00000LU, 0x03880000LU, 0x03800000LU, + 0x03980000LU, 0x03d80000LU, 0x03a80000LU, 0x03900000LU, 0x03b00000LU, 0x03d00000LU, 0x03c00000LU, 0x03e80000LU, + 0x06380000LU, 0x06780000LU, 0x06600000LU, 0x06700000LU, 0x06480000LU, 0x06200000LU, 0x06080000LU, 0x06000000LU, + 0x06180000LU, 0x06580000LU, 0x06280000LU, 0x06100000LU, 0x06300000LU, 0x06500000LU, 0x06400000LU, 0x06680000LU, + 0x00380000LU, 0x00780000LU, 0x00600000LU, 0x00700000LU, 0x00480000LU, 0x00200000LU, 0x00080000LU, 0x00000000LU, + 0x00180000LU, 0x00580000LU, 0x00280000LU, 0x00100000LU, 0x00300000LU, 0x00500000LU, 0x00400000LU, 0x00680000LU, + 0x07b80000LU, 0x07f80000LU, 0x07e00000LU, 0x07f00000LU, 0x07c80000LU, 0x07a00000LU, 0x07880000LU, 0x07800000LU, + 0x07980000LU, 0x07d80000LU, 0x07a80000LU, 0x07900000LU, 0x07b00000LU, 0x07d00000LU, 0x07c00000LU, 0x07e80000LU, + 0x01380000LU, 0x01780000LU, 0x01600000LU, 0x01700000LU, 0x01480000LU, 0x01200000LU, 0x01080000LU, 0x01000000LU, + 0x01180000LU, 0x01580000LU, 0x01280000LU, 0x01100000LU, 0x01300000LU, 0x01500000LU, 0x01400000LU, 0x01680000LU, + 0x04380000LU, 0x04780000LU, 0x04600000LU, 0x04700000LU, 0x04480000LU, 0x04200000LU, 0x04080000LU, 0x04000000LU, + 0x04180000LU, 0x04580000LU, 0x04280000LU, 0x04100000LU, 0x04300000LU, 0x04500000LU, 0x04400000LU, 0x04680000LU, + 0x07380000LU, 0x07780000LU, 0x07600000LU, 0x07700000LU, 0x07480000LU, 0x07200000LU, 0x07080000LU, 0x07000000LU, + 0x07180000LU, 0x07580000LU, 0x07280000LU, 0x07100000LU, 0x07300000LU, 0x07500000LU, 0x07400000LU, 0x07680000LU, + 0x00b80000LU, 0x00f80000LU, 0x00e00000LU, 0x00f00000LU, 0x00c80000LU, 0x00a00000LU, 0x00880000LU, 0x00800000LU, + 0x00980000LU, 0x00d80000LU, 0x00a80000LU, 0x00900000LU, 0x00b00000LU, 0x00d00000LU, 0x00c00000LU, 0x00e80000LU, + 0x03380000LU, 0x03780000LU, 0x03600000LU, 0x03700000LU, 0x03480000LU, 0x03200000LU, 0x03080000LU, 0x03000000LU, + 0x03180000LU, 0x03580000LU, 0x03280000LU, 0x03100000LU, 0x03300000LU, 0x03500000LU, 0x03400000LU, 0x03680000LU, + 0x02b80000LU, 0x02f80000LU, 0x02e00000LU, 0x02f00000LU, 0x02c80000LU, 0x02a00000LU, 0x02880000LU, 0x02800000LU, + 0x02980000LU, 0x02d80000LU, 0x02a80000LU, 0x02900000LU, 0x02b00000LU, 0x02d00000LU, 0x02c00000LU, 0x02e80000LU, + 0x06b80000LU, 0x06f80000LU, 0x06e00000LU, 0x06f00000LU, 0x06c80000LU, 0x06a00000LU, 0x06880000LU, 0x06800000LU, + 0x06980000LU, 0x06d80000LU, 0x06a80000LU, 0x06900000LU, 0x06b00000LU, 0x06d00000LU, 0x06c00000LU, 0x06e80000LU, + 0x05b80000LU, 0x05f80000LU, 0x05e00000LU, 0x05f00000LU, 0x05c80000LU, 0x05a00000LU, 0x05880000LU, 0x05800000LU, + 0x05980000LU, 0x05d80000LU, 0x05a80000LU, 0x05900000LU, 0x05b00000LU, 0x05d00000LU, 0x05c00000LU, 0x05e80000LU, + 0x04b80000LU, 0x04f80000LU, 0x04e00000LU, 0x04f00000LU, 0x04c80000LU, 0x04a00000LU, 0x04880000LU, 0x04800000LU, + 0x04980000LU, 0x04d80000LU, 0x04a80000LU, 0x04900000LU, 0x04b00000LU, 0x04d00000LU, 0x04c00000LU, 0x04e80000LU, + 0x01b80000LU, 0x01f80000LU, 0x01e00000LU, 0x01f00000LU, 0x01c80000LU, 0x01a00000LU, 0x01880000LU, 0x01800000LU, + 0x01980000LU, 0x01d80000LU, 0x01a80000LU, 0x01900000LU, 0x01b00000LU, 0x01d00000LU, 0x01c00000LU, 0x01e80000LU, + }, + { /* table 3 */ + 0xb8000003LU, 0xb0000003LU, 0xa0000003LU, 0xd8000003LU, 0xc8000003LU, 0xe0000003LU, 0x90000003LU, 0xd0000003LU, + 0x88000003LU, 0xc0000003LU, 0x80000003LU, 0xf0000003LU, 0xf8000003LU, 0xe8000003LU, 0x98000003LU, 0xa8000003LU, + 0x38000003LU, 0x30000003LU, 0x20000003LU, 0x58000003LU, 0x48000003LU, 0x60000003LU, 0x10000003LU, 0x50000003LU, + 0x08000003LU, 0x40000003LU, 0x00000003LU, 0x70000003LU, 0x78000003LU, 0x68000003LU, 0x18000003LU, 0x28000003LU, + 0x38000001LU, 0x30000001LU, 0x20000001LU, 0x58000001LU, 0x48000001LU, 0x60000001LU, 0x10000001LU, 0x50000001LU, + 0x08000001LU, 0x40000001LU, 0x00000001LU, 0x70000001LU, 0x78000001LU, 0x68000001LU, 0x18000001LU, 0x28000001LU, + 0x38000002LU, 0x30000002LU, 0x20000002LU, 0x58000002LU, 0x48000002LU, 0x60000002LU, 0x10000002LU, 0x50000002LU, + 0x08000002LU, 0x40000002LU, 0x00000002LU, 0x70000002LU, 0x78000002LU, 0x68000002LU, 0x18000002LU, 0x28000002LU, + 0xb8000006LU, 0xb0000006LU, 0xa0000006LU, 0xd8000006LU, 0xc8000006LU, 0xe0000006LU, 0x90000006LU, 0xd0000006LU, + 0x88000006LU, 0xc0000006LU, 0x80000006LU, 0xf0000006LU, 0xf8000006LU, 0xe8000006LU, 0x98000006LU, 0xa8000006LU, + 0xb8000004LU, 0xb0000004LU, 0xa0000004LU, 0xd8000004LU, 0xc8000004LU, 0xe0000004LU, 0x90000004LU, 0xd0000004LU, + 0x88000004LU, 0xc0000004LU, 0x80000004LU, 0xf0000004LU, 0xf8000004LU, 0xe8000004LU, 0x98000004LU, 0xa8000004LU, + 0xb8000007LU, 0xb0000007LU, 0xa0000007LU, 0xd8000007LU, 0xc8000007LU, 0xe0000007LU, 0x90000007LU, 0xd0000007LU, + 0x88000007LU, 0xc0000007LU, 0x80000007LU, 0xf0000007LU, 0xf8000007LU, 0xe8000007LU, 0x98000007LU, 0xa8000007LU, + 0x38000000LU, 0x30000000LU, 0x20000000LU, 0x58000000LU, 0x48000000LU, 0x60000000LU, 0x10000000LU, 0x50000000LU, + 0x08000000LU, 0x40000000LU, 0x00000000LU, 0x70000000LU, 0x78000000LU, 0x68000000LU, 0x18000000LU, 0x28000000LU, + 0x38000005LU, 0x30000005LU, 0x20000005LU, 0x58000005LU, 0x48000005LU, 0x60000005LU, 0x10000005LU, 0x50000005LU, + 0x08000005LU, 0x40000005LU, 0x00000005LU, 0x70000005LU, 0x78000005LU, 0x68000005LU, 0x18000005LU, 0x28000005LU, + 0xb8000000LU, 0xb0000000LU, 0xa0000000LU, 0xd8000000LU, 0xc8000000LU, 0xe0000000LU, 0x90000000LU, 0xd0000000LU, + 0x88000000LU, 0xc0000000LU, 0x80000000LU, 0xf0000000LU, 0xf8000000LU, 0xe8000000LU, 0x98000000LU, 0xa8000000LU, + 0xb8000002LU, 0xb0000002LU, 0xa0000002LU, 0xd8000002LU, 0xc8000002LU, 0xe0000002LU, 0x90000002LU, 0xd0000002LU, + 0x88000002LU, 0xc0000002LU, 0x80000002LU, 0xf0000002LU, 0xf8000002LU, 0xe8000002LU, 0x98000002LU, 0xa8000002LU, + 0xb8000005LU, 0xb0000005LU, 0xa0000005LU, 0xd8000005LU, 0xc8000005LU, 0xe0000005LU, 0x90000005LU, 0xd0000005LU, + 0x88000005LU, 0xc0000005LU, 0x80000005LU, 0xf0000005LU, 0xf8000005LU, 0xe8000005LU, 0x98000005LU, 0xa8000005LU, + 0x38000004LU, 0x30000004LU, 0x20000004LU, 0x58000004LU, 0x48000004LU, 0x60000004LU, 0x10000004LU, 0x50000004LU, + 0x08000004LU, 0x40000004LU, 0x00000004LU, 0x70000004LU, 0x78000004LU, 0x68000004LU, 0x18000004LU, 0x28000004LU, + 0x38000007LU, 0x30000007LU, 0x20000007LU, 0x58000007LU, 0x48000007LU, 0x60000007LU, 0x10000007LU, 0x50000007LU, + 0x08000007LU, 0x40000007LU, 0x00000007LU, 0x70000007LU, 0x78000007LU, 0x68000007LU, 0x18000007LU, 0x28000007LU, + 0x38000006LU, 0x30000006LU, 0x20000006LU, 0x58000006LU, 0x48000006LU, 0x60000006LU, 0x10000006LU, 0x50000006LU, + 0x08000006LU, 0x40000006LU, 0x00000006LU, 0x70000006LU, 0x78000006LU, 0x68000006LU, 0x18000006LU, 0x28000006LU, + 0xb8000001LU, 0xb0000001LU, 0xa0000001LU, 0xd8000001LU, 0xc8000001LU, 0xe0000001LU, 0x90000001LU, 0xd0000001LU, + 0x88000001LU, 0xc0000001LU, 0x80000001LU, 0xf0000001LU, 0xf8000001LU, 0xe8000001LU, 0x98000001LU, 0xa8000001LU, + }, + { /* table 4 */ + 0x000000e8LU, 0x000000f0LU, 0x000000a0LU, 0x00000088LU, 0x000000b8LU, 0x00000080LU, 0x000000a8LU, 0x000000d0LU, + 0x00000098LU, 0x000000e0LU, 0x000000c0LU, 0x000000f8LU, 0x000000b0LU, 0x00000090LU, 0x000000c8LU, 0x000000d8LU, + 0x000001e8LU, 0x000001f0LU, 0x000001a0LU, 0x00000188LU, 0x000001b8LU, 0x00000180LU, 0x000001a8LU, 0x000001d0LU, + 0x00000198LU, 0x000001e0LU, 0x000001c0LU, 0x000001f8LU, 0x000001b0LU, 0x00000190LU, 0x000001c8LU, 0x000001d8LU, + 0x00000568LU, 0x00000570LU, 0x00000520LU, 0x00000508LU, 0x00000538LU, 0x00000500LU, 0x00000528LU, 0x00000550LU, + 0x00000518LU, 0x00000560LU, 0x00000540LU, 0x00000578LU, 0x00000530LU, 0x00000510LU, 0x00000548LU, 0x00000558LU, + 0x000004e8LU, 0x000004f0LU, 0x000004a0LU, 0x00000488LU, 0x000004b8LU, 0x00000480LU, 0x000004a8LU, 0x000004d0LU, + 0x00000498LU, 0x000004e0LU, 0x000004c0LU, 0x000004f8LU, 0x000004b0LU, 0x00000490LU, 0x000004c8LU, 0x000004d8LU, + 0x000002e8LU, 0x000002f0LU, 0x000002a0LU, 0x00000288LU, 0x000002b8LU, 0x00000280LU, 0x000002a8LU, 0x000002d0LU, + 0x00000298LU, 0x000002e0LU, 0x000002c0LU, 0x000002f8LU, 0x000002b0LU, 0x00000290LU, 0x000002c8LU, 0x000002d8LU, + 0x000005e8LU, 0x000005f0LU, 0x000005a0LU, 0x00000588LU, 0x000005b8LU, 0x00000580LU, 0x000005a8LU, 0x000005d0LU, + 0x00000598LU, 0x000005e0LU, 0x000005c0LU, 0x000005f8LU, 0x000005b0LU, 0x00000590LU, 0x000005c8LU, 0x000005d8LU, + 0x00000268LU, 0x00000270LU, 0x00000220LU, 0x00000208LU, 0x00000238LU, 0x00000200LU, 0x00000228LU, 0x00000250LU, + 0x00000218LU, 0x00000260LU, 0x00000240LU, 0x00000278LU, 0x00000230LU, 0x00000210LU, 0x00000248LU, 0x00000258LU, + 0x000007e8LU, 0x000007f0LU, 0x000007a0LU, 0x00000788LU, 0x000007b8LU, 0x00000780LU, 0x000007a8LU, 0x000007d0LU, + 0x00000798LU, 0x000007e0LU, 0x000007c0LU, 0x000007f8LU, 0x000007b0LU, 0x00000790LU, 0x000007c8LU, 0x000007d8LU, + 0x00000468LU, 0x00000470LU, 0x00000420LU, 0x00000408LU, 0x00000438LU, 0x00000400LU, 0x00000428LU, 0x00000450LU, + 0x00000418LU, 0x00000460LU, 0x00000440LU, 0x00000478LU, 0x00000430LU, 0x00000410LU, 0x00000448LU, 0x00000458LU, + 0x00000368LU, 0x00000370LU, 0x00000320LU, 0x00000308LU, 0x00000338LU, 0x00000300LU, 0x00000328LU, 0x00000350LU, + 0x00000318LU, 0x00000360LU, 0x00000340LU, 0x00000378LU, 0x00000330LU, 0x00000310LU, 0x00000348LU, 0x00000358LU, + 0x000003e8LU, 0x000003f0LU, 0x000003a0LU, 0x00000388LU, 0x000003b8LU, 0x00000380LU, 0x000003a8LU, 0x000003d0LU, + 0x00000398LU, 0x000003e0LU, 0x000003c0LU, 0x000003f8LU, 0x000003b0LU, 0x00000390LU, 0x000003c8LU, 0x000003d8LU, + 0x00000768LU, 0x00000770LU, 0x00000720LU, 0x00000708LU, 0x00000738LU, 0x00000700LU, 0x00000728LU, 0x00000750LU, + 0x00000718LU, 0x00000760LU, 0x00000740LU, 0x00000778LU, 0x00000730LU, 0x00000710LU, 0x00000748LU, 0x00000758LU, + 0x000006e8LU, 0x000006f0LU, 0x000006a0LU, 0x00000688LU, 0x000006b8LU, 0x00000680LU, 0x000006a8LU, 0x000006d0LU, + 0x00000698LU, 0x000006e0LU, 0x000006c0LU, 0x000006f8LU, 0x000006b0LU, 0x00000690LU, 0x000006c8LU, 0x000006d8LU, + 0x00000068LU, 0x00000070LU, 0x00000020LU, 0x00000008LU, 0x00000038LU, 0x00000000LU, 0x00000028LU, 0x00000050LU, + 0x00000018LU, 0x00000060LU, 0x00000040LU, 0x00000078LU, 0x00000030LU, 0x00000010LU, 0x00000048LU, 0x00000058LU, + 0x00000168LU, 0x00000170LU, 0x00000120LU, 0x00000108LU, 0x00000138LU, 0x00000100LU, 0x00000128LU, 0x00000150LU, + 0x00000118LU, 0x00000160LU, 0x00000140LU, 0x00000178LU, 0x00000130LU, 0x00000110LU, 0x00000148LU, 0x00000158LU, + 0x00000668LU, 0x00000670LU, 0x00000620LU, 0x00000608LU, 0x00000638LU, 0x00000600LU, 0x00000628LU, 0x00000650LU, + 0x00000618LU, 0x00000660LU, 0x00000640LU, 0x00000678LU, 0x00000630LU, 0x00000610LU, 0x00000648LU, 0x00000658LU, + }, +}; diff --git a/ext/hash/php_hash_types.h b/ext/hash/php_hash_types.h deleted file mode 100644 index 8793da55d6727..0000000000000 --- a/ext/hash/php_hash_types.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 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_01.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: Michael Wallner | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#ifndef PHP_HASH_TYPES_H -#define PHP_HASH_TYPES_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#else -#ifndef PHP_WIN32 -#include "php_config.h" -#endif -#endif - -#ifndef PHP_WIN32 -#if SIZEOF_LONG == 8 -#define L64(x) x -typedef unsigned long php_hash_uint64; -#if SIZEOF_INT == 4 -typedef unsigned int php_hash_uint32; -#elif SIZEOF_SHORT == 4 -typedef unsigned short php_hash_uint32; -#else -#error "Need a 32bit integer type" -#endif -#elif SIZEOF_LONG_LONG == 8 -#define L64(x) x##LL -typedef unsigned long long php_hash_uint64; -#if SIZEOF_INT == 4 -typedef unsigned int php_hash_uint32; -#elif SIZEOF_LONG == 4 -typedef unsigned long php_hash_uint32; -#else -#error "Need a 32bit integer type" -#endif -#else -#error "Need a 64bit integer type" -#endif -#else -#define L64(x) x##i64 -typedef unsigned __int64 php_hash_uint64; -typedef unsigned __int32 php_hash_uint32; -#endif - -#endif - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ diff --git a/ext/hash/tests/gost.phpt b/ext/hash/tests/gost.phpt index b800e112e85c3..6ce00242b1a40 100644 --- a/ext/hash/tests/gost.phpt +++ b/ext/hash/tests/gost.phpt @@ -10,6 +10,13 @@ echo hash('gost', 'The quick brown fox jumps over the lazy cog'), "\n"; echo hash('gost', str_repeat('a', 31)), "\n"; echo hash('gost', str_repeat('a', 32)), "\n"; echo hash('gost', str_repeat('a', 33)), "\n"; + +echo hash('gost-crypto', ''), "\n"; +echo hash('gost-crypto', 'The quick brown fox jumps over the lazy dog'), "\n"; +echo hash('gost-crypto', 'The quick brown fox jumps over the lazy cog'), "\n"; +echo hash('gost-crypto', str_repeat('a', 31)), "\n"; +echo hash('gost-crypto', str_repeat('a', 32)), "\n"; +echo hash('gost-crypto', str_repeat('a', 33)), "\n"; ?> --EXPECT-- ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d @@ -18,3 +25,9 @@ a3ebc4daaab78b0be131dab5737a7f67e602670d543521319150d2e14eeec445 03840d6348763f11e28e7b1ecc4da0cdf7f898fa555b928ef684c6c5b8f46d9f fd1b746d9397e78edd311baef391450434271e02816caa37680d6d7381c79d4e 715e59cdc8ebde9fdf0fe2a2e811b3bf7f48209a01505e467d2cd2aa2bbb5ecf +981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0 +9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76 +a93124f5bf2c6d83c3bbf722bc55569310245ca5957541f4dbd7dfaf8137e6f2 +8978e06b0ecf54ea81ec51ca4e02bcb4eb390b3f04cb5f65ee8de195ffae591b +e121e3740ae94ca6d289e6d653ff31695783efff3dd960417a1098a0130fa720 +d3e8f22d9762a148ddfc84a6043d97a608604dae7c05baee72b55f559d03dd74 diff --git a/ext/hash/tests/hash_algos.phpt b/ext/hash/tests/hash_algos.phpt index 55796ecbce9aa..7773fe979a72d 100644 --- a/ext/hash/tests/hash_algos.phpt +++ b/ext/hash/tests/hash_algos.phpt @@ -18,7 +18,7 @@ var_dump(hash_algos()); ===Done=== --EXPECTF-- *** Testing hash_algos() : basic functionality *** -array(43) { +array(44) { [%d]=> string(3) "md2" [%d]=> @@ -64,6 +64,8 @@ array(43) { [%d]=> string(4) "gost" [%d]=> + string(11) "gost-crypto" + [%d]=> string(7) "adler32" [%d]=> string(5) "crc32" @@ -106,4 +108,4 @@ array(43) { [%d]=> string(10) "haval256,5" } -===Done=== \ No newline at end of file +===Done=== diff --git a/ext/hash/tests/hash_copy_001.phpt b/ext/hash/tests/hash_copy_001.phpt index 638b7f5fc109a..bb4a49da89712 100644 --- a/ext/hash/tests/hash_copy_001.phpt +++ b/ext/hash/tests/hash_copy_001.phpt @@ -97,6 +97,9 @@ string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26" string(4) "gost" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" +string(11) "gost-crypto" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" string(7) "adler32" string(8) "6f7c0928" string(8) "6f7c0928" @@ -226,6 +229,9 @@ string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0" string(4) "gost" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "a00961e371287c71c527a41c14564f13b6ed12ac7cd9d5f5dfb3542a25e28d3b" +string(11) "gost-crypto" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" +string(64) "68ca9aea6729dc07d995fbe071a4b5c6490bb27fc4dc65ec0e96200d5e082996" string(7) "adler32" string(8) "6f7c0928" string(8) "d9141747" diff --git a/ext/hash/tests/hash_file_basic.phpt b/ext/hash/tests/hash_file_basic.phpt index 9851c14b91692..b16927d20ed9c 100644 --- a/ext/hash/tests/hash_file_basic.phpt +++ b/ext/hash/tests/hash_file_basic.phpt @@ -15,7 +15,7 @@ Felix De Vliegher echo "*** Testing hash_file() : basic functionality ***\n"; // Set up file -$filename = 'hash_file_example.txt'; +$filename = 'hash_file_basic_example.txt'; file_put_contents( $filename, 'The quick brown fox jumped over the lazy dog.' ); var_dump( hash_file( 'md5', $filename ) ); @@ -30,7 +30,7 @@ var_dump( base64_encode( hash_file( 'md5', $filename, true ) ) ); --CLEAN-- diff --git a/ext/hash/tests/hash_file_error.phpt b/ext/hash/tests/hash_file_error.phpt index de7ce55b10570..96c41e643219a 100644 --- a/ext/hash/tests/hash_file_error.phpt +++ b/ext/hash/tests/hash_file_error.phpt @@ -15,7 +15,7 @@ Felix De Vliegher echo "*** Testing hash_file() : error conditions ***\n"; // Set up file -$filename = 'hash_file_example.txt'; +$filename = 'hash_file_error_example.txt'; file_put_contents( $filename, 'The quick brown fox jumped over the lazy dog.' ); @@ -38,7 +38,7 @@ var_dump( hash_file( 'md5', $filename, false, $extra_arg ) ); --CLEAN-- diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index e95f898c156f7..d50b78321fb89 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -67,6 +67,9 @@ #include #endif +#define PHP_LDAP_ESCAPE_FILTER 0x01 +#define PHP_LDAP_ESCAPE_DN 0x02 + typedef struct { LDAP *link; #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) @@ -195,6 +198,9 @@ PHP_MINIT_FUNCTION(ldap) REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS); #endif + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS); + le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number); le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number); le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number); @@ -2137,6 +2143,83 @@ PHP_FUNCTION(ldap_set_rebind_proc) /* }}} */ #endif +static void php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen, char **result, size_t *resultlen) +{ + char hex[] = "0123456789abcdef"; + int i, p = 0; + size_t len = 0; + + for (i = 0; i < valuelen; i++) { + len += (map[(unsigned char) value[i]]) ? 3 : 1; + } + + (*result) = (char *) safe_emalloc(1, len, 1); + (*resultlen) = len; + + for (i = 0; i < valuelen; i++) { + unsigned char v = (unsigned char) value[i]; + + if (map[v]) { + (*result)[p++] = '\\'; + (*result)[p++] = hex[v >> 4]; + (*result)[p++] = hex[v & 0x0f]; + } else { + (*result)[p++] = v; + } + } + + (*result)[p++] = '\0'; +} + +static void php_ldap_escape_map_set_chars(zend_bool *map, const char *chars, const int charslen, char escape) +{ + int i = 0; + while (i < charslen) { + map[(unsigned char) chars[i++]] = escape; + } +} + +PHP_FUNCTION(ldap_escape) +{ + char *value, *ignores, *result; + int valuelen = 0, ignoreslen = 0, i; + size_t resultlen; + long flags = 0; + zend_bool map[256] = {0}, havecharlist = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) { + return; + } + + if (!valuelen) { + RETURN_EMPTY_STRING(); + } + + if (flags & PHP_LDAP_ESCAPE_FILTER) { + havecharlist = 1; + php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1); + } + + if (flags & PHP_LDAP_ESCAPE_DN) { + havecharlist = 1; + php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1); + } + + if (!havecharlist) { + for (i = 0; i < 256; i++) { + map[i] = 1; + } + } + + if (ignoreslen) { + php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0); + } + + php_ldap_do_escape(map, value, valuelen, &result, &resultlen); + + RETURN_STRINGL(result, resultlen, 0); +} + #ifdef STR_TRANSLATION /* {{{ php_ldap_do_translate */ @@ -2626,6 +2709,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2) ZEND_END_ARG_INFO() #endif +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_escape, 0, 0, 1) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, ignore) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + #ifdef STR_TRANSLATION ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1) ZEND_ARG_INFO(0, value) @@ -2704,6 +2793,8 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc) #endif + PHP_FE(ldap_escape, arginfo_ldap_escape) + #ifdef STR_TRANSLATION PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859) PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61) diff --git a/ext/ldap/tests/ldap_escape_all.phpt b/ext/ldap/tests/ldap_escape_all.phpt new file mode 100644 index 0000000000000..a79be004ffe56 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_all.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test all +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(39) "\66\6f\6f\3d\62\61\72\28\62\61\7a\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_both.phpt b/ext/ldap/tests/ldap_escape_both.phpt new file mode 100644 index 0000000000000..2169c0ad2e75c --- /dev/null +++ b/ext/ldap/tests/ldap_escape_both.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test filter and DN +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(21) "foo\3dbar\28baz\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_dn.phpt b/ext/ldap/tests/ldap_escape_dn.phpt new file mode 100644 index 0000000000000..fbcb0545ae4e8 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_dn.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test DN +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(15) "foo\3dbar(baz)*" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_filter.phpt b/ext/ldap/tests/ldap_escape_filter.phpt new file mode 100644 index 0000000000000..e4540a452d3f6 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_filter.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test filter +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(19) "foo=bar\28baz\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_ignore.phpt b/ext/ldap/tests/ldap_escape_ignore.phpt new file mode 100644 index 0000000000000..ab56aa2d0e91f --- /dev/null +++ b/ext/ldap/tests/ldap_escape_ignore.phpt @@ -0,0 +1,15 @@ +--TEST-- +ldap_escape() test ignore +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(31) "\66oo\3d\62a\72\28\62a\7a\29\2a" \ No newline at end of file diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 354cb548a7a76..05b8df4d0d538 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -293,7 +293,8 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char php_stream_statbuf ssbuf; php_stream_context *context = NULL; php_stream_wrapper *wrapper = NULL; - char *resolved_path, *path_to_open = NULL; + char *resolved_path; + const char *path_to_open = NULL; void *ret_val = NULL; int isescaped=0; xmlURI *uri; diff --git a/ext/libxml/tests/bug61367-read.phpt b/ext/libxml/tests/bug61367-read.phpt index 75d0006a3f35e..b4ecaa0324292 100644 --- a/ext/libxml/tests/bug61367-read.phpt +++ b/ext/libxml/tests/bug61367-read.phpt @@ -32,10 +32,10 @@ XML } } -var_dump(mkdir('test_bug_61367')); -var_dump(mkdir('test_bug_61367/base')); -var_dump(file_put_contents('test_bug_61367/bad', 'blah')); -var_dump(chdir('test_bug_61367/base')); +var_dump(mkdir('test_bug_61367-read')); +var_dump(mkdir('test_bug_61367-read/base')); +var_dump(file_put_contents('test_bug_61367-read/bad', 'blah')); +var_dump(chdir('test_bug_61367-read/base')); stream_wrapper_register( 'exploit', 'StreamExploiter' ); $s = fopen( 'exploit://', 'r' ); @@ -43,9 +43,9 @@ $s = fopen( 'exploit://', 'r' ); ?> --CLEAN-- --EXPECTF-- bool(true) @@ -53,7 +53,7 @@ bool(true) int(4) bool(true) -Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "file:///%s/test_bug_61367/bad" in %s on line %d +Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "file:///%s/test_bug_61367-read/bad" in %s on line %d Warning: DOMDocument::loadXML(): Failure to process entity file in Entity, line: 4 in %s on line %d diff --git a/ext/libxml/tests/bug61367-write.phpt b/ext/libxml/tests/bug61367-write.phpt index e18b07149a7cb..63e99a8e50a2f 100644 --- a/ext/libxml/tests/bug61367-write.phpt +++ b/ext/libxml/tests/bug61367-write.phpt @@ -19,10 +19,10 @@ class StreamExploiter { } } -var_dump(mkdir('test_bug_61367')); -var_dump(mkdir('test_bug_61367/base')); -var_dump(file_put_contents('test_bug_61367/bad', 'blah')); -var_dump(chdir('test_bug_61367/base')); +var_dump(mkdir('test_bug_61367-write')); +var_dump(mkdir('test_bug_61367-write/base')); +var_dump(file_put_contents('test_bug_61367-write/bad', 'blah')); +var_dump(chdir('test_bug_61367-write/base')); stream_wrapper_register( 'exploit', 'StreamExploiter' ); $s = fopen( 'exploit://', 'r' ); @@ -30,9 +30,9 @@ $s = fopen( 'exploit://', 'r' ); ?> --CLEAN-- --EXPECTF-- bool(true) diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index 5ecc8f365e8ae..30764dc8076d3 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -364,6 +364,7 @@ SAPI_POST_HANDLER_FUNC(php_mb_post_handler) { const mbfl_encoding *detected; php_mb_encoding_handler_info_t info; + char *post_data_str = NULL; MBSTRG(http_input_identify_post) = NULL; @@ -376,7 +377,10 @@ SAPI_POST_HANDLER_FUNC(php_mb_post_handler) info.num_from_encodings = MBSTRG(http_input_list_size); info.from_language = MBSTRG(language); - detected = _php_mb_encoding_handler_ex(&info, arg, SG(request_info).post_data TSRMLS_CC); + php_stream_rewind(SG(request_info).request_body); + php_stream_copy_to_mem(SG(request_info).request_body, &post_data_str, PHP_STREAM_COPY_ALL, 0); + detected = _php_mb_encoding_handler_ex(&info, arg, post_data_str TSRMLS_CC); + STR_FREE(post_data_str); MBSTRG(http_input_identify) = detected; if (detected) { diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 4e430b6ea2364..168b133c6429f 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -402,10 +402,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_kana, 0, 0, 1) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 1, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 0, 0, 3) ZEND_ARG_INFO(0, to) ZEND_ARG_INFO(0, from) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity, 0, 0, 2) diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index 6f2e404087843..eb94ff65bbebf 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -43,23 +43,28 @@ #define MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_INFO(0, stmt) #endif -ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_result, 1) +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_result, 0) MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_param, 1) +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_param, 0) MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_INFO(0, types) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_result, 1) +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_result, 0) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_param, 1) +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_param, 0) ZEND_ARG_INFO(0, types) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(all_args_force_by_ref, 1) +ZEND_BEGIN_ARG_INFO(all_args_force_by_ref, 0) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_poll, 0, 0, 4) diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4 index 09aca5af8a559..0e08b977af94d 100644 --- a/ext/mysqlnd/config9.m4 +++ b/ext/mysqlnd/config9.m4 @@ -48,16 +48,4 @@ fi if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then PHP_ADD_BUILD_DIR([ext/mysqlnd], 1) - - dnl This creates a file so it has to be after above macros - PHP_CHECK_TYPES([int8 uint8 int16 uint16 int32 uint32 uchar ulong int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t], [ - ext/mysqlnd/php_mysqlnd_config.h - ],[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif - ]) fi diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 4ace69adcf9a0..c9127ef93c0ca 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -104,7 +104,7 @@ #define MYSQLND_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_TRANSACTIONS | \ CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | \ - CLIENT_MULTI_RESULTS | CLIENT_PS_MULTI_RESULTS | CLIENT_LOCAL_FILES | CLIENT_PLUGIN_AUTH) + CLIENT_MULTI_RESULTS | CLIENT_LOCAL_FILES | CLIENT_PLUGIN_AUTH) #define MYSQLND_NET_FLAG_USE_COMPRESSION 1 diff --git a/ext/mysqlnd/mysqlnd_portability.h b/ext/mysqlnd/mysqlnd_portability.h index b9479150ae03a..72a156a79500d 100644 --- a/ext/mysqlnd/mysqlnd_portability.h +++ b/ext/mysqlnd/mysqlnd_portability.h @@ -36,8 +36,6 @@ This file is public domain and comes with NO WARRANTY of any kind */ #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) # include "ext/mysqlnd/config-win.h" -#else -# include #endif /* _WIN32... */ #if __STDC_VERSION__ < 199901L && !defined(atoll) @@ -45,14 +43,7 @@ This file is public domain and comes with NO WARRANTY of any kind */ #define atoll atol #endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_STDINT_H -#include -#endif +#include "php_stdint.h" #if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG) #define _LONG_LONG 1 /* For AIX string library */ @@ -70,102 +61,6 @@ This file is public domain and comes with NO WARRANTY of any kind */ #define HAVE_LONG_LONG 1 #endif - -/* Typdefs for easyier portability */ -#ifndef HAVE_INT8_T -#ifndef HAVE_INT8 -typedef signed char int8_t; /* Signed integer >= 8 bits */ -#else -typedef int8 int8_t; /* Signed integer >= 8 bits */ -#endif -#endif - -#ifndef HAVE_UINT8_T -#ifndef HAVE_UINT8 -typedef unsigned char uint8_t; /* Unsigned integer >= 8 bits */ -#else -typedef uint8 uint8_t; /* Signed integer >= 8 bits */ -#endif -#endif - -#ifndef HAVE_INT16_T -#ifndef HAVE_INT16 -typedef signed short int16_t; /* Signed integer >= 16 bits */ -#else -typedef int16 int16_t; /* Signed integer >= 16 bits */ -#endif -#endif - -#ifndef HAVE_UINT16_T -#ifndef HAVE_UINT16 -typedef unsigned short uint16_t; /* Signed integer >= 16 bits */ -#else -typedef uint16 uint16_t; /* Signed integer >= 16 bits */ -#endif -#endif - - -#ifndef HAVE_INT32_T -#ifdef HAVE_INT32 -typedef int32 int32_t; -#elif SIZEOF_INT == 4 -typedef signed int int32_t; -#elif SIZEOF_LONG == 4 -typedef signed long int32_t; -#else -error "Neither int nor long is of 4 bytes width" -#endif -#endif /* HAVE_INT32_T */ - -#ifndef HAVE_UINT32_T -#ifdef HAVE_UINT32 -typedef uint32 uint32_t; -#elif SIZEOF_INT == 4 -typedef unsigned int uint32_t; -#elif SIZEOF_LONG == 4 -typedef unsigned long uint32_t; -#else -#error "Neither int nor long is of 4 bytes width" -#endif -#endif /* HAVE_UINT32_T */ - -#ifndef HAVE_INT64_T -#ifdef HAVE_INT64 -typedef int64 int64_t; -#elif SIZEOF_INT == 8 -typedef signed int int64_t; -#elif SIZEOF_LONG == 8 -typedef signed long int64_t; -#elif SIZEOF_LONG_LONG == 8 -#ifdef PHP_WIN32 -typedef __int64 int64_t; -#else -typedef signed long long int64_t; -#endif -#else -#error "Neither int nor long nor long long is of 8 bytes width" -#endif -#endif /* HAVE_INT64_T */ - -#ifndef HAVE_UINT64_T -#ifdef HAVE_UINT64 -typedef uint64 uint64_t; -#elif SIZEOF_INT == 8 -typedef unsigned int uint64_t; -#elif SIZEOF_LONG == 8 -typedef unsigned long uint64_t; -#elif SIZEOF_LONG_LONG == 8 -#ifdef PHP_WIN32 -typedef unsigned __int64 uint64_t; -#else -typedef unsigned long long uint64_t; -#endif -#else -#error "Neither int nor long nor long long is of 8 bytes width" -#endif -#endif /* HAVE_INT64_T */ - - #ifdef PHP_WIN32 #define MYSQLND_LLU_SPEC "%I64u" #define MYSQLND_LL_SPEC "%I64d" diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE new file mode 100644 index 0000000000000..42536af320686 --- /dev/null +++ b/ext/oci8/LICENSE @@ -0,0 +1,68 @@ +-------------------------------------------------------------------- + The PHP License, version 3.01 +Copyright (c) 1999 - 2012 The PHP Group. All rights reserved. +-------------------------------------------------------------------- + +Redistribution and use in source and binary forms, with or without +modification, is permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + 3. The name "PHP" must not be used to endorse or promote products + derived from this software without prior written permission. For + written permission, please contact group@php.net. + + 4. Products derived from this software may not be called "PHP", nor + may "PHP" appear in their name, without prior written permission + from group@php.net. You may indicate that your software works in + conjunction with PHP by saying "Foo for PHP" instead of calling + it "PHP Foo" or "phpfoo" + + 5. The PHP Group may publish revised and/or new versions of the + license from time to time. Each version will be given a + distinguishing version number. + Once covered code has been published under a particular version + of the license, you may always continue to use it under the terms + of that version. You may also choose to use such covered code + under the terms of any subsequent version of the license + published by the PHP Group. No one other than the PHP Group has + the right to modify the terms applicable to covered code created + under this License. + + 6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes PHP software, freely available from + ". + +THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND +ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP +DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------- + +This software consists of voluntary contributions made by many +individuals on behalf of the PHP Group. + +The PHP Group can be contacted via Email at group@php.net. + +For more information on the PHP Group and the PHP project, +please see . + +PHP includes the Zend Engine, freely available at +. diff --git a/ext/oci8/README b/ext/oci8/README index 420d5dac58e41..d662072743fd1 100644 --- a/ext/oci8/README +++ b/ext/oci8/README @@ -1,13 +1,20 @@ The OCI8 Extension ------------------ -Use the OCI8 extension to access Oracle Database. +Use the OCI8 extension to access Oracle Database. Documentation is at http://php.net/oci8 -The extension can be built with PHP versions 4.3.9 to 5.x using Oracle -9.2, 10, or 11 client libraries. Oracle's standard cross-version -connectivity applies. For example PHP linked with Oracle 11.2 client -libraries can connect to Oracle Database 9.2 onwards. See Oracle's -note "Oracle Client / Server Interoperability Support" (ID 207303.1) -for details. +The extension can be linked with Oracle client libraries from Oracle +Database 10.2, 11, or 12.1. These libraries are found in the database +installation, or in the free Oracle Instant Client available from +Oracle. + +Oracle's standard cross-version connectivity applies. For example, +PHP OCI8 linked with Instant Client 11.2 can connect to Oracle +Database 9.2 onward. See Oracle's note "Oracle Client / Server +Interoperability Support" (ID 207303.1) for details. + +PHP OCI8 2.0 can be built with PHP 5.2 onward. Use the older PHP OCI8 +1.4.10 when using PHP 4.3.9 through to PHP 5.1.x, or when only Oracle +Database 9.2 client libraries are available. diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4 index 39c037548a669..0d08d21c29e61 100644 --- a/ext/oci8/config.m4 +++ b/ext/oci8/config.m4 @@ -15,22 +15,6 @@ else PHP_OCI8_TAIL1="tail -1" fi -AC_DEFUN([PHP_OCI_IF_DEFINED],[ - old_CPPFLAGS=$CPPFLAGS - CPPFLAGS=$3 - AC_EGREP_CPP(yes,[ -#include -#if defined($1) - yes -#endif - ],[ - CPPFLAGS=$old_CPPFLAGS - $2 - ],[ - CPPFLAGS=$old_CPPFLAGS - ]) -]) - AC_DEFUN([AC_OCI8_CHECK_LIB_DIR],[ AC_MSG_CHECKING([ORACLE_HOME library validity]) if test ! -d "$OCI8_DIR"; then @@ -98,13 +82,99 @@ AC_DEFUN([AC_OCI8_ORACLE_VERSION],[ AC_MSG_RESULT($OCI8_ORACLE_VERSION) ]) +dnl +dnl OCI8_INIT_DTRACE(providerdesc, header-file, sources) +dnl This mimics PHP_INIT_DTRACE from PHP 5.4's acinclude.m4. It is +dnl necessarily different from PHP_INIT_DTRACE which doesn't currently +dnl support DTrace for extensions. Creating OCI8_INIT_DTRACE +dnl independently instead of using a refactored PHP_INIT_DTRACE allows +dnl OCI8 to be DTraced on versions of PHP where core PHP DTrace support +dnl isn't available. +dnl +AC_DEFUN([OCI8_INIT_DTRACE],[ + ac_srcdir=[]PHP_EXT_SRCDIR([oci8])/ + ac_bdir=[]PHP_EXT_BUILDDIR([oci8])/ + +dnl providerdesc + ac_provsrc=$1 + +dnl header-file + ac_hdrobj=$2 + +dnl DTrace objects + old_IFS=[$]IFS + for ac_src in $3; do + IFS=. + set $ac_src + ac_obj=[$]1 + IFS=$old_IFS + + OCI8_DTRACE_OBJS="[$]OCI8_DTRACE_OBJS [$]ac_bdir[$]ac_obj.lo" + done; + + for ac_lo in $OCI8_DTRACE_OBJS; do + dtrace_oci8_objs="[$]dtrace_oci8_objs `echo $ac_lo | $SED -e 's,\.lo$,.o,' -e 's#\(.*\)\/#\1\/.libs\/#'`" + done; + +dnl Generate Makefile.objects entry +dnl The empty $ac_provsrc command stops an implicit circular dependency +dnl in GNU Make which causes the .d file to be overwritten (Bug 61268) + cat>>Makefile.objects< \$[]@ + +\$(OCI8_DTRACE_OBJS): $ac_bdir[$]ac_hdrobj + +EOF + + case $host_alias in + *solaris*|*linux*) + dtrace_prov_name="`echo $ac_provsrc | $SED -e 's#\(.*\)\/##'`.o" + dtrace_lib_dir="`echo $ac_bdir[$]ac_provsrc | $SED -e 's#\(.*\)/[^/]*#\1#'`/.libs" + dtrace_d_obj="`echo $ac_bdir[$]ac_provsrc | $SED -e 's#\(.*\)/\([^/]*\)#\1/.libs/\2#'`.o" + dtrace_nolib_objs='$(OCI8_DTRACE_OBJS:.lo=.o)' + for ac_lo in $OCI8_DTRACE_OBJS; do + dtrace_oci8_lib_objs="[$]dtrace_oci8_lib_objs `echo $ac_lo | $SED -e 's,\.lo$,.o,' -e 's#\(.*\)\/#\1\/.libs\/#'`" + done; +dnl Always attempt to create both PIC and non-PIC DTrace objects (Bug 63692) + cat>>Makefile.objects< \$[]@ + @test -d "$dtrace_lib_dir" || mkdir $dtrace_lib_dir + if CFLAGS="\$(CFLAGS_CLEAN)" dtrace -G -o $dtrace_d_obj -s $ac_srcdir[$]ac_provsrc $dtrace_oci8_lib_objs 2> /dev/null && test -f "$dtrace_d_obj"; then [\\] + echo "pic_object=['].libs/$dtrace_prov_name[']" >> \$[]@ [;\\] + else [\\] + echo "pic_object='none'" >> \$[]@ [;\\] + fi + if CFLAGS="\$(CFLAGS_CLEAN)" dtrace -G -o $ac_bdir[$]ac_provsrc.o -s $ac_srcdir[$]ac_provsrc $dtrace_nolib_objs 2> /dev/null && test -f "$ac_bdir[$]ac_provsrc.o"; then [\\] + echo "non_pic_object=[']$dtrace_prov_name[']" >> \$[]@ [;\\] + else [\\] + echo "non_pic_object='none'" >> \$[]@ [;\\] + fi + +EOF + ;; + *) + AC_MSG_WARN([OCI8 extension: OCI8 DTrace support is not confirmed on this platform]) +cat>>Makefile.objects< | + | Authors: Stig Sæther Bakken | | Thies C. Arntzen | | Maxim Maletsky | | | @@ -37,41 +37,34 @@ #include "php_ini.h" #include "ext/standard/php_smart_str.h" -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef PHP_WIN32 -#include "win32/php_stdint.h" -#endif - #if HAVE_OCI8 -#if PHP_MAJOR_VERSION > 5 -#error This version of the PHP OCI8 extension is not compatible with PHP 6 or later -#elif PHP_MAJOR_VERSION < 5 -#ifdef ZTS -#error The PHP OCI8 extension does not support ZTS mode in PHP 4 -#endif +/* PHP 5.2 is the minimum supported version for OCI8 2.0 */ +#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1) +#error Use PHP OCI8 1.4 for your version of PHP #endif #include "php_oci8.h" #include "php_oci8_int.h" #include "zend_hash.h" -#if defined(HAVE_STDINT_H) || defined(PHP_WIN32) -#define OCI8_INT_TO_PTR(I) ((void *)(intptr_t)(I)) +#if defined(__PTRDIFF_TYPE__) +# define OCI8_INT_TO_PTR(I) ((void*)(__PTRDIFF_TYPE__)(I)) +# define OCI8_PTR_TO_INT(P) ((int)(__PTRDIFF_TYPE__)(P)) +#elif !defined(__GNUC__) +#define OCI8_INT_TO_PTR(I) ((void*)&((char*)0)[I]) +#define OCI8_PTR_TO_INT(P) ((int)(((char*)P)-(char*)0)) +#elif defined(HAVE_STDINT_H) +#define OCI8_INT_TO_PTR(I) ((void*)(intptr_t)(I)) #define OCI8_PTR_TO_INT(P) ((int)(intptr_t)(P)) #else -#define OCI8_INT_TO_PTR(I) ((void *)(I)) +#define OCI8_INT_TO_PTR(I) ((void*)(I)) #define OCI8_PTR_TO_INT(P) ((int)(P)) #endif ZEND_DECLARE_MODULE_GLOBALS(oci) -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) -/* This "if" allows PECL builds from this file to be portable to older PHP releases */ static PHP_GINIT_FUNCTION(oci); static PHP_GSHUTDOWN_FUNCTION(oci); -#endif /* Allow PHP 5.3 branch to be used in PECL for 5.x compatible builds */ #ifndef Z_ADDREF_P @@ -128,7 +121,7 @@ zend_class_entry *oci_coll_class_entry_ptr; #define PHP_OCI_INIT_MODE (OCI_DEFAULT | OCI_OBJECT) #endif -/* static protos {{{ */ +/* {{{ static protos */ static void php_oci_connection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC); static void php_oci_pconnection_list_dtor (zend_rsrc_list_entry * TSRMLS_DC); static void php_oci_pconnection_list_np_dtor (zend_rsrc_list_entry * TSRMLS_DC); @@ -152,7 +145,7 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS /* }}} */ /* {{{ dynamically loadable module stuff */ -#if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G) +#if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G) || defined(COMPILE_DL_OCI8_12C) ZEND_GET_MODULE(oci8) #endif /* COMPILE_DL */ /* }}} */ @@ -425,6 +418,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_parse, 0, 0, 2) ZEND_ARG_INFO(0, sql_text) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_get_implicit_resultset, 0, 0, 1) +ZEND_ARG_INFO(0, statement_resource) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_prefetch, 0, 0, 2) ZEND_ARG_INFO(0, statement_resource) ZEND_ARG_INFO(0, number_of_rows) @@ -454,6 +451,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_info, 0, 0, 2) ZEND_ARG_INFO(0, client_information) ZEND_END_ARG_INFO() +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_db_operation, 0, 0, 2) +ZEND_ARG_INFO(0, connection_resource) +ZEND_ARG_INFO(0, action) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_password_change, 0, 0, 4) ZEND_ARG_INFO(0, connection_resource_or_connection_string) ZEND_ARG_INFO(0, username) @@ -698,12 +702,16 @@ static unsigned char arginfo_oci_bind_array_by_name[] = { 3, BYREF_NONE, BYREF_N #define arginfo_oci_error NULL #define arginfo_oci_num_fields NULL #define arginfo_oci_parse NULL +#define arginfo_oci_get_implicit_resultset NULL #define arginfo_oci_set_prefetch NULL #define arginfo_oci_set_client_identifier NULL #define arginfo_oci_set_edition NULL #define arginfo_oci_set_module_name NULL #define arginfo_oci_set_action NULL #define arginfo_oci_set_client_info NULL +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +#define arginfo_oci_set_db_operation NULL +#endif #define arginfo_oci_password_change NULL #define arginfo_oci_new_cursor NULL #define arginfo_oci_result NULL @@ -786,6 +794,7 @@ PHP_FUNCTION(oci_rollback); PHP_FUNCTION(oci_new_descriptor); PHP_FUNCTION(oci_num_fields); PHP_FUNCTION(oci_parse); +PHP_FUNCTION(oci_get_implicit_resultset); PHP_FUNCTION(oci_new_cursor); PHP_FUNCTION(oci_result); PHP_FUNCTION(oci_client_version); @@ -794,6 +803,9 @@ PHP_FUNCTION(oci_statement_type); PHP_FUNCTION(oci_num_rows); PHP_FUNCTION(oci_set_prefetch); PHP_FUNCTION(oci_set_client_identifier); +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +PHP_FUNCTION(oci_set_db_operation); +#endif PHP_FUNCTION(oci_set_edition); PHP_FUNCTION(oci_set_module_name); PHP_FUNCTION(oci_set_action); @@ -862,6 +874,7 @@ zend_function_entry php_oci_functions[] = { PHP_FE(oci_internal_debug, arginfo_oci_internal_debug) PHP_FE(oci_num_fields, arginfo_oci_num_fields) PHP_FE(oci_parse, arginfo_oci_parse) + PHP_FE(oci_get_implicit_resultset, arginfo_oci_get_implicit_resultset) PHP_FE(oci_new_cursor, arginfo_oci_new_cursor) PHP_FE(oci_result, arginfo_oci_result) PHP_FE(oci_client_version, arginfo_oci_client_version) @@ -898,6 +911,9 @@ zend_function_entry php_oci_functions[] = { PHP_FE(oci_new_descriptor, arginfo_oci_new_descriptor) PHP_FE(oci_set_prefetch, arginfo_oci_set_prefetch) PHP_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier) +#ifdef WAITIING_ORACLE_BUG_16695981_FIX + PHP_FE(oci_set_db_operation, arginfo_oci_set_db_operation) +#endif PHP_FE(oci_set_edition, arginfo_oci_set_edition) PHP_FE(oci_set_module_name, arginfo_oci_set_module_name) PHP_FE(oci_set_action, arginfo_oci_set_action) @@ -1033,16 +1049,11 @@ zend_module_entry oci8_module_entry = { PHP_RSHUTDOWN(oci), /* per-request shutdown function */ PHP_MINFO(oci), /* information function */ PHP_OCI8_VERSION, -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* This check allows PECL builds from this file to be portable to older PHP releases */ PHP_MODULE_GLOBALS(oci), /* globals descriptor */ PHP_GINIT(oci), /* globals ctor */ PHP_GSHUTDOWN(oci), /* globals dtor */ NULL, /* post deactivate */ STANDARD_MODULE_PROPERTIES_EX -#else - STANDARD_MODULE_PROPERTIES -#endif }; /* }}} */ @@ -1055,8 +1066,12 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY( "oci8.statement_cache_size", "20", PHP_INI_SYSTEM, ONUPDATELONGFUNC, statement_cache_size, zend_oci_globals, oci_globals) STD_PHP_INI_ENTRY( "oci8.default_prefetch", "100", PHP_INI_SYSTEM, ONUPDATELONGFUNC, default_prefetch, zend_oci_globals, oci_globals) STD_PHP_INI_BOOLEAN("oci8.old_oci_close_semantics", "0", PHP_INI_SYSTEM, OnUpdateBool, old_oci_close_semantics,zend_oci_globals, oci_globals) +#if (OCI_MAJOR_VERSION >= 11) STD_PHP_INI_ENTRY( "oci8.connection_class", "", PHP_INI_ALL, OnUpdateString, connection_class, zend_oci_globals, oci_globals) +#endif +#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) STD_PHP_INI_BOOLEAN("oci8.events", "0", PHP_INI_SYSTEM, OnUpdateBool, events, zend_oci_globals, oci_globals) +#endif PHP_INI_END() /* }}} */ @@ -1132,7 +1147,8 @@ static void php_oci_init_global_handles(TSRMLS_D) } } } -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_cleanup_global_handles() * @@ -1149,18 +1165,14 @@ static void php_oci_cleanup_global_handles(TSRMLS_D) PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV)); OCI_G(env) = NULL; } -} /* }}} */ +} +/* }}} */ /* {{{ PHP_GINIT_FUNCTION * * Zerofill globals during module init */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) -/* This check allows PECL builds from this file to be portable to older PHP releases */ static PHP_GINIT_FUNCTION(oci) -#else -static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC) -#endif { memset(oci_globals, 0, sizeof(zend_oci_globals)); } @@ -1170,12 +1182,7 @@ static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC) * * Called for thread shutdown in ZTS, after module shutdown for non-ZTS */ -/* This check allows PECL builds from this file to be portable to older PHP releases */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) static PHP_GSHUTDOWN_FUNCTION(oci) -#else -static void php_oci_shutdown_globals(zend_oci_globals *oci_globals TSRMLS_DC) -#endif { php_oci_cleanup_global_handles(TSRMLS_C); } @@ -1186,12 +1193,6 @@ PHP_MINIT_FUNCTION(oci) zend_class_entry oci_lob_class_entry; zend_class_entry oci_coll_class_entry; -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* This check allows PECL builds from this file to be portable to older PHP releases */ - /* this is handled by new globals management code */ -#else - ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, php_oci_shutdown_globals); -#endif REGISTER_INI_ENTRIES(); le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number); @@ -1294,7 +1295,6 @@ PHP_MINIT_FUNCTION(oci) PHP_RINIT_FUNCTION(oci) { - OCI_G(debug_mode) = 0; /* start "fresh" */ OCI_G(num_links) = OCI_G(num_persistent); OCI_G(errcode) = 0; OCI_G(edition) = NULL; @@ -1304,13 +1304,6 @@ PHP_RINIT_FUNCTION(oci) PHP_MSHUTDOWN_FUNCTION(oci) { -/* Work around PHP_GSHUTDOWN_FUNCTION not being called in older versions of PHP */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) || (PHP_MAJOR_VERSION < 5) -#ifndef ZTS - php_oci_cleanup_global_handles(TSRMLS_C); -#endif -#endif - OCI_G(shutdown) = 1; UNREGISTER_INI_ENTRIES(); @@ -1336,22 +1329,26 @@ PHP_RSHUTDOWN_FUNCTION(oci) PHP_MINFO_FUNCTION(oci) { char buf[32]; +#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) char *ver; +#endif php_info_print_table_start(); php_info_print_table_row(2, "OCI8 Support", "enabled"); - php_info_print_table_row(2, "Version", PHP_OCI8_VERSION); +#if defined(HAVE_OCI8_DTRACE) + php_info_print_table_row(2, "OCI8 DTrace Support", "enabled"); +#else + php_info_print_table_row(2, "OCI8 DTrace Support", "disabled"); +#endif + php_info_print_table_row(2, "OCI8 Version", PHP_OCI8_VERSION); php_info_print_table_row(2, "Revision", "$Id$"); - snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent)); - php_info_print_table_row(2, "Active Persistent Connections", buf); - snprintf(buf, sizeof(buf), "%ld", OCI_G(num_links)); - php_info_print_table_row(2, "Active Connections", buf); - #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) php_oci_client_get_version(&ver TSRMLS_CC); php_info_print_table_row(2, "Oracle Run-time Client Library Version", ver); efree(ver); +#else + php_info_print_table_row(2, "Oracle Run-time Client Library Version", "Unknown"); #endif #if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION) snprintf(buf, sizeof(buf), "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION); @@ -1361,9 +1358,9 @@ PHP_MINFO_FUNCTION(oci) snprintf(buf, sizeof(buf), "Unknown"); #endif #if defined(HAVE_OCI_INSTANT_CLIENT) - php_info_print_table_row(2, "Oracle Instant Client Version", buf); + php_info_print_table_row(2, "Oracle Compile-time Instant Client Version", buf); #else - php_info_print_table_row(2, "Oracle Version", buf); + php_info_print_table_row(2, "Oracle Compile-time Version", buf); #endif #if !defined(PHP_WIN32) && !defined(HAVE_OCI_INSTANT_CLIENT) @@ -1375,14 +1372,22 @@ PHP_MINFO_FUNCTION(oci) #endif #endif - php_info_print_table_row(2, "Temporary Lob support", "enabled"); - php_info_print_table_row(2, "Collections support", "enabled"); + php_info_print_table_end(); + DISPLAY_INI_ENTRIES(); + + php_info_print_table_start(); + php_info_print_table_header(2, "Statistics", ""); + snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent)); + php_info_print_table_row(2, "Active Persistent Connections", buf); + snprintf(buf, sizeof(buf), "%ld", OCI_G(num_links)); + php_info_print_table_row(2, "Active Connections", buf); + php_info_print_table_end(); } /* }}} */ -/* list destructors {{{ */ +/* {{{ list destructors */ /* {{{ php_oci_connection_list_dtor() * @@ -1396,7 +1401,8 @@ static void php_oci_connection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) php_oci_connection_close(connection TSRMLS_CC); OCI_G(num_links)--; } -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_pconnection_list_dtor() * @@ -1411,7 +1417,8 @@ static void php_oci_pconnection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) OCI_G(num_persistent)--; OCI_G(num_links)--; } -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_pconnection_list_np_dtor() * @@ -1449,11 +1456,12 @@ static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_ OCI_G(num_persistent)--; } - if (OCI_G(debug_mode)) { - php_printf ("OCI8 DEBUG L1: np_dtor cleaning up: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_P_DTOR_CLOSE_ENABLED()) { + DTRACE_OCI8_CONNECT_P_DTOR_CLOSE(connection); } - } - else { +#endif /* HAVE_OCI8_DTRACE */ + } else { /* * Release the connection to underlying pool. We do this unconditionally so that * out-of-scope pconnects are now consistent with oci_close and out-of-scope new connect @@ -1465,11 +1473,14 @@ static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_ */ php_oci_connection_release(connection TSRMLS_CC); - if (OCI_G(debug_mode)) { - php_printf ("OCI8 DEBUG L1: np_dtor releasing: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_P_DTOR_RELEASE_ENABLED()) { + DTRACE_OCI8_CONNECT_P_DTOR_RELEASE(connection); } +#endif /* HAVE_OCI8_DTRACE */ } -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_statement_list_dtor() * @@ -1479,7 +1490,8 @@ static void php_oci_statement_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) { php_oci_statement *statement = (php_oci_statement *)entry->ptr; php_oci_statement_free(statement TSRMLS_CC); -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_descriptor_list_dtor() * @@ -1489,7 +1501,8 @@ static void php_oci_descriptor_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) { php_oci_descriptor *descriptor = (php_oci_descriptor *)entry->ptr; php_oci_lob_free(descriptor TSRMLS_CC); -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_list_dtor() * @@ -1499,11 +1512,12 @@ static void php_oci_collection_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) { php_oci_collection *collection = (php_oci_collection *)entry->ptr; php_oci_collection_close(collection TSRMLS_CC); -} /* }}} */ +} +/* }}} */ /* }}} */ -/* Hash Destructors {{{ */ +/* {{{ Hash Destructors */ /* {{{ php_oci_define_hash_dtor() * @@ -1605,18 +1619,17 @@ void php_oci_connection_descriptors_free(php_oci_connection *connection TSRMLS_D } /* }}} */ - /* {{{ php_oci_error() * * Fetch & print out error message if we get an error * Returns an Oracle error number */ -sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC) +sb4 php_oci_error(OCIError *err_p, sword errstatus TSRMLS_DC) { text *errbuf = (text *)NULL; - sb4 errcode = 0; + sb4 errcode = 0; /* Oracle error number */ - switch (status) { + switch (errstatus) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: @@ -1659,9 +1672,16 @@ sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC) php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE"); break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", status); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", errstatus); break; } + +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_ERROR_ENABLED()) { + DTRACE_OCI8_ERROR((int)errstatus, (long)errcode); + } +#endif /* HAVE_OCI8_DTRACE */ + return errcode; } /* }}} */ @@ -1690,7 +1710,8 @@ sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC) } } return error_code; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_fetch_sqltext_offset() * @@ -1718,7 +1739,8 @@ int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, u return 1; } return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_do_connect() * @@ -1738,18 +1760,32 @@ void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclus return; } +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_ENTRY_ENABLED()) { + DTRACE_OCI8_CONNECT_ENTRY(username, dbname, charset, session_mode, persistent, exclusive); + } +#endif /* HAVE_OCI8_DTRACE */ + if (!charset_len) { charset = NULL; } connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_RETURN_ENABLED()) { + DTRACE_OCI8_CONNECT_RETURN(connection); + } +#endif /* HAVE_OCI8_DTRACE */ + + if (!connection) { RETURN_FALSE; } - RETURN_RESOURCE(connection->rsrc_id); + RETURN_RESOURCE(connection->id); -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_do_connect_ex() * @@ -1908,16 +1944,11 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char } } - /* Debug statements {{{ */ - if (OCI_G(debug_mode)) { - if (connection && connection->is_stub) { - php_printf ("OCI8 DEBUG L1: Got a cached stub: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); - } else if (connection) { - php_printf ("OCI8 DEBUG L1: Got a cached connection: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); - } else { - php_printf ("OCI8 DEBUG L1: Got NO cached connection at (%s:%d) \n", __FILE__, __LINE__); - } - } /* }}} */ +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_LOOKUP_ENABLED()) { + DTRACE_OCI8_CONNECT_LOOKUP(connection, connection && connection->is_stub ? 1 : 0); + } +#endif /* HAVE_OCI8_DTRACE */ /* If we got a pconnection stub, then 'load'(OCISessionGet) the real connection from its * private spool A connection is a stub if it is only a cached structure and the real @@ -1963,24 +1994,20 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char /* okay, the connection is open and the server is still alive */ connection->used_this_request = 1; - tmp = (php_oci_connection *)zend_list_find(connection->rsrc_id, &rsrc_type); + tmp = (php_oci_connection *)zend_list_find(connection->id, &rsrc_type); if (tmp != NULL && rsrc_type == le_pconnection && strlen(tmp->hash_key) == hashed_details.len && - memcmp(tmp->hash_key, hashed_details.c, hashed_details.len) == 0 && zend_list_addref(connection->rsrc_id) == SUCCESS) { + memcmp(tmp->hash_key, hashed_details.c, hashed_details.len) == 0 && zend_list_addref(connection->id) == SUCCESS) { /* do nothing */ } else { -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - connection->rsrc_id = zend_list_insert(connection, le_pconnection TSRMLS_CC); -#else - connection->rsrc_id = zend_list_insert(connection, le_pconnection); -#endif + PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection); /* Persistent connections: For old close semantics we artificially * bump up the refcount to prevent the non-persistent destructor * from getting called until request shutdown. The refcount is * decremented in the persistent helper */ if (OCI_G(old_oci_close_semantics)) { - zend_list_addref(connection->rsrc_id); + zend_list_addref(connection->id); } } smart_str_free_ex(&hashed_details, 0); @@ -1991,7 +2018,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char } else { /* we do not ping non-persistent connections */ smart_str_free_ex(&hashed_details, 0); - zend_list_addref(connection->rsrc_id); + zend_list_addref(connection->id); return connection; } } /* is_open is true? */ @@ -2008,7 +2035,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char /* We have to do a hash_del but need to preserve the resource if there is a positive * refcount. Set the data pointer in the list entry to NULL */ - if (connection == zend_list_find(connection->rsrc_id, &rsrc_type) && rsrc_type == le_pconnection) { + if (connection == zend_list_find(connection->id, &rsrc_type) && rsrc_type == le_pconnection) { le->ptr = NULL; } @@ -2052,6 +2079,9 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection)); connection->hash_key = estrndup(hashed_details.c, hashed_details.len); connection->is_persistent = 0; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } else { connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection)); if (connection == NULL) { @@ -2063,11 +2093,17 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char return NULL; } connection->is_persistent = 1; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } } else { connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection)); connection->hash_key = estrndup(hashed_details.c, hashed_details.len); connection->is_persistent = 0; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } /* {{{ Get the session pool that suits this connection request from the persistent list. This @@ -2085,7 +2121,8 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char smart_str_free_ex(&hashed_details, 0); return NULL; } - } /* }}} */ + } + /* }}} */ connection->idle_expiry = (OCI_G(persistent_timeout) > 0) ? (timestamp + OCI_G(persistent_timeout)) : 0; @@ -2124,50 +2161,34 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char new_le.ptr = connection; new_le.type = le_pconnection; connection->used_this_request = 1; -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - connection->rsrc_id = zend_list_insert(connection, le_pconnection TSRMLS_CC); -#else - connection->rsrc_id = zend_list_insert(connection, le_pconnection); -#endif + PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection); /* Persistent connections: For old close semantics we artificially bump up the refcount to * prevent the non-persistent destructor from getting called until request shutdown. The * refcount is decremented in the persistent helper */ if (OCI_G(old_oci_close_semantics)) { - zend_list_addref(connection->rsrc_id); + zend_list_addref(connection->id); } zend_hash_update(&EG(persistent_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL); OCI_G(num_persistent)++; OCI_G(num_links)++; } else if (!exclusive) { -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - connection->rsrc_id = zend_list_insert(connection, le_connection TSRMLS_CC); -#else - connection->rsrc_id = zend_list_insert(connection, le_connection); -#endif - new_le.ptr = OCI8_INT_TO_PTR(connection->rsrc_id); + PHP_OCI_REGISTER_RESOURCE(connection, le_connection); + new_le.ptr = OCI8_INT_TO_PTR(connection->id); new_le.type = le_index_ptr; zend_hash_update(&EG(regular_list), connection->hash_key, strlen(connection->hash_key)+1, (void *)&new_le, sizeof(zend_rsrc_list_entry), NULL); OCI_G(num_links)++; } else { -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - connection->rsrc_id = zend_list_insert(connection, le_connection TSRMLS_CC); -#else - connection->rsrc_id = zend_list_insert(connection, le_connection); -#endif + PHP_OCI_REGISTER_RESOURCE(connection, le_connection); OCI_G(num_links)++; } - /* Debug statements {{{ */ - if (OCI_G(debug_mode)) { - if (connection->is_persistent) { - php_printf ("OCI8 DEBUG L1: New Persistent Connection address: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); - } else { - php_printf ("OCI8 DEBUG L1: New Non-Persistent Connection address: (%p) at (%s:%d) \n", connection, __FILE__, __LINE__); - } - php_printf ("OCI8 DEBUG L1: num_persistent=(%ld), num_links=(%ld) at (%s:%d) \n", OCI_G(num_persistent), OCI_G(num_links), __FILE__, __LINE__); - } /* }}} */ +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_TYPE_ENABLED()) { + DTRACE_OCI8_CONNECT_TYPE(connection->is_persistent ? 1 : 0, exclusive ? 1 : 0, connection, OCI_G(num_persistent), OCI_G(num_links)); + } +#endif /* HAVE_OCI8_DTRACE */ return connection; } @@ -2179,20 +2200,24 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char */ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC) { + sword errstatus; + + OCI_G(errcode) = 0; /* assume ping is successful */ + /* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation) * such as from Pre-10.1 servers, the error is still from the server and we would have * successfully performed a roundtrip and validated the connection. Use OCIServerVersion for * Pre-10.2 clients */ #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIPing available 10.2 onwards */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT)); + PHP_OCI_CALL_RETURN(errstatus, OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT)); #else char version[256]; /* use good old OCIServerVersion() */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX)); + PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX)); #endif - if (OCI_G(errcode) == OCI_SUCCESS) { + if (errstatus == OCI_SUCCESS) { return 1; } else { sb4 error_code = 0; @@ -2203,10 +2228,9 @@ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC) if (error_code == 1010) { return 1; } + OCI_G(errcode) = error_code; } - /* ignore errors here, just return failure - * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */ return 0; } /* }}} */ @@ -2217,17 +2241,17 @@ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC) */ static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC) { - ub4 ss = 0; + ub4 ss = OCI_SERVER_NOT_CONNECTED; + sword errstatus; /* get OCI_ATTR_SERVER_STATUS */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err))); - if (OCI_G(errcode) == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) { + if (errstatus == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) { return 1; } - /* ignore errors here, just return failure - * php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */ + /* ignore errors here, just return failure */ return 0; } /* }}} */ @@ -2238,16 +2262,20 @@ static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC) */ int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC) { - PHP_OCI_CALL_RETURN(connection->errcode, OCITransRollback, (connection->svc, connection->err, (ub4) 0)); - connection->needs_commit = 0; + sword errstatus; + + PHP_OCI_CALL_RETURN(errstatus, OCITransRollback, (connection->svc, connection->err, (ub4) 0)); + connection->rb_on_disconnect = 0; - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_connection_commit() * @@ -2255,16 +2283,20 @@ int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC) */ int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC) { - PHP_OCI_CALL_RETURN(connection->errcode, OCITransCommit, (connection->svc, connection->err, (ub4) 0)); - connection->needs_commit = 0; + sword errstatus; - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + PHP_OCI_CALL_RETURN(errstatus, OCITransCommit, (connection->svc, connection->err, (ub4) 0)); + connection->rb_on_disconnect = 0; + + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_connection_close() * @@ -2275,13 +2307,19 @@ static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC) int result = 0; zend_bool in_call_save = OCI_G(in_call); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECTION_CLOSE_ENABLED()) { + DTRACE_OCI8_CONNECTION_CLOSE(connection); + } +#endif /* HAVE_OCI8_DTRACE */ + if (!connection->is_stub) { /* Release resources associated with connection */ php_oci_connection_release(connection TSRMLS_CC); } if (!connection->using_spool && connection->svc) { - PHP_OCI_CALL(OCISessionEnd, (connection->svc, connection->err, connection->session, (ub4) 0)); + PHP_OCI_CALL(OCISessionEnd, (connection->svc, connection->err, connection->session, (ub4) 0)); } if (connection->err) { @@ -2302,7 +2340,7 @@ static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC) } if (connection->svc) { - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); } if (connection->server) { @@ -2319,21 +2357,20 @@ static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC) php_oci_spool_close(connection->private_spool TSRMLS_CC); } - if (connection->is_persistent) { - if (connection->hash_key) { - free(connection->hash_key); - } - free(connection); - } else { - if (connection->hash_key) { - efree(connection->hash_key); - } - efree(connection); + if (connection->hash_key) { + pefree(connection->hash_key, connection->is_persistent); + } +#ifdef HAVE_OCI8_DTRACE + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); } +#endif /* HAVE_OCI8_DTRACE */ + pefree(connection, connection->is_persistent); connection = NULL; OCI_G(in_call) = in_call_save; return result; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_connection_release() * @@ -2357,7 +2394,7 @@ int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC) if (connection->svc) { /* rollback outstanding transactions */ - if (connection->needs_commit) { + if (connection->rb_on_disconnect) { if (php_oci_connection_rollback(connection TSRMLS_CC)) { /* rollback failed */ result = 1; @@ -2408,18 +2445,25 @@ int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC) connection->server = NULL; connection->session = NULL; - connection->is_attached = connection->is_open = connection->needs_commit = connection->used_this_request = 0; + connection->is_attached = connection->is_open = connection->rb_on_disconnect = connection->used_this_request = 0; connection->is_stub = 1; /* Cut the link between the connection structure and the time_t structure allocated within * the OCI session */ connection->next_pingp = NULL; +#ifdef HAVE_OCI8_DTRACE + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); + connection->client_id = NULL; + } +#endif /* HAVE_OCI8_DTRACE */ } OCI_G(in_call) = in_call_save; return result; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_password_change() * @@ -2427,17 +2471,20 @@ int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC) */ int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len TSRMLS_DC) { - PHP_OCI_CALL_RETURN(connection->errcode, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT)); + sword errstatus; - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + PHP_OCI_CALL_RETURN(errstatus, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT)); + + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ connection->passwd_changed = 1; return 0; -} /* }}} */ - +} +/* }}} */ /* {{{ php_oci_client_get_version() * @@ -2446,21 +2493,21 @@ int php_oci_password_change(php_oci_connection *connection, char *user, int user void php_oci_client_get_version(char **version TSRMLS_DC) { char version_buff[256]; +#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIClientVersion only available 10.2 onwards */ sword major_version = 0; sword minor_version = 0; sword update_num = 0; sword patch_num = 0; sword port_update_num = 0; -#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIClientVersion only available 10.2 onwards */ PHP_OCI_CALL(OCIClientVersion, (&major_version, &minor_version, &update_num, &patch_num, &port_update_num)); snprintf(version_buff, sizeof(version_buff), "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num); #else memcpy(version_buff, "Unknown", sizeof("Unknown")); #endif *version = estrdup(version_buff); -} /* }}} */ - +} +/* }}} */ /* {{{ php_oci_server_get_version() * @@ -2468,19 +2515,21 @@ void php_oci_client_get_version(char **version TSRMLS_DC) */ int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC) { + sword errstatus; char version_buff[256]; - PHP_OCI_CALL_RETURN(connection->errcode, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX)); + PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } *version = estrdup(version_buff); return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_column_to_zval() * @@ -2564,14 +2613,19 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSR } /* }}} */ + /* {{{ php_oci_fetch_row() * * Fetch the next row from the given statement + * Has logic for Oracle 12c Implicit Result Sets */ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args) { zval *z_statement, *array; - php_oci_statement *statement; + php_oci_statement *statement; /* statement that will be fetched from */ +#if (OCI_MAJOR_VERSION >= 12) + php_oci_statement *invokedstatement; /* statement this function was invoked with */ +#endif /* OCI_MAJOR_VERSION */ php_oci_out_column *column; ub4 nrows = 1; int i; @@ -2617,11 +2671,63 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg } } +#if (OCI_MAJOR_VERSION < 12) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) { - RETURN_FALSE; + RETURN_FALSE; /* end of fetch */ } +#else /* OCI_MAJOR_VERSION */ + PHP_OCI_ZVAL_TO_STATEMENT(z_statement, invokedstatement); + + if (invokedstatement->impres_flag == PHP_OCI_IMPRES_NO_CHILDREN) { + /* Already know there are no Implicit Result Sets */ + statement = invokedstatement; + } else if (invokedstatement->impres_flag == PHP_OCI_IMPRES_HAS_CHILDREN) { + /* Previously saw an Implicit Result Set in an earlier invocation of php_oci_fetch_row */ + statement = (php_oci_statement *)invokedstatement->impres_child_stmt; + } else { + sword errstatus; + + /* Check for an Implicit Result Set on this statement handle */ + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)invokedstatement->stmt, OCI_HTYPE_STMT, + (dvoid *) &invokedstatement->impres_count, + (ub4 *)NULL, OCI_ATTR_IMPLICIT_RESULT_COUNT, invokedstatement->err)); + if (errstatus) { + RETURN_FALSE; + } + if (invokedstatement->impres_count > 0) { + /* Make it so the fetch occurs on the first Implicit Result Set */ + statement = php_oci_get_implicit_resultset(invokedstatement TSRMLS_CC); + if (!statement || php_oci_statement_execute(statement, (ub4)OCI_DEFAULT TSRMLS_CC)) + RETURN_FALSE; + invokedstatement->impres_count--; + invokedstatement->impres_child_stmt = (struct php_oci_statement *)statement; + invokedstatement->impres_flag = PHP_OCI_IMPRES_HAS_CHILDREN; + } else { + statement = invokedstatement; /* didn't find Implicit Result Sets */ + invokedstatement->impres_flag = PHP_OCI_IMPRES_NO_CHILDREN; /* Don't bother checking again */ + } + } + + if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) { + /* End of fetch */ + if (invokedstatement->impres_count > 0) { + /* Check next Implicit Result Set */ + statement = php_oci_get_implicit_resultset(invokedstatement TSRMLS_CC); + if (!statement || php_oci_statement_execute(statement, (ub4)OCI_DEFAULT TSRMLS_CC)) + RETURN_FALSE; + invokedstatement->impres_count--; + invokedstatement->impres_child_stmt = (struct php_oci_statement *)statement; + if (php_oci_statement_fetch(statement, nrows TSRMLS_CC)) { + /* End of all fetches */ + RETURN_FALSE; + } + } else { + RETURN_FALSE; + } + } +#endif /* OCI_MAJOR_VERSION */ array_init(return_value); @@ -2688,9 +2794,11 @@ static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC) connection = (php_oci_connection *)le->ptr; if (!connection->used_this_request && OCI_G(persistent_timeout) != -1) { - if (OCI_G(debug_mode)) { - php_printf ("OCI8 DEBUG L1: persistent_helper processing for timeout: (%p stub=%d) at (%s:%d) \n", connection, connection->is_stub, __FILE__, __LINE__); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_EXPIRY_ENABLED()) { + DTRACE_OCI8_CONNECT_EXPIRY(connection, connection->is_stub ? 1 : 0, (long)connection->idle_expiry, (long)timestamp); } +#endif /* HAVE_OCI8_DTRACE */ if (connection->idle_expiry < timestamp) { /* connection has timed out */ return ZEND_HASH_APPLY_REMOVE; @@ -2698,7 +2806,8 @@ static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC) } } return ZEND_HASH_APPLY_KEEP; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_create_spool() * @@ -2710,6 +2819,7 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha zend_bool iserror = 0; ub4 poolmode = OCI_DEFAULT; /* Mode to be passed to OCISessionPoolCreate */ OCIAuthInfo *spoolAuth = NULL; + sword errstatus; /* Allocate sessionpool out of persistent memory */ session_pool = (php_oci_spool *) calloc(1, sizeof(php_oci_spool)); @@ -2734,10 +2844,10 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha } /* Allocate the pool handle */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0)); + PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; } @@ -2746,10 +2856,10 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha * generic bug which can free up the OCI_G(err) variable before destroying connections. We * cannot use this for other roundtrip calls as there is no way the user can access this error */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0)); + PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; } @@ -2762,52 +2872,56 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha #endif #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2))) - /* Allocate auth handle for session pool {{{ */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL)); + /* {{{ Allocate auth handle for session pool */ + PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; - } /* }}} */ + } + /* }}} */ - /* Set the edition attribute on the auth handle {{{ */ + /* {{{ Set the edition attribute on the auth handle */ if (OCI_G(edition)) { - PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err))); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; } - } /* }}} */ + } + /* }}} */ - /* Set the driver name attribute on the auth handle {{{ */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err))); + /* {{{ Set the driver name attribute on the auth handle */ + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err))); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; - } /* }}} */ + } + /* }}} */ - /* Set the auth handle on the session pool {{{ */ - PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err))); + /* {{{ Set the auth handle on the session pool */ + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err))); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; goto exit_create_spool; - } /* }}} */ + } + /* }}} */ #endif /* Create the homogeneous session pool - We have different session pools for every different * username, password, charset and dbname. */ - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode)); + PHP_OCI_CALL_RETURN(errstatus, OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); iserror = 1; } @@ -2821,12 +2935,15 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha PHP_OCI_CALL(OCIHandleFree, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO)); } - if (OCI_G(debug_mode)) { - php_printf ("OCI8 DEBUG L1: create_spool: (%p) at (%s:%d) \n", session_pool, __FILE__, __LINE__); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_SESSPOOL_CREATE_ENABLED()) { + DTRACE_OCI8_SESSPOOL_CREATE(session_pool); } +#endif /* HAVE_OCI8_DTRACE */ return session_pool; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_get_spool() * @@ -2841,7 +2958,7 @@ static php_oci_spool *php_oci_get_spool(char *username, int username_len, char * zend_rsrc_list_entry *spool_out_le = NULL; zend_bool iserror = 0; - /* Create the spool hash key {{{ */ + /* {{{ Create the spool hash key */ smart_str_appendl_ex(&spool_hashed_details, "oci8spool***", sizeof("oci8spool***") - 1, 0); smart_str_appendl_ex(&spool_hashed_details, username, username_len, 0); smart_str_appendl_ex(&spool_hashed_details, "**", sizeof("**") - 1, 0); @@ -2880,11 +2997,7 @@ static php_oci_spool *php_oci_get_spool(char *username, int username_len, char * } spool_le.ptr = session_pool; spool_le.type = le_psessionpool; -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) - zend_list_insert(session_pool, le_psessionpool TSRMLS_CC); -#else - zend_list_insert(session_pool, le_psessionpool); -#endif + PHP_OCI_REGISTER_RESOURCE(session_pool, le_psessionpool); zend_hash_update(&EG(persistent_list), session_pool->spool_hash_key, strlen(session_pool->spool_hash_key)+1,(void *)&spool_le, sizeof(zend_rsrc_list_entry),NULL); } else if (spool_out_le->type == le_psessionpool && strlen(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key) == spool_hashed_details.len && @@ -2902,7 +3015,8 @@ static php_oci_spool *php_oci_get_spool(char *username, int username_len, char * return session_pool; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_create_env() * @@ -2933,7 +3047,8 @@ static OCIEnv *php_oci_create_env(ub2 charsetid TSRMLS_DC) return NULL; } return retenv; -}/* }}} */ +} +/* }}} */ /* {{{ php_oci_old_create_session() * @@ -2944,57 +3059,58 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna { ub4 statement_cache_size = (OCI_G(statement_cache_size) > 0) ? OCI_G(statement_cache_size) : 0; - if (OCI_G(debug_mode)) { - php_printf ("OCI8 DEBUG: Bypassing client-side session pool for session create at (%s:%d) \n", __FILE__, __LINE__); - } - /* Create the OCI environment separate for each connection */ if (!(connection->env = php_oci_create_env(connection->charset TSRMLS_CC))) { return 1; } - /* Allocate our server handle {{{ */ + /* {{{ Allocate our server handle */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->server), OCI_HTYPE_SERVER, 0, NULL)); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ - /* Attach to the server {{{ */ + /* {{{ Attach to the server */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerAttach, (connection->server, OCI_G(err), (text *)dbname, dbname_len, (ub4) OCI_DEFAULT)); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ connection->is_attached = 1; - /* Allocate our session handle {{{ */ + /* {{{ Allocate our session handle */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->session), OCI_HTYPE_SESSION, 0, NULL)); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ - /* Allocate our private error-handle {{{ */ + /* {{{ Allocate our private error-handle */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->err), OCI_HTYPE_ERROR, 0, NULL)); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ - /* Allocate our service-context {{{ */ + /* {{{ Allocate our service-context */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (connection->env, (dvoid **)&(connection->svc), OCI_HTYPE_SVCCTX, 0, NULL)); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ - /* Set the username {{{ */ + /* {{{ Set the username */ if (username) { PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) username, (ub4) username_len, (ub4) OCI_ATTR_USERNAME, OCI_G(err))); @@ -3002,9 +3118,10 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; } - }/* }}} */ + } + /* }}} */ - /* Set the password {{{ */ + /* {{{ Set the password */ if (password) { PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) password_len, (ub4) OCI_ATTR_PASSWORD, OCI_G(err))); @@ -3012,9 +3129,10 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; } - }/* }}} */ + } + /* }}} */ - /* Set the edition attribute on the session handle {{{ */ + /* {{{ Set the edition attribute on the session handle */ #if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2))) if (OCI_G(edition)) { PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(edition), (ub4) (strlen(OCI_G(edition))), (ub4) OCI_ATTR_EDITION, OCI_G(err))); @@ -3024,9 +3142,10 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna return 1; } } -#endif /* }}} */ +#endif +/* }}} */ - /* Set the driver name attribute on the session handle {{{ */ + /* {{{ Set the driver name attribute on the session handle */ #if (OCI_MAJOR_VERSION >= 11) PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err))); @@ -3034,26 +3153,29 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; } -#endif /* }}} */ +#endif +/* }}} */ - /* Set the server handle in the service handle {{{ */ + /* {{{ Set the server handle in the service handle */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->server, 0, OCI_ATTR_SERVER, OCI_G(err))); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ - /* Set the authentication handle in the service handle {{{ */ + /* {{{ Set the authentication handle in the service handle */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, (connection->svc, OCI_HTYPE_SVCCTX, connection->session, 0, OCI_ATTR_SESSION, OCI_G(err))); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ if (new_password) { - /* Try to change password if new one was provided {{{ */ + /* {{{ Try to change password if new one was provided */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPasswordChange, (connection->svc, OCI_G(err), (text *)username, username_len, (text *)password, password_len, (text *)new_password, new_password_len, OCI_AUTH)); if (OCI_G(errcode) != OCI_SUCCESS) { @@ -3066,9 +3188,10 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); return 1; - } /* }}} */ + } + /* }}} */ } else { - /* start the session {{{ */ + /* {{{ start the session */ ub4 cred_type = OCI_CRED_RDBMS; /* Extract the overloaded session_mode parameter into valid Oracle credential and session mode values */ @@ -3089,7 +3212,8 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna if (OCI_G(errcode) != OCI_SUCCESS_WITH_INFO) { return 1; } - } /* }}} */ + } + /* }}} */ } /* Brand new connection: Init and update the next_ping in the connection */ @@ -3107,7 +3231,8 @@ static int php_oci_old_create_session(php_oci_connection *connection, char *dbna /* Successfully created session */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_create_session() * @@ -3138,13 +3263,11 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool connection->using_spool = 1; } - if (OCI_G(debug_mode)) { - if (session_pool) { - php_printf ("OCI8 DEBUG L1: using shared pool: (%p) at (%s:%d) \n", session_pool, __FILE__, __LINE__); - } else { - php_printf ("OCI8 DEBUG L1: using private pool: (%p) at (%s:%d) \n", connection->private_spool, __FILE__, __LINE__); - } +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_SESSPOOL_TYPE_ENABLED()) { + DTRACE_OCI8_SESSPOOL_TYPE(session_pool ? 1 : 0, session_pool ? session_pool : connection->private_spool); } +#endif /* HAVE_OCI8_DTRACE */ /* The passed in "connection" can be a cached stub from plist or freshly created. In the former * case, we do not have to allocate any handles @@ -3170,7 +3293,7 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool /* Set the Connection class and purity if OCI client version >= 11g */ #if (OCI_MAJOR_VERSION > 10) - PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(connection_class), (ub4)(strlen(OCI_G(connection_class))), (ub4)OCI_ATTR_CONNECTION_CLASS, OCI_G(err))); + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->authinfo,(ub4) OCI_HTYPE_SESSION, (dvoid *) OCI_G(connection_class), (ub4)(strlen(OCI_G(connection_class))), (ub4)OCI_ATTR_CONNECTION_CLASS, OCI_G(err))); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); @@ -3189,16 +3312,20 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool return 1; } #endif - } /* }}} */ + } + /* }}} */ - /* Debug statements {{{ */ - if (OCI_G(debug_mode)) { + /* {{{ Debug statements */ +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_SESSPOOL_STATS_ENABLED()) { ub4 numfree = 0, numbusy = 0, numopen = 0; PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numopen, (ub4 *)0, OCI_ATTR_SPOOL_OPEN_COUNT, OCI_G(err))); PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numbusy, (ub4 *)0, OCI_ATTR_SPOOL_BUSY_COUNT, OCI_G(err))); numfree = numopen - numbusy; /* number of free connections in the pool */ - php_printf ("OCI8 DEBUG L1: (numopen=%d)(numbusy=%d)(numfree=%d) at (%s:%d) \n", numopen, numbusy, numfree, __FILE__, __LINE__); - } /* }}} */ + DTRACE_OCI8_SESSPOOL_STATS(numfree, numbusy, numopen); + } +#endif /* HAVE_OCI8_DTRACE */ + /* }}} */ /* Ping loop: Ping and loop till we get a good connection. When a database instance goes * down, it can leave several bad connections that need to be flushed out before getting a @@ -3225,7 +3352,8 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool /* {{{ Populate the session and server fields of the connection */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->server), (ub4 *)0, OCI_ATTR_SERVER, OCI_G(err))); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err))); /* }}} */ + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->svc, OCI_HTYPE_SVCCTX, (dvoid *)&(connection->session), (ub4 *)0, OCI_ATTR_SESSION, OCI_G(err))); + /* }}} */ PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIContextGetValue, (connection->session, OCI_G(err), (ub1 *)"NEXT_PING", (ub1)sizeof("NEXT_PING"), (void **)&(connection->next_pingp))); if (OCI_G(errcode) != OCI_SUCCESS) { @@ -3265,7 +3393,8 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool connection->is_attached = connection->is_open = 1; return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_spool_list_dtor() * @@ -3280,7 +3409,8 @@ static void php_oci_spool_list_dtor(zend_rsrc_list_entry *entry TSRMLS_DC) } return; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_spool_close() * @@ -3310,7 +3440,8 @@ static void php_oci_spool_close(php_oci_spool *session_pool TSRMLS_DC) } free(session_pool); -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_ping_init() * @@ -3353,7 +3484,22 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS connection->next_pingp = next_pingp; return OCI_SUCCESS; -} /* }}} */ +} +/* }}} */ + +/* {{{ php_oci_dtrace_check_connection() + * + * DTrace output for connections that may have become invalid and marked for reopening + */ +void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus) +{ +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CHECK_CONNECTION_ENABLED()) { + DTRACE_OCI8_CHECK_CONNECTION(connection, connection->client_id, connection->is_open ? 1 : 0, (long)errcode, (unsigned long)serverStatus); + } +#endif /* HAVE_OCI8_DTRACE */ +} +/* }}} */ #endif /* HAVE_OCI8 */ diff --git a/ext/oci8/oci8_collection.c b/ext/oci8/oci8_collection.c index 763e12e9249d7..35b70fa7af73f 100644 --- a/ext/oci8/oci8_collection.c +++ b/ext/oci8/oci8_collection.c @@ -44,21 +44,22 @@ /* {{{ php_oci_collection_create() Create and return connection handle */ -php_oci_collection * php_oci_collection_create(php_oci_connection *connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC) +php_oci_collection *php_oci_collection_create(php_oci_connection *connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC) { dvoid *dschp1 = NULL; dvoid *parmp1; dvoid *parmp2; php_oci_collection *collection; + sword errstatus; collection = emalloc(sizeof(php_oci_collection)); collection->connection = connection; collection->collection = NULL; - zend_list_addref(collection->connection->rsrc_id); + zend_list_addref(collection->connection->id); /* get type handle by name */ - PHP_OCI_CALL_RETURN(connection->errcode, OCITypeByName, + PHP_OCI_CALL_RETURN(errstatus, OCITypeByName, ( connection->env, connection->err, @@ -75,19 +76,19 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* allocate describe handle */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIHandleAlloc, (connection->env, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0)); + PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (connection->env, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* describe TDO */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIDescribeAny, + PHP_OCI_CALL_RETURN(errstatus, OCIDescribeAny, ( connection->svc, connection->err, @@ -100,19 +101,19 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* get first parameter handle */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, ((dvoid *) dschp1, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM, connection->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *) dschp1, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM, connection->err)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* get the collection type code of the attribute */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ( (dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, @@ -123,7 +124,7 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } @@ -131,7 +132,7 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c case OCI_TYPECODE_TABLE: case OCI_TYPECODE_VARRAY: /* get collection element handle */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ( (dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM, @@ -142,12 +143,12 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* get REF of the TDO for the type */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ( (dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, @@ -158,12 +159,12 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* get the TDO (only header) */ - PHP_OCI_CALL_RETURN(connection->errcode, OCITypeByRef, + PHP_OCI_CALL_RETURN(errstatus, OCITypeByRef, ( connection->env, connection->err, @@ -174,12 +175,12 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* get typecode */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIAttrGet, + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ( (dvoid*) parmp2, (ub4) OCI_DTYPE_PARAM, @@ -190,7 +191,7 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } break; @@ -201,7 +202,7 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c } /* Create object to hold return table */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIObjectNew, + PHP_OCI_CALL_RETURN(errstatus, OCIObjectNew, ( connection->env, connection->err, @@ -215,13 +216,14 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c ) ); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { goto CLEANUP; } /* free the describe handle (Bug #44113) */ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE)); PHP_OCI_REGISTER_RESOURCE(collection, le_collection); + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return collection; CLEANUP: @@ -230,27 +232,31 @@ php_oci_collection * php_oci_collection_create(php_oci_connection *connection, c /* free the describe handle (Bug #44113) */ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE)); } - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); php_oci_collection_close(collection TSRMLS_CC); return NULL; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_size() Return size of the collection */ int php_oci_collection_size(php_oci_collection *collection, sb4 *size TSRMLS_DC) { php_oci_connection *connection = collection->connection; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCICollSize, (connection->env, connection->err, collection->collection, (sb4 *)size)); + PHP_OCI_CALL_RETURN(errstatus, OCICollSize, (connection->env, connection->err, collection->collection, (sb4 *)size)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_max() Return max number of elements in the collection */ @@ -262,23 +268,27 @@ int php_oci_collection_max(php_oci_collection *collection, long *max TSRMLS_DC) /* error handling is not necessary here? */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_trim() Trim collection to the given number of elements */ int php_oci_collection_trim(php_oci_collection *collection, long trim_size TSRMLS_DC) { php_oci_connection *connection = collection->connection; - - PHP_OCI_CALL_RETURN(connection->errcode, OCICollTrim, (connection->env, connection->err, trim_size, collection->collection)); + sword errstatus; + + PHP_OCI_CALL_RETURN(errstatus, OCICollTrim, (connection->env, connection->err, trim_size, collection->collection)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + errstatus = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_append_null() Append NULL element to the end of the collection */ @@ -286,17 +296,20 @@ int php_oci_collection_append_null(php_oci_collection *collection TSRMLS_DC) { OCIInd null_index = OCI_IND_NULL; php_oci_connection *connection = collection->connection; + sword errstatus; /* append NULL element */ - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAppend, (connection->env, connection->err, (dvoid *)0, &null_index, collection->collection)); + PHP_OCI_CALL_RETURN(errstatus, OCICollAppend, (connection->env, connection->err, (dvoid *)0, &null_index, collection->collection)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + errstatus = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_append_date() Append DATE element to the end of the collection (use "DD-MON-YY" format) */ @@ -305,18 +318,19 @@ int php_oci_collection_append_date(php_oci_collection *collection, char *date, i OCIInd new_index = OCI_IND_NOTNULL; OCIDate oci_date; php_oci_connection *connection = collection->connection; + sword errstatus; /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { /* failed to convert string to date */ - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAppend, + PHP_OCI_CALL_RETURN(errstatus, OCICollAppend, ( connection->env, connection->err, @@ -326,14 +340,16 @@ int php_oci_collection_append_date(php_oci_collection *collection, char *date, i ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_append_number() Append NUMBER to the end of the collection */ @@ -343,24 +359,19 @@ int php_oci_collection_append_number(php_oci_collection *collection, char *numbe double element_double; OCINumber oci_number; php_oci_connection *connection = collection->connection; + sword errstatus; -#if (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION < 10) - /* minimum PHP version ext/oci8/config.m4 accepts is 4.3.9 */ - element_double = strtod(number, NULL); -#else - /* zend_strtod was introduced in PHP 4.3.10 */ element_double = zend_strtod(number, NULL); -#endif - PHP_OCI_CALL_RETURN(connection->errcode, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); + PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAppend, + PHP_OCI_CALL_RETURN(errstatus, OCICollAppend, ( connection->env, connection->err, @@ -370,14 +381,16 @@ int php_oci_collection_append_number(php_oci_collection *collection, char *numbe ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_append_string() Append STRING to the end of the collection */ @@ -386,16 +399,17 @@ int php_oci_collection_append_string(php_oci_collection *collection, char *eleme OCIInd new_index = OCI_IND_NOTNULL; OCIString *ocistr = (OCIString *)0; php_oci_connection *connection = collection->connection; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr)); + PHP_OCI_CALL_RETURN(errstatus, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAppend, + PHP_OCI_CALL_RETURN(errstatus, OCICollAppend, ( connection->env, connection->err, @@ -405,14 +419,16 @@ int php_oci_collection_append_string(php_oci_collection *collection, char *eleme ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_append() Append wrapper. Appends any supported element to the end of the collection */ @@ -452,7 +468,8 @@ int php_oci_collection_append(php_oci_collection *collection, char *element, int } /* never reached */ return 1; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_get() Get the element with the given index */ @@ -464,11 +481,14 @@ int php_oci_collection_element_get(php_oci_collection *collection, long index, z boolean exists; oratext buff[1024]; ub4 buff_len = 1024; + sword errstatus; MAKE_STD_ZVAL(*result_element); ZVAL_NULL(*result_element); - PHP_OCI_CALL_RETURN(connection->errcode, OCICollGetElem, + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ + + PHP_OCI_CALL_RETURN(errstatus, OCICollGetElem, ( connection->env, connection->err, @@ -480,8 +500,8 @@ int php_oci_collection_element_get(php_oci_collection *collection, long index, z ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); FREE_ZVAL(*result_element); return 1; @@ -500,10 +520,10 @@ int php_oci_collection_element_get(php_oci_collection *collection, long index, z switch (collection->element_typecode) { case OCI_TYPECODE_DATE: - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, element, 0, 0, 0, 0, &buff_len, buff)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, element, 0, 0, 0, 0, &buff_len, buff)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); FREE_ZVAL(*result_element); return 1; @@ -543,10 +563,10 @@ int php_oci_collection_element_get(php_oci_collection *collection, long index, z { double double_number; - PHP_OCI_CALL_RETURN(connection->errcode, OCINumberToReal, (connection->err, (CONST OCINumber *) element, (uword) sizeof(double), (dvoid *) &double_number)); + PHP_OCI_CALL_RETURN(errstatus, OCINumberToReal, (connection->err, (CONST OCINumber *) element, (uword) sizeof(double), (dvoid *) &double_number)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); FREE_ZVAL(*result_element); return 1; @@ -565,7 +585,8 @@ int php_oci_collection_element_get(php_oci_collection *collection, long index, z } /* never reached */ return 1; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_set_null() Set the element with the given index to NULL */ @@ -573,17 +594,20 @@ int php_oci_collection_element_set_null(php_oci_collection *collection, long ind { OCIInd null_index = OCI_IND_NULL; php_oci_connection *connection = collection->connection; + sword errstatus; /* set NULL element */ - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *)"", &null_index, collection->collection)); + PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *)"", &null_index, collection->collection)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_set_date() Change element's value to the given DATE */ @@ -592,18 +616,19 @@ int php_oci_collection_element_set_date(php_oci_collection *collection, long ind OCIInd new_index = OCI_IND_NOTNULL; OCIDate oci_date; php_oci_connection *connection = collection->connection; + sword errstatus; /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */ - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { /* failed to convert string to date */ - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAssignElem, + PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, ( connection->env, connection->err, @@ -614,14 +639,16 @@ int php_oci_collection_element_set_date(php_oci_collection *collection, long ind ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_set_number() Change element's value to the given NUMBER */ @@ -631,24 +658,19 @@ int php_oci_collection_element_set_number(php_oci_collection *collection, long i double element_double; OCINumber oci_number; php_oci_connection *connection = collection->connection; + sword errstatus; -#if (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION < 10) - /* minimum PHP version ext/oci8/config.m4 accepts is 4.3.9 */ - element_double = strtod(number, NULL); -#else - /* zend_strtod was introduced in PHP 4.3.10 */ element_double = zend_strtod(number, NULL); -#endif - PHP_OCI_CALL_RETURN(connection->errcode, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); + PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAssignElem, + PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, ( connection->env, connection->err, @@ -659,14 +681,16 @@ int php_oci_collection_element_set_number(php_oci_collection *collection, long i ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_set_string() Change element's value to the given string */ @@ -675,16 +699,17 @@ int php_oci_collection_element_set_string(php_oci_collection *collection, long i OCIInd new_index = OCI_IND_NOTNULL; OCIString *ocistr = (OCIString *)0; php_oci_connection *connection = collection->connection; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr)); + PHP_OCI_CALL_RETURN(errstatus, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAssignElem, + PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, ( connection->env, connection->err, @@ -695,14 +720,16 @@ int php_oci_collection_element_set_string(php_oci_collection *collection, long i ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_element_set() Collection element setter */ @@ -742,44 +769,51 @@ int php_oci_collection_element_set(php_oci_collection *collection, long index, c } /* never reached */ return 1; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_assign() Assigns a value to the collection from another collection */ int php_oci_collection_assign(php_oci_collection *collection_dest, php_oci_collection *collection_from TSRMLS_DC) { php_oci_connection *connection = collection_dest->connection; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCICollAssign, (connection->env, connection->err, collection_from->collection, collection_dest->collection)); + PHP_OCI_CALL_RETURN(errstatus, OCICollAssign, (connection->env, connection->err, collection_from->collection, collection_dest->collection)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_collection_close() Destroy collection and all associated resources */ void php_oci_collection_close(php_oci_collection *collection TSRMLS_DC) { php_oci_connection *connection = collection->connection; + sword errstatus; if (collection->collection) { - PHP_OCI_CALL_RETURN(connection->errcode, OCIObjectFree, (connection->env, connection->err, (dvoid *)collection->collection, (ub2)OCI_OBJECTFREE_FORCE)); + PHP_OCI_CALL_RETURN(errstatus, OCIObjectFree, (connection->env, connection->err, (dvoid *)collection->collection, (ub2)OCI_OBJECTFREE_FORCE)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); + } else { + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } } - zend_list_delete(collection->connection->rsrc_id); - + zend_list_delete(collection->connection->id); efree(collection); return; -} /* }}} */ +} +/* }}} */ #endif /* HAVE_OCI8 */ diff --git a/ext/oci8/oci8_dtrace.d b/ext/oci8/oci8_dtrace.d new file mode 100644 index 0000000000000..30c98de912828 --- /dev/null +++ b/ext/oci8/oci8_dtrace.d @@ -0,0 +1,36 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the Zend 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.zend.com/license/3_01.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Christopher Jones | + +----------------------------------------------------------------------+ +*/ + +provider phpoci { + probe oci8__check__connection(void *connection, char *client_id, int is_open, long errcode, unsigned long server_status); + probe oci8__connect__entry(char *username, char *dbname, char *charset, long session_mode, int persistent, int exclusive); + probe oci8__connect__return(void *connection); + probe oci8__connection__close(void *connection); + probe oci8__error(int status, long errcode); + probe oci8__execute__mode(void *connection, char *client_id, void *statement, unsigned int mode); + probe oci8__sqltext(void *connection, char *client_id, void *statement, char *sql); + + probe oci8__connect__p__dtor__close(void *connection); + probe oci8__connect__p__dtor__release(void *connection); + probe oci8__connect__lookup(void *connection, int is_stub); + probe oci8__connect__expiry(void *connection, int is_stub, long idle_expiry, long timestamp); + probe oci8__connect__type(int persistent, int exclusive, void *connection, long num_persistent, long num_connections); + probe oci8__sesspool__create(void *session_pool); + probe oci8__sesspool__stats(unsigned long free, unsigned long busy, unsigned long open); + probe oci8__sesspool__type(int type, void *session_pool); +}; diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index e51d3c92f5272..ccaed797429f1 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1308,12 +1308,7 @@ PHP_FUNCTION(oci_field_is_null) Toggle internal debugging output for the OCI extension */ PHP_FUNCTION(oci_internal_debug) { - zend_bool on_off; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &on_off) == FAILURE) { - return; - } - OCI_G(debug_mode) = on_off; + /* NOP in OCI8 2.0. Obsoleted by DTrace probes */ } /* }}} */ @@ -1434,13 +1429,7 @@ PHP_FUNCTION(oci_fetch_all) if (flags & PHP_OCI_NUM) { zend_hash_next_index_insert(Z_ARRVAL_P(row), &element, sizeof(zval*), NULL); } else { /* default to ASSOC */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* zend_symtable_update is only available in 5.2+ */ zend_symtable_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL); -#else - /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */ - zend_hash_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL); -#endif } } @@ -1472,13 +1461,7 @@ PHP_FUNCTION(oci_fetch_all) MAKE_STD_ZVAL(tmp); array_init(tmp); -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* zend_symtable_update is only available in 5.2+ */ zend_symtable_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ])); -#else - /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */ - zend_hash_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ])); -#endif } } @@ -1583,7 +1566,7 @@ PHP_FUNCTION(oci_close) } PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - zend_list_delete(connection->rsrc_id); + zend_list_delete(connection->id); ZVAL_NULL(z_connection); @@ -1591,7 +1574,7 @@ PHP_FUNCTION(oci_close) } /* }}} */ -/* {{{ proto resource oci_new_connect(string user, string pass [, string db]) +/* {{{ proto resource oci_new_connect(string user, string pass [, string db, string charset [, int session_mode ]]) Connect to an Oracle database and log on. Returns a new session. */ PHP_FUNCTION(oci_new_connect) { @@ -1607,7 +1590,7 @@ PHP_FUNCTION(oci_connect) } /* }}} */ -/* {{{ proto resource oci_pconnect(string user, string pass [, string db [, string charset ]]) +/* {{{ proto resource oci_pconnect(string user, string pass [, string db [, string charset [, int session_mode ]]) Connect to an Oracle database using a persistent connection and log on. Returns a new session. */ PHP_FUNCTION(oci_pconnect) { @@ -1624,7 +1607,6 @@ PHP_FUNCTION(oci_error) php_oci_connection *connection; text *errbuf; sb4 errcode = 0; - sword error = OCI_SUCCESS; dvoid *errh = NULL; ub2 error_offset = 0; text *sqltext = NULL; @@ -1635,10 +1617,9 @@ PHP_FUNCTION(oci_error) if (ZEND_NUM_ARGS() > 0) { statement = (php_oci_statement *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_statement); - if (statement) { errh = statement->err; - error = statement->errcode; + errcode = statement->errcode; if (php_oci_fetch_sqltext_offset(statement, &sqltext, &error_offset TSRMLS_CC)) { RETURN_FALSE; @@ -1649,23 +1630,23 @@ PHP_FUNCTION(oci_error) connection = (php_oci_connection *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_connection); if (connection) { errh = connection->err; - error = connection->errcode; + errcode = connection->errcode; goto go_out; } connection = (php_oci_connection *) zend_fetch_resource(&arg TSRMLS_CC, -1, NULL, NULL, 1, le_pconnection); if (connection) { errh = connection->err; - error = connection->errcode; + errcode = connection->errcode; goto go_out; } } else { errh = OCI_G(err); - error = OCI_G(errcode); + errcode = OCI_G(errcode); } go_out: - if (error == OCI_SUCCESS) { /* no error set in the handle */ + if (errcode == 0) { /* no error set in the handle */ RETURN_FALSE; } @@ -1744,7 +1725,12 @@ PHP_FUNCTION(oci_set_prefetch) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - if (php_oci_statement_set_prefetch(statement, size TSRMLS_CC)) { + if (size < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0"); + return; + } + + if (php_oci_statement_set_prefetch(statement, (ub4)size TSRMLS_CC)) { RETURN_FALSE; } RETURN_TRUE; @@ -1759,6 +1745,7 @@ PHP_FUNCTION(oci_set_client_identifier) php_oci_connection *connection; char *client_id; int client_id_len; + sword errstatus; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &client_id, &client_id_len) == FAILURE) { return; @@ -1766,13 +1753,37 @@ PHP_FUNCTION(oci_set_client_identifier) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_id, (ub4) client_id_len, (ub4) OCI_ATTR_CLIENT_IDENTIFIER, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_id, (ub4) client_id_len, (ub4) OCI_ATTR_CLIENT_IDENTIFIER, connection->err)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); RETURN_FALSE; } +#ifdef HAVE_OCI8_DTRACE + /* The alternatives to storing client_id like done below are + i) display it in a probe here in oci_set_client_identifier and + let the user D script correlate the connection address probe + argument and the client_id. This would likely require user D + script variables, which would use kernel memory. + ii) call OCIAttrGet for each probe definition that uses + client_id. This would be slower than storing it. + */ + + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); + } + + if (client_id) { + /* this long winded copy allows compatibility with older PHP versions */ + connection->client_id = (char *)pemalloc(client_id_len+1, connection->is_persistent); + memcpy(connection->client_id, client_id, client_id_len); + connection->client_id[client_id_len] = '\0'; + } else { + connection->client_id = NULL; + } +#endif /* HAVE_OCI8_DTRACE */ + RETURN_TRUE; } /* }}} */ @@ -1791,13 +1802,14 @@ PHP_FUNCTION(oci_set_edition) if (OCI_G(edition)) { efree(OCI_G(edition)); - OCI_G(edition) = NULL; } if (edition) { - OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(text), 0); + OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(char), 0); memcpy(OCI_G(edition), edition, edition_len); OCI_G(edition)[edition_len] = '\0'; + } else { + OCI_G(edition) = NULL; } RETURN_TRUE; @@ -1809,7 +1821,7 @@ PHP_FUNCTION(oci_set_edition) /* }}} */ /* {{{ proto bool oci_set_module_name(resource connection, string value) - Sets the module attribute on the connection */ + Sets the module attribute on the connection for end-to-end tracing */ PHP_FUNCTION(oci_set_module_name) { #if (OCI_MAJOR_VERSION >= 10) @@ -1817,6 +1829,7 @@ PHP_FUNCTION(oci_set_module_name) php_oci_connection *connection; char *module; int module_len; + sword errstatus; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &module, &module_len) == FAILURE) { return; @@ -1824,10 +1837,10 @@ PHP_FUNCTION(oci_set_module_name) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) module, (ub4) module_len, (ub4) OCI_ATTR_MODULE, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) module, (ub4) module_len, (ub4) OCI_ATTR_MODULE, connection->err)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); RETURN_FALSE; } @@ -1840,7 +1853,7 @@ PHP_FUNCTION(oci_set_module_name) /* }}} */ /* {{{ proto bool oci_set_action(resource connection, string value) - Sets the action attribute on the connection */ + Sets the action attribute on the connection for end-to-end tracing */ PHP_FUNCTION(oci_set_action) { #if (OCI_MAJOR_VERSION >= 10) @@ -1848,6 +1861,7 @@ PHP_FUNCTION(oci_set_action) php_oci_connection *connection; char *action; int action_len; + sword errstatus; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &action, &action_len) == FAILURE) { return; @@ -1855,10 +1869,10 @@ PHP_FUNCTION(oci_set_action) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) action, (ub4) action_len, (ub4) OCI_ATTR_ACTION, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) action, (ub4) action_len, (ub4) OCI_ATTR_ACTION, connection->err)); - if (OCI_G(errcode) != OCI_SUCCESS) { - php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); RETURN_FALSE; } @@ -1871,7 +1885,7 @@ PHP_FUNCTION(oci_set_action) /* }}} */ /* {{{ proto bool oci_set_client_info(resource connection, string value) - Sets the client info attribute on the connection */ + Sets the client info attribute on the connection for end-to-end tracing */ PHP_FUNCTION(oci_set_client_info) { #if (OCI_MAJOR_VERSION >= 10) @@ -1879,6 +1893,7 @@ PHP_FUNCTION(oci_set_client_info) php_oci_connection *connection; char *client_info; int client_info_len; + sword errstatus; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &client_info, &client_info_len) == FAILURE) { return; @@ -1886,13 +1901,44 @@ PHP_FUNCTION(oci_set_client_info) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_info, (ub4) client_info_len, (ub4) OCI_ATTR_CLIENT_INFO, OCI_G(err))); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) client_info, (ub4) client_info_len, (ub4) OCI_ATTR_CLIENT_INFO, connection->err)); + + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ + +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +/* {{{ proto bool oci_set_db_operation(resource connection, string value) + Sets the "DB operation" on the connection for Oracle end-to-end tracing */ +PHP_FUNCTION(oci_set_db_operation) +{ +#if (OCI_MAJOR_VERSION > 11) + zval *z_connection; + php_oci_connection *connection; + char *dbop_name; + int dbop_name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &dbop_name, &dbop_name_len) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) dbop_name, (ub4) dbop_name_len, (ub4) OCI_ATTR_DBOP, OCI_G(err))); if (OCI_G(errcode) != OCI_SUCCESS) { php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); RETURN_FALSE; } - RETURN_TRUE; #else php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); @@ -1900,6 +1946,7 @@ PHP_FUNCTION(oci_set_client_info) #endif } /* }}} */ +#endif /* WAITIING_ORACLE_BUG_16695981_FIX */ /* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password) Changes the password of an account */ @@ -1957,7 +2004,7 @@ PHP_FUNCTION(oci_password_change) if (!connection) { RETURN_FALSE; } - RETURN_RESOURCE(connection->rsrc_id); + RETURN_RESOURCE(connection->id); } WRONG_PARAM_COUNT; } @@ -2395,6 +2442,32 @@ PHP_FUNCTION(oci_new_collection) } /* }}} */ +/* {{{ proto bool oci_get_implicit(resource stmt) + Get the next statement resource from an Oracle 12c PL/SQL Implicit Result Set */ +PHP_FUNCTION(oci_get_implicit_resultset) +{ + zval *z_statement; + php_oci_statement *statement; + php_oci_statement *imp_statement; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_statement) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); + + imp_statement = php_oci_get_implicit_resultset(statement TSRMLS_CC); + + if (imp_statement) { + if (php_oci_statement_execute(imp_statement, (ub4)OCI_DEFAULT TSRMLS_CC)) + RETURN_FALSE; + RETURN_RESOURCE(imp_statement->id); + } + RETURN_FALSE; +} + +/* }}} */ + #endif /* HAVE_OCI8 */ /* diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c index d05e053919217..4f58c65737f97 100644 --- a/ext/oci8/oci8_lob.c +++ b/ext/oci8/oci8_lob.c @@ -54,6 +54,7 @@ php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long type TSRMLS_DC) { php_oci_descriptor *descriptor; + sword errstatus; switch (type) { case OCI_DTYPE_FILE: @@ -70,15 +71,17 @@ php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long typ descriptor = ecalloc(1, sizeof(php_oci_descriptor)); descriptor->type = type; descriptor->connection = connection; - zend_list_addref(descriptor->connection->rsrc_id); + zend_list_addref(descriptor->connection->id); - PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0)); + PHP_OCI_CALL_RETURN(errstatus, OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0)); - if (OCI_G(errcode) != OCI_SUCCESS) { - OCI_G(errcode) = php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, OCI_G(errcode)); efree(descriptor); return NULL; + } else { + OCI_G(errcode) = 0; /* retain backwards compat with OCI8 1.4 */ } PHP_OCI_REGISTER_RESOURCE(descriptor, le_descriptor); @@ -109,13 +112,15 @@ php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, long typ } return descriptor; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_get_length() Get length of the LOB. The length is cached so we don't need to ask Oracle every time */ int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; + sword errstatus; *length = 0; @@ -124,18 +129,18 @@ int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_D return 0; } else { if (descriptor->type == OCI_DTYPE_FILE) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY)); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobGetLength, (connection->svc, connection->err, descriptor->descriptor, (ub4 *)length)); + PHP_OCI_CALL_RETURN(errstatus, OCILobGetLength, (connection->svc, connection->err, descriptor->descriptor, (ub4 *)length)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } @@ -143,25 +148,24 @@ int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_D descriptor->lob_size = *length; if (descriptor->type == OCI_DTYPE_FILE) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor)); + PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } } + + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_callback() Append LOB portion to a memory buffer */ -#if defined(HAVE_OCI_LOB_READ2) sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp) -#else -sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece) -#endif { ub4 lenp = (ub4) len; php_oci_lob_ctx *ctx = (php_oci_lob_ctx *)ctxp; @@ -203,25 +207,28 @@ sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece) } /* }}} */ -/* {{{ php_oci_lob_calculate_buffer() */ +/* {{{ php_oci_lob_calculate_buffer() + Work out the size for LOB buffering */ static inline int php_oci_lob_calculate_buffer(php_oci_descriptor *descriptor, long read_length TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; ub4 chunk_size; + sword errstatus; if (descriptor->type == OCI_DTYPE_FILE) { return read_length; } if (!descriptor->chunk_size) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobGetChunkSize, (connection->svc, connection->err, descriptor->descriptor, &chunk_size)); + PHP_OCI_CALL_RETURN(errstatus, OCILobGetChunkSize, (connection->svc, connection->err, descriptor->descriptor, &chunk_size)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return read_length; /* we have to return original length here */ } descriptor->chunk_size = chunk_size; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } if ((read_length % descriptor->chunk_size) != 0) { @@ -240,16 +247,12 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini int buffer_size = PHP_OCI_LOB_BUFFER_SIZE; php_oci_lob_ctx ctx; ub1 *bufp; -#if defined(HAVE_OCI_LOB_READ2) oraub8 bytes_read, offset = 0; oraub8 requested_len = read_length; /* this is by default */ oraub8 chars_read = 0; -#else - int bytes_read, offset = 0; - int requested_len = read_length; /* this is by default */ -#endif int is_clob = 0; sb4 bytes_per_char = 1; + sword errstatus; *data_len = 0; *data = NULL; @@ -286,20 +289,20 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini offset = initial_offset; if (descriptor->type == OCI_DTYPE_FILE) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY)); + PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } } else { ub2 charset_id = 0; - PHP_OCI_CALL_RETURN(connection->errcode, OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id)); + PHP_OCI_CALL_RETURN(errstatus, OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } @@ -310,10 +313,10 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini } if (is_clob) { - PHP_OCI_CALL_RETURN(connection->errcode, OCINlsNumericInfoGet, (connection->env, connection->err, &bytes_per_char, OCI_NLS_CHARSET_MAXBYTESZ)); + PHP_OCI_CALL_RETURN(errstatus, OCINlsNumericInfoGet, (connection->env, connection->err, &bytes_per_char, OCI_NLS_CHARSET_MAXBYTESZ)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } @@ -324,7 +327,6 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini ctx.alloc_len = (requested_len + 1) * bytes_per_char; *data = ecalloc(bytes_per_char, requested_len + 1); -#ifdef HAVE_OCI_LOB_READ2 if (is_clob) { chars_read = requested_len; bytes_read = 0; @@ -337,7 +339,7 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini buffer_size = php_oci_lob_calculate_buffer(descriptor, buffer_size TSRMLS_CC); /* use chunk size */ bufp = (ub1 *) ecalloc(1, buffer_size); - PHP_OCI_CALL_RETURN(connection->errcode, OCILobRead2, + PHP_OCI_CALL_RETURN(errstatus, OCILobRead2, ( connection->svc, connection->err, @@ -362,37 +364,9 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini } else { offset = descriptor->lob_current_position + bytes_read; } - -#else - - bytes_read = requested_len; - buffer_size = (requested_len < buffer_size ) ? requested_len : buffer_size; /* optimize buffer size */ - buffer_size = php_oci_lob_calculate_buffer(descriptor, buffer_size TSRMLS_CC); /* use chunk size */ - - bufp = (ub1 *) ecalloc(1, buffer_size); - PHP_OCI_CALL_RETURN(connection->errcode, OCILobRead, - ( - connection->svc, - connection->err, - descriptor->descriptor, - &bytes_read, /* IN/OUT bytes toread/read */ - offset + 1, /* offset (starts with 1) */ - (dvoid *) bufp, - (ub4) buffer_size, /* size of buffer */ - (dvoid *)&ctx, - (OCICallbackLobRead) php_oci_lob_callback, /* callback... */ - (ub2) descriptor->charset_id, /* The character set ID of the buffer data. */ - (ub1) descriptor->charset_form /* The character set form of the buffer data. */ - ) - ); - - efree(bufp); - offset = descriptor->lob_current_position + bytes_read; - -#endif - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); if (*data) { efree(*data); @@ -405,10 +379,10 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini descriptor->lob_current_position = (int)offset; if (descriptor->type == OCI_DTYPE_FILE) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor)); + PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); if (*data) { efree(*data); @@ -419,8 +393,10 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini } } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_write() Write data to the LOB */ @@ -429,6 +405,7 @@ int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, i OCILobLocator *lob = (OCILobLocator *) descriptor->descriptor; php_oci_connection *connection = (php_oci_connection *) descriptor->connection; ub4 lob_length; + sword errstatus; *bytes_written = 0; if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) { @@ -447,7 +424,7 @@ int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, i offset = descriptor->lob_current_position; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobWrite, + PHP_OCI_CALL_RETURN(errstatus, OCILobWrite, ( connection->svc, connection->err, @@ -464,8 +441,8 @@ int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, i ) ); - if (connection->errcode) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); *bytes_written = 0; return 1; @@ -482,14 +459,17 @@ int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, i descriptor->buffering = PHP_OCI_LOB_BUFFER_USED; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_set_buffering() Turn buffering off/onn for this particular LOB */ int php_oci_lob_set_buffering (php_oci_descriptor *descriptor, int on_off TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; + sword errstatus; if (!on_off && descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) { /* disabling when it's already off */ @@ -502,19 +482,21 @@ int php_oci_lob_set_buffering (php_oci_descriptor *descriptor, int on_off TSRMLS } if (on_off) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobEnableBuffering, (connection->svc, connection->err, descriptor->descriptor)); + PHP_OCI_CALL_RETURN(errstatus, OCILobEnableBuffering, (connection->svc, connection->err, descriptor->descriptor)); } else { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobDisableBuffering, (connection->svc, connection->err, descriptor->descriptor)); + PHP_OCI_CALL_RETURN(errstatus, OCILobDisableBuffering, (connection->svc, connection->err, descriptor->descriptor)); } - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } descriptor->buffering = on_off ? PHP_OCI_LOB_BUFFER_ENABLED : PHP_OCI_LOB_BUFFER_DISABLED; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_get_buffering() Return current buffering state for the LOB */ @@ -525,7 +507,8 @@ int php_oci_lob_get_buffering (php_oci_descriptor *descriptor) } else { return 0; } -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_copy() Copy one LOB (or its part) to another one */ @@ -533,6 +516,7 @@ int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *d { php_oci_connection *connection = descriptor_dest->connection; ub4 length_dest, length_from, copy_len; + sword errstatus; if (php_oci_lob_get_length(descriptor_dest, &length_dest TSRMLS_CC)) { return 1; @@ -553,7 +537,7 @@ int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *d return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobCopy, + PHP_OCI_CALL_RETURN(errstatus, OCILobCopy, ( connection->svc, connection->err, @@ -565,29 +549,33 @@ int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *d ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_close() Close LOB */ int php_oci_lob_close (php_oci_descriptor *descriptor TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; - + sword errstatus; + if (descriptor->is_open) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobClose, (connection->svc, connection->err, descriptor->descriptor)); - } + PHP_OCI_CALL_RETURN(errstatus, OCILobClose, (connection->svc, connection->err, descriptor->descriptor)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); - PHP_OCI_HANDLE_ERROR(connection, connection->errcode); - return 1; + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); + PHP_OCI_HANDLE_ERROR(connection, connection->errcode); + return 1; + } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } if (php_oci_temp_lob_close(descriptor TSRMLS_CC)) { @@ -595,7 +583,8 @@ int php_oci_lob_close (php_oci_descriptor *descriptor TSRMLS_DC) } return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_temp_lob_close() Close Temporary LOB */ @@ -603,27 +592,29 @@ int php_oci_temp_lob_close (php_oci_descriptor *descriptor TSRMLS_DC) { php_oci_connection *connection = descriptor->connection; int is_temporary; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCILobIsTemporary, (connection->env,connection->err, descriptor->descriptor, &is_temporary)); + PHP_OCI_CALL_RETURN(errstatus, OCILobIsTemporary, (connection->env,connection->err, descriptor->descriptor, &is_temporary)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } if (is_temporary) { - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFreeTemporary, (connection->svc, connection->err, descriptor->descriptor)); + PHP_OCI_CALL_RETURN(errstatus, OCILobFreeTemporary, (connection->svc, connection->err, descriptor->descriptor)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ - +} +/* }}} */ /* {{{ php_oci_lob_flush() Flush buffers for the LOB (only if they have been used) */ @@ -631,7 +622,8 @@ int php_oci_lob_flush(php_oci_descriptor *descriptor, long flush_flag TSRMLS_DC) { OCILobLocator *lob = descriptor->descriptor; php_oci_connection *connection = descriptor->connection; - + sword errstatus; + if (!lob) { return 1; } @@ -654,18 +646,20 @@ int php_oci_lob_flush(php_oci_descriptor *descriptor, long flush_flag TSRMLS_DC) return 0; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobFlushBuffer, (connection->svc, connection->err, lob, flush_flag)); + PHP_OCI_CALL_RETURN(errstatus, OCILobFlushBuffer, (connection->svc, connection->err, lob, flush_flag)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } /* marking buffer as enabled and not used */ descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_free() Close LOB descriptor and free associated resources */ @@ -709,9 +703,10 @@ void php_oci_lob_free (php_oci_descriptor *descriptor TSRMLS_DC) PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type)); - zend_list_delete(descriptor->connection->rsrc_id); + zend_list_delete(descriptor->connection->id); efree(descriptor); -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_import() Import LOB contents from the given file */ @@ -723,6 +718,7 @@ int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename TSRMLS_DC php_oci_connection *connection = descriptor->connection; char buf[8192]; ub4 offset = 1; + sword errstatus; #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5) /* Safe mode has been removed in PHP 5.4 */ @@ -739,7 +735,7 @@ int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename TSRMLS_DC } while ((loblen = read(fp, &buf, sizeof(buf))) > 0) { - PHP_OCI_CALL_RETURN(connection->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCILobWrite, ( connection->svc, @@ -757,18 +753,21 @@ int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename TSRMLS_DC ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); close(fp); return 1; + } else { + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } offset += loblen; } close(fp); return 0; -} /* }}} */ +} + /* }}} */ /* {{{ php_oci_lob_append() Append data to the end of the LOB */ @@ -778,6 +777,7 @@ int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor OCILobLocator *lob_dest = descriptor_dest->descriptor; OCILobLocator *lob_from = descriptor_from->descriptor; ub4 dest_len, from_len; + sword errstatus; if (php_oci_lob_get_length(descriptor_dest, &dest_len TSRMLS_CC)) { return 1; @@ -791,15 +791,17 @@ int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor return 0; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from)); + PHP_OCI_CALL_RETURN(errstatus, OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_truncate() Truncate LOB to the given length */ @@ -808,6 +810,7 @@ int php_oci_lob_truncate (php_oci_descriptor *descriptor, long new_lob_length TS php_oci_connection *connection = descriptor->connection; OCILobLocator *lob = descriptor->descriptor; ub4 lob_length; + sword errstatus; if (php_oci_lob_get_length(descriptor, &lob_length TSRMLS_CC)) { return 1; @@ -827,17 +830,20 @@ int php_oci_lob_truncate (php_oci_descriptor *descriptor, long new_lob_length TS return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobTrim, (connection->svc, connection->err, lob, new_lob_length)); + PHP_OCI_CALL_RETURN(errstatus, OCILobTrim, (connection->svc, connection->err, lob, new_lob_length)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } descriptor->lob_size = new_lob_length; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ + return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_erase() Erase (or fill with whitespaces, depending on LOB type) the LOB (or its part) */ @@ -846,6 +852,7 @@ int php_oci_lob_erase (php_oci_descriptor *descriptor, long offset, ub4 length, php_oci_connection *connection = descriptor->connection; OCILobLocator *lob = descriptor->descriptor; ub4 lob_length; + sword errstatus; *bytes_erased = 0; @@ -861,17 +868,19 @@ int php_oci_lob_erase (php_oci_descriptor *descriptor, long offset, ub4 length, length = lob_length; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobErase, (connection->svc, connection->err, lob, (ub4 *)&length, offset+1)); + PHP_OCI_CALL_RETURN(errstatus, OCILobErase, (connection->svc, connection->err, lob, (ub4 *)&length, offset+1)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } *bytes_erased = length; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_is_equal() Compare two LOB descriptors and figure out if they are pointing to the same LOB */ @@ -880,16 +889,19 @@ int php_oci_lob_is_equal (php_oci_descriptor *descriptor_first, php_oci_descript php_oci_connection *connection = descriptor_first->connection; OCILobLocator *first_lob = descriptor_first->descriptor; OCILobLocator *second_lob = descriptor_second->descriptor; + sword errstatus; - PHP_OCI_CALL_RETURN(connection->errcode, OCILobIsEqual, (connection->env, first_lob, second_lob, result)); + PHP_OCI_CALL_RETURN(errstatus, OCILobIsEqual, (connection->env, first_lob, second_lob, result)); - if (connection->errcode) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_lob_write_tmp() Create temporary LOB and write data to it */ @@ -898,6 +910,7 @@ int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, long type, char *data php_oci_connection *connection = descriptor->connection; OCILobLocator *lob = descriptor->descriptor; ub4 bytes_written = 0; + sword errstatus; switch (type) { case OCI_TEMP_BLOB: @@ -914,7 +927,7 @@ int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, long type, char *data return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobCreateTemporary, + PHP_OCI_CALL_RETURN(errstatus, OCILobCreateTemporary, ( connection->svc, connection->err, @@ -927,24 +940,26 @@ int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, long type, char *data ) ); - if (connection->errcode) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } - PHP_OCI_CALL_RETURN(connection->errcode, OCILobOpen, (connection->svc, connection->err, lob, OCI_LOB_READWRITE)); + PHP_OCI_CALL_RETURN(errstatus, OCILobOpen, (connection->svc, connection->err, lob, OCI_LOB_READWRITE)); - if (connection->errcode) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return 1; } descriptor->is_open = 1; + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return php_oci_lob_write(descriptor, 0, data, data_len, &bytes_written TSRMLS_CC); -} /* }}} */ +} +/* }}} */ #endif /* HAVE_OCI8 */ diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 89facb0703431..1e66308e53ca4 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -43,21 +43,24 @@ /* {{{ php_oci_statement_create() Create statemend handle and allocate necessary resources */ -php_oci_statement *php_oci_statement_create (php_oci_connection *connection, char *query, int query_len TSRMLS_DC) +php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char *query, int query_len TSRMLS_DC) { php_oci_statement *statement; - + sword errstatus; + + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ + statement = ecalloc(1,sizeof(php_oci_statement)); if (!query_len) { /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */ PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL)); } - + PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL)); if (query_len > 0) { - PHP_OCI_CALL_RETURN(connection->errcode, OCIStmtPrepare2, + PHP_OCI_CALL_RETURN(errstatus, OCIStmtPrepare2, ( connection->svc, &(statement->stmt), @@ -70,14 +73,19 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha OCI_DEFAULT ) ); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_SQLTEXT_ENABLED()) { + DTRACE_OCI8_SQLTEXT(connection, connection->client_id, statement, query); + } +#endif /* HAVE_OCI8_DTRACE */ - PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT)); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); + + PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, OCI_STRLS_CACHE_DELETE)); PHP_OCI_CALL(OCIHandleFree,(statement->err, OCI_HTYPE_ERROR)); - - efree(statement); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); + efree(statement); return NULL; } } @@ -95,10 +103,15 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha statement->has_data = 0; statement->has_descr = 0; statement->parent_stmtid = 0; - zend_list_addref(statement->connection->rsrc_id); + statement->impres_child_stmt = NULL; + statement->impres_count = 0; + statement->impres_flag = PHP_OCI_IMPRES_UNKNOWN; /* may or may not have Implicit Result Set children */ + zend_list_addref(statement->connection->id); if (OCI_G(default_prefetch) >= 0) { - php_oci_statement_set_prefetch(statement, OCI_G(default_prefetch) TSRMLS_CC); + php_oci_statement_set_prefetch(statement, (ub4)OCI_G(default_prefetch) TSRMLS_CC); + } else { + php_oci_statement_set_prefetch(statement, (ub4)100 TSRMLS_CC); /* semi-arbitrary, "sensible default" */ } PHP_OCI_REGISTER_RESOURCE(statement, le_statement); @@ -109,25 +122,85 @@ php_oci_statement *php_oci_statement_create (php_oci_connection *connection, cha } /* }}} */ +/* {{{ php_oci_get_implicit_resultset() + Fetch implicit result set statement resource */ +php_oci_statement *php_oci_get_implicit_resultset(php_oci_statement *statement TSRMLS_DC) +{ +#if (OCI_MAJOR_VERSION < 12) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Implicit results are available in Oracle Database 12c onwards"); + return NULL; +#else + void *result; + ub4 rtype; + php_oci_statement *statement2; /* implicit result set statement handle */ + sword errstatus; + + PHP_OCI_CALL_RETURN(errstatus, OCIStmtGetNextResult, (statement->stmt, statement->err, &result, &rtype, OCI_DEFAULT)); + if (errstatus == OCI_NO_DATA) { + return NULL; + } + + if (rtype != OCI_RESULT_TYPE_SELECT) { + /* Only OCI_RESULT_TYPE_SELECT is supported by Oracle DB 12cR1 */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected implicit result type returned from Oracle Database"); + return NULL; + } else { + statement2 = ecalloc(1,sizeof(php_oci_statement)); + + PHP_OCI_CALL(OCIHandleAlloc, (statement->connection->env, (dvoid **)&(statement2->err), OCI_HTYPE_ERROR, 0, NULL)); + statement2->stmt = (OCIStmt *)result; + statement2->parent_stmtid = statement->id; + statement2->impres_child_stmt = NULL; + statement2->impres_count = 0; + statement2->impres_flag = PHP_OCI_IMPRES_IS_CHILD; + statement2->connection = statement->connection; + statement2->errcode = 0; + statement2->last_query = NULL; + statement2->last_query_len = 0; + statement2->columns = NULL; + statement2->binds = NULL; + statement2->defines = NULL; + statement2->ncolumns = 0; + statement2->executed = 0; + statement2->has_data = 0; + statement2->has_descr = 0; + statement2->stmttype = 0; + + zend_list_addref(statement->id); + zend_list_addref(statement2->connection->id); + + php_oci_statement_set_prefetch(statement2, statement->prefetch_count TSRMLS_CC); + + PHP_OCI_REGISTER_RESOURCE(statement2, le_statement); + + OCI_G(num_statements)++; + + return statement2; + } +#endif /* OCI_MAJOR_VERSION < 12 */ +} +/* }}} */ + /* {{{ php_oci_statement_set_prefetch() - Set prefetch buffer size for the statement (we're assuming that one row is ~1K sized) */ -int php_oci_statement_set_prefetch(php_oci_statement *statement, long size TSRMLS_DC) + Set prefetch buffer size for the statement */ +int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch TSRMLS_DC) { - ub4 prefetch = size; + sword errstatus; - if (size < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0"); - return 1; + if (prefetch > 20000) { + prefetch = 20000; /* keep it somewhat sane */ } + + PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err)); - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrSet, (statement->stmt, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, statement->err)); - - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); + statement->prefetch_count = 0; return 1; } - + statement->prefetch_count = prefetch; + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; } /* }}} */ @@ -163,8 +236,8 @@ int php_oci_cleanup_pre_fetch(void *data TSRMLS_DC) } return ZEND_HASH_APPLY_KEEP; -} /* }}} */ - +} +/* }}} */ /* {{{ php_oci_statement_fetch() Fetch a row from the statement */ @@ -175,16 +248,18 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) ub4 typep, iterp, idxp; ub1 in_outp, piecep; zend_bool piecewisecols = 0; - php_oci_out_column *column; + sword errstatus; + + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ if (statement->has_descr && statement->columns) { zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch TSRMLS_CC); } - PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT)); + PHP_OCI_CALL_RETURN(errstatus, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT)); - if ( statement->errcode == OCI_NO_DATA || nrows == 0 ) { + if (errstatus == OCI_NO_DATA || nrows == 0) { if (statement->last_query == NULL) { /* reset define-list for refcursors */ if (statement->columns) { @@ -196,7 +271,6 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) statement->executed = 0; } - statement->errcode = 0; /* OCI_NO_DATA is NO error for us!!! */ statement->has_data = 0; if (nrows == 0) { @@ -209,15 +283,15 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) /* reset length for all piecewise columns */ for (i = 0; i < statement->ncolumns; i++) { column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC); - if (column->piecewise) { + if (column && column->piecewise) { column->retlen4 = 0; piecewisecols = 1; } } - while (statement->errcode == OCI_NEED_DATA) { + while (errstatus == OCI_NEED_DATA) { if (piecewisecols) { - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIStmtGetPieceInfo, ( statement->stmt, @@ -234,7 +308,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) /* scan through our columns for a piecewise column with a matching handle */ for (i = 0; i < statement->ncolumns; i++) { column = php_oci_statement_get_column(statement, i + 1, NULL, 0 TSRMLS_CC); - if (column->piecewise && handlepp == column->oci_define) { + if (column && column->piecewise && handlepp == column->oci_define) { if (!column->data) { column->data = (text *) ecalloc(1, PHP_OCI_PIECE_SIZE + 1); } else { @@ -259,7 +333,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) } } - PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT)); + PHP_OCI_CALL_RETURN(errstatus, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT)); if (piecewisecols) { for (i = 0; i < statement->ncolumns; i++) { @@ -271,7 +345,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) } } - if (statement->errcode == OCI_SUCCESS_WITH_INFO || statement->errcode == OCI_SUCCESS) { + if (errstatus == OCI_SUCCESS_WITH_INFO || errstatus == OCI_SUCCESS) { statement->has_data = 1; /* do the stuff needed for OCIDefineByName */ @@ -292,7 +366,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC) return 0; } - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); statement->has_data = 0; @@ -332,7 +406,7 @@ php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, l } /* }}} */ -/* php_oci_define_callback() {{{ */ +/* {{{ php_oci_define_callback() */ sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcpp) { php_oci_out_column *outcol = (php_oci_out_column *)ctx; @@ -415,12 +489,18 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) ub4 colcount; ub2 dynamic; dvoid *buf; + sword errstatus; switch (mode) { case OCI_COMMIT_ON_SUCCESS: case OCI_DESCRIBE_ONLY: case OCI_DEFAULT: /* only these are allowed */ +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_EXECUTE_MODE_ENABLED()) { + DTRACE_OCI8_EXECUTE_MODE(statement->connection, statement->connection->client_id, statement, mode); + } +#endif /* HAVE_OCI8_DTRACE */ break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid execute mode given: %d", mode); @@ -430,12 +510,14 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) if (!statement->stmttype) { /* get statement type */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement->stmttype, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; + } else { + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } } @@ -445,9 +527,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) iters = 1; } - if (statement->last_query) { - /* if we execute refcursors we don't have a query and - we don't want to execute!!! */ + if (statement->last_query) { /* Don't execute REFCURSORS or Implicit Result Set handles */ if (statement->binds) { int result = 0; @@ -458,10 +538,10 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) } /* execute statement */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIStmtExecute, (statement->connection->svc, statement->stmt, statement->err, iters, 0, NULL, NULL, mode)); + PHP_OCI_CALL_RETURN(errstatus, OCIStmtExecute, (statement->connection->svc, statement->stmt, statement->err, iters, 0, NULL, NULL, mode)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } @@ -471,10 +551,20 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) } if (mode & OCI_COMMIT_ON_SUCCESS) { - statement->connection->needs_commit = 0; - } else { - statement->connection->needs_commit = 1; + /* No need to rollback on disconnect */ + statement->connection->rb_on_disconnect = 0; + } else if (statement->stmttype != OCI_STMT_SELECT) { + /* Assume some uncommitted DML occurred */ + statement->connection->rb_on_disconnect = 1; } + /* else for SELECT with OCI_NO_AUTO_COMMIT, leave + * "rb_on_disconnect" at its previous value. SELECT can't + * initiate uncommitted DML. (An AUTONOMOUS_TRANSACTION in + * invoked PL/SQL must explicitly rollback/commit else the + * SELECT fails). + */ + + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } if (statement->stmttype == OCI_STMT_SELECT && statement->executed == 0) { @@ -487,10 +577,10 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) counter = 1; /* get number of columns */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (dvoid *)&colcount, (ub4 *)0, OCI_ATTR_PARAM_COUNT, statement->err)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } @@ -507,50 +597,50 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) } /* get column */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)¶m, counter)); + PHP_OCI_CALL_RETURN(errstatus, OCIParamGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, statement->err, (dvoid**)¶m, counter)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get column datatype */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_type, (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get character set form */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_form, (ub4 *)0, OCI_ATTR_CHARSET_FORM, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_form, (ub4 *)0, OCI_ATTR_CHARSET_FORM, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get character set id */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_id, (ub4 *)0, OCI_ATTR_CHARSET_ID, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->charset_id, (ub4 *)0, OCI_ATTR_CHARSET_ID, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get size of the column */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->data_size, (dvoid *)0, OCI_ATTR_DATA_SIZE, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } @@ -559,31 +649,31 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) outcol->retlen = outcol->data_size; /* get scale of the column */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->scale, (dvoid *)0, OCI_ATTR_SCALE, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get precision of the column */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid *)&outcol->precision, (dvoid *)0, OCI_ATTR_PRECISION, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } /* get name of the column */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)param, OCI_DTYPE_PARAM, (dvoid **)&colname, (ub4 *)&outcol->name_len, (ub4)OCI_ATTR_NAME, statement->err)); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } @@ -591,7 +681,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) outcol->name = estrndup((char*) colname, outcol->name_len); - /* find a user-setted define */ + /* find a user-set define */ if (statement->defines) { if (zend_hash_find(statement->defines,outcol->name,outcol->name_len,(void **) &outcol->define) == SUCCESS) { if (outcol->define->type) { @@ -679,7 +769,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) } if (dynamic == OCI_DYNAMIC_FETCH) { - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIDefineByPos, ( statement->stmt, /* IN/OUT handle to the requested SQL query */ @@ -697,7 +787,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) ); } else { - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIDefineByPos, ( statement->stmt, /* IN/OUT handle to the requested SQL query */ @@ -716,10 +806,10 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) } - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); - return 0; + return 1; } /* additional OCIDefineDynamic() call */ @@ -729,7 +819,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) case SQLT_BLOB: case SQLT_CLOB: case SQLT_BFILE: - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIDefineDynamic, ( outcol->oci_define, @@ -739,9 +829,15 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) ) ); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); + PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); + return 1; + } break; } } + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } return 0; @@ -752,10 +848,9 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) Cancel statement */ int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC) { - return php_oci_statement_fetch(statement, 0 TSRMLS_CC); - -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_statement_free() Destroy statement handle and free associated resources */ @@ -764,15 +859,15 @@ void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC) if (statement->stmt) { if (statement->last_query_len) { /* FIXME: magical */ PHP_OCI_CALL(OCIStmtRelease, (statement->stmt, statement->err, NULL, 0, statement->errcode ? OCI_STRLS_CACHE_DELETE : OCI_DEFAULT)); - } else { + } else if (statement->impres_flag != PHP_OCI_IMPRES_IS_CHILD) { /* Oracle doc says don't free Implicit Result Set handles */ PHP_OCI_CALL(OCIHandleFree, (statement->stmt, OCI_HTYPE_STMT)); } - statement->stmt = 0; + statement->stmt = NULL; } if (statement->err) { PHP_OCI_CALL(OCIHandleFree, (statement->err, OCI_HTYPE_ERROR)); - statement->err = 0; + statement->err = NULL; } if (statement->last_query) { @@ -798,11 +893,12 @@ void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC) zend_list_delete(statement->parent_stmtid); } - zend_list_delete(statement->connection->rsrc_id); + zend_list_delete(statement->connection->id); efree(statement); OCI_G(num_statements)--; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_pre_exec() Helper function */ @@ -872,6 +968,7 @@ int php_oci_bind_post_exec(void *data TSRMLS_DC) { php_oci_bind *bind = (php_oci_bind *) data; php_oci_connection *connection = bind->parent_statement->connection; + sword errstatus; if (bind->indicator == -1) { /* NULL */ zval *val = bind->zval; @@ -931,24 +1028,26 @@ int php_oci_bind_post_exec(void *data TSRMLS_DC) memset((void*)buff,0,sizeof(buff)); if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff)); zval_dtor(*entry); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); ZVAL_NULL(*entry); } else { + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ ZVAL_STRINGL(*entry, (char *)buff, buff_len, 1); } zend_hash_move_forward(hash); } else { - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff)); - if (connection->errcode != OCI_SUCCESS) { - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff)); + if (errstatus != OCI_SUCCESS) { + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); add_next_index_null(bind->zval); } else { + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ add_next_index_stringl(bind->zval, (char *)buff, buff_len, 1); } } @@ -982,7 +1081,7 @@ int php_oci_bind_post_exec(void *data TSRMLS_DC) /* {{{ php_oci_bind_by_name() Bind zval to the given placeholder */ -int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long maxlength, ub2 type TSRMLS_DC) +int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long maxlength, ub2 type TSRMLS_DC) { php_oci_collection *bind_collection = NULL; php_oci_descriptor *bind_descriptor = NULL; @@ -994,6 +1093,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, php_oci_bind bind, *old_bind, *bindp; int mode = OCI_DATA_AT_EXEC; sb4 value_sz = -1; + sword errstatus; switch (type) { case SQLT_NTY: @@ -1117,7 +1217,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, bindp->type = type; zval_add_ref(&var); - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIBindByName, ( statement->stmt, /* statement handle */ @@ -1137,14 +1237,14 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, ) ); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } if (mode == OCI_DATA_AT_EXEC) { - PHP_OCI_CALL_RETURN(statement->errcode, OCIBindDynamic, + PHP_OCI_CALL_RETURN(errstatus, OCIBindDynamic, ( bindp->bind, statement->err, @@ -1155,8 +1255,8 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, ) ); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } @@ -1164,7 +1264,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, if (type == SQLT_NTY) { /* Bind object */ - PHP_OCI_CALL_RETURN(statement->errcode, OCIBindObject, + PHP_OCI_CALL_RETURN(errstatus, OCIBindObject, ( bindp->bind, statement->err, @@ -1176,15 +1276,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, ) ); - if (statement->errcode) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } } + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_in_callback() Callback used when binding LOBs and VARCHARs */ @@ -1235,7 +1337,8 @@ sb4 php_oci_bind_in_callback( *piecep = OCI_ONE_PIECE; /* pass all data in one go */ return OCI_CONTINUE; -}/* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_out_callback() Callback used when binding LOBs and VARCHARs */ @@ -1358,55 +1461,61 @@ php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAME zval_dtor(&tmp); } return column; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_statement_get_type() Return type of the statement */ int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC) { ub2 statement_type; + sword errstatus; *type = 0; - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub2 *)&statement_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, statement->err)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } - + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ *type = statement_type; return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_statement_get_numrows() Get the number of rows fetched to the clientside (NOT the number of rows in the result set) */ int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC) { ub4 statement_numrows; + sword errstatus; *numrows = 0; - PHP_OCI_CALL_RETURN(statement->errcode, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err)); + PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)statement->stmt, OCI_HTYPE_STMT, (ub4 *)&statement_numrows, (ub4 *)0, OCI_ATTR_ROW_COUNT, statement->err)); - if (statement->errcode != OCI_SUCCESS) { - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + if (errstatus != OCI_SUCCESS) { + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } - + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ *numrows = statement_numrows; return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_array_by_name() Bind arrays to PL/SQL types */ -int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC) +int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long max_table_length, long maxlength, long type TSRMLS_DC) { php_oci_bind *bind, *bindp; + sword errstatus; convert_to_array(var); @@ -1470,7 +1579,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam zval_add_ref(&var); - PHP_OCI_CALL_RETURN(statement->errcode, + PHP_OCI_CALL_RETURN(errstatus, OCIBindByName, ( statement->stmt, @@ -1491,19 +1600,21 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam ); - if (statement->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { efree(bind); - statement->errcode = php_oci_error(statement->err, statement->errcode TSRMLS_CC); + statement->errcode = php_oci_error(statement->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ efree(bind); return 0; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_array_helper_string() Bind arrays to PL/SQL types */ -php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC) +php_oci_bind *php_oci_bind_array_helper_string(zval *var, long max_table_length, long maxlength TSRMLS_DC) { php_oci_bind *bind; ub4 i; @@ -1568,11 +1679,12 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, zend_hash_internal_pointer_reset(hash); return bind; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_array_helper_number() Bind arrays to PL/SQL types */ -php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC) +php_oci_bind *php_oci_bind_array_helper_number(zval *var, long max_table_length TSRMLS_DC) { php_oci_bind *bind; ub4 i; @@ -1606,11 +1718,12 @@ php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length zend_hash_internal_pointer_reset(hash); return bind; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_array_helper_double() Bind arrays to PL/SQL types */ -php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC) +php_oci_bind *php_oci_bind_array_helper_double(zval *var, long max_table_length TSRMLS_DC) { php_oci_bind *bind; ub4 i; @@ -1644,16 +1757,18 @@ php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length zend_hash_internal_pointer_reset(hash); return bind; -} /* }}} */ +} +/* }}} */ /* {{{ php_oci_bind_array_helper_date() Bind arrays to PL/SQL types */ -php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC) +php_oci_bind *php_oci_bind_array_helper_date(zval *var, long max_table_length, php_oci_connection *connection TSRMLS_DC) { php_oci_bind *bind; ub4 i; HashTable *hash; zval **entry; + sword errstatus; hash = HASH_OF(var); @@ -1675,14 +1790,14 @@ php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, p if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { convert_to_string_ex(entry); - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), NULL, 0, NULL, 0, &oci_date)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { /* failed to convert string to date */ efree(bind->array.element_lengths); efree(bind->array.elements); efree(bind); - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return NULL; } @@ -1690,25 +1805,27 @@ php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, p ((OCIDate *)bind->array.elements)[i] = oci_date; zend_hash_move_forward(hash); } else { - PHP_OCI_CALL_RETURN(connection->errcode, OCIDateFromText, (connection->err, (CONST text *)"01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date)); + PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)"01-JAN-00", sizeof("01-JAN-00")-1, NULL, 0, NULL, 0, &oci_date)); - if (connection->errcode != OCI_SUCCESS) { + if (errstatus != OCI_SUCCESS) { /* failed to convert string to date */ efree(bind->array.element_lengths); efree(bind->array.elements); efree(bind); - connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC); + connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); return NULL; } ((OCIDate *)bind->array.elements)[i] = oci_date; } + connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ } zend_hash_internal_pointer_reset(hash); return bind; -} /* }}} */ +} +/* }}} */ #endif /* HAVE_OCI8 */ diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml index feadf1907b6a0..7be825b895b39 100644 --- a/ext/oci8/package.xml +++ b/ext/oci8/package.xml @@ -6,7 +6,19 @@ http://pear.php.net/dtd/package-2.0.xsd"> oci8 pecl.php.net Extension for Oracle Database - This extension allows you to access Oracle databases. It can be built with PHP 4.3.9 to 5.x. It can be linked with Oracle 9.2, 10, 11, or 12.1 client libraries. + + +Use the OCI8 extension to access Oracle Database. The extension can +be linked with Oracle client libraries from Oracle Database 10.2, 11, +or 12.1. These libraries are found in the database installation, or +in the free Oracle Instant Client available from Oracle. Oracle's +standard cross-version connectivity applies. For example, PHP OCI8 +linked with Instant Client 11.2 can connect to Oracle Database 9.2 +onward. See Oracle's note "Oracle Client / Server Interoperability +Support" (ID 207303.1) for details. PHP OCI8 2.0 can be built with +PHP 5.2 onward. Use the older PHP OCI8 1.4.10 when using PHP 4.3.9 +through to PHP 5.1.x, or when only Oracle Database 9.2 client +libraries are available. Christopher Jones @@ -18,7 +30,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> Antony Dovgal tony2001 tony2001@php.net - yes + no Wez Furlong @@ -33,21 +45,22 @@ http://pear.php.net/dtd/package-2.0.xsd"> no - 2013-07-08 + 2013-10-22 - - 1.4.10 - 1.4.10 - - - stable - stable - - PHP - - Bump PECL package info version check to allow PECL installs with PHP 5.5+ - + + 2.0.6 + 2.0.6 + + + stable + stable + + PHP + +Added a LICENSE file to make it easier for PECL binary distributions +to conform with the license. + @@ -94,6 +107,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + @@ -131,7 +145,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - @@ -144,7 +157,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - @@ -213,6 +225,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + @@ -258,6 +272,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + @@ -287,6 +302,38 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -335,6 +382,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + @@ -383,21 +431,21 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + + - 4.3.9 - 6.0.0 + 5.2.0 1.4.0b1 @@ -410,6 +458,187 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + + 2.0.5 + 2.0.5 + + + stable + stable + + PHP + +Bump PHP OCI8 2.0 mininum requirements to PHP 5.2 and Oracle client +library 10.2. (Use OCI8 1.4 for older PHP version support or if only +Oracle 9.2 client libraries are available.) + +Re-enable php_oci8.dll and php_oci8_11g.dll for Windows builds so URL +links work in the new Windows PECL infrastructure. + + + + + + 2.0.4 + 2.0.4 + + + devel + devel + + PHP + +Fix persistent memory usage with --enable-dtrace +Export get_module() for Windows php_oci8_12c.dll + + + + + + 2.0.3 + 2.0.3 + + + devel + devel + + PHP + +Add the oci_set_client_identifier() value and statement structure pointer to several DTrace probes. +Use 'phpoci' as the DTrace provider name since uniqueness is required by the Linux fasttrap module. +Update Windows builds to create only php_oci8_12c.dll. + + + + + + 2.0.2 + 2.0.2 + + + devel + devel + + PHP + +Review and improve error handling code and data types. +Fix oci_set_*($connection, ...) error handling so oci_error($connection) works. +Add DTrace oci8-connection-close probe +Add the connection handle to several DTrace probes. + + + + + + 2.0.1 + 2.0.1 + + + devel + devel + + PHP + +Fixed --enable-maintainer-zts mode. +Allow Implicit Result Set statement resources to inherit the parent's current prefetch count. +Allow OCI8 to be DTrace-enabled independently from core PHP. +Require OCI8 to be configured 'shared' when enabling DTrace support. + + + + + + 2.0.0 + 2.0.0 + + + devel + devel + + PHP + +- NEW FUNCTIONALITY: + + - Added Implicit Result Set support for Oracle Database 12c. + Streaming of all IRS's returned from a PL/SQL block is available + via oci_fetch_array, oci_fetch_assoc, oci_fetch_object and + oci_fetch_row (but not oci_fetch or oci_fetch_all). + Alternatively individual IRS statement resources can be obtained + with the new function 'oci_get_implicit_resultset' and passed to + any oci_fetch_* function. + + - Added DTrace probes enabled with PHP's generic --enable-dtrace + +- IMPROVED FUNCTIONALITY: + + - Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no + longer unnecessarily initiates an internal ROLLBACK during + connection close. This can improve overall scalability by + reducing "round trips" between PHP and the database. + +- CHANGED FUNCTIONALITY: + + - PHPINFO() CHANGES: + + - The oci8.event and oci8.connection_class values are now shown + only when the Oracle client libraries support the respective + functionality. + + - Connection statistics are now in a separate phpinfo() table. + + - Temporary LOB and Collection support status lines in + phpinfo() were removed. These features have always been + enabled since 2007. + + - OCI_INTERNAL_DEBUG() CHANGES: + + - The oci_internal_debug() function is now a no-op. Use PHP's + --enable-dtrace functionality with DTrace or SystemTap instead. + +- INTERNAL CHANGES: + + - Fixed a potential NULL pointer dereference flagged by Parfait + static code analysis. + + - Extended testing of existing OCI8 functionality. + + - Improved test output portability when using the PHP development + web server to run tests. + + - Removed no-longer necessary Unicode patterns from tests + (vestiges of PHP's previous PHP 6 project) + + - Improved build portability by removing compilation type cast + warnings with some compilers. + + - Fixed compilation warnings when building with Oracle 9.2 + client libraries. + + - Updated code to use internal macro PHP_OCI_REGISTER_RESOURCE. + + - Regularized code prototypes and fixed some in-line documentation + prototypes. + + - Fixed code folding. + + + + + + 1.4.10 + 1.4.10 + + + stable + stable + + PHP + + Bump PECL package info version check to allow PECL installs with PHP 5.5+ + + + 1.4.9 @@ -457,7 +686,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> Fixed OCI8 part of bug #55748 (CVE-2011-4153: multiple NULL pointer dereferences with zend_strndup) Fixed OCI8 part of bug #55301 (multiple null pointer dereferences with calloc) Increased maximum Oracle error message buffer length for new Oracle 11.2.0.3 size - Improve internal initalization failure error messages + Improve internal initialization failure error messages @@ -472,7 +701,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP - Added oci_client_version() returning the runtime Oracle client library version + Added oci_client_version() returning the run time Oracle client library version Made OCI8 extension buildable with PHP 5.4-development code @@ -846,7 +1075,7 @@ Fixed bug #36820 (Privileged connection with an Oracle password file fails) 2006-03-16 PHP Changed OCI8 code to use OCIServerVersion() instead of OCIPing(), which may crash Oracle server of version < 10.2 -Fixed bug #36235 (ocicolumnname returns false before a successfull fetch) +Fixed bug #36235 (ocicolumnname returns false before a successful fetch) Fixed bug #36096 (oci_result() returns garbage after oci_fetch() failed) Fixed bug #36055 (possible OCI8 crash in multithreaded environment) Fixed bug #36010 (Segfault when re-creating and re-executing statements with bound parameters) diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index f1079526f66f1..751041554982f 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -41,12 +41,11 @@ */ #ifdef PHP_OCI8_VERSION /* The definition of PHP_OCI8_VERSION changed in PHP 5.3 and building - * this code with PHP 5.2 and earlier (e.g. when using OCI8 from PECL) - * will conflict. + * this code with PHP 5.2 (e.g. when using OCI8 from PECL) will conflict. */ #undef PHP_OCI8_VERSION #endif -#define PHP_OCI8_VERSION "1.4.10" +#define PHP_OCI8_VERSION "2.0.6" extern zend_module_entry oci8_module_entry; #define phpext_oci8_ptr &oci8_module_entry diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 155e57d2cd1a0..e50983d75eb53 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -31,7 +31,7 @@ # ifndef PHP_OCI8_INT_H # define PHP_OCI8_INT_H -/* misc defines {{{ */ +/* {{{ misc defines */ # if (defined(__osf__) && defined(__alpha)) # ifndef A_OSF # define A_OSF @@ -44,6 +44,10 @@ # endif # endif /* osf alpha */ +#ifdef HAVE_OCI8_DTRACE +#include "oci8_dtrace_gen.h" +#endif + #if defined(min) #undef min #endif @@ -66,7 +70,7 @@ extern int le_session; extern zend_class_entry *oci_lob_class_entry_ptr; extern zend_class_entry *oci_coll_class_entry_ptr; -/* constants {{{ */ +/* {{{ constants */ #define PHP_OCI_SEEK_SET 0 #define PHP_OCI_SEEK_CUR 1 #define PHP_OCI_SEEK_END 2 @@ -101,6 +105,11 @@ extern zend_class_entry *oci_coll_class_entry_ptr; #error Invalid value for PHP_OCI_CRED_EXT #endif +#define PHP_OCI_IMPRES_UNKNOWN 0 +#define PHP_OCI_IMPRES_NO_CHILDREN 1 +#define PHP_OCI_IMPRES_HAS_CHILDREN 2 +#define PHP_OCI_IMPRES_IS_CHILD 3 + /* * Name passed to Oracle for tracing. Note some DB views only show * the first nine characters of the driver name. @@ -109,16 +118,21 @@ extern zend_class_entry *oci_coll_class_entry_ptr; /* }}} */ -typedef struct { /* php_oci_spool {{{ */ - OCIEnv *env; /*env of this session pool */ +/* {{{ php_oci_spool */ +typedef struct { + int id; /* resource id */ + OCIEnv *env; /* env of this session pool */ OCIError *err; /* pool's error handle */ OCISPool *poolh; /* pool handle */ void *poolname; /* session pool name */ unsigned int poolname_len; /* length of session pool name */ char *spool_hash_key; /* Hash key for session pool in plist */ -} php_oci_spool; /* }}} */ +} php_oci_spool; +/* }}} */ -typedef struct { /* php_oci_connection {{{ */ +/* {{{ php_oci_connection */ +typedef struct { + int id; /* resource ID */ OCIEnv *env; /* private env handle */ ub2 charset; /* charset ID */ OCIServer *server; /* private server handle */ @@ -127,7 +141,7 @@ typedef struct { /* php_oci_connection {{{ */ OCIAuthInfo *authinfo; /* Cached authinfo handle for OCISessionGet */ OCIError *err; /* private error handle */ php_oci_spool *private_spool; /* private session pool (for persistent) */ - sword errcode; /* last errcode */ + sb4 errcode; /* last ORA- error number */ HashTable *descriptors; /* descriptors hash, used to flush all the LOBs using this connection on commit */ ulong descriptor_count; /* used to index the descriptors hash table. Not an accurate count */ @@ -135,17 +149,21 @@ typedef struct { /* php_oci_connection {{{ */ unsigned is_attached:1; /* hels to determine if we should detach from the server when closing/freeing the connection */ unsigned is_persistent:1; /* self-descriptive */ unsigned used_this_request:1; /* helps to determine if we should reset connection's next ping time and check its timeout */ - unsigned needs_commit:1; /* helps to determine if we should rollback this connection on close/shutdown */ + unsigned rb_on_disconnect:1; /* helps to determine if we should rollback this connection on close/shutdown */ unsigned passwd_changed:1; /* helps determine if a persistent connection hash should be invalidated after a password change */ unsigned is_stub:1; /* flag to keep track whether the connection structure has a real OCI connection associated */ unsigned using_spool:1; /* Is this connection from session pool? */ - int rsrc_id; /* resource ID */ time_t idle_expiry; /* time when the connection will be considered as expired */ time_t *next_pingp; /* (pointer to) time of the next ping */ char *hash_key; /* hashed details of the connection */ -} php_oci_connection; /* }}} */ +#ifdef HAVE_OCI8_DTRACE + char *client_id; /* The oci_set_client_identifier() value */ +#endif +} php_oci_connection; +/* }}} */ -typedef struct { /* php_oci_descriptor {{{ */ +/* {{{ php_oci_descriptor */ +typedef struct { int id; ulong index; /* descriptors hash table index */ php_oci_connection *connection; /* parent connection handle */ @@ -158,15 +176,19 @@ typedef struct { /* php_oci_descriptor {{{ */ ub1 charset_form; /* charset form, required for NCLOBs */ ub2 charset_id; /* charset ID */ unsigned is_open:1; /* helps to determine if lob is open or not */ -} php_oci_descriptor; /* }}} */ +} php_oci_descriptor; +/* }}} */ -typedef struct { /* php_oci_lob_ctx {{{ */ +/* {{{ php_oci_lob_ctx */ +typedef struct { char **lob_data; /* address of pointer to LOB data */ ub4 *lob_len; /* address of LOB length variable (bytes) */ ub4 alloc_len; -} php_oci_lob_ctx; /* }}} */ +} php_oci_lob_ctx; +/* }}} */ -typedef struct { /* php_oci_collection {{{ */ +/* {{{ php_oci_collection */ +typedef struct { int id; php_oci_connection *connection; /* parent connection handle */ OCIType *tdo; /* collection's type handle */ @@ -175,23 +197,30 @@ typedef struct { /* php_oci_collection {{{ */ OCIType *element_type; /* element's type handle */ OCITypeCode element_typecode; /* element's typecode handle */ OCIColl *collection; /* collection handle */ -} php_oci_collection; /* }}} */ +} php_oci_collection; +/* }}} */ -typedef struct { /* php_oci_define {{{ */ +/* {{{ php_oci_define */ +typedef struct { zval *zval; /* zval used in define */ text *name; /* placeholder's name */ ub4 name_len; /* placeholder's name length */ ub4 type; /* define type */ -} php_oci_define; /* }}} */ +} php_oci_define; +/* }}} */ -typedef struct { /* php_oci_statement {{{ */ +/* {{{ php_oci_statement */ +typedef struct { int id; int parent_stmtid; /* parent statement id */ + struct php_oci_statement *impres_child_stmt;/* child of current Implicit Result Set statement handle */ + ub4 impres_count; /* count of remaining Implicit Result children on parent statement handle */ php_oci_connection *connection; /* parent connection handle */ - sword errcode; /* last errcode*/ + sb4 errcode; /* last ORA- error number */ OCIError *err; /* private error handle */ OCIStmt *stmt; /* statement handle */ - char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor received from Oracle */ + char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor recieved from Oracle */ + char impres_flag; /* PHP_OCI_IMPRES_*_ */ long last_query_len; /* last query length */ HashTable *columns; /* hash containing all the result columns */ HashTable *binds; /* binds hash */ @@ -201,9 +230,12 @@ typedef struct { /* php_oci_statement {{{ */ unsigned has_data:1; /* statement has more data flag */ unsigned has_descr:1; /* statement has at least one descriptor or cursor column */ ub2 stmttype; /* statement type */ -} php_oci_statement; /* }}} */ + ub4 prefetch_count; /* current prefetch count */ +} php_oci_statement; +/* }}} */ -typedef struct { /* php_oci_bind {{{ */ +/* {{{ php_oci_bind */ +typedef struct { OCIBind *bind; /* bind handle */ zval *zval; /* value */ dvoid *descriptor; /* used for binding of LOBS etc */ @@ -222,9 +254,11 @@ typedef struct { /* php_oci_bind {{{ */ sb2 indicator; /* -1 means NULL */ ub2 retcode; ub4 dummy_len; /* a dummy var to store alenpp value in bind OUT callback */ -} php_oci_bind; /* }}} */ +} php_oci_bind; +/* }}} */ -typedef struct { /* php_oci_out_column {{{ */ +/* {{{ php_oci_out_column */ +typedef struct { php_oci_statement *statement; /* statement handle. used when fetching REFCURSORS */ php_oci_statement *nested_statement; /* statement handle. used when fetching REFCURSORS */ OCIDefine *oci_define; /* define handle */ @@ -249,28 +283,23 @@ typedef struct { /* php_oci_out_column {{{ */ sb2 precision; /* column precision */ ub1 charset_form; /* charset form, required for NCLOBs */ ub2 charset_id; /* charset ID */ -} php_oci_out_column; /* }}} */ +} php_oci_out_column; +/* }}} */ /* {{{ macros */ -#define PHP_OCI_CALL(func, params) \ - do { \ - if (OCI_G(debug_mode)) { \ - php_printf ("OCI8 DEBUG: " #func " at (%s:%d) \n", __FILE__, __LINE__); \ - } \ - OCI_G(in_call) = 1; \ - func params; \ - OCI_G(in_call) = 0; \ +#define PHP_OCI_CALL(func, params) \ + do { \ + OCI_G(in_call) = 1; \ + func params; \ + OCI_G(in_call) = 0; \ } while (0) -#define PHP_OCI_CALL_RETURN(__retval, func, params) \ - do { \ - if (OCI_G(debug_mode)) { \ - php_printf ("OCI8 DEBUG: " #func " at (%s:%d) \n", __FILE__, __LINE__); \ - } \ - OCI_G(in_call) = 1; \ - __retval = func params; \ - OCI_G(in_call) = 0; \ +#define PHP_OCI_CALL_RETURN(__retval, func, params) \ + do { \ + OCI_G(in_call) = 1; \ + __retval = func params; \ + OCI_G(in_call) = 0; \ } while (0) /* Check for errors that indicate the connection to the DB is no @@ -284,6 +313,7 @@ typedef struct { /* php_oci_out_column {{{ */ */ #define PHP_OCI_HANDLE_ERROR(connection, errcode) \ do { \ + ub4 serverStatus = OCI_SERVER_NORMAL; \ switch (errcode) { \ case 1013: \ zend_bailout(); \ @@ -313,7 +343,6 @@ typedef struct { /* php_oci_out_column {{{ */ break; \ default: \ { \ - ub4 serverStatus = OCI_SERVER_NORMAL; \ PHP_OCI_CALL(OCIAttrGet, ((dvoid *)(connection)->server, OCI_HTYPE_SERVER, (dvoid *)&serverStatus, \ (ub4 *)0, OCI_ATTR_SERVER_STATUS, (connection)->err)); \ if (serverStatus != OCI_SERVER_NORMAL) { \ @@ -322,6 +351,7 @@ typedef struct { /* php_oci_out_column {{{ */ } \ break; \ } \ + php_oci_dtrace_check_connection(connection, errcode, serverStatus); \ } while (0) #define PHP_OCI_REGISTER_RESOURCE(resource, le_resource) \ @@ -365,117 +395,106 @@ typedef struct { /* php_oci_out_column {{{ */ /* PROTOS */ -/* main prototypes {{{ */ - -void php_oci_column_hash_dtor (void *data); -void php_oci_define_hash_dtor (void *data); -void php_oci_bind_hash_dtor (void *data); -void php_oci_descriptor_flush_hash_dtor (void *data); +/* {{{ main prototypes */ +void php_oci_column_hash_dtor(void *data); +void php_oci_define_hash_dtor(void *data); +void php_oci_bind_hash_dtor(void *data); +void php_oci_descriptor_flush_hash_dtor(void *data); void php_oci_connection_descriptors_free(php_oci_connection *connection TSRMLS_DC); - -sb4 php_oci_error (OCIError *, sword TSRMLS_DC); -sb4 php_oci_fetch_errmsg(OCIError *, text ** TSRMLS_DC); -int php_oci_fetch_sqltext_offset(php_oci_statement *, text **, ub2 * TSRMLS_DC); - -void php_oci_do_connect (INTERNAL_FUNCTION_PARAMETERS, int , int); +sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC); +sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf TSRMLS_DC); +int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset TSRMLS_DC); +void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive); php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, long session_mode, int persistent, int exclusive TSRMLS_DC); - -int php_oci_connection_rollback(php_oci_connection * TSRMLS_DC); -int php_oci_connection_commit(php_oci_connection * TSRMLS_DC); +int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC); +int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC); int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC); - -int php_oci_password_change(php_oci_connection *, char *, int, char *, int, char *, int TSRMLS_DC); -void php_oci_client_get_version(char ** TSRMLS_DC); -int php_oci_server_get_version(php_oci_connection *, char ** TSRMLS_DC); - -void php_oci_fetch_row(INTERNAL_FUNCTION_PARAMETERS, int, int); -int php_oci_column_to_zval(php_oci_out_column *, zval *, int TSRMLS_DC); +int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len TSRMLS_DC); +void php_oci_client_get_version(char **version TSRMLS_DC); +int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC); +void php_oci_fetch_row(INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args); +int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode TSRMLS_DC); +void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus); /* }}} */ -/* lob related prototypes {{{ */ - -php_oci_descriptor * php_oci_lob_create (php_oci_connection *, long TSRMLS_DC); -int php_oci_lob_get_length (php_oci_descriptor *, ub4 * TSRMLS_DC); -int php_oci_lob_read (php_oci_descriptor *, long, long, char **, ub4 * TSRMLS_DC); -int php_oci_lob_write (php_oci_descriptor *, ub4, char *, int, ub4 * TSRMLS_DC); -int php_oci_lob_flush (php_oci_descriptor *, long TSRMLS_DC); -int php_oci_lob_set_buffering (php_oci_descriptor *, int TSRMLS_DC); -int php_oci_lob_get_buffering (php_oci_descriptor *); -int php_oci_lob_copy (php_oci_descriptor *, php_oci_descriptor *, long TSRMLS_DC); -int php_oci_lob_close (php_oci_descriptor * TSRMLS_DC); -int php_oci_temp_lob_close (php_oci_descriptor * TSRMLS_DC); -int php_oci_lob_write_tmp (php_oci_descriptor *, long, char *, int TSRMLS_DC); -void php_oci_lob_free(php_oci_descriptor * TSRMLS_DC); -int php_oci_lob_import(php_oci_descriptor *descriptor, char * TSRMLS_DC); -int php_oci_lob_append (php_oci_descriptor *, php_oci_descriptor * TSRMLS_DC); -int php_oci_lob_truncate (php_oci_descriptor *, long TSRMLS_DC); -int php_oci_lob_erase (php_oci_descriptor *, long, ub4, ub4 * TSRMLS_DC); -int php_oci_lob_is_equal (php_oci_descriptor *, php_oci_descriptor *, boolean * TSRMLS_DC); -#if defined(HAVE_OCI_LOB_READ2) -sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp); -#else -sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece); -#endif +/* {{{ lob related prototypes */ + +php_oci_descriptor *php_oci_lob_create(php_oci_connection *connection, long type TSRMLS_DC); +int php_oci_lob_get_length(php_oci_descriptor *descriptor, ub4 *length TSRMLS_DC); +int php_oci_lob_read(php_oci_descriptor *descriptor, long read_length, long inital_offset, char **data, ub4 *data_len TSRMLS_DC); +int php_oci_lob_write(php_oci_descriptor *descriptor, ub4 offset, char *data, int data_len, ub4 *bytes_written TSRMLS_DC); +int php_oci_lob_flush(php_oci_descriptor *descriptor, long flush_flag TSRMLS_DC); +int php_oci_lob_set_buffering(php_oci_descriptor *descriptor, int on_off TSRMLS_DC); +int php_oci_lob_get_buffering(php_oci_descriptor *descriptor); +int php_oci_lob_copy(php_oci_descriptor *descriptor, php_oci_descriptor *descriptor_from, long length TSRMLS_DC); +int php_oci_lob_close(php_oci_descriptor *descriptor TSRMLS_DC); +int php_oci_temp_lob_close(php_oci_descriptor *descriptor TSRMLS_DC); +int php_oci_lob_write_tmp(php_oci_descriptor *descriptor, long type, char *data, int data_len TSRMLS_DC); +void php_oci_lob_free(php_oci_descriptor *descriptor TSRMLS_DC); +int php_oci_lob_import(php_oci_descriptor *descriptor, char *filename TSRMLS_DC); +int php_oci_lob_append(php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from TSRMLS_DC); +int php_oci_lob_truncate(php_oci_descriptor *descriptor, long new_lob_length TSRMLS_DC); +int php_oci_lob_erase(php_oci_descriptor *descriptor, long offset, ub4 length, ub4 *bytes_erased TSRMLS_DC); +int php_oci_lob_is_equal(php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result TSRMLS_DC); +sb4 php_oci_lob_callback(dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp); /* }}} */ -/* collection related prototypes {{{ */ - -php_oci_collection * php_oci_collection_create(php_oci_connection *, char *, int, char *, int TSRMLS_DC); -int php_oci_collection_size(php_oci_collection *, sb4 * TSRMLS_DC); -int php_oci_collection_max(php_oci_collection *, long * TSRMLS_DC); -int php_oci_collection_trim(php_oci_collection *, long TSRMLS_DC); -int php_oci_collection_append(php_oci_collection *, char *, int TSRMLS_DC); -int php_oci_collection_element_get(php_oci_collection *, long, zval** TSRMLS_DC); -int php_oci_collection_element_set(php_oci_collection *, long, char *, int TSRMLS_DC); -int php_oci_collection_element_set_null(php_oci_collection *, long TSRMLS_DC); -int php_oci_collection_element_set_date(php_oci_collection *, long, char *, int TSRMLS_DC); -int php_oci_collection_element_set_number(php_oci_collection *, long, char *, int TSRMLS_DC); -int php_oci_collection_element_set_string(php_oci_collection *, long, char *, int TSRMLS_DC); -int php_oci_collection_assign(php_oci_collection *, php_oci_collection * TSRMLS_DC); -void php_oci_collection_close(php_oci_collection * TSRMLS_DC); -int php_oci_collection_append_null(php_oci_collection * TSRMLS_DC); -int php_oci_collection_append_date(php_oci_collection *, char *, int TSRMLS_DC); -int php_oci_collection_append_number(php_oci_collection *, char *, int TSRMLS_DC); -int php_oci_collection_append_string(php_oci_collection *, char *, int TSRMLS_DC); +/* {{{ collection related prototypes */ + +php_oci_collection *php_oci_collection_create(php_oci_connection *connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC); +int php_oci_collection_size(php_oci_collection *collection, sb4 *size TSRMLS_DC); +int php_oci_collection_max(php_oci_collection *collection, long *max TSRMLS_DC); +int php_oci_collection_trim(php_oci_collection *collection, long trim_size TSRMLS_DC); +int php_oci_collection_append(php_oci_collection *collection, char *element, int element_len TSRMLS_DC); +int php_oci_collection_element_get(php_oci_collection *collection, long index, zval **result_element TSRMLS_DC); +int php_oci_collection_element_set(php_oci_collection *collection, long index, char *value, int value_len TSRMLS_DC); +int php_oci_collection_element_set_null(php_oci_collection *collection, long index TSRMLS_DC); +int php_oci_collection_element_set_date(php_oci_collection *collection, long index, char *date, int date_len TSRMLS_DC); +int php_oci_collection_element_set_number(php_oci_collection *collection, long index, char *number, int number_len TSRMLS_DC); +int php_oci_collection_element_set_string(php_oci_collection *collection, long index, char *element, int element_len TSRMLS_DC); +int php_oci_collection_assign(php_oci_collection *collection_dest, php_oci_collection *collection_from TSRMLS_DC); +void php_oci_collection_close(php_oci_collection *collection TSRMLS_DC); +int php_oci_collection_append_null(php_oci_collection *collection TSRMLS_DC); +int php_oci_collection_append_date(php_oci_collection *collection, char *date, int date_len TSRMLS_DC); +int php_oci_collection_append_number(php_oci_collection *collection, char *number, int number_len TSRMLS_DC); +int php_oci_collection_append_string(php_oci_collection *collection, char *element, int element_len TSRMLS_DC); /* }}} */ -/* statement related prototypes {{{ */ +/* {{{ statement related prototypes */ -php_oci_statement * php_oci_statement_create (php_oci_connection *, char *, int TSRMLS_DC); -int php_oci_statement_set_prefetch (php_oci_statement *, long TSRMLS_DC); -int php_oci_statement_fetch (php_oci_statement *, ub4 TSRMLS_DC); -php_oci_out_column * php_oci_statement_get_column (php_oci_statement *, long, char *, int TSRMLS_DC); -int php_oci_statement_execute (php_oci_statement *, ub4 TSRMLS_DC); -int php_oci_statement_cancel (php_oci_statement * TSRMLS_DC); -void php_oci_statement_free (php_oci_statement * TSRMLS_DC); +php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char *query, int query_len TSRMLS_DC); +php_oci_statement *php_oci_get_implicit_resultset(php_oci_statement *statement TSRMLS_DC); +int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch TSRMLS_DC); +int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows TSRMLS_DC); +php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, long column_index, char *column_name, int column_name_len TSRMLS_DC); +int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC); +int php_oci_statement_cancel(php_oci_statement *statement TSRMLS_DC); +void php_oci_statement_free(php_oci_statement *statement TSRMLS_DC); int php_oci_bind_pre_exec(void *data, void *result TSRMLS_DC); int php_oci_bind_post_exec(void *data TSRMLS_DC); -int php_oci_bind_by_name(php_oci_statement *, char *, int, zval*, long, ub2 TSRMLS_DC); -sb4 php_oci_bind_in_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 *, ub1 *, dvoid **); -sb4 php_oci_bind_out_callback(dvoid *, OCIBind *, ub4, ub4, dvoid **, ub4 **, ub1 *, dvoid **, ub2 **); +int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long maxlength, ub2 type TSRMLS_DC); +sb4 php_oci_bind_in_callback(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp); +sb4 php_oci_bind_out_callback(dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp); php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data); int php_oci_cleanup_pre_fetch(void *data TSRMLS_DC); - -int php_oci_statement_get_type(php_oci_statement *, ub2 * TSRMLS_DC); -int php_oci_statement_get_numrows(php_oci_statement *, ub4 * TSRMLS_DC); -int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval* var, long max_table_length, long maxlength, long type TSRMLS_DC); -php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length TSRMLS_DC); -php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length TSRMLS_DC); -php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, long maxlength TSRMLS_DC); -php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, php_oci_connection *connection TSRMLS_DC); +int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type TSRMLS_DC); +int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows TSRMLS_DC); +int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, long max_table_length, long maxlength, long type TSRMLS_DC); +php_oci_bind *php_oci_bind_array_helper_number(zval *var, long max_table_length TSRMLS_DC); +php_oci_bind *php_oci_bind_array_helper_double(zval *var, long max_table_length TSRMLS_DC); +php_oci_bind *php_oci_bind_array_helper_string(zval *var, long max_table_length, long maxlength TSRMLS_DC); +php_oci_bind *php_oci_bind_array_helper_date(zval *var, long max_table_length, php_oci_connection *connection TSRMLS_DC); /* }}} */ -ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ */ - sword errcode; /* global last error code (used when connect fails, for example) */ +ZEND_BEGIN_MODULE_GLOBALS(oci) /* {{{ Module globals */ + sb4 errcode; /* global last ORA- error number. Used when connect fails, for example */ OCIError *err; /* global error handle */ - zend_bool debug_mode; /* debug mode flag */ - long max_persistent; /* maximum number of persistent connections per process */ long num_persistent; /* number of existing persistent connections */ long num_links; /* non-persistent + persistent connections */ diff --git a/ext/oci8/tests/bind_char_1.phpt b/ext/oci8/tests/bind_char_1.phpt index 91fa4b75b76b2..dc162ff943182 100644 --- a/ext/oci8/tests/bind_char_1.phpt +++ b/ext/oci8/tests/bind_char_1.phpt @@ -5,13 +5,9 @@ SELECT oci_bind_by_name with SQLT_AFC aka CHAR if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 2) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); - } -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_1_11gR1.phpt b/ext/oci8/tests/bind_char_1_11gR1.phpt index a7feff9f6a879..bdc29f766dab3 100644 --- a/ext/oci8/tests/bind_char_1_11gR1.phpt +++ b/ext/oci8/tests/bind_char_1_11gR1.phpt @@ -5,10 +5,9 @@ SELECT oci_bind_by_name with SQLT_AFC aka CHAR if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 11\.1\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_2.phpt b/ext/oci8/tests/bind_char_2.phpt index 43661a065da49..9c61a858c8e71 100644 --- a/ext/oci8/tests/bind_char_2.phpt +++ b/ext/oci8/tests/bind_char_2.phpt @@ -5,13 +5,9 @@ SELECT oci_bind_by_name with SQLT_AFC aka CHAR and dates if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 2) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); - } -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_2_11gR1.phpt b/ext/oci8/tests/bind_char_2_11gR1.phpt index edb2a12ff0a29..06c37afc93e20 100644 --- a/ext/oci8/tests/bind_char_2_11gR1.phpt +++ b/ext/oci8/tests/bind_char_2_11gR1.phpt @@ -5,10 +5,9 @@ SELECT oci_bind_by_name with SQLT_AFC aka CHAR and dates if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 11\.1\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_3.phpt b/ext/oci8/tests/bind_char_3.phpt index 25115836dfcb7..177676e25ca3b 100644 --- a/ext/oci8/tests/bind_char_3.phpt +++ b/ext/oci8/tests/bind_char_3.phpt @@ -5,13 +5,9 @@ PL/SQL oci_bind_by_name with SQLT_AFC aka CHAR to CHAR parameter if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 2) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); - } -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_3_11gR1.phpt b/ext/oci8/tests/bind_char_3_11gR1.phpt index fea77754d1760..c3ec999d0f10d 100644 --- a/ext/oci8/tests/bind_char_3_11gR1.phpt +++ b/ext/oci8/tests/bind_char_3_11gR1.phpt @@ -5,10 +5,9 @@ PL/SQL oci_bind_by_name with SQLT_AFC aka CHAR to CHAR parameter if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 11\.1\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_4.phpt b/ext/oci8/tests/bind_char_4.phpt index 36765f8137443..b4d3e089b136f 100644 --- a/ext/oci8/tests/bind_char_4.phpt +++ b/ext/oci8/tests/bind_char_4.phpt @@ -5,13 +5,9 @@ PL/SQL oci_bind_by_name with SQLT_AFC aka CHAR to VARCHAR2 parameter if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 2) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); - } -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_4_11gR1.phpt b/ext/oci8/tests/bind_char_4_11gR1.phpt index 2bc2f1424634d..ccad2cb7894c1 100644 --- a/ext/oci8/tests/bind_char_4_11gR1.phpt +++ b/ext/oci8/tests/bind_char_4_11gR1.phpt @@ -5,10 +5,9 @@ PL/SQL oci_bind_by_name with SQLT_AFC aka CHAR to VARCHAR2 parameter if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 11\.1\./', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_misccoltypes.phpt b/ext/oci8/tests/bind_misccoltypes.phpt index 0da8c8bf8803a..9e55b3b1ff74b 100644 --- a/ext/oci8/tests/bind_misccoltypes.phpt +++ b/ext/oci8/tests/bind_misccoltypes.phpt @@ -4,9 +4,6 @@ Bind miscellaneous column types using default types true, 'timesten' => false); // test runs on these DBs require(dirname(__FILE__).'/skipif.inc'); -if (preg_match('/^1[012]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- --INI-- precision = 14 diff --git a/ext/oci8/tests/bind_sqltnum.phpt b/ext/oci8/tests/bind_sqltnum.phpt index d3828b73eea95..93fc4809ec10d 100644 --- a/ext/oci8/tests/bind_sqltnum.phpt +++ b/ext/oci8/tests/bind_sqltnum.phpt @@ -3,9 +3,6 @@ Bind with SQLT_NUM --SKIPIF-- --FILE-- --FILE-- = 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_1_11gR1.phpt b/ext/oci8/tests/bug27303_1_11gR1.phpt index 6de9b99378553..d2018783bc925 100644 --- a/ext/oci8/tests/bug27303_1_11gR1.phpt +++ b/ext/oci8/tests/bug27303_1_11gR1.phpt @@ -5,12 +5,9 @@ Bug #27303 (OCIBindByName binds numeric PHP values as characters) if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.1\.0\.6/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using specific Oracle database versions"); - } - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug27303_2.phpt b/ext/oci8/tests/bug27303_2.phpt index 1fb2b31682719..ee2f7b52aa5e6 100644 --- a/ext/oci8/tests/bug27303_2.phpt +++ b/ext/oci8/tests/bug27303_2.phpt @@ -5,13 +5,9 @@ Bug #27303 (OCIBindByName binds numeric PHP values as characters) if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\.0\.2/', oci_server_version($c), $matches) !== 1 && - preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 10.2.0.2 or 11.2.0.2 databases"); - // Other point releases may also work -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_2_11gR1.phpt b/ext/oci8/tests/bug27303_2_11gR1.phpt index 1e3e3105ad665..06133e0115723 100644 --- a/ext/oci8/tests/bug27303_2_11gR1.phpt +++ b/ext/oci8/tests/bug27303_2_11gR1.phpt @@ -5,12 +5,9 @@ Bug #27303 (OCIBindByName binds numeric PHP values as characters) if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.1\.0\.6/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using specific Oracle database versions"); - } - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug27303_4.phpt b/ext/oci8/tests/bug27303_4.phpt index 3137db8659191..ed9d5a1fe6d43 100644 --- a/ext/oci8/tests/bug27303_4.phpt +++ b/ext/oci8/tests/bug27303_4.phpt @@ -5,13 +5,9 @@ Bug #27303 (OCIBindByName binds numeric PHP values as characters) if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\.0\.2/', oci_server_version($c), $matches) !== 1 && - preg_match('/Release 11\.2\.0\.2/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 10.2.0.2 or 11.2.0.2 databases"); - // Other point releases may also work -} -if (preg_match('/^11\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_4_11gR1.phpt b/ext/oci8/tests/bug27303_4_11gR1.phpt index f9bc2da8a25ad..550d89fdcc52f 100644 --- a/ext/oci8/tests/bug27303_4_11gR1.phpt +++ b/ext/oci8/tests/bug27303_4_11gR1.phpt @@ -5,12 +5,9 @@ Bug #27303 (OCIBindByName binds numeric PHP values as characters) if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. -if (preg_match('/Release 10\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.1\.0\.6/', oci_server_version($c), $matches) !== 1) { - if (preg_match('/Release 11\.2\.0\.3/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using specific Oracle database versions"); - } - } +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug36403.phpt b/ext/oci8/tests/bug36403.phpt index 53dae694ec8bf..122b06bbfa2b0 100644 --- a/ext/oci8/tests/bug36403.phpt +++ b/ext/oci8/tests/bug36403.phpt @@ -3,9 +3,6 @@ Bug #36403 (oci_execute no longer supports OCI_DESCRIBE_ONLY) --SKIPIF-- --FILE-- true, 'timesten' => false); // test runs on these DBs require(dirname(__FILE__).'/skipif.inc'); if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); -if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip expected output only valid with Oracle 10g or greater version of client"); -} ?> --FILE-- true, 'timesten' => false); // test runs on these DBs -require(dirname(__FILE__).'/skipif.inc'); -if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); -ob_start(); -phpinfo(INFO_MODULES); -$phpinfo = ob_get_clean(); -$iv = preg_match('/Oracle .*Version => (9\.2)/', $phpinfo); -if ($iv != 1) { - die ("skip tests a feature that works only with Oracle 9iR2 client"); -} -?> ---FILE-- -free(); // cleanup properly - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -// Read all XML data using explicit LOB locator but without freeing the temp lobs -function readxmltab_ex_nofree($c) -{ - $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); - - $cntchk = 0; - if (oci_execute($stmt)) { - while ($result = oci_fetch_array($stmt, OCI_NUM)) { - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -// Read all XML data using implicit LOB locator -function readxmltab_im($c) -{ - $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); - - $cntchk = 0; - if (oci_execute($stmt)) { - while ($result = oci_fetch_array($stmt, OCI_NUM+OCI_RETURN_LOBS)) { - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -function createxmltab($c) // create table w/ field of XML type -{ - @dropxmltab($c); - $stmt = oci_parse($c, "create table bug43497_tab (id number primary key, xml xmltype)"); - oci_execute($stmt); -} - -function dropxmltab($c) // delete table -{ - $stmt = oci_parse($c, "drop table bug43497_tab"); - oci_execute($stmt); -} - - -function fillxmltab($c) -{ - for ($id = 1; $id <= 100; $id++) { - - // create an XML element string with random data - $s = ""; - for ($j = 0; $j < 128; $j++) { - $s .= rand(); - } - $s .= "\n"; - for ($j = 0; $j < 4; $j++) { - $s .= $s; - } - $data = "" . $s . ""; - - // insert XML data into database - - $stmt = oci_parse($c, "insert into bug43497_tab(id, xml) values (:id, sys.xmltype.createxml(:xml))"); - oci_bind_by_name($stmt, ":id", $id); - $clob = oci_new_descriptor($c, OCI_D_LOB); - oci_bind_by_name($stmt, ":xml", $clob, -1, OCI_B_CLOB); - $clob->writetemporary($data); - oci_execute($stmt); - - $clob->close(); - $clob->free(); - } -} - - -// Initialize - -createxmltab($c); -fillxmltab($c); - -// Run Test - -$sid = sessionid($c); - -echo "Explicit LOB use\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_ex($c); -} - -echo "\nImplicit LOB use\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_im($c); -} - -echo "\nExplicit LOB with no free (i.e. a temp lob leak)\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_ex_nofree($c); -} - - - -// Cleanup - -dropxmltab($c); - -oci_close($c); - -echo "Done\n"; -?> ---EXPECT-- -Explicit LOB use - -Run = 1 -Temporary LOBs = 0 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 900 -Loop count check = 100 - -Implicit LOB use - -Run = 1 -Temporary LOBs = 1000 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 1100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 1200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 1300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 1400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 1500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 1600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 1700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 1800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 1900 -Loop count check = 100 - -Explicit LOB with no free (i.e. a temp lob leak) - -Run = 1 -Temporary LOBs = 2000 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 2100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 2200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 2300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 2400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 2500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 2600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 2700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 2800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 2900 -Loop count check = 100 -Done \ No newline at end of file diff --git a/ext/oci8/tests/bug47281.phpt b/ext/oci8/tests/bug47281.phpt index d0e00235374c9..00c43c22dac7c 100644 --- a/ext/oci8/tests/bug47281.phpt +++ b/ext/oci8/tests/bug47281.phpt @@ -6,11 +6,12 @@ $target_dbs = array('oracledb' => true, 'timesten' => false); // test runs on t require(dirname(__FILE__).'/skipif.inc'); // error3.phpt obsoletes this test for newer Oracle client versions // Assume runtime client version is >= compile time client version -$cv = explode('.', oci_client_version()); -if ($cv[0] > 11 || ($cv[0] == 11 && $cv[1] > 2) || ($cv[0] == 11 && $cv[1] == 2 && $cv[3] >= 3)) { +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!isset($matches[0]) || + ($matches[1] > 11 || ($matches[1] == 11 && $matches[2] > 2) || ($matches[1] == 11 && $matches[2] == 2 && $matches[4] >= 3) + )) { die("skip test works only with Oracle 11.2.0.2 or earlier Oracle client libraries"); } - ?> --ENV-- NLS_LANG=.AL32UTF8 diff --git a/ext/oci8/tests/clientversion.phpt b/ext/oci8/tests/clientversion.phpt index db70b5affcea4..262ded462f9d9 100644 --- a/ext/oci8/tests/clientversion.phpt +++ b/ext/oci8/tests/clientversion.phpt @@ -3,9 +3,6 @@ oci_client_version() --SKIPIF-- --FILE-- ---FILE-- - -===DONE=== - ---EXPECTF-- -Unknown -===DONE=== diff --git a/ext/oci8/tests/commit_001.phpt b/ext/oci8/tests/commit_001.phpt index 806fb193a0e7c..ef4018118e31a 100644 --- a/ext/oci8/tests/commit_001.phpt +++ b/ext/oci8/tests/commit_001.phpt @@ -81,48 +81,48 @@ echo "Done\n"; bool(true) int(0) array(5) { - [%u|b%"ID"]=> + ["ID"]=> array(0) { } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(0) { } - [%u|b%"BLOB"]=> + ["BLOB"]=> array(0) { } - [%u|b%"CLOB"]=> + ["CLOB"]=> array(0) { } - [%u|b%"STRING"]=> + ["STRING"]=> array(0) { } } bool(true) int(4) array(5) { - [%u|b%"ID"]=> + ["ID"]=> array(4) { [0]=> - %string|unicode%(1) "1" + string(1) "1" [1]=> - %string|unicode%(1) "1" + string(1) "1" [2]=> - %string|unicode%(1) "1" + string(1) "1" [3]=> - %string|unicode%(1) "1" + string(1) "1" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(4) { [0]=> - %string|unicode%(1) "1" + string(1) "1" [1]=> - %string|unicode%(1) "1" + string(1) "1" [2]=> - %string|unicode%(1) "1" + string(1) "1" [3]=> - %string|unicode%(1) "1" + string(1) "1" } - [%u|b%"BLOB"]=> + ["BLOB"]=> array(4) { [0]=> NULL @@ -133,7 +133,7 @@ array(5) { [3]=> NULL } - [%u|b%"CLOB"]=> + ["CLOB"]=> array(4) { [0]=> NULL @@ -144,7 +144,7 @@ array(5) { [3]=> NULL } - [%u|b%"STRING"]=> + ["STRING"]=> array(4) { [0]=> NULL diff --git a/ext/oci8/tests/conn_attr.inc b/ext/oci8/tests/conn_attr.inc index 220e6882106b6..2edc1c95528db 100644 --- a/ext/oci8/tests/conn_attr.inc +++ b/ext/oci8/tests/conn_attr.inc @@ -2,30 +2,28 @@ require(dirname(__FILE__)."/connect.inc"); -$sv = oci_server_version($c); -$sv = preg_match('/Release (11\.2|12)\./', $sv, $matches); -if ($sv == 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if ((isset($matches[1]) && $matches[1] >= 11)) { // Server is Oracle 11.2+ $stmtarray = array( - "drop user testuser cascade", - "create user testuser identified by testuser", - "grant connect,resource,dba to testuser", - "alter user testuser enable editions", - "drop edition myedition1", - "drop edition myedition", - "grant create any edition to testuser", + "drop user $testuser cascade", + "create user $testuser identified by $testpassword", // $testuser should be set by the file that includes conn_attr.inc + "grant connect,resource,dba to $testuser", + "alter user $testuser enable editions", + "drop edition myedition1 cascade", + "drop edition myedition cascade", + "grant create any edition to $testuser", "create edition myedition", "create edition myedition1 as child of myedition", - "grant use on edition myedition to testuser", - "grant use on edition myedition1 to testuser", + "grant use on edition myedition to $testuser", + "grant use on edition myedition1 to $testuser", ); -} -else { +} else { // Server is Pre 11.2 $stmtarray = array( - "drop user testuser cascade", - "create user testuser identified by testuser", - "grant connect,resource,dba to testuser", + "drop user $testuser cascade", + "create user $testuser identified by $testpassword", + "grant connect,resource,dba to $testuser", ); } @@ -68,8 +66,8 @@ function get_attr($conn,$attr) function get_conn($conn_type) { - $user = 'testuser'; - $password = 'testuser'; + $user = $GLOBALS['testuser']; + $password = $GLOBALS['testpassword']; $dbase = $GLOBALS['dbase']; switch($conn_type) { case 1: @@ -139,9 +137,9 @@ function get_sys_attr($conn,$attr) function clean_up($c) { $stmtarray = array( - "drop user testuser cascade", - "drop edition myedition1", - "drop edition myedition", + "drop edition myedition1 cascade", + "drop edition myedition cascade", + "drop user " . $GLOBALS['testuser'] . " cascade", ); foreach ($stmtarray as $stmt) { diff --git a/ext/oci8/tests/conn_attr_1.phpt b/ext/oci8/tests/conn_attr_1.phpt index ad508a2ed2a4f..745b1cd93f906 100644 --- a/ext/oci8/tests/conn_attr_1.phpt +++ b/ext/oci8/tests/conn_attr_1.phpt @@ -9,15 +9,17 @@ if (strcasecmp($user, "system") && strcasecmp($user, "sys")) die("skip needs to be run as a DBA user"); if ($test_drcp) die("skip output might vary with DRCP"); -if (preg_match('/Release 1[01]\./', oci_server_version($c), $matches) !== 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); -} else if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); } - ?> --FILE-- = 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); -} else if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); } - ?> --INI-- oci8.privileged_connect = On --FILE-- = 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); -} else if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); } ?> --FILE-- = 2) || + ($matches[1] >= 12) + ))) { + // Bug fixed in 11.2 prevents client_info being reset die("skip expected output only valid when using Oracle 11gR2 or greater database server"); -} else if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); } ?> --FILE-- = 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); -} else if (preg_match('/^1[01]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); } ?> --FILE-- (10\.2)/', $phpinfo); -if ($iv != 1) { - die ("skip tests a feature that works only with Oracle 10gR2"); +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!isset($matches[0]) || !($matches[1] == 10 && $matches[2] == 2)) { + die ("skip tests a feature that works only with Oracle 10gR2 client"); } ?> --ENV-- diff --git a/ext/oci8/tests/connect_without_oracle_home_11.phpt b/ext/oci8/tests/connect_without_oracle_home_11.phpt index 1620803dbb738..42c45644567c4 100644 --- a/ext/oci8/tests/connect_without_oracle_home_11.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_11.phpt @@ -10,7 +10,11 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov != 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/^11\.2|12\./', oci_client_version()) != 1) { +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/connect_without_oracle_home_old.phpt b/ext/oci8/tests/connect_without_oracle_home_old.phpt index 5a731337af13c..d6d12b47ba338 100644 --- a/ext/oci8/tests/connect_without_oracle_home_old.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_old.phpt @@ -10,9 +10,6 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/^10\.2\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10gR2 client libraries"); -} ?> --ENV-- ORACLE_HOME="" @@ -33,5 +30,8 @@ else { --EXPECTF-- Warning: ocilogon(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and %s are set and point to the right directories in %s on line %d + +Warning: ocilogon(): %s ORA-01804 + in %s on line %d bool(false) ===DONE=== diff --git a/ext/oci8/tests/connect_without_oracle_home_old_11.phpt b/ext/oci8/tests/connect_without_oracle_home_old_11.phpt index c7cfecf396119..eb5fb0cc4d333 100644 --- a/ext/oci8/tests/connect_without_oracle_home_old_11.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_old_11.phpt @@ -10,7 +10,11 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/^11\.2|12\./', oci_client_version()) != 1) { +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/cursors_old.phpt b/ext/oci8/tests/cursors_old.phpt index d60e2ff1ea430..aa25937570e59 100644 --- a/ext/oci8/tests/cursors_old.phpt +++ b/ext/oci8/tests/cursors_old.phpt @@ -52,19 +52,19 @@ echo "Done\n"; ?> --EXPECTF-- array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(1) "1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(1) "1" } bool(true) Warning: ocifetchinto():%sORA-01002: %s in %scursors_old.php on line %d array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(1) "1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(1) "1" } bool(true) Done diff --git a/ext/oci8/tests/db_op_1.phpt b/ext/oci8/tests/db_op_1.phpt new file mode 100644 index 0000000000000..f645cf80ff3b2 --- /dev/null +++ b/ext/oci8/tests/db_op_1.phpt @@ -0,0 +1,61 @@ +--TEST-- +oci_set_db_operation: basic test for end-to-end tracing +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { + die("skip needs to be run as a DBA user"); +} +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +if (!function_exists('oci_set_db_operation')) +{ + die("skip function oci_set_db_operation() does not exist"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +array(1) { + ["DBOP_NAME"]=> + string(7) "db_op_1" +} +===DONE=== + diff --git a/ext/oci8/tests/db_op_2.phpt b/ext/oci8/tests/db_op_2.phpt new file mode 100644 index 0000000000000..05c2269ae0bfd --- /dev/null +++ b/ext/oci8/tests/db_op_2.phpt @@ -0,0 +1,69 @@ +--TEST-- +oci_set_db_operation: basic test for end-to-end tracing +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { + die("skip needs to be run as a DBA user"); +} +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +if (!function_exists('oci_set_db_operation')) +{ + die("skip function oci_set_db_operation() does not exist"); +} +?> +--FILE-- + +===DONE=== + +--XFAIL-- +Fails due to Oracle Bug 16695981 +--EXPECTF-- +Test 1 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +Test 2 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +Test 3 +array(2) { + ["DBOP_NAME"]=> + string(7) "db_op_2a" +} +===DONE=== + diff --git a/ext/oci8/tests/debug.phpt b/ext/oci8/tests/debug.phpt index fe96e6e87ec44..66ab0f0d005f0 100644 --- a/ext/oci8/tests/debug.phpt +++ b/ext/oci8/tests/debug.phpt @@ -16,10 +16,9 @@ else { oci_connect($user, $password); } -echo "Done\n"; - oci_internal_debug(false); ?> ---EXPECTREGEX-- -^OCI8 DEBUG: .*Done$ +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/oci8/tests/define.phpt b/ext/oci8/tests/define.phpt index c6ce7bd9b3048..b78f698e7c38e 100644 --- a/ext/oci8/tests/define.phpt +++ b/ext/oci8/tests/define.phpt @@ -44,5 +44,5 @@ echo "Done\n"; ?> --EXPECTF-- -%unicode|string%(%d) "some" +string(%d) "some" Done diff --git a/ext/oci8/tests/define1.phpt b/ext/oci8/tests/define1.phpt index 6e4b74e3bacb5..be16271d5bb16 100644 --- a/ext/oci8/tests/define1.phpt +++ b/ext/oci8/tests/define1.phpt @@ -55,5 +55,5 @@ bool(false) Warning: oci_define_by_name() expects at least 3 parameters, 2 given in %s on line %d NULL -%unicode|string%(4) "some" +string(4) "some" Done diff --git a/ext/oci8/tests/define4.phpt b/ext/oci8/tests/define4.phpt index 266fd7edd70fe..3114a73937696 100644 --- a/ext/oci8/tests/define4.phpt +++ b/ext/oci8/tests/define4.phpt @@ -58,15 +58,15 @@ echo "Done\n"; Test 1 bool(true) Test 2 -%unicode|string%(4) "1234" -%unicode|string%(4) "some" -%unicode|string%(4) "some" -%unicode|string%(4) "some" -%unicode|string%(4) "1234" -%unicode|string%(4) "some" +string(4) "1234" +string(4) "some" +string(4) "some" +string(4) "some" +string(4) "1234" +string(4) "some" Test 3 bool(true) -%unicode|string%(4) "some" +string(4) "some" Warning: oci_result(): %d is not a valid oci8 statement resource in %s on line %d bool(false) diff --git a/ext/oci8/tests/define5.phpt b/ext/oci8/tests/define5.phpt index 68fa01d09aa87..978d66b260745 100644 --- a/ext/oci8/tests/define5.phpt +++ b/ext/oci8/tests/define5.phpt @@ -61,12 +61,12 @@ echo "Done\n"; Test 1 - must do define before execute bool(true) NULL -%unicode|string%(4) "some" +string(4) "some" Test 2 - normal define order bool(true) -%unicode|string%(4) "some" +string(4) "some" Test 3 - no new define done -%unicode|string%(4) "some" -%unicode|string%(5) "thing" +string(4) "some" +string(5) "thing" Done diff --git a/ext/oci8/tests/define_old.phpt b/ext/oci8/tests/define_old.phpt index f65e6b80809b4..cc07e2ea94fb8 100644 --- a/ext/oci8/tests/define_old.phpt +++ b/ext/oci8/tests/define_old.phpt @@ -44,5 +44,5 @@ echo "Done\n"; ?> --EXPECTF-- -%unicode|string%(4) "some" +string(4) "some" Done diff --git a/ext/oci8/tests/details.inc b/ext/oci8/tests/details.inc index 9a86c46868478..e54ea84abdb47 100644 --- a/ext/oci8/tests/details.inc +++ b/ext/oci8/tests/details.inc @@ -52,7 +52,7 @@ if (!function_exists('oci8_test_sql_execute')) { $s = oci_parse($c, $stmt); if (!$s) { $m = oci_error($c); - echo $stmt . PHP_EOL . $m['message'] . PHP_EOL; + echo "oci8_test_sql_execute() error:". PHP_EOL . $stmt . PHP_EOL . $m['message'] . PHP_EOL; } else { $r = @oci_execute($s); @@ -66,7 +66,7 @@ if (!function_exists('oci8_test_sql_execute')) { , 4080 // trigger does not exist , 38802 // edition does not exist ))) { - echo $stmt . PHP_EOL . $m['message'] . PHP_EOL; + echo "oci8_test_sql_execute() error:". PHP_EOL . $stmt . PHP_EOL . $m['message'] . PHP_EOL; } } } diff --git a/ext/oci8/tests/drcp_cclass1.phpt b/ext/oci8/tests/drcp_cclass1.phpt index 068331e5a95ae..5c78a2943e94e 100644 --- a/ext/oci8/tests/drcp_cclass1.phpt +++ b/ext/oci8/tests/drcp_cclass1.phpt @@ -3,9 +3,21 @@ DRCP: Test setting connection class inline --SKIPIF-- = 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); +} ?> --FILE-- += 11)) { + die("skip works only with Oracle 11g or greater version of Oracle client libraries"); +} +?> --INI-- oci8.connection_class=test --FILE-- diff --git a/ext/oci8/tests/drcp_privileged.phpt b/ext/oci8/tests/drcp_privileged.phpt index da8702e3c9204..3871341bc50cc 100644 --- a/ext/oci8/tests/drcp_privileged.phpt +++ b/ext/oci8/tests/drcp_privileged.phpt @@ -3,7 +3,8 @@ DRCP: privileged connect --SKIPIF-- = 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); +} ?> --INI-- oci8.privileged_connect=1 diff --git a/ext/oci8/tests/driver_name.phpt b/ext/oci8/tests/driver_name.phpt index bf86e66e7b64f..f63979d6b54c0 100644 --- a/ext/oci8/tests/driver_name.phpt +++ b/ext/oci8/tests/driver_name.phpt @@ -7,10 +7,19 @@ require(dirname(__FILE__)."/connect.inc"); if (strcasecmp($user, "system") && strcasecmp($user, "sys")) die("skip needs to be run as a DBA user"); if ($test_drcp) die("skip as Output might vary with DRCP"); -if (preg_match('/Release (11\.2|12)/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12\.)/', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/edition_1.phpt b/ext/oci8/tests/edition_1.phpt index b9c8fd817ef87..3e55ee902c970 100644 --- a/ext/oci8/tests/edition_1.phpt +++ b/ext/oci8/tests/edition_1.phpt @@ -10,9 +10,18 @@ if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { if ($test_drcp) { die("skip as Output might vary with DRCP"); } -if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12)\./', oci_client_version()) != 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> @@ -24,6 +33,9 @@ if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== * already */ +$testuser = 'testuser_attr_1'; // Used in conn_attr.inc +$testpassword = 'testuser'; + require(dirname(__FILE__)."/conn_attr.inc"); function select_fn($conn) { @@ -39,7 +51,7 @@ function select_fn($conn) { select from both the editions and verify the contents. */ set_edit_attr('MYEDITION'); -$conn = oci_connect('testuser','testuser',$dbase); +$conn = oci_connect($testuser,$testpassword,$dbase); if ($conn === false) { $m = oci_error(); die("Error:" . $m['message']); @@ -61,7 +73,7 @@ select_fn($conn); // Create a different version of view_ed in MYEDITION1. set_edit_attr('MYEDITION1'); -$conn2 = oci_new_connect('testuser','testuser',$dbase); +$conn2 = oci_new_connect($testuser,$testpassword,$dbase); $stmt = "create or replace editioning view view_ed as select name,age,job,salary from edit_tab"; $s = oci_parse($conn2, $stmt); oci_execute($s); @@ -87,58 +99,58 @@ The value of edition has been successfully set The value of current EDITION is MYEDITION array(3) { [0]=> - %unicode|string%(%d) "mike" + string(%d) "mike" [1]=> - %unicode|string%(%d) "30" + string(%d) "30" [2]=> - %unicode|string%(%d) "Senior engineer" + string(%d) "Senior engineer" } array(3) { [0]=> - %unicode|string%(%d) "juan" + string(%d) "juan" [1]=> - %unicode|string%(%d) "25" + string(%d) "25" [2]=> - %unicode|string%(%d) "engineer" + string(%d) "engineer" } The value of edition has been successfully set The value of current EDITION is MYEDITION1 array(4) { [0]=> - %unicode|string%(%d) "mike" + string(%d) "mike" [1]=> - %unicode|string%(%d) "30" + string(%d) "30" [2]=> - %unicode|string%(%d) "Senior engineer" + string(%d) "Senior engineer" [3]=> - %unicode|string%(%d) "200" + string(%d) "200" } array(4) { [0]=> - %unicode|string%(%d) "juan" + string(%d) "juan" [1]=> - %unicode|string%(%d) "25" + string(%d) "25" [2]=> - %unicode|string%(%d) "engineer" + string(%d) "engineer" [3]=> - %unicode|string%(%d) "100" + string(%d) "100" } version of view_ed in MYEDITION The value of current EDITION is MYEDITION array(3) { [0]=> - %unicode|string%(%d) "mike" + string(%d) "mike" [1]=> - %unicode|string%(%d) "30" + string(%d) "30" [2]=> - %unicode|string%(%d) "Senior engineer" + string(%d) "Senior engineer" } array(3) { [0]=> - %unicode|string%(%d) "juan" + string(%d) "juan" [1]=> - %unicode|string%(%d) "25" + string(%d) "25" [2]=> - %unicode|string%(%d) "engineer" + string(%d) "engineer" } Done diff --git a/ext/oci8/tests/edition_2.phpt b/ext/oci8/tests/edition_2.phpt index 030e6a673c859..12e902667e621 100644 --- a/ext/oci8/tests/edition_2.phpt +++ b/ext/oci8/tests/edition_2.phpt @@ -8,10 +8,18 @@ if (strcasecmp($user, "system") && strcasecmp($user, "sys")) die("skip needs to be run as a DBA user"); if ($test_drcp) die("skip as Output might vary with DRCP"); - -if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12)\./', oci_client_version()) != 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } @@ -24,10 +32,10 @@ if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== * already */ -require(dirname(__FILE__)."/conn_attr.inc"); +$testuser = 'testuser_ed_2'; // Used in conn_attr.inc +$testpassword = 'testuser'; -$user = 'testuser'; -$password = 'testuser'; +require(dirname(__FILE__)."/conn_attr.inc"); echo"**Test 1.1 - Default value for the attribute **************\n"; get_edit_attr($c); @@ -50,7 +58,7 @@ get_edit_attr($conn3); oci_close($conn1); // With a oci_pconnect with a different charset. -$pc1 = oci_pconnect($user,$password,$dbase,"utf8"); +$pc1 = oci_pconnect($testuser,$testpassword,$dbase,"utf8"); get_edit_attr($pc1); oci_close($pc1); @@ -145,7 +153,7 @@ function set_scope() { } function get_scope() { - $sc1 = oci_connect($GLOBALS['user'],$GLOBALS['password'],$GLOBALS['dbase']); + $sc1 = oci_connect($GLOBALS['testuser'],$GLOBALS['testpassword'],$GLOBALS['dbase']); if ($sc1 === false) { $m = oci_error(); die("Error:" . $m['message']); diff --git a/ext/oci8/tests/error_set.phpt b/ext/oci8/tests/error_set.phpt new file mode 100644 index 0000000000000..ad56e8aefadb1 --- /dev/null +++ b/ext/oci8/tests/error_set.phpt @@ -0,0 +1,72 @@ +--TEST-- +Check oci_set_{action,client_identifier,module_name,client_info} error handling +--SKIPIF-- + +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +bool(false) +24960 +bool(false) +24960 +bool(false) +24960 +bool(false) +24960 + +Test 2 +bool(true) +bool(true) +bool(true) +bool(true) +===DONE=== diff --git a/ext/oci8/tests/extauth_01.phpt b/ext/oci8/tests/extauth_01.phpt index 37f8f3834d803..1194ae180dd20 100644 --- a/ext/oci8/tests/extauth_01.phpt +++ b/ext/oci8/tests/extauth_01.phpt @@ -143,56 +143,56 @@ Test 7 Warning: oci_connect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 8 Warning: oci_connect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 9 Warning: oci_connect(): ORA-%d: TNS:%s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 10 Warning: oci_connect(): ORA-%d: TNS:%s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/extauth_02.phpt b/ext/oci8/tests/extauth_02.phpt index f3b517f730af4..0a3227019ce41 100644 --- a/ext/oci8/tests/extauth_02.phpt +++ b/ext/oci8/tests/extauth_02.phpt @@ -142,56 +142,56 @@ Test 7 Warning: oci_new_connect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 8 Warning: oci_new_connect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 9 Warning: oci_new_connect(): ORA-%d: TNS:%s %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 10 Warning: oci_new_connect(): ORA-%d: TNS:%s %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/extauth_03.phpt b/ext/oci8/tests/extauth_03.phpt index e6685eb1769ba..d7884ce6b48f6 100644 --- a/ext/oci8/tests/extauth_03.phpt +++ b/ext/oci8/tests/extauth_03.phpt @@ -142,56 +142,56 @@ Test 7 Warning: oci_pconnect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 8 Warning: oci_pconnect(): ORA-12154: %s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(12154) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-12154: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-12154: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 9 Warning: oci_pconnect(): ORA-%d: TNS:%s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) Test 10 Warning: oci_pconnect(): ORA-%d: TNS:%s in %s on line %d array(4) { - [%u|b%"code"]=> + ["code"]=> int(%d) - [%u|b%"message"]=> - %unicode|string%(%d) "ORA-%d: %s" - [%u|b%"offset"]=> + ["message"]=> + string(%d) "ORA-%d: %s" + ["offset"]=> int(0) - [%u|b%"sqltext"]=> - %unicode|string%(0) "" + ["sqltext"]=> + string(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/fetch.phpt b/ext/oci8/tests/fetch.phpt index e48aeefd87b61..b968ae4bf6ea1 100644 --- a/ext/oci8/tests/fetch.phpt +++ b/ext/oci8/tests/fetch.phpt @@ -47,10 +47,10 @@ oci8_test_sql_execute($c, $stmtarray); echo "Done\n"; ?> --EXPECTF-- -%unicode|string%(1) "1" -%unicode|string%(1) "1" -%unicode|string%(1) "1" -%unicode|string%(1) "1" -%unicode|string%(1) "1" -%unicode|string%(1) "1" +string(1) "1" +string(1) "1" +string(1) "1" +string(1) "1" +string(1) "1" +string(1) "1" Done diff --git a/ext/oci8/tests/fetch_all.phpt b/ext/oci8/tests/fetch_all.phpt index 4fc41daad482f..b8155b170b0aa 100644 --- a/ext/oci8/tests/fetch_all.phpt +++ b/ext/oci8/tests/fetch_all.phpt @@ -51,44 +51,44 @@ echo "Done\n"; --EXPECTF-- int(3) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } } int(3) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } } Done diff --git a/ext/oci8/tests/fetch_all1.phpt b/ext/oci8/tests/fetch_all1.phpt index 4fc41daad482f..b8155b170b0aa 100644 --- a/ext/oci8/tests/fetch_all1.phpt +++ b/ext/oci8/tests/fetch_all1.phpt @@ -51,44 +51,44 @@ echo "Done\n"; --EXPECTF-- int(3) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } } int(3) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" [2]=> - %unicode|string%(1) "1" + string(1) "1" } } Done diff --git a/ext/oci8/tests/fetch_all3.phpt b/ext/oci8/tests/fetch_all3.phpt index 1748ea5658eb3..4c0be1cc079b1 100644 --- a/ext/oci8/tests/fetch_all3.phpt +++ b/ext/oci8/tests/fetch_all3.phpt @@ -129,105 +129,105 @@ echo "Done\n"; None int(4) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_ASSOC int(4) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_COLUMN int(4) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_COLUMN|OCI_ASSOC int(4) array(2) { - [%u|b%"ID"]=> + ["ID"]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } - [%u|b%"VALUE"]=> + ["VALUE"]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_COLUMN|OCI_NUM @@ -236,24 +236,24 @@ array(2) { [0]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } [1]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_COLUMN|OCI_NUM|OCI_ASSOC @@ -262,24 +262,24 @@ array(2) { [0]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } [1]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW @@ -287,31 +287,31 @@ int(4) array(4) { [0]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(2) "-1" } [1]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "2" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-2" + ["ID"]=> + string(1) "2" + ["VALUE"]=> + string(2) "-2" } [2]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "3" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-3" + ["ID"]=> + string(1) "3" + ["VALUE"]=> + string(2) "-3" } [3]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "4" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-4" + ["ID"]=> + string(1) "4" + ["VALUE"]=> + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_ASSOC @@ -319,31 +319,31 @@ int(4) array(4) { [0]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(2) "-1" } [1]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "2" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-2" + ["ID"]=> + string(1) "2" + ["VALUE"]=> + string(2) "-2" } [2]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "3" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-3" + ["ID"]=> + string(1) "3" + ["VALUE"]=> + string(2) "-3" } [3]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "4" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-4" + ["ID"]=> + string(1) "4" + ["VALUE"]=> + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_FETCHSTATEMENT_BY_COLUMN @@ -351,31 +351,31 @@ int(4) array(4) { [0]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(2) "-1" } [1]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "2" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-2" + ["ID"]=> + string(1) "2" + ["VALUE"]=> + string(2) "-2" } [2]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "3" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-3" + ["ID"]=> + string(1) "3" + ["VALUE"]=> + string(2) "-3" } [3]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "4" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-4" + ["ID"]=> + string(1) "4" + ["VALUE"]=> + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_FETCHSTATEMENT_BY_COLUMN|OCI_ASSOC @@ -383,31 +383,31 @@ int(4) array(4) { [0]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-1" + ["ID"]=> + string(1) "1" + ["VALUE"]=> + string(2) "-1" } [1]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "2" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-2" + ["ID"]=> + string(1) "2" + ["VALUE"]=> + string(2) "-2" } [2]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "3" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-3" + ["ID"]=> + string(1) "3" + ["VALUE"]=> + string(2) "-3" } [3]=> array(2) { - [%u|b%"ID"]=> - %unicode|string%(1) "4" - [%u|b%"VALUE"]=> - %unicode|string%(2) "-4" + ["ID"]=> + string(1) "4" + ["VALUE"]=> + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_FETCHSTATEMENT_BY_COLUMN|OCI_NUM @@ -416,30 +416,30 @@ array(4) { [0]=> array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(2) "-1" + string(2) "-1" } [1]=> array(2) { [0]=> - %unicode|string%(1) "2" + string(1) "2" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" } [2]=> array(2) { [0]=> - %unicode|string%(1) "3" + string(1) "3" [1]=> - %unicode|string%(2) "-3" + string(2) "-3" } [3]=> array(2) { [0]=> - %unicode|string%(1) "4" + string(1) "4" [1]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_FETCHSTATEMENT_BY_COLUMN|OCI_NUM|OCI_ASSOC @@ -448,30 +448,30 @@ array(4) { [0]=> array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(2) "-1" + string(2) "-1" } [1]=> array(2) { [0]=> - %unicode|string%(1) "2" + string(1) "2" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" } [2]=> array(2) { [0]=> - %unicode|string%(1) "3" + string(1) "3" [1]=> - %unicode|string%(2) "-3" + string(2) "-3" } [3]=> array(2) { [0]=> - %unicode|string%(1) "4" + string(1) "4" [1]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_NUM @@ -480,30 +480,30 @@ array(4) { [0]=> array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(2) "-1" + string(2) "-1" } [1]=> array(2) { [0]=> - %unicode|string%(1) "2" + string(1) "2" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" } [2]=> array(2) { [0]=> - %unicode|string%(1) "3" + string(1) "3" [1]=> - %unicode|string%(2) "-3" + string(2) "-3" } [3]=> array(2) { [0]=> - %unicode|string%(1) "4" + string(1) "4" [1]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_FETCHSTATEMENT_BY_ROW|OCI_NUM|OCI_ASSOC @@ -512,30 +512,30 @@ array(4) { [0]=> array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(2) "-1" + string(2) "-1" } [1]=> array(2) { [0]=> - %unicode|string%(1) "2" + string(1) "2" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" } [2]=> array(2) { [0]=> - %unicode|string%(1) "3" + string(1) "3" [1]=> - %unicode|string%(2) "-3" + string(2) "-3" } [3]=> array(2) { [0]=> - %unicode|string%(1) "4" + string(1) "4" [1]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_NUM @@ -544,24 +544,24 @@ array(2) { [0]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } [1]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } OCI_NUM|OCI_ASSOC @@ -570,24 +570,24 @@ array(2) { [0]=> array(4) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" [3]=> - %unicode|string%(1) "4" + string(1) "4" } [1]=> array(4) { [0]=> - %unicode|string%(2) "-1" + string(2) "-1" [1]=> - %unicode|string%(2) "-2" + string(2) "-2" [2]=> - %unicode|string%(2) "-3" + string(2) "-3" [3]=> - %unicode|string%(2) "-4" + string(2) "-4" } } Done diff --git a/ext/oci8/tests/fetch_all4.phpt b/ext/oci8/tests/fetch_all4.phpt index 1d3c9677ee9c6..1d4a8df7b7c11 100644 --- a/ext/oci8/tests/fetch_all4.phpt +++ b/ext/oci8/tests/fetch_all4.phpt @@ -51,10 +51,10 @@ oci8_test_sql_execute($c, $stmtarray); Test 1 int(0) array(2) { - [%u|b%"MYCOL1"]=> + ["MYCOL1"]=> array(0) { } - [%u|b%"MYCOL2"]=> + ["MYCOL2"]=> array(0) { } } diff --git a/ext/oci8/tests/fetch_all5.phpt b/ext/oci8/tests/fetch_all5.phpt index a6bb3c3f18a0d..d82fd30e41cdd 100644 --- a/ext/oci8/tests/fetch_all5.phpt +++ b/ext/oci8/tests/fetch_all5.phpt @@ -62,45 +62,45 @@ oci_close($c); Test 1 int(3) array(2) { - [%u|b%"MYCOL1"]=> + ["MYCOL1"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" } - [%u|b%"MYCOL2"]=> + ["MYCOL2"]=> array(3) { [0]=> - %unicode|string%(3) "abc" + string(3) "abc" [1]=> - %unicode|string%(3) "def" + string(3) "def" [2]=> - %unicode|string%(3) "ghi" + string(3) "ghi" } } Test 1 int(3) array(2) { - [%u|b%"MYCOL1"]=> + ["MYCOL1"]=> array(3) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "2" + string(1) "2" [2]=> - %unicode|string%(1) "3" + string(1) "3" } - [%u|b%"MYCOL2"]=> + ["MYCOL2"]=> array(3) { [0]=> - %unicode|string%(3) "abc" + string(3) "abc" [1]=> - %unicode|string%(3) "def" + string(3) "def" [2]=> - %unicode|string%(3) "ghi" + string(3) "ghi" } } Test 3 diff --git a/ext/oci8/tests/fetch_into.phpt b/ext/oci8/tests/fetch_into.phpt index 45a6a8132ed12..d90c4d95dcb26 100644 --- a/ext/oci8/tests/fetch_into.phpt +++ b/ext/oci8/tests/fetch_into.phpt @@ -53,19 +53,19 @@ echo "Done\n"; int(2) array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" } int(2) array(4) { [0]=> - %unicode|string%(1) "1" - [%u|b%"ID"]=> - %unicode|string%(1) "1" + string(1) "1" + ["ID"]=> + string(1) "1" [1]=> - %unicode|string%(1) "1" - [%u|b%"VALUE"]=> - %unicode|string%(1) "1" + string(1) "1" + ["VALUE"]=> + string(1) "1" } Done diff --git a/ext/oci8/tests/fetch_object.phpt b/ext/oci8/tests/fetch_object.phpt index 1c290d5e953dd..73711baa1884e 100644 --- a/ext/oci8/tests/fetch_object.phpt +++ b/ext/oci8/tests/fetch_object.phpt @@ -82,28 +82,28 @@ oci8_test_sql_execute($c, $stmtarray); --EXPECTF-- Test 1 object(stdClass)#1 (3) { - [%u|b%"caseSensitive"]=> - %unicode|string%(3) "123" - [%u|b%"SECONDCOL"]=> - %unicode|string%(19) "1st row col2 string" - [%u|b%"ANOTHERCOL"]=> - %unicode|string%(15) "1 more text " + ["caseSensitive"]=> + string(3) "123" + ["SECONDCOL"]=> + string(19) "1st row col2 string" + ["ANOTHERCOL"]=> + string(15) "1 more text " } object(stdClass)#2 (3) { - [%u|b%"caseSensitive"]=> - %unicode|string%(3) "456" - [%u|b%"SECONDCOL"]=> - %unicode|string%(19) "2nd row col2 string" - [%u|b%"ANOTHERCOL"]=> - %unicode|string%(15) "2 more text " + ["caseSensitive"]=> + string(3) "456" + ["SECONDCOL"]=> + string(19) "2nd row col2 string" + ["ANOTHERCOL"]=> + string(15) "2 more text " } object(stdClass)#1 (3) { - [%u|b%"caseSensitive"]=> - %unicode|string%(3) "789" - [%u|b%"SECONDCOL"]=> - %unicode|string%(19) "3rd row col2 string" - [%u|b%"ANOTHERCOL"]=> - %unicode|string%(15) "3 more text " + ["caseSensitive"]=> + string(3) "789" + ["SECONDCOL"]=> + string(19) "3rd row col2 string" + ["ANOTHERCOL"]=> + string(15) "3 more text " } Test 2 123 diff --git a/ext/oci8/tests/fetch_row.phpt b/ext/oci8/tests/fetch_row.phpt index 2b28634ab3f01..40bc4f893cad5 100644 --- a/ext/oci8/tests/fetch_row.phpt +++ b/ext/oci8/tests/fetch_row.phpt @@ -46,20 +46,20 @@ echo "Done\n"; --EXPECTF-- array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" } array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" } array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" } Done diff --git a/ext/oci8/tests/field_funcs1.phpt b/ext/oci8/tests/field_funcs1.phpt index c14ee8957e709..41d8627ce46cb 100644 --- a/ext/oci8/tests/field_funcs1.phpt +++ b/ext/oci8/tests/field_funcs1.phpt @@ -85,9 +85,9 @@ echo "Done\n"; --EXPECTF-- array(2) { [0]=> - %unicode|string%(1) "1" + string(1) "1" [1]=> - %unicode|string%(1) "1" + string(1) "1" } Test 1 diff --git a/ext/oci8/tests/function_aliases.phpt b/ext/oci8/tests/function_aliases.phpt index 4c6ce8375965c..2c890d6403ca2 100644 --- a/ext/oci8/tests/function_aliases.phpt +++ b/ext/oci8/tests/function_aliases.phpt @@ -104,8 +104,6 @@ NULL Warning: ocifreestatement() expects exactly 1 parameter, 0 given in %s on line %d NULL - -Warning: ociinternaldebug() expects exactly 1 parameter, 0 given in %s on line %d NULL Warning: ocinumcols() expects exactly 1 parameter, 0 given in %s on line %d diff --git a/ext/oci8/tests/imp_res_1.phpt b/ext/oci8/tests/imp_res_1.phpt new file mode 100644 index 0000000000000..a36f89f4da002 --- /dev/null +++ b/ext/oci8/tests/imp_res_1.phpt @@ -0,0 +1,630 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: basic test +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 - oci_fetch_assoc +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} +array(1) { + ["C3"]=> + string(1) "t" +} +array(1) { + ["C3"]=> + string(1) "u" +} +array(1) { + [99]=> + string(2) "99" +} +array(2) { + ["NULL"]=> + NULL + ["'Z'"]=> + string(1) "Z" +} +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} + +Test 2 - oci_fetch_object +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} +object(stdClass)#%d (1) { + ["C3"]=> + string(1) "t" +} +object(stdClass)#%d (1) { + ["C3"]=> + string(1) "u" +} +object(stdClass)#%d (1) { + [99]=> + string(2) "99" +} +object(stdClass)#%d (2) { + ["NULL"]=> + NULL + ["'Z'"]=> + string(1) "Z" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} + +Test 3 - oci_fetch_row +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} +array(1) { + [0]=> + string(1) "t" +} +array(1) { + [0]=> + string(1) "u" +} +array(1) { + [0]=> + string(2) "99" +} +array(2) { + [0]=> + NULL + [1]=> + string(1) "Z" +} +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} + +Test 4 - oci_fetch_array(OCI_ASSOC+OCI_RETURN_NULLS) +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} +array(1) { + ["C3"]=> + string(1) "t" +} +array(1) { + ["C3"]=> + string(1) "u" +} +array(1) { + [99]=> + string(2) "99" +} +array(2) { + ["NULL"]=> + NULL + ["'Z'"]=> + string(1) "Z" +} +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} + +Test 5 - oci_fetch_array(OCI_ASSOC) +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} +array(1) { + ["C3"]=> + string(1) "t" +} +array(1) { + ["C3"]=> + string(1) "u" +} +array(1) { + [99]=> + string(2) "99" +} +array(1) { + ["'Z'"]=> + string(1) "Z" +} +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(5) "abcde" +} +array(2) { + ["C1"]=> + string(1) "2" + ["C2"]=> + string(5) "fghij" +} +array(2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(5) "klmno" +} + +Test 6 - oci_fetch_array(OCI_NUM) +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} +array(1) { + [0]=> + string(1) "t" +} +array(1) { + [0]=> + string(1) "u" +} +array(1) { + [0]=> + string(2) "99" +} +array(1) { + [1]=> + string(1) "Z" +} +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} + +Test 7 - oci_fetch_array(OCI_BOTH) +array(4) { + [0]=> + string(1) "1" + ["C1"]=> + string(1) "1" + [1]=> + string(5) "abcde" + ["C2"]=> + string(5) "abcde" +} +array(4) { + [0]=> + string(1) "2" + ["C1"]=> + string(1) "2" + [1]=> + string(5) "fghij" + ["C2"]=> + string(5) "fghij" +} +array(4) { + [0]=> + string(1) "3" + ["C1"]=> + string(1) "3" + [1]=> + string(5) "klmno" + ["C2"]=> + string(5) "klmno" +} +array(2) { + [0]=> + string(1) "t" + ["C3"]=> + string(1) "t" +} +array(2) { + [0]=> + string(1) "u" + ["C3"]=> + string(1) "u" +} +array(2) { + [0]=> + string(2) "99" + [99]=> + string(2) "99" +} +array(2) { + [1]=> + string(1) "Z" + ["'Z'"]=> + string(1) "Z" +} +array(4) { + [0]=> + string(1) "1" + ["C1"]=> + string(1) "1" + [1]=> + string(5) "abcde" + ["C2"]=> + string(5) "abcde" +} +array(4) { + [0]=> + string(1) "2" + ["C1"]=> + string(1) "2" + [1]=> + string(5) "fghij" + ["C2"]=> + string(5) "fghij" +} +array(4) { + [0]=> + string(1) "3" + ["C1"]=> + string(1) "3" + [1]=> + string(5) "klmno" + ["C2"]=> + string(5) "klmno" +} + +Test 8 - oci_fetch_array(OCI_BOTH+OCI_RETURN_NULLS) +array(4) { + [0]=> + string(1) "1" + ["C1"]=> + string(1) "1" + [1]=> + string(5) "abcde" + ["C2"]=> + string(5) "abcde" +} +array(4) { + [0]=> + string(1) "2" + ["C1"]=> + string(1) "2" + [1]=> + string(5) "fghij" + ["C2"]=> + string(5) "fghij" +} +array(4) { + [0]=> + string(1) "3" + ["C1"]=> + string(1) "3" + [1]=> + string(5) "klmno" + ["C2"]=> + string(5) "klmno" +} +array(2) { + [0]=> + string(1) "t" + ["C3"]=> + string(1) "t" +} +array(2) { + [0]=> + string(1) "u" + ["C3"]=> + string(1) "u" +} +array(2) { + [0]=> + string(2) "99" + [99]=> + string(2) "99" +} +array(4) { + [0]=> + NULL + ["NULL"]=> + NULL + [1]=> + string(1) "Z" + ["'Z'"]=> + string(1) "Z" +} +array(4) { + [0]=> + string(1) "1" + ["C1"]=> + string(1) "1" + [1]=> + string(5) "abcde" + ["C2"]=> + string(5) "abcde" +} +array(4) { + [0]=> + string(1) "2" + ["C1"]=> + string(1) "2" + [1]=> + string(5) "fghij" + ["C2"]=> + string(5) "fghij" +} +array(4) { + [0]=> + string(1) "3" + ["C1"]=> + string(1) "3" + [1]=> + string(5) "klmno" + ["C2"]=> + string(5) "klmno" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_2.phpt b/ext/oci8/tests/imp_res_2.phpt new file mode 100644 index 0000000000000..860a5fbb34e07 --- /dev/null +++ b/ext/oci8/tests/imp_res_2.phpt @@ -0,0 +1,99 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: Zero Rows +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +Test 2 +array(1) { + [0]=> + string(1) "X" +} +Test 2 +array(1) { + [0]=> + string(1) "X" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_3.phpt b/ext/oci8/tests/imp_res_3.phpt new file mode 100644 index 0000000000000..0fc4815893d6d --- /dev/null +++ b/ext/oci8/tests/imp_res_3.phpt @@ -0,0 +1,1257 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: bigger data size +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X + 1 a 1 a 1 a 1 a 1 a + 1 a 1 a 1 a 1 a 2 f + 1 a 1 a 1 a 2 f 1 a + 1 a 1 a 1 a 2 f 2 f + 1 a 1 a 2 f 1 a 1 a + 1 a 1 a 2 f 1 a 2 f + 1 a 1 a 2 f 2 f 1 a + 1 a 1 a 2 f 2 f 2 f + 1 a 2 f 1 a 1 a 1 a + 1 a 2 f 1 a 1 a 2 f + 1 a 2 f 1 a 2 f 1 a + 1 a 2 f 1 a 2 f 2 f + 1 a 2 f 2 f 1 a 1 a + 1 a 2 f 2 f 1 a 2 f + 1 a 2 f 2 f 2 f 1 a + 1 a 2 f 2 f 2 f 2 f + 2 f 1 a 1 a 1 a 1 a + 2 f 1 a 1 a 1 a 2 f + 2 f 1 a 1 a 2 f 1 a + 2 f 1 a 1 a 2 f 2 f + 2 f 1 a 2 f 1 a 1 a + 2 f 1 a 2 f 1 a 2 f + 2 f 1 a 2 f 2 f 1 a + 2 f 1 a 2 f 2 f 2 f + 2 f 2 f 1 a 1 a 1 a + 2 f 2 f 1 a 1 a 2 f + 2 f 2 f 1 a 2 f 1 a + 2 f 2 f 1 a 2 f 2 f + 2 f 2 f 2 f 1 a 1 a + 2 f 2 f 2 f 1 a 2 f + 2 f 2 f 2 f 2 f 1 a + 2 f 2 f 2 f 2 f 2 f + a + f + t + u + v + w + X +===DONE=== diff --git a/ext/oci8/tests/imp_res_4.phpt b/ext/oci8/tests/imp_res_4.phpt new file mode 100644 index 0000000000000..762ae7722491d --- /dev/null +++ b/ext/oci8/tests/imp_res_4.phpt @@ -0,0 +1,82 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_fetch +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + +Warning: oci_fetch(): ORA-24374: %s in %simp_res_4.php on line %d +bool(false) + +Test 2 +array(1) { + [0]=> + string(1) "1" +} + +Warning: oci_fetch(): ORA-24374: %s in %simp_res_4.php on line %d +bool(false) +array(1) { + [0]=> + string(1) "2" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_5.phpt b/ext/oci8/tests/imp_res_5.phpt new file mode 100644 index 0000000000000..564a7a37404ef --- /dev/null +++ b/ext/oci8/tests/imp_res_5.phpt @@ -0,0 +1,84 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_fetch_all +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + +Warning: oci_fetch_all(): ORA-24374: %s in %simp_res_5.php on line %d +array(0) { +} + +Test 2 +array(1) { + [0]=> + string(1) "1" +} + +Warning: oci_fetch_all(): ORA-24374: %s in %simp_res_5.php on line %d +array(0) { +} +array(1) { + [0]=> + string(1) "2" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_6.phpt b/ext/oci8/tests/imp_res_6.phpt new file mode 100644 index 0000000000000..f94efe70db921 --- /dev/null +++ b/ext/oci8/tests/imp_res_6.phpt @@ -0,0 +1,118 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: alternating oci_fetch_* calls +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(2) { + ["C1"]=> + string(1) "1" + ["C2"]=> + string(1) "a" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(1) "b" +} +object(stdClass)#%d (2) { + ["C1"]=> + string(1) "3" + ["C2"]=> + string(1) "c" +} +array(4) { + [0]=> + string(1) "4" + ["C1"]=> + string(1) "4" + [1]=> + string(1) "d" + ["C2"]=> + string(1) "d" +} +array(2) { + [0]=> + string(1) "5" + [1]=> + string(1) "e" +} +array(2) { + ["C1"]=> + string(1) "6" + ["C2"]=> + string(1) "f" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_7.phpt b/ext/oci8/tests/imp_res_7.phpt new file mode 100644 index 0000000000000..05ae5e6857940 --- /dev/null +++ b/ext/oci8/tests/imp_res_7.phpt @@ -0,0 +1,873 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: bigger data size +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + 130 + 131 + 132 + 133 + 134 + 135 + 136 + 137 + 138 + 139 + 140 + 141 + 142 + 143 + 144 + 145 + 146 + 147 + 148 + 149 + 150 + 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + 184 + 185 + 186 + 187 + 188 + 189 + 190 + 191 + 192 + 193 + 194 + 195 + 196 + 197 + 198 + 199 + 200 + 201 + 202 + 203 + 204 + 205 + 206 + 207 + 208 + 209 + 210 + 211 + 212 + 213 + 214 + 215 + 216 + 217 + 218 + 219 + 220 + 221 + 222 + 223 + 224 + 225 + 226 + 227 + 228 + 229 + 230 + 231 + 232 + 233 + 234 + 235 + 236 + 237 + 238 + 239 + 240 + 241 + 242 + 243 + 244 + 245 + 246 + 247 + 248 + 249 + 250 + 251 + 252 + 253 + 254 + 255 + 256 + 257 + 258 + 259 + 260 + 261 + 262 + 263 + 264 + 265 + 266 + 267 + 268 + 269 + 270 + 271 + 272 + 273 + 274 + 275 +===DONE=== diff --git a/ext/oci8/tests/imp_res_call_error.phpt b/ext/oci8/tests/imp_res_call_error.phpt new file mode 100644 index 0000000000000..8b0fa78db91a9 --- /dev/null +++ b/ext/oci8/tests/imp_res_call_error.phpt @@ -0,0 +1,61 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: using SQL 'CALL' +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + +Warning: oci_execute(): ORA-29478: %s +ORA-06512: at "SYS.DBMS_SQL", line %d +ORA-06512: at "SYS.DBMS_SQL", line %d +ORA-06512: at "SYSTEM.IMP_RES_CALL_ERR_PROC", line %d in %simp_res_call_error.php on line %d +===DONE=== diff --git a/ext/oci8/tests/imp_res_cancel.phpt b/ext/oci8/tests/imp_res_cancel.phpt new file mode 100644 index 0000000000000..663d630dfbeb0 --- /dev/null +++ b/ext/oci8/tests/imp_res_cancel.phpt @@ -0,0 +1,68 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_cancel +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 +bool(true) + 2 +bool(true) + 3 +bool(true) +===DONE=== diff --git a/ext/oci8/tests/imp_res_close.phpt b/ext/oci8/tests/imp_res_close.phpt new file mode 100644 index 0000000000000..01ac2c75e0018 --- /dev/null +++ b/ext/oci8/tests/imp_res_close.phpt @@ -0,0 +1,69 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_free_statement #1 +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 2 + +Warning: oci_fetch_array(): %d is not a valid oci8 statement resource in %simp_res_close.php on line %d +===DONE=== diff --git a/ext/oci8/tests/imp_res_cursor.phpt b/ext/oci8/tests/imp_res_cursor.phpt new file mode 100644 index 0000000000000..cac0a5d1c0b7d --- /dev/null +++ b/ext/oci8/tests/imp_res_cursor.phpt @@ -0,0 +1,99 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: nested cursor +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + X + 1 abcde + 2 fghij + 3 klmno + + t + u +===DONE=== diff --git a/ext/oci8/tests/imp_res_dbmsoutput.phpt b/ext/oci8/tests/imp_res_dbmsoutput.phpt new file mode 100644 index 0000000000000..8c9808d96c332 --- /dev/null +++ b/ext/oci8/tests/imp_res_dbmsoutput.phpt @@ -0,0 +1,136 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: interleaved with DBMS_OUTPUT +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(2) { + [0]=> + string(18) "dbms_output Line 1" + [1]=> + string(18) "dbms_output Line 2" +} + 1 abcde + 2 fghij + 3 klmno + t + u + v + +Test 2 + 1 abcde + 2 fghij + 3 klmno + t + u + v +array(2) { + [0]=> + string(18) "dbms_output Line 1" + [1]=> + string(18) "dbms_output Line 2" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_field.phpt b/ext/oci8/tests/imp_res_field.phpt new file mode 100644 index 0000000000000..54b8295cf9284 --- /dev/null +++ b/ext/oci8/tests/imp_res_field.phpt @@ -0,0 +1,227 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: field tests +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + Result set ".++$i."\n"; + print_fields($s1); + while (($r = oci_fetch_row($s1)) !== false) { + var_dump($r); + } +} + +echo "\nTest 5 - get IRS fields when fetching rows\n"; +$s = oci_parse($c, "begin imp_res_field_proc(); end;"); +oci_execute($s); +$i = 0; +while (($s1 = oci_get_implicit_resultset($s))) { + echo "===> Result set ".++$i."\n"; + while (($r = oci_fetch_row($s1)) !== false) { + var_dump($r); + print_fields($s1); + } +} + +// Clean up + +$stmtarray = array( + "drop procedure imp_res_field_proc", + "drop table imp_res_field_tab_1", + "drop table imp_res_field_tab_2", + "drop table imp_res_field_tab_3" +); + +oci8_test_sql_execute($c, $stmtarray); + +?> +===DONE=== + +--EXPECTF-- +Test 1 - can't get IRS fields from parent +num fields : 0 + +Test 2 - can't get IRS fields from parent when fetching +array(2) { + [0]=> + string(4) "1111" + [1]=> + string(5) "abcde" +} +num fields : 0 +array(1) { + [0]=> + string(4) "tttt" +} +num fields : 0 +array(1) { + [0]=> + string(2) "33" +} +num fields : 0 +array(1) { + [0]=> + NULL +} +num fields : 0 + +Test 3 - get IRS fields +num fields : 2 +C1_NUMBER : is_null F, precision 0, scale -127, size 22, typeraw 2, type NUMBER +C2_VARCHAR210 : is_null F, precision 0, scale 0, size 10, typeraw 1, type VARCHAR2 +num fields : 1 +C3_VARCHAR21 : is_null F, precision 0, scale 0, size 4, typeraw 1, type VARCHAR2 +num fields : 1 +C4_NUMBER52 : is_null F, precision 5, scale 2, size 22, typeraw 2, type NUMBER + +Test 4 - get IRS fields before fetching rows +===> Result set 1 +num fields : 2 +C1_NUMBER : is_null F, precision 0, scale -127, size 22, typeraw 2, type NUMBER +C2_VARCHAR210 : is_null F, precision 0, scale 0, size 10, typeraw 1, type VARCHAR2 +array(2) { + [0]=> + string(4) "1111" + [1]=> + string(5) "abcde" +} +===> Result set 2 +num fields : 1 +C3_VARCHAR21 : is_null F, precision 0, scale 0, size 4, typeraw 1, type VARCHAR2 +array(1) { + [0]=> + string(4) "tttt" +} +===> Result set 3 +num fields : 1 +C4_NUMBER52 : is_null F, precision 5, scale 2, size 22, typeraw 2, type NUMBER +array(1) { + [0]=> + string(2) "33" +} +array(1) { + [0]=> + NULL +} + +Test 5 - get IRS fields when fetching rows +===> Result set 1 +array(2) { + [0]=> + string(4) "1111" + [1]=> + string(5) "abcde" +} +num fields : 2 +C1_NUMBER : is_null F, precision 0, scale -127, size 22, typeraw 2, type NUMBER +C2_VARCHAR210 : is_null F, precision 0, scale 0, size 10, typeraw 1, type VARCHAR2 +===> Result set 2 +array(1) { + [0]=> + string(4) "tttt" +} +num fields : 1 +C3_VARCHAR21 : is_null F, precision 0, scale 0, size 4, typeraw 1, type VARCHAR2 +===> Result set 3 +array(1) { + [0]=> + string(2) "33" +} +num fields : 1 +C4_NUMBER52 : is_null F, precision 5, scale 2, size 22, typeraw 2, type NUMBER +array(1) { + [0]=> + NULL +} +num fields : 1 +C4_NUMBER52 : is_null T, precision 5, scale 2, size 22, typeraw 2, type NUMBER +===DONE=== diff --git a/ext/oci8/tests/imp_res_func_error.phpt b/ext/oci8/tests/imp_res_func_error.phpt new file mode 100644 index 0000000000000..73c0557930cd8 --- /dev/null +++ b/ext/oci8/tests/imp_res_func_error.phpt @@ -0,0 +1,67 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: test with a PL/SQL function +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + +Warning: oci_execute(): ORA-29478: %s +ORA-06512: %s +ORA-06512: %s +ORA-06512: %s +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_1.phpt b/ext/oci8/tests/imp_res_get_1.phpt new file mode 100644 index 0000000000000..665f773b57341 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_1.phpt @@ -0,0 +1,109 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: basic test +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 abcde + 2 fghij + 3 klmno + t + u + X + +Test 2 - with execute + 1 abcde + 2 fghij + 3 klmno + t + u + X +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_2.phpt b/ext/oci8/tests/imp_res_get_2.phpt new file mode 100644 index 0000000000000..b20b8dd3970e8 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_2.phpt @@ -0,0 +1,107 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: similar to imp_res_get_1 but with unrolled loop +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 abcde + 2 fghij + 3 klmno + t + u + X +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_3.phpt b/ext/oci8/tests/imp_res_get_3.phpt new file mode 100644 index 0000000000000..15b2efaef0d91 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_3.phpt @@ -0,0 +1,267 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: basic test 3 +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--INI-- +oci8.statement_cache_size = 0 +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X + 1 abcde + 2 fghij + 3 klmno + t + u + X +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_4.phpt b/ext/oci8/tests/imp_res_get_4.phpt new file mode 100644 index 0000000000000..ea7fb8775a725 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_4.phpt @@ -0,0 +1,146 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: interleaved fetches +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 abcde + t + 2 fghij + u + 3 klmno + v +Test 2 - too many fetches + 1 abcde + t + 2 fghij + u + 3 klmno + v +Return is false +Return is false + +Warning: oci_fetch_array(): ORA-01002: %s in %simp_res_get_4.php on line %d +Return is false + +Warning: oci_fetch_array(): ORA-01002: %s in %simp_res_get_4.php on line %d +Return is false +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_5.phpt b/ext/oci8/tests/imp_res_get_5.phpt new file mode 100644 index 0000000000000..3cfa0967a211a --- /dev/null +++ b/ext/oci8/tests/imp_res_get_5.phpt @@ -0,0 +1,124 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: get from wrong statement +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 3 + 4 + 5 + 6 + +Test 2 - fetch first IRS explicitly + 1 + 2 + 3 + 4 + 5 + 6 + +Test 3 - fetch part of IRS explicitly + 1 + 2 + 3 + 5 + 6 + 4 + +Test 4 - skip IRSs + 5 + 6 +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_all.phpt b/ext/oci8/tests/imp_res_get_all.phpt new file mode 100644 index 0000000000000..d2dcbea6c782f --- /dev/null +++ b/ext/oci8/tests/imp_res_get_all.phpt @@ -0,0 +1,120 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: oci_fetch_all +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(1) { + [1]=> + array(2) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + } +} +array(1) { + [3]=> + array(2) { + [0]=> + string(1) "3" + [1]=> + string(1) "4" + } +} +array(1) { + [5]=> + array(2) { + [0]=> + string(1) "5" + [1]=> + string(1) "6" + } +} + +Test 2 +array(1) { + [1]=> + array(2) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + } +} +array(1) { + [3]=> + array(2) { + [0]=> + string(1) "3" + [1]=> + string(1) "4" + } +} +array(1) { + [5]=> + array(2) { + [0]=> + string(1) "5" + [1]=> + string(1) "6" + } +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_cancel.phpt b/ext/oci8/tests/imp_res_get_cancel.phpt new file mode 100644 index 0000000000000..7dbcecbfe9db7 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_cancel.phpt @@ -0,0 +1,56 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: oci_cancel +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 3 +===DONE=== + diff --git a/ext/oci8/tests/imp_res_get_close_1.phpt b/ext/oci8/tests/imp_res_get_close_1.phpt new file mode 100644 index 0000000000000..2edc8bf604b8f --- /dev/null +++ b/ext/oci8/tests/imp_res_get_close_1.phpt @@ -0,0 +1,68 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: oci_free_statement #1 +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + +Warning: oci_fetch_array(): %d is not a valid oci8 statement resource in %s on line %d + 3 + +Warning: oci_fetch_array(): %d is not a valid oci8 statement resource in %s on line %d + 5 + +Warning: oci_fetch_array(): %d is not a valid oci8 statement resource in %s on line %d +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_close_2.phpt b/ext/oci8/tests/imp_res_get_close_2.phpt new file mode 100644 index 0000000000000..b3153834babf3 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_close_2.phpt @@ -0,0 +1,64 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: oci_free_statement #2 +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 2 + +Warning: oci_fetch_array(): OCI_INVALID_HANDLE in %s on line %d + +Warning: oci_get_implicit_resultset(): %d is not a valid oci8 statement resource in %s on line %d +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_close_3.phpt b/ext/oci8/tests/imp_res_get_close_3.phpt new file mode 100644 index 0000000000000..4793a6c88207c --- /dev/null +++ b/ext/oci8/tests/imp_res_get_close_3.phpt @@ -0,0 +1,65 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: oci_free_statement #3 +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 2 + 3 + 4 + 5 + 6 +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_cursor.phpt b/ext/oci8/tests/imp_res_get_cursor.phpt new file mode 100644 index 0000000000000..ccdb6f549030d --- /dev/null +++ b/ext/oci8/tests/imp_res_get_cursor.phpt @@ -0,0 +1,101 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: nested cursor +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 abcde + 2 fghij + 3 klmno + + t + u + X +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_dbmsoutput.phpt b/ext/oci8/tests/imp_res_get_dbmsoutput.phpt new file mode 100644 index 0000000000000..cbc2389e46885 --- /dev/null +++ b/ext/oci8/tests/imp_res_get_dbmsoutput.phpt @@ -0,0 +1,156 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: interleaved with DBMS_OUTPUT +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(3) { + [0]=> + string(6) "Line 1" + [1]=> + string(6) "Line 2" + [2]=> + string(6) "Line 3" +} + 1 abcde + 2 fghij + 3 klmno + t + u + v + X +Test 2 + 1 abcde + 2 fghij + 3 klmno + t + u + v + X +array(3) { + [0]=> + string(6) "Line 1" + [1]=> + string(6) "Line 2" + [2]=> + string(6) "Line 3" +} +===DONE=== + diff --git a/ext/oci8/tests/imp_res_get_exec.phpt b/ext/oci8/tests/imp_res_get_exec.phpt new file mode 100644 index 0000000000000..dbd8f3ef3a20a --- /dev/null +++ b/ext/oci8/tests/imp_res_get_exec.phpt @@ -0,0 +1,55 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: Execute twice +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 + 1 + 2 +===DONE=== diff --git a/ext/oci8/tests/imp_res_get_none.phpt b/ext/oci8/tests/imp_res_get_none.phpt new file mode 100644 index 0000000000000..981f4945e245a --- /dev/null +++ b/ext/oci8/tests/imp_res_get_none.phpt @@ -0,0 +1,46 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: oci_get_implicit_resultset: no implicit results +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +bool(false) +===DONE=== diff --git a/ext/oci8/tests/imp_res_insert.phpt b/ext/oci8/tests/imp_res_insert.phpt new file mode 100644 index 0000000000000..d9c0705b55419 --- /dev/null +++ b/ext/oci8/tests/imp_res_insert.phpt @@ -0,0 +1,152 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: Commit modes +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 - No commit in procedure, OCI_COMMIT_ON_SUCCESS mode +111 +array(1) { + [0]=> + string(3) "111" +} + +Test 2 - No commit in procedure, OCI_NO_AUTO_COMMIT mode +111 +222 +array(1) { + [0]=> + string(3) "111" +} + +Test 3 - Commit in procedure, OCI_COMMIT_ON_SUCCESS mode +111 +222 +333 +array(3) { + [0]=> + string(3) "111" + [1]=> + string(3) "222" + [2]=> + string(3) "333" +} + +Test 4 - Commit in procedure, OCI_NO_AUTO_COMMIT mode +111 +222 +333 +444 +array(4) { + [0]=> + string(3) "111" + [1]=> + string(3) "222" + [2]=> + string(3) "333" + [3]=> + string(3) "444" +} +===DONE=== diff --git a/ext/oci8/tests/imp_res_lob.phpt b/ext/oci8/tests/imp_res_lob.phpt new file mode 100644 index 0000000000000..247803581d215 --- /dev/null +++ b/ext/oci8/tests/imp_res_lob.phpt @@ -0,0 +1,101 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: LOBs +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- +load(); + } else { + echo " " . $item; + } + } + echo "\n"; +} + +echo "\nTest 2 - don't fetch all rows\n"; +$s = oci_parse($c, "begin imp_res_lob_proc(); end;"); +oci_execute($s); +$row = oci_fetch_row($s); +foreach ($row as $item) { + if (is_object($item)) { + echo " " . $item->load(); + } else { + echo " " . $item; + } +} +echo "\n"; + +// Clean up + +$stmtarray = array( + "drop procedure imp_res_lob_proc", + "drop table imp_res_lob_tab", +); + +oci8_test_sql_execute($c, $stmtarray); + +?> +===DONE=== + +--EXPECTF-- +Test 1 + 1 aaaaa a + 2 bbbbb b + 3 ccccc c + 4 ddddd d + X + aaaaa + bbbbb + ccccc + ddddd + +Test 2 - don't fetch all rows + 1 aaaaa a +===DONE=== diff --git a/ext/oci8/tests/imp_res_prefetch.phpt b/ext/oci8/tests/imp_res_prefetch.phpt new file mode 100644 index 0000000000000..5acdd518e5843 --- /dev/null +++ b/ext/oci8/tests/imp_res_prefetch.phpt @@ -0,0 +1,185 @@ +--TEST-- +Oracle Database 12c Implicit Result Sets: basic test +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 - prefetch 0 +bool(true) +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} +array(1) { + [0]=> + string(1) "t" +} +array(1) { + [0]=> + string(1) "u" +} +array(1) { + [0]=> + string(1) "v" +} + +Test 1 - prefetch 1 +bool(true) +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} +array(1) { + [0]=> + string(1) "t" +} +array(1) { + [0]=> + string(1) "u" +} +array(1) { + [0]=> + string(1) "v" +} + +Test 1 - prefetch 2 +bool(true) +array(2) { + [0]=> + string(1) "1" + [1]=> + string(5) "abcde" +} +array(2) { + [0]=> + string(1) "2" + [1]=> + string(5) "fghij" +} +array(2) { + [0]=> + string(1) "3" + [1]=> + string(5) "klmno" +} +array(1) { + [0]=> + string(1) "t" +} +array(1) { + [0]=> + string(1) "u" +} +array(1) { + [0]=> + string(1) "v" +} +===DONE=== diff --git a/ext/oci8/tests/ini_1.phpt b/ext/oci8/tests/ini_1.phpt index 4c23b72b41fdb..2fba79813e845 100644 --- a/ext/oci8/tests/ini_1.phpt +++ b/ext/oci8/tests/ini_1.phpt @@ -1,7 +1,13 @@ --TEST-- Test OCI8 php.ini settings --SKIPIF-- - += 11)) { + die("skip works only with Oracle 11g or greater version of Oracle client libraries"); +} +?> --INI-- oci8.privileged_connect = On oci8.max_persistent = 111 diff --git a/ext/oci8/tests/lob_015.phpt b/ext/oci8/tests/lob_015.phpt index b4a19684a3950..59e8fec42ae38 100644 --- a/ext/oci8/tests/lob_015.phpt +++ b/ext/oci8/tests/lob_015.phpt @@ -48,7 +48,7 @@ Warning: oci_bind_by_name() expects at least 3 parameters, 2 given in %s on line Warning: oci_bind_by_name() expects at least 3 parameters, 1 given in %s on line %d -Warning: oci_execute(): ORA-00932: %s NUMBER %s BLOB in %s on line %d +Warning: oci_execute(): ORA-00932: %s on line %d object(OCI-Lob)#%d (1) { ["descriptor"]=> resource(%d) of type (oci8 descriptor) diff --git a/ext/oci8/tests/lob_temp2.phpt b/ext/oci8/tests/lob_temp2.phpt new file mode 100644 index 0000000000000..d774b4d7249e3 --- /dev/null +++ b/ext/oci8/tests/lob_temp2.phpt @@ -0,0 +1,40 @@ +--TEST-- +Writing temporary lob before binding +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +?> +--FILE-- +writeTemporary("test")); + +$statement = oci_parse($c, $ora_sql); +oci_bind_by_name($statement, ":v_clob", $clob, -1, OCI_B_CLOB); +oci_execute($statement, OCI_DEFAULT); + +$s = oci_parse($c, "select clob from ". $schema.$table_name); +oci_execute($s); +oci_fetch_all($s, $res); +var_dump($res); + +?> +===DONE=== +--EXPECTF-- +bool(true) +array(1) { + ["CLOB"]=> + array(1) { + [0]=> + string(4) "test" + } +} +===DONE=== diff --git a/ext/oci8/tests/minfo.phpt b/ext/oci8/tests/minfo.phpt index f6b95ff296168..34a19ca693ea5 100644 --- a/ext/oci8/tests/minfo.phpt +++ b/ext/oci8/tests/minfo.phpt @@ -8,12 +8,12 @@ Code coverage for PHP_MINFO_FUNCTION(oci) ob_start(); phpinfo(INFO_MODULES); $v = ob_get_clean(); -$r = strpos($v, 'OCI8 Support => enabled'); -var_dump($r); +$r = preg_match('/OCI8 Support .* enabled/', $v); +if ($r !== 1) + var_dump($r); echo "Done\n"; ?> --EXPECTF-- -int(%d) Done diff --git a/ext/oci8/tests/password.phpt b/ext/oci8/tests/password.phpt index 1738702cb6624..8ea81d3fc0e0f 100644 --- a/ext/oci8/tests/password.phpt +++ b/ext/oci8/tests/password.phpt @@ -14,28 +14,28 @@ if ($test_drcp) die("skip password change not supported in DRCP Mode"); require(dirname(__FILE__)."/connect.inc"); $stmtarray = array( - "drop user testuser cascade", - "create user testuser identified by testuserpwd", - "grant connect, create session to testuser" + "drop user testuser_pw cascade", + "create user testuser_pw identified by testuserpwd", + "grant connect, create session to testuser_pw" ); oci8_test_sql_execute($c, $stmtarray); // Connect and change the password -$c1 = oci_connect("testuser", "testuserpwd", $dbase); +$c1 = oci_connect("testuser_pw", "testuserpwd", $dbase); var_dump($c1); $rn1 = (int)$c1; -oci_password_change($c1, "testuser", "testuserpwd", "testuserpwd2"); +oci_password_change($c1, "testuser_pw", "testuserpwd", "testuserpwd2"); // Second connect should return a new resource because the hash string will be different from $c1 -$c2 = oci_connect("testuser", "testuserpwd2", $dbase); +$c2 = oci_connect("testuser_pw", "testuserpwd2", $dbase); var_dump($c2); $rn2 = (int)$c2; // Despite using the old password this connect should succeed and return the original resource -$c3 = oci_connect("testuser", "testuserpwd", $dbase); +$c3 = oci_connect("testuser_pw", "testuserpwd", $dbase); var_dump($c3); $rn3 = (int)$c3; @@ -67,7 +67,7 @@ echo "Done\n"; require(dirname(__FILE__)."/connect.inc"); $stmtarray = array( - "drop user testuser cascade" + "drop user testuser_pw cascade" ); oci8_test_sql_execute($c, $stmtarray); diff --git a/ext/oci8/tests/password_2.phpt b/ext/oci8/tests/password_2.phpt index ceba0bba80d9c..13da9ff7b269f 100644 --- a/ext/oci8/tests/password_2.phpt +++ b/ext/oci8/tests/password_2.phpt @@ -14,27 +14,27 @@ if ($test_drcp) die("skip password change not supported in DRCP Mode"); require(dirname(__FILE__)."/connect.inc"); $stmtarray = array( - "drop user testuser cascade", - "create user testuser identified by testuserpwd", - "grant connect, create session to testuser" + "drop user testuser_pw2 cascade", + "create user testuser_pw2 identified by testuserpwd", + "grant connect, create session to testuser_pw2" ); oci8_test_sql_execute($c, $stmtarray); // Connect (persistent) and change the password -$c1 = oci_pconnect("testuser", "testuserpwd", $dbase); +$c1 = oci_pconnect("testuser_pw2", "testuserpwd", $dbase); var_dump($c1); $rn1 = (int)$c1; -oci_password_change($c1, "testuser", "testuserpwd", "testuserpwd2"); +oci_password_change($c1, "testuser_pw2", "testuserpwd", "testuserpwd2"); // Second connect should return a new resource because the hash string will be different from $c1 -$c2 = oci_pconnect("testuser", "testuserpwd2", $dbase); +$c2 = oci_pconnect("testuser_pw2", "testuserpwd2", $dbase); var_dump($c2); $rn2 = (int)$c2; // Despite using the old password this connect should succeed and return the original resource -$c3 = oci_pconnect("testuser", "testuserpwd", $dbase); +$c3 = oci_pconnect("testuser_pw2", "testuserpwd", $dbase); var_dump($c3); $rn3 = (int)$c3; @@ -66,7 +66,7 @@ echo "Done\n"; require(dirname(__FILE__)."/connect.inc"); $stmtarray = array( - "drop user testuser cascade" + "drop user testuser_pw2 cascade" ); oci8_test_sql_execute($c, $stmtarray); diff --git a/ext/oci8/tests/password_new.phpt b/ext/oci8/tests/password_new.phpt index c218d904fa2da..a29fb8f52ff2b 100644 --- a/ext/oci8/tests/password_new.phpt +++ b/ext/oci8/tests/password_new.phpt @@ -3,36 +3,40 @@ oci_password_change() --SKIPIF-- true, 'timesten' => false); // test runs on thes -require(dirname(__FILE__).'/skipif.inc'); +require(dirname(__FILE__).'/connect.inc'); if (empty($dbase)) die ("skip requires database connection string be set"); if ($test_drcp) die("skip password change not supported in DRCP Mode"); -// This test is known to fail with Oracle 10.2.0.4 client libraries -// connecting to Oracle Database 11 (Oracle bug 6277160, fixed 10.2.0.5) -if (preg_match('/Release (11|12)\./', oci_server_version($c), $matches) === 1 && - preg_match('/^10\.2\.0\.[1234]/', oci_client_version()) === 1) { - die ("skip test known to fail using Oracle 10.2.0.4 client libs connecting to Oracle 11 (6277160)"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches_sv); +preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches_sv[0]) && isset($matches[0]) + && $matches_sv[1] == $matches[1] + && $matches_sv[2] == $matches[2] + && $matches_sv[3] == $matches[3] + && $matches_sv[4] == $matches[4])) { + // Avoid diffs due to cross version protocol changes (e.g. like 11.2.0.2-11.2.0.3) and bugs like Oracle bug: 6277160 + die ("skip test only runs when database client libraries and database server are the same version"); +} + +// This test in Oracle 12c needs a non-CDB or the root container +if (isset($matches_sv[0]) && $matches_sv[1] >= 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); } ?> --FILE-- true, 'timesten' => false); // test runs on thes -require(dirname(__FILE__).'/skipif.inc'); +require(dirname(__FILE__).'/connect.inc'); if (empty($dbase)) die ("skip requires database connection string be set"); if ($test_drcp) die("skip password change not supported in DRCP Mode"); -// This test is known to fail with Oracle 10.2.0.4 client libraries -// connecting to Oracle Database 11 (Oracle bug 6277160, fixed 10.2.0.5) -if (preg_match('/Release (11|12)\./', oci_server_version($c), $matches) === 1 && - preg_match('/^10\.2\.0\.[1234]/', oci_client_version()) === 1) { - die ("skip test known to fail using Oracle 10.2.0.4 client libs connecting to Oracle 11 (6277160)"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches_sv); +preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches_sv[0]) && isset($matches[0]) + && $matches_sv[1] == $matches[1] + && $matches_sv[2] == $matches[2] + && $matches_sv[3] == $matches[3] + && $matches_sv[4] == $matches[4])) { + // Avoid diffs due to cross version protocol changes (e.g. like 11.2.0.2-11.2.0.3) and bugs like Oracle bug: 6277160 + die ("skip test only runs when database client libraries and database server are the same version"); } - +// This test in Oracle 12c needs a non-CDB or the root container +if (isset($matches_sv[0]) && $matches_sv[1] >= 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); +} ?> --FILE-- diff --git a/ext/oci8/tests/pecl_bug16035.phpt b/ext/oci8/tests/pecl_bug16035.phpt index ddd0038de1524..29ff6439d1c8a 100644 --- a/ext/oci8/tests/pecl_bug16035.phpt +++ b/ext/oci8/tests/pecl_bug16035.phpt @@ -10,9 +10,6 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/Unknown/', oci_client_version()) == 1) { - die("skip expected output only valid with Oracle clients > 9gR2"); -} ?> --ENV-- ORACLE_HOME="" diff --git a/ext/oci8/tests/refcur_prefetch_1.phpt b/ext/oci8/tests/refcur_prefetch_1.phpt index ea09fbcd979cf..c7e200932aece 100644 --- a/ext/oci8/tests/refcur_prefetch_1.phpt +++ b/ext/oci8/tests/refcur_prefetch_1.phpt @@ -4,9 +4,16 @@ Prefetch with REF cursor. Test different values for prefetch with oci_set_prefet = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/refcur_prefetch_2.phpt b/ext/oci8/tests/refcur_prefetch_2.phpt index 8d65251077ea3..9b2472db5df44 100644 --- a/ext/oci8/tests/refcur_prefetch_2.phpt +++ b/ext/oci8/tests/refcur_prefetch_2.phpt @@ -4,9 +4,16 @@ Prefetch with REF cursor. Test No 2 = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/refcur_prefetch_3.phpt b/ext/oci8/tests/refcur_prefetch_3.phpt index 8c0414042b0fc..f29345e515d47 100644 --- a/ext/oci8/tests/refcur_prefetch_3.phpt +++ b/ext/oci8/tests/refcur_prefetch_3.phpt @@ -6,12 +6,20 @@ oci8.default_prefetch=5 = 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } - ?> --FILE-- - %unicode|string%(%d) "test0" + string(%d) "test0" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test1" + string(%d) "test1" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test2" + string(%d) "test2" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test3" + string(%d) "test3" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test4" + string(%d) "test4" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test5" + string(%d) "test5" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test6" + string(%d) "test6" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test7" + string(%d) "test7" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test8" + string(%d) "test8" } Fetch Row using Nested cursor Query array(1) { [0]=> - %unicode|string%(%d) "test9" + string(%d) "test9" } Number of roundtrips made with prefetch count 5 for 10 rows is 3 Done diff --git a/ext/oci8/tests/refcur_prefetch_4.phpt b/ext/oci8/tests/refcur_prefetch_4.phpt index d24398c00e6bf..f0c7183d0e9da 100644 --- a/ext/oci8/tests/refcur_prefetch_4.phpt +++ b/ext/oci8/tests/refcur_prefetch_4.phpt @@ -4,9 +4,16 @@ Prefetch with REF cursor. Test No 4 = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/reflection1.phpt b/ext/oci8/tests/reflection1.phpt index 5f2e73d80bde4..f76d7261aa78e 100644 --- a/ext/oci8/tests/reflection1.phpt +++ b/ext/oci8/tests/reflection1.phpt @@ -126,6 +126,7 @@ reflection::export(new reflectionfunction('oci_set_module_name')); reflection::export(new reflectionfunction('oci_set_action')); reflection::export(new reflectionfunction('oci_set_client_info')); reflection::export(new reflectionfunction('oci_set_client_identifier')); +reflection::export(new reflectionfunction('oci_get_implicit_resultset')); ?> ===DONE=== @@ -1093,4 +1094,11 @@ Function [ function oci_set_client_identifier ] { } } +Function [ function oci_get_implicit_resultset ] { + + - Parameters [1] { + Parameter #0 [ $statement_resource ] + } +} + ===DONE=== diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4 index eaed212cd7076..7bc06715dd7b5 100644 --- a/ext/odbc/config.m4 +++ b/ext/odbc/config.m4 @@ -365,7 +365,7 @@ fi if test -z "$ODBC_TYPE"; then PHP_ARG_WITH(iodbc,, -[ --with-iodbc[=DIR] Include iODBC support [/usr/local]]) +[ --with-iodbc[=DIR] Include iODBC support]) if test "$PHP_IODBC" != "no"; then AC_MSG_CHECKING(for iODBC support) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 1c34cffbf76e7..a4e661e3f897a 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1899,7 +1899,7 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra #endif /* Find a set of variables which are used outside of the block where they are - * defined. We won't apply some optimization patterns for sush variables. */ + * defined. We won't apply some optimization patterns for such variables. */ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char *used_ext) { zend_code_block *next_block = block->next; @@ -1931,6 +1931,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * if (RESULT_USED(opline)) { if (!defined_here[VAR_NUM(ZEND_RESULT(opline).var)] && !used_ext[VAR_NUM(ZEND_RESULT(opline).var)] && (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT || + opline->opcode == ZEND_RECV_VARIADIC || (opline->opcode == ZEND_OP_DATA && ZEND_RESULT_TYPE(opline) == IS_TMP_VAR) || opline->opcode == ZEND_ADD_ARRAY_ELEMENT)) { /* these opcodes use the result as argument */ @@ -2015,6 +2016,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * if (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT || + opline->opcode == ZEND_RECV_VARIADIC || opline->opcode == ZEND_ADD_ARRAY_ELEMENT) { if (ZEND_OP1_TYPE(opline) == IS_VAR || ZEND_OP1_TYPE(opline) == IS_TMP_VAR) { usage[VAR_NUM(ZEND_RESULT(opline).var)] = 1; diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c new file mode 100644 index 0000000000000..b29241344c45e --- /dev/null +++ b/ext/opcache/Optimizer/compact_literals.c @@ -0,0 +1,481 @@ +/* pass 11 + * - compact literals table + */ +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + +#define DEBUG_COMPACT_LITERALS 0 + +#define LITERAL_VALUE 0x0100 +#define LITERAL_FUNC 0x0200 +#define LITERAL_CLASS 0x0300 +#define LITERAL_CONST 0x0400 +#define LITERAL_CLASS_CONST 0x0500 +#define LITERAL_STATIC_METHOD 0x0600 +#define LITERAL_STATIC_PROPERTY 0x0700 +#define LITERAL_METHOD 0x0800 +#define LITERAL_PROPERTY 0x0900 + +#define LITERAL_EX_CLASS 0x4000 +#define LITERAL_EX_OBJ 0x2000 +#define LITERAL_MAY_MERGE 0x1000 +#define LITERAL_KIND_MASK 0x0f00 +#define LITERAL_NUM_RELATED_MASK 0x000f +#define LITERAL_NUM_SLOTS_MASK 0x00f0 +#define LITERAL_NUM_SLOTS_SHIFT 4 + +#define LITERAL_NUM_RELATED(info) (info & LITERAL_NUM_RELATED_MASK) +#define LITERAL_NUM_SLOTS(info) ((info & LITERAL_NUM_SLOTS_MASK) >> LITERAL_NUM_SLOTS_SHIFT) + +typedef struct _literal_info { + zend_uint flags; /* bitmask (see defines above) */ + union { + int num; /* variable number or class name literal number */ + } u; +} literal_info; + +#define LITERAL_FLAGS(kind, slots, related) \ + ((kind) | ((slots) << LITERAL_NUM_SLOTS_SHIFT) | (related)) + +#define LITERAL_INFO(n, kind, merge, slots, related) do { \ + info[n].flags = (((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ + } while (0) + +#define LITERAL_INFO_CLASS(n, kind, merge, slots, related, _num) do { \ + info[n].flags = (LITERAL_EX_CLASS | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ + info[n].u.num = (_num); \ + } while (0) + +#define LITERAL_INFO_OBJ(n, kind, merge, slots, related, _num) do { \ + info[n].flags = (LITERAL_EX_OBJ | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ + info[n].u.num = (_num); \ + } while (0) + +static void optimizer_literal_obj_info(literal_info *info, + zend_uchar op_type, + znode_op op, + int constant, + zend_uint kind, + zend_uint slots, + zend_uint related, + zend_op_array *op_array) +{ + /* For now we merge only $this object properties and methods. + * In general it's also possible to do it for any CV variable as well, + * but it would require complex dataflow and/or type analysis. + */ + if (Z_TYPE(op_array->literals[constant].constant) == IS_STRING && + op_type == IS_UNUSED) { + LITERAL_INFO_OBJ(constant, kind, 1, slots, related, op_array->this_var); + } else { + LITERAL_INFO(constant, kind, 0, slots, related); + } +} + +static void optimizer_literal_class_info(literal_info *info, + zend_uchar op_type, + znode_op op, + int constant, + zend_uint kind, + zend_uint slots, + zend_uint related, + zend_op_array *op_array) +{ + if (op_type == IS_CONST) { + LITERAL_INFO_CLASS(constant, kind, 1, slots, related, op.constant); + } else { + LITERAL_INFO(constant, kind, 0, slots, related); + } +} + +static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) +{ + zend_op *opline, *end; + int i, j, n, *pos, *map, cache_slots; + ulong h; + literal_info *info; + int l_null = -1; + int l_false = -1; + int l_true = -1; + HashTable hash; + char *key; + int key_len; + + if (op_array->last_literal) { + info = (literal_info*)ecalloc(op_array->last_literal, sizeof(literal_info)); + + /* Mark literals of specific types */ + opline = op_array->opcodes; + end = opline + op_array->last; + while (opline < end) { + switch (opline->opcode) { + case ZEND_DO_FCALL: + LITERAL_INFO(opline->op1.constant, LITERAL_FUNC, 1, 1, 1); + break; + case ZEND_INIT_FCALL_BY_NAME: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2); + } + break; + case ZEND_INIT_NS_FCALL_BY_NAME: + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3); + break; + case ZEND_INIT_METHOD_CALL: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + optimizer_literal_obj_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_METHOD, 2, 2, + op_array); + } + break; + case ZEND_INIT_STATIC_METHOD_CALL: + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + } + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + optimizer_literal_class_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_STATIC_METHOD, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 2, + op_array); + } + break; + case ZEND_CATCH: + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + break; + case ZEND_FETCH_CONSTANT: + if (ZEND_OP1_TYPE(opline) == IS_UNUSED) { + if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 5); + } else { + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 3); + } + } else { + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + } + optimizer_literal_class_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_CLASS_CONST, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 1, + op_array); + } + break; + case ZEND_FETCH_R: + case ZEND_FETCH_W: + case ZEND_FETCH_RW: + case ZEND_FETCH_IS: + case ZEND_FETCH_UNSET: + case ZEND_FETCH_FUNC_ARG: + case ZEND_UNSET_VAR: + case ZEND_ISSET_ISEMPTY_VAR: + if (ZEND_OP2_TYPE(opline) == IS_UNUSED) { + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); + } + } else { + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); + } + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + optimizer_literal_class_info( + info, + opline->op2_type, + opline->op2, + opline->op1.constant, + LITERAL_STATIC_PROPERTY, 2, 1, + op_array); + } + } + break; + case ZEND_FETCH_CLASS: + case ZEND_ADD_INTERFACE: + case ZEND_ADD_TRAIT: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); + } + break; + case ZEND_ASSIGN_OBJ: + case ZEND_FETCH_OBJ_R: + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_IS: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_UNSET_OBJ: + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + case ZEND_ISSET_ISEMPTY_PROP_OBJ: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + optimizer_literal_obj_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_PROPERTY, 2, 1, + op_array); + } + break; + case ZEND_ASSIGN_ADD: + case ZEND_ASSIGN_SUB: + case ZEND_ASSIGN_MUL: + case ZEND_ASSIGN_DIV: + case ZEND_ASSIGN_MOD: + case ZEND_ASSIGN_SL: + case ZEND_ASSIGN_SR: + case ZEND_ASSIGN_CONCAT: + case ZEND_ASSIGN_BW_OR: + case ZEND_ASSIGN_BW_AND: + case ZEND_ASSIGN_BW_XOR: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + if (opline->extended_value == ZEND_ASSIGN_OBJ) { + optimizer_literal_obj_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_PROPERTY, 2, 1, + op_array); + } else { + LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1); + } + } + break; + default: + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); + } + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1); + } + break; + } + opline++; + } + +#if DEBUG_COMPACT_LITERALS + { + int i, use_copy; + fprintf(stderr, "File %s func %s\n", op_array->filename, + op_array->function_name? op_array->function_name : "main"); + fprintf(stderr, "Literlas table size %d\n", op_array->last_literal); + + for (i = 0; i < op_array->last_literal; i++) { + zval zv = op_array->literals[i].constant; + zend_make_printable_zval(&op_array->literals[i].constant, &zv, &use_copy); + fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv)); + if (use_copy) { + zval_dtor(&zv); + } + } + fflush(stderr); + } +#endif + + /* Merge equal constants */ + j = 0; cache_slots = 0; + zend_hash_init(&hash, 16, NULL, NULL, 0); + map = (int*)ecalloc(op_array->last_literal, sizeof(int)); + for (i = 0; i < op_array->last_literal; i++) { + if (!info[i].flags) { + /* unsed literal */ + zval_dtor(&op_array->literals[i].constant); + continue; + } + switch (Z_TYPE(op_array->literals[i].constant)) { + case IS_NULL: + if (l_null < 0) { + l_null = j; + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + } + map[i] = l_null; + break; + case IS_BOOL: + if (Z_LVAL(op_array->literals[i].constant)) { + if (l_true < 0) { + l_true = j; + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + } + map[i] = l_true; + } else { + if (l_false < 0) { + l_false = j; + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + } + map[i] = l_false; + } + break; + case IS_LONG: + if (zend_hash_index_find(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&pos) == SUCCESS) { + map[i] = *pos; + } else { + map[i] = j; + zend_hash_index_update(&hash, Z_LVAL(op_array->literals[i].constant), (void**)&j, sizeof(int), NULL); + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + } + break; + case IS_DOUBLE: + if (zend_hash_find(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&pos) == SUCCESS) { + map[i] = *pos; + } else { + map[i] = j; + zend_hash_add(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void**)&j, sizeof(int), NULL); + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + } + break; + case IS_STRING: + case IS_CONSTANT: + if (info[i].flags & LITERAL_MAY_MERGE) { + if (info[i].flags & LITERAL_EX_OBJ) { + key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i].constant); + key = emalloc(key_len); + key_len = snprintf(key, key_len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i].constant)); + } else if (info[i].flags & LITERAL_EX_CLASS) { + zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num].constant; + key_len = Z_STRLEN_P(class_name) + sizeof("::") + Z_STRLEN(op_array->literals[i].constant); + key = emalloc(key_len); + memcpy(key, Z_STRVAL_P(class_name), Z_STRLEN_P(class_name)); + memcpy(key + Z_STRLEN_P(class_name), "::", sizeof("::") - 1); + memcpy(key + Z_STRLEN_P(class_name) + sizeof("::") - 1, + Z_STRVAL(op_array->literals[i].constant), + Z_STRLEN(op_array->literals[i].constant) + 1); + } else { + key = Z_STRVAL(op_array->literals[i].constant); + key_len = Z_STRLEN(op_array->literals[i].constant)+1; + } + h = zend_hash_func(key, key_len); + h += info[i].flags; + } + if ((info[i].flags & LITERAL_MAY_MERGE) && + zend_hash_quick_find(&hash, key, key_len, h, (void**)&pos) == SUCCESS && + Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[*pos].constant) && + info[i].flags == info[*pos].flags) { + + if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) { + efree(key); + } + map[i] = *pos; + zval_dtor(&op_array->literals[i].constant); + n = LITERAL_NUM_RELATED(info[i].flags); + while (n > 1) { + i++; + zval_dtor(&op_array->literals[i].constant); + n--; + } + } else { + map[i] = j; + if (info[i].flags & LITERAL_MAY_MERGE) { + zend_hash_quick_add(&hash, key, key_len, h, (void**)&j, sizeof(int), NULL); + if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) { + efree(key); + } + } + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + if (!op_array->literals[j].hash_value) { + if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { + op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); + } else { + op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); + } + } + if (LITERAL_NUM_SLOTS(info[i].flags)) { + op_array->literals[j].cache_slot = cache_slots; + cache_slots += LITERAL_NUM_SLOTS(info[i].flags); + } + j++; + n = LITERAL_NUM_RELATED(info[i].flags); + while (n > 1) { + i++; + if (i != j) op_array->literals[j] = op_array->literals[i]; + if (!op_array->literals[j].hash_value) { + if (IS_INTERNED(Z_STRVAL(op_array->literals[j].constant))) { + op_array->literals[j].hash_value = INTERNED_HASH(Z_STRVAL(op_array->literals[j].constant)); + } else { + op_array->literals[j].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[j].constant), Z_STRLEN(op_array->literals[j].constant)+1); + } + } + j++; + n--; + } + } + break; + default: + /* don't merge other types */ + map[i] = j; + if (i != j) { + op_array->literals[j] = op_array->literals[i]; + info[j] = info[i]; + } + j++; + break; + } + } + zend_hash_destroy(&hash); + op_array->last_literal = j; + op_array->last_cache_slot = cache_slots; + + /* Update opcodes to use new literals table */ + opline = op_array->opcodes; + end = opline + op_array->last; + while (opline < end) { + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + opline->op1.constant = map[opline->op1.constant]; + } + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + opline->op2.constant = map[opline->op2.constant]; + } + opline++; + } + efree(map); + efree(info); + +#if DEBUG_COMPACT_LITERALS + { + int i, use_copy; + fprintf(stderr, "Optimized literlas table size %d\n", op_array->last_literal); + + for (i = 0; i < op_array->last_literal; i++) { + zval zv = op_array->literals[i].constant; + zend_make_printable_zval(&op_array->literals[i].constant, &zv, &use_copy); + fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv)); + if (use_copy) { + zval_dtor(&zv); + } + } + fflush(stderr); + } +#endif + } +} +#endif diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c new file mode 100644 index 0000000000000..98bfc1e99ecf7 --- /dev/null +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -0,0 +1,138 @@ +/* pass 4 + * - optimize INIT_FCALL_BY_NAME to DO_FCALL + */ +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + +typedef struct _optimizer_call_info { + zend_function *func; + zend_op *opline; +} optimizer_call_info; + +static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script *script TSRMLS_DC) { + zend_op *opline = op_array->opcodes; + zend_op *end = opline + op_array->last; + int call = 0; +#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO + optimizer_call_info *call_stack = ecalloc(op_array->nested_calls + 1, sizeof(optimizer_call_info)); +#else + int stack_size = 4; + optimizer_call_info *call_stack = ecalloc(stack_size, sizeof(optimizer_call_info)); +#endif + + while (opline < end) { + switch (opline->opcode) { + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + zend_function *func; + zval *function_name = &op_array->literals[opline->op2.constant + 1].constant; + if ((zend_hash_quick_find(&script->function_table, + Z_STRVAL_P(function_name), Z_STRLEN_P(function_name) + 1, + Z_HASH_P(function_name), (void **)&func) == SUCCESS)) { + call_stack[call].func = func; + } + } + /* break missing intentionally */ + case ZEND_NEW: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_STATIC_METHOD_CALL: + call_stack[call].opline = opline; + call++; +#if ZEND_EXTENSION_API_NO < PHP_5_5_X_API_NO + if (call == stack_size) { + stack_size += 4; + call_stack = erealloc(call_stack, sizeof(optimizer_call_info) * stack_size); + memset(call_stack + 4, 0, 4 * sizeof(optimizer_call_info)); + } +#endif + break; + case ZEND_DO_FCALL_BY_NAME: + call--; + if (call_stack[call].func && call_stack[call].opline) { + zend_op *fcall = call_stack[call].opline; + + opline->opcode = ZEND_DO_FCALL; + ZEND_OP1_TYPE(opline) = IS_CONST; + opline->op1.constant = fcall->op2.constant + 1; + op_array->literals[fcall->op2.constant + 1].cache_slot = op_array->literals[fcall->op2.constant].cache_slot; + literal_dtor(&ZEND_OP2_LITERAL(fcall)); + if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { + literal_dtor(&op_array->literals[fcall->op2.constant + 2].constant); + } + MAKE_NOP(fcall); + } else if (opline->extended_value == 0 && + call_stack[call].opline && + call_stack[call].opline->opcode == ZEND_INIT_FCALL_BY_NAME && + ZEND_OP2_TYPE(call_stack[call].opline) == IS_CONST) { + + zend_op *fcall = call_stack[call].opline; + + opline->opcode = ZEND_DO_FCALL; + ZEND_OP1_TYPE(opline) = IS_CONST; + opline->op1.constant = fcall->op2.constant + 1; + op_array->literals[fcall->op2.constant + 1].cache_slot = op_array->literals[fcall->op2.constant].cache_slot; + literal_dtor(&ZEND_OP2_LITERAL(fcall)); + MAKE_NOP(fcall); + } + call_stack[call].func = NULL; + call_stack[call].opline = NULL; + break; + case ZEND_FETCH_FUNC_ARG: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_FETCH_DIM_FUNC_ARG: + if (call_stack[call - 1].func) { + if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + opline->extended_value = 0; + opline->opcode -= 9; + } else { + opline->extended_value = 0; + opline->opcode -= 12; + } + } + break; + case ZEND_SEND_VAL: + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { + if (ARG_MUST_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { + /* We won't convert it into_DO_FCALL to emit error at run-time */ + call_stack[call - 1].opline = NULL; + } else { + opline->extended_value = ZEND_DO_FCALL; + } + } + break; + case ZEND_SEND_VAR: + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { + if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { + opline->opcode = ZEND_SEND_REF; + } + opline->extended_value = ZEND_DO_FCALL; + } + break; + case ZEND_SEND_VAR_NO_REF: + if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) { + if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { + opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND | ZEND_ARG_SEND_BY_REF; + } else if (opline->extended_value) { + opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND; + } else { + opline->opcode = ZEND_SEND_VAR; + opline->extended_value = ZEND_DO_FCALL; + } + } + break; + case ZEND_SEND_REF: + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { + /* We won't handle run-time pass by reference */ + call_stack[call - 1].opline = NULL; + } + break; + + default: + break; + } + opline++; + } + + efree(call_stack); +} +#endif diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 70ec6d5e2ec11..2960e583aa35c 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -3,13 +3,13 @@ * - perform compile-time evaluation of constant binary and unary operations * - optimize series of ADD_STRING and/or ADD_CHAR * - convert CAST(IS_BOOL,x) into BOOL(x) - * - convert INTI_FCALL_BY_NAME, DO_FCALL_BY_NAME into DO_FCALL */ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { int i = 0; zend_op *opline = op_array->opcodes; zend_op *end = opline + op_array->last; + zend_bool collect_constants = (op_array == &script->main_op_array); while (opline < end) { switch (opline->opcode) { @@ -241,7 +241,9 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { zval c; if (!zend_get_persistent_constant(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { - break; + if (!*constants || !zend_optimizer_get_collected_constant(*constants, &ZEND_OP2_LITERAL(opline), &c)) { + break; + } } literal_dtor(&ZEND_OP2_LITERAL(opline)); ZEND_OP1_TYPE(opline) = IS_CONST; @@ -255,22 +257,70 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } break; - case ZEND_INIT_FCALL_BY_NAME: - if (opline->extended_value == 0 /* not method */ && - ZEND_OP1_TYPE(opline) == IS_UNUSED && - ZEND_OP2_TYPE(opline) == IS_CONST) { - if ((opline + 1)->opcode == ZEND_DO_FCALL_BY_NAME && - (opline + 1)->extended_value == 0) { - (opline + 1)->opcode = ZEND_DO_FCALL; - COPY_NODE((opline + 1)->op1, opline->op2); - zend_str_tolower(Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1))); + case ZEND_DO_FCALL: + /* define("name", scalar); */ + if (collect_constants && + opline->extended_value == 2 && + ZEND_OP1_TYPE(opline) == IS_CONST && + Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING && + Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("define")-1 && + zend_binary_strcasecmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)), "define", sizeof("define")-1) == 0 && + (opline-1)->opcode == ZEND_SEND_VAL && + ZEND_OP1_TYPE(opline-1) == IS_CONST && + (Z_TYPE(ZEND_OP1_LITERAL(opline-1)) <= IS_BOOL || + Z_TYPE(ZEND_OP1_LITERAL(opline-1)) == IS_STRING) && + (opline-2)->opcode == ZEND_SEND_VAL && + ZEND_OP1_TYPE(opline-2) == IS_CONST && + Z_TYPE(ZEND_OP1_LITERAL(opline-2)) == IS_STRING) { + zend_optimizer_collect_constant(constants, &ZEND_OP1_LITERAL(opline-2), &ZEND_OP1_LITERAL(opline-1)); + } + break; +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO + case ZEND_DECLARE_CONST: + if (collect_constants && + Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING && + (Z_TYPE(ZEND_OP2_LITERAL(opline)) <= IS_BOOL || + Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING)) { + zend_optimizer_collect_constant(constants, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline)); + } + break; +#endif + + case ZEND_RETURN: #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - Z_HASH_P(&ZEND_OP1_LITERAL(opline + 1)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)) + 1); - op_array->literals[(opline + 1)->op1.constant].cache_slot = op_array->last_cache_slot++; + case ZEND_RETURN_BY_REF: #endif - MAKE_NOP(opline); - } - } +#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO + case ZEND_GENERATOR_RETURN: +#endif + case ZEND_EXIT: + case ZEND_THROW: + case ZEND_CATCH: + case ZEND_BRK: + case ZEND_CONT: +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + case ZEND_GOTO: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO + case ZEND_FAST_CALL: + case ZEND_FAST_RET: +#endif + case ZEND_JMP: + case ZEND_JMPZNZ: + case ZEND_JMPZ: + case ZEND_JMPNZ: + case ZEND_JMPZ_EX: + case ZEND_JMPNZ_EX: + case ZEND_FE_RESET: + case ZEND_FE_FETCH: + case ZEND_NEW: +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + case ZEND_JMP_SET: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + case ZEND_JMP_SET_VAR: +#endif + collect_constants = 0; break; #if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 28085cb441e22..ec36502f167b1 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -24,10 +24,41 @@ #include "zend_API.h" #include "zend_constants.h" #include "zend_execute.h" +#include "zend_vm.h" #define OPTIMIZATION_LEVEL \ ZCG(accel_directives).optimization_level +static void zend_optimizer_zval_dtor_wrapper(zval *zvalue) +{ + zval_dtor(zvalue); +} + +static void zend_optimizer_collect_constant(HashTable **constants, zval *name, zval* value) +{ + zval val; + + if (!*constants) { + *constants = emalloc(sizeof(HashTable)); + zend_hash_init(*constants, 16, NULL, (void (*)(void *))zend_optimizer_zval_dtor_wrapper, 0); + } + val = *value; + zval_copy_ctor(&val); + zend_hash_add(*constants, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, (void**)&val, sizeof(zval), NULL); +} + +static int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) +{ + zval *val; + + if (zend_hash_find(constants, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, (void**)&val) == SUCCESS) { + *value = *val; + zval_copy_ctor(value); + return 1; + } + return 0; +} + #if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len) { @@ -62,10 +93,7 @@ int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC { int i = op_array->last_literal; op_array->last_literal++; - if (i >= CG(context).literals_size) { - CG(context).literals_size += 16; /* FIXME */ - op_array->literals = (zend_literal*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zend_literal)); - } + op_array->literals = (zend_literal*)erealloc(op_array->literals, op_array->last_literal * sizeof(zend_literal)); op_array->literals[i].constant = *zv; op_array->literals[i].hash_value = 0; op_array->literals[i].cache_slot = -1; @@ -244,8 +272,12 @@ static void replace_tmp_by_const(zend_op_array *op_array, #include "Optimizer/nop_removal.c" #include "Optimizer/block_pass.c" #include "Optimizer/optimize_temp_vars_5.c" +#include "Optimizer/compact_literals.c" +#include "Optimizer/optimize_func_calls.c" -void zend_optimizer(zend_op_array *op_array TSRMLS_DC) +static void zend_optimize(zend_op_array *op_array, + zend_persistent_script *script, + HashTable **constants TSRMLS_DC) { if (op_array->type == ZEND_EVAL_CODE || (op_array->fn_flags & ZEND_ACC_INTERACTIVE)) { @@ -257,7 +289,6 @@ void zend_optimizer(zend_op_array *op_array TSRMLS_DC) * - perform compile-time evaluation of constant binary and unary operations * - optimize series of ADD_STRING and/or ADD_CHAR * - convert CAST(IS_BOOL,x) into BOOL(x) - * - convert INTI_FCALL_BY_NAME + DO_FCALL_BY_NAME into DO_FCALL */ #include "Optimizer/pass1_5.c" @@ -275,12 +306,21 @@ void zend_optimizer(zend_op_array *op_array TSRMLS_DC) */ #include "Optimizer/pass3.c" +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + /* pass 4: + * - INIT_FCALL_BY_NAME -> DO_FCALL + */ + if (ZEND_OPTIMIZER_PASS_4 & OPTIMIZATION_LEVEL) { + optimize_func_calls(op_array, script TSRMLS_CC); + } +#endif + /* pass 5: * - CFG optimization */ #include "Optimizer/pass5.c" - /* pass 9: + /* pass 9: * - Optimize temp variables usage */ #include "Optimizer/pass9.c" @@ -289,4 +329,143 @@ void zend_optimizer(zend_op_array *op_array TSRMLS_DC) * - remove NOPs */ #include "Optimizer/pass10.c" + +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + /* pass 11: + * - Compact literals table + */ + if (ZEND_OPTIMIZER_PASS_11 & OPTIMIZATION_LEVEL) { + optimizer_compact_literals(op_array TSRMLS_CC); + } +#endif +} + +static void zend_accel_optimize(zend_op_array *op_array, + zend_persistent_script *script, + HashTable **constants TSRMLS_DC) +{ + zend_op *opline, *end; + + /* Revert pass_two() */ + opline = op_array->opcodes; + end = opline + op_array->last; + while (opline < end) { +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + if (opline->op1_type == IS_CONST) { + opline->op1.constant = opline->op1.literal - op_array->literals; + } + if (opline->op2_type == IS_CONST) { + opline->op2.constant = opline->op2.literal - op_array->literals; + } +#endif + switch (opline->opcode) { + case ZEND_JMP: +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO + case ZEND_GOTO: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO + case ZEND_FAST_CALL: +#endif + ZEND_OP1(opline).opline_num = ZEND_OP1(opline).jmp_addr - op_array->opcodes; + break; + case ZEND_JMPZ: + case ZEND_JMPNZ: + case ZEND_JMPZ_EX: + case ZEND_JMPNZ_EX: +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO + case ZEND_JMP_SET: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + case ZEND_JMP_SET_VAR: +#endif + ZEND_OP2(opline).opline_num = ZEND_OP2(opline).jmp_addr - op_array->opcodes; + break; + } + opline++; + } + + /* Do actual optimizations */ + zend_optimize(op_array, script, constants TSRMLS_CC); + + /* Redo pass_two() */ + opline = op_array->opcodes; + end = opline + op_array->last; + while (opline < end) { +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + if (opline->op1_type == IS_CONST) { + opline->op1.zv = &op_array->literals[opline->op1.constant].constant; + } + if (opline->op2_type == IS_CONST) { + opline->op2.zv = &op_array->literals[opline->op2.constant].constant; + } +#endif + switch (opline->opcode) { + case ZEND_JMP: +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO + case ZEND_GOTO: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO + case ZEND_FAST_CALL: +#endif + ZEND_OP1(opline).jmp_addr = &op_array->opcodes[ZEND_OP1(opline).opline_num]; + break; + case ZEND_JMPZ: + case ZEND_JMPNZ: + case ZEND_JMPZ_EX: + case ZEND_JMPNZ_EX: +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO + case ZEND_JMP_SET: +#endif +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + case ZEND_JMP_SET_VAR: +#endif + ZEND_OP2(opline).jmp_addr = &op_array->opcodes[ZEND_OP2(opline).opline_num]; + break; + } + ZEND_VM_SET_OPCODE_HANDLER(opline); + opline++; + } +} + +int zend_accel_script_optimize(zend_persistent_script *script TSRMLS_DC) +{ + Bucket *p, *q; + HashTable *constants = NULL; + + zend_accel_optimize(&script->main_op_array, script, &constants TSRMLS_CC); + + p = script->function_table.pListHead; + while (p) { + zend_op_array *op_array = (zend_op_array*)p->pData; + zend_accel_optimize(op_array, script, &constants TSRMLS_CC); + p = p->pListNext; + } + + p = script->class_table.pListHead; + while (p) { + zend_class_entry *ce = (zend_class_entry*)p->pDataPtr; + q = ce->function_table.pListHead; + while (q) { + zend_op_array *op_array = (zend_op_array*)q->pData; + if (op_array->scope == ce) { + zend_accel_optimize(op_array, script, &constants TSRMLS_CC); + } else if (op_array->type == ZEND_USER_FUNCTION) { + zend_op_array *orig_op_array; + if (zend_hash_find(&op_array->scope->function_table, q->arKey, q->nKeyLength, (void**)&orig_op_array) == SUCCESS) { + HashTable *ht = op_array->static_variables; + *op_array = *orig_op_array; + op_array->static_variables = ht; + } + } + q = q->pListNext; + } + p = p->pListNext; + } + + if (constants) { + zend_hash_destroy(constants); + efree(constants); + } + + return 1; } diff --git a/ext/opcache/Optimizer/zend_optimizer.h b/ext/opcache/Optimizer/zend_optimizer.h index 98275a20aae0e..5a3d715ac9b1a 100644 --- a/ext/opcache/Optimizer/zend_optimizer.h +++ b/ext/opcache/Optimizer/zend_optimizer.h @@ -28,14 +28,14 @@ #define ZEND_OPTIMIZER_PASS_1 (1<<0) /* CSE, STRING construction */ #define ZEND_OPTIMIZER_PASS_2 (1<<1) /* Constant conversion and jumps */ #define ZEND_OPTIMIZER_PASS_3 (1<<2) /* ++, +=, series of jumps */ -#define ZEND_OPTIMIZER_PASS_4 (1<<3) +#define ZEND_OPTIMIZER_PASS_4 (1<<3) /* INIT_FCALL_BY_NAME -> DO_FCALL */ #define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */ #define ZEND_OPTIMIZER_PASS_6 (1<<5) #define ZEND_OPTIMIZER_PASS_7 (1<<6) #define ZEND_OPTIMIZER_PASS_8 (1<<7) #define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */ #define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */ -#define ZEND_OPTIMIZER_PASS_11 (1<<10) +#define ZEND_OPTIMIZER_PASS_11 (1<<10) /* Merge equal constants */ #define ZEND_OPTIMIZER_PASS_12 (1<<11) #define ZEND_OPTIMIZER_PASS_13 (1<<12) #define ZEND_OPTIMIZER_PASS_14 (1<<13) @@ -44,6 +44,4 @@ #define DEFAULT_OPTIMIZATION_LEVEL "0xFFFFFFFF" -void zend_optimizer(zend_op_array *op_array TSRMLS_DC); - #endif diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 8eaa0a37788c6..0d7b94057b36c 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -36,7 +36,7 @@ #include "main/php_open_temporary_file.h" #include "zend_API.h" #include "zend_ini.h" -#include "TSRM/tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_accelerator_util_funcs.h" #include "zend_accelerator_hash.h" @@ -1130,6 +1130,10 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr return new_persistent_script; } + if (!zend_accel_script_optimize(new_persistent_script TSRMLS_CC)) { + return new_persistent_script; + } + if (!compact_persistent_script(new_persistent_script)) { return new_persistent_script; } @@ -2773,19 +2777,6 @@ void accelerator_shm_read_unlock(TSRMLS_D) } } -static void accel_op_array_handler(zend_op_array *op_array) -{ - TSRMLS_FETCH(); - - if (ZCG(enabled) && - accel_startup_ok && - ZCSG(accelerator_enabled) && - !ZSMMG(memory_exhausted) && - !ZCSG(restart_pending)) { - zend_optimizer(op_array TSRMLS_CC); - } -} - ZEND_EXT_API zend_extension zend_extension_entry = { ACCELERATOR_PRODUCT_NAME, /* name */ ACCELERATOR_VERSION, /* version */ @@ -2797,7 +2788,7 @@ ZEND_EXT_API zend_extension zend_extension_entry = { accel_activate, /* per-script activation */ accel_deactivate, /* per-script deactivation */ NULL, /* message handler */ - accel_op_array_handler, /* op_array handler */ + NULL, /* op_array handler */ NULL, /* extended statement handler */ NULL, /* extended fcall begin handler */ NULL, /* extended fcall end handler */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index b9d7ef34704d8..2f6ee068e8111 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -330,6 +330,7 @@ void accel_shutdown(TSRMLS_D); void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC); void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC); int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC); +int zend_accel_script_optimize(zend_persistent_script *persistent_script TSRMLS_DC); int accelerator_shm_read_lock(TSRMLS_D); void accelerator_shm_read_unlock(TSRMLS_D); diff --git a/ext/opcache/tests/compact_literals.phpt b/ext/opcache/tests/compact_literals.phpt new file mode 100644 index 0000000000000..367331f74255c --- /dev/null +++ b/ext/opcache/tests/compact_literals.phpt @@ -0,0 +1,215 @@ +--TEST-- +Test with compact literals +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--SKIPIF-- + +--FILE-- + "one", + "2" => "two", + "one" => 1, + "two" => 2, +); + +unset($array["one"]); +unset($array["2"]); + +print_r($array); + +echo "function define" . ":" . PHP_EOL; +if (!function_exists("dummy")) { + function dummy() { + var_dump(__FUNCTION__); + } +} + +dummy(); + +$dummy = function () { var_dump("lambda" . "dummy"); }; +$dummy(); + +if (!class_exists("A")) { + class A { + public static $name = "A"; + public static function say($n = "name") { + var_dump(static::$name); + } + } +} + +class B extends A { + public static $name = "B"; +} + +if (!class_exists("C")) { + class C extends B { + public static $name = "C"; + } +} + +A::say(); +B::Say(); +A::say(); +B::say(); +C::say(); + +function get_eol_define() { + define("MY_EOL", PHP_EOL); +} +get_eol_define(); +define("EOL", MY_EOL); + +echo "constants define" . ":" . EOL; + +echo "define " . "TEST" . EOL; +define("TEST", "TEST"); + +class E { + public static $E="EP"; + const E="E"; + const TEST="NULL"; +} + +class F { + const F="F"; + public static $E="FEP"; + const E="FE"; + const TEST="FALSE"; + public static $F = "FP"; +} + +var_dump(TEST); //"TEST" +var_dump(E::E); //"E" +var_dump(F::E); //"FE" +var_dump(F::F); //"F" +var_dump(E::TEST); //"NULL" +var_dump(F::TEST); //"FALSE" +var_dump(E::$E); //"EP" +var_dumP(F::$F); //"FP" +var_dumP(F::$E); //"FEP" + +echo "propertes and methods" . EOL; + +class CH { + const H = "H"; + public function h() { + var_dump(self::H); + } +} + +class CI { + const H = "I"; + public function h() { + var_dump(self::H); + } +} + +function change(&$obj) { + $obj = new CH; +} + +function geti() { + return new CI; +} + +$h = new CH; + +echo "-->H" . PHP_EOL; +$h->H(); +var_dump($h::H); +var_dump(CH::H); + +$h->H(); +var_dump($h::H); +var_dump(CH::H); + +echo "-->I" . PHP_EOL; +$h = new CI; +$h->H(); +var_dump($h::H); +var_dump(CI::H); +$h->H(); +var_dump($h::H); +var_dump(CI::H); + +echo "-->H" . PHP_EOL; +change($h); + +$h->H(); +var_dump($h::H); +var_dump(CH::H); + +$h->H(); +var_dump($h::H); +var_dump(CH::H); + +echo "-->I" . PHP_EOL; +$h = geti(); +$h->H(); +var_dump($h::H); +var_dump(CI::H); +$h->H(); +var_dump($h::H); +var_dump(CI::H); +?> +--EXPECT-- +array key hash: +Array +( + [1] => one + [two] => 2 +) +function define: +string(5) "dummy" +string(11) "lambdadummy" +string(1) "A" +string(1) "B" +string(1) "A" +string(1) "B" +string(1) "C" +constants define: +define TEST +string(4) "TEST" +string(1) "E" +string(2) "FE" +string(1) "F" +string(4) "NULL" +string(5) "FALSE" +string(2) "EP" +string(2) "FP" +string(3) "FEP" +propertes and methods +-->H +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +-->I +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" +-->H +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +string(1) "H" +-->I +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" +string(1) "I" diff --git a/ext/opcache/tests/optimize_func_calls.phpt b/ext/opcache/tests/optimize_func_calls.phpt new file mode 100644 index 0000000000000..b3bc8da6a9596 --- /dev/null +++ b/ext/opcache/tests/optimize_func_calls.phpt @@ -0,0 +1,130 @@ +--TEST-- +Test with optimization of function calls +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--SKIPIF-- + +--FILE-- +obj); +$obj = new A; +ref($obj->obj); +var_dump($obj->obj); + +ref(retarray()[0]); + +$a = "a"; +foo(a($a), $a, ref($b, $c), $obj); +var_dump($a); +var_dump($b); + +/* + * INIT_FCALL_BY_NAME + * SEND_VAL + * DO_FCALL_BY_NAME + */ +ref("xxx"); + +function retarray() { + return array("retarray"); +} + +function foo($a) { + print_r(func_get_args()); +} + +function ref(&$b) { + $b = "changed"; + return "ref"; +} +--EXPECTF-- +Array +( + [0] => done +) +string(7) "changed" +Array +( + [0] => done +) +string(7) "changed" +Array +( + [0] => A Object + ( + [obj] => + ) + +) +Array +( + [0] => +) +string(7) "changed" +Array +( + [0] => done + [1] => changed + [2] => ref + [3] => A Object + ( + [obj] => changed + ) + +) +string(7) "changed" +string(7) "changed" + +Fatal error: Cannot pass parameter 1 by reference in %soptimize_func_calls.php on line %d diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 0914fb68dd936..2ee02a60ce846 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -28,7 +28,7 @@ #include "zend_accelerator_blacklist.h" #include "php_ini.h" #include "SAPI.h" -#include "TSRM/tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "ext/standard/info.h" #include "ext/standard/php_filestat.h" diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 59a58b1c00256..7cf637c7f6cbd 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -129,6 +129,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_export, 0, 0, 2) ZEND_ARG_INFO(0, notext) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_fingerprint, 0, 0, 1) + ZEND_ARG_INFO(0, x509) + ZEND_ARG_INFO(0, method) + ZEND_ARG_INFO(0, raw_output) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_openssl_x509_check_private_key, 0) ZEND_ARG_INFO(0, cert) ZEND_ARG_INFO(0, key) @@ -394,11 +400,35 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_random_pseudo_bytes, 0, 0, 1) ZEND_ARG_INFO(0, length) ZEND_ARG_INFO(1, result_is_strong) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_spki_new, 0, 0, 2) + ZEND_ARG_INFO(0, privkey) + ZEND_ARG_INFO(0, challenge) + ZEND_ARG_INFO(0, algo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_verify, 0) + ZEND_ARG_INFO(0, spki) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export, 0) + ZEND_ARG_INFO(0, spki) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_openssl_spki_export_challenge, 0) + ZEND_ARG_INFO(0, spki) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ openssl_functions[] */ const zend_function_entry openssl_functions[] = { +/* spki functions */ + PHP_FE(openssl_spki_new, arginfo_openssl_spki_new) + PHP_FE(openssl_spki_verify, arginfo_openssl_spki_verify) + PHP_FE(openssl_spki_export, arginfo_openssl_spki_export) + PHP_FE(openssl_spki_export_challenge, arginfo_openssl_spki_export_challenge) + /* public/private key functions */ PHP_FE(openssl_pkey_free, arginfo_openssl_pkey_free) PHP_FE(openssl_pkey_new, arginfo_openssl_pkey_new) @@ -419,6 +449,7 @@ const zend_function_entry openssl_functions[] = { PHP_FE(openssl_x509_checkpurpose, arginfo_openssl_x509_checkpurpose) PHP_FE(openssl_x509_check_private_key, arginfo_openssl_x509_check_private_key) PHP_FE(openssl_x509_export, arginfo_openssl_x509_export) + PHP_FE(openssl_x509_fingerprint, arginfo_openssl_x509_fingerprint) PHP_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file) /* PKCS12 funcs */ @@ -781,6 +812,7 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */ static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo); +int openssl_spki_cleanup(const char *src, char *dest); static int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args TSRMLS_DC) /* {{{ */ { @@ -1151,6 +1183,10 @@ PHP_MINIT_FUNCTION(openssl) php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC); #endif php_stream_xport_register("tls", php_openssl_ssl_socket_factory TSRMLS_CC); +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory TSRMLS_CC); + php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory TSRMLS_CC); +#endif /* override the default tcp socket provider */ php_stream_xport_register("tcp", php_openssl_ssl_socket_factory TSRMLS_CC); @@ -1189,6 +1225,10 @@ PHP_MSHUTDOWN_FUNCTION(openssl) #endif php_stream_xport_unregister("sslv3" TSRMLS_CC); php_stream_xport_unregister("tls" TSRMLS_CC); +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + php_stream_xport_unregister("tlsv1.1" TSRMLS_CC); + php_stream_xport_unregister("tlsv1.2" TSRMLS_CC); +#endif /* reinstate the default tcp handler */ php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC); @@ -1325,6 +1365,279 @@ PHP_FUNCTION(openssl_x509_export_to_file) } /* }}} */ +/* {{{ proto string openssl_spki_new(mixed zpkey, string challenge [, mixed method]) + Creates new private key (or uses existing) and creates a new spki cert + outputting results to var */ +PHP_FUNCTION(openssl_spki_new) +{ + int challenge_len; + char * challenge = NULL, * spkstr = NULL, * s = NULL; + long keyresource = -1; + const char *spkac = "SPKAC="; + long algo = OPENSSL_ALGO_MD5; + + zval *method = NULL; + zval * zpkey = NULL; + EVP_PKEY * pkey = NULL; + NETSCAPE_SPKI *spki=NULL; + const EVP_MD *mdtype; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|z", &zpkey, &challenge, &challenge_len, &method) == FAILURE) { + return; + } + RETVAL_FALSE; + + pkey = php_openssl_evp_from_zval(&zpkey, 0, challenge, 1, &keyresource TSRMLS_CC); + + if (pkey == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied private key"); + goto cleanup; + } + + if (method != NULL) { + if (Z_TYPE_P(method) == IS_LONG) { + algo = Z_LVAL_P(method); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Algorithm must be of supported type"); + goto cleanup; + } + } + mdtype = php_openssl_get_evp_md_from_algo(algo); + + if (!mdtype) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm"); + goto cleanup; + } + + if ((spki = NETSCAPE_SPKI_new()) == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create new SPKAC"); + goto cleanup; + } + + if (challenge) { + ASN1_STRING_set(spki->spkac->challenge, challenge, challenge_len); + } + + if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to embed public key"); + goto cleanup; + } + + if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to sign with specified algorithm"); + goto cleanup; + } + + spkstr = NETSCAPE_SPKI_b64_encode(spki); + if (!spkstr){ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to encode SPKAC"); + goto cleanup; + } + + s = emalloc(strlen(spkac) + strlen(spkstr) + 1); + sprintf(s, "%s%s", spkac, spkstr); + + RETVAL_STRINGL(s, strlen(s), 0); + goto cleanup; + +cleanup: + + if (keyresource == -1 && spki != NULL) { + NETSCAPE_SPKI_free(spki); + } + if (keyresource == -1 && pkey != NULL) { + EVP_PKEY_free(pkey); + } + if (keyresource == -1 && spkstr != NULL) { + efree(spkstr); + } + + if (strlen(s) <= 0) { + RETVAL_FALSE; + } + + if (keyresource == -1 && s != NULL) { + efree(s); + } +} +/* }}} */ + +/* {{{ proto bool openssl_spki_verify(string spki) + Verifies spki returns boolean */ +PHP_FUNCTION(openssl_spki_verify) +{ + int spkstr_len, i = 0; + char *spkstr = NULL, * spkstr_cleaned = NULL; + + EVP_PKEY *pkey = NULL; + NETSCAPE_SPKI *spki = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) { + return; + } + RETVAL_FALSE; + + if (spkstr == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC"); + goto cleanup; + } + + spkstr_cleaned = emalloc(spkstr_len + 1); + openssl_spki_cleanup(spkstr, spkstr_cleaned); + + if (strlen(spkstr_cleaned)<=0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid SPKAC"); + goto cleanup; + } + + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned)); + if (spki == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC"); + goto cleanup; + } + + pkey = X509_PUBKEY_get(spki->spkac->pubkey); + if (pkey == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to acquire signed public key"); + goto cleanup; + } + + i = NETSCAPE_SPKI_verify(spki, pkey); + goto cleanup; + +cleanup: + if (spki != NULL) { + NETSCAPE_SPKI_free(spki); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + if (spkstr_cleaned != NULL) { + efree(spkstr_cleaned); + } + + if (i > 0) { + RETVAL_TRUE; + } +} +/* }}} */ + +/* {{{ proto string openssl_spki_export(string spki) + Exports public key from existing spki to var */ +PHP_FUNCTION(openssl_spki_export) +{ + int spkstr_len; + char *spkstr = NULL, * spkstr_cleaned = NULL, * s = NULL; + + EVP_PKEY *pkey = NULL; + NETSCAPE_SPKI *spki = NULL; + BIO *out = BIO_new(BIO_s_mem()); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) { + return; + } + RETVAL_FALSE; + + if (spkstr == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC"); + goto cleanup; + } + + spkstr_cleaned = emalloc(spkstr_len + 1); + openssl_spki_cleanup(spkstr, spkstr_cleaned); + + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned)); + if (spki == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode supplied SPKAC"); + goto cleanup; + } + + pkey = X509_PUBKEY_get(spki->spkac->pubkey); + if (pkey == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to acquire signed public key"); + goto cleanup; + } + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + PEM_write_bio_PUBKEY(out, pkey); + goto cleanup; + +cleanup: + + if (spki != NULL) { + NETSCAPE_SPKI_free(spki); + } + if (out != NULL) { + BIO_free_all(out); + } + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + if (spkstr_cleaned != NULL) { + efree(spkstr_cleaned); + } + if (s != NULL) { + efree(s); + } +} +/* }}} */ + +/* {{{ proto string openssl_spki_export_challenge(string spki) + Exports spkac challenge from existing spki to var */ +PHP_FUNCTION(openssl_spki_export_challenge) +{ + int spkstr_len; + char *spkstr = NULL, * spkstr_cleaned = NULL; + + NETSCAPE_SPKI *spki = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &spkstr, &spkstr_len) == FAILURE) { + return; + } + RETVAL_FALSE; + + if (spkstr == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to use supplied SPKAC"); + goto cleanup; + } + + spkstr_cleaned = emalloc(spkstr_len + 1); + openssl_spki_cleanup(spkstr, spkstr_cleaned); + + spki = NETSCAPE_SPKI_b64_decode(spkstr_cleaned, strlen(spkstr_cleaned)); + if (spki == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode SPKAC"); + goto cleanup; + } + + RETVAL_STRING((char *) ASN1_STRING_data(spki->spkac->challenge), 1); + goto cleanup; + +cleanup: + if (spkstr_cleaned != NULL) { + efree(spkstr_cleaned); + } +} +/* }}} */ + +/* {{{ strip line endings from spkac */ +int openssl_spki_cleanup(const char *src, char *dest) +{ + int removed=0; + + while (*src) { + if (*src!='\n'&&*src!='\r') { + *dest++=*src; + } else { + ++removed; + } + ++src; + } + *dest=0; + return removed; +} +/* }}} */ + /* {{{ proto bool openssl_x509_export(mixed x509, string &out [, bool notext = true]) Exports a CERT to file or a var */ PHP_FUNCTION(openssl_x509_export) @@ -1367,6 +1680,121 @@ PHP_FUNCTION(openssl_x509_export) } /* }}} */ +static int php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw, char **out, int *out_len TSRMLS_DC) +{ + unsigned char md[EVP_MAX_MD_SIZE]; + const EVP_MD *mdtype; + unsigned int n; + + if (!(mdtype = EVP_get_digestbyname(method))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm"); + return FAILURE; + } else if (!X509_digest(peer, mdtype, md, &n)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not generate signature"); + return FAILURE; + } + + if (raw) { + *out_len = n; + *out = estrndup((char *) md, n); + } else { + *out_len = n * 2; + *out = emalloc(*out_len + 1); + + make_digest_ex(*out, md, n); + } + + return SUCCESS; +} + +static int php_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected TSRMLS_DC) +{ + char *fingerprint; + int fingerprint_len; + int result = -1; + + if (php_openssl_x509_fingerprint(peer, method, 0, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) { + result = strcmp(expected, fingerprint); + efree(fingerprint); + } + + return result; +} + +static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC) +{ + if (Z_TYPE_P(val) == IS_STRING) { + const char *method = NULL; + + switch (Z_STRLEN_P(val)) { + case 32: + method = "md5"; + break; + + case 40: + method = "sha1"; + break; + } + + return method && php_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val) TSRMLS_CC) == 0; + } else if (Z_TYPE_P(val) == IS_ARRAY) { + HashPosition pos; + zval **current; + char *key; + uint key_len; + ulong key_index; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(val), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(val), (void **)¤t, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(val), &pos) + ) { + int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(val), &key, &key_len, &key_index, 0, &pos); + + if (key_type == HASH_KEY_IS_STRING + && Z_TYPE_PP(current) == IS_STRING + && php_x509_fingerprint_cmp(peer, key, Z_STRVAL_PP(current) TSRMLS_CC) != 0 + ) { + return 0; + } + } + return 1; + } + return 0; +} + +PHP_FUNCTION(openssl_x509_fingerprint) +{ + X509 *cert; + zval **zcert; + long certresource; + zend_bool raw_output = 0; + char *method = "sha1"; + int method_len; + + char *fingerprint; + int fingerprint_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|sb", &zcert, &method, &method_len, &raw_output) == FAILURE) { + return; + } + + cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); + if (cert == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); + RETURN_FALSE; + } + + if (php_openssl_x509_fingerprint(cert, method, raw_output, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) { + RETVAL_STRINGL(fingerprint, fingerprint_len, 0); + } else { + RETVAL_FALSE; + } + + if (certresource == -1 && cert) { + X509_free(cert); + } +} + /* {{{ proto bool openssl_x509_check_private_key(mixed cert, mixed key) Checks if a private key corresponds to a CERT */ PHP_FUNCTION(openssl_x509_check_private_key) @@ -4496,14 +4924,12 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */ { php_stream *stream; SSL *ssl; - X509 *err_cert; int err, depth, ret; zval **val; ret = preverify_ok; /* determine the status for the current cert */ - err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); @@ -4531,12 +4957,91 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */ } /* }}} */ +static zend_bool matches_wildcard_name(const char *subjectname, const char *certname) +{ + char *wildcard; + int prefix_len, suffix_len, subject_len; + + if (strcasecmp(subjectname, certname) == 0) { + return 1; + } + + if (!(wildcard = strchr(certname, '*'))) { + return 0; + } + + // 1) prefix, if not empty, must match subject + prefix_len = wildcard - certname; + if (prefix_len && strncasecmp(subjectname, certname, prefix_len) != 0) { + return 0; + } + + suffix_len = strlen(wildcard + 1); + subject_len = strlen(subjectname); + if (suffix_len <= subject_len) { + /* 2) suffix must match + * 3) no . between prefix and suffix + **/ + return strcasecmp(wildcard + 1, subjectname + subject_len - suffix_len) == 0 && + memchr(subjectname + prefix_len, '.', subject_len - suffix_len - prefix_len) == NULL; + } + + return 0; +} + +static zend_bool matches_san_list(X509 *peer, const char *subject_name) +{ + int i; + zend_bool is_match = 0; + unsigned char *cert_name; + + GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0); + int alt_name_count = sk_GENERAL_NAME_num(alt_names); + + for (i = 0; i < alt_name_count; i++) { + GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); + + if (GEN_DNS == san->type) { + ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); + is_match = matches_wildcard_name(subject_name, (char *) cert_name); + OPENSSL_free(cert_name); + } + + if (is_match) { + break; + } + } + + return is_match; +} + +static zend_bool matches_common_name(X509 *peer, const char *subject_name TSRMLS_DC) +{ + char buf[1024]; + X509_NAME *cert_name; + zend_bool is_match = 0; + int cert_name_len; + + cert_name = X509_get_subject_name(peer); + cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf)); + + if (cert_name_len == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); + } else if (cert_name_len != strlen(buf)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf); + } else if (matches_wildcard_name(subject_name, buf)) { + is_match = 1; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", cert_name_len, buf, subject_name); + } + + return is_match; +} + int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC) /* {{{ */ { zval **val = NULL; char *cnmatch = NULL; - X509_NAME *name; - char buf[1024]; int err; /* verification is turned off */ @@ -4567,36 +5072,25 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre /* if the cert passed the usual checks, apply our own local policies now */ - name = X509_get_subject_name(peer); - - /* Does the common name match ? (used primarily for https://) */ - GET_VER_OPT_STRING("CN_match", cnmatch); - if (cnmatch) { - int match = 0; - int name_len = X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf)); - - if (name_len == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); - return FAILURE; - } else if (name_len != strlen(buf)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", name_len, buf); - return FAILURE; - } - - match = strcmp(cnmatch, buf) == 0; - if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == '.') { - /* Try wildcard */ - - if (strchr(buf+2, '.')) { - char *tmp = strstr(cnmatch, buf+1); - - match = tmp && strcmp(tmp, buf+2) && tmp == strchr(cnmatch, '.'); + if (GET_VER_OPT("peer_fingerprint")) { + if (Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_ARRAY) { + if (!php_x509_fingerprint_match(peer, *val TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer fingerprint doesn't match"); + return FAILURE; } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected peer fingerprint must be a string or an array"); } + } - if (!match) { - /* didn't match */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", name_len, buf, cnmatch); + GET_VER_OPT_STRING("CN_match", cnmatch); + + if (cnmatch) { + if (matches_san_list(peer, cnmatch)) { + return SUCCESS; + } else if (matches_common_name(peer, cnmatch TSRMLS_CC)) { + return SUCCESS; + } else { return FAILURE; } } diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index e6b064a277e68..a06e43db1ce5e 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -66,6 +66,7 @@ PHP_FUNCTION(openssl_x509_free); PHP_FUNCTION(openssl_x509_parse); PHP_FUNCTION(openssl_x509_checkpurpose); PHP_FUNCTION(openssl_x509_export); +PHP_FUNCTION(openssl_x509_fingerprint); PHP_FUNCTION(openssl_x509_export_to_file); PHP_FUNCTION(openssl_x509_check_private_key); @@ -79,6 +80,11 @@ PHP_FUNCTION(openssl_csr_export_to_file); PHP_FUNCTION(openssl_csr_sign); PHP_FUNCTION(openssl_csr_get_subject); PHP_FUNCTION(openssl_csr_get_public_key); + +PHP_FUNCTION(openssl_spki_new); +PHP_FUNCTION(openssl_spki_verify); +PHP_FUNCTION(openssl_spki_export); +PHP_FUNCTION(openssl_spki_export_challenge); #else #define phpext_openssl_ptr NULL diff --git a/ext/openssl/tests/bug65729.pem b/ext/openssl/tests/bug65729.pem new file mode 100644 index 0000000000000..dbeed6efd3011 --- /dev/null +++ b/ext/openssl/tests/bug65729.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIICCTCCAXICCQDNMI29sowT7TANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJT +RzESMBAGA1UECBMJVGVzdHZpbGxlMREwDwYDVQQKEwhkYXRpYmJhdzETMBEGA1UE +AxQKKi50ZXN0LmNvbTAeFw0xMzA5MjEwNzUyMjRaFw0xNDA5MjEwNzUyMjRaMEkx +CzAJBgNVBAYTAlNHMRIwEAYDVQQIEwlUZXN0dmlsbGUxETAPBgNVBAoTCGRhdGli +YmF3MRMwEQYDVQQDFAoqLnRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK03oAd1jTe +Vd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOXZPG3UViD +rtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQABMA0GCSqG +SIb3DQEBBQUAA4GBAAS07u/Ke+EhEHidz6CG3Qcr+zg483JKRgZFyGz+YUKyyKKy +fmLs7JieGJxYQjOmIpj/6X9Gnb2HjIPDnI6A+MV1emXDTnnmsgf2/lZGcthhpZn2 +rMbj9bI0iH6HwOVGtp4ZJA5fB7nj3J+gWNTCQzDDOxwX36d2LL9ua+UMnk/g +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK0 +3oAd1jTeVd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOX +ZPG3UViDrtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQAB +AoGAeyzTwKPDl5QMRejHQL57GOwlH1vLcXrjv+VzwHZZKQ0IoKM++5fCQYf29KXp +XPahaluGW2u9sWa8R/7wGcd0Q4RtquGzsgT3+AQsIc5KfIamyOyDaRVM/ymX3fWg +gHIU7OOzB+ihOU8sHyRIwfbk01/kmrBXLRj8E31sy3i3PIECQQDQQYE+aN7Acrdt +yN5CaqvbkiCGjRvASlemiTzPosgOtndyp21w1gakJwKYhYDk1N6A6Qb8REMZqM/U +wFypldV/AkEAwfq6NFuhpGL6hDA7MvlyY1KiZ0cHetPUX+PgdNqy2DA+1Sv4i7gm +Wd/uA651K7aPXuUaf9dKtPCmZwI4M6SEsQJBALW89HTqP7niYoDEEnITdPaghxHk +gptERUln6lGo1L1CLus3gSI/JHyMLo+7scgAnEwTD62GRKhX0Ubwt+ymfTECQAY5 +fHYnppU20+EgBxZIqOIFCc8UmWnYmE0Ha/Fz/x8u1SVUBuK84wYpSGL32yyu7ATY +hzQo/W229zABAzqtAdECQQCUdB7IBFpPnsfv/EUBFX7X/7zAc9JpACmu9It5ju8C +KIsMuz/02D+TQoJNjdAngBM+4AJDIaGFgTMIfaDMh5L7 +-----END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/bug65729.phpt b/ext/openssl/tests/bug65729.phpt new file mode 100644 index 0000000000000..c0ee4443ebee5 --- /dev/null +++ b/ext/openssl/tests/bug65729.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #65729: CN_match gives false positive when wildcard is used +--SKIPIF-- + array( + 'verify_peer' => true, + 'allow_self_signed' => true, + 'CN_match' => $expected_name, + ) + )); + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + } +} else { + @pcntl_wait($status); + foreach ($expected_names as $name) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +Warning: stream_socket_client(): Peer certificate CN=`*.test.com' did not match expected CN=`foo.test.com.sg' in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) +resource(%d) of type (stream) +resource(%d) of type (stream) + +Warning: stream_socket_client(): Peer certificate CN=`*.test.com' did not match expected CN=`foo.bar.test.com' in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt b/ext/openssl/tests/openssl_peer_fingerprint.phpt new file mode 100644 index 0000000000000..2960dffae506e --- /dev/null +++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt @@ -0,0 +1,62 @@ +--TEST-- +Testing peer fingerprint on connection +--SKIPIF-- + array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'capture_peer_cert' => true, + 'peer_fingerprint' => '81cafc260aa8d82956ebc6212a362ece', + ) + ) + ); + // should be: 81cafc260aa8d82956ebc6212a362ecc + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + + $contextC = stream_context_create( + array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'capture_peer_cert' => true, + 'peer_fingerprint' => array( + 'sha256' => '78ea579f2c3b439359dec5dac9d445108772927427c4780037e87df3799a0aa0', + ), + ) + ) + ); + + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); +} else { + @pcntl_wait($status); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +} +--EXPECTF-- +Warning: stream_socket_client(): Peer fingerprint doesn't match in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) +resource(9) of type (stream) diff --git a/ext/openssl/tests/openssl_spki_export.phpt b/ext/openssl/tests/openssl_spki_export.phpt new file mode 100644 index 0000000000000..59332f70a5ca7 --- /dev/null +++ b/ext/openssl/tests/openssl_spki_export.phpt @@ -0,0 +1,62 @@ +--TEST-- +Testing openssl_spki_export() +Creates SPKAC for all available key sizes & signature algorithms and exports public key +--SKIPIF-- + +--FILE-- +1024, + '2048'=>2048, + '4096'=>4096); + +/* array of available hashings to test */ +$algo = array('md4'=>OPENSSL_ALGO_MD4, + 'md5'=>OPENSSL_ALGO_MD5, + 'sha1'=>OPENSSL_ALGO_SHA1, + 'sha224'=>OPENSSL_ALGO_SHA224, + 'sha256'=>OPENSSL_ALGO_SHA256, + 'sha384'=>OPENSSL_ALGO_SHA384, + 'sha512'=>OPENSSL_ALGO_SHA512, + 'rmd160'=>OPENSSL_ALGO_RMD160); + +/* loop over key sizes for test */ +foreach($ksize as $k => $v) { + + /* generate new private key of specified size to use for tests */ + $pkey = openssl_pkey_new(array('digest_alg' => 'sha512', + 'private_key_type' => OPENSSL_KEYTYPE_RSA, + 'private_key_bits' => $v)); + openssl_pkey_export($pkey, $pass); + + /* loop to create and verify results */ + foreach($algo as $key => $value) { + $spkac = openssl_spki_new($pkey, _uuid(), $value); + echo openssl_spki_export(preg_replace('/SPKAC=/', '', $spkac)); + } + openssl_free_key($pkey); +} + +/* generate a random challenge */ +function _uuid() +{ + return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff)); +} + +?> +--EXPECTREGEX-- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- +\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\- diff --git a/ext/openssl/tests/openssl_spki_export_challenge.phpt b/ext/openssl/tests/openssl_spki_export_challenge.phpt new file mode 100644 index 0000000000000..71ef62edd5083 --- /dev/null +++ b/ext/openssl/tests/openssl_spki_export_challenge.phpt @@ -0,0 +1,105 @@ +--TEST-- +Testing openssl_spki_export_challenge() +Creates SPKAC for all available key sizes & signature algorithms and exports challenge +--INI-- +error_reporting=0 +--SKIPIF-- + +--FILE-- +1024, + '2048'=>2048, + '4096'=>4096); + +/* array of available hashings to test */ +$algo = array('md4'=>OPENSSL_ALGO_MD4, + 'md5'=>OPENSSL_ALGO_MD5, + 'sha1'=>OPENSSL_ALGO_SHA1, + 'sha224'=>OPENSSL_ALGO_SHA224, + 'sha256'=>OPENSSL_ALGO_SHA256, + 'sha384'=>OPENSSL_ALGO_SHA384, + 'sha512'=>OPENSSL_ALGO_SHA512, + 'rmd160'=>OPENSSL_ALGO_RMD160); + +/* loop over key sizes for test */ +foreach($ksize as $k => $v) { + + /* generate new private key of specified size to use for tests */ + $pkey = openssl_pkey_new(array('digest_alg' => 'sha512', + 'private_key_type' => OPENSSL_KEYTYPE_RSA, + 'private_key_bits' => $v)); + openssl_pkey_export($pkey, $pass); + + /* loop to create and verify results */ + foreach($algo as $key => $value) { + $spkac = openssl_spki_new($pkey, _uuid(), $value); + var_dump(openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spkac))); + var_dump(openssl_spki_export_challenge($spkac.'Make it fail')); + } + openssl_free_key($pkey); +} + +/* generate a random challenge */ +function _uuid() +{ + return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff)); +} + +?> +--EXPECTREGEX-- +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) +string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\" +bool\(false\) diff --git a/ext/openssl/tests/openssl_spki_new.phpt b/ext/openssl/tests/openssl_spki_new.phpt new file mode 100644 index 0000000000000..e40f9bf28e253 --- /dev/null +++ b/ext/openssl/tests/openssl_spki_new.phpt @@ -0,0 +1,77 @@ +--TEST-- +Testing openssl_spki_new() +Tests SPKAC for all available private key sizes & hashing algorithms +--SKIPIF-- + +--FILE-- +1024, + '2048'=>2048, + '4096'=>4096); + +/* array of available hashings to test */ +$algo = array('md4'=>OPENSSL_ALGO_MD4, + 'md5'=>OPENSSL_ALGO_MD5, + 'sha1'=>OPENSSL_ALGO_SHA1, + 'sha224'=>OPENSSL_ALGO_SHA224, + 'sha256'=>OPENSSL_ALGO_SHA256, + 'sha384'=>OPENSSL_ALGO_SHA384, + 'sha512'=>OPENSSL_ALGO_SHA512, + 'rmd160'=>OPENSSL_ALGO_RMD160); + +/* loop over key sizes for test */ +foreach($ksize as $k => $v) { + + /* generate new private key of specified size to use for tests */ + $pkey = openssl_pkey_new(array('digest_alg' => 'sha512', + 'private_key_type' => OPENSSL_KEYTYPE_RSA, + 'private_key_bits' => $v)); + openssl_pkey_export($pkey, $pass); + + /* loop to create and verify results */ + foreach($algo as $key => $value) { + var_dump(openssl_spki_new($pkey, _uuid(), $value)); + } + openssl_free_key($pkey); +} + +/* generate a random challenge */ +function _uuid() +{ + return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff)); +} + +?> +--EXPECTF-- +string(478) "%s" +string(478) "%s" +string(478) "%s" +string(478) "%s" +string(478) "%s" +string(478) "%s" +string(478) "%s" +string(474) "%s" +string(830) "%s" +string(830) "%s" +string(830) "%s" +string(830) "%s" +string(830) "%s" +string(830) "%s" +string(830) "%s" +string(826) "%s" +string(1510) "%s" +string(1510) "%s" +string(1510) "%s" +string(1510) "%s" +string(1510) "%s" +string(1510) "%s" +string(1510) "%s" +string(1506) "%s" diff --git a/ext/openssl/tests/openssl_spki_verify.phpt b/ext/openssl/tests/openssl_spki_verify.phpt new file mode 100644 index 0000000000000..1ee573fd3f056 --- /dev/null +++ b/ext/openssl/tests/openssl_spki_verify.phpt @@ -0,0 +1,105 @@ +--TEST-- +Testing openssl_spki_verify() +Creates SPKAC for all available key sizes & signature algorithms and tests for valid signature +--INI-- +error_reporting=0 +--SKIPIF-- + +--FILE-- +1024, + '2048'=>2048, + '4096'=>4096); + +/* array of available hashings to test */ +$algo = array('md4'=>OPENSSL_ALGO_MD4, + 'md5'=>OPENSSL_ALGO_MD5, + 'sha1'=>OPENSSL_ALGO_SHA1, + 'sha224'=>OPENSSL_ALGO_SHA224, + 'sha256'=>OPENSSL_ALGO_SHA256, + 'sha384'=>OPENSSL_ALGO_SHA384, + 'sha512'=>OPENSSL_ALGO_SHA512, + 'rmd160'=>OPENSSL_ALGO_RMD160); + +/* loop over key sizes for test */ +foreach($ksize as $k => $v) { + + /* generate new private key of specified size to use for tests */ + $pkey = openssl_pkey_new(array('digest_alg' => 'sha512', + 'private_key_type' => OPENSSL_KEYTYPE_RSA, + 'private_key_bits' => $v)); + openssl_pkey_export($pkey, $pass); + + /* loop to create and verify results */ + foreach($algo as $key => $value) { + $spkac = openssl_spki_new($pkey, _uuid(), $value); + var_dump(openssl_spki_verify(preg_replace('/SPKAC=/', '', $spkac))); + var_dump(openssl_spki_verify($spkac.'Make it fail')); + } + openssl_free_key($pkey); +} + +/* generate a random challenge */ +function _uuid() +{ + return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, + mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), + mt_rand(0, 0xffff), mt_rand(0, 0xffff)); +} + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) \ No newline at end of file diff --git a/ext/openssl/tests/openssl_x509_fingerprint.phpt b/ext/openssl/tests/openssl_x509_fingerprint.phpt new file mode 100644 index 0000000000000..6cd464a894872 --- /dev/null +++ b/ext/openssl/tests/openssl_x509_fingerprint.phpt @@ -0,0 +1,47 @@ +--TEST-- +Testing openssl_x509_fingerprint() +--SKIPIF-- + +--FILE-- + array( + 'local_cert' => __DIR__ . '/san-cert.pem', + 'allow_self_signed' => true, + ), +)); + +$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr, + STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context); + + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} else if ($pid) { + $contextC = stream_context_create( + array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/san-ca.pem', + 'CN_match' => 'example.org', + ) + ) + ); + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + + $contextC = stream_context_create(array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/san-ca.pem', + 'CN_match' => 'moar.example.org', + ) + )); + + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + +} else { + @pcntl_wait($status); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +} +--EXPECTF-- +resource(%d) of type (stream) + +Warning: stream_socket_client(): Unable to locate peer certificate CN in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) diff --git a/ext/openssl/tests/streams_crypto_method.pem b/ext/openssl/tests/streams_crypto_method.pem new file mode 100644 index 0000000000000..9d754d460d57c --- /dev/null +++ b/ext/openssl/tests/streams_crypto_method.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx +HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN +MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu +ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB +ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy +V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6 +JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S +S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R +aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E +1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy +NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho ++Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ +JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0 +Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7 +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc= +-----END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/streams_crypto_method.phpt b/ext/openssl/tests/streams_crypto_method.phpt new file mode 100644 index 0000000000000..97a6e9ee8ba85 --- /dev/null +++ b/ext/openssl/tests/streams_crypto_method.phpt @@ -0,0 +1,77 @@ +--TEST-- +Specific crypto method for ssl:// transports. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Hello World! diff --git a/ext/openssl/tests/tlsv1.1_wrapper_001.phpt b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt new file mode 100644 index 0000000000000..56211f0b965e0 --- /dev/null +++ b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt @@ -0,0 +1,46 @@ +--TEST-- +tlsv1.1 stream wrapper +--SKIPIF-- + array( + 'local_cert' => __DIR__ . '/streams_crypto_method.pem', +))); + +$server = stream_socket_server('tlsv1.1://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); +var_dump($server); + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} elseif ($pid) { + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(array('ssl' => array( + 'verify_peer' => false + ))); + + $client = stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + +} else { + @pcntl_wait($status); + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +resource(%d) of type (stream) +resource(%d) of type (stream) +bool(false) +bool(false) diff --git a/ext/openssl/tests/tlsv1.2_wrapper_002.phpt b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt new file mode 100644 index 0000000000000..cb3f4106c727e --- /dev/null +++ b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt @@ -0,0 +1,46 @@ +--TEST-- +tlsv1.2 stream wrapper +--SKIPIF-- + array( + 'local_cert' => __DIR__ . '/streams_crypto_method.pem', +))); + +$server = stream_socket_server('tlsv1.2://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); +var_dump($server); + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} elseif ($pid) { + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(array('ssl' => array( + 'verify_peer' => false + ))); + + $client = stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + +} else { + @pcntl_wait($status); + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +resource(%d) of type (stream) +resource(%d) of type (stream) +bool(false) +bool(false) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index a1a7ffc3f4bdc..2e7f0cdc3f676 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -309,7 +309,7 @@ static inline int php_openssl_setup_crypto(php_stream *stream, php_stream_xport_crypto_param *cparam TSRMLS_DC) { - SSL_METHOD *method; + const SSL_METHOD *method; long ssl_ctx_options = SSL_OP_ALL; if (sslsock->ssl_handle) { @@ -346,6 +346,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream, sslsock->is_client = 1; method = TLSv1_client_method(); break; + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 1; + method = TLSv1_1_client_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 1; + method = TLSv1_2_client_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif case STREAM_CRYPTO_METHOD_SSLv23_SERVER: sslsock->is_client = 0; method = SSLv23_server_method(); @@ -367,6 +385,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream, sslsock->is_client = 0; method = TLSv1_server_method(); break; + case STREAM_CRYPTO_METHOD_TLSv1_1_SERVER: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 0; + method = TLSv1_1_server_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif + case STREAM_CRYPTO_METHOD_TLSv1_2_SERVER: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 0; + method = TLSv1_2_server_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif default: return -1; @@ -667,6 +703,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ case STREAM_CRYPTO_METHOD_TLS_CLIENT: sock->method = STREAM_CRYPTO_METHOD_TLS_SERVER; break; + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_TLSv1_1_SERVER; + break; + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; + break; default: break; } @@ -853,8 +895,32 @@ php_stream_ops php_openssl_socket_ops = { php_openssl_sockop_set_option, }; -static char * get_sni(php_stream_context *ctx, char *resourcename, long resourcenamelen, int is_persistent TSRMLS_DC) { +static int get_crypto_method(php_stream_context *ctx) { + if (ctx) { + zval **val = NULL; + long crypto_method; + + if (php_stream_context_get_option(ctx, "ssl", "crypto_method", &val) == SUCCESS) { + convert_to_long_ex(val); + crypto_method = (long)Z_LVAL_PP(val); + + switch (crypto_method) { + case STREAM_CRYPTO_METHOD_SSLv2_CLIENT: + case STREAM_CRYPTO_METHOD_SSLv3_CLIENT: + case STREAM_CRYPTO_METHOD_SSLv23_CLIENT: + case STREAM_CRYPTO_METHOD_TLS_CLIENT: + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: + return crypto_method; + } + + } + } + + return STREAM_CRYPTO_METHOD_SSLv23_CLIENT; +} +static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) { php_url *url; if (ctx) { @@ -900,8 +966,8 @@ static char * get_sni(php_stream_context *ctx, char *resourcename, long resource return NULL; } -php_stream *php_openssl_ssl_socket_factory(const char *proto, long protolen, - char *resourcename, long resourcenamelen, +php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, + const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, php_stream_context *context STREAMS_DC TSRMLS_DC) @@ -939,7 +1005,12 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, long protolen, if (strncmp(proto, "ssl", protolen) == 0) { sslsock->enable_on_connect = 1; - sslsock->method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT; + + /* General ssl:// transports can use a number + * of crypto methods. The actual methhod can be + * provided in the streams context options. + */ + sslsock->method = get_crypto_method(context); } else if (strncmp(proto, "sslv2", protolen) == 0) { #ifdef OPENSSL_NO_SSL2 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library PHP is linked against"); @@ -954,8 +1025,24 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, long protolen, } else if (strncmp(proto, "tls", protolen) == 0) { sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_TLS_CLIENT; + } else if (strncmp(proto, "tlsv1.1", protolen) == 0) { +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->enable_on_connect = 1; + sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return NULL; +#endif + } else if (strncmp(proto, "tlsv1.2", protolen) == 0) { +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->enable_on_connect = 1; + sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return NULL; +#endif } - + return stream; } diff --git a/ext/pdo/Makefile.frag b/ext/pdo/Makefile.frag index 5ba5f80840ec6..dc25c9f70b76c 100644 --- a/ext/pdo/Makefile.frag +++ b/ext/pdo/Makefile.frag @@ -2,7 +2,8 @@ phpincludedir=$(prefix)/include/php PDO_HEADER_FILES= \ php_pdo.h \ - php_pdo_driver.h + php_pdo_driver.h \ + php_pdo_error.h $(srcdir)/pdo_sql_parser.c: $(srcdir)/pdo_sql_parser.re diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index ac8d29a95cad1..67c6c58ed96b9 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -101,7 +101,7 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate } /* }}} */ -void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ +PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ { pdo_error_type *pdo_err = &dbh->error_code; const char *msg = "<>"; @@ -1328,16 +1328,12 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC) } else { ifunc->required_num_args = info->required_num_args; } - if (info->pass_rest_by_reference) { - if (info->pass_rest_by_reference == ZEND_SEND_PREFER_REF) { - ifunc->fn_flags |= ZEND_ACC_PASS_REST_PREFER_REF; - } else { - ifunc->fn_flags |= ZEND_ACC_PASS_REST_BY_REFERENCE; - } - } if (info->return_reference) { ifunc->fn_flags |= ZEND_ACC_RETURN_REFERENCE; } + if (funcs->arg_info[funcs->num_args].is_variadic) { + ifunc->fn_flags |= ZEND_ACC_VARIADIC; + } } else { ifunc->arg_info = NULL; ifunc->num_args = 0; diff --git a/ext/pdo/php_pdo_error.h b/ext/pdo/php_pdo_error.h new file mode 100644 index 0000000000000..387436af8fd22 --- /dev/null +++ b/ext/pdo/php_pdo_error.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 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_01.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: Wez Furlong | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_PDO_ERROR_H +#define PHP_PDO_ERROR_H + +#include "php_pdo_driver.h" + +PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC); + +#define PDO_DBH_CLEAR_ERR() do { \ + strlcpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \ + if (dbh->query_stmt) { \ + dbh->query_stmt = NULL; \ + zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \ + } \ +} while (0) +#define PDO_STMT_CLEAR_ERR() strcpy(stmt->error_code, PDO_ERR_NONE) +#define PDO_HANDLE_DBH_ERR() if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL TSRMLS_CC); } +#define PDO_HANDLE_STMT_ERR() if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); } + +#endif /* PHP_PDO_ERROR_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 + */ diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index 91d0bf0412f77..59dbaf9b0190a 100644 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -23,6 +23,8 @@ /* Stuff private to the PDO extension and not for consumption by PDO drivers * */ +#include "php_pdo_error.h" + extern HashTable pdo_driver_hash; extern zend_class_entry *pdo_exception_ce; PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC); @@ -55,19 +57,6 @@ zend_object_iterator *php_pdo_dbstmt_iter_get(zend_class_entry *ce, zval *object extern pdo_driver_t *pdo_find_driver(const char *name, int namelen); -extern void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC); - -#define PDO_DBH_CLEAR_ERR() do { \ - strlcpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \ - if (dbh->query_stmt) { \ - dbh->query_stmt = NULL; \ - zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \ - } \ -} while (0) -#define PDO_STMT_CLEAR_ERR() strcpy(stmt->error_code, PDO_ERR_NONE) -#define PDO_HANDLE_DBH_ERR() if (strcmp(dbh->error_code, PDO_ERR_NONE)) { pdo_handle_error(dbh, NULL TSRMLS_CC); } -#define PDO_HANDLE_STMT_ERR() if (strcmp(stmt->error_code, PDO_ERR_NONE)) { pdo_handle_error(stmt->dbh, stmt TSRMLS_CC); } - int pdo_sqlstate_init_error_table(void); void pdo_sqlstate_fini_error_table(void); const char *pdo_sqlstate_state_to_description(char *state); diff --git a/ext/pdo_firebird/CREDITS b/ext/pdo_firebird/CREDITS index a33294b69c0e6..60b917415db69 100644 --- a/ext/pdo_firebird/CREDITS +++ b/ext/pdo_firebird/CREDITS @@ -1,2 +1,2 @@ -Firebird/InterBase driver for PDO +Firebird driver for PDO Ard Biesheuvel diff --git a/ext/pdo_firebird/package2.xml b/ext/pdo_firebird/package2.xml index 5b5984c80fa56..b744d388bc0d5 100644 --- a/ext/pdo_firebird/package2.xml +++ b/ext/pdo_firebird/package2.xml @@ -5,9 +5,9 @@ http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> PDO_FIREBIRD pecl.php.net - Firebird/InterBase 6 driver for PDO - This extension provides a Firebird/InterBase driver for PDO. It supports -all versions of Firebird and InterBase versions 6 and up. + Firebird driver for PDO + This extension provides a Firebird driver for PDO. It supports +all versions of Firebird 2.1 and up. Ard Biesheuvel @@ -15,18 +15,17 @@ all versions of Firebird and InterBase versions 6 and up. abies@php.net yes - 2006-05-01 + 2013-09-01 - 0.3 - 0.3 + 1.0 + 1.0 - beta - beta + stable + stable PHP - To compile and run this module, you will need to have the main PDO module and Firebird's -or InterBase's client library installed on your system. + To compile and run this module, you will need to have the main PDO module and Firebird's client library installed on your system. Hope it works! @@ -49,7 +48,7 @@ Hope it works! - 5.0.3 + 5.3.27 1.4.0 diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 50136430a0db9..cb89809f023a0 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -27,8 +27,10 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" +#include "main/php_network.h" #include "pdo/php_pdo.h" #include "pdo/php_pdo_driver.h" +#include "pdo/php_pdo_error.h" #include "ext/standard/file.h" #undef PACKAGE_BUGREPORT @@ -60,7 +62,7 @@ static char * _pdo_pgsql_trim_message(const char *message, int persistent) return tmp; } -int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *file, int line TSRMLS_DC) /* {{{ */ +int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *msg, const char *file, int line TSRMLS_DC) /* {{{ */ { pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code; @@ -83,7 +85,10 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char * strcpy(*pdo_err, sqlstate); } - if (errmsg) { + if (msg) { + einfo->errmsg = estrdup(msg); + } + else if (errmsg) { einfo->errmsg = _pdo_pgsql_trim_message(errmsg, dbh->is_persistent); } @@ -91,7 +96,7 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char * zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s", *pdo_err, einfo->errcode, einfo->errmsg); } - + return errcode; } /* }}} */ @@ -535,11 +540,13 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); + /* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */ if (pg_fields) { - spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } else { - spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } /* Obtain db Handle */ @@ -583,7 +590,8 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray) query[query_len] = '\0'; if (PQputCopyData(H->server, query, query_len) != 1) { efree(query); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } zend_hash_move_forward_ex(Z_ARRVAL_P(pg_rows), &pos); @@ -593,22 +601,25 @@ static PHP_METHOD(PDO, pgsqlCopyFromArray) } if (PQputCopyEnd(H->server, NULL) != 1) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } while ((pgsql_result = PQgetResult(H->server))) { if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); command_failed = 1; } PQclear(pgsql_result); } + PDO_HANDLE_DBH_ERR(); RETURN_BOOL(!command_failed); } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); PQclear(pgsql_result); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -637,17 +648,20 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile) /* Obtain db Handler */ dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); - stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, FG(default_context)); + stream = php_stream_open_wrapper_ex(filename, "rb", ENFORCE_SAFE_MODE, NULL, FG(default_context)); if (!stream) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file"); + pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file"); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } + /* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */ if (pg_fields) { - spprintf(&query, 0, "COPY %s (%s) FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } else { - spprintf(&query, 0, "COPY %s FROM STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -674,8 +688,9 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile) while ((buf = php_stream_get_line(stream, NULL, 0, &line_len)) != NULL) { if (PQputCopyData(H->server, buf, line_len) != 1) { efree(buf); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "copy failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); php_stream_close(stream); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } efree(buf); @@ -683,23 +698,26 @@ static PHP_METHOD(PDO, pgsqlCopyFromFile) php_stream_close(stream); if (PQputCopyEnd(H->server, NULL) != 1) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "putcopyend failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } while ((pgsql_result = PQgetResult(H->server))) { if (PGRES_COMMAND_OK != PQresultStatus(pgsql_result)) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); command_failed = 1; } PQclear(pgsql_result); } + PDO_HANDLE_DBH_ERR(); RETURN_BOOL(!command_failed); } else { - PQclear(pgsql_result); php_stream_close(stream); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); + PQclear(pgsql_result); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -730,12 +748,14 @@ static PHP_METHOD(PDO, pgsqlCopyToFile) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); H = (pdo_pgsql_db_handle *)dbh->driver_data; - stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, FG(default_context)); + stream = php_stream_open_wrapper_ex(filename, "wb", ENFORCE_SAFE_MODE, NULL, FG(default_context)); if (!stream) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing"); + pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to open the file for writing"); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } @@ -743,10 +763,11 @@ static PHP_METHOD(PDO, pgsqlCopyToFile) PQclear(pgsql_result); } + /* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */ if (pg_fields) { - spprintf(&query, 0, "COPY %s (%s) TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } else { - spprintf(&query, 0, "COPY %s TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } pgsql_result = PQexec(H->server, query); efree(query); @@ -767,16 +788,18 @@ static PHP_METHOD(PDO, pgsqlCopyToFile) break; /* done */ } else if (ret > 0) { if (php_stream_write(stream, csv, ret) != ret) { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Unable to write to file"); + pdo_pgsql_error_msg(dbh, PGRES_FATAL_ERROR, "Unable to write to file"); PQfreemem(csv); php_stream_close(stream); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } else { PQfreemem(csv); } } else { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); php_stream_close(stream); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -788,8 +811,9 @@ static PHP_METHOD(PDO, pgsqlCopyToFile) RETURN_TRUE; } else { php_stream_close(stream); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); PQclear(pgsql_result); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -817,6 +841,7 @@ static PHP_METHOD(PDO, pgsqlCopyToArray) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -824,10 +849,11 @@ static PHP_METHOD(PDO, pgsqlCopyToArray) PQclear(pgsql_result); } + /* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */ if (pg_fields) { - spprintf(&query, 0, "COPY %s (%s) TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s (%s) TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } else { - spprintf(&query, 0, "COPY %s TO STDIN DELIMITERS E'%c' WITH NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); + spprintf(&query, 0, "COPY %s TO STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N")); } pgsql_result = PQexec(H->server, query); efree(query); @@ -851,7 +877,8 @@ static PHP_METHOD(PDO, pgsqlCopyToArray) add_next_index_stringl(return_value, csv, ret, 1); PQfreemem(csv); } else { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed: getline failed"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -860,8 +887,9 @@ static PHP_METHOD(PDO, pgsqlCopyToArray) PQclear(pgsql_result); } } else { + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, pdo_pgsql_sqlstate(pgsql_result)); PQclear(pgsql_result); - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "Copy command failed"); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } } @@ -878,6 +906,7 @@ static PHP_METHOD(PDO, pgsqlLOBCreate) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); H = (pdo_pgsql_db_handle *)dbh->driver_data; lfd = lo_creat(H->server, INV_READ|INV_WRITE); @@ -887,8 +916,9 @@ static PHP_METHOD(PDO, pgsqlLOBCreate) spprintf(&buf, 0, "%lu", (long) lfd); RETURN_STRING(buf, 0); } - - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } /* }}} */ @@ -924,6 +954,7 @@ static PHP_METHOD(PDO, pgsqlLOBOpen) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); H = (pdo_pgsql_db_handle *)dbh->driver_data; @@ -936,8 +967,10 @@ static PHP_METHOD(PDO, pgsqlLOBOpen) return; } } else { - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); } + + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } /* }}} */ @@ -964,17 +997,98 @@ static PHP_METHOD(PDO, pgsqlLOBUnlink) dbh = zend_object_store_get_object(getThis() TSRMLS_CC); PDO_CONSTRUCT_CHECK; + PDO_DBH_CLEAR_ERR(); H = (pdo_pgsql_db_handle *)dbh->driver_data; - + if (1 == lo_unlink(H->server, oid)) { RETURN_TRUE; } - pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000"); + + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL); + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } /* }}} */ +/* {{{ proto mixed PDO::pgsqlGetNotify([ int $result_type = PDO::FETCH_USE_DEFAULT] [, int $ms_timeout = 0 ]]) + Get asyncronous notification */ +static PHP_METHOD(PDO, pgsqlGetNotify) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + long result_type = PDO_FETCH_USE_DEFAULT; + long ms_timeout = 0; + PGnotify *pgsql_notify; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", + &result_type, &ms_timeout)) { + RETURN_FALSE; + } + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + if (result_type == PDO_FETCH_USE_DEFAULT) { + result_type = dbh->default_fetch_type; + } + + if (result_type != PDO_FETCH_BOTH && result_type != PDO_FETCH_ASSOC && result_type != PDO_FETCH_NUM) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid result type"); + RETURN_FALSE; + } + + if (ms_timeout < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid timeout"); + RETURN_FALSE; + } + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + PQconsumeInput(H->server); + pgsql_notify = PQnotifies(H->server); + + if (ms_timeout && !pgsql_notify) { + php_pollfd_for_ms(PQsocket(H->server), PHP_POLLREADABLE, ms_timeout); + + PQconsumeInput(H->server); + pgsql_notify = PQnotifies(H->server); + } + + if (!pgsql_notify) { + RETURN_FALSE; + } + + array_init(return_value); + if (result_type == PDO_FETCH_NUM || result_type == PDO_FETCH_BOTH) { + add_index_string(return_value, 0, pgsql_notify->relname, 1); + add_index_long(return_value, 1, pgsql_notify->be_pid); + } + if (result_type == PDO_FETCH_ASSOC || result_type == PDO_FETCH_BOTH) { + add_assoc_string(return_value, "message", pgsql_notify->relname, 1); + add_assoc_long(return_value, "pid", pgsql_notify->be_pid); + } + + PQfreemem(pgsql_notify); +} +/* }}} */ + +/* {{{ proto int PDO::pgsqlGetPid() + Get backend(server) pid */ +static PHP_METHOD(PDO, pgsqlGetPid) +{ + pdo_dbh_t *dbh; + pdo_pgsql_db_handle *H; + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + + H = (pdo_pgsql_db_handle *)dbh->driver_data; + + RETURN_LONG(PQbackendPID(H->server)); +} +/* }}} */ + static const zend_function_entry dbh_methods[] = { PHP_ME(PDO, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC) @@ -984,6 +1098,8 @@ static const zend_function_entry dbh_methods[] = { PHP_ME(PDO, pgsqlCopyFromFile, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlCopyToArray, NULL, ZEND_ACC_PUBLIC) PHP_ME(PDO, pgsqlCopyToFile, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlGetNotify, NULL, ZEND_ACC_PUBLIC) + PHP_ME(PDO, pgsqlGetPid, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 02a6717760cd6..5600a925411cc 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -83,9 +83,11 @@ typedef struct { extern pdo_driver_t pdo_pgsql_driver; -extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *file, int line TSRMLS_DC); -#define pdo_pgsql_error(d,e,z) _pdo_pgsql_error(d, NULL, e, z, __FILE__, __LINE__ TSRMLS_CC) -#define pdo_pgsql_error_stmt(s,e,z) _pdo_pgsql_error(s->dbh, s, e, z, __FILE__, __LINE__ TSRMLS_CC) +extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *sqlstate, const char *msg, const char *file, int line TSRMLS_DC); +#define pdo_pgsql_error(d,e,z) _pdo_pgsql_error(d, NULL, e, z, NULL, __FILE__, __LINE__ TSRMLS_CC) +#define pdo_pgsql_error_msg(d,e,m) _pdo_pgsql_error(d, NULL, e, NULL, m, __FILE__, __LINE__ TSRMLS_CC) +#define pdo_pgsql_error_stmt(s,e,z) _pdo_pgsql_error(s->dbh, s, e, z, NULL, __FILE__, __LINE__ TSRMLS_CC) +#define pdo_pgsql_error_stmt_msg(s,e,m) _pdo_pgsql_error(s->dbh, s, e, NULL, m, __FILE__, __LINE__ TSRMLS_CC) extern struct pdo_stmt_methods pgsql_stmt_methods; diff --git a/ext/pdo_pgsql/tests/copy_from.phpt b/ext/pdo_pgsql/tests/copy_from.phpt index 10967b0fe9e34..de1140dfea712 100644 --- a/ext/pdo_pgsql/tests/copy_from.phpt +++ b/ext/pdo_pgsql/tests/copy_from.phpt @@ -16,8 +16,6 @@ $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); $db->exec('CREATE TABLE test (a integer not null primary key, b text, c integer)'); -try { - echo "Preparing test file and array for CopyFrom tests\n"; $tableRows = array(); @@ -68,10 +66,13 @@ $db->rollback(); echo "Testing pgsqlCopyFromArray() with error\n"; $db->beginTransaction(); -var_dump($db->pgsqlCopyFromArray('test_error',$tableRowsWithDifferentNullValuesAndSelectedFields,";","NULL",'a,c')); +try { + var_dump($db->pgsqlCopyFromArray('test_error',$tableRowsWithDifferentNullValuesAndSelectedFields,";","NULL",'a,c')); +} catch (Exception $e) { + echo "Exception: {$e->getMessage()}\n"; +} $db->rollback(); - echo "Testing pgsqlCopyFromFile() with default parameters\n"; $db->beginTransaction(); var_dump($db->pgsqlCopyFromFile('test',$filename)); @@ -102,14 +103,21 @@ $db->rollback(); echo "Testing pgsqlCopyFromFile() with error\n"; $db->beginTransaction(); -var_dump($db->pgsqlCopyFromFile('test_error',$filenameWithDifferentNullValuesAndSelectedFields,";","NULL",'a,c')); +try { + var_dump($db->pgsqlCopyFromFile('test_error',$filenameWithDifferentNullValuesAndSelectedFields,";","NULL",'a,c')); +} catch (Exception $e) { + echo "Exception: {$e->getMessage()}\n"; +} $db->rollback(); +echo "Testing pgsqlCopyFromFile() with non existing file\n"; +$db->beginTransaction(); +try { + var_dump($db->pgsqlCopyFromFile('test',"nonexisting/foo.csv",";","NULL",'a,c')); } catch (Exception $e) { - /* catch exceptions so that we can show the relative error */ - echo "Exception! at line ", $e->getLine(), "\n"; - var_dump($e->getMessage()); + echo "Exception: {$e->getMessage()}\n"; } +$db->rollback(); // Clean up foreach (array($filename, $filenameWithDifferentNullValues, $filenameWithDifferentNullValuesAndSelectedFields) as $f) { @@ -251,7 +259,7 @@ array(6) { NULL } Testing pgsqlCopyFromArray() with error -bool(false) +Exception: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "test_error" does not exist Testing pgsqlCopyFromFile() with default parameters bool(true) array(6) { @@ -385,4 +393,7 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with error -bool(false) +Exception: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "test_error" does not exist +Testing pgsqlCopyFromFile() with non existing file +Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file + diff --git a/ext/pdo_pgsql/tests/copy_to.phpt b/ext/pdo_pgsql/tests/copy_to.phpt index 1dc7d1de33ed5..7bc46c6e0b6e2 100644 --- a/ext/pdo_pgsql/tests/copy_to.phpt +++ b/ext/pdo_pgsql/tests/copy_to.phpt @@ -17,7 +17,6 @@ $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); $db->exec('CREATE TABLE test (a integer not null primary key, b text, c integer)'); $db->beginTransaction(); -try { echo "Preparing test table for CopyTo tests\n"; $stmt = $db->prepare("INSERT INTO test (a, b, c) values (?, ?, ?)"); @@ -42,8 +41,11 @@ echo "Testing pgsqlCopyToArray() with only selected fields\n"; var_dump($db->pgsqlCopyToArray('test',";","NULL",'a,c')); echo "Testing pgsqlCopyToArray() with error\n"; -var_dump($db->pgsqlCopyToArray('test_error')); - +try { + var_dump($db->pgsqlCopyToArray('test_error')); +} catch (Exception $e) { + echo "Exception: {$e->getMessage()}\n"; +} echo "Testing pgsqlCopyToFile() with default parameters\n"; @@ -58,14 +60,19 @@ var_dump($db->pgsqlCopyToFile('test',$filename,";","NULL",'a,c')); echo file_get_contents($filename); echo "Testing pgsqlCopyToFile() with error\n"; -var_dump($db->pgsqlCopyToFile('test_error',$filename)); - +try { + var_dump($db->pgsqlCopyToFile('test_error',$filename)); +} catch (Exception $e) { + echo "Exception: {$e->getMessage()}\n"; +} +echo "Testing pgsqlCopyToFile() to unwritable file\n"; +try { + var_dump($db->pgsqlCopyToFile('test', 'nonexistent/foo.csv')); } catch (Exception $e) { - /* catch exceptions so that we can show the relative error */ - echo "Exception! at line ", $e->getLine(), "\n"; - var_dump($e->getMessage()); + echo "Exception: {$e->getMessage()}\n"; } + if(isset($filename)) { @unlink($filename); } @@ -109,7 +116,7 @@ array(3) { " } Testing pgsqlCopyToArray() with error -bool(false) +Exception: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "test_error" does not exist Testing pgsqlCopyToFile() with default parameters bool(true) 0 test insert 0 \N @@ -126,4 +133,7 @@ bool(true) 1;NULL 2;NULL Testing pgsqlCopyToFile() with error -bool(false) \ No newline at end of file +Exception: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "test_error" does not exist +Testing pgsqlCopyToFile() to unwritable file +Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file for writing + diff --git a/ext/pdo_pgsql/tests/getnotify.phpt b/ext/pdo_pgsql/tests/getnotify.phpt new file mode 100644 index 0000000000000..c093e0357a5df --- /dev/null +++ b/ext/pdo_pgsql/tests/getnotify.phpt @@ -0,0 +1,109 @@ +--TEST-- +PDO PgSQL LISTEN/NOTIFY support +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +// pgsqlGetPid should return something meaningful +$pid = $db->pgsqlGetPid(); +var_dump($pid > 0); + +// No listen, no notifies +var_dump($db->pgsqlGetNotify()); + +// Listen started, no notifies +$db->exec("LISTEN notifies_phpt"); +var_dump($db->pgsqlGetNotify()); + +// No parameters, use default PDO::FETCH_NUM +$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_NUM); +$db->exec("NOTIFY notifies_phpt"); +$notify = $db->pgsqlGetNotify(); +var_dump(count($notify)); +var_dump($notify[0]); +var_dump($notify[1] == $pid); + +// No parameters, use default PDO::FETCH_ASSOC +$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); +$db->exec("NOTIFY notifies_phpt"); +$notify = $db->pgsqlGetNotify(); +var_dump(count($notify)); +var_dump($notify['message']); +var_dump($notify['pid'] == $pid); + +// Test PDO::FETCH_NUM as parameter +$db->exec("NOTIFY notifies_phpt"); +$notify = $db->pgsqlGetNotify(PDO::FETCH_NUM); +var_dump(count($notify)); +var_dump($notify[0]); +var_dump($notify[1] == $pid); + +// Test PDO::FETCH_ASSOC as parameter +$db->exec("NOTIFY notifies_phpt"); +$notify = $db->pgsqlGetNotify(PDO::FETCH_ASSOC); +var_dump(count($notify)); +var_dump($notify['message']); +var_dump($notify['pid'] == $pid); + +// Test PDO::FETCH_BOTH as parameter +$db->exec("NOTIFY notifies_phpt"); +$notify = $db->pgsqlGetNotify(PDO::FETCH_BOTH); +var_dump(count($notify)); +var_dump($notify['message']); +var_dump($notify['pid'] == $pid); +var_dump($notify[0]); +var_dump($notify[1] == $pid); + +// Verify that there are no notifies queued +var_dump($db->pgsqlGetNotify()); + + +// Test second parameter, should wait 2 seconds because no notify is queued +$t = microtime(1); +$notify = $db->pgsqlGetNotify(PDO::FETCH_ASSOC, 1000); +var_dump((microtime(1) - $t) >= 1); +var_dump($notify); + +// Test second parameter, should return immediately because a notify is queued +$db->exec("NOTIFY notifies_phpt"); +$t = microtime(1); +$notify = $db->pgsqlGetNotify(PDO::FETCH_ASSOC, 5000); +var_dump((microtime(1) - $t) < 1); +var_dump(count($notify)); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(false) +int(2) +string(13) "notifies_phpt" +bool(true) +int(2) +string(13) "notifies_phpt" +bool(true) +int(2) +string(13) "notifies_phpt" +bool(true) +int(2) +string(13) "notifies_phpt" +bool(true) +int(4) +string(13) "notifies_phpt" +bool(true) +string(13) "notifies_phpt" +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +int(2) diff --git a/ext/pgsql/tests/00version.phpt b/ext/pgsql/tests/00version.phpt new file mode 100644 index 0000000000000..d72d9e1f212b7 --- /dev/null +++ b/ext/pgsql/tests/00version.phpt @@ -0,0 +1,30 @@ +--TEST-- +PostgreSQL version +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(3) { + ["client"]=> + string(%d) "%s" + ["protocol"]=> + int(%d) + ["server"]=> + string(%d) "%s" +} +string(%d) "%s" +OK diff --git a/ext/pgsql/tests/14pg_update_9.phpt b/ext/pgsql/tests/14pg_update_9.phpt index e766c1f3807c2..c33f1afbd6e45 100644 --- a/ext/pgsql/tests/14pg_update_9.phpt +++ b/ext/pgsql/tests/14pg_update_9.phpt @@ -1,5 +1,5 @@ --TEST-- -PostgreSQL pg_update() (9.0) +PostgreSQL pg_update() (9.0+) --SKIPIF-- abstract; - phar_zstr key; char *str_key; uint keylen; ulong unused; - if (FAILURE == zend_hash_has_more_elements(data)) { + if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(data, &str_key, &keylen, &unused, 0, NULL)) { return 0; } - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(data, &key, &keylen, &unused, 0, NULL)) { - return 0; - } - - PHAR_STR(key, str_key); zend_hash_move_forward(data); to_read = MIN(keylen, count); if (to_read == 0 || count < keylen) { - PHAR_STR_FREE(str_key); return 0; } memset(buf, 0, sizeof(php_stream_dirent)); memcpy(((php_stream_dirent *) buf)->d_name, str_key, to_read); - PHAR_STR_FREE(str_key); ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0'; return sizeof(php_stream_dirent); @@ -189,13 +181,12 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) { HashTable *data; int dirlen = strlen(dir); - phar_zstr key; char *entry, *found, *save, *str_key; uint keylen; ulong unused; ALLOC_HASHTABLE(data); - zend_hash_init(data, 64, zend_get_hash_value, NULL, 0); + zend_hash_init(data, 64, NULL, NULL, 0); if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || (dirlen >= sizeof(".phar")-1 && !memcmp(dir, ".phar", sizeof(".phar")-1))) { /* make empty root directory for empty phar */ @@ -207,15 +198,12 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) zend_hash_internal_pointer_reset(manifest); while (FAILURE != zend_hash_has_more_elements(manifest)) { - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) { + if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { break; } - PHAR_STR(key, str_key); - if (keylen <= (uint)dirlen) { if (keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) { - PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } @@ -226,7 +214,6 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) if (*dir == '/') { /* root directory */ if (keylen >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) { - PHAR_STR_FREE(str_key); /* do not add any magic entries to this directory */ if (SUCCESS != zend_hash_move_forward(manifest)) { break; @@ -246,19 +233,16 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) entry[keylen] = '\0'; } - PHAR_STR_FREE(str_key); goto PHAR_ADD_ENTRY; } else { if (0 != memcmp(str_key, dir, dirlen)) { /* entry in directory not found */ - PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } continue; } else { if (str_key[dirlen] != '/') { - PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } @@ -285,7 +269,6 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) entry[keylen - dirlen - 1] = '\0'; keylen = keylen - dirlen - 1; } - PHAR_STR_FREE(str_key); PHAR_ADD_ENTRY: if (keylen) { phar_add_empty(data, entry, keylen); @@ -315,12 +298,11 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) /** * Open a directory handle within a phar archive */ -php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ +php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ { php_url *resource = NULL; php_stream *ret; char *internal_file, *error, *str_key; - phar_zstr key; uint keylen; ulong unused; phar_archive_data *phar; @@ -401,17 +383,14 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) { if (HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex( - &phar->manifest, &key, &keylen, &unused, 0, NULL)) { - PHAR_STR(key, str_key); + &phar->manifest, &str_key, &keylen, &unused, 0, NULL)) { if (keylen > (uint)i_len && 0 == memcmp(str_key, internal_file, i_len)) { - PHAR_STR_FREE(str_key); /* directory found */ internal_file = estrndup(internal_file, i_len); php_url_free(resource); return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC); } - PHAR_STR_FREE(str_key); } if (SUCCESS != zend_hash_move_forward(&phar->manifest)) { @@ -428,7 +407,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char /** * Make a new directory within a phar archive */ -int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ +int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ { phar_entry_info entry, *e; phar_archive_data *phar = NULL; @@ -560,7 +539,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, in /** * Remove a directory within a phar archive */ -int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ +int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ { phar_entry_info *entry; phar_archive_data *phar = NULL; @@ -568,7 +547,6 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ int arch_len, entry_len; php_url *resource = NULL; uint host_len; - phar_zstr key; char *str_key; uint key_len; ulong unused; @@ -633,15 +611,12 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ if (!entry->is_deleted) { for (zend_hash_internal_pointer_reset(&phar->manifest); - HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL); - zend_hash_move_forward(&phar->manifest)) { - - PHAR_STR(key, str_key); - + HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->manifest, &str_key, &key_len, &unused, 0, NULL); + zend_hash_move_forward(&phar->manifest) + ) { if (key_len > path_len && memcmp(str_key, resource->path+1, path_len) == 0 && IS_SLASH(str_key[path_len])) { - PHAR_STR_FREE(str_key); php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); if (entry->is_temp_dir) { efree(entry->filename); @@ -650,19 +625,15 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ php_url_free(resource); return 0; } - PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); - HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL); + HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &key_len, &unused, 0, NULL); zend_hash_move_forward(&phar->virtual_dirs)) { - PHAR_STR(key, str_key); - if (key_len > path_len && memcmp(str_key, resource->path+1, path_len) == 0 && IS_SLASH(str_key[path_len])) { - PHAR_STR_FREE(str_key); php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); if (entry->is_temp_dir) { efree(entry->filename); @@ -671,7 +642,6 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ php_url_free(resource); return 0; } - PHAR_STR_FREE(str_key); } } diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index 9b07c9d799085..030fe6536e913 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -20,11 +20,11 @@ /* $Id$ */ BEGIN_EXTERN_C() -int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC); -int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); +int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC); +int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); #ifdef PHAR_DIRSTREAM -php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*filename,%20char%20*mode,%20int%20options%20TSRMLS_DC); +php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*filename,%20const%20char%20*mode,%20int%20options%20TSRMLS_DC); /* directory handlers */ static size_t phar_dir_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC); @@ -33,7 +33,7 @@ static int phar_dir_close(php_stream *stream, int close_handle TSRMLS_DC); static int phar_dir_flush(php_stream *stream TSRMLS_DC); static int phar_dir_seek( php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC); #else -php_stream* phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +php_stream* phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); #endif END_EXTERN_C() diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 13b3d6428e324..d4716bca914ea 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1639,7 +1639,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a php_stream_filter_append(&temp->writefilters, filter); - if (SUCCESS != phar_stream_copy_to_stream(fp, temp, PHP_STREAM_COPY_ALL, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(fp, temp, PHP_STREAM_COPY_ALL, NULL)) { if (err) { php_stream_close(temp); MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\", ext/zlib is buggy in PHP versions older than 5.2.6") @@ -1681,7 +1681,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a php_stream_filter_append(&temp->writefilters, filter); - if (SUCCESS != phar_stream_copy_to_stream(fp, temp, PHP_STREAM_COPY_ALL, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(fp, temp, PHP_STREAM_COPY_ALL, NULL)) { php_stream_close(temp); MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\" to temporary file") } @@ -1954,67 +1954,45 @@ int phar_detect_phar_fname_ext(const char *filename, int filename_len, const cha goto woohoo; } } else { - phar_zstr key; char *str_key; uint keylen; ulong unused; - zend_hash_internal_pointer_reset(&(PHAR_GLOBALS->phar_fname_map)); - - while (FAILURE != zend_hash_has_more_elements(&(PHAR_GLOBALS->phar_fname_map))) { - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &key, &keylen, &unused, 0, NULL)) { - break; - } - - PHAR_STR(key, str_key); - + for (zend_hash_internal_pointer_reset(&(PHAR_GLOBALS->phar_fname_map)); + HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &str_key, &keylen, &unused, 0, NULL); + zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)) + ) { if (keylen > (uint) filename_len) { - zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)); - PHAR_STR_FREE(str_key); continue; } if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen || filename[keylen] == '/' || filename[keylen] == '\0')) { - PHAR_STR_FREE(str_key); if (FAILURE == zend_hash_get_current_data(&(PHAR_GLOBALS->phar_fname_map), (void **) &pphar)) { break; } *ext_str = filename + (keylen - (*pphar)->ext_len); goto woohoo; } - - PHAR_STR_FREE(str_key); - zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)); } if (PHAR_G(manifest_cached)) { - zend_hash_internal_pointer_reset(&cached_phars); - - while (FAILURE != zend_hash_has_more_elements(&cached_phars)) { - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&cached_phars, &key, &keylen, &unused, 0, NULL)) { - break; - } - - PHAR_STR(key, str_key); - + for (zend_hash_internal_pointer_reset(&cached_phars); + HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&cached_phars, &str_key, &keylen, &unused, 0, NULL); + zend_hash_move_forward(&cached_phars) + ) { if (keylen > (uint) filename_len) { - zend_hash_move_forward(&cached_phars); - PHAR_STR_FREE(str_key); continue; } if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen || filename[keylen] == '/' || filename[keylen] == '\0')) { - PHAR_STR_FREE(str_key); if (FAILURE == zend_hash_get_current_data(&cached_phars, (void **) &pphar)) { break; } *ext_str = filename + (keylen - (*pphar)->ext_len); goto woohoo; } - PHAR_STR_FREE(str_key); - zend_hash_move_forward(&cached_phars); } } } @@ -2249,13 +2227,13 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ * * This is used by phar_parse_url() */ -int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC) /* {{{ */ +int phar_split_fname(const char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC) /* {{{ */ { const char *ext_str; #ifdef PHP_WIN32 char *save; #endif - int ext_len, free_filename = 0; + int ext_len; if (!strncasecmp(filename, "phar://", 7)) { filename += 7; @@ -2264,7 +2242,6 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le ext_len = 0; #ifdef PHP_WIN32 - free_filename = 1; save = filename; filename = estrndup(filename, filename_len); phar_unixify_path_separators(filename, filename_len); @@ -2280,10 +2257,9 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le #endif } - if (free_filename) { - efree(filename); - } - +#ifdef PHP_WIN32 + efree(filename); +#endif return FAILURE; } @@ -2306,9 +2282,9 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le *entry = estrndup("/", 1); } - if (free_filename) { - efree(filename); - } +#ifdef PHP_WIN32 + efree(filename); +#endif return SUCCESS; } @@ -2701,7 +2677,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, size_t written; if (!user_stub && phar->halt_offset && oldfile && !phar->is_brandnew) { - phar_stream_copy_to_stream(oldfile, newfile, phar->halt_offset, &written); + php_stream_copy_to_stream_ex(oldfile, newfile, phar->halt_offset, &written); newstub = NULL; } else { /* this is either a brand new phar or a default stub overwrite */ @@ -2889,7 +2865,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, return EOF; } php_stream_filter_append((&entry->cfp->writefilters), filter); - if (SUCCESS != phar_stream_copy_to_stream(file, entry->cfp, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(file, entry->cfp, entry->uncompressed_filesize, NULL)) { if (closeoldfile) { php_stream_close(oldfile); } @@ -3121,7 +3097,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, /* this will have changed for all files that have either changed compression or been modified */ entry->offset = entry->offset_abs = offset; offset += entry->compressed_filesize; - if (phar_stream_copy_to_stream(file, newfile, entry->compressed_filesize, &wrote) == FAILURE) { + if (php_stream_copy_to_stream_ex(file, newfile, entry->compressed_filesize, &wrote) == FAILURE) { if (closeoldfile) { php_stream_close(oldfile); } @@ -3267,7 +3243,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, } php_stream_filter_append(&phar->fp->writefilters, filter); - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); php_stream_close(phar->fp); @@ -3276,14 +3252,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, } else if (phar->flags & PHAR_FILE_COMPRESSED_BZ2) { filter = php_stream_filter_create("bzip2.compress", NULL, php_stream_is_persistent(phar->fp) TSRMLS_CC); php_stream_filter_append(&phar->fp->writefilters, filter); - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); php_stream_close(phar->fp); /* use the temp stream as our base */ phar->fp = newfile; } else { - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); /* we could also reopen the file in "rb" mode but there is no need for that */ php_stream_close(newfile); } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index fcfb6471844a0..359f25b4c635b 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -54,7 +54,7 @@ #ifndef PHP_WIN32 #include "TSRM/tsrm_strtok_r.h" #endif -#include "TSRM/tsrm_virtual_cwd.h" +#include "Zend/zend_virtual_cwd.h" #if HAVE_SPL #include "ext/spl/spl_array.h" #include "ext/spl/spl_directory.h" @@ -63,27 +63,11 @@ #include "ext/spl/spl_iterators.h" #endif #include "php_phar.h" -#ifdef HAVE_STDINT_H -#include -#endif #ifdef PHAR_HASH_OK #include "ext/hash/php_hash.h" #include "ext/hash/php_hash_sha.h" #endif -#ifndef E_RECOVERABLE_ERROR -# define E_RECOVERABLE_ERROR E_ERROR -#endif - -#ifndef pestrndup -# define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length))) -#endif - -#ifndef ALLOC_PERMANENT_ZVAL -# define ALLOC_PERMANENT_ZVAL(z) \ - (z) = (zval*)malloc(sizeof(zval)) -#endif - /* PHP_ because this is public information via MINFO */ #define PHP_PHAR_API_VERSION "1.1.1" /* x.y.z maps to 0xyz0 */ @@ -519,15 +503,6 @@ union _phar_entry_object { extern char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC); #endif -# define phar_stream_copy_to_stream(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC) - -typedef char *phar_zstr; -#define PHAR_STR(a, b) \ - b = a; -#define PHAR_ZSTR(a, b) \ - b = a; -#define PHAR_STR_FREE(a) - BEGIN_EXTERN_C() #ifdef PHP_WIN32 @@ -631,11 +606,11 @@ int phar_entry_delref(phar_entry_data *idata TSRMLS_DC); phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error, int security TSRMLS_DC); phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, char **error, int security TSRMLS_DC); -phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC); -int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC); +phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security TSRMLS_DC); +int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security TSRMLS_DC); int phar_flush(phar_archive_data *archive, char *user_stub, long len, int convert, char **error TSRMLS_DC); int phar_detect_phar_fname_ext(const char *filename, int filename_len, const char **ext_str, int *ext_len, int executable, int for_create, int is_complete TSRMLS_DC); -int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC); +int phar_split_fname(const char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len, int executable, int for_create TSRMLS_DC); typedef enum { pcr_use_query, diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 7d2922fbaa15c..7c11a48f9cc87 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1707,7 +1707,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ data->internal_file->fp_type = PHAR_UFP; data->internal_file->offset_abs = data->internal_file->offset = php_stream_tell(p_obj->fp); data->fp = NULL; - phar_stream_copy_to_stream(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); + php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize = php_stream_tell(p_obj->fp) - data->internal_file->offset; } @@ -1997,7 +1997,7 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS link = entry; } - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize, NULL)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", entry->phar->fname, entry->filename); return FAILURE; @@ -3651,7 +3651,7 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", filename); return; } - phar_stream_copy_to_stream(contents_file, data->fp, PHP_STREAM_COPY_ALL, &contents_len); + php_stream_copy_to_stream_ex(contents_file, data->fp, PHP_STREAM_COPY_ALL, &contents_len); } data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len; @@ -4224,7 +4224,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * return FAILURE; } - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), fp, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0 TSRMLS_CC), fp, entry->uncompressed_filesize, NULL)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", copying contents failed", entry->filename, fullpath); efree(fullpath); php_stream_close(fp); diff --git a/ext/phar/stream.c b/ext/phar/stream.c index f4197a5b11672..1b353e0d18c33 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -56,7 +56,7 @@ php_stream_wrapper php_stream_phar_wrapper = { /** * Open a phar file for streams API */ -php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*filename,%20char%20*mode,%20int%20options%20TSRMLS_DC) /* {{{ */ +php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*filename,%20const%20char%20*mode,%20int%20options%20TSRMLS_DC) /* {{{ */ { php_url *resource; char *arch = NULL, *entry = NULL, *error; @@ -155,7 +155,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, char *filename, char *mode, /** * used for fopen('phar://...') and company */ -static php_stream * phar_wrapper_open_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*path,%20char%20*mode,%20int%20options,%20char%20**opened_path,%20php_stream_context%20*context%20STREAMS_DC%20TSRMLS_DC) /* {{{ */ +static php_stream * phar_wrapper_open_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*path,%20const%20char%20*mode,%20int%20options,%20char%20**opened_path,%20php_stream_context%20*context%20STREAMS_DC%20TSRMLS_DC) /* {{{ */ { phar_archive_data *phar; phar_entry_data *idata; @@ -563,7 +563,7 @@ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_D /** * Stream wrapper stat implementation of stat() */ -static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, +static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) /* {{{ */ { php_url *resource = NULL; @@ -627,21 +627,16 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, } /* check for mounted directories */ if (phar->mounted_dirs.arBuckets && zend_hash_num_elements(&phar->mounted_dirs)) { - phar_zstr key; char *str_key; ulong unused; uint keylen; HashPosition pos; - zend_hash_internal_pointer_reset_ex(&phar->mounted_dirs, &pos); - while (FAILURE != zend_hash_has_more_elements_ex(&phar->mounted_dirs, &pos)) { - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, &pos)) { - break; - } - PHAR_STR(key, str_key); + for (zend_hash_internal_pointer_reset_ex(&phar->mounted_dirs, &pos); + HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &keylen, &unused, 0, &pos); + zend_hash_move_forward_ex(&phar->mounted_dirs, &pos) + ) { if ((int)keylen >= internal_file_len || strncmp(str_key, internal_file, keylen)) { - zend_hash_move_forward_ex(&phar->mounted_dirs, &pos); - PHAR_STR_FREE(str_key); continue; } else { char *test; @@ -649,17 +644,14 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf ssbi; if (SUCCESS != zend_hash_find(&phar->manifest, str_key, keylen, (void **) &entry)) { - PHAR_STR_FREE(str_key); goto free_resource; } - PHAR_STR_FREE(str_key); if (!entry->tmp || !entry->is_mounted) { goto free_resource; } test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, internal_file + keylen); if (SUCCESS != php_stream_stat_path(test, &ssbi)) { efree(test); - zend_hash_move_forward_ex(&phar->mounted_dirs, &pos); continue; } /* mount the file/directory just in time */ @@ -686,7 +678,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, /** * Unlink a file within a phar archive */ -static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ +static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ { php_url *resource; char *internal_file, *error; @@ -762,7 +754,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio } /* }}} */ -static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ +static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC) /* {{{ */ { php_url *resource_from, *resource_to; char *error; @@ -910,7 +902,6 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char /* Rename directory. Update all nested paths */ if (is_dir) { int key_type; - phar_zstr key, new_key; char *str_key, *new_str_key; uint key_len, new_key_len; ulong unused; @@ -918,12 +909,10 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char uint to_len = strlen(resource_to->path+1); for (zend_hash_internal_pointer_reset(&phar->manifest); - HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL)) && + HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &str_key, &key_len, &unused, 0, NULL)) && SUCCESS == zend_hash_get_current_data(&phar->manifest, (void **) &entry); - zend_hash_move_forward(&phar->manifest)) { - - PHAR_STR(key, str_key); - + zend_hash_move_forward(&phar->manifest) + ) { if (!entry->is_deleted && key_len > from_len && memcmp(str_key, resource_from->path+1, from_len) == 0 && @@ -941,18 +930,14 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char entry->filename = new_str_key; entry->filename_len = new_key_len; - PHAR_ZSTR(new_str_key, new_key); - zend_hash_update_current_key_ex(&phar->manifest, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); + zend_hash_update_current_key_ex(&phar->manifest, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); } - PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); - HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL)); - zend_hash_move_forward(&phar->virtual_dirs)) { - - PHAR_STR(key, str_key); - + HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &key_len, &unused, 0, NULL)); + zend_hash_move_forward(&phar->virtual_dirs) + ) { if (key_len >= from_len && memcmp(str_key, resource_from->path+1, from_len) == 0 && (key_len == from_len || IS_SLASH(str_key[from_len]))) { @@ -963,20 +948,16 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char memcpy(new_str_key + to_len, str_key + from_len, key_len - from_len); new_str_key[new_key_len] = 0; - PHAR_ZSTR(new_str_key, new_key); - zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); + zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); efree(new_str_key); } - PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->mounted_dirs); - HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &key_len, &unused, 0, NULL)) && + HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &key_len, &unused, 0, NULL)) && SUCCESS == zend_hash_get_current_data(&phar->mounted_dirs, (void **) &entry); - zend_hash_move_forward(&phar->mounted_dirs)) { - - PHAR_STR(key, str_key); - + zend_hash_move_forward(&phar->mounted_dirs) + ) { if (key_len >= from_len && memcmp(str_key, resource_from->path+1, from_len) == 0 && (key_len == from_len || IS_SLASH(str_key[from_len]))) { @@ -987,11 +968,9 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char memcpy(new_str_key + to_len, str_key + from_len, key_len - from_len); new_str_key[new_key_len] = 0; - PHAR_ZSTR(new_str_key, new_key); - zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); + zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); efree(new_str_key); } - PHAR_STR_FREE(str_key); } } diff --git a/ext/phar/stream.h b/ext/phar/stream.h index b22b67ab01749..0155759d12989 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -21,13 +21,13 @@ BEGIN_EXTERN_C() -php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*filename,%20char%20*mode,%20int%20options%20TSRMLS_DC); +php_url* phar_parse_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*filename,%20const%20char%20*mode,%20int%20options%20TSRMLS_DC); void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC); -static php_stream* phar_wrapper_open_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*path,%20char%20*mode,%20int%20options,%20char%20**opened_path,%20php_stream_context%20*context%20STREAMS_DC%20TSRMLS_DC); -static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC); -static int phar_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); -static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); +static php_stream* phar_wrapper_open_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*path,%20const%20char%20*mode,%20int%20options,%20char%20**opened_path,%20php_stream_context%20*context%20STREAMS_DC%20TSRMLS_DC); +static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); +static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); +static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); /* file/stream handlers */ static size_t phar_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 0e60e3db134b4..180675a9d23b8 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -783,7 +783,7 @@ static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ * return ZEND_HASH_APPLY_STOP; } - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), fp->new, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0 TSRMLS_CC), fp->new, entry->uncompressed_filesize, NULL)) { if (fp->error) { spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, entry->filename); } @@ -1288,7 +1288,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau if (!filter) { /* copy contents uncompressed rather than lose them */ - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_close(newfile); if (error) { spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname); @@ -1297,7 +1297,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau } php_stream_filter_append(&phar->fp->writefilters, filter); - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); php_stream_close(phar->fp); @@ -1308,14 +1308,14 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau filter = php_stream_filter_create("bzip2.compress", NULL, php_stream_is_persistent(phar->fp) TSRMLS_CC); php_stream_filter_append(&phar->fp->writefilters, filter); - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); php_stream_close(phar->fp); /* use the temp stream as our base */ phar->fp = newfile; } else { - phar_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); /* we could also reopen the file in "rb" mode but there is no need for that */ php_stream_close(newfile); } diff --git a/ext/phar/tests/031.phpt b/ext/phar/tests/031.phpt index 4d5988621de88..d458f068f5513 100644 --- a/ext/phar/tests/031.phpt +++ b/ext/phar/tests/031.phpt @@ -22,10 +22,10 @@ require $pname; ===DONE=== --CLEAN-- --EXPECTF-- string(25) "getMessage(); ===DONE=== --CLEAN-- --EXPECTF-- -phar "%sphar_oo_test.phar.php" does not have a signature===DONE=== \ No newline at end of file +phar "%s032.phar.php" does not have a signature===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/files/phar_oo_test.inc b/ext/phar/tests/files/phar_oo_test.inc index e92b4444c1572..45421568dee10 100644 --- a/ext/phar/tests/files/phar_oo_test.inc +++ b/ext/phar/tests/files/phar_oo_test.inc @@ -2,7 +2,8 @@ ini_set('date.timezone', 'GMT'); -$fname = dirname(__FILE__) . '/phar_oo_test.phar.php'; +$tname = basename(current(get_included_files()), ".php"); +$fname = dirname(__FILE__) . "/$tname.phar.php"; $pname = 'phar://' . $fname; $file = (binary)''; diff --git a/ext/phar/tests/phar_buildfromdirectory1.phpt b/ext/phar/tests/phar_buildfromdirectory1.phpt index 63e06fa474de8..957f246664f67 100644 --- a/ext/phar/tests/phar_buildfromdirectory1.phpt +++ b/ext/phar/tests/phar_buildfromdirectory1.phpt @@ -7,7 +7,7 @@ phar.require_hash=0 phar.readonly=0 --FILE-- buildFromDirectory(1); @@ -19,7 +19,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromdirectory2-win.phpt b/ext/phar/tests/phar_buildfromdirectory2-win.phpt index 9dbcf965e32ba..5ed890a48bfb1 100644 --- a/ext/phar/tests/phar_buildfromdirectory2-win.phpt +++ b/ext/phar/tests/phar_buildfromdirectory2-win.phpt @@ -11,7 +11,7 @@ phar.readonly=0 --FILE-- buildFromDirectory(1); } catch (Exception $e) { var_dump(get_class($e)); @@ -21,7 +21,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromdirectory2.phpt b/ext/phar/tests/phar_buildfromdirectory2.phpt index 639ff0bd4b77f..a33e50abbb0b7 100644 --- a/ext/phar/tests/phar_buildfromdirectory2.phpt +++ b/ext/phar/tests/phar_buildfromdirectory2.phpt @@ -11,7 +11,7 @@ phar.readonly=0 --FILE-- buildFromDirectory(1); } catch (Exception $e) { var_dump(get_class($e)); @@ -21,7 +21,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromdirectory3.phpt b/ext/phar/tests/phar_buildfromdirectory3.phpt index 2134cbdb5397a..921e39593ddc8 100644 --- a/ext/phar/tests/phar_buildfromdirectory3.phpt +++ b/ext/phar/tests/phar_buildfromdirectory3.phpt @@ -9,7 +9,7 @@ phar.readonly=0 buildFromDirectory('files', new stdClass); } catch (Exception $e) { var_dump(get_class($e)); @@ -19,7 +19,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromdirectory4.phpt b/ext/phar/tests/phar_buildfromdirectory4.phpt index 683ac4bbc8365..5ee2c33871a51 100644 --- a/ext/phar/tests/phar_buildfromdirectory4.phpt +++ b/ext/phar/tests/phar_buildfromdirectory4.phpt @@ -9,14 +9,14 @@ open_basedir= --FILE-- buildFromDirectory(dirname(__FILE__) . '/testdir'); + $phar = new Phar(dirname(__FILE__) . '/buildfromdirectory4.phar'); + $a = $phar->buildFromDirectory(dirname(__FILE__) . '/testdir4'); asort($a); var_dump($a); } catch (Exception $e) { @@ -24,28 +24,28 @@ try { echo $e->getMessage() . "\n"; } -var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory.phar')); +var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory4.phar')); ?> ===DONE=== --CLEAN-- --EXPECTF-- array(4) { ["file1.txt"]=> - string(%d) "%stestdir%cfile1.txt" + string(%d) "%stestdir4%cfile1.txt" ["file2.txt"]=> - string(%d) "%stestdir%cfile2.txt" + string(%d) "%stestdir4%cfile2.txt" ["file3.txt"]=> - string(%d) "%stestdir%cfile3.txt" + string(%d) "%stestdir4%cfile3.txt" ["file4.txt"]=> - string(%d) "%stestdir%cfile4.txt" + string(%d) "%stestdir4%cfile4.txt" } bool(true) ===DONE=== diff --git a/ext/phar/tests/phar_buildfromdirectory5.phpt b/ext/phar/tests/phar_buildfromdirectory5.phpt index 51e5cec6911af..f20c52ab91f95 100644 --- a/ext/phar/tests/phar_buildfromdirectory5.phpt +++ b/ext/phar/tests/phar_buildfromdirectory5.phpt @@ -8,14 +8,14 @@ phar.readonly=0 --FILE-- buildFromDirectory(dirname(__FILE__) . '/testdir', '/\.txt/'); + $phar = new Phar(dirname(__FILE__) . '/buildfromdirectory5.phar'); + $a = $phar->buildFromDirectory(dirname(__FILE__) . '/testdir5', '/\.txt/'); asort($a); var_dump($a); } catch (Exception $e) { @@ -23,28 +23,28 @@ try { echo $e->getMessage() . "\n"; } -var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory.phar')); +var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory5.phar')); ?> ===DONE=== --CLEAN-- --EXPECTF-- array(4) { ["file1.txt"]=> - string(%d) "%stestdir%cfile1.txt" + string(%d) "%stestdir5%cfile1.txt" ["file2.txt"]=> - string(%d) "%stestdir%cfile2.txt" + string(%d) "%stestdir5%cfile2.txt" ["file3.txt"]=> - string(%d) "%stestdir%cfile3.txt" + string(%d) "%stestdir5%cfile3.txt" ["file4.txt"]=> - string(%d) "%stestdir%cfile4.txt" + string(%d) "%stestdir5%cfile4.txt" } bool(true) ===DONE=== diff --git a/ext/phar/tests/phar_buildfromdirectory6.phpt b/ext/phar/tests/phar_buildfromdirectory6.phpt index 99566c192669e..5537ebac2358b 100644 --- a/ext/phar/tests/phar_buildfromdirectory6.phpt +++ b/ext/phar/tests/phar_buildfromdirectory6.phpt @@ -8,30 +8,30 @@ phar.readonly=0 --FILE-- buildFromDirectory(dirname(__FILE__) . '/testdir', '/\.php$/')); + $phar = new Phar(dirname(__FILE__) . '/buildfromdirectory6.phar'); + var_dump($phar->buildFromDirectory(dirname(__FILE__) . '/testdir6', '/\.php$/')); } catch (Exception $e) { var_dump(get_class($e)); echo $e->getMessage() . "\n"; } -var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory.phar')); +var_dump(file_exists(dirname(__FILE__) . '/buildfromdirectory6.phar')); ?> ===DONE=== --CLEAN-- --EXPECT-- array(0) { diff --git a/ext/phar/tests/phar_buildfromiterator1.phpt b/ext/phar/tests/phar_buildfromiterator1.phpt index 238ede6cbe160..0f656b64f2053 100644 --- a/ext/phar/tests/phar_buildfromiterator1.phpt +++ b/ext/phar/tests/phar_buildfromiterator1.phpt @@ -7,7 +7,7 @@ phar.require_hash=0 phar.readonly=0 --FILE-- buildFromIterator(1); @@ -19,7 +19,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator10.phpt b/ext/phar/tests/phar_buildfromiterator10.phpt index 024277ed0acc6..e6b9c025da8c8 100644 --- a/ext/phar/tests/phar_buildfromiterator10.phpt +++ b/ext/phar/tests/phar_buildfromiterator10.phpt @@ -11,7 +11,7 @@ phar.readonly=0 buildFromIterator(new RegexIterator($iter, '/_\d{3}\.phpt$/'), dirname(__FILE__) . DIRECTORY_SEPARATOR); @@ -25,7 +25,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator2.phpt b/ext/phar/tests/phar_buildfromiterator2.phpt index cdc2df1050be0..e9dd26e9de074 100644 --- a/ext/phar/tests/phar_buildfromiterator2.phpt +++ b/ext/phar/tests/phar_buildfromiterator2.phpt @@ -8,7 +8,7 @@ phar.readonly=0 --FILE-- buildFromIterator(new stdClass); } catch (Exception $e) { var_dump(get_class($e)); @@ -18,7 +18,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator3.phpt b/ext/phar/tests/phar_buildfromiterator3.phpt index 4a3bc7c0a52de..1603631278397 100644 --- a/ext/phar/tests/phar_buildfromiterator3.phpt +++ b/ext/phar/tests/phar_buildfromiterator3.phpt @@ -36,7 +36,7 @@ class myIterator implements Iterator } } try { - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator3.phar'); $phar->buildFromIterator(new myIterator(array()), new stdClass); } catch (Exception $e) { var_dump(get_class($e)); @@ -46,7 +46,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator4.phpt b/ext/phar/tests/phar_buildfromiterator4.phpt index cd261386d5d73..9277db562b481 100644 --- a/ext/phar/tests/phar_buildfromiterator4.phpt +++ b/ext/phar/tests/phar_buildfromiterator4.phpt @@ -37,7 +37,7 @@ class myIterator implements Iterator } try { chdir(dirname(__FILE__)); - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator4.phar'); var_dump($phar->buildFromIterator(new myIterator( array( 'a' => basename(__FILE__, 'php') . 'phpt', @@ -54,7 +54,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator5.phpt b/ext/phar/tests/phar_buildfromiterator5.phpt index 8431c12a7c64b..b6fafec6f4f92 100644 --- a/ext/phar/tests/phar_buildfromiterator5.phpt +++ b/ext/phar/tests/phar_buildfromiterator5.phpt @@ -37,7 +37,7 @@ class myIterator implements Iterator } try { chdir(dirname(__FILE__)); - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator5.phar'); var_dump($phar->buildFromIterator(new myIterator(array('a' => new stdClass)))); } catch (Exception $e) { var_dump(get_class($e)); @@ -47,7 +47,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator6.phpt b/ext/phar/tests/phar_buildfromiterator6.phpt index 9c506c85283f8..3a315fae4dcb3 100644 --- a/ext/phar/tests/phar_buildfromiterator6.phpt +++ b/ext/phar/tests/phar_buildfromiterator6.phpt @@ -37,7 +37,7 @@ class myIterator implements Iterator } try { chdir(dirname(__FILE__)); - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator6.phar'); var_dump($phar->buildFromIterator(new myIterator(array(basename(__FILE__, 'php') . 'phpt')))); } catch (Exception $e) { var_dump(get_class($e)); @@ -47,7 +47,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator7.phpt b/ext/phar/tests/phar_buildfromiterator7.phpt index 2bac4c8269a57..3dd8fc1b001d0 100644 --- a/ext/phar/tests/phar_buildfromiterator7.phpt +++ b/ext/phar/tests/phar_buildfromiterator7.phpt @@ -37,7 +37,7 @@ class myIterator implements Iterator } try { chdir(dirname(__FILE__)); - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator7.phar'); var_dump($phar->buildFromIterator(new myIterator(array('a' => basename(__FILE__, 'php') . '/oopsie/there.phpt')))); } catch (Exception $e) { var_dump(get_class($e)); @@ -47,7 +47,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator8.phpt b/ext/phar/tests/phar_buildfromiterator8.phpt index bb1b780d759b7..de37ee868784d 100644 --- a/ext/phar/tests/phar_buildfromiterator8.phpt +++ b/ext/phar/tests/phar_buildfromiterator8.phpt @@ -8,7 +8,7 @@ phar.readonly=0 buildFromIterator(new RegexIterator(new DirectoryIterator('.'), '/^\d{0,3}\.phpt\\z|^\.\\z|^\.\.\\z/'), dirname(__FILE__) . DIRECTORY_SEPARATOR); asort($a); var_dump($a); @@ -20,7 +20,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_buildfromiterator9.phpt b/ext/phar/tests/phar_buildfromiterator9.phpt index 0b56307545677..2c9306b6cc86e 100644 --- a/ext/phar/tests/phar_buildfromiterator9.phpt +++ b/ext/phar/tests/phar_buildfromiterator9.phpt @@ -37,7 +37,7 @@ class myIterator implements Iterator } try { chdir(dirname(__FILE__)); - $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar'); + $phar = new Phar(dirname(__FILE__) . '/buildfromiterator9.phar'); var_dump($phar->buildFromIterator(new myIterator(array('a' => $a = fopen(basename(__FILE__, 'php') . 'phpt', 'r'))))); fclose($a); } catch (Exception $e) { @@ -48,7 +48,7 @@ try { ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_extract.phpt b/ext/phar/tests/phar_extract.phpt index 01d65f9091de0..bc545236fd886 100644 --- a/ext/phar/tests/phar_extract.phpt +++ b/ext/phar/tests/phar_extract.phpt @@ -38,9 +38,9 @@ var_dump(file_get_contents(dirname(__FILE__) . '/extract1/file1.txt')); $a->extractTo(dirname(__FILE__) . '/extract1', 'subdir/ectory/file.txt'); var_dump(file_get_contents(dirname(__FILE__) . '/extract1/subdir/ectory/file.txt')); -$a->extractTo(dirname(__FILE__) . '/extract2', array('file2.txt', 'one/level')); -var_dump(file_get_contents(dirname(__FILE__) . '/extract2/file2.txt')); -var_dump(is_dir(dirname(__FILE__) . '/extract2/one/level')); +$a->extractTo(dirname(__FILE__) . '/extract1-2', array('file2.txt', 'one/level')); +var_dump(file_get_contents(dirname(__FILE__) . '/extract1-2/file2.txt')); +var_dump(is_dir(dirname(__FILE__) . '/extract1-2/one/level')); try { $a->extractTo(dirname(__FILE__) . '/whatever', 134); @@ -119,7 +119,7 @@ $e = dirname(__FILE__) . '/extract1/'; @rmdir($e . 'subdir/ectory'); @rmdir($e . 'subdir'); @rmdir($e); -$e = dirname(__FILE__) . '/extract2/'; +$e = dirname(__FILE__) . '/extract1-2/'; @unlink($e . 'file2.txt'); @rmdir($e . 'one/level'); @rmdir($e . 'one'); diff --git a/ext/phar/tests/phar_extract2.phpt b/ext/phar/tests/phar_extract2.phpt index cac509f9dc666..7de8cee5b0e90 100644 --- a/ext/phar/tests/phar_extract2.phpt +++ b/ext/phar/tests/phar_extract2.phpt @@ -16,14 +16,14 @@ $phar->setAlias('fred'); $phar['file1.txt'] = 'hi'; $phar['file2.txt'] = 'hi2'; $phar['subdir/ectory/file.txt'] = 'hi3'; -$phar->mount($pname . '/mount', __FILE__); +$phar->mount($pname . '/mount2', __FILE__); $phar->addEmptyDir('one/level'); -$phar->extractTo(dirname(__FILE__) . '/extract', 'mount'); -$phar->extractTo(dirname(__FILE__) . '/extract'); +$phar->extractTo(dirname(__FILE__) . '/extract2', 'mount2'); +$phar->extractTo(dirname(__FILE__) . '/extract2'); $out = array(); -foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__) . '/extract', 0x00003000), RecursiveIteratorIterator::CHILD_FIRST) as $path => $file) { +foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__) . '/extract2', 0x00003000), RecursiveIteratorIterator::CHILD_FIRST) as $path => $file) { $extracted[] = $path; } @@ -38,7 +38,7 @@ foreach ($extracted as $out) { --CLEAN-- --EXPECTF-- -%sextract%cfile1.txt -%sextract%cfile2.txt -%sextract%cone -%sextract%csubdir -%sextract%csubdir%cectory -%sextract%csubdir%cectory%cfile.txt +%sextract2%cfile1.txt +%sextract2%cfile2.txt +%sextract2%cone +%sextract2%csubdir +%sextract2%csubdir%cectory +%sextract2%csubdir%cectory%cfile.txt ===DONE=== diff --git a/ext/phar/tests/phar_extract3.phpt b/ext/phar/tests/phar_extract3.phpt index df85211a23920..475583938bb0d 100644 --- a/ext/phar/tests/phar_extract3.phpt +++ b/ext/phar/tests/phar_extract3.phpt @@ -9,7 +9,7 @@ phar.readonly=0 $fname = dirname(__FILE__) . '/files/bogus.zip'; $fname2 = dirname(__FILE__) . '/files/notbogus.zip'; -$extract = dirname(__FILE__) . '/test'; +$extract = dirname(__FILE__) . '/test-extract3'; $phar = new PharData($fname); @@ -34,7 +34,7 @@ try { ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_001U.phpt b/ext/phar/tests/phar_oo_001U.phpt index f13ddd4b0b206..a21026a5b6947 100644 --- a/ext/phar/tests/phar_oo_001U.phpt +++ b/ext/phar/tests/phar_oo_001U.phpt @@ -46,7 +46,7 @@ try { ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_002.phpt b/ext/phar/tests/phar_oo_002.phpt index 3754151d42f0a..476cd7d3c216f 100644 --- a/ext/phar/tests/phar_oo_002.phpt +++ b/ext/phar/tests/phar_oo_002.phpt @@ -50,11 +50,11 @@ foreach(new RecursiveIteratorIterator($phar) as $name => $ent) ===DONE=== --CLEAN-- --EXPECTF-- -string(42) "phar://*/files/phar_oo_test.phar.php%ca.php" +string(41) "phar://*/files/phar_oo_002.phar.php%ca.php" string(5) "a.php" int(32) string(4) "file" @@ -67,7 +67,7 @@ bool(false) int(%d) int(%d) int(%d) -string(38) "phar://*/files/phar_oo_test.phar.php%cb" +string(37) "phar://*/files/phar_oo_002.phar.php%cb" string(1) "b" int(0) string(3) "dir" @@ -80,7 +80,7 @@ bool(false) int(%d) int(%d) int(%d) -string(42) "phar://*/files/phar_oo_test.phar.php%cb.php" +string(41) "phar://*/files/phar_oo_002.phar.php%cb.php" string(5) "b.php" int(32) string(4) "file" @@ -93,7 +93,7 @@ bool(false) int(%d) int(%d) int(%d) -string(42) "phar://*/files/phar_oo_test.phar.php%ce.php" +string(41) "phar://*/files/phar_oo_002.phar.php%ce.php" string(5) "e.php" int(32) string(4) "file" @@ -107,31 +107,31 @@ int(%d) int(%d) int(%d) ==RECURSIVE== -string(42) "phar://*/files/phar_oo_test.phar.php%ca.php" +string(41) "phar://*/files/phar_oo_002.phar.php%ca.php" string(5) "a.php" int(32) bool(false) NULL int(0) -string(44) "phar://*/files/phar_oo_test.phar.php/b%cc.php" +string(43) "phar://*/files/phar_oo_002.phar.php/b%cc.php" string(5) "c.php" int(34) bool(false) NULL int(0) -string(44) "phar://*/files/phar_oo_test.phar.php/b%cd.php" +string(43) "phar://*/files/phar_oo_002.phar.php/b%cd.php" string(5) "d.php" int(34) bool(false) NULL int(0) -string(42) "phar://*/files/phar_oo_test.phar.php%cb.php" +string(41) "phar://*/files/phar_oo_002.phar.php%cb.php" string(5) "b.php" int(32) bool(false) NULL int(0) -string(42) "phar://*/files/phar_oo_test.phar.php%ce.php" +string(41) "phar://*/files/phar_oo_002.phar.php%ce.php" string(5) "e.php" int(32) bool(false) diff --git a/ext/phar/tests/phar_oo_002U.phpt b/ext/phar/tests/phar_oo_002U.phpt index 26d0d68d97474..da17152b3273f 100644 --- a/ext/phar/tests/phar_oo_002U.phpt +++ b/ext/phar/tests/phar_oo_002U.phpt @@ -50,11 +50,11 @@ foreach(new RecursiveIteratorIterator($phar) as $name => $ent) ===DONE=== --CLEAN-- --EXPECTF-- -unicode(42) "phar://*/files/phar_oo_test.phar.php%ca.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%ca.php" string(5) "a.php" int(32) unicode(4) "file" @@ -67,7 +67,7 @@ bool(false) int(%d) int(%d) int(%d) -unicode(38) "phar://*/files/phar_oo_test.phar.php%cb" +unicode(38) "phar://*/files/phar_oo_002.phar.php%cb" string(1) "b" int(0) unicode(3) "dir" @@ -80,7 +80,7 @@ bool(false) int(%d) int(%d) int(%d) -unicode(42) "phar://*/files/phar_oo_test.phar.php%cb.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%cb.php" string(5) "b.php" int(32) unicode(4) "file" @@ -93,7 +93,7 @@ bool(false) int(%d) int(%d) int(%d) -unicode(42) "phar://*/files/phar_oo_test.phar.php%ce.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%ce.php" string(5) "e.php" int(32) unicode(4) "file" @@ -107,31 +107,31 @@ int(%d) int(%d) int(%d) ==RECURSIVE== -unicode(42) "phar://*/files/phar_oo_test.phar.php%ca.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%ca.php" unicode(5) "a.php" int(32) bool(false) NULL int(0) -unicode(44) "phar://*/files/phar_oo_test.phar.php/b%cc.php" +unicode(44) "phar://*/files/phar_oo_002.phar.php/b%cc.php" unicode(5) "c.php" int(34) bool(false) NULL int(0) -unicode(44) "phar://*/files/phar_oo_test.phar.php/b%cd.php" +unicode(44) "phar://*/files/phar_oo_002.phar.php/b%cd.php" unicode(5) "d.php" int(34) bool(false) NULL int(0) -unicode(42) "phar://*/files/phar_oo_test.phar.php%cb.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%cb.php" unicode(5) "b.php" int(32) bool(false) NULL int(0) -unicode(42) "phar://*/files/phar_oo_test.phar.php%ce.php" +unicode(42) "phar://*/files/phar_oo_002.phar.php%ce.php" unicode(5) "e.php" int(32) bool(false) diff --git a/ext/phar/tests/phar_oo_003.phpt b/ext/phar/tests/phar_oo_003.phpt index ccaf7c65f80d7..4395792632433 100644 --- a/ext/phar/tests/phar_oo_003.phpt +++ b/ext/phar/tests/phar_oo_003.phpt @@ -27,7 +27,7 @@ foreach($phar as $name => $ent) ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_004.phpt b/ext/phar/tests/phar_oo_004.phpt index ba67749843ab0..3e4581992eaab 100644 --- a/ext/phar/tests/phar_oo_004.phpt +++ b/ext/phar/tests/phar_oo_004.phpt @@ -78,7 +78,7 @@ foreach($it as $name => $ent) ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_004U.phpt b/ext/phar/tests/phar_oo_004U.phpt index 2762ee3c3568f..51be9dab2e2bc 100644 --- a/ext/phar/tests/phar_oo_004U.phpt +++ b/ext/phar/tests/phar_oo_004U.phpt @@ -78,7 +78,7 @@ foreach($it as $name => $ent) ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_005.phpt b/ext/phar/tests/phar_oo_005.phpt index cb3f2987280f0..b01231e9c2652 100644 --- a/ext/phar/tests/phar_oo_005.phpt +++ b/ext/phar/tests/phar_oo_005.phpt @@ -32,7 +32,7 @@ foreach($it as $name => $ent) ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_005U.phpt b/ext/phar/tests/phar_oo_005U.phpt index bcdcb08b0dc9f..9c04b93cef33c 100644 --- a/ext/phar/tests/phar_oo_005U.phpt +++ b/ext/phar/tests/phar_oo_005U.phpt @@ -31,7 +31,7 @@ foreach($it as $name => $ent) ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_005_5.2.phpt b/ext/phar/tests/phar_oo_005_5.2.phpt index 9e509d94b704c..399edb0dd37b1 100644 --- a/ext/phar/tests/phar_oo_005_5.2.phpt +++ b/ext/phar/tests/phar_oo_005_5.2.phpt @@ -31,7 +31,7 @@ foreach($it as $name => $ent) ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_006.phpt b/ext/phar/tests/phar_oo_006.phpt index 556c98ce0b620..5d1d7052066c4 100644 --- a/ext/phar/tests/phar_oo_006.phpt +++ b/ext/phar/tests/phar_oo_006.phpt @@ -38,7 +38,7 @@ echo $phar['b.php']->getFilename() . "\n"; ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_007.phpt b/ext/phar/tests/phar_oo_007.phpt index 788b11f1f81a4..d0b5aa5ecaec0 100644 --- a/ext/phar/tests/phar_oo_007.phpt +++ b/ext/phar/tests/phar_oo_007.phpt @@ -59,11 +59,11 @@ var_dump($f->eof()); ===DONE=== --CLEAN-- --EXPECTF-- -MyFile::__construct(phar://*/files/phar_oo_test.phar.php/a.php) +MyFile::__construct(phar://*/files/phar_oo_007.phar.php/a.php) int(%d) int(%d) int(%d) @@ -79,7 +79,7 @@ int(0) string(32) "" int(32) ===AGAIN=== -MyFile::__construct(phar://*/files/phar_oo_test.phar.php/a.php) +MyFile::__construct(phar://*/files/phar_oo_007.phar.php/a.php) int(0) bool(false) string(32) "" diff --git a/ext/phar/tests/phar_oo_008.phpt b/ext/phar/tests/phar_oo_008.phpt index 80d1ece0ca97d..d95af571b3c04 100644 --- a/ext/phar/tests/phar_oo_008.phpt +++ b/ext/phar/tests/phar_oo_008.phpt @@ -83,7 +83,7 @@ foreach($v as $k => $d) ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_009.phpt b/ext/phar/tests/phar_oo_009.phpt index 6abd03ee30b52..3c842fabeda52 100644 --- a/ext/phar/tests/phar_oo_009.phpt +++ b/ext/phar/tests/phar_oo_009.phpt @@ -36,7 +36,7 @@ foreach($f as $k => $v) ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_010.phpt b/ext/phar/tests/phar_oo_010.phpt index 1d3ff73242418..331d300a8c650 100644 --- a/ext/phar/tests/phar_oo_010.phpt +++ b/ext/phar/tests/phar_oo_010.phpt @@ -36,7 +36,7 @@ var_dump(isset($phar['b'])); ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_011.phpt b/ext/phar/tests/phar_oo_011.phpt index cfbab702ad8c8..01fa9f01e6ec4 100644 --- a/ext/phar/tests/phar_oo_011.phpt +++ b/ext/phar/tests/phar_oo_011.phpt @@ -26,7 +26,7 @@ echo "\n"; ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_011b.phpt b/ext/phar/tests/phar_oo_011b.phpt index 36d9963a2283d..34cae0e760b73 100644 --- a/ext/phar/tests/phar_oo_011b.phpt +++ b/ext/phar/tests/phar_oo_011b.phpt @@ -31,7 +31,7 @@ catch (BadMethodCallException $e) ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phar_oo_012.phpt b/ext/phar/tests/phar_oo_012.phpt index e79ac0960edc6..b6f9f44b1e153 100644 --- a/ext/phar/tests/phar_oo_012.phpt +++ b/ext/phar/tests/phar_oo_012.phpt @@ -27,7 +27,7 @@ var_dump(isset($phar['f.php'])); ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_012_confirm.phpt b/ext/phar/tests/phar_oo_012_confirm.phpt index 58a3be87b323f..ce5a58f212d7e 100644 --- a/ext/phar/tests/phar_oo_012_confirm.phpt +++ b/ext/phar/tests/phar_oo_012_confirm.phpt @@ -30,7 +30,7 @@ var_dump(isset($phar['f.php'])); ===DONE=== --CLEAN-- --EXPECT-- diff --git a/ext/phar/tests/phar_oo_012b.phpt b/ext/phar/tests/phar_oo_012b.phpt index 80d8ed8dc4d7a..066d3bc0687b1 100644 --- a/ext/phar/tests/phar_oo_012b.phpt +++ b/ext/phar/tests/phar_oo_012b.phpt @@ -34,7 +34,7 @@ catch (BadMethodCallException $e) ===DONE=== --CLEAN-- --EXPECTF-- diff --git a/ext/phar/tests/phpinfo_004.phpt b/ext/phar/tests/phpinfo_004.phpt index 24263f07bee69..c57e850d82f9f 100644 --- a/ext/phar/tests/phpinfo_004.phpt +++ b/ext/phar/tests/phpinfo_004.phpt @@ -23,9 +23,9 @@ phpinfo(INFO_MODULES); ?> ===DONE=== --EXPECTF-- -%a
+%a

Phar

- +
@@ -36,20 +36,20 @@ phpinfo(INFO_MODULES); -
Phar: PHP Archive supportenabled
Phar EXT version %s
Phar API version 1.1.1
gzip compression enabled
bzip2 compression enabled
OpenSSL support disabled (install ext/openssl)

- +
+ -
Phar based on pear/PHP_Archive, original concept by Davey Shafik.
Phar fully realized by Gregory Beaver and Marcus Boerger.
Portions of tar implementation Copyright (c) %d-%d Tim Kientzle.

- +
+ -
DirectiveLocal ValueMaster Value
phar.cache_listno valueno value
phar.readonlyOffOff
phar.require_hashOffOff

-%a
+ +%a

Phar

- +
@@ -60,16 +60,16 @@ Phar based on pear/PHP_Archive, original concept by Davey Shafik.
Phar full -
Phar: PHP Archive supportenabled
Phar EXT version %s
Phar API version 1.1.1
gzip compression enabled
bzip2 compression enabled
OpenSSL support disabled (install ext/openssl)

- +
+ -
Phar based on pear/PHP_Archive, original concept by Davey Shafik.
Phar fully realized by Gregory Beaver and Marcus Boerger.
Portions of tar implementation Copyright (c) %d-%d Tim Kientzle.

- +
+ -
DirectiveLocal ValueMaster Value
phar.cache_listno valueno value
phar.readonlyOnOff
phar.require_hashOnOff

-%a
+ +%a ===DONE=== diff --git a/ext/phar/util.c b/ext/phar/util.c index 31d12e3da7b52..a887daecdce68 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -350,7 +350,7 @@ char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_d * appended, truncated, or read. For read, if the entry is marked unmodified, it is * assumed that the file pointer, if present, is opened for reading */ -int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC) /* {{{ */ +int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security TSRMLS_DC) /* {{{ */ { phar_archive_data *phar; phar_entry_info *entry; @@ -511,7 +511,7 @@ int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char /** * Create a new dummy file slot within a writeable phar for a newly created file */ -phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error, int security TSRMLS_DC) /* {{{ */ +phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security TSRMLS_DC) /* {{{ */ { phar_archive_data *phar; phar_entry_info *entry, etemp; @@ -673,7 +673,7 @@ int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **er link = source; } - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), dest->fp, link->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0 TSRMLS_CC), dest->fp, link->uncompressed_filesize, NULL)) { php_stream_close(dest->fp); dest->fp_type = PHAR_FP; if (error) { @@ -775,7 +775,7 @@ int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links TS php_stream_seek(phar_get_entrypfp(entry TSRMLS_CC), phar_get_fp_offset(entry TSRMLS_CC), SEEK_SET); if (entry->uncompressed_filesize) { - if (SUCCESS != phar_stream_copy_to_stream(phar_get_entrypfp(entry TSRMLS_CC), ufp, entry->compressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry TSRMLS_CC), ufp, entry->compressed_filesize, NULL)) { spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename); php_stream_filter_remove(filter, 1 TSRMLS_CC); return FAILURE; @@ -882,7 +882,7 @@ int phar_separate_entry_fp(phar_entry_info *entry, char **error TSRMLS_DC) /* {{ link = entry; } - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0 TSRMLS_CC), fp, link->uncompressed_filesize, NULL)) { if (error) { spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname); } @@ -1299,21 +1299,17 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in } if (phar->mounted_dirs.arBuckets && zend_hash_num_elements(&phar->mounted_dirs)) { - phar_zstr key; char *str_key; ulong unused; uint keylen; zend_hash_internal_pointer_reset(&phar->mounted_dirs); while (FAILURE != zend_hash_has_more_elements(&phar->mounted_dirs)) { - if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, NULL)) { + if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &keylen, &unused, 0, NULL)) { break; } - PHAR_STR(key, str_key); - if ((int)keylen >= path_len || strncmp(str_key, path, keylen)) { - PHAR_STR_FREE(str_key); continue; } else { char *test; @@ -1324,7 +1320,6 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", str_key); } - PHAR_STR_FREE(str_key); return NULL; } @@ -1332,10 +1327,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", str_key); } - PHAR_STR_FREE(str_key); return NULL; } - PHAR_STR_FREE(str_key); test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + keylen); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index e3b64859b89cc..2e977b8840fe1 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -417,11 +417,11 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, php_stream_seek(fp, 0, SEEK_SET); /* copy file contents + local headers and zip comment, if any, to be hashed for signature */ - phar_stream_copy_to_stream(fp, sigfile, entry.header_offset, NULL); + php_stream_copy_to_stream_ex(fp, sigfile, entry.header_offset, NULL); /* seek to central directory */ php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET); /* copy central directory header */ - phar_stream_copy_to_stream(fp, sigfile, beforeus - PHAR_GET_32(locator.cdir_offset), NULL); + php_stream_copy_to_stream_ex(fp, sigfile, beforeus - PHAR_GET_32(locator.cdir_offset), NULL); if (metadata) { php_stream_write(sigfile, metadata, PHAR_GET_16(locator.comment_len)); } @@ -905,7 +905,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */ php_stream_filter_append((&entry->cfp->writefilters), filter); - if (SUCCESS != phar_stream_copy_to_stream(efp, entry->cfp, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(efp, entry->cfp, entry->uncompressed_filesize, NULL)) { spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", entry->filename, entry->phar->fname); return ZEND_HASH_APPLY_STOP; } @@ -1010,7 +1010,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */ if (!not_really_modified && entry->is_modified) { if (entry->cfp) { - if (SUCCESS != phar_stream_copy_to_stream(entry->cfp, p->filefp, entry->compressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(entry->cfp, p->filefp, entry->compressed_filesize, NULL)) { spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname); return ZEND_HASH_APPLY_STOP; } @@ -1024,7 +1024,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */ phar_seek_efp(entry, 0, SEEK_SET, 0, 0 TSRMLS_CC); - if (SUCCESS != phar_stream_copy_to_stream(phar_get_efp(entry, 0 TSRMLS_CC), p->filefp, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0 TSRMLS_CC), p->filefp, entry->uncompressed_filesize, NULL)) { spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", entry->filename, entry->phar->fname); return ZEND_HASH_APPLY_STOP; } @@ -1050,7 +1050,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */ } } - if (!entry->is_dir && entry->compressed_filesize && SUCCESS != phar_stream_copy_to_stream(p->old, p->filefp, entry->compressed_filesize, NULL)) { + if (!entry->is_dir && entry->compressed_filesize && SUCCESS != php_stream_copy_to_stream_ex(p->old, p->filefp, entry->compressed_filesize, NULL)) { spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname); return ZEND_HASH_APPLY_STOP; } @@ -1093,10 +1093,10 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas st = tell = php_stream_tell(pass->filefp); /* copy the local files, central directory, and the zip comment to generate the hash */ php_stream_seek(pass->filefp, 0, SEEK_SET); - phar_stream_copy_to_stream(pass->filefp, newfile, tell, NULL); + php_stream_copy_to_stream_ex(pass->filefp, newfile, tell, NULL); tell = php_stream_tell(pass->centralfp); php_stream_seek(pass->centralfp, 0, SEEK_SET); - phar_stream_copy_to_stream(pass->centralfp, newfile, tell, NULL); + php_stream_copy_to_stream_ex(pass->centralfp, newfile, tell, NULL); if (metadata->c) { php_stream_write(newfile, metadata->c, metadata->len); } @@ -1431,7 +1431,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau { size_t clen; - int ret = phar_stream_copy_to_stream(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL, &clen); + int ret = php_stream_copy_to_stream_ex(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL, &clen); if (SUCCESS != ret || clen != cdir_size) { if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", phar->fname); @@ -1501,7 +1501,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau return EOF; } php_stream_rewind(pass.filefp); - phar_stream_copy_to_stream(pass.filefp, phar->fp, PHP_STREAM_COPY_ALL, NULL); + php_stream_copy_to_stream_ex(pass.filefp, phar->fp, PHP_STREAM_COPY_ALL, NULL); /* we could also reopen the file in "rb" mode but there is no need for that */ php_stream_close(pass.filefp); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b1f7484f243ca..cc148b39c5663 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -681,8 +681,8 @@ static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset) ++offset; while (op < end) { - if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) - && op->op1.num == (long)offset) + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT + || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == (long)offset) { return op; } @@ -715,6 +715,9 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg if (arg_info->pass_by_reference) { string_write(str, "&", sizeof("&")-1); } + if (arg_info->is_variadic) { + string_write(str, "...", sizeof("...")-1); + } if (arg_info->name) { string_printf(str, "$%s", arg_info->name); } else { @@ -2652,6 +2655,22 @@ ZEND_METHOD(reflection_parameter, getDefaultValueConstantName) } /* }}} */ +/* {{{ proto public bool ReflectionParameter::isVariadic() + Returns whether this parameter is a variadic parameter */ +ZEND_METHOD(reflection_parameter, isVariadic) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->is_variadic); +} +/* }}} */ + /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection_method, export) @@ -3095,6 +3114,14 @@ ZEND_METHOD(reflection_function, isGenerator) } /* }}} */ +/* {{{ proto public bool ReflectionFunction::isVariadic() + Returns whether this function is variadic */ +ZEND_METHOD(reflection_function, isVariadic) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_VARIADIC); +} +/* }}} */ + /* {{{ proto public bool ReflectionFunction::inNamespace() Returns whether this function is defined in namespace */ ZEND_METHOD(reflection_function, inNamespace) @@ -5720,6 +5747,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = { ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0) ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0) ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isVariadic, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0) @@ -6022,6 +6050,7 @@ static const zend_function_entry reflection_parameter_functions[] = { ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0) ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0) ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isVariadic, arginfo_reflection__void, 0) PHP_FE_END }; diff --git a/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt b/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt new file mode 100644 index 0000000000000..50b6bb495e449 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +ReflectionFunction::isVariadic() +--FILE-- +isVariadic()); +var_dump((new ReflectionFunction('test2'))->isVariadic()); +var_dump((new ReflectionFunction('test3'))->isVariadic()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) diff --git a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt index 82c62001226b2..4772f6548dcae 100644 --- a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt +++ b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt @@ -61,6 +61,10 @@ Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING Is passed by reference: yes Can be passed by value: yes +Name: more_array_and_sort_options +Is passed by reference: yes +Can be passed by value: yes + => sort: Name: arg diff --git a/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt b/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt new file mode 100644 index 0000000000000..370edc388df39 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +ReflectionParameter::isVariadic() +--FILE-- +getParameters()[0]->isVariadic()); +var_dump($r2->getParameters()[0]->isVariadic()); +var_dump($r3->getParameters()[0]->isVariadic()); +var_dump($r3->getParameters()[1]->isVariadic()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt index 268ced15eca32..d1a23c758d3a3 100644 --- a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt +++ b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt @@ -4,7 +4,7 @@ ReflectionParameter::__toString() Stefan Koopmanschap --FILE-- $value) { --EXPECT-- Parameter #0 [ $test ] Parameter #1 [ $test2 = NULL ] +Parameter #2 [ ...$test3 ] ==DONE== diff --git a/ext/session/php_session.h b/ext/session/php_session.h index e8e79f0fa69e4..4307e6afc5c14 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -180,6 +180,7 @@ typedef struct _php_ps_globals { double rfc1867_min_freq; /* session.upload_progress.min_freq */ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + unsigned char session_data_hash[16]; /* binary MD5 hash length */ } php_ps_globals; typedef php_ps_globals zend_ps_globals; diff --git a/ext/session/session.c b/ext/session/session.c index 7bb6584621d8d..5b4820a65cfa4 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -505,8 +505,17 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */ */ } if (val) { + PHP_MD5_CTX context; + + /* Store read data's MD5 hash */ + PHP_MD5Init(&context); + PHP_MD5Update(&context, val, vallen); + PHP_MD5Final(PS(session_data_hash), &context); + php_session_decode(val, vallen TSRMLS_CC); efree(val); + } else { + memset(PS(session_data_hash),'\0', 16); } if (!PS(use_cookies) && PS(send_cookie)) { @@ -529,7 +538,19 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */ val = php_session_encode(&vallen TSRMLS_CC); if (val) { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC); + PHP_MD5_CTX context; + unsigned char digest[16]; + + /* Generate data's MD5 hash */ + PHP_MD5Init(&context); + PHP_MD5Update(&context, val, vallen); + PHP_MD5Final(digest, &context); + /* Write only when save is required */ + if (memcmp(digest, PS(session_data_hash), 16)) { + ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC); + } else { + ret = SUCCESS; + } efree(val); } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC); @@ -727,6 +748,7 @@ static PHP_INI_MH(OnUpdateHashFunc) /* {{{ */ } #endif /* HAVE_HASH_EXT }}} */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "session.configuration 'session.hash_function' must be existing hash function. %s does not exist.", new_value); return FAILURE; } /* }}} */ @@ -1567,6 +1589,26 @@ static void php_session_flush(TSRMLS_D) /* {{{ */ } /* }}} */ +static void php_session_abort(TSRMLS_D) /* {{{ */ +{ + if (PS(session_status) == php_session_active) { + PS(session_status) = php_session_none; + if (PS(mod_data) || PS(mod_user_implemented)) { + PS(mod)->s_close(&PS(mod_data) TSRMLS_CC); + } + } +} +/* }}} */ + +static void php_session_reset(TSRMLS_D) /* {{{ */ +{ + if (PS(session_status) == php_session_active) { + php_session_initialize(TSRMLS_C); + } +} +/* }}} */ + + PHPAPI void session_adapt_url(https://github.com/const%20char%20*url,%20size_t%20urllen,%20char%20**new,%20size_t%20*newlen%20TSRMLS_DC) /* {{{ */ { if (PS(apply_trans_sid) && (PS(session_status) == php_session_active)) { @@ -1685,6 +1727,31 @@ static PHP_FUNCTION(session_module_name) } /* }}} */ +/* {{{ proto mixed session_serializer_name([string newname]) + Return the current serializer name used for encode/decode session data. If newname is given, the serialzer name is replaced with newname and return bool */ +static PHP_FUNCTION(session_serializer_name) +{ + char *name = NULL; + int name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) { + return; + } + + /* Return serializer name */ + if (!name) { + RETURN_STRING(zend_ini_string("session.serialize_handler", sizeof("session.serialize_handler"), 0), 1); + } + + /* Set serializer name */ + if (zend_alter_ini_entry("session.serialize_handler", sizeof("session.serialize_handler"), name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == SUCCESS) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + /* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc, string create_sid) Sets user-level functions */ static PHP_FUNCTION(session_set_save_handler) @@ -2048,6 +2115,22 @@ static PHP_FUNCTION(session_write_close) } /* }}} */ +/* {{{ proto void session_abort(void) + Abort session and end session. Session data will not be written */ +static PHP_FUNCTION(session_abort) +{ + php_session_abort(TSRMLS_C); +} +/* }}} */ + +/* {{{ proto void session_reset(void) + Reset session data from saved session data */ +static PHP_FUNCTION(session_reset) +{ + php_session_reset(TSRMLS_C); +} +/* }}} */ + /* {{{ proto int session_status(void) Returns the current session status */ static PHP_FUNCTION(session_status) @@ -2060,6 +2143,39 @@ static PHP_FUNCTION(session_status) } /* }}} */ +/* {{{ proto int session_gc([int maxlifetime]) + Execute garbage collection returns number of deleted data */ +static PHP_FUNCTION(session_gc) +{ + int nrdels = -1; + long maxlifetime = PS(gc_maxlifetime); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &maxlifetime) == FAILURE) { + return; + } + + /* Session must be active to have PS(mod) */ + if (PS(session_status) != php_session_active) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to garbage collect without active session"); + RETURN_FALSE; + } + + if (!PS(mod) || !PS(mod)->s_gc) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session save handler does not have gc()"); + RETURN_FALSE; + } + PS(mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels TSRMLS_CC); + + if (nrdels < 0) { + /* Files save handler return -1 if there is not a permission to remove. + Save handlder should return negative nrdels when something wrong. */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session gc failed. Check permission or session storage"); + RETURN_FALSE; + } + RETURN_LONG((long)nrdels); +} +/* }}} */ + /* {{{ proto void session_register_shutdown(void) Registers session_write_close() as a shutdown function */ static PHP_FUNCTION(session_register_shutdown) @@ -2106,6 +2222,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_session_module_name, 0, 0, 0) ZEND_ARG_INFO(0, module) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_session_serializer_name, 0, 0, 0) + ZEND_ARG_INFO(0, module) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_session_save_path, 0, 0, 0) ZEND_ARG_INFO(0, path) ZEND_END_ARG_INFO() @@ -2151,6 +2271,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_cookie_params, 0, 0, 1) ZEND_ARG_INFO(0, httponly) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_session_gc, 0) + ZEND_ARG_INFO(0, maxlifetime) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_session_class_open, 0) ZEND_ARG_INFO(0, save_path) ZEND_ARG_INFO(0, session_name) @@ -2185,6 +2309,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry session_functions[] = { PHP_FE(session_name, arginfo_session_name) PHP_FE(session_module_name, arginfo_session_module_name) + PHP_FE(session_serializer_name, arginfo_session_serializer_name) PHP_FE(session_save_path, arginfo_session_save_path) PHP_FE(session_id, arginfo_session_id) PHP_FE(session_regenerate_id, arginfo_session_regenerate_id) @@ -2199,7 +2324,10 @@ static const zend_function_entry session_functions[] = { PHP_FE(session_set_cookie_params, arginfo_session_set_cookie_params) PHP_FE(session_get_cookie_params, arginfo_session_void) PHP_FE(session_write_close, arginfo_session_void) + PHP_FE(session_abort, arginfo_session_void) + PHP_FE(session_reset, arginfo_session_void) PHP_FE(session_status, arginfo_session_void) + PHP_FE(session_gc, arginfo_session_gc) PHP_FE(session_register_shutdown, arginfo_session_void) PHP_FALIAS(session_commit, session_write_close, arginfo_session_void) PHP_FE_END diff --git a/ext/session/tests/session_abort_basic.phpt b/ext/session/tests/session_abort_basic.phpt new file mode 100644 index 0000000000000..4a6702f0dc667 --- /dev/null +++ b/ext/session/tests/session_abort_basic.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test session_abort() function : basic functionality +--SKIPIF-- + +--INI-- +session.save_path= +session.name=PHPSESSID +--FILE-- + +--EXPECTF-- +*** Testing session_abort() : basic functionality *** +array(2) { + ["foo"]=> + int(123) + ["bar"]=> + int(456) +} +array(1) { + ["foo"]=> + int(123) +} +Done diff --git a/ext/session/tests/session_gc_basic.phpt b/ext/session/tests/session_gc_basic.phpt new file mode 100644 index 0000000000000..f0726ce93bbbf --- /dev/null +++ b/ext/session/tests/session_gc_basic.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test session_gc() function : basic functionality +--SKIPIF-- + +--INI-- +session.serialize_handler=php +session.save_handler=files +session.maxlifetime=782000 +--FILE-- += 3); + +echo "Done".PHP_EOL; + +?> +--EXPECTF-- +*** Testing session_gc() : basic functionality *** + +Warning: session_gc(): Trying to garbage collect without active session in %s on line 15 +bool(false) +int(%d) +int(0) +bool(true) +Done diff --git a/ext/session/tests/session_hash_function_basic.phpt b/ext/session/tests/session_hash_function_basic.phpt new file mode 100644 index 0000000000000..663852d9d1a1c --- /dev/null +++ b/ext/session/tests/session_hash_function_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test session.hash_function ini setting : basic functionality +--SKIPIF-- + +--INI-- +session.hash_bits_per_character=4 +--FILE-- + +--EXPECTF-- +*** Testing session.hash_function : basic functionality *** +string(1) "0" +bool(true) +bool(true) +string(32) "%s" +bool(true) +string(3) "md5" +bool(true) +bool(true) +string(40) "%s" +bool(true) + +Warning: ini_set(): session.configuration 'session.hash_function' must be existing hash function. none does not exist. in %s/session_hash_function_basic.php on line 17 +bool(false) +bool(true) +bool(true) +string(40) "%s" +bool(true) +Done diff --git a/ext/session/tests/session_reset_basic.phpt b/ext/session/tests/session_reset_basic.phpt new file mode 100644 index 0000000000000..75c6a04119106 --- /dev/null +++ b/ext/session/tests/session_reset_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test session_reset() function : basic functionality +--SKIPIF-- + +--INI-- +session.save_path= +session.name=PHPSESSID +--FILE-- + +--EXPECTF-- +*** Testing session_abort() : basic functionality *** +array(2) { + ["foo"]=> + int(123) + ["bar"]=> + int(456) +} +array(1) { + ["foo"]=> + int(123) +} +Done diff --git a/ext/session/tests/session_serializer_name_basic.phpt b/ext/session/tests/session_serializer_name_basic.phpt new file mode 100644 index 0000000000000..ca292dd36f4a7 --- /dev/null +++ b/ext/session/tests/session_serializer_name_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test session_serializer_name() function : basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing session_serializer_name() : basic functionality *** +string(3) "php" +bool(true) +bool(true) + +Warning: session_serializer_name(): Cannot find serialization handler 'none' in %s/session_serializer_name_basic.php on line 16 +bool(false) +string(10) "php_binary" +Done + diff --git a/ext/session/tests/session_set_save_handler_basic.phpt b/ext/session/tests/session_set_save_handler_basic.phpt index 3897ba9a92752..e8496e8afb72e 100644 --- a/ext/session/tests/session_set_save_handler_basic.phpt +++ b/ext/session/tests/session_set_save_handler_basic.phpt @@ -43,6 +43,7 @@ session_id($session_id); session_set_save_handler("open", "close", "read", "write", "destroy", "gc"); session_start(); var_dump($_SESSION); +$_SESSION['Bar'] = 'Foo'; session_write_close(); ob_end_flush(); @@ -91,5 +92,5 @@ array(3) { ["Guff"]=> int(1234567890) } -Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;] +Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";] Close [%s,PHPSESSID] diff --git a/ext/session/tests/session_set_save_handler_class_003.phpt b/ext/session/tests/session_set_save_handler_class_003.phpt index e9a3cc2febab4..29b3846851263 100644 --- a/ext/session/tests/session_set_save_handler_class_003.phpt +++ b/ext/session/tests/session_set_save_handler_class_003.phpt @@ -58,6 +58,7 @@ session_set_save_handler($handler); session_start(); +$_SESSION['bar'] = 'hello'; session_write_close(); session_unset(); @@ -71,8 +72,10 @@ array(1) { } int(4) string(%d) "%s" -array(1) { +array(2) { ["foo"]=> string(5) "hello" + ["bar"]=> + string(5) "hello" } string(3) "hai" diff --git a/ext/session/tests/session_set_save_handler_class_007.phpt b/ext/session/tests/session_set_save_handler_class_007.phpt index 7344ae1ef30b2..55f722515ea6f 100644 --- a/ext/session/tests/session_set_save_handler_class_007.phpt +++ b/ext/session/tests/session_set_save_handler_class_007.phpt @@ -56,6 +56,7 @@ $handler = new MySession(2); session_set_save_handler($handler); session_start(); +$_SESSION['abc'] = 'xyz'; // implicit close (called by shutdown function) echo "done\n"; ob_end_flush(); @@ -69,6 +70,6 @@ ob_end_flush(); (#2) constructor called (#1) destructor called done -(#2) writing %s = foo|s:3:"bar"; +(#2) writing %s = foo|s:3:"bar";abc|s:3:"xyz"; (#2) closing %s (#2) destructor called diff --git a/ext/session/tests/session_set_save_handler_closures.phpt b/ext/session/tests/session_set_save_handler_closures.phpt index 21b2c68737099..1251886b011f9 100644 --- a/ext/session/tests/session_set_save_handler_closures.phpt +++ b/ext/session/tests/session_set_save_handler_closures.phpt @@ -42,6 +42,7 @@ echo "Starting session again..!\n"; session_id($session_id); session_set_save_handler($open_closure, $close_closure, $read_closure, $write_closure, $destroy_closure, $gc_closure); session_start(); +$_SESSION['Bar'] = 'Foo'; var_dump($_SESSION); session_write_close(); @@ -83,13 +84,15 @@ array(3) { Starting session again..! Open [%s,PHPSESSID] Read [%s,%s] -array(3) { +array(4) { ["Blah"]=> string(12) "Hello World!" ["Foo"]=> bool(false) ["Guff"]=> int(1234567890) + ["Bar"]=> + string(3) "Foo" } -Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;] +Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";] Close [%s,PHPSESSID] diff --git a/ext/session/tests/session_set_save_handler_write_short_circuit.phpt b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt new file mode 100644 index 0000000000000..02ca182ec6b54 --- /dev/null +++ b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt @@ -0,0 +1,104 @@ +--TEST-- +Test session_set_save_handler() function : test write short circuit +--INI-- +session.save_path= +session.name=PHPSESSID +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing session_set_save_handler() : test write short circuit *** + +Open [%s,PHPSESSID] +Read [%s,%s] +array(3) { + ["Blah"]=> + string(12) "Hello World!" + ["Foo"]=> + bool(false) + ["Guff"]=> + int(1234567890) +} +Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;] +Close [%s,PHPSESSID] +array(3) { + ["Blah"]=> + string(12) "Hello World!" + ["Foo"]=> + bool(false) + ["Guff"]=> + int(1234567890) +} +Starting session again..! +Open [%s,PHPSESSID] +Read [%s,%s] +array(3) { + ["Blah"]=> + string(12) "Hello World!" + ["Foo"]=> + bool(false) + ["Guff"]=> + int(1234567890) +} +Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";] +Close [%s,PHPSESSID] +Starting session again..! +Open [%s,PHPSESSID] +Read [%s,%s] +array(4) { + ["Blah"]=> + string(12) "Hello World!" + ["Foo"]=> + bool(false) + ["Guff"]=> + int(1234567890) + ["Bar"]=> + string(3) "Foo" +} +Close [%s,PHPSESSID] \ No newline at end of file diff --git a/ext/simplexml/config.m4 b/ext/simplexml/config.m4 index 387a24ea2190b..b06f5b00f0494 100644 --- a/ext/simplexml/config.m4 +++ b/ext/simplexml/config.m4 @@ -18,6 +18,7 @@ if test "$PHP_SIMPLEXML" != "no"; then PHP_SETUP_LIBXML(SIMPLEXML_SHARED_LIBADD, [ AC_DEFINE(HAVE_SIMPLEXML,1,[ ]) PHP_NEW_EXTENSION(simplexml, simplexml.c sxe.c, $ext_shared) + PHP_INSTALL_HEADERS([ext/simplexml/php_simplexml.h ext/simplexml/php_simplexml_exports.h]) PHP_SUBST(SIMPLEXML_SHARED_LIBADD) ], [ AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.]) diff --git a/ext/simplexml/config.w32 b/ext/simplexml/config.w32 index 2d2ed285ebdac..a02f3dded3a18 100644 --- a/ext/simplexml/config.w32 +++ b/ext/simplexml/config.w32 @@ -16,6 +16,7 @@ if (PHP_SIMPLEXML == "yes") { MESSAGE("\tSPL support in simplexml disabled"); } ADD_FLAG("CFLAGS_SIMPLEXML", "/D PHP_SIMPLEXML_EXPORTS "); + PHP_INSTALL_HEADERS("ext/simplexml/", "php_simplexml.h php_simplexml_exports.h"); } else { PHP_SIMPLEXML = "no"; WARNING("simplexml not enabled; libraries and headers not found"); diff --git a/ext/skeleton/php_skeleton.h b/ext/skeleton/php_skeleton.h index 0716ae05e6241..d0ba6f04abea4 100644 --- a/ext/skeleton/php_skeleton.h +++ b/ext/skeleton/php_skeleton.h @@ -20,15 +20,6 @@ extern zend_module_entry extname_module_entry; #include "TSRM.h" #endif -PHP_MINIT_FUNCTION(extname); -PHP_MSHUTDOWN_FUNCTION(extname); -PHP_RINIT_FUNCTION(extname); -PHP_RSHUTDOWN_FUNCTION(extname); -PHP_MINFO_FUNCTION(extname); - -PHP_FUNCTION(confirm_extname_compiled); /* For testing, remove later. */ -/* __function_declarations_here__ */ - /* Declare any global variables you may need between the BEGIN and END macros here: diff --git a/ext/skeleton/skeleton.c b/ext/skeleton/skeleton.c index 2e373442d8dd1..462e48756ff07 100644 --- a/ext/skeleton/skeleton.c +++ b/ext/skeleton/skeleton.c @@ -16,41 +16,6 @@ ZEND_DECLARE_MODULE_GLOBALS(extname) /* True global resources - no need for thread safety here */ static int le_extname; -/* {{{ extname_functions[] - * - * Every user visible function must have an entry in extname_functions[]. - */ -const zend_function_entry extname_functions[] = { - PHP_FE(confirm_extname_compiled, NULL) /* For testing, remove later. */ - /* __function_entries_here__ */ - PHP_FE_END /* Must be the last line in extname_functions[] */ -}; -/* }}} */ - -/* {{{ extname_module_entry - */ -zend_module_entry extname_module_entry = { -#if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, -#endif - "extname", - extname_functions, - PHP_MINIT(extname), - PHP_MSHUTDOWN(extname), - PHP_RINIT(extname), /* Replace with NULL if there's nothing to do at request start */ - PHP_RSHUTDOWN(extname), /* Replace with NULL if there's nothing to do at request end */ - PHP_MINFO(extname), -#if ZEND_MODULE_API_NO >= 20010901 - PHP_EXTNAME_VERSION, -#endif - STANDARD_MODULE_PROPERTIES -}; -/* }}} */ - -#ifdef COMPILE_DL_EXTNAME -ZEND_GET_MODULE(extname) -#endif - /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini @@ -61,6 +26,35 @@ PHP_INI_END() */ /* }}} */ +/* Remove the following function when you have successfully modified config.m4 + so that your module can be compiled into PHP, it exists only for testing + purposes. */ + +/* Every user-visible function in PHP should document itself in the source */ +/* {{{ proto string confirm_extname_compiled(string arg) + Return a string to confirm that the module is compiled in */ +PHP_FUNCTION(confirm_extname_compiled) +{ + char *arg = NULL; + int arg_len, len; + char *strg; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { + return; + } + + len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "extname", arg); + RETURN_STRINGL(strg, len, 0); +} +/* }}} */ +/* The previous line is meant for vim and emacs, so it can correctly fold and + unfold functions in source code. See the corresponding marks just before + function definition, where the functions purpose is also documented. Please + follow this convention for the convenience of others editing your code. +*/ + +/* __function_stubs_here__ */ + /* {{{ php_extname_init_globals */ /* Uncomment this function if you have INI entries @@ -126,35 +120,36 @@ PHP_MINFO_FUNCTION(extname) } /* }}} */ +/* {{{ extname_functions[] + * + * Every user visible function must have an entry in extname_functions[]. + */ +const zend_function_entry extname_functions[] = { + PHP_FE(confirm_extname_compiled, NULL) /* For testing, remove later. */ + /* __function_entries_here__ */ + PHP_FE_END /* Must be the last line in extname_functions[] */ +}; +/* }}} */ -/* Remove the following function when you have successfully modified config.m4 - so that your module can be compiled into PHP, it exists only for testing - purposes. */ - -/* Every user-visible function in PHP should document itself in the source */ -/* {{{ proto string confirm_extname_compiled(string arg) - Return a string to confirm that the module is compiled in */ -PHP_FUNCTION(confirm_extname_compiled) -{ - char *arg = NULL; - int arg_len, len; - char *strg; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { - return; - } - - len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "extname", arg); - RETURN_STRINGL(strg, len, 0); -} +/* {{{ extname_module_entry + */ +zend_module_entry extname_module_entry = { + STANDARD_MODULE_HEADER, + "extname", + extname_functions, + PHP_MINIT(extname), + PHP_MSHUTDOWN(extname), + PHP_RINIT(extname), /* Replace with NULL if there's nothing to do at request start */ + PHP_RSHUTDOWN(extname), /* Replace with NULL if there's nothing to do at request end */ + PHP_MINFO(extname), + PHP_EXTNAME_VERSION, + STANDARD_MODULE_PROPERTIES +}; /* }}} */ -/* The previous line is meant for vim and emacs, so it can correctly fold and - unfold functions in source code. See the corresponding marks just before - function definition, where the functions purpose is also documented. Please - follow this convention for the convenience of others editing your code. -*/ -/* __function_stubs_here__ */ +#ifdef COMPILE_DL_EXTNAME +ZEND_GET_MODULE(extname) +#endif /* * Local variables: diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index a7a5071c08535..f8c6940c1fb1c 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -24,7 +24,7 @@ #include "libxml/uri.h" #include "ext/standard/md5.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include #include diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 00e80efbcbca4..c5900dc645af4 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1560,48 +1560,45 @@ PHP_METHOD(SoapServer, handle) } if (ZEND_NUM_ARGS() == 0) { - if (SG(request_info).raw_post_data) { - char *post_data = SG(request_info).raw_post_data; - int post_data_length = SG(request_info).raw_post_data_length; + if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) { zval **server_vars, **encoding; + php_stream_filter *zf = NULL; zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS && Z_TYPE_PP(server_vars) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS && Z_TYPE_PP(encoding) == IS_STRING) { - zval func; - zval retval; - zval param; - zval *params[1]; - - if ((strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 || - strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0) && - zend_hash_exists(EG(function_table), "gzinflate", sizeof("gzinflate"))) { - ZVAL_STRING(&func, "gzinflate", 0); - params[0] = ¶m; - ZVAL_STRINGL(params[0], post_data+10, post_data_length-10, 0); - INIT_PZVAL(params[0]); - } else if (strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 && - zend_hash_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress"))) { - ZVAL_STRING(&func, "gzuncompress", 0); - params[0] = ¶m; - ZVAL_STRINGL(params[0], post_data, post_data_length, 0); - INIT_PZVAL(params[0]); + + if (strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 + || strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0 + || strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 + ) { + zval filter_params; + + INIT_PZVAL(&filter_params); + array_init_size(&filter_params, 1); + add_assoc_long_ex(&filter_params, ZEND_STRS("window"), 0x2f); /* ANY WBITS */ + + zf = php_stream_filter_create("zlib.inflate", &filter_params, 0 TSRMLS_CC); + zval_dtor(&filter_params); + + if (zf) { + php_stream_filter_append(&SG(request_info).request_body->readfilters, zf); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't uncompress compressed request"); + return; + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_PP(encoding)); return; } - if (call_user_function(CG(function_table), (zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS && - Z_TYPE(retval) == IS_STRING) { - doc_request = soap_xmlParseMemory(Z_STRVAL(retval),Z_STRLEN(retval)); - zval_dtor(&retval); - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't uncompress compressed request"); - return; - } - } else { - doc_request = soap_xmlParseMemory(post_data, post_data_length); + } + + doc_request = soap_xmlParseFile("php://input" TSRMLS_CC); + + if (zf) { + php_stream_filter_remove(zf, 1 TSRMLS_CC); } } else { zval_ptr_dtor(&retval); diff --git a/ext/sockets/tests/ipv4loop.phpt b/ext/sockets/tests/ipv4loop.phpt index 9fdcc17dad06f..920b27b66e3fd 100644 --- a/ext/sockets/tests/ipv4loop.phpt +++ b/ext/sockets/tests/ipv4loop.phpt @@ -13,8 +13,15 @@ IPv4 Loopback test if (!$server) { die('Unable to create AF_INET socket [server]'); } - if (!socket_bind($server, '127.0.0.1', 31337)) { - die('Unable to bind to 127.0.0.1:31337'); + $bound = false; + for($port = 31337; $port < 31357; ++$port) { + if (socket_bind($server, '127.0.0.1', $port)) { + $bound = true; + break; + } + } + if (!$bound) { + die("Unable to bind to 127.0.0.1"); } if (!socket_listen($server, 2)) { die('Unable to listen on socket'); @@ -25,7 +32,7 @@ IPv4 Loopback test if (!$client) { die('Unable to create AF_INET socket [client]'); } - if (!socket_connect($client, '127.0.0.1', 31337)) { + if (!socket_connect($client, '127.0.0.1', $port)) { die('Unable to connect to server socket'); } diff --git a/ext/sockets/tests/ipv6loop.phpt b/ext/sockets/tests/ipv6loop.phpt index 6967605ffa2ed..4720cb49e4014 100644 --- a/ext/sockets/tests/ipv6loop.phpt +++ b/ext/sockets/tests/ipv6loop.phpt @@ -14,8 +14,15 @@ IPv6 Loopback test if (!$server) { die('Unable to create AF_INET6 socket [server]'); } - if (!socket_bind($server, '::1', 31337)) { - die('Unable to bind to [::1]:31337'); + $bound = false; + for($port = 31337; $port < 31357; ++$port) { + if (socket_bind($server, '::1', $port)) { + $bound = true; + break; + } + } + if (!$bound) { + die("Unable to bind to [::1]:$port"); } if (!socket_listen($server, 2)) { die('Unable to listen on socket'); @@ -26,7 +33,7 @@ IPv6 Loopback test if (!$client) { die('Unable to create AF_INET6 socket [client]'); } - if (!socket_connect($client, '::1', 31337)) { + if (!socket_connect($client, '::1', $port)) { die('Unable to connect to server socket'); } diff --git a/ext/sockets/tests/socket_getpeername_ipv4loop.phpt b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt index aa59abb8da032..b948e0e7f4a1c 100644 --- a/ext/sockets/tests/socket_getpeername_ipv4loop.phpt +++ b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt @@ -14,17 +14,23 @@ ext/sockets - socket_getpeername_ipv4loop - basic test /* Bind and connect sockets to localhost */ $localhost = '127.0.0.1'; - /* Hold the port associated to address */ - $port = 31337; - /* Setup socket server */ $server = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); if (!$server) { die('Unable to create AF_INET socket [server]'); } - - if (!socket_bind($server, $localhost, $port)) { - die('Unable to bind to '.$localhost.':'.$port); + + $minport = 31337; + $maxport = 31356; + $bound = false; + for($port = $minport; $port <= $maxport; ++$port) { + if (socket_bind($server, $localhost, $port)) { + $bound = true; + break; + } + } + if (!$bound) { + die('Unable to bind to '.$localhost); } if (!socket_listen($server, 2)) { die('Unable to listen on socket'); @@ -45,10 +51,10 @@ ext/sockets - socket_getpeername_ipv4loop - basic test die('Unable to accept connection'); } - if (!socket_getpeername($client, $address, $port)) { + if (!socket_getpeername($client, $address, $peerport)) { die('Unable to retrieve peer name'); } - var_dump($address, $port); + var_dump($address, $port === $peerport); socket_close($client); socket_close($socket); @@ -56,4 +62,4 @@ ext/sockets - socket_getpeername_ipv4loop - basic test ?> --EXPECT-- string(9) "127.0.0.1" -int(31337) +bool(true) diff --git a/ext/sockets/tests/socket_getpeername_ipv6loop.phpt b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt index e865f3e0642a7..5d03e32ce009e 100644 --- a/ext/sockets/tests/socket_getpeername_ipv6loop.phpt +++ b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt @@ -15,17 +15,23 @@ require 'ipv6_skipif.inc'; /* Bind and connect sockets to localhost */ $localhost = '::1'; - /* Hold the port associated to address */ - $port = 31337; - /* Setup socket server */ $server = socket_create(AF_INET6, SOCK_STREAM, getprotobyname('tcp')); if (!$server) { die('Unable to create AF_INET6 socket [server]'); } - - if (!socket_bind($server, $localhost, $port)) { - die('Unable to bind to '.$localhost.':'.$port); + + $minport = 31337; + $maxport = 31356; + $bound = false; + for($port = $minport; $port <= $maxport; ++$port) { + if (socket_bind($server, $localhost, $port)) { + $bound = true; + break; + } + } + if (!$bound) { + die('Unable to bind to '.$localhost); } if (!socket_listen($server, 2)) { die('Unable to listen on socket'); @@ -46,10 +52,10 @@ require 'ipv6_skipif.inc'; die('Unable to accept connection'); } - if (!socket_getpeername($client, $address, $port)) { + if (!socket_getpeername($client, $address, $peerport)) { die('Unable to retrieve peer name'); } - var_dump($address, $port); + var_dump($address, $port === $peerport); socket_close($client); socket_close($socket); @@ -57,4 +63,4 @@ require 'ipv6_skipif.inc'; ?> --EXPECT-- string(3) "::1" -int(31337) +bool(true) diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 4794f12443eaa..28aa19def3af6 100644 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -20,11 +20,6 @@ #define PHP_SPL_H #include "php.h" -#if defined(PHP_WIN32) -# include "win32/php_stdint.h" -#elif defined(HAVE_STDINT_H) -# include -#endif #include #if 0 diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 3dc7b7925c949..f73e8ee9f0db4 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -2938,8 +2938,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1) ZEND_ARG_INFO(0, format) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 273bc7506aa74..d5a9f83ae1411 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -603,7 +603,7 @@ SPL_METHOD(SplDoublyLinkedList, pop) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -626,7 +626,7 @@ SPL_METHOD(SplDoublyLinkedList, shift) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -649,7 +649,7 @@ SPL_METHOD(SplDoublyLinkedList, top) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -672,7 +672,7 @@ SPL_METHOD(SplDoublyLinkedList, bottom) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -695,7 +695,7 @@ SPL_METHOD(SplDoublyLinkedList, count) long count; spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -710,7 +710,7 @@ SPL_METHOD(SplDoublyLinkedList, isEmpty) { long count; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -750,7 +750,7 @@ SPL_METHOD(SplDoublyLinkedList, getIteratorMode) { spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 86a5371ed30d3..8624b35a4b616 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -583,7 +583,7 @@ SPL_METHOD(SplFixedArray, __construct) spl_fixedarray_object *intern; long size = 0; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) == FAILURE) { return; } @@ -613,7 +613,7 @@ SPL_METHOD(SplFixedArray, __wakeup) HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC); zval **data; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -643,7 +643,7 @@ SPL_METHOD(SplFixedArray, count) zval *object = getThis(); spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -661,7 +661,7 @@ SPL_METHOD(SplFixedArray, toArray) { spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -693,7 +693,7 @@ SPL_METHOD(SplFixedArray, fromArray) int num; zend_bool save_indexes = 1; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes) == FAILURE) { return; } @@ -777,7 +777,7 @@ SPL_METHOD(SplFixedArray, getSize) zval *object = getThis(); spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -797,7 +797,7 @@ SPL_METHOD(SplFixedArray, setSize) spl_fixedarray_object *intern; long size; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) { return; } diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index cb1f68dcf1196..77b31c06dcdc7 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -587,7 +587,7 @@ SPL_METHOD(SplHeap, count) long count; spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -602,7 +602,7 @@ SPL_METHOD(SplHeap, isEmpty) { spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -643,7 +643,7 @@ SPL_METHOD(SplHeap, extract) zval *value; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -705,7 +705,7 @@ SPL_METHOD(SplPriorityQueue, extract) zval *value, *value_out, **value_out_pp; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -748,7 +748,7 @@ SPL_METHOD(SplPriorityQueue, top) zval *value, **value_out; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -802,7 +802,7 @@ SPL_METHOD(SplHeap, recoverFromCorruption) { spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -835,7 +835,7 @@ SPL_METHOD(SplHeap, top) zval *value; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt b/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt index ed1f473be9ed3..d4f22f68a1ba3 100644 --- a/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt +++ b/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt @@ -4,7 +4,7 @@ DirectoryIterator::getBasename() - Basic Test PHPNW Testfest 2009 - Adrian Hardy --FILE-- --CLEAN-- diff --git a/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt b/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt index b2df8a55c947d..ef1352023748c 100644 --- a/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt +++ b/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt @@ -4,7 +4,7 @@ DirectoryIterator::getBasename() - Pass unexpected array PHPNW Testfest 2009 - Adrian Hardy --FILE-- --CLEAN-- diff --git a/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt b/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt index f0b2b0182cc90..f6bc266cb1d2a 100644 --- a/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt +++ b/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt @@ -5,7 +5,7 @@ Pawel Krynicki #testfest AmsterdamPHP 2012-06-23 --FILE-- diff --git a/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt b/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt index 7b12672e14c50..6527d84bfe854 100644 --- a/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt +++ b/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt @@ -5,7 +5,7 @@ Pawel Krynicki #testfest AmsterdamPHP 2012-06-23 --FILE-- --EXPECTF-- diff --git a/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt b/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt index abfe5f235f334..84b540369865c 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_basic.phpt @@ -2,7 +2,7 @@ SplFileObject::fgetcsv default path --FILE-- fgetcsv()); ?> --CLEAN-- --EXPECTF-- array(4) { diff --git a/ext/spl/tests/SplFileObject_fgetcsv_delimiter_basic.phpt b/ext/spl/tests/SplFileObject_fgetcsv_delimiter_basic.phpt index 4402d6ca4c32e..a8125a0257128 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_delimiter_basic.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_delimiter_basic.phpt @@ -2,7 +2,7 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv('|')); ?> --CLEAN-- --EXPECTF-- array(4) { diff --git a/ext/spl/tests/SplFileObject_fgetcsv_delimiter_error.phpt b/ext/spl/tests/SplFileObject_fgetcsv_delimiter_error.phpt index 64d6514a29a4a..169ded7dc3ccd 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_delimiter_error.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_delimiter_error.phpt @@ -2,7 +2,7 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv('invalid')); ?> --CLEAN-- --EXPECTF-- Warning: SplFileObject::fgetcsv(): delimiter must be a character in %s on line %d diff --git a/ext/spl/tests/SplFileObject_fgetcsv_enclosure_basic.phpt b/ext/spl/tests/SplFileObject_fgetcsv_enclosure_basic.phpt index efbb5fb68559f..efe765cbf84dd 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_enclosure_basic.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_enclosure_basic.phpt @@ -2,7 +2,7 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv(',', '"')); ?> --CLEAN-- --EXPECTF-- array(4) { diff --git a/ext/spl/tests/SplFileObject_fgetcsv_enclosure_error.phpt b/ext/spl/tests/SplFileObject_fgetcsv_enclosure_error.phpt index 7487b8353c96a..f8c14f0e35e41 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_enclosure_error.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_enclosure_error.phpt @@ -2,7 +2,7 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv(',', 'invalid')); ?> --CLEAN-- --EXPECTF-- Warning: SplFileObject::fgetcsv(): enclosure must be a character in %s on line %d diff --git a/ext/spl/tests/SplFileObject_fgetcsv_escape_basic.phpt b/ext/spl/tests/SplFileObject_fgetcsv_escape_basic.phpt index 1a94532b2b6b5..960f36d63f635 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_escape_basic.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_escape_basic.phpt @@ -2,16 +2,16 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv(',', '"', '"')); ?> --CLEAN-- --EXPECTF-- array(3) { diff --git a/ext/spl/tests/SplFileObject_fgetcsv_escape_default.phpt b/ext/spl/tests/SplFileObject_fgetcsv_escape_default.phpt index c628ac043d82c..69089636c1166 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_escape_default.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_escape_default.phpt @@ -2,16 +2,16 @@ SplFileObject::fgetcsv with default escape character --FILE-- fgetcsv()); ?> --CLEAN-- --EXPECTF-- array(3) { diff --git a/ext/spl/tests/SplFileObject_fgetcsv_escape_error.phpt b/ext/spl/tests/SplFileObject_fgetcsv_escape_error.phpt index fd90103bfa7ef..b49bcdd13c345 100644 --- a/ext/spl/tests/SplFileObject_fgetcsv_escape_error.phpt +++ b/ext/spl/tests/SplFileObject_fgetcsv_escape_error.phpt @@ -2,16 +2,16 @@ SplFileObject::fgetcsv with alternative delimiter --FILE-- fgetcsv(',', '"', 'invalid')); ?> --CLEAN-- --EXPECTF-- Warning: SplFileObject::fgetcsv(): escape must be a character in %s on line %d diff --git a/ext/spl/tests/SplFileObject_fputcsv_002.phpt b/ext/spl/tests/SplFileObject_fputcsv_002.phpt index db174931f704b..fdd4112ee6dd5 100644 --- a/ext/spl/tests/SplFileObject_fputcsv_002.phpt +++ b/ext/spl/tests/SplFileObject_fputcsv_002.phpt @@ -2,7 +2,7 @@ SplFileObject::fputcsv(): Checking data after calling the function --FILE-- --CLEAN-- --EXPECTF-- diff --git a/ext/spl/tests/SplFileObject_fputcsv_error.phpt b/ext/spl/tests/SplFileObject_fputcsv_error.phpt index 8368e4211dedc..cdee48c874b7e 100644 --- a/ext/spl/tests/SplFileObject_fputcsv_error.phpt +++ b/ext/spl/tests/SplFileObject_fputcsv_error.phpt @@ -2,7 +2,7 @@ SplFileObject::fputcsv(): error conditions --FILE-- fputcsv($fields, $delim, $enclosure, $fo) ); echo "Done\n"; --CLEAN-- --EXPECTF-- diff --git a/ext/spl/tests/bug51532.phpt b/ext/spl/tests/bug51532.phpt index 3a0722b2af68d..26eaa8f82f87d 100644 --- a/ext/spl/tests/bug51532.phpt +++ b/ext/spl/tests/bug51532.phpt @@ -4,7 +4,7 @@ SPL: Allow valid extension of SplFileObject::fscanf seek(2); $n = 0; diff --git a/ext/sqlite3/config.w32 b/ext/sqlite3/config.w32 index 01e4625feddd1..8ddb6b9ac8b4b 100644 --- a/ext/sqlite3/config.w32 +++ b/ext/sqlite3/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("sqlite3", "SQLite 3 support", "no"); if (PHP_SQLITE3 != "no") { - ADD_FLAG("CFLAGS_SQLITE3", "/D SQLITE_THREADSAFE=" + (PHP_ZTS == "yes" ? "1" : "0") + " /D SQLITE_ENABLE_FTS3=1 /D SQLITE_ENABLE_COLUMN_METADATA=1 /D SQLITE_CORE=1 "); + ADD_FLAG("CFLAGS_SQLITE3", "/D SQLITE_THREADSAFE=" + (PHP_ZTS == "yes" ? "1" : "0") + " /D SQLITE_ENABLE_FTS3=1 /D SQLITE_ENABLE_COLUMN_METADATA=1 /D SQLITE_CORE=1 /D SQLITE_API=__declspec(dllexport) "); EXTENSION("sqlite3", "sqlite3.c", null, "/I" + configure_module_dirname + "/libsqlite /I" + configure_module_dirname); ADD_SOURCES(configure_module_dirname + "/libsqlite", "sqlite3.c", "sqlite3"); diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 2aef0414aab69..19bf58deb8f19 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1890,7 +1890,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_bindvalue, 0, 0, 2) ZEND_ARG_INFO(0, type) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_sqlite3stmt_construct, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3stmt_construct, 0, 0, 1) ZEND_ARG_INFO(0, sqlite3) ZEND_END_ARG_INFO() diff --git a/ext/standard/array.c b/ext/standard/array.c index 360a691d38d76..17be59d6ca4b8 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -127,6 +127,9 @@ PHP_MINIT_FUNCTION(array) /* {{{ */ REGISTER_LONG_CONSTANT("COUNT_NORMAL", COUNT_NORMAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("COUNT_RECURSIVE", COUNT_RECURSIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_BOTH", ARRAY_FILTER_USE_BOTH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_KEY", ARRAY_FILTER_USE_KEY, CONST_CS | CONST_PERSISTENT); + return SUCCESS; } /* }}} */ @@ -830,7 +833,7 @@ PHP_FUNCTION(end) RETURN_FALSE; } - RETURN_ZVAL(*entry, 1, 0); + RETURN_ZVAL_FAST(*entry); } } /* }}} */ @@ -853,7 +856,7 @@ PHP_FUNCTION(prev) RETURN_FALSE; } - RETURN_ZVAL(*entry, 1, 0); + RETURN_ZVAL_FAST(*entry); } } /* }}} */ @@ -876,7 +879,7 @@ PHP_FUNCTION(next) RETURN_FALSE; } - RETURN_ZVAL(*entry, 1, 0); + RETURN_ZVAL_FAST(*entry); } } /* }}} */ @@ -899,7 +902,7 @@ PHP_FUNCTION(reset) RETURN_FALSE; } - RETURN_ZVAL(*entry, 1, 0); + RETURN_ZVAL_FAST(*entry); } } /* }}} */ @@ -918,7 +921,8 @@ PHP_FUNCTION(current) if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) { RETURN_FALSE; } - RETURN_ZVAL(*entry, 1, 0); + + RETURN_ZVAL_FAST(*entry); } /* }}} */ @@ -958,7 +962,7 @@ PHP_FUNCTION(min) RETVAL_NULL(); } else { if (zend_hash_minmax(Z_ARRVAL_PP(args[0]), php_array_data_compare, 0, (void **) &result TSRMLS_CC) == SUCCESS) { - RETVAL_ZVAL(*result, 1, 0); + RETVAL_ZVAL_FAST(*result); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain at least one element"); RETVAL_FALSE; @@ -978,7 +982,7 @@ PHP_FUNCTION(min) } } - RETVAL_ZVAL(*min, 1, 0); + RETVAL_ZVAL_FAST(*min); } if (args) { @@ -1009,7 +1013,7 @@ PHP_FUNCTION(max) RETVAL_NULL(); } else { if (zend_hash_minmax(Z_ARRVAL_PP(args[0]), php_array_data_compare, 1, (void **) &result TSRMLS_CC) == SUCCESS) { - RETVAL_ZVAL(*result, 1, 0); + RETVAL_ZVAL_FAST(*result); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain at least one element"); RETVAL_FALSE; @@ -1029,7 +1033,7 @@ PHP_FUNCTION(max) } } - RETVAL_ZVAL(*max, 1, 0); + RETVAL_ZVAL_FAST(*max); } if (args) { @@ -1955,7 +1959,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end) zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack)); } zend_hash_get_current_data(Z_ARRVAL_P(stack), (void **)&val); - RETVAL_ZVAL(*val, 1, 0); + RETVAL_ZVAL_FAST(*val); /* Delete the first or last value */ zend_hash_get_current_key_ex(Z_ARRVAL_P(stack), &key, &key_len, &index, 0, NULL); @@ -4204,9 +4208,11 @@ PHP_FUNCTION(array_filter) { zval *array; zval **operand; - zval **args[1]; + zval **args[2]; zval *retval = NULL; + zval *key = NULL; zend_bool have_callback = 0; + long use_type = 0; char *string_key; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; @@ -4214,7 +4220,7 @@ PHP_FUNCTION(array_filter) ulong num_key; HashPosition pos; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|f", &array, &fci, &fci_cache) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fl", &array, &fci, &fci_cache, &use_type) == FAILURE) { return; } @@ -4227,23 +4233,54 @@ PHP_FUNCTION(array_filter) have_callback = 1; fci.no_separation = 0; fci.retval_ptr_ptr = &retval; - fci.param_count = 1; + + if (use_type == ARRAY_FILTER_USE_BOTH) { + fci.param_count = 2; + args[1] = &key; + } else { + fci.param_count = 1; + if (use_type == ARRAY_FILTER_USE_KEY) { + args[0] = &key; + } + } } for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) ) { + int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos); + if (have_callback) { - args[0] = operand; + if (use_type) { + MAKE_STD_ZVAL(key); + /* Set up the key */ + switch (key_type) { + case HASH_KEY_IS_LONG: + Z_TYPE_P(key) = IS_LONG; + Z_LVAL_P(key) = num_key; + break; + + case HASH_KEY_IS_STRING: + ZVAL_STRINGL(key, string_key, string_key_len - 1, 1); + break; + } + } + + if (use_type != ARRAY_FILTER_USE_KEY) { + args[0] = operand; + } fci.params = args; if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) { - if (!zend_is_true(retval)) { - zval_ptr_dtor(&retval); + int retval_true = zend_is_true(retval); + + zval_ptr_dtor(&retval); + if (use_type) { + zval_ptr_dtor(&key); + } + if (!retval_true) { continue; - } else { - zval_ptr_dtor(&retval); } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback"); @@ -4254,7 +4291,7 @@ PHP_FUNCTION(array_filter) } zval_add_ref(operand); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos)) { + switch (key_type) { case HASH_KEY_IS_STRING: zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, operand, sizeof(zval *), NULL); break; diff --git a/ext/standard/assert.c b/ext/standard/assert.c index 631834c97c0f3..1a24ade79e64f 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -200,7 +200,7 @@ PHP_FUNCTION(assert) } if (ASSERTG(callback)) { - zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval **), 0); + zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval *), 0); zval *retval; int i; uint lineno = zend_get_executed_lineno(TSRMLS_C); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index b4128e066b7f8..cb1ada22e2a90 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -288,11 +288,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_reset, 0) ZEND_ARG_INFO(1, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_current, ZEND_SEND_PREFER_REF) +ZEND_BEGIN_ARG_INFO(arginfo_current, 0) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_key, ZEND_SEND_PREFER_REF) +ZEND_BEGIN_ARG_INFO(arginfo_key, 0) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) ZEND_END_ARG_INFO() @@ -564,13 +564,14 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_udiff_uassoc, 0) ZEND_ARG_INFO(0, callback_key_comp_func) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_multisort, ZEND_SEND_PREFER_REF, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_multisort, 0, 0, 1) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr1) /* ARRAY_INFO(0, arg1, 0) */ ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_ASC_or_SORT_DESC) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr2) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_ASC_or_SORT_DESC) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING) + ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, more_array_and_sort_options) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) @@ -595,6 +596,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_filter, 0, 0, 1) ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, use_keys) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_map, 0, 0, 2) @@ -1139,10 +1141,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_fgetss, 0, 0, 1) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_fscanf, 1, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_fscanf, 0, 0, 2) ZEND_ARG_INFO(0, stream) ZEND_ARG_INFO(0, format) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_fwrite, 0, 0, 2) @@ -2450,10 +2452,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_str_pad, 0, 0, 2) ZEND_ARG_INFO(0, pad_type) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_sscanf, 1, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_sscanf, 0, 0, 2) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, format) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_str_rot13, 0) @@ -2679,6 +2681,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_unserialize, 0) ZEND_ARG_INFO(0, variable_representation) + ZEND_ARG_INFO(1, consumed) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_memory_get_usage, 0, 0, 0) diff --git a/ext/standard/credits_ext.h b/ext/standard/credits_ext.h index 2770d162fb37f..382e70e7d7fc3 100644 --- a/ext/standard/credits_ext.h +++ b/ext/standard/credits_ext.h @@ -42,8 +42,8 @@ CREDIT_LINE("MS SQL", "Frank M. Kromann"); CREDIT_LINE("Multibyte String Functions", "Tsukada Takuya, Rui Hirokawa"); CREDIT_LINE("MySQL driver for PDO", "George Schlossnagle, Wez Furlong, Ilia Alshanetsky, Johannes Schlueter"); CREDIT_LINE("MySQLi", "Zak Greant, Georg Richter, Andrey Hristov, Ulf Wendel"); -CREDIT_LINE("MySQLnd", "Andrey Hristov, Ulf Wendel, Georg Richter, Johannes Schlueter"); -CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter, Andrey Hristov"); +CREDIT_LINE("MySQLnd", "Andrey Hristov, Ulf Wendel, Georg Richter"); +CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter"); CREDIT_LINE("OCI8", "Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal, Andi Gutmans, Wez Furlong, Christopher Jones, Oracle Corporation"); CREDIT_LINE("ODBC driver for PDO", "Wez Furlong"); CREDIT_LINE("ODBC", "Stig Bakken, Andreas Karajannis, Frank M. Kromann, Daniel R. Kalowsky"); diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 113a5bd0f516c..354c263afbd0c 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -272,6 +272,8 @@ PHP_FUNCTION(crypt) if (salt_in) { memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash."); } /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */ diff --git a/ext/standard/crypt_freesec.h b/ext/standard/crypt_freesec.h index a87663d4feaaf..860462a2dd622 100644 --- a/ext/standard/crypt_freesec.h +++ b/ext/standard/crypt_freesec.h @@ -4,26 +4,13 @@ #define _CRYPT_FREESEC_H #if PHP_WIN32 -# include "win32/php_stdint.h" # ifndef inline # define inline __inline # endif -#else -# include "php_config.h" -# if HAVE_INTTYPES_H -# include -# elif HAVE_STDINT_H -# include -# endif -# ifndef HAVE_UINT32_T -# if SIZEOF_INT == 4 -typedef unsigned int uint32_t; -# elif SIZEOF_LONG == 4 -typedef unsigned long int uint32_t; -# endif -# endif #endif +#include "php_stdint.h" + #define MD5_HASH_MAX_LEN 120 struct php_crypt_extended_data { diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index d334e3d477d89..ccfa66bd60a8e 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -9,15 +9,9 @@ #include #ifdef PHP_WIN32 -# include "win32/php_stdint.h" # define __alignof__ __alignof # define alloca _alloca #else -# if HAVE_INTTYPES_H -# include -# elif HAVE_STDINT_H -# include -# endif # ifndef HAVE_ALIGNOF # include # define __alignof__(type) offsetof (struct { char c; type member;}, member) diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index 0955532131588..ebabed9d24f44 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -8,15 +8,9 @@ #include #include #ifdef PHP_WIN32 -# include "win32/php_stdint.h" # define __alignof__ __alignof # define alloca _alloca #else -# if HAVE_INTTYPES_H -# include -# elif HAVE_STDINT_H -# include -# endif # ifndef HAVE_ALIGNOF # include # define __alignof__(type) offsetof (struct { char c; type member;}, member) diff --git a/ext/standard/css.c b/ext/standard/css.c index d76f9ee662676..459a7bfc307cf 100644 --- a/ext/standard/css.c +++ b/ext/standard/css.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Colin Viebrock | + | Authors: Colin Viebrock | +----------------------------------------------------------------------+ */ @@ -23,25 +23,24 @@ PHPAPI void php_info_print_css(TSRMLS_D) /* {{{ */ { - PUTS("body {background-color: #ffffff; color: #000000;}\n"); - PUTS("body, td, th, h1, h2 {font-family: sans-serif;}\n"); - PUTS("pre {margin: 0px; font-family: monospace;}\n"); - PUTS("a:link {color: #000099; text-decoration: none; background-color: #ffffff;}\n"); + PUTS("body {background-color: #fff; color: #222; font-family: sans-serif;}\n"); + PUTS("pre {margin: 0; font-family: monospace;}\n"); + PUTS("a:link {color: #009; text-decoration: none; background-color: #fff;}\n"); PUTS("a:hover {text-decoration: underline;}\n"); - PUTS("table {border-collapse: collapse;}\n"); + PUTS("table {border-collapse: collapse; border: 0; width: 934px; box-shadow: 1px 2px 3px #ccc;}\n"); PUTS(".center {text-align: center;}\n"); - PUTS(".center table { margin-left: auto; margin-right: auto; text-align: left;}\n"); - PUTS(".center th { text-align: center !important; }\n"); - PUTS("td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}\n"); + PUTS(".center table {margin: 1em auto; text-align: left;}\n"); + PUTS(".center th {text-align: center !important;}\n"); + PUTS("td, th {border: 1px solid #666; font-size: 75%; vertical-align: baseline; padding: 4px 5px;}\n"); PUTS("h1 {font-size: 150%;}\n"); PUTS("h2 {font-size: 125%;}\n"); PUTS(".p {text-align: left;}\n"); - PUTS(".e {background-color: #ccccff; font-weight: bold; color: #000000;}\n"); - PUTS(".h {background-color: #9999cc; font-weight: bold; color: #000000;}\n"); - PUTS(".v {background-color: #cccccc; color: #000000;}\n"); - PUTS(".vr {background-color: #cccccc; text-align: right; color: #000000;}\n"); - PUTS("img {float: right; border: 0px;}\n"); - PUTS("hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}\n"); + PUTS(".e {background-color: #ccf; width: 300px; font-weight: bold;}\n"); + PUTS(".h {background-color: #99c; font-weight: bold;}\n"); + PUTS(".v {background-color: #ddd; max-width: 300px; overflow-x: auto;}\n"); + PUTS(".v i {color: #999;}\n"); + PUTS("img {float: right; border: 0;}\n"); + PUTS("hr {width: 934px; background-color: #ccc; border: 0; height: 1px;}\n"); } /* }}} */ diff --git a/ext/standard/css.h b/ext/standard/css.h index d7275e08efd04..0b3ae87cbd86c 100644 --- a/ext/standard/css.h +++ b/ext/standard/css.h @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Colin Viebrock | + | Authors: Colin Viebrock | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/dir.c b/ext/standard/dir.c index ef28e9feafbc6..ca7e576c922fd 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -491,13 +491,18 @@ PHP_FUNCTION(glob) /* now catch the FreeBSD style of "no matches" */ if (!globbuf.gl_pathc || !globbuf.gl_pathv) { no_results: +#ifndef PHP_WIN32 + /* Paths containing '*', '?' and some other chars are + illegal on Windows but legit on other platforms. For + this reason the direct basedir check against the glob + query is senseless on windows. For instance while *.txt + is a pretty valid filename on EXT3, it's invalid on NTFS. */ if (PG(open_basedir) && *PG(open_basedir)) { - struct stat s; - - if (0 != VCWD_STAT(pattern, &s) || S_IFDIR != (s.st_mode & S_IFMT)) { + if (php_check_open_basedir_ex(pattern, 0 TSRMLS_CC)) { RETURN_FALSE; } } +#endif array_init(return_value); return; } diff --git a/ext/standard/file.c b/ext/standard/file.c index ad6bdad34f2ed..2bd35bf8941ae 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -223,10 +223,14 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT); @@ -1284,7 +1288,7 @@ PHPAPI PHP_FUNCTION(fseek) */ /* DEPRECATED APIs: Use php_stream_mkdir() instead */ -PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC) +PHPAPI int php_mkdir_ex(const char *dir, long mode, int options TSRMLS_DC) { int ret; @@ -1299,7 +1303,7 @@ PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC) return ret; } -PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC) +PHPAPI int php_mkdir(const char *dir, long mode TSRMLS_DC) { return php_mkdir_ex(dir, mode, REPORT_ERRORS TSRMLS_CC); } @@ -1623,7 +1627,7 @@ PHP_FUNCTION(copy) /* {{{ php_copy_file */ -PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC) +PHPAPI int php_copy_file(const char *src, const char *dest TSRMLS_DC) { return php_copy_file_ctx(src, dest, 0, NULL TSRMLS_CC); } @@ -1631,7 +1635,7 @@ PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC) /* {{{ php_copy_file_ex */ -PHPAPI int php_copy_file_ex(char *src, char *dest, int src_flg TSRMLS_DC) +PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_flg TSRMLS_DC) { return php_copy_file_ctx(src, dest, 0, NULL TSRMLS_CC); } @@ -1639,7 +1643,7 @@ PHPAPI int php_copy_file_ex(char *src, char *dest, int src_flg TSRMLS_DC) /* {{{ php_copy_file_ctx */ -PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_flg, php_stream_context *ctx TSRMLS_DC) +PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_flg, php_stream_context *ctx TSRMLS_DC) { php_stream *srcstream = NULL, *deststream = NULL; int ret = FAILURE; diff --git a/ext/standard/file.h b/ext/standard/file.h index 2bcdfd64bf5e6..d6f142a7690d1 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -74,11 +74,11 @@ PHP_MINIT_FUNCTION(user_streams); PHPAPI int php_le_stream_context(TSRMLS_D); PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC); -PHPAPI int php_copy_file(char *src, char *dest TSRMLS_DC); -PHPAPI int php_copy_file_ex(char *src, char *dest, int src_chk TSRMLS_DC); -PHPAPI int php_copy_file_ctx(char *src, char *dest, int src_chk, php_stream_context *ctx TSRMLS_DC); -PHPAPI int php_mkdir_ex(char *dir, long mode, int options TSRMLS_DC); -PHPAPI int php_mkdir(char *dir, long mode TSRMLS_DC); +PHPAPI int php_copy_file(const char *src, const char *dest TSRMLS_DC); +PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_chk TSRMLS_DC); +PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_chk, php_stream_context *ctx TSRMLS_DC); +PHPAPI int php_mkdir_ex(const char *dir, long mode, int options TSRMLS_DC); +PHPAPI int php_mkdir(const char *dir, long mode TSRMLS_DC); PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char escape_char, size_t buf_len, char *buf, zval *return_value TSRMLS_DC); PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char enclosure, char escape_char TSRMLS_DC); @@ -121,7 +121,7 @@ typedef struct { long default_socket_timeout; char *user_agent; /* for the http wrapper */ char *from_address; /* for the ftp and http wrappers */ - char *user_stream_current_filename; /* for simple recursion protection */ + const char *user_stream_current_filename; /* for simple recursion protection */ php_stream_context *default_context; HashTable *stream_wrappers; /* per-request copy of url_stream_wrappers_hash */ HashTable *stream_filters; /* per-request copy of stream_filters_hash */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 2713d23f1d826..0b40e7319b398 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -857,7 +857,7 @@ PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int typ "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks" }; - char *local; + const char *local; php_stream_wrapper *wrapper; if (!filename_length) { diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 86975d7f5b20b..d04ef52be7494 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -130,8 +130,9 @@ static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream * /* {{{ php_ftp_fopen_connect */ -static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, - php_stream **preuseid, php_url **presource, int *puse_ssl, int *puse_ssl_on_data TSRMLS_DC) +static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, + char **opened_path, php_stream_context *context, php_stream **preuseid, + php_url **presource, int *puse_ssl, int *puse_ssl_on_data TSRMLS_DC) { php_stream *stream = NULL, *reuseid = NULL; php_url *resource = NULL; @@ -410,7 +411,8 @@ static unsigned short php_fopen_do_pasv(php_stream *stream, char *ip, size_t ip_ /* {{{ php_fopen_url_wrap_ftp */ -php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *path, const char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL, *datastream = NULL; php_url *resource = NULL; @@ -691,7 +693,8 @@ static php_stream_ops php_ftp_dirstream_ops = { /* {{{ php_stream_ftp_opendir */ -php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, + char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { php_stream *stream, *reuseid, *datastream = NULL; php_ftp_dirstream_data *dirsdata; @@ -780,7 +783,7 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, char *path, cha /* {{{ php_stream_ftp_url_stat */ -static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; @@ -903,7 +906,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, char *url, int f /* {{{ php_stream_ftp_unlink */ -static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; @@ -953,7 +956,7 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, char *url, int opt /* {{{ php_stream_ftp_rename */ -static int php_stream_ftp_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) +static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC) { php_stream *stream = NULL; php_url *resource_from = NULL, *resource_to = NULL; @@ -1032,7 +1035,7 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, char *url_from, ch /* {{{ php_stream_ftp_mkdir */ -static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC) +static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; @@ -1126,7 +1129,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, char *url, int mode /* {{{ php_stream_ftp_rmdir */ -static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 4605e7494fa3d..f5184ceec6019 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -80,6 +80,7 @@ #define HTTP_HEADER_FROM 8 #define HTTP_HEADER_CONTENT_LENGTH 16 #define HTTP_HEADER_TYPE 32 +#define HTTP_HEADER_CONNECTION 64 #define HTTP_WRAPPER_HEADER_INIT 1 #define HTTP_WRAPPER_REDIRECTED 2 @@ -108,7 +109,9 @@ static inline void strip_header(char *header_bag, char *lc_header_bag, } } -php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ +php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, + const char *path, const char *mode, int options, char **opened_path, + php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *stream = NULL; php_url *resource = NULL; @@ -409,8 +412,6 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, strlcat(scratch, " HTTP/", scratch_len); strlcat(scratch, protocol_version, scratch_len); strlcat(scratch, "\r\n", scratch_len); - efree(protocol_version); - protocol_version = NULL; } else { strlcat(scratch, " HTTP/1.0\r\n", scratch_len); } @@ -490,6 +491,11 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_TYPE; } + if ((s = strstr(tmp, "connection:")) && + (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || + *(s-1) == '\t' || *(s-1) == ' ')) { + have_header |= HTTP_HEADER_CONNECTION; + } /* remove Proxy-Authorization header */ if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || @@ -563,6 +569,16 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, } } + /* Send a Connection: close header when using HTTP 1.1 or later to avoid + * hanging when the server interprets the RFC literally and establishes a + * keep-alive connection, unless the user specifically requests something + * else by specifying a Connection header in the context options. */ + if (protocol_version && + ((have_header & HTTP_HEADER_CONNECTION) == 0) && + (strncmp(protocol_version, "1.0", MIN(protocol_version_len, 3)) > 0)) { + php_stream_write_string(stream, "Connection: close\r\n"); + } + if (context && php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS && Z_TYPE_PP(ua_zval) == IS_STRING) { @@ -922,7 +938,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, } /* }}} */ -php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ +php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ { return php_stream_url_wrap_http_ex(wrapper, path, mode, options, opened_path, context, PHP_URL_REDIRECT_MAX, HTTP_WRAPPER_HEADER_INIT STREAMS_CC TSRMLS_CC); } diff --git a/ext/standard/info.c b/ext/standard/info.c index 48e0e85cc51d9..cfff023afa8e5 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | - | Colin Viebrock | + | Colin Viebrock | +----------------------------------------------------------------------+ */ @@ -67,7 +67,7 @@ static int php_info_print_html_esc(const char *str, int len) /* {{{ */ int written; char *new_str; TSRMLS_FETCH(); - + new_str = php_escape_html_entities((unsigned char *) str, len, &new_len, 0, ENT_QUOTES, "utf-8" TSRMLS_CC); written = php_output_write(new_str, new_len TSRMLS_CC); efree(new_str); @@ -81,11 +81,11 @@ static int php_info_printf(const char *fmt, ...) /* {{{ */ int len, written; va_list argv; TSRMLS_FETCH(); - + va_start(argv, fmt); len = vspprintf(&buf, 0, fmt, argv); va_end(argv); - + written = php_output_write(buf, len TSRMLS_CC); efree(buf); return written; @@ -103,7 +103,7 @@ static void php_info_print_stream_hash(const char *name, HashTable *ht TSRMLS_DC { char *key; uint len; - + if (ht) { if (zend_hash_num_elements(ht)) { HashPosition pos; @@ -113,7 +113,7 @@ static void php_info_print_stream_hash(const char *name, HashTable *ht TSRMLS_DC } else { php_info_printf("\nRegistered %s => ", name); } - + zend_hash_internal_pointer_reset_ex(ht, &pos); while (zend_hash_get_current_key_ex(ht, &key, &len, NULL, 0, &pos) == HASH_KEY_IS_STRING) { @@ -129,7 +129,7 @@ static void php_info_print_stream_hash(const char *name, HashTable *ht TSRMLS_DC break; } } - + if (!sapi_module.phpinfo_as_text) { php_info_print("\n"); } @@ -164,10 +164,10 @@ PHPAPI void php_info_print_module(zend_module_entry *zend_module TSRMLS_DC) /* { } } else { if (!sapi_module.phpinfo_as_text) { - php_info_printf("%s\n", zend_module->name); + php_info_printf("%s\n", zend_module->name); } else { php_info_printf("%s\n", zend_module->name); - } + } } } /* }}} */ @@ -212,7 +212,7 @@ static void php_print_gpcse_array(char *name, uint name_length TSRMLS_DC) php_info_print(name); php_info_print("[\""); - + switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: if (!sapi_module.phpinfo_as_text) { @@ -442,7 +442,7 @@ char* php_get_windows_name() sub = "Web Edition"; else sub = "Standard Edition"; } - } + } } if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) { @@ -535,7 +535,7 @@ PHPAPI char *php_get_uname(char mode) DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; char ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; - + GetComputerName(ComputerName, &dwSize); if (mode == 's') { @@ -584,7 +584,7 @@ PHPAPI char *php_get_uname(char mode) if (mode == 's') { php_uname = buf.sysname; } else if (mode == 'r') { - snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d.%d", + snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d.%d", buf.netware_major, buf.netware_minor, buf.netware_revision); php_uname = tmp_uname; } else if (mode == 'n') { @@ -674,7 +674,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) char temp_api[10]; php_uname = php_get_uname('a'); - + if (!sapi_module.phpinfo_as_text) { php_info_print_box_start(1); } @@ -698,7 +698,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) php_info_printf("

PHP Version %s

\n", PHP_VERSION); } else { php_info_print_table_row(2, "PHP Version", PHP_VERSION); - } + } php_info_print_box_end(); php_info_print_table_start(); php_info_print_table_row(2, "System", php_uname ); @@ -783,7 +783,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) #else php_info_print_table_row(2, "DTrace Support", "disabled" ); #endif - + php_info_print_stream_hash("PHP Streams", php_stream_get_url_stream_wrappers_hash() TSRMLS_CC); php_info_print_stream_hash("Stream Socket Transports", php_stream_xport_get_hash() TSRMLS_CC); php_info_print_stream_hash("Stream Filters", php_get_stream_filters_hash() TSRMLS_CC); @@ -815,7 +815,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) php_info_print("

Configuration

\n"); } else { SECTION("Configuration"); - } + } if (!(flag & PHP_INFO_MODULES)) { SECTION("PHP Core"); display_ini_entries(NULL); @@ -889,7 +889,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) } - if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) { + if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) { php_info_print_hr(); php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE TSRMLS_CC); } @@ -930,24 +930,24 @@ PHPAPI void php_print_info(int flag TSRMLS_DC) if (!sapi_module.phpinfo_as_text) { php_info_print(""); - } + } } /* }}} */ PHPAPI void php_info_print_table_start(void) /* {{{ */ { if (!sapi_module.phpinfo_as_text) { - php_info_print("\n"); + php_info_print("
\n"); } else { php_info_print("\n"); - } + } } /* }}} */ PHPAPI void php_info_print_table_end(void) /* {{{ */ { if (!sapi_module.phpinfo_as_text) { - php_info_print("

\n"); + php_info_print("\n"); } } @@ -965,7 +965,7 @@ PHPAPI void php_info_print_box_start(int flag) /* {{{ */ php_info_print("\n"); } else { php_info_print("\n"); - } + } } } /* }}} */ @@ -998,7 +998,7 @@ PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) /* { } else { spaces = (74 - strlen(header)); php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " "); - } + } } /* }}} */ @@ -1013,7 +1013,7 @@ PHPAPI void php_info_print_table_header(int num_cols, ...) va_start(row_elements, num_cols); if (!sapi_module.phpinfo_as_text) { php_info_print(""); - } + } for (i=0; i"); - } + } for (i=0; i", (i==0 ? "e" : value_class ) ); - } + } row_element = va_arg(row_elements, char *); if (!row_element || !*row_element) { if (!sapi_module.phpinfo_as_text) { @@ -1071,7 +1071,7 @@ static void php_info_print_table_row_internal(int num_cols, php_info_print(row_element); if (i < num_cols-1) { php_info_print(" => "); - } + } } } if (!sapi_module.phpinfo_as_text) { @@ -1091,7 +1091,7 @@ static void php_info_print_table_row_internal(int num_cols, PHPAPI void php_info_print_table_row(int num_cols, ...) { va_list row_elements; - + va_start(row_elements, num_cols); php_info_print_table_row_internal(num_cols, "v", row_elements); va_end(row_elements); @@ -1100,11 +1100,11 @@ PHPAPI void php_info_print_table_row(int num_cols, ...) /* {{{ php_info_print_table_row_ex */ -PHPAPI void php_info_print_table_row_ex(int num_cols, const char *value_class, +PHPAPI void php_info_print_table_row_ex(int num_cols, const char *value_class, ...) { va_list row_elements; - + va_start(row_elements, value_class); php_info_print_table_row_internal(num_cols, value_class, row_elements); va_end(row_elements); @@ -1232,7 +1232,7 @@ PHP_FUNCTION(php_ini_scanned_files) if (zend_parse_parameters_none() == FAILURE) { return; } - + if (strlen(PHP_CONFIG_FILE_SCAN_DIR) && php_ini_scanned_files) { RETURN_STRING(php_ini_scanned_files, 1); } else { @@ -1248,7 +1248,7 @@ PHP_FUNCTION(php_ini_loaded_file) if (zend_parse_parameters_none() == FAILURE) { return; } - + if (php_ini_opened_path) { RETURN_STRING(php_ini_opened_path, 1); } else { diff --git a/ext/standard/info.h b/ext/standard/info.h index 46a0dfc24080d..b616204b30f29 100644 --- a/ext/standard/info.h +++ b/ext/standard/info.h @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ @@ -14,6 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | + | Colin Viebrock | +----------------------------------------------------------------------+ */ @@ -22,9 +23,9 @@ #ifndef INFO_H #define INFO_H -#define PHP_ENTRY_NAME_COLOR "#ccccff" -#define PHP_CONTENTS_COLOR "#cccccc" -#define PHP_HEADER_COLOR "#9999cc" +#define PHP_ENTRY_NAME_COLOR "#ccf" +#define PHP_CONTENTS_COLOR "#ccc" +#define PHP_HEADER_COLOR "#99c" #define PHP_INFO_GENERAL (1<<0) #define PHP_INFO_CREDITS (1<<1) @@ -50,9 +51,9 @@ #endif /* HAVE_CREDITS_DEFS */ -#define PHP_LOGO_DATA_URI "data:image/gif;base64,R0lGODlheABDAOZqAH+CuDk3RyglKszN4qGky9PV57K01ENCWIOGuYKDs1JScpCSwsLE3qqs0ExLY1tcg93e7Ds4PG5xpWptnWFjjXV5sXt+teXm8JmcxoyNwbm62Wtrkk5Oa3F0qXp6o4iLvXJ0o3RzmI6QwVpbfuLj73t9raSl0G1wonJ2rJWWyLu92XR4roWIu5KVw9jZ6pKSxGRmkmtun6WozpSWxS4rL1NRaLO012xqjFxbdoqNv2ZolmhqmpyfyDEuOa6w05yczVVWeJ6hypaZxYGCr2dplz89ULy+2l5giZiZyIyOv4mKuldYfLa319XX6CIeIGxvns7Q5L/A3Hd7tHZ4p19efZmZzG5vmHN3riIeH////5COj1lWV8fGx+7u9dXU1fb2+oKAgayqq3Ryc/Hw8Z6cnePi40tISbm4uWdkZYmJtgD/AEdGX9/g7ZuczGlrnG9zp4yMuri52bi615qbzKeqz9vc65qcyWZkhGhniaeo0m5woIuLucbH4MfJ4WlsnJeYyyH5BAEAAGoALAAAAAB4AEMAAAf/gGqCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXlm0/bXOYnp+gP3l5Nj4acUwaGkwGPj4NMgRBPBhCLQtJIjkfGTkiLymgwqENGgx9TQVQUAN9fAxRUSpyrK90sbNCMy26HwgAFhYVVyglFgkZwcPrjCZxfC5sbBAQdS7JA9QysyIf/iwAEQgEQLDgN4LhpKxA8UbCCT87nkwZkoSdRTVBbAxgQ+KCRxIk8jUQskCKyZMoU6pceXJcBwkTduiAQeEIBStDRFzEFIQJFI4eL7gwQqcFy6NIk6K88iYGjCNHHoxYcsSDzp2Qfmh0AYEjBCMEWCgdSzbplRM6HiwBokDBiCkz/7AuMqGhQBMXdQoYSFK2r1+kHWAsUcCBgwM8CeQayhNlAJQCA3zk+LtyAYbLmDF8oJz0DQUFDtasUeBBsZo8Rvj0GcBkBueVH7JwmU2bS5fXSt0sWXPggIMQO91FYcCgAQLcKzFwwcK8uZnbyJN22F2kyJrSw374kGNEBQ8L0VeqINO8uZgC4ZVeeXAgQAAOcECZMMBEDgEA6VcWEFOeORkV+Sn1hgLu9XAHJnPQ4YMBMhwXoEpdmNEfFlwQ8KBSMazRQw8H7FHJDzI00EBJF6YEQBYTYpHFZiUm9UAAGwInSRsE7ONgiycpN6EZX+ColB9F0EADFZHYEQQBM4CH1P8HmTXZJItHqRDGhGJc0CSJLDHp5Jb4jYWCAzQIUMMjSGAQBJRHffBFFmy26eabWXRRQANdolQAGBOSAWebFwxg4UkL7Ckom10M0IBSQAgggAONzCAEBmIpRcByKVZqBhhcfAEgSl1sUWmKNGyhRRldkGjAlJ9OuAUYXnRxKFIjCOAEo4psI8SNSY2X6qdbeAFBlyfu+ikYY2AgxQB4CqtqGQMkNYITTuCQSAoitIBmUhDwp2yKYUBgEgZebJsiGrdd4Km45dHgRbNIrQEtdoX84ctkZX0hIbr9eQGglPjm2wCK/TZHQxl/HhWAEwIsYEg/9JIVW8DlbdHjnRAzp8X/BeFWjIUY0B3VgaxjEpICAh/UOdakO8I5xhnaTugFAZ1OyMWbY3CBRopaZIFqxHCWcca5E5aBJUsKQJsGId7gOpau/YnhLUoLNNAFeRNqwQDA/a2IEgYNfBFB1VloUTW7gBrwRbL9hWGAUjTMOsgfACCgZFnZ5rmpiVl83XQWGZfH40oQAN1czoIzd8baKn0wBs53H7UEtAqrIYIFJpNlr8wFpxS4qjpT+XRKMfd3RhY0BG3sSqGXp0XjLHUA7Q2CsJBQXw9POMa1J23eHxpZoN3cfyoFG3QZE9KQxVGpD846S0W4rUY4c5OFcn8R9MjS5f0RjrlK4BafxRmqXnAU/9blAa8UB070IEgFlDFdHhqfp1R72uQ3d7tK/Pa3Rdhjs4QB8dtTCgWgJYgVUKZu2VueSQwAvqD1rTnV04/vmAOGLBQOC4djCQOo1p/7CZCAKbgC+/yCvfJUiCXJY04EOre7+J0khVgIA+lMtxIAeG1C5CLLAJ0gCBQYsC/C6yDujkWp7PWuassLYnm8AMB0HU8/HCxPGBS4kh0KogMoGCFZdES9J6LkAwXwQun6Q4MxfOGCJ0xJ9yb0vfBxDwJinFD1KncUK6phIVpcWhSZQy4V+FEFEOjCGLQwRtENoH7M8SBK8sczsWWvC38EZBfK4EiZUXEl6FPf8zpwhb7sR/9VWghlKMVwrxSJ4QsEeKAKvWinCWKhghcUlSi1QMphia8szaPVB97Qgb5ESGNo+MICToVDF5rEXBOSYSEDdsqhSed1gkiBBN7wQ6UosV/NPJYrrbYSRGKBiRoDgzD78jgnRO55EujlWNbYLxqcYZxSQGZ/uPCqramSOW0MWATOcAFnss15gnjBCSTQSaUwUlxmIMMYBlCnGXbQn8TUH//wZQYZMoCOSSmaE45GiCGc4A1joZj+ZjlLMnBhDIVCU6BIGkpWnkQFXGDp6C4oBpaG0qQoZcAQpQMyQ6TgBCdQJ1JgyIUL0IMeBfgjAfxpEkAe9aiZA9QAnkqPQy6TOV7/MOpRk+pHAux0LAdL2CGSEIMToAAp10wkU30khQU0sTxZwChy3OUEeBkiAWUtaHLuuUK2sqQBDYxYx/JTTmkpogR5ZclB+WhMv0qBAZVsDhjQE6By0moRiDWrBKvGAMeqRHdSvCRlNHpZRpRgAjHoQB6lQNR6etYkeXPZ6aLTgQNAq7SNSABqJaDFtGJhDGv10QIWx0a5+oUIPYCWYSOhhCdMQLNS+N8Wpktd3r3WntSlLhgG+xoFyEoAMprEC0DghxjwFgAFoCo9EHddKaBXvRBwLWWIcDAnRICjlkiAG1D7htW2168nsK1yQfGCKfgBtar9r19RwAFZOaEI+AWF/xL04IYD91fBJTrBGhzcg/CygwUUPrAEzorh8BzhAIoSQA9gpxgWgGAHbnBDDKhZYsr4gQMBCJMAAsBi0wgiCSUgwg5gPAEa1zgpEyBQD4QkJrv6eBApSIAedEAEIbshqP7F8BuOgOMNLbkIeHjBkxfxAinr4Mxn3sFHSXzdHRxBAe2B0YYOcAMPjfkRL0DAFIgAgz77mQh++KhQ8zMBIjwANNVxj6JxEAI735kSIhjCnilA6UpT+gh9rnCg38BpTkvg058GKlCJcGm2iKY3B6hOEQJwABxsIDGPFkYKPlACEFgBKlB5gK53PZUlrAUIbGkLYQpjmNCcujdFUAAVbjgwBDHHWjEpUAICPOCBDWwgLb4GdrDbQmzDcIAKIxiBFaxQgmY/+9yLEEEaEHAVdLv73fCOd7wDAQA7AA==" -#define PHP_EGG_LOGO_DATA_URI "data:image/gif;base64,R0lGODlheABDAOf/ABIZISAeIhwhLA8jRwYlVSUoLyIpNSkoKwkvbR4tRBUwVDMuNysxOx87Yg89gDo3RTI5SgBCkDg6PDY7RyBCcTxBQz9BVD9ETxxPkQ9SoktIYkROVkpNWDJSeilVhkxObEZTZQVevgBfxVZQZRxcn1BUYFNTc1FXWRZht1ZYVQBm0ghlzBhksVVafyNlqSpkn1hcZwBr2EVfhABs0lRdcF5adRJpyWBcaVlgYl5dh15efh5q0gdw3iFsxhBy2Rtxxhhx0Ttsn2BkigB45SxwtDFwq0dslGNoc1pqfRtz6GRmkypzwFZuiQl772psaWlpiiF25Ax94zB10BB+3iV44BR96yN71TJ5vit7zih73GluoDt6tk53nix66QOG+nBwl0l7r3F2cjOAzSKB9guI9SKC8HF1lW90pm93jTCC3SaE6zWC12F8knR6fHV5gzaC5SmH6ESC3y6H9kGGyiqJ8UuDzXx5oWV9v1aA0nl6qWmAnXl6tHJ8tV6AyVGGuS6K/EyHwyKO/D6J5T+K2SGQ9zqL3ziN9jaP6jmP8WaHwYGCsHqIkC6U/C2V9naFv0GS50mS2IGFuYeHnEWU4iyZ/16P2ISIr1iSz4mLiF2SxV+TvImLlmiSsnqPrIeLvzmc/kOa9Uaa74aNtHWRyXiSvk+a6YyNvIGQwo6OsImTnFib3lKd5l2d2kKi/WSd0k2h9zeo/1Gi8ZSUw5GVyn+czE2m/46bsY2ZyHugwUmr/12n8GCn6pieoGWn5Hekzpueq26n25yby1ms/ICk25ejrlGy/56iymav+V2y+2yv7Wex9KaopWG2/1e5/5Wu2H216265/HW3/qus0aavxWe+/66wvYy33YC4+Hi7+bO0uHPB/aq3wa6112vF/4e/9pfA27u31YDF/XnK/5PG77y/25TI/MDBxYbN/qvH7LfH2qPP+47V/57T/cPN2abT9c3M5Jna/77S7LrU57HV+KLg/7zd+tbb3dbb6a7l/sbh99Hi+Lrp++Pm7+Hx/P3//P///yH5BAEKAP8ALAAAAAB4AEMAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixosWLFoNpDIaxo8ePwaRJ4yaNHDhw5EySFCnNmEtjt2TJMmXKk01PpmbN+sgTZEly7+7de0eUaMqj4FaKfBlzps1IkfZI3cMnzx5Fnnb23MrQGLig/PgJHTvUZEtjNZ9CXcu2bVSpfPicOaOlrpY8ikxx3fvPGLd3YQOHfUdOWkw+jkaNEjVtquPHkCNLnVtXieUcSr7k5YvRK2DB9wrLctSnUi9dxYpRo6atEy/JsGM7pqskh+0WLXLY0csZYrC/QsOGNubplrNkxWq1Wp6rObNu53y5kU2dupbaLUxob5FHVu+Fxsj+kb3HzdTUc/TonWtWrLnqXMWaiQvnC031+7LPKMn+4YOGJ4p8Z1BJRA0ljSeQ1XMOPOt00wx7xYhDjWrinDNOEFzQwgd+HEamnwkahGiCHQL+QyBR4MgSWzjw0CNOM+4xKN868FhjhB/PqIMON844c8spp6zlSSSexIXYUx06pkULGlhggQZfcObVUdK8FRs70NCzDnvNUeNgN+vQ4w4XfvSizDHIQAMNM8LooosyaWqDDTbhhOPNnc9g88www/RIHH5nMOmkBiT2FNJRxuBXjzAMTghLK/IVAyY843TgAhaHIKIpIXDQgUgjhwjySCijllLKKrqssssuqaqaTDL+e57CYQ4WPPDAB7x15BdKxlgp2zi9JBPLOetQkwsssBTTYDPwwMMOBSRYgQghdMhRxrVl0AHHG9xuO0UWghRSyCOlTCJuIZNAoq4qwMh63xkm2LrAExiFNFKV96GzyyOICPNIOfRQs9wnucCjTTf07OMOBREAQQcZZXhRxcTYUmExFVFEkUUWaXTscRqhlDuIGGJA0ssoHGqhwQILWJCrRPZKo+J9z5xpCBnUNtrKJwTjc4426bHTQQQzVHFtFU00AUUXEw8BxRBUDBHFtnAIksYUVpOLzDGpTjLIIJA40mEOD7AcJczGtORrbJ48E8orn8jhhRyv4AMPMrBQAkv+M14ijI/QRHeBLdJdMA3F0jzwAIUPb2iKCBwbTwHHI6PqEoub6c6xYcoWHHCADhEF49LM1UWyCyigEMIIIYY0EY56xeycCzO5NAP0PoDPEDG2XSR9eBeHQ8GDD3CUk4862AgD+cZZwAHHIY/EEssqkGjeIR8aeD7CQ6L/eZ8jlWg6hxVkQFxFi8bunOze4tCDzzgNOFB0E9c2UcUYSRd++BA++JCFPm5wwjLKcQjnZcEHQJjcuB6BKl2oQmwdMoHnNNAQWdyiV/iJRB2yoAY1vOEFVbBWFegBD3HkYjmtaI+X4PG++PmgfnKIobXKEDWnDWF4abgHBwzgBG/AQXL+kANCGg6RBitYAQtrgMQqVgFBDrXgAAGgoEJkcou1xeYWdZjCFKKghiqQQAr4o0N61hG7T+gtF+IQBz7wYQ0FEG0M12IEz0DBM001QlNU8EEa2nEBA7QBG5ATxLeAgMRChGINP0jkD7AghkQ08T4tCEAAapCQWZhCFgi6zyjWIAhr2MIFQ5DaD4bQBUS4Dx7NeJQZYQGdfdDjGQOIQAzo14h5yCMf+ahHPfIhj3ZsQx7QgMMg2jEBAbQBecd4xSOIuIZmkguJWFDkJWiRJA1IslAFmQVOMkmdSFxiDYfQhz/8gYQodMFpwAsFPlzZjJ0xohVoPMc+4OEKAkSACnL+IMQxsnGBC3DgnyXgwAYusIFslGMV1SjmAU6AAzfwIh3YCMUkelEKcj0CXWuI5hzmYA0ryuYBATiAdwqSlvvwQRVYyMI8xumPVKTBaEgrwzHWCI/YMeKdxdBG+9jBBQJkoAqBQAQ2NlECGJSABjCgwVEDygBzeGMTEyiAAUrQTwYUIAzeCIUtiPGNZ+jCVI9Iww/EcAlX+OIWHDoDFLdHkFkQyaORuURKB5GCaoxTD4gog7WaMAZvjJE9rUjWg9JTKQKggAyMaEQ53FDUauAyl/r4RQkY0AZ+HOECASBGNX7BWAEAYBGlYAJBcRAGTGBiG8oQK1kzwQpSbK46JpD+5MuGBFfI3AELQKBCEAxQgHbYwwWNKB+22JEeF7WHldQIEzy8kQAEZOETO5sHDU5Qgm08QxiNgEMhzFGCAlTgHiWYgATycad52KKYJ3gGCATAgA1woJ8GwEQpevCDQQACEHMwqzPuA0Up/sOttX0MH3oAhBn4wAPTOAANNpEFMuyVfuxoETy6cSxJSXgdroglHGbXCnnQwA1HSIcyJhaFQqSjuwzYBgcYcIRywCENkPhFAQBwAmJ+Nh7TIAYaeAsMIPRADHPwwxKuAAhXkOIUpJNMJAMwUvMEeCoDtsEKVjADEhQgAAIggRrIUIXCNYEM7KARPNIHC3Gs48zhkIH+YUEhDIGlgwM3cIMtjlEFKrzhEe1Y8QIka4BFxEINgngGGjy7iGp4Fhe64Fo8DAAATkyhB1iYQxBcsAQiXGELW8iENcwjmTNIkl7/ePJUPLEEKatABTsAAgUSgAE43OxavVMDO85h5mZANxfJPbM3GoCANLyiGMyAxDQ4AINNWEMYhEDEIdTxiwsU4AhouIAAqoEINWTBGRAAAAC2MWgGJEOZj7hEAgDAhTSgAAtXeIELWMBuEpCACJl2RqIiY4EoCsSkgOjBCmIQgx34GwiF4CAhhHutRqwjjetABnRhQawzZ2IAGXiFMNqjilT8MxvooAYzoMGObBxhAgywBxL++oiODmahE4xmQDuyvQFtvCIUhfCDZzlxiB8sYQ5bIAG7WeBuF5CgCGDwAy6SLJUPBGAB967OKbBggx3wIAYq4PcOfBAFOljdwVXwAjPCcY5uSCgXyulGs8rRAQLUgRlsyoU30MCBEpjjHubYBjGcQGwIpOIeMJjABp5BBzVYAQmePcI0ZkwMbQgjFpDoxKHhIIYrXKEIL3gBEdTtbgz8HNOcgIwSJCmQ18LGE3MAwgpUwIMh8LvfPqBCsgcOMTLQ6WDnmBB75lOODDsgFhpnRivmAYK2X4AGE7hA8IvqhnhUY8Vt8IYa6FAHC2h7G0gAwAbkMQ49pYMGAJAAKwT+MYgrECEIHog8vOHt7hcUYQuZf8zmA/Df6owCC1OOOg/KUIWnx2AIjYCbIT5BBkNwHRoVcg7MkFPUcA7eUHZigAy0Iwy5IA8QAGdHAGJHAAMw4AbbMA+PIAkcMAG8UA5UoAaJwGgXkA7ZJgG8cIK8AAOYlQrmMgiWFgQyAAZbQAQu4AKRB35BEARbgAvqx3n/EBeyUQdSIAKoFgM+MARkoAZPFwWH8AqtMC37Bw3noCZmdg51Uid+AHG6gAwMWAu5sA0TcAMlwA+5VA/zEA/qcAyIUArtQAzEcA/XQAVwgAsW0Ge2IAEAwADvBVAX0AbPUAhgA29GgAZ2wARgAHn+JPACYLAhlsAFXOAr6ycQZ+B5kDEKPzADoxcDw/OBZaAGqfcKyAAKzNEKwhAOycMiB5cM4QAMCuAAk6ANtOOF0PALxOYG/XAMn9B3VmcI1vYK0VAO0QAKQwAH4xAP98APSMBb9rANqbAIbpAK1gU9I+MCWyADViEVXAAGL+ABMiAKsBGJP0iJjnEKYtB0UcdvPEAFj1MGQ6AGsRAO0KANasIMyKAM2nAMUpgMu6AKl0ABCPADCrgzlNAKi1UCJbAJ/SAMhlAG+1M+VJAtjUAIVMADnggEVkAKHCAAOOANwrAL3lAOyhAKhyAujQdvLeAYkZAJWwAGRgAGcGV0SPf+D3twBrBBCz+wbzvQb5rYjocACogQCsKgDcmgDXUiDtCADLrQC7twCYDgARRAAAhgA8sBC59wU69QDzTQdsSQD7kgQkNQBWRAB1FTOFUwAxTpAzbQA53AAABADNAACj8EB8o2koUwB5dABGBwkpDhB2DABeIoFfUmRZ4wF5FhCnNgAyIweudYenCgBqUQC6FwDMpwCZcQDuIgj/QoBhjgAAiAABGAAoeAQq1ACYxACbnQD8SQCr/AD+wACnJgOF0gB0l4Q1BABTuAhFQABGswaAXwDcIACm8ABEAgOWmALqswB98nBJEBhJ32aQIxC3MhjqfwAzbgA5mYOFDzBnD+AIqxIAzQoApqgg0AGA7FgJRr0ANWIIrKwTNVeVOtcA7lwA7qUA6toFdlADwhlIRwIDw8MAO46QOq4EvtgA1PSAVU9i1TAIjdRwQyQJMdsmQjJZOE+RiJgJgr4G85eYRcBAehoAxvogtzIJnHsHU/U570CAqUMJDtGQgsGghyEAipwQgLKTiFwwP0Y3VUUAVQwG/0wz9AEAq6IAwF6gMxMAPDmQZYMDLw9gFJsgf91VZa4KCOIQYhMGX+dkOpJwiv0ITSswu9sAXKoAxrwnVT2Aq0U5Us6gVj4AV/4AVuOgayWQZKMzFQwJD2Uwaf0nemN0sMOQPVyYSgoAZRMAT+MzADWWBESep9QWACSRJbAfAy/6AIUeoYjrAEISACiTkDVAAFHVQ1QJoqqpAJXHAJpRCPxGKFDLgzaKqmY7Cmc+OirZo099llWVcGhNAIPlkFQ5CTE8MDK2ADUfAKjaAGX9mffmoDRyQGRFAEMpAkahUAbAWlkyoVpmCpU9ZviVMFzgMKoTA9quAHIAABMgAJukAnVmh4yqGqjOCmavoHbeqmMeQFhuAFSUM/clAFt5o6N6QCsUkGUGCkbNYKXMY/MxACBktfiiql+AFSInUQplAXm3MLV2ChM8BvnKpsoCA9q8AKIBB8MNAJvYCU0BAOsEg7N0WagcCmf7CmcqP+pl4AMU3AA0nQBHNDBqCAq4SgBjwKMTxgA3Bws2QQCOwIBDZgsCGAAijAAkSgBNV0TQkhqVowFXOgb5m4A3KIOofQravgCv2EBlFxCqzwJtigDfIopGj6B4HgroHACHLQpoaAPxGTOE0gm4QgiohQBToLBS/bBf0JBy5KCOzoA/SFAkeLtCwQBEmyZJSkEHlQF1LhCjeZiUaoBoggCC9WCKWgCRNgBo7BB6OwC8rAdfLoTmzrru46BmjLqknjBUkws0GLq69QbVRQNLLZBLs6BNlSBVNjBT2AtL7LAi7AtE4kSf7FuHWRB7TAdIrJb4VKdVlwCLqgCRcQGZ+rU/D+eEJoOgaBsKauCqdkUK/1ijOgkAtwmUcvVD4xW3p0ADxRAASYerRLkAEZcLgRRLwP0bhaUK02UKinJzwW8wbQK72SMQracK4Tdyw8Q7ot6qJyUK9dVgafAAqxCwdRcIQvS69OYzQ8oAJWWqg2sAQukAFXcI3VcQb1Zm8QIamKMLGYuJMTmXocmgycML2S8QxXCA0a1x7tWQvIgAyyA13r6gVlkITQlSkV/JDcGzx1+nSh5KOEdAUukAj4oQQLIEmLGxGm8AWQ0AP7u2+lJ4eI8AqSKcCScQrnYIXUIAxww6JoGwitADe31go3VZVPyK2QY2CqI1zAMwR0QH+h9IH+U1CckxBk3ghbUHQAZzMRwcAKkXuhBna1r/AmmUDDNUyy2oAMuVCVbfsHhCAHhvAHMbS2awu7W3oIUmADWYAIrdAImlwGjdAIgWAIA2d1zyNRG8uD1KEEIBUAEgCpEjEOa4CJ+5Z6VysM9QgMG/CXUvEM2kANOCwMtcAIaXtT0iw3oMyilEAwuRAKoVBEaTC+ckzNN5VPrEctcNAIo7IKyYDLsKEFJzxJHjEIUubFX6nKbaIMwEADlgAbySMMbCIM0tyiN+WibhrL7vnGsaAMkDAIsXAMwgCUzQE30izN5UMHyQYqDJQMvgAbfPABUBQALvMRqmAFhXqbH6jKDo3+DL2ABJIgGXygDasskC1qCIbwogu8ttCVQuWpDZegCvdYCkRZtlXpYMJl0VGgbJfTC8DwGKjAByrz0QuQyB6RDGlQqM2rBuf8CpezC5xwBPy8xmRwzS4a0HLzou7phWhXjy/ACspQCshAlOGgxmgaCLOJt3J4CKai1L5CK55zAPPCFX/opzPgb1RXy6WwC5oAA9z0GL0Qzg7WtgtsCGlr0+8kDJYdJx6wBazQCw7NDNpQC+tJCSwqm4aAMbU8CaowCuahBR/wAH39AKC2F5NAtBc6dVQXBYJwKq4AA5bwl6uQOgHNrnJQzaBs1gMZ0bmgDcrQAAPgAZcgppg5MIb+cFMQcy1yuAZ9cAd7oAXxsgB9PQLYxBeQUGAVW7H9EwVTcNjAUAJfYBdS6gmlgAhBG7RuSgij3bY2nc21wIC58ArQoAsNoAAYAAbQIJ7Q0B7qKt9VkAXYLRc50Nos490W8ARa8R2qQJ3XqpPEk9DJgARmYBkgXheTeAd9sAZxoAbWPDdqet9yBE8nlAv/TQEUcAWqMLbNDM2fQDl4kN3bnQMmUCtlwzIT7su9AbnzvLw+MAXKgA3JwAZu4FZ5AOJSrgQifgYk3gd4YOLc4jgRLJqX45R2yQp8MgqOsCHX4eNNAuS28gA18AVEXiLleKmJqQIGlgXlus4wQBCmoAjAUT7lII4ZVO7eczHohG4X13EZ2hEiTrLotWIBbR4gJaIQl0C4mBp/SV4KSQkMOIAQ2pQHefAFthHqop4DuIEb2nHq2tEf/REirM7oJqADAFLhkc4QlI6pdH6kupAMu+0QlhQJdmAHX/AF2JEdqJ7qqq4BH6ADuBHseCHrs/4QkEu4iJlqFrkGk8AKrrABPEETkfDmz94RgEC4IWCkVpAG4eKlmiAB377uFeEKS4ACNvADQpQG5LILwMAE7J7vAhEQADs=" -#define ZEND_LOGO_DATA_URI "data:image/gif;base64,R0lGODlhcQBIANUAAA0NDgEDBgIFCS5EXhUdJwUPGgQKER0rOgABAgkZKiZpqxhDbQ0kOwobLQkZKSNgnSBXjh1PghpGchQ2Vx1NfAoaKiJYjQoYJgsaKQECAzdQaS0/UTE1OQUPGAkaKh5ViiFclRpJdQocLSBZjh5UhhpIcw8qQxc+YwwgMwcVIQkaKQgXIwcZJTM6PwIEBRkaGjEyMv9mAP///8zMzMfHx7+/v6urq5KSknNzc1VVVTw8PDc3NyYmJgcHBwMDAwAAACwAAAAAcQBIAAAG/8CZcEgsGo/IpHJ5/DGf0KiU+Ks6p9Kr0KrFer9GbReM7IrJ6O95Zt262durUy5uD8/rtL58h7vlf3+AcHlsdoR7iU12eIhzbXVVfpOTgGOKiWNrkpKUhZ99iJijl4d5kFSdXKmdb6OvsFOXsbS1oba4ubq7vL1DNjg6ODW+xVg3OTw/AisCOMbQSsA6AD8FDAsjIwwv0d5DNcnLIhMU2uclPzbf3jwC2Ofx585MwTfssD8n8vwjKDpLcggo8OMZPkw8GPSTN6HKCxg5hhHJ8WOCv4IHFeEwsDAeiQULJjBYUQXGM4oWtTU0mDGNjR/mOi48gcJKynMrW+oBcFNmP/8SJnri/JFDJ5kaL0T4XLqwYVGjWGy8MFCCqVWGRKFKsQGgAImrYIc+1bqEq9ewaEc0vEc2CdKzacOmY9vWxjoiMAx81Sajr9+/MhaE2Iu2hAAexPraJUbGxo3HkB/f/XKjCgBhwH5kOwcYsAoU5dKSMIBYSN8cOSZvxRGjtevXOnREZDwFhogSE1AYqKIwXl8VBlKoUNHXgAEUJwhfJVGgtGkZsek+Afa6uvUY0bFUjEdhgnJtIUwwmLDAb4cU3tM2pz2jb/YnN67Lr/4eSuWYPkmEGDyiL4MODITgm1+CkdBZgSh00xkMOkiHRHzWxSahDvNJyN4SG6HV1wSfJcf/GWAMdObfCQv8IOILDUoj34QTrhgbS0zAgEJYfqGgQnp8yXACA8N9NkFfHQRX4wl+6cADDH2h6KBdz7jIYosRShjFdmD5B6CAH/JIHkgh9JUCeuXJAOBpPDTYF4MO4mDCAU5KmMMNxNDAWpSx2QdTlTJwiNxeIhbYnwzDZeMlcTLAAAOc7qVIxAsVsrjkdRNCkeFVNd5ImIgqmCDgbyoICiihZd5gQ189KDoDDTcYcN1lE+JAgxE2QCrlEzLi+V+Af+4XpnHCafpnoL8SWugNOwD5gqg4oMbDCtahkAGD9RUBIX2xjbUElUyJ6BcDJoQJ2AldfuppoCJe0IEOB5hw/wIEKFRQnQgesJrDhUTI+iJ8d2arbXGdjhDub6BxOm6nJvzVwMEMSCDBAw+AwIAHr3kgQgdl5vAqEjXYq4NqSeAgAFjd2djjyL7qJ9JwDCQXnq/+mqBpCQXsWIEHKVPwQcMgOOyAaw4k0EAKGCmhsbVKVLbCBFUtte+GC+ylH5df6cffCFIbKAMJJ5A4GARcdz2BA2CH3YAIDABA7y8aO1g0NeOEttDSgLJMowwuh9D13VwDFTbYCZjQMEBIDO3FNACY0NFvwY3M72ZoLWCACRTgLfnXYTPwAQgKmFAUDjjQ1SbHtfXWz29gggSSSHKHRcIKJkAAguR4R/C1CJFD8P+AAiykABoCQrQJoxc4FHC4uPLod+DUfxI4mF8O/AhYgXj/JdjNEUSgwAMY1ECDxjpcDEZl330IrDzapvyViCn7FUD5yXXdWcqXg3D7CdPCNqHaWNSA7YDPIw+kkH1BTo3OA6QA9UUAIvhfCoZEAgj0ZUdhA03tRvAAEvhuDzpQCj8wJTcvgamAVgqYDIQTpgIkcIQfFFOAHCgDBjTPdFvj2gPaRDQy4CBf5JMBr4bTQeINinTe+U0BCiYDBzSgL2BbAAtT4IA+xbBrIODe2cDwghltEIVb8p8PPyWwPxlAAERsgAeQ6AAlklFEDtAUFKNIp9iADlXJQs2bbuA9Jdz/ED/i69eHwgUsTvkFPVb7QQUk0BcPNLGIZWRhEsPFqzTazXUzbKOphBCrNnaujkUwS/jgFqItkqszCKDdGRFpRlJa7VuDiaQliVBJ7t0LVl0JX/K0ZYAuCuyUfrEGBUaZREUmEgL/KiJoIqBKagljCPUz5pN+N4MaxLIj4RmZNINSN/BUE2s86gsADBABEJSgbit7ZDjzFgKRgC1lEJgPdiw2g2Ta70lvOkINeACXhTzNdPgUDAX24zR+asN4MjiSAS73AX5WjZxPhMA9Q/ABdbYGVY1aJuiGsBFZxqUjhhFGDlwgP4aN4HWwC2nXLOjQiLJIInbUy0Wt4pQa2IUH/ydQwARmKr8RiDSkJW3T/TCJMXpadKX/ZEBWKEqAFgDgBjCYgAJAetO75VSZjuKpEuYpgKQBlR8lYqZdhsCBhTG1qSR96pMkREcvUNWq/CBPXOixBA5QIGdN5dpTsTPWBkk1CmftR0N+YACkhUUEgJOGD0jwVa7l7LCvy2ld33TXKeQ1HiuxQQ5eUIUVoEBdS5kAAJ7gghM84G45Y9jtSgCCCHjAA2PzwGHqOqF4KuKxagkaJTmngxcIzycU+AH+iFADFCwVtCAgTwRQEIALQEAEIlBBB15QJtbKZrdpqAEMqhrbGiIThx0pgHWJgAMJ/NawDxhADzj3DBioSwQGAIfADpyLUloIpCbbHQJPlsIAGCxhBxa4HcM6at865qCcRFlsWXORA5MwIYMyWQADBBBfIdzgBRpAwVtvpzkjhCM1lHQMZKb4DY/xozsiEMAPeNDeJNDAMT/YwAkkwICJcpgsL9mMgglyGRxMlAmiAoCN2zIFeoZ4xK6NLo+nYIMX3XjISNZKEAAAOw==" +#define PHP_LOGO_DATA_URI "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHkAAABACAYAAAA+j9gsAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAD4BJREFUeNrsnXtwXFUdx8/dBGihmE21QCrQDY6oZZykon/gY5qizjgM2KQMfzFAOioOA5KEh+j4R9oZH7zT6MAMKrNphZFSQreKHRgZmspLHSCJ2Co6tBtJk7Zps7tJs5t95F5/33PvWU4293F29ybdlPzaM3df2XPv+Zzf4/zOuWc1tkjl+T0HQ3SQC6SBSlD6WKN4rusGm9F1ps/o5mPriOf8dd0YoNfi0nt4ntB1PT4zYwzQkf3kR9/sW4xtpS0CmE0SyPUFUJXFMIxZcM0jAZ4xrKMudQT7963HBF0n6EaUjkP0vI9K9OEHWqJLkNW1s8mC2WgVTwGAqWTafJzTWTKZmQuZ/k1MpAi2+eys6mpWfVaAPzcILu8EVKoCAaYFtPxrAXo8qyNwzZc7gSgzgN9Hx0Ecn3j8xr4lyHOhNrlpaJIgptM5DjCdzrJ0Jmce6bWFkOpqs0MErA4gXIBuAmY53gFmOPCcdaTXCbq+n16PPLXjewMfGcgEttECeouTpk5MplhyKsPBTiXNYyULtwIW7Cx1vlwuJyDLR9L0mQiVPb27fhA54yBbGttMpc1OWwF1cmKaH2FSF7vAjGezOZZJZ9j0dIZlMhnuRiToMO0c+N4X7oksasgEt9XS2KZCHzoem2Ixq5zpAuDTqTR14FMslZyepeEI4Ogj26n0vLj33uiigExgMWRpt+CGCsEePZqoePM738BPTaJzT7CpU0nu1yXpAXCC3VeRkCW4bfJYFZo6dmJyQTW2tvZc1nb719iyZWc5fmZ6Osu6H3uVzit52oBnMll2YizGxk8muFZLAshb/YKtzQdcaO3Y2CQ7eiy+YNGvLN+4+nJetm3bxhKJxJz316xZw1pbW9kLew+w1944XBEaPj6eYCeOx1gqNe07bK1MwIDbKcOFOR49GuePT5fcfOMX2drPXcQ0zf7y2tvbWVdXF/v1k2+yQ4dPVpQ5P0Um/NjoCX6UBMFZR6k+u7qMYVBYDIEqBW7eXAfPZX19zp2/oaGBHysNMGTFinPZik9fWggbI5Omb13zUDeB3lLsdwaK/YPeyAFU0i8Aw9/2Dwyx4SPjFQEYUlf3MTYw4Jx7CIVCbHR0oqIDNMD+FMG+ZE0dO/tsHlvAWnYS6H4qjfMC+Zld/wg92/tuv2WeeYT87j+H2aFDxysGLuSy+o/z49DQkONnmpqa2MjRyoYsZOXKGnb5Z+vZqlUrxUsAvI9At/oK+elnBpoNw+Dai9TekSMxDrgSh0KrSYshTprc2NhoRf1JtlikqirAVl98AddsSavDBDrsC+QdT7/TSoB344tzOZ39+70RbporVerqasyw1MEnC8iV6I9VTDi0uqbmfPFSq2W+gyUHXuEdb3WR5rab5jnD3i/BNMN8ChNaqsTiKa55KmBWX+Tuj0XQdQVF307nhTH0CPls+O0UPbaT5TQG/8qX68u6LpV67LQ6dNknaYgaYyPDx2TzvYGCsnhRkH8b/rsF2GDj1MCInkvxvRjOuCUlipWD/zrKx7ZOwBF0vfSSM2ShyaqAAOC1Nw+zt9/5YNbrN1zfwIdpfgnqebv/A6pnWAn4qlW1HPgHQ6OeoG3N9RO/+StMdDtmV2LxJPfBpQCGfwTgrVu38jFrKaW2tpZt2LCBdXR0sEgkwhv21u9cxQsyW3ZB1+DgoOM54btU6tu8eTPr6elhy5fr7IZNDey+e76e9/fCLcAllHpdKKinpaUlX8+111xB9VzNrYxqUAY/XVVVJYMOekLu2fFGM8VWYQRYiYkU9bD4vPlHFYnH4/zvkb1CgwACHgMoUpdyw3sFXcXUh4YHaNSHDqaxdL5jwVTXBpeXVY9oF3RcUQ+O09NT7Cayfld+4RJlP42gTIq8w66Qf/X4a6FTSSMMDcaE/NhYecMM+MdyG90OAhodWoAGkTUaSZByO5WdiA4GqwStrrM6k5vFKEXQserr63l7oR5V0NBojKctaSZtbneErOtGmFxwkGewjk0UzpCUlJSIRqMcjN8CkHLDqyRByq0PEGBBhDmdj7rQVujAaLfrrlk7xyW5gUaxpEtOmOQDr0e799NYmDVBi0+OT7FcbsaXxEQk8qprEBQMBm0vVKUBRcNjskFE8W71lSt79uzhda1d6w4ZGTUUp3NWAQ3TvW/fPvbVq+rZH/ceULOcF1/I06CY3QJohCCzNJnYdgEwwvpUKuNbUsLNpO3evZtfSGHp7+/nS2pw3LLFPVWLoA5yHQUtXvXFYjH+vU4F5yOibzsRUL38MTqC3XWh8GCWziMcDjt2BNEZUIfoUOpJkwvziT3S5ua8Jj/4yD5E0yERbPkhKv4RF4mhkN1wCMHN2rWfYZ2dnWz9+vXchNkJzBoaQ8Bxqg91wWo41YdO2dzczD+3bt06Rw0rBG4nOF8oi9M0Jsw9OgLqQ124BifLgeuHyVbN0NXUrODBmDWxgRR0pNrUYqMNgDOZGZbNzvgCuc4j0kX+GPJ2//CcMagQmKkbrm/knwVEp++SIXulM1+nhj9AY207QRDnpsnye24WA59DkuPlV/5j+z5eB2hE0W1tbTyQdNJmDpksRzFp2E9csFJAboRvDvz8gZdJgw2ek55KZphfAv+Inu8UdKnmkEUHQK93EjEZ4Rbkifq8JiactEpYAy9Nli2Gm6CjIZPn1qlKFWizleOG3BIwdKNZ+KRMxr9VHKvr1NKLXo2BhlAVFRPq1qlWW6MBr3NWyY2rTGXO5ySJlN9uDuiGsV7XTVPtl8CHYGizf/9+V5Om0hAwVV4ahuU8qia03HP26kyqFkMOTudDzjs/P/QKBUiBYa5ZNucfZJUkCG/0IhpCxYyqBF3lnLOII8q1GKqdStQ3rTh5MStwXX5O/nE1metGQzPHUH6JatA1OppQ8u1eUbpX44tO4GY5vM5Z9sduFgOfG1GwUOK6VFzaSAmrWCSfzGCuuT/O+bi6QwRdTtqXN2keJ4/ejgkJ5HedRARkbkGe6ARulgMWQ+Wc3cDAWohhoZdcue7ifJ7crfP6Me8dELd0Mv8U2begC2k9SHd3t+NnNm7cqKwRbiYUkykqvlZlmOYVLIq5bHRep46JzotOc9BhuFc0ZHGLph+CJIaXr1FZSIfxsdBiN1+LpALEK2By61Aqs0rwtV7DNBU3BMCYixYTLU6C8bM5hBwum0k1mesBpmPtlj+qXFenFsAgCVLon9DYeIxUnmh05HCdBIkCVRP6ussiepVZJZXIutCHwt2I0YGY2Kiz3AIyeG5aLNooVULQBbHy1/nAK2oEtEanheil+GO3aFg0FnwSilNC4q6OrXzywc0XCy1WMaFu/tgrCBLRuWpHuP+n1zqmRXFN0GAnwKgHeW1E1C/86UDJHFKptATZMPZTafbLXHtN3OPixKRC4ev4GwB2Gy6JxhQNEYul+KoKp79RMaGqKzy9ovzt27c7pidVZtYAGJMYOP7u6bdK1mLI1GQ+/ogSZBahwKuLO2jSZt0odw65xrUhAMNrZskLsGiIXz72F3bTjV+ixvtbWcMQr3NWCbog5VyXAIy63PLrqpJITIqHkcD9P7suSiYbG53wvTLKDbr8WBbjZqIF4F3PD3ItRn1eQd5CBF3lCM5RAIYfVp0/dgZ8SvbJ2/l8MmlvNw+8qJTjm+drWQwaAXO9KMuWncc1GBMXKkGeV/pU5ZxFIsTvzovOCu3HvDnOE7NTu3rLr+PE8fy6+IEX9947YM4n/+LbPT/88R8QqoYAuVSDrZLFKcYso2AcLBIeGDPu6h3M+yqvIE/4Y6w4LdUfi+jcr86L75KvC9+PcbVfd1hCi6U7Innwk1/+Q5rcoetsdyBg3s9aCmivBsNFifGfG9zCJUFiztmpEXAbqhMgr6SLWBPu9R1enRfm1ktrC6cVYWH+/Mqg43x6sYK1edaCex7vkRZHZkF+6P6NkXvvi/TpLNBUaqTtdcsoLtIrVTcem2EHDh7m2uq0ikMINBvafOmazzt+BkGMW9CF70DndPsOaJqb38Y1oXjdCYHOiqwbPofrKid6thMAlnxxPtMy6w4K0ubNhq73U5wd5PtVleCTd+50D2CEafLloqixyv0ufMcOGq64CVaMYN2119gfAdPpuscKOxWgCMDwxfm0pvzBhx9siRLoFt3ca7Ikf+x2yygaYzHdTSi7IT9y8fMJ2Lpdhg+ZCPA2+f05d1A88mBLHzQaoA1dL6ohVLJGi+1uQj8XQMyHIMgaGT6eDxuozMkD294LRaB7CPI27DLHQSskSFRvGa30O/zndF4fF0DMhwa//9//iZ2DcILqN7xBHn1oUweNn7eJ3WO9QHvdMlrMsphKEj8XQPgpuHVVMtGOgF0hC9CGTqbb2kHOzXx73aKiuiymEv2x22ICMYYeWSALBQ7RQ0fkoZIr4DnRtS3ohzf1dNzTG9d0PcwMLahZO8UyKTMm38wteratSVtkplq4oWj0PcfrEinPhYg14H+hvdIwCVs1bvb6O+UBMYFGl90d0LRGLRDgoHEUwYnXDniQStocTVUwfPLaKQGA/RoWOmkvtnsaG8unK+PWMKlH5e+Lznp03N27RdO0TkxmYNZKszYBlyfI3RpjsQkmMOo8ls4Wsx1EKcEVAEvayyNoeRzsO2RI+93PNRLesGYtNpBhL4l/prlgZz5ob0mbtZVFhWC301d0EuQgAHPgS7D9hssTHKyMbRfLptF213NBDRuoaqxNA2yh2VUBDnxJ1M1yRW6gOgt2x64gqXK7ht1yOWyW1+wl7bYXvhUygQXgit4KuVDuBGzSbA2bmmtayNzpRgJOGu7XosHFChZzvrGTiUKt5UMiVsmbmtsCb3+2lZmwm3hFNsA/CiYdKyfhYx3Aws8urp8nsJM72naGCG8zYwZMecjk/WHVVRbsMwU6tBVQsWJS2sNDlrgVTO0RE/vzKQtuN2+/85k5PxlUaL75D3BZwKss+JUqSFRAO/F7Eqlkmj+2gbrgYE8rZFluu+P3pOGsyWCG/Y9/GR8exC+vYfc5flxgzRdDGsDEz/8AJsxwQcBUKPCtmKOMFJO8OKMgF8r3b3sKkAm69TN+2OZCAm5ID/g9XPypwX29ufWgudq0urrKes/8nPkxgy1bdg6z/or/SFc2mzV/xs+6HwySTmdYJp2dpaWKEregYrVfn9/B0xkD2U6+e+sOaHqImTfLrycUOIZM1hJwC3oemPXbi/y5PnsrJ136bUa8pxu69BklmANWwDRkgR1wmwVaglyi3Nz6JLQ+ZG5NxQsgNdAhmIfJN7wxgoWg9fxzPQ+c/g9YAIXgeUKCyipJO4uR/wswAOIwB/5IgxvbAAAAAElFTkSuQmCC" +#define PHP_EGG_LOGO_DATA_URI "data:image/gif;base64,R0lGODlheQBAAOZ/AB0BAHB0r0xPkMmMdtjXu9CYh2sxAquv1pJsTmUCAKyQaaVnA6lwVYOGvJM1ANvbwYlPMJubzVYCAGgRAJhqLm9BCq99aLetkqpMAKJCAJdvYqtzHZZWAnNsmIUjAHdKNW8bALqST3ABAJpjEVYnA08xU5JLBG1FU8fKtIhcS4d0kYJFBLiQgkABAIQwAd3h0eDm2sXCpdXYxIiKwG05M7CtuH4UAVNGdNPWwJ5dAcB+ZOjv6NrdxqRMAN7ZuH1qeXZYYszQunp9toxRBJ2dz5yHaa6ANoVYHrWgebK54M28jdfbxpGTxpWWyY8tAJqFl6hHANzUr5J+UqOm0Z47AI9eG9LKolo1IEASAkNIjJSczVkUAYyPw1NNTqSdrYNgZ3hMGK9XAa5KAJNKGaGdv3k6BVgZE6BTGmVopNrezIJhNGgeFpJCKFogM9DTvpiQrm1afpiYxZxQClZZmKJSBaNGAWsnItLQscC8p7NaEI47BpdhQGwVFy0bH18LAJmZzCH5BAEAAH8ALAAAAAB5AEAAAAf/gH+Cg4SFhoeIiYIRRERTj48HkgeQU40Rf3FNm5yLEZ+YhnFeTYqmp6ipioyOU5OSSbGys0mTkERaTUxcM729XExMpaCYTTU+NaWqy8yoo3Gtk7SxlGRvT08qPz9f3UBAX0A/KuQNXOfnMw0NQu3t5n+YNQ9RXs33+IOfeFE1B7MHyGTjdoLGGjN+JChcyLChHz981tixQ+MEEDhwOgRoFyAAmo1C3rh5gEdZvpOnHB2Y56ZGkilvfpyws6WFzRYMH+rcOaGnz58+/UwQ2lPiiYxokqLpgIKHlSeXUEolpPLfgRgv8KQw6CdBAoU3cUp4OHanWbNA06aleOIGGjw8/x4gQSOkCZFQU+9FcPWv1hsvBF4g6fpwKNiwDRMvPMu4sdk1F+IqgZNFABoujPDmTemK2pOZWyKnKVK4Z8KwYhXnHLvYsWudSNLQ+5KltoA5Qv7c3axIZSwyKuwstBMkLgKipv2gVpjw9Vm1yNWajv3gAYUtbW7UzoLbLm9DRGAleUIjYQKyCNLwwKEG6OmbzBlLTwtiPlAQ+CdQ5xGiPog1JWwngBCMfKdbZweoUF5ZO8XGwx0QIEcWYqVF9xMILtyHX349bejhh/ghERcPSHjgIYDacdfAJ5t1Np5w551lRwxpLGEFGNG9J5aFaq2wAYge+gQkkBfI9oASZXw4VP+AtaHhHUrhxfIGDa2ZJcEHbvBgI44/6cicWkFWYcSQHE5ApodlxLBEdVasoGRXZjA54G74IPiFYlYisISWN+YoAXxjgbnhBBT0ZyaQQx16JghgBFHdA3dU8eZXEmTX5JPMdPbEGsw15NWnEmjAQ1wQJpCcjjgVxhNQRoRggIb1NafokBMggMMDa95BwZtfgsDkHDMQscxektzZqQSfeoWsskUYecceySrbAgA2MRhtshO0WoYEIng1galDyXpmTwrI8AAPBBBAQYemLXRoAm3Y1oCwqBBLBg2pqdYQC6M+QAAD0f5J4bXRghBCCCssS3CgIPbUrVcX4IruvwG7G6v/QiUIkIUQ9JriSBxt5JvQQoAudMGe/iqQ2HJdUaqYAQeboNBXyi503qz1PfzVGjFInC4CoDaUn8tMzmvKXm/wIYIIEzDdU9AuM3dyXAQM1tByyJJc7UJlGLEBByNrXa1QSlJqEwIEnLsEAVEgIHa1Zo58U8Ybd3wIEW+wYYMHfPftgQ2ABy444HigTIASeizddIw6PV1z1BKUscACOYBwNXxEefjVTWZckLaWBDx7GLXUtlDf6DYFKAAXdg8ShxZxsOGEA7TX7sTtuOeOux6F93uHER444ffwfA8uOAhl5LBB5QnYIILzDzO9oYlDK5uCGwTsuQQOpb5NFKo2aTdH/xOa/bGJFinMXvv66jvQvu28S+wvEnrYjrv77Ot++wqFhrCBCSAI3u36pjsXuGCAfkNC2s4lAxzEYAzG6xDfQGCDpz0kAXzQDhpaxwQtaOB96wuhCGmnh5OtyV9WoID6bjfCEbqgAmBQgxQUoIYKkAALIGwh+xhwh8+thwB4GIP+cHdA3fmNBrUxmiCCMYO/8c2AUDQg3+7nAD1Y8YoXkIHhohAC/OVOh7SjggGwcAUjrIAEN7yhC6gARhGeQQnpekCNcIAD+rURjOIjn/m4oIUTLG1pftjCFu4zqydKEQky0GJ1CJDCvf3NkQSkogNWYAADgEEKBiiDCVZgAgNgqP+NbGSjHhT4uTm6QQE5vGPtylAbjkVgFypQWAKmBYDSoQZrCtFAIlHmgygowQM6+9QfB5dJTnLABENYAAdykIMVlMGTASTeFIXnBAX0sDppSIMM3BAECghQdyS84gipQIUTZGGDfwDGCa5Wy1rS0p3tbOdNUoADLcall1ycwJ/2abMELC0BWzCACUzAzMkpcwQcoMMxDbCFlkXrYR6wQA8/94LtuSEGegPch55oABd0NIDRdEEVkbi6JsyAC21gpzzjyVKWXgEFu6wOPkNwy5IF1Jg5MKgyc8CBZXLgjDWpaQs+cIEoxPEBL3hBA4OABH1m7ZZYiKpUWyBVQYKABNr/CQAvhOBQf4pAJ6wRGE5ustIWZNGe94xCFJCAr5pKIKBlOMIQlpnTyXFgBENg5k9dQIKatNMMNEAAEqxg1AWmAQZL2GYQ9gCod7b0se0MEBp6oQLBCXB4FOxJBSvYpYQgwA27vCc+rRCCD5hBrG8lQRlWMIS5Us6gd6XrT58pyCsUAQlKIGwvCeCD6vAABtrEgRsusIZbQva4tezDbRowgy+Q87nQfa77vjhCJ4whBvVcAsoe4IPu9tIKSkACEsZw1UyWYa50hS1e9brJZ5YBCdxVa3cXeC4YKFW4QUBATZF7XOUKYB3OzYCAB0xgAUe3wASmAhLckN1+ydS7vVXC/wIqUIFiznUIIzBCMimHUMod05mrDQF3e/soXB0Wsfi9QBlq9jaBwROyfagMgKmA4BrbuMBUoAAKGIzWuDy4u0agwAoqvNqecqAKajDA5HiazGNucgWsNcKtSoyrF+xgB4nFQRBQsAf9+S2a1PMQ4CZQwYfE678NCPCN12zjBdezxz5GqhKMgAAwEBkMHEjmCI4wgg0sYAQddjKUh3CEDVghLtrdEwyuHFxu0i/BNM5AdKVbO3LSDnckXccPqFCHTnu6DgMGNZsLfIYY8BjOcYEBEqRAATBU0gAryPMCNkBrP+N1BMoc6KCrQIEi7SkNL1g0lhvIzQuMIdI2FnUGQP/d6Rt/gDszEEIH9NCDalv72tX+tLa3DWoG7PjN2h0VD9QjBSkcwYYGqEAVWjvrWucA0Lh28mqHUIUqKGAJSRU2YokdBDzswQFrbnaoPW1jc86BCe2ggR4GynCGy8EEcpADtieO7TooIAinTvQSYBCDctuQBOmWKwfaTWtAVyGnFAYxvdWAABRc+cr7xq+/HaDsAn9awNyucVb/IIQGlEBRJuooFMtQBhdcUQ9QbnjDHy4HJGCcx4lWtRTUcIU+AMCS6+ZArUsO6MlVGOQkgKEMLwDzRgeh3/+GArc9rfZtt13tOK8DFNhQmxlEINpw8OofFee0n1Rwo5W8KsgreXH/jGd3CaMpQpLRmO5193kDXtvACCjA668N4eNhl2ERkppI/AbhAhAAOIHrQPHSX5vtUDD4JxAuhDbofe+wj33sN1c6P7TcDbiXQRpQUO4roLECZahAax9vBK8hNAdVQOgQKPn7GEoBBdrk5pYVYIdDmcgDRh9oxOVAh+7TYfveD3/45aAdjgmiHR1owetlz/7Zw6cFKbjA2d2QBjyUGwxXgOERKECBIVCA1sW3AYVCAUbQZ3jlTBQGBmBAVGlwdp+HAEFFISBQSURXBkd3gWNgAhmYgQxnTgLABJjwSu1QAgDALe13grH3fmZQBDEQBDJwAWpQQxUGQzBUBZLHa17D/2uUdwRHAAaU9GowpIB4cFFFYAaP9X5YECiD8zyD4zc2YAcaY36L0AAdYXUmmCwoyH4lcyVFgAJFgEaMl3IrMAL1FgL8t3WS11o/CIZYgEZqUAQf4Fjy9H7IkoWyJz6agQntgAbU4k8EQzB/tH4SQC0MgRMfAAFt2IbpBgaERnlqQEMh0CqRRwE5sHzPBIYkcAWl8ydHmC92KHt0wzqFEAFN0A5zgBN/mIrC9EeDaEtjFTljBHL6t39HQGeCFV5IEIn8VwVQdolYAAZGYAC21IoshRjr94nxkgVKNIpcsBFwsCzBpIoPNUvFeBMhcASKGENqoIBgcARqQAEIgAD8h/8AVcCDdvZ1NwQGFIAF7mQTR0g66vdPWPh6WNgGGhMArUMIEdCMQgAHLuCExrNZ7ceJLTVUaOR7QdiNPMhy4RiOu1iOllhJNxRVAIAFQdWJ7uRVgBiNCcAkAcAiiXB3G6ECxyZpk8ZG04VAxIMfVlUfE7AFUZV5e7AHDMAAFnCTLJCTOWkBNbkHEPCTdiaR7EhVQ+mO03JLsiSNXkE3aACSq9CMGwEBUDCVVAkFGHCVVZmVU3lzBQYCZJQCNqkDOjAAZEmWBXCWaHmWAyCWOsCTDIAAKQAGE7kYp0IWwqSUXuEHKYKP5ROSCNcRKQAFYmCVV1mYhjmVhpmYislXYGn/AWwplmWZlgVQlo8pljX5llcQVSAgSbkDkIHzPLJnKXPCDKQoBCMplYqZmqqpmCZwBY3pmGUZmWpplmSpAwzAlpe5B5qIBVQgBoO5lYSZlaJ2kuSkB+YEbflYLxFAhR3xBWcgBqsZnalpAGAZjrc5AJKZnWt5mbfJkzO5m78JnNKplWJQBx+QIk6SnKpQmh0RACmAAdApnfK5AofIcimQAjSJnZJpmxqwBw2JADTplhBgdSQQnlQpn4Q5mBCQIv9FJyeBCdHWER2QAnIQn/KZmnnwAR9wnxrQoRoKlpFpARqQAh9AAynQoXAJljWpiR/AABmglYIZnb6JAQtqGwGA/ylTgQnMCZjPaaEXepUZ+gEacJMpEA5AwKFrWQA8eZ9F2qE3qQE2iYgAcJts8KJZuZq+CQU12iRM4KC8QYo7GgA/sAcx+qMYEAZlkAIsYAE0IA5X0AVF0KFoKaL3+QNv2gU0wAAswAA0AAEf0Ad7oANsQAVZ6aNX6ZtiMAZtYRuX4aUG8glNEKYTegY9YKiqGQYGIKQIoKFf0AU/0KEpYAGTeZ/hqAKe+gUfgAAaYKIWgIhUSqhVGZ+IigFjsKWV0ah9aSCekE6m2Z4d8AUQQAfwGZ1jQKIMsAcc2qEasKEDwABCKqKqOqIpgACOaZt+OpmDGp6I6puKmiK10R2Oqv+rh7B67NCeAfCrM3kGYbCu7LquNokANnmT8moBV8AAa+ma88qTN1kAlgkBGjCZepAB21oHtbqo2zEHaLAi4SquIUmuHfERH9EB3CCOW2cEPXmbY0mWzmqvOnCiZKmTFoAAYymWezAGgcoAhFoHbPABBnuwAWB3jcCw+MAiTBChSqEUErsNnzqvbbmWPmmZNJmxssmvx/oB4AAEbeGt30oXDaAb6imzpEmz5XqzVNsBHUAOKoAN3XCZRWoB2PC124ARAqAx2yEglvGydhEVUPsdoPAHuxChHoEGczC3dFu3c3sbY0u2Zbu3t/ERQnBSaeuUayuzoLAbTcALU6sUdnsSt2Nrt0mxETPABE57Cbmqq4EAADs=" +#define ZEND_LOGO_DATA_URI "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAAvCAYAAADKH9ehAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAEWJJREFUeNrsXQl0VNUZvjNJSAgEAxHCGsNitSBFxB1l0boUW1pp3VAUrKLWKgUPUlEB13K0Yq1alaXWuh5EadWK1F0s1gJaoaCgQDRKBBJDVhKSzPR+zPfg5vLevCUzmZnwvnP+k8ybN3fevfff73/vBAJTHxc+khL5kr6T1ODk5nAgTRTWloghFVtEg/zfh2PkSvq9pJGSKiX9SdKittbJoD/PSYkrJD0vKeB4IsNNotfuUtHk/CM+IvijpF9KGiDpGEkLJZ3lC7qPeKKTpD9IWiDpUOfWPCi61ZeLvD2VIhTwp9QlTjK5NsIXdB/xxHmSpvD/OucWPSAyQw2+LfeG1SbXVra1Tqb785xUaNdMel0g7Iu5V1zPv6dJqpD0kKR/+ILuI55o8oeg1bFT0kWSOkraQxK+oPvw0TZR3ZY758foyQXf//ZxUFh0Q/GEfNf9gHkaJ6m7pHJJSyTt9tnXhxtBR2EGlnHCMbZMaHuHzX19JZ0u6VRJh0k6hM+BpMjnklZIelPSNhff3V5StkNlEWBMFm+3LcC+BW3GuZP2GvfmiEiCCMUzxZIKRGSt9zeML/fdGAW9JB3O8c6SlMZ+b5f0qaQiF7EpnieXY1auvZfG7zhSUk8RSS428F7M5xfsh1eAV/vxOzoq16sklZBqbdpo5H2qDPRQXoP3Ki0+20FSFyrZUgt+Rt/7KH2vZb8/t/iMG2Sy/0dI6sbvgHGoV8a3xErQb5Q0iTfHCplkzlkW7w+VNF3ST7QJUzFK0pVkDFiw+yV95uC7r5Z0k3CW2ApwIkrJ9B9IelfSh2SIlqC/pDFUZAVk0rQoMhk2GYswx+AtWvMKPtcyEckW37pPwsIHNAuBniDpYhEpBMmJwvibJL0gIlVh39r0C8UlczkXQ/mM6OtEzuf3RfPVAxUY47f5PStcGKPxpOMldbbxiBptPMavJX1PuQ/P/olyz12S7rD4PLyqBTQ8gyXVSOot6VK+dxR53wyl7POjkv7pkpcwpleJSCHP4eQjM0BB/ZuG4Hl9EO8mQx4ZQ0FfL+k+k+t4wNlULpkO24IGnSzpQklzKPDRAMvZ1eXz9uXfH/Pvx5Ie44C5zYQXUgDPj6LEnMCQ3AFkjjupjGF9/kJmxPw1oiquz+6dalXcCRSmYxwK0kDSRI71azb3Y+6GiMi6P/5ey3F3YpExjxdQoG61uX8gBetkh2OWFkUIVGUT1pS9yosZNu1nkl8uZH+mikhxkx1wz7mkB0WkXsKJFw1ZuSWKotY9wjNJS6mUy41JK5P0c2qCnBgIeQWZvEK7Dnf6WUljTT5TS7d0KwezkJShdWIeGeuKKJo7FktUQylcl0i6RtL/HH4OjP+wB0UTLTGHfubRDWyi1g7SaoZQ495z9w7RpaHKqHEfLeklEyWzk+7dl3TTu1KQCpV7+pBB4IWstFFAgvOpJnTL6DoW0xPbw3k/nIYkW+kbmHeXhUEABklazrBDBdzTDfyuBo5DPq1eoUk7ZbSk70l6n3MZjUdCDpQvMF/rezn7/hX7Xs8wsj/7rsrWdQxnZtrwwENUosJkDDZxTjOUkEH1ds6lzJyDZzGScRsonGNcMCIG+WgRKTRQ8Su2p7uRi/mlKjZKekREChS2KIOcTvfqp3RZDlM+cxnfv8Thc75Pt8kqo92VzNTbxBqcQlceivAdByHDIxbvFTMOLovyHAGGK3qc/jJDoDc4hpjABzBm4UAglBFqEAOqt8mB29ss4uJnNCHfSK/tVZMYEfMykt7Bcco1eDLDHCT8gmzzRdLHZL6wRSgzg6GIgVl8Xj2uhPA+oQn53yTdK2mVMC8NzuJ8zaSyM/ApxyzWCFJRvUQ3eQ29BTNFcRgt+FTl2g30zDZZtD/ZRMifE5ES6Y9MxqAHQ7XZikI9nd97j5p1f83GZTPr6Crt2sOcOB1zTYT8HrqjVRZx4wbSAt47SXn/YsZV9zp4zuvJgNGQRaszmoN1rBY6IH4dHiVHcA5dZd2zeIbPv8ZBkghYTQFTx/h1WvSz6c3kM5ewGG8Prvxc5DZWS2u+dypnM5Y3sIJMXmbxfXW0misZN56oxITnWsyl2fg+6+C+zWTefMWr68RwaYF271htHBZqCsKqL28wB/ACjYShrE9nUjfWmEU33A7woqbR4k5UlNk4yoYOzOHvtGs30KO1QgnlZC2VohGOIGn7WEvW0ZdoMeCHfBgdo8X++m3V+s2wEHKzJMblJom92+ne2SHDwT1gknUispPpJLrrVZqwLxTmy5F5jOdVS72F/b6UwlbrcEytrD00+a8l/ZUM82jEZd8peu8uNYS8JxNWqis5IYqQCy1rPUULh8Y7fOYal3zzmPb6aJN7zlf+32bBV9ESclNE85WUX4j4oNbl/fM1b2eoxX3jyXNqiDTP4Xe8Rm9ItfSjvAr6DM0d+o5MXW/CuHO0a7eZTLYT3KF9LktYZ/WdCI+IkoV+lFZ6l3J9OF14HdM0F3MrhXxFjJmqhh5FBera24XqxaCqL0UosK97Z2ku+yJaEqf4D62ByoROcjZuN78Xaa9zTBSzKvxvC+vlrmgWVPU2h4j4FCO5lZ+vNBnpYHHfOOX/PfR83eApTaGM8CLop5l88WSLWAOu4AiNme5owcBO1xhlLGO/eGAFkyYqrtFe5zKzqU7KBE5o/BAIiv7VJSK7qV4GhEF1XtSk0YseWl6lWYI+cXj6pigJLkH3Vk0qfebxe4q0JGOGSDxCWn/Nchk9qJgMfGKS87LDes1IHeVW0LszgaC6sPMYE5lBt4CzRcuy4lVMLKlWfWwcJ+YpxtcGjtOYfzRjTgNIlv0rnpyCveeHNFSJ/jUlonH/3nNYqyOU28qYhHOLbzVPqFc81JQDKxnQ5twLdmjfmQzlxU6eoZ/mma3y8D3VonlhUr6bElhMwJ81RseSxW+jfOYULdYGAw5s4WBtpeU0ijKwxnp/HCfn70piCNlMFEUU8/WpmnZe1Bq80r96m5yMkIwx9nnNHTWFs114q0ArM1HsiUY7j5/rKFIThdrrzR7agHyoy9vd3Ag64uEfKa+xjIKlLqtTUBB7FWgJrQ9joFl1d2cQ2wzHaeDXa6/ztO9Wx+OT+FrzSAKuV12ptOZp+ljnaVawk8uxDpnMZXYCGB3PXqe5sl7QQ5ubhhQR9B4mQpvjIR+gJgrbOxV0rK/rVUyXmyRWdI2a2YLEhVP3BwmN9sJ9BtQpKkxiSDOrUeUhaeQaPevKzKQ3oIVTSGatcynoRl29sIkh440a8pURNoz00Ab4Ts1obxCps1FKl8k5IpKbcmsgu6nz6ETQC+iSqoKKOPmVJBmYnDjHX4EozB9s7TgwykkyYS13URAHpmstYIloOP/HEi6Wx5a4+DwSpH2V18tTyHUPm3iQeS1s09ai4/0ntVgNRQmzHTRulGwaQNnei3FgHqPcMBEJlXrNioAaE8AcupKBd7ElBu1uTxCzg+dmKB4TahiQNX/OxssAb00Uzdeci4S3FYhEQdfkWCrc1cI2K+2EDhsP1OUxZGUnOWTmcgphV0UgZ4jUR1hLlBiuJfqJpb61CXimOrq8RqiEeu6TU3iMwdzYgWhUnWHDDKr0ptLar6USqmOfYYiGMMTUN/KgziGVTo+pNJHBBfF0zVAQc6N2DUL+tcO2Yc1Rk2ss+yBmOko43yCSCljJXAWA7PD4eAt6MBy2yiNACRvVVN05t40pPLYPsT+zlRDpOLG/Jt8OSGKhmnBpivV7q/Y6JkucVgkyWKb52rVZwl0tvNDi+AzRvKjfK1Dnjvpd1FhPEc1LBVsbqENXN35cFaPY2BIVGdlWYZKqgPPj/RythNtpcNycpoOxwAae0bGwhAkAQg01cfiDWDRqZtHhCqFQ5FAtOXKXh/Yh6Ci2N5YMUDW2SHg/N3scn02N++cnMIZCBdwS9gtApRxqDc6OlzWtSrdc8cJGlzP5fzZDri1tQNixISWL/5fSQvcVzfe/wzXfSG8Kuw03pHB/t5KMik+EYJ1EC1d0zCw6fofqRI2ZJwpvyxN4uPs0q/6UR2szyESobxatf3aa7jvfrT0DGPNpYV3H3CI0BYLGllQdy7TX14rUP/zzDHpuRp0EPLnJvH68Qij/RXnyIyku5Ea+5S3NO7s01q77eMY1qqY8T7Qs+4qtq+o2UWhjZO6HuWhjJBlZXWbAHvbFSTAxqMW+RbuG3VfviAP36tshujINh6Tr3kE0BNMl5x8Qq6+mVTdwrMlzpRrGaGPzVpw9NDNFngjoFZZzRCS/FRPXHRZT31X2MgfYTQYX1WE1moaaQJfKEFTs/camkXnUwt9YtNWPiuc67VmRlb0yiRgS/cAe7is0QXuTAm9kikM2DNc5OkeGRaMU8tq0TJHbUCOtezMeRfITiSv1PLLbGE5gb/NOB/1AuR1KlLETDltidyR4XIPasyEnc6eIbRa9kfNifFeXJOAnVJBiKfFCvobcLKccLHWojHJpIPH3iXQlpoNLrdcH44sucvmQOHHjZ9rDrGdbixVmbk/XGy4mtiKuoQDjmQpFJLs6wuSZvqKmL0ky6zOZLry+420UKUaue5ooyeqy9+iopgM989cp1Dcp16bSU1tOJbyFyjedTID5wOk6OAUFFXUDKFRLkmBM3xH7fzIJwPLsxexDMWP2b8g38DqN45ywCuH0VNuv+XmjwOYCjtUakbg6AkGlNoQGBMB5A9g8hh2g7zFE2U4F35FxfHfmwwbxcz3Yl32C/oAwPwDAS6UXdpOhXPZ27Trc9R/SLTla0zzGoXl2QAexnLVZJB/CZMpV7HthfL4lJIrb54u+tdv3/rCiSbw+k88yM9ZxXgKwlHmZycq13iSr0KeMHmUZw6r1VICrLT4D5fy4wq/5DAvfjaWC9oAd9KxwTNUJynUjL+EqpwSTME1zOWMBuIxmZ7p9RCsNq+NmdxW09I1MdNkJeYZNHsIt0qKEO2Z4kvmHadS+Xqv2cqzc93rpuhdl54tg2DISuJljBW3uZjMHrAPqHOYK6zPIM23G2+14Rts4cyLbdxo3Y667UskOo/W/m/PwRhQBwZFkT2vXzDbTtLMZCyfP1155bbfDrpjKZoYH41bO+d97jmEgMPVxFMF0iHESIkiNtDhKuwV058cw0dBZNP+lFsSU/6VWf0E4P/x+IF2eJnokr4uW/2jAKPYjjRb7Cxef70c3qsCl0im1Gj/Uu2eF6sWo0rUiTQq7zS+pYjywnXYwcyOZfI4mKgHj9N2ttHqbRfSlQXhjw5XXy4S7ZbzOovkxVRsphHp8ia3HlyleZS1zHcvoVrdjuNFdEe7edGHzSbpSria/WZ3+cxYV5DCx/4w7FUfyfTW0WO+i7x2YrzKUXZFw/sut+OxJDGkHUxEZPwgCquQcIgxZR9oXekDQk8FF60bqwocupaIoEz6EmaC3C+0Ro6Wgp4eb2tpPJqN+4xXFXQ3TfUfCc5PDNnLZDpLIV1NADKyjZa87mHgmWX57bYdIfIY3pdCGf43xQUXI62kBn3fZxi4SPC8crIjDQ4yzFAaz/XcPJn7xf03VRzIB5Z7qCbBzPQi5jga2E9bCD+ELug8ficEZCk/Cmj8Ro3aLtLxDR1/QffhIHNRTUZCf+S5G7SJBp2b7G31B9+EjcVAFEInZQ2LU7jiN1zf4gu7DR+KwTvkfO9bGx6BNnEQ8XXmN5cT3fEH34SNxwN4A9dgknIEwyWNbeRTwV7WYHBVwFQfbwKb7vOUjiYAiKVT1PczXqCLD/n5UbuLcNxTKoCgExSFNmsFCHI6iJBQFnUbqqbWPHyFceDAOrC/oPpIN+FVaVLrNUa6dLPbvoEQdO4pd1OUylBVkCutsOkqosbNvwcE6qL6g+0hG3MY4ejots1pT3kE4P9QDdfuLKeDfHswD6gu6j2TF2yQcLoqEGurre9EdP1QTfmxJRdn0NlrvD+jmY69Egz+UQvxfgAEALJ4EcRDa/toAAAAASUVORK5CYII=" BEGIN_EXTERN_C() PHP_FUNCTION(phpversion); @@ -84,3 +85,4 @@ void register_phpinfo_constants(INIT_FUNC_ARGS); END_EXTERN_C() #endif /* INFO_H */ + diff --git a/ext/standard/password.c b/ext/standard/password.c index ca852038a67ed..9c5280a4cb7c2 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -183,7 +183,7 @@ PHP_FUNCTION(password_get_info) return; } - if (hash_len < 0 || (size_t) hash_len < 0) { + if (hash_len < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied password hash too long to safely identify"); RETURN_FALSE; } diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index 1cf27790718d7..ef43cddfcc416 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -117,6 +117,9 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC); #define PHP_SORT_NATURAL 6 #define PHP_SORT_FLAG_CASE 8 +#define ARRAY_FILTER_USE_BOTH 1 +#define ARRAY_FILTER_USE_KEY 2 + ZEND_BEGIN_MODULE_GLOBALS(array) int *multisort_flags[2]; int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC); diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index f8d7bda482385..0adb1e05290a0 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -63,6 +63,12 @@ php_stream_ops php_stream_output_ops = { NULL /* set_option */ }; +typedef struct php_stream_input { /* {{{ */ + php_stream **body_ptr; + off_t position; +} php_stream_input_t; +/* }}} */ + static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */ { return -1; @@ -71,42 +77,36 @@ static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */ { - off_t *position = (off_t*)stream->abstract; - size_t read_bytes = 0; - - if (!stream->eof) { - if (SG(request_info).raw_post_data) { /* data has already been read by a post handler */ - read_bytes = SG(request_info).raw_post_data_length - *position; - if (read_bytes <= count) { - stream->eof = 1; - } else { - read_bytes = count; - } - if (read_bytes) { - memcpy(buf, SG(request_info).raw_post_data + *position, read_bytes); - } - } else if (sapi_module.read_post) { - read_bytes = sapi_module.read_post(buf, count TSRMLS_CC); - if (read_bytes <= 0) { - stream->eof = 1; - read_bytes = 0; - } - /* Increment SG(read_post_bytes) only when something was actually read. */ - SG(read_post_bytes) += read_bytes; - } else { - stream->eof = 1; + php_stream_input_t *input = stream->abstract; + size_t read; + + if (!SG(post_read) && SG(read_post_bytes) < input->position + count) { + /* read requested data from SAPI */ + int read_bytes = sapi_read_post_block(buf, count TSRMLS_CC); + + if (read_bytes > 0) { + php_stream_seek(*input->body_ptr, 0, SEEK_END); + php_stream_write(*input->body_ptr, buf, read_bytes); } } - *position += read_bytes; + php_stream_seek(*input->body_ptr, input->position, SEEK_SET); + read = php_stream_read(*input->body_ptr, buf, count); + + if (!read || read == (size_t) -1) { + stream->eof = 1; + } else { + input->position += read; + } - return read_bytes; + return read; } /* }}} */ static int php_stream_input_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ { efree(stream->abstract); + stream->abstract = NULL; return 0; } @@ -118,13 +118,27 @@ static int php_stream_input_flush(php_stream *stream TSRMLS_DC) /* {{{ */ } /* }}} */ +static int php_stream_input_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) /* {{{ */ +{ + php_stream_input_t *input = stream->abstract; + + if (*input->body_ptr) { + int sought = php_stream_seek(*input->body_ptr, offset, whence); + *newoffset = (*input->body_ptr)->position; + return sought; + } + + return -1; +} +/* }}} */ + php_stream_ops php_stream_input_ops = { php_stream_input_write, php_stream_input_read, php_stream_input_close, php_stream_input_flush, "Input", - NULL, /* seek */ + php_stream_input_seek, NULL, /* cast */ NULL, /* stat */ NULL /* set_option */ @@ -157,7 +171,8 @@ static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, i } /* }}} */ -php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ +php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, + char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ { int fd = -1; int mode_rw = 0; @@ -203,13 +218,23 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch } if (!strcasecmp(path, "input")) { + php_stream_input_t *input; + if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration"); } return NULL; } - return php_stream_alloc(&php_stream_input_ops, ecalloc(1, sizeof(off_t)), 0, "rb"); + + input = ecalloc(1, sizeof(*input)); + if (*(input->body_ptr = &SG(request_info).request_body)) { + php_stream_rewind(*input->body_ptr); + } else { + *input->body_ptr = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE); + } + + return php_stream_alloc(&php_stream_input_ops, input, 0, "rb"); } if (!strcasecmp(path, "stdin")) { @@ -258,8 +283,8 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch fd = dup(STDERR_FILENO); } } else if (!strncasecmp(path, "fd/", 3)) { - char *start, - *end; + const char *start; + char *end; long fildes_ori; int dtablesize; diff --git a/ext/standard/php_fopen_wrappers.h b/ext/standard/php_fopen_wrappers.h index 5f78256bcb423..366a1295b3c2c 100644 --- a/ext/standard/php_fopen_wrappers.h +++ b/ext/standard/php_fopen_wrappers.h @@ -23,8 +23,8 @@ #ifndef PHP_FOPEN_WRAPPERS_H #define PHP_FOPEN_WRAPPERS_H -php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -php_stream *php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +php_stream *php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); extern PHPAPI php_stream_wrapper php_stream_http_wrapper; extern PHPAPI php_stream_wrapper php_stream_ftp_wrapper; extern php_stream_wrapper php_stream_php_wrapper; diff --git a/ext/standard/string.c b/ext/standard/string.c index b9d7427eb9092..2f05b65bb939c 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -13,7 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | - | Stig S�ther Bakken | + | Stig S�ther Bakken | | Zeev Suraski | +----------------------------------------------------------------------+ */ @@ -23,11 +23,6 @@ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ #include -#ifdef PHP_WIN32 -# include "win32/php_stdint.h" -#else -# include -#endif #include "php.h" #include "php_rand.h" #include "php_string.h" diff --git a/ext/standard/tests/array/array_filter_error.phpt b/ext/standard/tests/array/array_filter_error.phpt index 20e89aa4b776e..3f8f51bc14a5b 100644 --- a/ext/standard/tests/array/array_filter_error.phpt +++ b/ext/standard/tests/array/array_filter_error.phpt @@ -28,7 +28,7 @@ $extra_arg = 10; // with one more than the expected number of arguments echo "-- Testing array_filter() function with more than expected no. of arguments --"; -var_dump( array_filter($input, "odd", $extra_arg) ); +var_dump( array_filter($input, "odd", $extra_arg, $extra_arg) ); // with incorrect callback function echo "-- Testing array_filter() function with incorrect callback --"; @@ -42,7 +42,7 @@ echo "Done" Warning: array_filter() expects at least 1 parameter, 0 given in %s on line %d NULL -- Testing array_filter() function with more than expected no. of arguments -- -Warning: array_filter() expects at most 2 parameters, 3 given in %s on line %d +Warning: array_filter() expects at most 3 parameters, 4 given in %s on line %d NULL -- Testing array_filter() function with incorrect callback -- Warning: array_filter() expects parameter 2 to be a valid callback, function 'even' not found or invalid function name in %s on line %d diff --git a/ext/standard/tests/array/array_filter_variation10.phpt b/ext/standard/tests/array/array_filter_variation10.phpt new file mode 100644 index 0000000000000..f0a6115f79ccf --- /dev/null +++ b/ext/standard/tests/array/array_filter_variation10.phpt @@ -0,0 +1,103 @@ +--TEST-- +Test array_filter() function : usage variations - using the array keys inside 'callback' +--FILE-- + 4; +} + +var_dump( array_filter($input, 'dump2', true) ); + +echo "*** Testing array_filter() : usage variations - 'callback' expecting second argument ***\n"; + +var_dump( array_filter($small, 'dump', false) ); + +echo "*** Testing array_filter() with various use types ***\n"; + +$mixed = array(1 => 'a', 2 => 'b', 'a' => 1, 'b' => 2); + +var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_KEY)); + +var_dump(array_filter($mixed, 'is_numeric', 0)); + +var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_BOTH)); + +echo "Done" +?> +--EXPECTF-- +*** Testing array_filter() : usage variations - using array keys in 'callback' *** +0 = 0 +1 = 1 +2 = -1 +3 = 10 +4 = 100 +5 = 1000 +6 = Hello +7 = +array(0) { +} +*** Testing array_filter() : usage variations - 'callback' filters based on key value *** +array(3) { + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL +} +*** Testing array_filter() : usage variations - 'callback' expecting second argument *** + +Warning: Missing argument 2 for dump() in %s on line %d + +Notice: Undefined variable: key in %s on line %d + = 123 +array(0) { +} +*** Testing array_filter() with various use types *** +array(2) { + [1]=> + string(1) "a" + [2]=> + string(1) "b" +} +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 +array(0) { +} +Done diff --git a/ext/standard/tests/dir/chdir_basic.phpt b/ext/standard/tests/dir/chdir_basic.phpt index 5fc0e5b8867f0..81d3c7c9d1a1f 100644 --- a/ext/standard/tests/dir/chdir_basic.phpt +++ b/ext/standard/tests/dir/chdir_basic.phpt @@ -14,40 +14,40 @@ Test chdir() function : basic functionality echo "*** Testing chdir() : basic functionality ***\n"; $base_dir_path = dirname(__FILE__); -$level_one_dir_name = "level_one"; -$level_one_dir_path = "$base_dir_path/$level_one_dir_name"; +$level1_one_dir_name = "level1_one"; +$level1_one_dir_path = "$base_dir_path/$level1_one_dir_name"; -$level_two_dir_name = "level_two"; -$level_two_dir_path = "$base_dir_path/$level_one_dir_name/$level_two_dir_name"; +$level1_two_dir_name = "level1_two"; +$level1_two_dir_path = "$base_dir_path/$level1_one_dir_name/$level1_two_dir_name"; // create directories -mkdir($level_one_dir_path); -mkdir($level_two_dir_path); +mkdir($level1_one_dir_path); +mkdir($level1_two_dir_path); echo "\n-- Testing chdir() with absolute path: --\n"; chdir($base_dir_path); -var_dump(chdir($level_one_dir_path)); +var_dump(chdir($level1_one_dir_path)); var_dump(getcwd()); echo "\n-- Testing chdir() with relative paths: --\n"; -var_dump(chdir($level_two_dir_name)); +var_dump(chdir($level1_two_dir_name)); var_dump(getcwd()); ?> ===DONE=== --CLEAN-- --EXPECTF-- *** Testing chdir() : basic functionality *** -- Testing chdir() with absolute path: -- bool(true) -string(%d) "%slevel_one" +string(%d) "%slevel1_one" -- Testing chdir() with relative paths: -- bool(true) -string(%d) "%slevel_one%elevel_two" +string(%d) "%slevel1_one%elevel1_two" ===DONE=== diff --git a/ext/standard/tests/dir/chdir_variation2.phpt b/ext/standard/tests/dir/chdir_variation2.phpt index fa70f9e104f5d..9ca6a9774873d 100644 --- a/ext/standard/tests/dir/chdir_variation2.phpt +++ b/ext/standard/tests/dir/chdir_variation2.phpt @@ -15,32 +15,32 @@ echo "*** Testing chdir() : usage variations ***\n"; $base_dir_path = dirname(__FILE__); -$level_one_dir_name = "level_one"; -$level_one_dir_path = "$base_dir_path/$level_one_dir_name"; +$level2_one_dir_name = "level2_one"; +$level2_one_dir_path = "$base_dir_path/$level2_one_dir_name"; -$level_two_dir_name = "level_two"; -$level_two_dir_path = "$base_dir_path/$level_one_dir_name/$level_two_dir_name"; +$level2_two_dir_name = "level2_two"; +$level2_two_dir_path = "$base_dir_path/$level2_one_dir_name/$level2_two_dir_name"; // create directories -mkdir($level_one_dir_path); -mkdir($level_two_dir_path); +mkdir($level2_one_dir_path); +mkdir($level2_two_dir_path); -echo "\n-- \$directory = './level_one': --\n"; +echo "\n-- \$directory = './level2_one': --\n"; var_dump(chdir($base_dir_path)); -var_dump(chdir("./$level_one_dir_name")); +var_dump(chdir("./$level2_one_dir_name")); var_dump(getcwd()); -echo "\n-- \$directory = 'level_one/level_two': --\n"; +echo "\n-- \$directory = 'level2_one/level2_two': --\n"; var_dump(chdir($base_dir_path)); -var_dump(chdir("$level_one_dir_name/$level_two_dir_name")); +var_dump(chdir("$level2_one_dir_name/$level2_two_dir_name")); var_dump(getcwd()); echo "\n-- \$directory = '..': --\n"; var_dump(chdir('..')); var_dump(getcwd()); -echo "\n-- \$directory = 'level_two', '.': --\n"; -var_dump(chdir($level_two_dir_path)); +echo "\n-- \$directory = 'level2_two', '.': --\n"; +var_dump(chdir($level2_two_dir_path)); var_dump(chdir('.')); var_dump(getcwd()); @@ -49,13 +49,13 @@ var_dump(chdir('../')); var_dump(getcwd()); echo "\n-- \$directory = './': --\n"; -var_dump(chdir($level_two_dir_path)); +var_dump(chdir($level2_two_dir_path)); var_dump(chdir('./')); var_dump(getcwd()); -echo "\n-- \$directory = '../../'level_one': --\n"; -var_dump(chdir($level_two_dir_path)); -var_dump(chdir("../../$level_one_dir_name")); +echo "\n-- \$directory = '../../'level2_one': --\n"; +var_dump(chdir($level2_two_dir_path)); +var_dump(chdir("../../$level2_one_dir_name")); var_dump(getcwd()); ?> @@ -63,42 +63,42 @@ var_dump(getcwd()); --CLEAN-- --EXPECTF-- *** Testing chdir() : usage variations *** --- $directory = './level_one': -- +-- $directory = './level2_one': -- bool(true) bool(true) -string(%d) "%slevel_one" +string(%d) "%slevel2_one" --- $directory = 'level_one/level_two': -- +-- $directory = 'level2_one/level2_two': -- bool(true) bool(true) -string(%d) "%slevel_one%elevel_two" +string(%d) "%slevel2_one%elevel2_two" -- $directory = '..': -- bool(true) -string(%d) "%slevel_one" +string(%d) "%slevel2_one" --- $directory = 'level_two', '.': -- +-- $directory = 'level2_two', '.': -- bool(true) bool(true) -string(%d) "%slevel_one%elevel_two" +string(%d) "%slevel2_one%elevel2_two" -- $directory = '../': -- bool(true) -string(%d) "%slevel_one" +string(%d) "%slevel2_one" -- $directory = './': -- bool(true) bool(true) -string(%d) "%slevel_one%elevel_two" +string(%d) "%slevel2_one%elevel2_two" --- $directory = '../../'level_one': -- +-- $directory = '../../'level2_one': -- bool(true) bool(true) -string(%d) "%slevel_one" +string(%d) "%slevel2_one" ===DONE=== diff --git a/ext/standard/tests/file/bug41655_2.phpt b/ext/standard/tests/file/bug41655_2.phpt index d406f1ba0404b..96f5cc86f0e54 100644 --- a/ext/standard/tests/file/bug41655_2.phpt +++ b/ext/standard/tests/file/bug41655_2.phpt @@ -5,11 +5,13 @@ open_basedir=/ --FILE-- --EXPECTF-- Array ( [0] => %stest.csv + [1] => %stest2.csv + [2] => %stest3.csv ) diff --git a/ext/standard/tests/file/copy_variation16-win32.phpt b/ext/standard/tests/file/copy_variation16-win32.phpt index 7688f5eeabf86..d95d24adacb56 100644 --- a/ext/standard/tests/file/copy_variation16-win32.phpt +++ b/ext/standard/tests/file/copy_variation16-win32.phpt @@ -22,7 +22,7 @@ mkdir($base_dir); $sub_dir = $base_dir."/copy_variation16_sub"; mkdir($sub_dir); -$dirname_with_blank = $sub_dir."/copy variation6"; +$dirname_with_blank = $sub_dir."/copy variation16"; mkdir($dirname_with_blank); $src_file_name = dirname(__FILE__)."/copy_variation16.tmp"; @@ -139,6 +139,6 @@ Existence of destination file => bool(false) Size of source file => int(3500) Copy operation => bool(true) Existence of destination file => bool(true) -Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation6/copy_copy_variation16.tmp +Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation16/copy_copy_variation16.tmp Size of destination file => int(3500) *** Done *** diff --git a/ext/standard/tests/file/copy_variation16.phpt b/ext/standard/tests/file/copy_variation16.phpt index 9ad834bdb4192..e36fee1d666b7 100644 --- a/ext/standard/tests/file/copy_variation16.phpt +++ b/ext/standard/tests/file/copy_variation16.phpt @@ -22,7 +22,7 @@ mkdir($base_dir); $sub_dir = $base_dir."/copy_variation16_sub"; mkdir($sub_dir); -$dirname_with_blank = $sub_dir."/copy variation6"; +$dirname_with_blank = $sub_dir."/copy variation16"; mkdir($dirname_with_blank); $src_file_name = dirname(__FILE__)."/copy_variation16.tmp"; @@ -138,6 +138,6 @@ Size of destination file => int(3500) Size of source file => int(3500) Copy operation => bool(true) Existence of destination file => bool(true) -Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation6/copy_copy_variation16.tmp +Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation16/copy_copy_variation16.tmp Size of destination file => int(3500) *** Done *** diff --git a/ext/standard/tests/file/disk_free_space_basic.phpt b/ext/standard/tests/file/disk_free_space_basic.phpt index 200e92ab43e84..2904ff9a5bfe0 100644 --- a/ext/standard/tests/file/disk_free_space_basic.phpt +++ b/ext/standard/tests/file/disk_free_space_basic.phpt @@ -29,7 +29,7 @@ $space1 = disk_free_space($file_path.$dir); var_dump( $space1 ); $fh = fopen($file_path.$dir."/disk_free_space.tmp", "a"); -$data = str_repeat("x", 4096); +$data = str_repeat("x", 0xffff); fwrite($fh, (binary)$data); fclose($fh); @@ -39,8 +39,10 @@ var_dump( $space2 ); if($space1 > $space2 ) echo "\n Free Space Value Is Correct\n"; -else +else { echo "\n Free Space Value Is Incorrect\n"; + var_dump($space1, $space2); +} echo "*** Testing with Binary Input ***\n"; var_dump( disk_free_space(b"$file_path") ); diff --git a/ext/standard/tests/file/fopen_include_path.inc b/ext/standard/tests/file/fopen_include_path.inc index 7d6723a815018..5bc9b6ce3b201 100644 --- a/ext/standard/tests/file/fopen_include_path.inc +++ b/ext/standard/tests/file/fopen_include_path.inc @@ -1,6 +1,6 @@ ==DONE== --EXPECT-- array(0) { } -bool(false) +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +bool(true) ==DONE== diff --git a/ext/standard/tests/file/glob_variation4.phpt b/ext/standard/tests/file/glob_variation4.phpt new file mode 100644 index 0000000000000..00d8f648aad36 --- /dev/null +++ b/ext/standard/tests/file/glob_variation4.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test glob() function: ensure no platform difference, variation 2 +--FILE-- + +==DONE== +--EXPECT-- +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +bool(true) +==DONE== diff --git a/ext/standard/tests/file/glob_variation5.phpt b/ext/standard/tests/file/glob_variation5.phpt new file mode 100644 index 0000000000000..10db40099bc57 --- /dev/null +++ b/ext/standard/tests/file/glob_variation5.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test glob() function: ensure no platform difference, variation 3 +--SKIPIF-- + +--FILE-- + +==DONE== +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +==DONE== diff --git a/ext/standard/tests/file/glob_variation6.phpt b/ext/standard/tests/file/glob_variation6.phpt new file mode 100644 index 0000000000000..9cd9c2b3538b7 --- /dev/null +++ b/ext/standard/tests/file/glob_variation6.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test glob() function: ensure no platform difference, variation 4 +--SKIPIF-- + +--FILE-- + +==DONE== +--EXPECT-- +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +bool(true) +==DONE== diff --git a/ext/standard/tests/file/rename_variation1.phpt b/ext/standard/tests/file/rename_variation1.phpt index 0f7321e20506c..54338d74601a7 100644 --- a/ext/standard/tests/file/rename_variation1.phpt +++ b/ext/standard/tests/file/rename_variation1.phpt @@ -16,16 +16,16 @@ $file_path = dirname(__FILE__); echo "\n*** Testing rename() : renaming directory across directories ***\n"; $src_dirs = array ( /* Testing simple directory tree */ - "$file_path/rename_variation/", + "$file_path/rename_variation1/", /* Testing a dir with trailing slash */ - "$file_path/rename_variation/", + "$file_path/rename_variation1/", /* Testing dir with double trailing slashes */ - "$file_path//rename_variation//", + "$file_path//rename_variation1//", ); -$dest_dir = "$file_path/rename_variation_dir"; +$dest_dir = "$file_path/rename_variation1_dir"; // create the $dest_dir mkdir($dest_dir); @@ -35,7 +35,7 @@ foreach($src_dirs as $src_dir) { echo "-- Iteration $counter --\n"; // create the src dir - mkdir("$file_path/rename_variation/"); + mkdir("$file_path/rename_variation1/"); // rename the src dir to a new dir in dest dir var_dump( rename($src_dir, $dest_dir."/new_dir") ); // ensure that dir was renamed @@ -52,7 +52,7 @@ echo "Done\n"; --CLEAN-- --EXPECTF-- *** Testing rename() : renaming directory across directories *** diff --git a/ext/standard/tests/file/rename_variation2-win32.phpt b/ext/standard/tests/file/rename_variation2-win32.phpt index 87f4e7ddb139c..9627a9fa53012 100644 --- a/ext/standard/tests/file/rename_variation2-win32.phpt +++ b/ext/standard/tests/file/rename_variation2-win32.phpt @@ -15,27 +15,27 @@ if (substr(PHP_OS, 0, 3) != 'WIN') { require dirname(__FILE__).'/file.inc'; $file_path = dirname(__FILE__); -mkdir("$file_path/rename_variation_dir"); +mkdir("$file_path/rename_variation2_dir"); /* Renaming a file and directory to numeric name */ echo "\n*** Testing rename() by renaming a file and directory to numeric name ***\n"; -$fp = fopen($file_path."/rename_variation.tmp", "w"); +$fp = fopen($file_path."/rename_variation2.tmp", "w"); fclose($fp); // renaming existing file to numeric name -var_dump( rename($file_path."/rename_variation.tmp", $file_path."/12345") ); +var_dump( rename($file_path."/rename_variation2.tmp", $file_path."/12345") ); // ensure that rename worked fine -var_dump( file_exists($file_path."/rename_variation.tmp" ) ); // expecting false +var_dump( file_exists($file_path."/rename_variation2.tmp" ) ); // expecting false var_dump( file_exists($file_path."/12345" ) ); // expecting true unlink($file_path."/12345"); // renaming a directory to numeric name -var_dump( rename($file_path."/rename_variation_dir/", $file_path."/12345") ); +var_dump( rename($file_path."/rename_variation2_dir/", $file_path."/12345") ); // ensure that rename worked fine -var_dump( file_exists($file_path."/rename_variation_dir" ) ); // expecting false +var_dump( file_exists($file_path."/rename_variation2_dir" ) ); // expecting false var_dump( file_exists($file_path."/12345" ) ); // expecting true rmdir($file_path."/12345"); @@ -45,9 +45,9 @@ echo "Done\n"; --CLEAN-- --EXPECTF-- *** Testing rename() by renaming a file and directory to numeric name *** diff --git a/ext/standard/tests/file/rename_variation2.phpt b/ext/standard/tests/file/rename_variation2.phpt index fa3ee1e017f6b..1e0a5d9edd306 100644 --- a/ext/standard/tests/file/rename_variation2.phpt +++ b/ext/standard/tests/file/rename_variation2.phpt @@ -11,7 +11,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $file_path = dirname(__FILE__); -$dest_dir = "$file_path/rename_variation_dir"; +$dest_dir = "$file_path/rename_variation2_dir"; // create the $dest_dir mkdir($dest_dir); @@ -23,11 +23,11 @@ $filename = $file_path."/rename_variation2.tmp"; var_dump(touch($filename)); // create the soft links to the file -$linkname = $file_path."/rename_variation_soft_link1.tmp"; +$linkname = $file_path."/rename_variation2_soft_link1.tmp"; var_dump(symlink($filename, $linkname)); //rename the link to a new name in the same dir -$dest_linkname = $file_path."/rename_variation_soft_link2.tmp"; +$dest_linkname = $file_path."/rename_variation2_soft_link2.tmp"; var_dump( rename( $linkname, $dest_linkname) ); //ensure that link was renamed clearstatcache(); @@ -35,14 +35,14 @@ var_dump( file_exists($linkname) ); // expecting false var_dump( file_exists($dest_linkname) ); // expecting true // rename a link across dir -var_dump( rename($dest_linkname, $dest_dir."/rename_variation_soft_link2.tmp")); +var_dump( rename($dest_linkname, $dest_dir."/rename_variation2_soft_link2.tmp")); //ensure that link got renamed clearstatcache(); var_dump( file_exists($dest_linkname) ); // expecting false -var_dump( file_exists($dest_dir."/rename_variation_soft_link2.tmp") ); // expecting true +var_dump( file_exists($dest_dir."/rename_variation2_soft_link2.tmp") ); // expecting true // delete the link file now -unlink($dest_dir."/rename_variation_soft_link2.tmp"); +unlink($dest_dir."/rename_variation2_soft_link2.tmp"); echo "Done\n"; ?> @@ -50,7 +50,7 @@ echo "Done\n"; --EXPECTF-- *** Testing rename() on soft links *** diff --git a/ext/standard/tests/file/rename_variation3.phpt b/ext/standard/tests/file/rename_variation3.phpt index ce8921630b73c..7c47040729c77 100644 --- a/ext/standard/tests/file/rename_variation3.phpt +++ b/ext/standard/tests/file/rename_variation3.phpt @@ -11,41 +11,41 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { $file_path = dirname(__FILE__); -$dest_dir = "$file_path/rename_variation_dir"; +$dest_dir = "$file_path/rename_variation3_dir"; // create the $dest_dir mkdir($dest_dir); echo "\n*** Testing rename() on hard links ***\n"; -$filename = $file_path."/rename_variation1.tmp"; +$filename = $file_path."/rename_variation31.tmp"; @unlink($filename); var_dump(touch($filename)); -$linkname = $file_path."/rename_variation_hard_link1.tmp"; +$linkname = $file_path."/rename_variation3_hard_link1.tmp"; var_dump(link($filename, $linkname)); //rename the link to a new name in the same dir -$dest_linkname = $file_path."/rename_variation_hard_link2.tmp"; +$dest_linkname = $file_path."/rename_variation3_hard_link2.tmp"; var_dump( rename( $filename, $dest_linkname) ); //ensure that link was renamed var_dump( file_exists($filename) ); // expecting false var_dump( file_exists($dest_linkname) ); // expecting true // rename a hard link across dir -var_dump( rename($dest_linkname, $dest_dir."/rename_variation_hard_link2.tmp") ); +var_dump( rename($dest_linkname, $dest_dir."/rename_variation3_hard_link2.tmp") ); //ensure that link got renamed var_dump( file_exists($dest_linkname) ); // expecting false -var_dump( file_exists($dest_dir."/rename_variation_hard_link2.tmp") ); // expecting true +var_dump( file_exists($dest_dir."/rename_variation3_hard_link2.tmp") ); // expecting true // delete the link file now -unlink($dest_dir."/rename_variation_hard_link2.tmp"); +unlink($dest_dir."/rename_variation3_hard_link2.tmp"); echo "Done\n"; ?> --CLEAN-- --EXPECTF-- *** Testing rename() on hard links *** diff --git a/ext/standard/tests/file/rename_variation4.phpt b/ext/standard/tests/file/rename_variation4.phpt index 2965f7534a64d..69753bc322fa7 100644 --- a/ext/standard/tests/file/rename_variation4.phpt +++ b/ext/standard/tests/file/rename_variation4.phpt @@ -15,22 +15,22 @@ require dirname(__FILE__).'/file.inc'; /* Renaming a file, link and directory to numeric name */ echo "\n*** Testing rename() by renaming a file, link and directory to numeric name ***\n"; -$fp = fopen($file_path."/rename_variation.tmp", "w"); +$fp = fopen($file_path."/rename_variation4.tmp", "w"); fclose($fp); // renaming existing file to numeric name -var_dump( rename($file_path."/rename_variation.tmp", $file_path."/12345") ); +var_dump( rename($file_path."/rename_variation4.tmp", $file_path."/12345") ); // ensure that rename worked fine -var_dump( file_exists($file_path."/rename_variation.tmp" ) ); // expecting false +var_dump( file_exists($file_path."/rename_variation4.tmp" ) ); // expecting false var_dump( file_exists($file_path."/12345" ) ); // expecting true // remove the file unlink($file_path."/12345"); -mkdir($file_path."/rename_variation_dir"); +mkdir($file_path."/rename_variation4_dir"); // renaming a directory to numeric name -var_dump( rename($file_path."/rename_variation_dir/", $file_path."/12345") ); +var_dump( rename($file_path."/rename_variation4_dir/", $file_path."/12345") ); // ensure that rename worked fine -var_dump( file_exists($file_path."/rename_variation_dir" ) ); // expecting false +var_dump( file_exists($file_path."/rename_variation4_dir" ) ); // expecting false var_dump( file_exists($file_path."/12345" ) ); // expecting true echo "Done\n"; diff --git a/ext/standard/tests/file/rename_variation5.phpt b/ext/standard/tests/file/rename_variation5.phpt index bf43e49510f3e..2518cf48ea8b8 100644 --- a/ext/standard/tests/file/rename_variation5.phpt +++ b/ext/standard/tests/file/rename_variation5.phpt @@ -13,14 +13,14 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { and one another */ // create a dir $file_path = dirname(__FILE__); -$dirname = "$file_path/rename_variation_dir"; +$dirname = "$file_path/rename_variation5_dir"; mkdir($dirname); //create a file -$filename = "$file_path/rename_variation.tmp"; +$filename = "$file_path/rename_variation5.tmp"; $fp = fopen($filename, "w"); fclose($fp); // create a link -$linkname = "$file_path/rename_variation_link.tmp"; +$linkname = "$file_path/rename_variation5_link.tmp"; symlink($filename, $linkname); echo "\n-- Renaming link to same link name --\n"; @@ -54,9 +54,9 @@ echo "Done\n"; --CLEAN-- --EXPECTF-- -- Renaming link to same link name -- diff --git a/ext/standard/tests/http/bug65634.phpt b/ext/standard/tests/http/bug65634.phpt new file mode 100644 index 0000000000000..8f358cc6cfc84 --- /dev/null +++ b/ext/standard/tests/http/bug65634.phpt @@ -0,0 +1,81 @@ +--TEST-- +Bug #65634 (HTTP wrapper is very slow with protocol_version 1.1) +--INI-- +allow_url_fopen=1 +--SKIPIF-- + +--FILE-- + [ + 'protocol_version' => $version, + ], + ]; + + if ($connection) { + $options['http']['header'] = "Connection: $connection"; + } + + $ctx = stream_context_create($options); + + $responses = ["data://text/plain,HTTP/$version 204 No Content\r\n\r\n"]; + $pid = http_server('tcp://127.0.0.1:12342', $responses, $output); + + $fd = fopen('http://127.0.0.1:12342/', 'rb', false, $ctx); + fseek($output, 0, SEEK_SET); + echo stream_get_contents($output); + + http_server_kill($pid); +} + +echo "HTTP/1.0, default behaviour:\n"; +do_test('1.0', null); + +echo "HTTP/1.0, connection: close:\n"; +do_test('1.0', 'close'); + +echo "HTTP/1.0, connection: keep-alive:\n"; +do_test('1.0', 'keep-alive'); + +echo "HTTP/1.1, default behaviour:\n"; +do_test('1.1', null); + +echo "HTTP/1.1, connection: close:\n"; +do_test('1.1', 'close'); + +echo "HTTP/1.1, connection: keep-alive:\n"; +do_test('1.1', 'keep-alive'); +?> +--EXPECT-- +HTTP/1.0, default behaviour: +GET / HTTP/1.0 +Host: 127.0.0.1:12342 + +HTTP/1.0, connection: close: +GET / HTTP/1.0 +Host: 127.0.0.1:12342 +Connection: close + +HTTP/1.0, connection: keep-alive: +GET / HTTP/1.0 +Host: 127.0.0.1:12342 +Connection: keep-alive + +HTTP/1.1, default behaviour: +GET / HTTP/1.1 +Host: 127.0.0.1:12342 +Connection: close + +HTTP/1.1, connection: close: +GET / HTTP/1.1 +Host: 127.0.0.1:12342 +Connection: close + +HTTP/1.1, connection: keep-alive: +GET / HTTP/1.1 +Host: 127.0.0.1:12342 +Connection: keep-alive + diff --git a/ext/standard/tests/serialize/serialization_error_001.phpt b/ext/standard/tests/serialize/serialization_error_001.phpt index da6f50cc02b29..c6c17512f3978 100644 --- a/ext/standard/tests/serialize/serialization_error_001.phpt +++ b/ext/standard/tests/serialize/serialization_error_001.phpt @@ -21,7 +21,7 @@ var_dump( unserialize() ); //Test serialize with one more than the expected number of arguments var_dump( serialize(1,2) ); -var_dump( unserialize(1,2) ); +var_dump( unserialize(1,$x,2) ); echo "Done"; ?> @@ -31,12 +31,12 @@ echo "Done"; Warning: serialize() expects exactly 1 parameter, 0 given in %s on line 16 NULL -Warning: unserialize() expects exactly 1 parameter, 0 given in %s on line 17 +Warning: unserialize() expects at least 1 parameter, 0 given in %s on line 17 bool(false) Warning: serialize() expects exactly 1 parameter, 2 given in %s on line 20 NULL -Warning: unserialize() expects exactly 1 parameter, 2 given in %s on line 21 +Warning: unserialize() expects at most 2 parameters, 3 given in %s on line 21 bool(false) Done diff --git a/ext/standard/tests/serialize/unserialize_consumed.phpt b/ext/standard/tests/serialize/unserialize_consumed.phpt new file mode 100644 index 0000000000000..6cc11e273faaf --- /dev/null +++ b/ext/standard/tests/serialize/unserialize_consumed.phpt @@ -0,0 +1,27 @@ +--TEST-- +Unserialization of partial strings +--FILE-- +nApplyCount > 0){ + if (myht->nApplyCount > 0){ smart_str_appendl(buf, "NULL", 4); zend_error(E_WARNING, "var_export does not handle circular references"); return; @@ -943,7 +943,7 @@ PHP_FUNCTION(serialize) } /* }}} */ -/* {{{ proto mixed unserialize(string variable_representation) +/* {{{ proto mixed unserialize(string variable_representation[, int &consumed]) Takes a string representation of variable and recreates it */ PHP_FUNCTION(unserialize) { @@ -951,8 +951,9 @@ PHP_FUNCTION(unserialize) int buf_len; const unsigned char *p; php_unserialize_data_t var_hash; + zval *consumed = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &buf, &buf_len, &consumed) == FAILURE) { RETURN_FALSE; } @@ -971,6 +972,11 @@ PHP_FUNCTION(unserialize) RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + + if (consumed) { + zval_dtor(consumed); + ZVAL_LONG(consumed, ((char*)p) - buf); + } } /* }}} */ diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index 57b29e1dd7006..8c4786575effc 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -38,6 +38,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_LOGICAL_XOR", T_LOGICAL_XOR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_LOGICAL_AND", T_LOGICAL_AND, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PRINT", T_PRINT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_SR_EQUAL", T_SR_EQUAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_SL_EQUAL", T_SL_EQUAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_XOR_EQUAL", T_XOR_EQUAL, CONST_CS | CONST_PERSISTENT); @@ -108,7 +109,6 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_RETURN", T_RETURN, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_TRY", T_TRY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CATCH", T_CATCH, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FINALLY", T_FINALLY, CONST_CS | CONST_PERSISTENT); @@ -158,6 +158,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_NS_C", T_NS_C, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DIR", T_DIR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NS_SEPARATOR", T_NS_SEPARATOR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_ELLIPSIS", T_ELLIPSIS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DOUBLE_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT); } @@ -174,6 +175,7 @@ char *get_token_type_name(int token_type) case T_LOGICAL_XOR: return "T_LOGICAL_XOR"; case T_LOGICAL_AND: return "T_LOGICAL_AND"; case T_PRINT: return "T_PRINT"; + case T_YIELD: return "T_YIELD"; case T_SR_EQUAL: return "T_SR_EQUAL"; case T_SL_EQUAL: return "T_SL_EQUAL"; case T_XOR_EQUAL: return "T_XOR_EQUAL"; @@ -244,7 +246,6 @@ char *get_token_type_name(int token_type) case T_FUNCTION: return "T_FUNCTION"; case T_CONST: return "T_CONST"; case T_RETURN: return "T_RETURN"; - case T_YIELD: return "T_YIELD"; case T_TRY: return "T_TRY"; case T_CATCH: return "T_CATCH"; case T_FINALLY: return "T_FINALLY"; @@ -294,6 +295,7 @@ char *get_token_type_name(int token_type) case T_NS_C: return "T_NS_C"; case T_DIR: return "T_DIR"; case T_NS_SEPARATOR: return "T_NS_SEPARATOR"; + case T_ELLIPSIS: return "T_ELLIPSIS"; } return "UNKNOWN"; diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index aae55c8b3e2fa..76cd56f144ed7 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -588,9 +588,6 @@ PHP_METHOD(xmlreader, getAttributeNo) if (retchar) { RETVAL_STRING(retchar, 1); xmlFree(retchar); - return; - } else { - RETURN_EMPTY_STRING(); } } /* }}} */ @@ -622,9 +619,6 @@ PHP_METHOD(xmlreader, getAttributeNs) if (retchar) { RETVAL_STRING(retchar, 1); xmlFree(retchar); - return; - } else { - RETURN_EMPTY_STRING(); } } /* }}} */ diff --git a/ext/zip/CREDITS b/ext/zip/CREDITS index 6c7e42d417160..59b7ef097e531 100644 --- a/ext/zip/CREDITS +++ b/ext/zip/CREDITS @@ -1,2 +1,2 @@ Zip -Pierre-Alain Joye +Pierre-Alain Joye, Remi Collet diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 805d92442e017..83e32feca76ee 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -11,10 +11,14 @@ if test -z "$PHP_ZLIB_DIR"; then fi PHP_ARG_WITH(pcre-dir, pcre install prefix, -[ --with-pcre-dir ZIP: pcre install prefix], no, no) +[ --with-pcre-dir ZIP: pcre install prefix], no, no) + +PHP_ARG_WITH(libzip, libzip, +[ --with-libzip[=DIR] ZIP: use libzip], no, no) if test "$PHP_ZIP" != "no"; then + dnl libzip, depends on zlib if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then PHP_ZLIB_DIR="$PHP_ZLIB_DIR" @@ -47,61 +51,124 @@ if test "$PHP_ZIP" != "no"; then PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR) fi - dnl This is PECL build, check if bundled PCRE library is used - old_CPPFLAGS=$CPPFLAGS - CPPFLAGS=$INCLUDES - AC_EGREP_CPP(yes,[ -#include
-#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) -yes -#endif - ],[ - PHP_PCRE_REGEX=yes - ],[ - AC_EGREP_CPP(yes,[ -#include
-#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE) -yes -#endif - ],[ - PHP_PCRE_REGEX=pecl - ],[ - PHP_PCRE_REGEX=no + if test "$PHP_LIBZIP" != "no"; then + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + + dnl system libzip, depends on libzip + AC_MSG_CHECKING(for libzip) + if test -r $PHP_LIBZIP/include/zip.h; then + LIBZIP_CFLAGS="-I$PHP_LIBZIP/include" + LIBZIP_LIBDIR="$PHP_LIBZIP/$PHP_LIBDIR" + AC_MSG_RESULT(from option: found in $PHP_LIBZIP) + + elif test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libzip; then + LIBZIP_CFLAGS=`$PKG_CONFIG libzip --cflags` + LIBZIP_LIBDIR=`$PKG_CONFIG libzip --variable=libdir` + AC_MSG_RESULT(from pkgconfig: found in $LIBZIP_LIBDIR) + + else + for i in /usr/local /usr; do + if test -r $i/include/zip.h; then + LIBZIP_CFLAGS="-I$i/include" + LIBZIP_LIBDIR="$i/$PHP_LIBDIR" + AC_MSG_RESULT(in default path: found in $i) + break + fi + done + fi + + if test -z "$LIBZIP_LIBDIR"; then + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Please reinstall the libzip distribution) + fi + + dnl Could not think of a simple way to check libzip for overwrite support + PHP_CHECK_LIBRARY(zip, zip_open, + [ + PHP_ADD_LIBRARY_WITH_PATH(zip, $LIBZIP_LIBDIR, ZIP_SHARED_LIBADD) + AC_DEFINE(HAVE_LIBZIP,1,[ ]) + ], [ + AC_MSG_ERROR(could not find usable libzip) + ], [ + -L$LIBZIP_LIBDIR ]) - ]) - CPPFLAGS=$old_CPPFLAGS - - PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_error.c lib/zip_fclose.c \ - lib/zip_fread.c lib/zip_open.c lib/zip_source_filep.c \ - lib/zip_strerror.c lib/zip_close.c lib/zip_error_get.c \ - lib/zip_file_error_get.c lib/zip_free.c lib/zip_rename.c \ - lib/zip_source_free.c lib/zip_unchange_all.c lib/zip_delete.c \ - lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \ - lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \ - lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \ - lib/zip_filerange_crc.c lib/zip_file_strerror.c lib/zip_get_num_files.c \ - lib/zip_get_archive_flag.c lib/zip_set_archive_flag.c \ - lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \ - lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \ - lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \ - lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \ - lib/zip_get_archive_comment.c lib/zip_get_file_comment.c \ - lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \ - lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ - lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \ - lib/zip_error_clear.c lib/zip_file_error_clear.c \ - lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \ - lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \ - lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \ - lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \ - lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \ - lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \ - lib/zip_source_read.c lib/zip_source_stat.c" + + AC_DEFINE(HAVE_ZIP,1,[ ]) + PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c, $ext_shared,, $LIBZIP_CFLAGS) + PHP_SUBST(ZIP_SHARED_LIBADD) + else + + + PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_add_dir.c lib/zip_add_entry.c\ + lib/zip_close.c lib/zip_delete.c lib/zip_dir_add.c lib/zip_dirent.c lib/zip_discard.c lib/zip_entry.c\ + lib/zip_err_str.c lib/zip_error.c lib/zip_error_clear.c lib/zip_error_get.c lib/zip_error_get_sys_type.c\ + lib/zip_error_strerror.c lib/zip_error_to_str.c lib/zip_extra_field.c lib/zip_extra_field_api.c\ + lib/zip_fclose.c lib/zip_fdopen.c lib/zip_file_add.c lib/zip_file_error_clear.c lib/zip_file_error_get.c\ + lib/zip_file_get_comment.c lib/zip_file_get_offset.c lib/zip_file_rename.c lib/zip_file_replace.c\ + lib/zip_file_set_comment.c lib/zip_file_strerror.c lib/zip_filerange_crc.c lib/zip_fopen.c\ + lib/zip_fopen_encrypted.c lib/zip_fopen_index.c lib/zip_fopen_index_encrypted.c lib/zip_fread.c\ + lib/zip_get_archive_comment.c lib/zip_get_archive_flag.c lib/zip_get_compression_implementation.c\ + lib/zip_get_encryption_implementation.c lib/zip_get_file_comment.c lib/zip_get_name.c lib/zip_get_num_entries.c \ + lib/zip_get_num_files.c lib/zip_memdup.c lib/zip_name_locate.c lib/zip_new.c lib/zip_open.c lib/zip_rename.c lib/zip_replace.c\ + lib/zip_set_archive_comment.c lib/zip_set_archive_flag.c lib/zip_set_default_password.c lib/zip_set_file_comment.c\ + lib/zip_set_file_compression.c lib/zip_set_name.c lib/zip_source_buffer.c lib/zip_source_close.c lib/zip_source_crc.c\ + lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_file.c lib/zip_source_filep.c lib/zip_source_free.c\ + lib/zip_source_function.c lib/zip_source_layered.c lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c\ + lib/zip_source_read.c lib/zip_source_stat.c lib/zip_source_window.c lib/zip_source_zip.c lib/zip_source_zip_new.c\ + lib/zip_stat.c lib/zip_stat_index.c lib/zip_stat_init.c lib/zip_strerror.c lib/zip_string.c lib/zip_unchange.c lib/zip_unchange_all.c\ + lib/zip_unchange_archive.c lib/zip_unchange_data.c lib/zip_utf-8.c lib/mkstemp.c" AC_DEFINE(HAVE_ZIP,1,[ ]) PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) PHP_ADD_BUILD_DIR($ext_builddir/lib, 1) PHP_SUBST(ZIP_SHARED_LIBADD) +fi + + +AC_CHECK_TYPES([int8_t]) +AC_CHECK_TYPES([int16_t]) +AC_CHECK_TYPES([int32_t]) +AC_CHECK_TYPES([int64_t]) +AC_CHECK_TYPES([uint8_t]) +AC_CHECK_TYPES([uint16_t]) +AC_CHECK_TYPES([uint32_t]) +AC_CHECK_TYPES([uint64_t]) +AC_CHECK_TYPES([ssize_t]) + +AC_CHECK_SIZEOF([short]) +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long]) +AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([off_t]) +AC_CHECK_SIZEOF([size_t]) + +AC_PATH_PROG([TOUCH], [touch]) +AC_PATH_PROG([UNZIP], [unzip]) + +AC_STRUCT_TIMEZONE + +case $host_os +in + *bsd*) MANFMT=mdoc;; + *) MANFMT=man;; +esac +AC_SUBST([MANFMT]) + +AH_BOTTOM([ +#ifndef HAVE_SSIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT +typedef int ssize_t; +# elif SIZEOF_SIZE_T == SIZEOF_LONG +typedef long ssize_t; +# elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG +typedef long long ssize_t; +# else +#error no suitable type for ssize_t found +# endif +#endif +]) + dnl so we always include the known-good working hack. PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index fa0a5180df5ce..5b9f09575a769 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -9,36 +9,28 @@ if (PHP_ZIP != "no") { (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "zip", PHP_ZIP)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED))) ) { EXTENSION('zip', 'php_zip.c zip_stream.c'); - ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \ - zip_fread.c zip_open.c zip_source_filep.c \ - zip_strerror.c zip_close.c zip_error_get.c \ - zip_file_error_get.c zip_free.c zip_rename.c \ - zip_source_free.c zip_unchange_all.c zip_delete.c \ - zip_error_get_sys_type.c zip_file_get_offset.c \ - zip_get_name.c zip_replace.c zip_source_function.c \ - zip_unchange.c zip_dirent.c zip_error_strerror.c \ - zip_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \ - zip_get_archive_flag.c zip_set_archive_flag.c \ - zip_set_name.c zip_source_zip.c zip_unchange_data.c \ - zip_entry_free.c zip_error_to_str.c zip_fopen.c \ - zip_name_locate.c zip_source_buffer.c zip_stat.c \ - zip_entry_new.c zip_err_str.c zip_fopen_index.c \ - zip_new.c zip_source_file.c zip_stat_index.c \ - zip_get_archive_comment.c zip_get_file_comment.c \ - zip_set_archive_comment.c zip_set_file_comment.c \ - zip_unchange_archive.c zip_memdup.c zip_stat_init.c \ - zip_add_dir.c zip_file_error_clear.c zip_error_clear.c \ - zip_fdopen.c zip_fopen_encrypted.c zip_fopen_index_encrypted.c \ - zip_get_compression_implementation.c zip_get_encryption_implementation.c \ - zip_get_file_extra.c zip_get_num_entries.c zip_set_default_password.c \ - zip_set_file_extra.c zip_source_close.c zip_source_crc.c \ - zip_source_deflate.c zip_source_error.c zip_source_layered.c \ - zip_source_open.c zip_source_pkware.c zip_source_pop.c \ - zip_source_read.c zip_source_stat.c", "zip"); + ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_add_dir.c zip_add_entry.c\ + zip_close.c zip_delete.c zip_dir_add.c zip_dirent.c zip_discard.c zip_entry.c\ + zip_err_str.c zip_error.c zip_error_clear.c zip_error_get.c zip_error_get_sys_type.c\ + zip_error_strerror.c zip_error_to_str.c zip_extra_field.c zip_extra_field_api.c\ + zip_fclose.c zip_fdopen.c zip_file_add.c zip_file_error_clear.c zip_file_error_get.c\ + zip_file_get_comment.c zip_file_get_offset.c zip_file_rename.c zip_file_replace.c\ + zip_file_set_comment.c zip_file_strerror.c zip_filerange_crc.c zip_fopen.c\ + zip_fopen_encrypted.c zip_fopen_index.c zip_fopen_index_encrypted.c zip_fread.c\ + zip_get_archive_comment.c zip_get_archive_flag.c zip_get_compression_implementation.c\ + zip_get_encryption_implementation.c zip_get_file_comment.c zip_get_name.c zip_get_num_entries.c \ + zip_get_num_files.c zip_memdup.c zip_name_locate.c zip_new.c zip_open.c zip_rename.c zip_replace.c\ + zip_set_archive_comment.c zip_set_archive_flag.c zip_set_default_password.c zip_set_file_comment.c\ + zip_set_file_compression.c zip_set_name.c zip_source_buffer.c zip_source_close.c zip_source_crc.c\ + zip_source_deflate.c zip_source_error.c zip_source_file.c zip_source_filep.c zip_source_free.c\ + zip_source_function.c zip_source_layered.c zip_source_open.c zip_source_pkware.c zip_source_pop.c\ + zip_source_read.c zip_source_stat.c zip_source_window.c zip_source_zip.c zip_source_zip_new.c\ + zip_stat.c zip_stat_index.c zip_stat_init.c zip_strerror.c zip_string.c zip_unchange.c zip_unchange_all.c\ + zip_unchange_archive.c zip_unchange_data.c zip_utf-8.c mkstemp.c", "zip"); AC_DEFINE('HAVE_ZIP', 1); + ADD_FLAG("CFLAGS_ZIP", "/D _WIN32"); } else { WARNING("zip not enabled; libraries and headers not found"); } } - diff --git a/ext/zip/examples/addglob.php b/ext/zip/examples/addglob.php new file mode 100644 index 0000000000000..790312b4d586a --- /dev/null +++ b/ext/zip/examples/addglob.php @@ -0,0 +1,14 @@ +open('a.zip', ZIPARCHIVE::CREATE); + +/* or 'remove_all_path' => 0*/ +$options = array( + 'remove_path' => '/home/francis/myimages', + 'add_path' => 'images/', +); +$found = $z->addGlob("/home/pierre/cvs/gd/libgd/tests/*.png", 0, $options); +var_dump($found); +$z->close(); + diff --git a/ext/zip/examples/addpattern.php b/ext/zip/examples/addpattern.php new file mode 100644 index 0000000000000..a1a9b122914e5 --- /dev/null +++ b/ext/zip/examples/addpattern.php @@ -0,0 +1,13 @@ +open('a.zip', ZIPARCHIVE::CREATE); + +/* or 'remove_all_path' => 0*/ +$options = array('remove_path' => '/home/pierre/cvs/gd/libgd/tests', +'add_path' => 'images/', +); + +$found = $z->addPattern("/(\.png)$/i", "/home/pierre/cvs/gd/libgd/tests", $options); +var_dump($found); +$z->close(); + diff --git a/ext/zip/lib/mkstemp.c b/ext/zip/lib/mkstemp.c new file mode 100644 index 0000000000000..843d5e3613143 --- /dev/null +++ b/ext/zip/lib/mkstemp.c @@ -0,0 +1,151 @@ +/* Adapted from NetBSB libc by Dieter Baron */ + +/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#include +#include + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + + +int +_zip_mkstemp(char *path) +{ +#ifdef _WIN32 + int ret; + ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE); + if (ret == -1) { + return 0; + } else { + return ret; + } +#else + int fd; + char *start, *trv; + struct stat sbuf; + pid_t pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + static char xtra[2] = "aa"; + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0) + return (fd); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +#endif +} diff --git a/ext/zip/lib/php_zip_config.w32.h b/ext/zip/lib/php_zip_config.w32.h new file mode 100644 index 0000000000000..8956839c62c32 --- /dev/null +++ b/ext/zip/lib/php_zip_config.w32.h @@ -0,0 +1,57 @@ +#ifndef HAD_CONFIG_H +#define HAD_CONFIG_H +#define HAVE__CLOSE +#define HAVE__DUP +#define HAVE__FDOPEN +#define HAVE__FILENO +#define HAVE__OPEN +#define HAVE__SNPRINTF +/* #undef HAVE__STRCMPI */ +#define HAVE__STRDUP +#define HAVE__STRICMP +/* #undef HAVE_FSEEKO */ +/* #undef HAVE_FTELLO */ +/* #undef HAVE_MKSTEMP */ +#define HAVE_MOVEFILEEXA +/* #undef HAVE_SNPRINTF */ +/* #undef HAVE_STRCASECMP */ +/* #undef HAVE_STRINGS_H */ +/* #undef HAVE_STRUCT_TM_TM_ZONE */ +/* #undef HAVE_UNISTD_H */ +#define PACKAGE "libzip" +#define VERSION "0.10.b" + +/* #undef HAVE_SSIZE_T */ + +#ifndef HAVE_SSIZE_T + +#ifndef SIZE_T_LIBZIP +#define SIZE_T_LIBZIP 4 +#endif +#ifndef INT_LIBZIP +#define INT_LIBZIP 4 +#endif +#ifndef LONG_LIBZIP +#define LONG_LIBZIP 4 +#endif +#ifndef LONG_LONG_LIBZIP +#define LONG_LONG_LIBZIP 8 +#endif +#ifndef SIZEOF_OFF_T +#define SIZEOF_OFF_T 4 +#endif + +# if SIZE_T_LIBZIP == INT_LIBZIP +# ifndef ssize_t +typedef int ssize_t; +# endif +# elif SIZE_T_LIBZIP == LONG_LIBZIP +typedef long ssize_t; +# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP +typedef long long ssize_t; +# else +#error no suitable type for ssize_t found +# endif +#endif + +#endif /* HAD_CONFIG_H */ diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index f11c9aba7f99c..1fb1dbf5e0f5b 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -3,7 +3,7 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -38,18 +38,30 @@ #include "main/php.h" #ifdef PHP_WIN32 -# include "zip_win32.h" -# ifdef PHP_ZIP_EXPORTS -# define ZIP_EXTERN(rt) __declspec(dllexport)rt _stdcall -# else -# define ZIP_EXTERN(rt) rt -# endif +#ifdef PHP_ZIP_EXPORTS +# define ZIP_EXTERN __declspec(dllexport) _stdcall +# else +# define ZIP_EXTERN +# endif #elif defined(__GNUC__) && __GNUC__ >= 4 -# define ZIP_EXTERN(rt) __attribute__ ((visibility("default"))) rt +# define ZIP_EXTERN __attribute__ ((visibility("default"))) #else -# define ZIP_EXTERN(rt) rt +# define ZIP_EXTERN #endif + +#ifndef ZIP_EXTERN +#ifdef _WIN32 +#define ZIP_EXTERN __declspec(dllimport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ZIP_EXTERN __attribute__ ((visibility ("default"))) +#else +#define ZIP_EXTERN +#endif +#endif + + + BEGIN_EXTERN_C() #include "zipconf.h" @@ -63,27 +75,40 @@ BEGIN_EXTERN_C() #define ZIP_CREATE 1 #define ZIP_EXCL 2 #define ZIP_CHECKCONS 4 -#define ZIP_OVERWRITE 8 - +#define ZIP_TRUNCATE 8 /* flags for zip_name_locate, zip_fopen, zip_stat, ... */ -#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */ -#define ZIP_FL_NODIR 2 /* ignore directory component */ -#define ZIP_FL_COMPRESSED 4 /* read compressed data */ -#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ -#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */ -#define ZIP_FL_ENCRYPTED 32 /* read encrypted data - (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ +#define ZIP_FL_NODIR 2u /* ignore directory component */ +#define ZIP_FL_COMPRESSED 4u /* read compressed data */ +#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ +#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ +#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ +#define ZIP_FL_ENC_RAW 64u /* get unmodified string */ +#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ +#define ZIP_FL_LOCAL 256u /* in local header */ +#define ZIP_FL_CENTRAL 512u /* in central directory */ +/* 1024u reserved for internal use */ +#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ +#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ +#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ /* archive global flags flags */ -#define ZIP_AFL_TORRENT 1 /* torrent zipped */ -#define ZIP_AFL_RDONLY 2 /* read only -- cannot be cleared */ +#define ZIP_AFL_TORRENT 1u /* torrent zipped */ +#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ + +/* create a new extra field */ + +#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX +#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX /* flags for compression and encryption sources */ +#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ #define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ @@ -178,15 +203,15 @@ enum zip_source_cmd { #define ZIP_SOURCE_ERR_LOWER -2 -#define ZIP_STAT_NAME 0x0001 -#define ZIP_STAT_INDEX 0x0002 -#define ZIP_STAT_SIZE 0x0004 -#define ZIP_STAT_COMP_SIZE 0x0008 -#define ZIP_STAT_MTIME 0x0010 -#define ZIP_STAT_CRC 0x0020 -#define ZIP_STAT_COMP_METHOD 0x0040 -#define ZIP_STAT_ENCRYPTION_METHOD 0x0080 -#define ZIP_STAT_FLAGS 0x0100 +#define ZIP_STAT_NAME 0x0001u +#define ZIP_STAT_INDEX 0x0002u +#define ZIP_STAT_SIZE 0x0004u +#define ZIP_STAT_COMP_SIZE 0x0008u +#define ZIP_STAT_MTIME 0x0010u +#define ZIP_STAT_CRC 0x0020u +#define ZIP_STAT_COMP_METHOD 0x0040u +#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u +#define ZIP_STAT_FLAGS 0x0100u struct zip_stat { zip_uint64_t valid; /* which fields have valid values */ @@ -205,72 +230,78 @@ struct zip; struct zip_file; struct zip_source; +typedef zip_uint32_t zip_flags_t; + typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *); -ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *); -ZIP_EXTERN(int) zip_close(struct zip *); -ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t); -ZIP_EXTERN(void) zip_error_clear(struct zip *); -ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *); -ZIP_EXTERN(int) zip_error_get_sys_type(int); -ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int); -ZIP_EXTERN(int) zip_fclose(struct zip_file *); -ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *); -ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *); -ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *); -ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *); -ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int); -ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *, - int, const char *); -ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int); -ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *, - zip_uint64_t, int, - const char *); -ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t); -ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int); -ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int); -ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t, - int *, int); -ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t, - int *, int); -ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int); -ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int); -ZIP_EXTERN(int) zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */ -ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int); -ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *); -ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *); -ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *); -ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int); -ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int); -ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *); -ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t, - const char *, int); -ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t, - const char *, int); -ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *, - zip_uint64_t, int); -ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(void) zip_source_free(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *, - zip_source_callback, void *); -ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *, - zip_uint64_t, int, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *); -ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int, - struct zip_stat *); -ZIP_EXTERN(void) zip_stat_init(struct zip_stat *); -ZIP_EXTERN(const char *)zip_strerror(struct zip *); -ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t); -ZIP_EXTERN(int) zip_unchange_all(struct zip *); -ZIP_EXTERN(int) zip_unchange_archive(struct zip *); +#ifndef ZIP_DISABLE_DEPRECATED +ZIP_EXTERN zip_int64_t zip_add(struct zip *, const char *, struct zip_source *); /* use zip_file_add */ +ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *, const char *); /* use zip_dir_add */ +ZIP_EXTERN const char *zip_get_file_comment(struct zip *, zip_uint64_t, int *, int); /* use zip_file_get_comment */ +ZIP_EXTERN int zip_get_num_files(struct zip *); /* use zip_get_num_entries instead */ +ZIP_EXTERN int zip_rename(struct zip *, zip_uint64_t, const char *); /* use zip_file_rename */ +ZIP_EXTERN int zip_replace(struct zip *, zip_uint64_t, struct zip_source *); /* use zip_file_replace */ +ZIP_EXTERN int zip_set_file_comment(struct zip *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */ +#endif + +ZIP_EXTERN int zip_archive_set_tempdir(struct zip *, const char *); +ZIP_EXTERN zip_int64_t zip_file_add(struct zip *, const char *, struct zip_source *, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN int zip_close(struct zip *); +ZIP_EXTERN void zip_discard(struct zip *); +ZIP_EXTERN int zip_delete(struct zip *, zip_uint64_t); +ZIP_EXTERN int zip_file_extra_field_delete(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN void zip_error_clear(struct zip *); +ZIP_EXTERN void zip_error_get(struct zip *, int *, int *); +ZIP_EXTERN int zip_error_get_sys_type(int); +ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); +ZIP_EXTERN int zip_fclose(struct zip_file *); +ZIP_EXTERN struct zip *zip_fdopen(int, int, int *); +ZIP_EXTERN void zip_file_error_clear(struct zip_file *); +ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *); +ZIP_EXTERN const char *zip_file_strerror(struct zip_file *); +ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN struct zip_file *zip_fopen_encrypted(struct zip *, const char *, zip_flags_t, const char *); +ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN struct zip_file *zip_fopen_index_encrypted(struct zip *, zip_uint64_t, zip_flags_t, const char *); +ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t); +ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, zip_flags_t); +ZIP_EXTERN int zip_get_archive_flag(struct zip *, zip_flags_t, zip_flags_t); +ZIP_EXTERN const char *zip_file_get_comment(struct zip *, zip_uint64_t, zip_uint32_t *, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_get_num_entries(struct zip *, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_name_locate(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN struct zip *zip_open(const char *, int, int *); +ZIP_EXTERN int zip_file_rename(struct zip *, zip_uint64_t, const char *, zip_flags_t); +ZIP_EXTERN int zip_file_replace(struct zip *, zip_uint64_t, struct zip_source *, zip_flags_t); +ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, zip_uint16_t); +ZIP_EXTERN int zip_set_archive_flag(struct zip *, zip_flags_t, int); +ZIP_EXTERN int zip_set_default_password(struct zip *, const char *); +ZIP_EXTERN int zip_file_set_comment(struct zip *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_set_file_compression(struct zip *, zip_uint64_t, zip_int32_t, zip_uint32_t); +ZIP_EXTERN int zip_file_extra_field_set(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t); +ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *, zip_uint64_t, int); +ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *, zip_uint64_t, zip_int64_t); +ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *, zip_uint64_t, zip_int64_t); +ZIP_EXTERN void zip_source_free(struct zip_source *); +ZIP_EXTERN struct zip_source *zip_source_function(struct zip *, zip_source_callback, void *); +ZIP_EXTERN struct zip_source *zip_source_zip(struct zip *, struct zip *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); +ZIP_EXTERN int zip_stat(struct zip *, const char *, zip_flags_t, struct zip_stat *); +ZIP_EXTERN int zip_stat_index(struct zip *, zip_uint64_t, zip_flags_t, struct zip_stat *); +ZIP_EXTERN void zip_stat_init(struct zip_stat *); +ZIP_EXTERN const char *zip_strerror(struct zip *); +ZIP_EXTERN int zip_unchange(struct zip *, zip_uint64_t); +ZIP_EXTERN int zip_unchange_all(struct zip *); +ZIP_EXTERN int zip_unchange_archive(struct zip *); + END_EXTERN_C(); #endif /* _HAD_ZIP_H */ diff --git a/ext/zip/lib/zip_add.c b/ext/zip/lib/zip_add.c index 6067abbac491f..4bce3fd4af274 100644 --- a/ext/zip/lib/zip_add.c +++ b/ext/zip/lib/zip_add.c @@ -1,6 +1,6 @@ /* zip_add.c -- add file via callback function - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,6 +33,7 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" @@ -44,13 +45,8 @@ ZIP_UINT64_MAX, and each entry is larger than 2 bytes. */ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_add(struct zip *za, const char *name, struct zip_source *source) { - if (name == NULL || source == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_replace(za, ZIP_UINT64_MAX, name, source); + return zip_file_add(za, name, source, 0); } diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c index 0a9d7f4863011..22a28bd856253 100644 --- a/ext/zip/lib/zip_add_dir.c +++ b/ext/zip/lib/zip_add_dir.c @@ -1,6 +1,6 @@ /* zip_add_dir.c -- add directory - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,56 +33,15 @@ -#include -#include - +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" /* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *za, const char *name) { - int len; - zip_int64_t ret; - char *s; - struct zip_source *source; - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (name == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - s = NULL; - len = strlen(name); - - if (name[len-1] != '/') { - if ((s=(char *)malloc(len+2)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - strcpy(s, name); - s[len] = '/'; - s[len+1] = '\0'; - } - - if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { - free(s); - return -1; - } - - ret = _zip_replace(za, -1, s ? s : name, source); - - free(s); - if (ret < 0) - zip_source_free(source); - - return ret; + return zip_dir_add(za, name, 0); } diff --git a/ext/zip/lib/zip_add_entry.c b/ext/zip/lib/zip_add_entry.c new file mode 100644 index 0000000000000..3a7e2ccbe920f --- /dev/null +++ b/ext/zip/lib/zip_add_entry.c @@ -0,0 +1,66 @@ +/* + zip_add_entry.c -- create and init struct zip_entry + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include + +#include "zipint.h" + + + +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +zip_int64_t +_zip_add_entry(struct zip *za) +{ + zip_uint64_t idx; + + if (za->nentry+1 >= za->nentry_alloc) { + struct zip_entry *rentries; + zip_uint64_t nalloc = za->nentry_alloc + 16; + rentries = (struct zip_entry *)realloc(za->entry, sizeof(struct zip_entry) * nalloc); + if (!rentries) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + za->entry = rentries; + za->nentry_alloc = nalloc; + } + + idx = za->nentry++; + + _zip_entry_init(za->entry+idx); + + return (zip_int64_t)idx; +} diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index 576be3b3536fb..c9c7e58088644 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -38,6 +38,9 @@ #include #include #include +#ifdef HAVE_STRINGS_H +#include +#endif #include #ifdef HAVE_UNISTD_H #include @@ -49,110 +52,106 @@ #include #endif -static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, - FILE *); -static int copy_data(FILE *, off_t, FILE *, struct zip_error *); + + +/* max deflate size increase: size + ceil(size/16k)*5+6 */ +#define MAX_DEFLATE_SIZE_32 4293656963u + +static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, FILE *); +static int copy_data(FILE *, zip_uint64_t, FILE *, struct zip_error *); static int copy_source(struct zip *, struct zip_source *, FILE *); -static int write_cdir(struct zip *, struct zip_cdir *, FILE *); -static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *); +static int write_cdir(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *); static char *_zip_create_temp_output(struct zip *, FILE **); static int _zip_torrentzip_cmp(const void *, const void *); -struct filelist { - int idx; - const char *name; -}; - - - -ZIP_EXTERN(int) +ZIP_EXTERN int zip_close(struct zip *za) { - int survivors; - int i, j, error; + zip_uint64_t i, j, survivors; + int error; char *temp; FILE *out; #ifndef PHP_WIN32 mode_t mask; #endif - struct zip_cdir *cd; - struct zip_dirent de; - struct filelist *filelist; + struct zip_filelist *filelist; int reopen_on_error; int new_torrentzip; + int changed; reopen_on_error = 0; if (za == NULL) return -1; - if (!_zip_changed(za, &survivors)) { - _zip_free(za); - return 0; - } + changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { - if (za->zn && za->zp) { + if (za->zn && ((za->open_flags & ZIP_TRUNCATE) || (changed && za->zp))) { if (remove(za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); return -1; } } - _zip_free(za); + zip_discard(za); return 0; } - if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) - == NULL) - return -1; - - if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) { - free(filelist); - return -1; + if (!changed) { + zip_discard(za); + return 0; } - for (i=0; ientry[i]); + if (survivors > za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if ((filelist=(struct zip_filelist *)malloc(sizeof(filelist[0])*survivors)) == NULL) + return -1; /* archive comment is special for torrentzip */ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) { - cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX", - TORRENT_SIG_LEN + TORRENT_CRC_LEN, - &za->error); - if (cd->comment == NULL) { - _zip_cdir_free(cd); - free(filelist); - return -1; - } - cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN; - } - else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) { - if (_zip_cdir_set_comment(cd, za) == -1) { - _zip_cdir_free(cd); + /* XXX: use internal function when zip_set_archive_comment clears TORRENT flag */ + if (zip_set_archive_comment(za, TORRENT_SIG "XXXXXXXX", TORRENT_SIG_LEN + TORRENT_CRC_LEN) < 0) { free(filelist); return -1; } } - - if ((temp=_zip_create_temp_output(za, &out)) == NULL) { - _zip_cdir_free(cd); - free(filelist); - return -1; - } + /* XXX: if no longer torrentzip and archive comment not changed by user, delete it */ /* create list of files with index into original archive */ for (i=j=0; inentry; i++) { - if (za->entry[i].state == ZIP_ST_DELETED) + if (za->entry[i].deleted) continue; + if (j >= survivors) { + free(filelist); + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + filelist[j].idx = i; filelist[j].name = zip_get_name(za, i, 0); j++; } + if (j < survivors) { + free(filelist); + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + + if ((temp=_zip_create_temp_output(za, &out)) == NULL) { + free(filelist); + return -1; + } + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) qsort(filelist, survivors, sizeof(filelist[0]), _zip_torrentzip_cmp); @@ -162,106 +161,49 @@ zip_close(struct zip *za) ZIP_FL_UNCHANGED) == 0); error = 0; for (j=0; jentry+i; - _zip_dirent_init(&de); + new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || new_torrentzip || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD)); /* create new local directory entry */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { - - if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) - _zip_dirent_torrent_normalize(&de); - - /* use it as central directory entry */ - memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); - - /* set/update file name */ - if (za->entry[i].ch_filename == NULL) { - if (za->entry[i].state == ZIP_ST_ADDED) { - de.filename = strdup("-"); - de.filename_len = 1; - cd->entry[j].filename = "-"; - cd->entry[j].filename_len = 1; - } - else { - de.filename = strdup(za->cdir->entry[i].filename); - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->cdir->entry[i].filename; - cd->entry[j].filename_len = de.filename_len; - } + if (entry->changes == NULL) { + if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + error = 1; + break; } } - else { - /* copy existing directory entries */ - if ((NULL == za->zp) || (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0)) { - _zip_error_set(&za->error, ZIP_ER_SEEK, errno); - error = 1; - break; - } - if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, - &za->error) != 0) { - error = 1; - break; - } - memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); - if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - de.crc = za->cdir->entry[i].crc; - de.comp_size = za->cdir->entry[i].comp_size; - de.uncomp_size = za->cdir->entry[i].uncomp_size; - de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; - cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; - } - } + de = entry->changes; - if (za->entry[i].ch_filename) { - free(de.filename); - if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) { - error = 1; - break; - } - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->entry[i].ch_filename; - cd->entry[j].filename_len = de.filename_len; + if (_zip_read_local_ef(za, i) < 0) { + error = 1; + break; } - if (za->entry[i].ch_extra_len != -1) { - free(de.extrafield); - if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) { - error = 1; - break; - } - memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len); - de.extrafield_len = za->entry[i].ch_extra_len; - /* as the rest of cd entries, its malloc/free is done by za */ - /* TODO unsure if this should also be set in the CD -- - * not done for now - cd->entry[j].extrafield = za->entry[i].ch_extra; - cd->entry[j].extrafield_len = za->entry[i].ch_extra_len; - */ - } + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + _zip_dirent_torrent_normalize(entry->changes); - if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0 - && za->entry[i].ch_comment_len != -1) { - /* as the rest of cd entries, its malloc/free is done by za */ - cd->entry[j].comment = za->entry[i].ch_comment; - cd->entry[j].comment_len = za->entry[i].ch_comment_len; - } - cd->entry[j].offset = ftello(out); + de->offset = (zip_uint64_t)ftello(out); /* XXX: check for errors */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + if (new_data) { struct zip_source *zs; zs = NULL; - if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) - == NULL) { + if (!ZIP_ENTRY_DATA_CHANGED(entry)) { + if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { error = 1; break; } } - if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { + /* add_data writes dirent */ + if (add_data(za, zs ? zs : entry->source, de, out) < 0) { error = 1; if (zs) zip_source_free(zs); @@ -269,51 +211,49 @@ zip_close(struct zip *za) } if (zs) zip_source_free(zs); - - cd->entry[j].last_mod = de.last_mod; - cd->entry[j].comp_method = de.comp_method; - cd->entry[j].comp_size = de.comp_size; - cd->entry[j].uncomp_size = de.uncomp_size; - cd->entry[j].crc = de.crc; } else { - if (_zip_dirent_write(&de, out, 1, &za->error) < 0) { + zip_uint64_t offset; + + /* when copying data, all sizes are known -> no data descriptor needed */ + de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + if (_zip_dirent_write(de, out, ZIP_FL_LOCAL, &za->error) < 0) { error = 1; break; } - /* we just read the local dirent, file is at correct position */ - if (copy_data(za->zp, cd->entry[j].comp_size, out, - &za->error) < 0) { + if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) { + error = 1; + break; + } + if ((fseek(za->zp, (off_t)offset, SEEK_SET) < 0)) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + error = 1; + break; + } + if (copy_data(za->zp, de->comp_size, out, &za->error) < 0) { error = 1; break; } } - - _zip_dirent_finalize(&de); } - free(filelist); - if (!error) { - if (write_cdir(za, cd, out) < 0) + if (write_cdir(za, filelist, survivors, out) < 0) error = 1; } - /* pointers in cd entries are owned by za */ - cd->nentry = 0; - _zip_cdir_free(cd); + free(filelist); if (error) { - _zip_dirent_finalize(&de); fclose(out); - remove(temp); + (void)remove(temp); free(temp); return -1; } if (fclose(out) != 0) { _zip_error_set(&za->error, ZIP_ER_CLOSE, errno); - remove(temp); + (void)remove(temp); free(temp); return -1; } @@ -325,7 +265,7 @@ zip_close(struct zip *za) } if (_zip_rename(temp, za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_RENAME, errno); - remove(temp); + (void)remove(temp); free(temp); if (reopen_on_error) { /* ignore errors, since we're already in an error case */ @@ -339,56 +279,112 @@ zip_close(struct zip *za) chmod(za->zn, 0666&~mask); #endif - _zip_free(za); - free(temp); - + zip_discard(za); + free(temp); + return 0; } static int -add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, - FILE *ft) +add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, FILE *ft) { off_t offstart, offdata, offend; struct zip_stat st; struct zip_source *s2; - zip_compression_implementation comp_impl; int ret; + int is_zip64; + zip_flags_t flags; if (zip_source_stat(src, &st) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } + if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { + st.valid |= ZIP_STAT_COMP_METHOD; + st.comp_method = ZIP_CM_STORE; + } + + if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) + de->comp_method = st.comp_method; + else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { + st.valid |= ZIP_STAT_COMP_SIZE; + st.comp_size = st.size; + } + else { + /* we'll recompress */ + st.valid &= ~ZIP_STAT_COMP_SIZE; + } + + + flags = ZIP_EF_LOCAL; + + if ((st.valid & ZIP_STAT_SIZE) == 0) + flags |= ZIP_FL_FORCE_ZIP64; + else { + de->uncomp_size = st.size; + + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { + if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32) + || (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method)))) + flags |= ZIP_FL_FORCE_ZIP64; + } + else + de->comp_size = st.comp_size; + } + + offstart = ftello(ft); - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + /* as long as we don't support non-seekable output, clear data descriptor bit */ + de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + if ((is_zip64=_zip_dirent_write(de, ft, flags, &za->error)) < 0) return -1; - if ((s2=zip_source_crc(za, src, 0)) == NULL) { - zip_source_pop(s2); - return -1; - } - - /* XXX: deflate 0-byte files for torrentzip? */ - if (((st.valid & ZIP_STAT_COMP_METHOD) == 0 - || st.comp_method == ZIP_CM_STORE) - && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) { - comp_impl = NULL; - if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE)) - == NULL) { - _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - zip_source_pop(s2); - return -1; + + if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) { + struct zip_source *s_store, *s_crc; + zip_compression_implementation comp_impl; + + if (st.comp_method != ZIP_CM_STORE) { + if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return -1; + } + if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) { + /* error set by comp_impl */ + return -1; + } } - if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE)) - == NULL) { - /* XXX: set error? */ - zip_source_pop(s2); + else + s_store = src; + + if ((s_crc=zip_source_crc(za, s_store, 0)) == NULL) { + if (s_store != src) + zip_source_pop(s_store); return -1; } + + /* XXX: deflate 0-byte files for torrentzip? */ + if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) { + if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } + if ((s2=comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE)) == NULL) { + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } + } + else + s2 = s_crc; } else s2 = src; @@ -418,18 +414,33 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, return -1; } - de->last_mod = st.mtime; + if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (st.valid & ZIP_STAT_MTIME) + de->last_mod = st.mtime; + else + time(&de->last_mod); de->comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; - de->comp_size = offend - offdata; + de->comp_size = (zip_uint64_t)(offend - offdata); if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(de); - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + if ((ret=_zip_dirent_write(de, ft, flags, &za->error)) < 0) return -1; - + + if (is_zip64 != ret) { + /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; @@ -441,24 +452,26 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, static int -copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) +copy_data(FILE *fs, zip_uint64_t len, FILE *ft, struct zip_error *error) { char buf[BUFSIZE]; - int n, nn; + size_t n, nn; if (len == 0) return 0; while (len > 0) { nn = len > sizeof(buf) ? sizeof(buf) : len; - if ((n=fread(buf, 1, nn, fs)) < 0) { - _zip_error_set(error, ZIP_ER_READ, errno); - return -1; - } - else if (n == 0) { - _zip_error_set(error, ZIP_ER_EOF, 0); - return -1; - } + if ((n=fread(buf, 1, nn, fs)) == 0) { + if (ferror(fs)) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + else { + _zip_error_set(error, ZIP_ER_EOF, 0); + return -1; + } + } if (fwrite(buf, 1, n, ft) != (size_t)n) { _zip_error_set(error, ZIP_ER_WRITE, errno); @@ -487,7 +500,7 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft) ret = 0; while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) { - if (fwrite(buf, 1, n, ft) != (size_t)n) { + if (fwrite(buf, 1, (size_t)n, ft) != (size_t)n) { _zip_error_set(&za->error, ZIP_ER_WRITE, errno); ret = -1; break; @@ -508,29 +521,32 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft) static int -write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) +write_cdir(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *out) { - off_t offset; + off_t cd_start, end; + zip_int64_t size; uLong crc; char buf[TORRENT_CRC_LEN+1]; - if (_zip_cdir_write(cd, out, &za->error) < 0) + cd_start = ftello(out); + + if ((size=_zip_cdir_write(za, filelist, survivors, out)) < 0) return -1; + end = ftello(out); + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0) return 0; /* fix up torrentzip comment */ - offset = ftello(out); - - if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0) + if (_zip_filerange_crc(out, cd_start, size, &crc, &za->error) < 0) return -1; snprintf(buf, sizeof(buf), "%08lX", (long)crc); - if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) { + if (fseeko(out, end-TORRENT_CRC_LEN, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; } @@ -545,47 +561,22 @@ write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) -static int -_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) -{ - if (src->ch_comment_len != -1) { - dest->comment = _zip_memdup(src->ch_comment, - src->ch_comment_len, &src->error); - if (dest->comment == NULL) - return -1; - dest->comment_len = src->ch_comment_len; - } else { - if (src->cdir && src->cdir->comment) { - dest->comment = _zip_memdup(src->cdir->comment, - src->cdir->comment_len, &src->error); - if (dest->comment == NULL) - return -1; - dest->comment_len = src->cdir->comment_len; - } - } - - return 0; -} - - - int -_zip_changed(struct zip *za, int *survivorsp) +_zip_changed(const struct zip *za, zip_uint64_t *survivorsp) { - int changed, i, survivors; + int changed; + zip_uint64_t i, survivors; - changed = survivors = 0; + changed = 0; + survivors = 0; - if (za->ch_comment_len != -1 - || za->ch_flags != za->flags) + if (za->comment_changed || za->ch_flags != za->flags) changed = 1; for (i=0; inentry; i++) { - if ((za->entry[i].state != ZIP_ST_UNCHANGED) - || (za->entry[i].ch_extra_len != -1) - || (za->entry[i].ch_comment_len != -1)) + if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0)) changed = 1; - if (za->entry[i].state != ZIP_ST_DELETED) + if (!za->entry[i].deleted) survivors++; } @@ -603,14 +594,21 @@ _zip_create_temp_output(struct zip *za, FILE **outp) char *temp; int tfd; FILE *tfp; - int len = strlen(za->zn) + 8; - - if ((temp=(char *)malloc(len)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; + + if (za->tempdir) { + if ((temp=(char *)malloc(strlen(za->tempdir)+13)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + sprintf(temp, "%s/.zip.XXXXXX", za->tempdir); + } + else { + if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + sprintf(temp, "%s.XXXXXX", za->zn); } - - snprintf(temp, len, "%s.XXXXXX", za->zn); if ((tfd=mkstemp(temp)) == -1) { _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); @@ -621,7 +619,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp) if ((tfp=fdopen(tfd, "r+b")) == NULL) { _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); close(tfd); - remove(temp); + (void)remove(temp); free(temp); return NULL; } @@ -630,7 +628,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp) According to Pierre Joye, Windows in some environments per default creates text files, so force binary mode. */ - _setmode(_fileno(tfp), _O_BINARY ); + _setmode(_fileno(tfp), _O_BINARY ); #endif *outp = tfp; @@ -642,6 +640,13 @@ _zip_create_temp_output(struct zip *za, FILE **outp) static int _zip_torrentzip_cmp(const void *a, const void *b) { - return strcasecmp(((const struct filelist *)a)->name, - ((const struct filelist *)b)->name); + const char *aname = ((const struct zip_filelist *)a)->name; + const char *bname = ((const struct zip_filelist *)b)->name; + + if (aname == NULL) + return (bname != NULL) * -1; + else if (bname == NULL) + return 1; + + return strcasecmp(aname, bname); } diff --git a/ext/zip/lib/zip_delete.c b/ext/zip/lib/zip_delete.c index 131d444124c4b..cb769367cc6f6 100644 --- a/ext/zip/lib/zip_delete.c +++ b/ext/zip/lib/zip_delete.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_delete(struct zip *za, zip_uint64_t idx) { if (idx >= za->nentry) { @@ -55,7 +55,7 @@ zip_delete(struct zip *za, zip_uint64_t idx) if (_zip_unchange(za, idx, 1) != 0) return -1; - za->entry[idx].state = ZIP_ST_DELETED; + za->entry[idx].deleted = 1; return 0; } diff --git a/ext/zip/lib/zip_entry_new.c b/ext/zip/lib/zip_dir_add.c similarity index 61% rename from ext/zip/lib/zip_entry_new.c rename to ext/zip/lib/zip_dir_add.c index ad5d59975a927..0a74bd608764e 100644 --- a/ext/zip/lib/zip_entry_new.c +++ b/ext/zip/lib/zip_dir_add.c @@ -1,6 +1,6 @@ /* - zip_entry_new.c -- create and init struct zip_entry - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + zip_dir_add.c -- add directory + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -34,48 +34,55 @@ #include +#include #include "zipint.h" -struct zip_entry * -_zip_entry_new(struct zip *za) +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +ZIP_EXTERN zip_int64_t +zip_dir_add(struct zip *za, const char *name, zip_flags_t flags) { - struct zip_entry *ze; - if (!za) { - ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); - if (!ze) { - return NULL; - } + size_t len; + zip_int64_t ret; + char *s; + struct zip_source *source; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; } - else { - if (za->nentry+1 >= za->nentry_alloc) { - struct zip_entry *rentries; - za->nentry_alloc += 16; - rentries = (struct zip_entry *)realloc(za->entry, - sizeof(struct zip_entry) - * za->nentry_alloc); - if (!rentries) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - za->entry = rentries; - } - ze = za->entry+za->nentry; + + if (name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - ze->state = ZIP_ST_UNCHANGED; + s = NULL; + len = strlen(name); - ze->ch_filename = NULL; - ze->ch_extra = NULL; - ze->ch_extra_len = -1; - ze->ch_comment = NULL; - ze->ch_comment_len = -1; - ze->source = NULL; + if (name[len-1] != '/') { + if ((s=(char *)malloc(len+2)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + strcpy(s, name); + s[len] = '/'; + s[len+1] = '\0'; + } + + if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + free(s); + return -1; + } + + ret = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags); - if (za) - za->nentry++; + free(s); + if (ret < 0) + zip_source_free(source); - return ze; + return ret; } diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c index b9dac5c989e32..f4f2deb6fc5b9 100644 --- a/ext/zip/lib/zip_dirent.c +++ b/ext/zip/lib/zip_dirent.c @@ -1,6 +1,6 @@ /* zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,48 +42,54 @@ #include "zipint.h" -static time_t _zip_d2u_time(int, int); -static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *); -static char *_zip_readstr(unsigned char **, int, int, struct zip_error *); -static void _zip_write2(unsigned short, FILE *); -static void _zip_write4(unsigned int, FILE *); +static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); +static struct zip_string *_zip_read_string(const unsigned char **, FILE *, zip_uint16_t, int, struct zip_error *); +static struct zip_string *_zip_dirent_process_ef_utf_8(const struct zip_dirent *, zip_uint16_t, struct zip_string *); +static struct zip_extra_field *_zip_ef_utf8(zip_uint16_t, struct zip_string *, struct zip_error *); void _zip_cdir_free(struct zip_cdir *cd) { - int i; + zip_uint64_t i; if (!cd) return; for (i=0; inentry; i++) - _zip_dirent_finalize(cd->entry+i); - free(cd->comment); + _zip_entry_finalize(cd->entry+i); free(cd->entry); + _zip_string_free(cd->comment); free(cd); } int -_zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) +_zip_cdir_grow(struct zip_cdir *cd, zip_uint64_t nentry, struct zip_error *error) { - struct zip_dirent *entry; + struct zip_entry *entry; + zip_uint64_t i; - if (nentry < cd->nentry) { + if (nentry < cd->nentry_alloc) { _zip_error_set(error, ZIP_ER_INTERNAL, 0); return -1; } - if ((entry=((struct zip_dirent *) + if (nentry == cd->nentry_alloc) + return 0; + + if ((entry=((struct zip_entry *) realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return -1; } + + for (i=cd->nentry_alloc; inentry = nentry; + cd->nentry_alloc = nentry; cd->entry = entry; return 0; @@ -92,64 +98,132 @@ _zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) struct zip_cdir * -_zip_cdir_new(int nentry, struct zip_error *error) +_zip_cdir_new(zip_uint64_t nentry, struct zip_error *error) { struct zip_cdir *cd; + zip_uint64_t i; if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } - if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) - == NULL) { + if (nentry == 0) + cd->entry = NULL; + else if ((cd->entry=(struct zip_entry *)malloc(sizeof(*(cd->entry))*nentry)) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); free(cd); return NULL; } - /* entries must be initialized by caller */ + for (i=0; ientry+i); - cd->nentry = nentry; + cd->nentry = cd->nentry_alloc = nentry; cd->size = cd->offset = 0; cd->comment = NULL; - cd->comment_len = 0; return cd; } -int -_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) +zip_int64_t +_zip_cdir_write(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *fp) { - int i; + off_t off; + zip_uint64_t offset, size; + struct zip_string *comment; + zip_uint64_t i; + int is_zip64; + int ret; + + if ((off=ftello(fp)) < 0) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + offset = (zip_uint64_t)off; - cd->offset = ftello(fp); + is_zip64 = 0; - for (i=0; inentry; i++) { - if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) + for (i=0; ientry+filelist[i].idx; + + if ((ret=_zip_dirent_write(entry->changes ? entry->changes : entry->orig, fp, ZIP_FL_CENTRAL, &za->error)) < 0) return -1; + if (ret) + is_zip64 = 1; + } + + if ((off=ftello(fp)) < 0) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + size = (zip_uint64_t)off - offset; + + if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) + is_zip64 = 1; + + if (is_zip64) { + fwrite(EOCD64_MAGIC, 1, 4, fp); + _zip_write8(EOCD64LEN-12, fp); + _zip_write2(45, fp); + _zip_write2(45, fp); + _zip_write4(0, fp); + _zip_write4(0, fp); + _zip_write8(survivors, fp); + _zip_write8(survivors, fp); + _zip_write8(size, fp); + _zip_write8(offset, fp); + + fwrite(EOCD64LOC_MAGIC, 1, 4, fp); + _zip_write4(0, fp); + _zip_write8(offset+size, fp); + _zip_write4(1, fp); + } - cd->size = ftello(fp) - cd->offset; - /* clearerr(fp); */ fwrite(EOCD_MAGIC, 1, 4, fp); _zip_write4(0, fp); - _zip_write2((unsigned short)cd->nentry, fp); - _zip_write2((unsigned short)cd->nentry, fp); - _zip_write4(cd->size, fp); - _zip_write4(cd->offset, fp); - _zip_write2(cd->comment_len, fp); - fwrite(cd->comment, 1, cd->comment_len, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp); + _zip_write4(size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size, fp); + _zip_write4(offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset, fp); + + comment = za->comment_changed ? za->comment_changes : za->comment_orig; + + _zip_write2(comment ? comment->length : 0, fp); + if (comment) + fwrite(comment->raw, 1, comment->length, fp); if (ferror(fp)) { - _zip_error_set(error, ZIP_ER_WRITE, errno); + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); return -1; } - return 0; + return (zip_int64_t)size; +} + + + +struct zip_dirent * +_zip_dirent_clone(const struct zip_dirent *sde) +{ + struct zip_dirent *tde; + + if ((tde=(struct zip_dirent *)malloc(sizeof(*tde))) == NULL) + return NULL; + + if (sde) + memcpy(tde, sde, sizeof(*sde)); + else + _zip_dirent_init(tde); + + tde->changed = 0; + tde->cloned = 1; + + return tde; } @@ -157,18 +231,24 @@ _zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) void _zip_dirent_finalize(struct zip_dirent *zde) { - if (zde->filename_len > 0) { - free(zde->filename); - } - zde->filename = NULL; - if (zde->extrafield_len > 0) { - free(zde->extrafield); - } - zde->extrafield = NULL; - if (zde->comment_len > 0) { - free(zde->comment); - } - zde->comment = NULL; + if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) + _zip_string_free(zde->filename); + if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) + _zip_ef_free(zde->extra_fields); + if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) + _zip_string_free(zde->comment); +} + + + +void +_zip_dirent_free(struct zip_dirent *zde) +{ + if (zde == NULL) + return; + + _zip_dirent_finalize(zde); + free(zde); } @@ -176,20 +256,21 @@ _zip_dirent_finalize(struct zip_dirent *zde) void _zip_dirent_init(struct zip_dirent *de) { - de->version_madeby = 0; + de->changed = 0; + de->local_extra_fields_read = 0; + de->cloned = 0; + + de->version_madeby = 20; de->version_needed = 20; /* 2.0 */ de->bitflags = 0; - de->comp_method = 0; + de->comp_method = ZIP_CM_DEFAULT; de->last_mod = 0; de->crc = 0; de->comp_size = 0; de->uncomp_size = 0; de->filename = NULL; - de->filename_len = 0; - de->extrafield = NULL; - de->extrafield_len = 0; + de->extra_fields = NULL; de->comment = NULL; - de->comment_len = 0; de->disk_number = 0; de->int_attrib = 0; de->ext_attrib = 0; @@ -198,6 +279,32 @@ _zip_dirent_init(struct zip_dirent *de) +int +_zip_dirent_needs_zip64(const struct zip_dirent *de, zip_flags_t flags) +{ + if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX + || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) + return 1; + + return 0; +} + + + +struct zip_dirent * +_zip_dirent_new(void) +{ + struct zip_dirent *de; + + if ((de=(struct zip_dirent *)malloc(sizeof(*de))) == NULL) + return NULL; + + _zip_dirent_init(de); + return de; +} + + + /* _zip_dirent_read(zde, fp, bufp, left, localp, error): Fills the zip directory entry zde. @@ -218,13 +325,14 @@ _zip_dirent_init(struct zip_dirent *de) int _zip_dirent_read(struct zip_dirent *zde, FILE *fp, - unsigned char **bufp, zip_uint32_t *leftp, int local, + const unsigned char **bufp, zip_uint64_t *leftp, int local, struct zip_error *error) { unsigned char buf[CDENTRYSIZE]; - unsigned char *cur; - unsigned short dostime, dosdate; + const unsigned char *cur; + zip_uint16_t dostime, dosdate; zip_uint32_t size; + zip_uint16_t filename_len, comment_len, ef_len; if (local) size = LENTRYSIZE; @@ -255,9 +363,10 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, } cur += 4; - + /* convert buffercontents to zip_dirent */ - + + _zip_dirent_init(zde); if (!local) zde->version_madeby = _zip_read2(&cur); else @@ -275,17 +384,17 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, zde->comp_size = _zip_read4(&cur); zde->uncomp_size = _zip_read4(&cur); - zde->filename_len = _zip_read2(&cur); - zde->extrafield_len = _zip_read2(&cur); + filename_len = _zip_read2(&cur); + ef_len = _zip_read2(&cur); if (local) { - zde->comment_len = 0; + comment_len = 0; zde->disk_number = 0; zde->int_attrib = 0; zde->ext_attrib = 0; zde->offset = 0; } else { - zde->comment_len = _zip_read2(&cur); + comment_len = _zip_read2(&cur); zde->disk_number = _zip_read2(&cur); zde->int_attrib = _zip_read2(&cur); zde->ext_attrib = _zip_read4(&cur); @@ -293,56 +402,102 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, } zde->filename = NULL; - zde->extrafield = NULL; + zde->extra_fields = NULL; zde->comment = NULL; - size += zde->filename_len+zde->extrafield_len+zde->comment_len; + size += filename_len+ef_len+comment_len; if (leftp && (*leftp < size)) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; } - if (bufp) { - if (zde->filename_len) { - zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); - if (!zde->filename) - return -1; - } + if (filename_len) { + zde->filename = _zip_read_string(bufp ? &cur : NULL, fp, filename_len, 1, error); + if (!zde->filename) + return -1; - if (zde->extrafield_len) { - zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0, - error); - if (!zde->extrafield) + if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { + if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; + } } + } - if (zde->comment_len) { - zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error); - if (!zde->comment) - return -1; + if (ef_len) { + zip_uint8_t *ef = _zip_read_data(bufp ? &cur : NULL, fp, ef_len, 0, error); + + if (ef == NULL) + return -1; + if ((zde->extra_fields=_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error)) == NULL) { + free(ef); + return -1; } + free(ef); + if (local) + zde->local_extra_fields_read = 1; } - else { - if (zde->filename_len) { - zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error); - if (!zde->filename) - return -1; - } - if (zde->extrafield_len) { - zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0, - error); - if (!zde->extrafield) + if (comment_len) { + zde->comment = _zip_read_string(bufp ? &cur : NULL, fp, comment_len, 0, error); + if (!zde->comment) + return -1; + + if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { + if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; + } } + } - if (zde->comment_len) { - zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error); - if (!zde->comment) - return -1; + zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename); + zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment); + + /* Zip64 */ + + if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) { + zip_uint16_t got_len, needed_len; + const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error); + /* XXX: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */ + if (ef == NULL) + return -1; + + + if (local) + needed_len = 16; + else + needed_len = ((zde->uncomp_size == ZIP_UINT32_MAX) + (zde->comp_size == ZIP_UINT32_MAX) + (zde->offset == ZIP_UINT32_MAX)) * 8 + + (zde->disk_number == ZIP_UINT16_MAX) * 4; + + if (got_len != needed_len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return -1; } + + if (zde->uncomp_size == ZIP_UINT32_MAX) + zde->uncomp_size = _zip_read8(&ef); + else if (local) + ef += 8; + if (zde->comp_size == ZIP_UINT32_MAX) + zde->comp_size = _zip_read8(&ef); + if (!local) { + if (zde->offset == ZIP_UINT32_MAX) + zde->offset = _zip_read8(&ef); + if (zde->disk_number == ZIP_UINT16_MAX) + zde->disk_number = _zip_read4(&ef); + } + } + + if (!local) { + if (zde->offset > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return -1; + } } + + zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields); if (bufp) *bufp = cur; @@ -354,6 +509,65 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, +static struct zip_string * +_zip_dirent_process_ef_utf_8(const struct zip_dirent *de, zip_uint16_t id, struct zip_string *str) +{ + zip_uint16_t ef_len; + zip_uint32_t ef_crc; + + const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL); + + if (ef == NULL || ef_len < 5 || ef[0] != 1) + return str; + + ef++; + ef_crc = _zip_read4(&ef); + + if (_zip_string_crc32(str) == ef_crc) { + struct zip_string *ef_str = _zip_string_new(ef, ef_len-5, ZIP_ENCODING_UTF8_KNOWN, NULL); + + if (ef_str != NULL) { + _zip_string_free(str); + str = ef_str; + } + } + + return str; +} + + + +zip_int32_t +_zip_dirent_size(FILE *f, zip_uint16_t flags, struct zip_error *error) +{ + zip_int32_t size; + int local = (flags & ZIP_EF_LOCAL); + int i; + unsigned char b[6]; + const unsigned char *p; + + size = local ? LENTRYSIZE : CDENTRYSIZE; + + if (fseek(f, local ? 26 : 28, SEEK_CUR) < 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fread(b, (local ? 4 : 6), 1, f) != 1) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + + p = b; + for (i=0; i<(local ? 2 : 3); i++) { + size += _zip_read2(&p); + } + + return size; +} + + + /* _zip_dirent_torrent_normalize(de); Set values suitable for torrentzip. */ @@ -399,84 +613,157 @@ _zip_dirent_torrent_normalize(struct zip_dirent *de) de->disk_number = 0; de->int_attrib = 0; de->ext_attrib = 0; - de->offset = 0; - free(de->extrafield); - de->extrafield = NULL; - de->extrafield_len = 0; - free(de->comment); + _zip_ef_free(de->extra_fields); + de->extra_fields = NULL; + _zip_string_free(de->comment); de->comment = NULL; - de->comment_len = 0; } -/* _zip_dirent_write(zde, fp, localp, error): +/* _zip_dirent_write(zde, fp, flags, error): Writes zip directory entry zde to file fp. - If localp != 0, it writes a local header instead of a central - directory entry. + If flags & ZIP_EF_LOCAL, it writes a local header instead of a central + directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed. - Returns 0 if successful. On error, error is filled in and -1 is + Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is returned. */ int -_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, - struct zip_error *error) +_zip_dirent_write(struct zip_dirent *de, FILE *fp, zip_flags_t flags, struct zip_error *error) { unsigned short dostime, dosdate; + enum zip_encoding_type com_enc, name_enc; + struct zip_extra_field *ef; + zip_uint8_t ef_zip64[24], *ef_zip64_p; + int is_zip64; + int is_really_zip64; + + ef = NULL; - fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + is_zip64 = 0; - if (!localp) - _zip_write2(zde->version_madeby, fp); - _zip_write2(zde->version_needed, fp); - _zip_write2(zde->bitflags, fp); - _zip_write2(zde->comp_method, fp); + fwrite((flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); - _zip_u2d_time(zde->last_mod, &dostime, &dosdate); + name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN); + com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN); + + if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || + (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || + (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) + de->bitflags |= ZIP_GPBF_ENCODING_UTF_8; + else { + de->bitflags &= ~ZIP_GPBF_ENCODING_UTF_8; + if (name_enc == ZIP_ENCODING_UTF8_KNOWN) { + ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, error); + if (ef == NULL) + return -1; + } + if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){ + struct zip_extra_field *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, error); + if (ef2 == NULL) { + _zip_ef_free(ef); + return -1; + } + ef2->next = ef; + ef = ef2; + } + } + + ef_zip64_p = ef_zip64; + if (flags & ZIP_FL_LOCAL) { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) { + _zip_poke8(de->comp_size, &ef_zip64_p); + _zip_poke8(de->uncomp_size, &ef_zip64_p); + } + } + else { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) { + if (de->comp_size >= ZIP_UINT32_MAX) + _zip_poke8(de->comp_size, &ef_zip64_p); + if (de->uncomp_size >= ZIP_UINT32_MAX) + _zip_poke8(de->uncomp_size, &ef_zip64_p); + if (de->offset >= ZIP_UINT32_MAX) + _zip_poke8(de->offset, &ef_zip64_p); + } + } + + if (ef_zip64_p != ef_zip64) { + struct zip_extra_field *ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(ef_zip64_p-ef_zip64), ef_zip64, ZIP_EF_BOTH); + ef64->next = ef; + ef = ef64; + is_zip64 = 1; + } + + if ((flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) + is_really_zip64 = _zip_dirent_needs_zip64(de, flags); + else + is_really_zip64 = is_zip64; + + if ((flags & ZIP_FL_LOCAL) == 0) + _zip_write2(is_really_zip64 ? 45 : de->version_madeby, fp); + _zip_write2(is_really_zip64 ? 45 : de->version_needed, fp); + _zip_write2(de->bitflags&0xfff9, fp); /* clear compression method specific flags */ + _zip_write2((zip_uint16_t)de->comp_method, fp); /* XXX: can it be ZIP_CM_DEFAULT? */ + + _zip_u2d_time(de->last_mod, &dostime, &dosdate); _zip_write2(dostime, fp); _zip_write2(dosdate, fp); + + _zip_write4(de->crc, fp); + if (de->comp_size < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->comp_size, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); + if (de->uncomp_size < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->uncomp_size, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); + + _zip_write2(_zip_string_length(de->filename), fp); + _zip_write2(_zip_ef_size(de->extra_fields, flags) + _zip_ef_size(ef, ZIP_EF_BOTH), fp); - _zip_write4(zde->crc, fp); - _zip_write4(zde->comp_size, fp); - _zip_write4(zde->uncomp_size, fp); - - _zip_write2(zde->filename_len, fp); - _zip_write2(zde->extrafield_len, fp); - - if (!localp) { - _zip_write2(zde->comment_len, fp); - _zip_write2(zde->disk_number, fp); - _zip_write2(zde->int_attrib, fp); - _zip_write4(zde->ext_attrib, fp); - _zip_write4(zde->offset, fp); + if ((flags & ZIP_FL_LOCAL) == 0) { + _zip_write2(_zip_string_length(de->comment), fp); + _zip_write2((zip_uint16_t)de->disk_number, fp); + _zip_write2(de->int_attrib, fp); + _zip_write4(de->ext_attrib, fp); + if (de->offset < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->offset, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); } - if (zde->filename_len) - fwrite(zde->filename, 1, zde->filename_len, fp); + if (de->filename) + _zip_string_write(de->filename, fp); - if (zde->extrafield_len) - fwrite(zde->extrafield, 1, zde->extrafield_len, fp); + if (ef) + _zip_ef_write(ef, ZIP_EF_BOTH, fp); + if (de->extra_fields) + _zip_ef_write(de->extra_fields, flags, fp); - if (!localp) { - if (zde->comment_len) - fwrite(zde->comment, 1, zde->comment_len, fp); + if ((flags & ZIP_FL_LOCAL) == 0) { + if (de->comment) + _zip_string_write(de->comment, fp); } + _zip_ef_free(ef); + if (ferror(fp)) { _zip_error_set(error, ZIP_ER_WRITE, errno); return -1; } - return 0; + return is_zip64; } static time_t -_zip_d2u_time(int dtime, int ddate) +_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { struct tm tm; @@ -498,12 +785,72 @@ _zip_d2u_time(int dtime, int ddate) -unsigned short -_zip_read2(unsigned char **a) +static struct zip_extra_field * +_zip_ef_utf8(zip_uint16_t id, struct zip_string *str, struct zip_error *error) { - unsigned short ret; + const zip_uint8_t *raw; + zip_uint8_t *data, *p; + zip_uint32_t len; + struct zip_extra_field *ef; + + raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL); + + if (len+5 > ZIP_UINT16_MAX) { + /* XXX: error */ + } + + if ((data=(zip_uint8_t *)malloc(len+5)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + p = data; + *(p++) = 1; + _zip_poke4(_zip_string_crc32(str), &p); + memcpy(p, raw, len); + p += len; + + ef = _zip_ef_new(id, (zip_uint16_t)(p-data), data, ZIP_EF_BOTH); + free(data); + return ef; +} + + + +struct zip_dirent * +_zip_get_dirent(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error) +{ + if (error == NULL) + error = &za->error; + + if (idx >= za->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) { + if (za->entry[idx].orig == NULL) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) { + _zip_error_set(error, ZIP_ER_DELETED, 0); + return NULL; + } + return za->entry[idx].orig; + } + else + return za->entry[idx].changes; +} + + - ret = (*a)[0]+((*a)[1]<<8); +zip_uint16_t +_zip_read2(const zip_uint8_t **a) +{ + zip_uint16_t ret; + + ret = (zip_uint16_t)((*a)[0]+((*a)[1]<<8)); *a += 2; return ret; @@ -511,12 +858,12 @@ _zip_read2(unsigned char **a) -unsigned int -_zip_read4(unsigned char **a) +zip_uint32_t +_zip_read4(const zip_uint8_t **a) { - unsigned int ret; + zip_uint32_t ret; - ret = ((((((*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + ret = ((((((zip_uint32_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; *a += 4; return ret; @@ -524,65 +871,108 @@ _zip_read4(unsigned char **a) -static char * -_zip_readfpstr(FILE *fp, unsigned int len, int nulp, struct zip_error *error) +zip_uint64_t +_zip_read8(const zip_uint8_t **a) { - char *r, *o; + zip_uint64_t x, y; + + x = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + y = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + + return x+(y<<32); +} - r = (char *)malloc(nulp ? len+1 : len); + + +zip_uint8_t * +_zip_read_data(const zip_uint8_t **buf, FILE *fp, size_t len, int nulp, struct zip_error *error) +{ + zip_uint8_t *r; + + if (len == 0 && nulp == 0) + return NULL; + + r = (zip_uint8_t *)malloc(nulp ? len+1 : len); if (!r) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } - if (fread(r, 1, len, fp)>8)&0xff; + *((*p)++) = (i>>16)&0xff; + *((*p)++) = (i>>24)&0xff; +} + + + +void +_zip_poke8(zip_uint64_t i, zip_uint8_t **p) +{ + *((*p)++) = i&0xff; + *((*p)++) = (i>>8)&0xff; + *((*p)++) = (i>>16)&0xff; + *((*p)++) = (i>>24)&0xff; + *((*p)++) = (i>>32)&0xff; + *((*p)++) = (i>>40)&0xff; + *((*p)++) = (i>>48)&0xff; + *((*p)++) = (i>>56)&0xff; } -static void -_zip_write2(unsigned short i, FILE *fp) +void +_zip_write2(zip_uint16_t i, FILE *fp) { putc(i&0xff, fp); putc((i>>8)&0xff, fp); @@ -592,13 +982,30 @@ _zip_write2(unsigned short i, FILE *fp) -static void -_zip_write4(unsigned int i, FILE *fp) +void +_zip_write4(zip_uint32_t i, FILE *fp) +{ + putc(i&0xff, fp); + putc((i>>8)&0xff, fp); + putc((i>>16)&0xff, fp); + putc((i>>24)&0xff, fp); + + return; +} + + + +void +_zip_write8(zip_uint64_t i, FILE *fp) { putc(i&0xff, fp); putc((i>>8)&0xff, fp); putc((i>>16)&0xff, fp); putc((i>>24)&0xff, fp); + putc((i>>32)&0xff, fp); + putc((i>>40)&0xff, fp); + putc((i>>48)&0xff, fp); + putc((i>>56)&0xff, fp); return; } @@ -606,15 +1013,13 @@ _zip_write4(unsigned int i, FILE *fp) void -_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) +_zip_u2d_time(time_t time, zip_uint16_t *dtime, zip_uint16_t *ddate) { struct tm *tm; tm = localtime(&time); - *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) - + tm->tm_mday; - *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) - + ((tm->tm_sec)>>1); + *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday); + *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1)); return; } diff --git a/ext/zip/lib/zip_free.c b/ext/zip/lib/zip_discard.c similarity index 86% rename from ext/zip/lib/zip_free.c rename to ext/zip/lib/zip_discard.c index 9932c14fec9a2..37ba8c2ea64de 100644 --- a/ext/zip/lib/zip_free.c +++ b/ext/zip/lib/zip_discard.c @@ -1,6 +1,6 @@ /* - zip_free.c -- free struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_discard.c -- discard and free struct zip + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -39,14 +39,14 @@ -/* _zip_free: +/* zip_discard: frees the space allocated to a zipfile struct, and closes the corresponding file. */ void -_zip_free(struct zip *za) +zip_discard(struct zip *za) { - int i; + zip_uint64_t i; if (za == NULL) return; @@ -58,13 +58,12 @@ _zip_free(struct zip *za) fclose(za->zp); free(za->default_password); - _zip_cdir_free(za->cdir); - free(za->ch_comment); + _zip_string_free(za->comment_orig); + _zip_string_free(za->comment_changes); if (za->entry) { - for (i=0; inentry; i++) { - _zip_entry_free(za->entry+i); - } + for (i=0; inentry; i++) + _zip_entry_finalize(za->entry+i); free(za->entry); } diff --git a/ext/zip/lib/zip_entry_free.c b/ext/zip/lib/zip_entry.c similarity index 79% rename from ext/zip/lib/zip_entry_free.c rename to ext/zip/lib/zip_entry.c index e8a77707f0bfa..58663e8d0c88e 100644 --- a/ext/zip/lib/zip_entry_free.c +++ b/ext/zip/lib/zip_entry.c @@ -1,6 +1,6 @@ /* - zip_entry_free.c -- free struct zip_entry - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_entry.c -- struct zip_entry helper functions + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,23 +33,23 @@ -#include - #include "zipint.h" +void +_zip_entry_finalize(struct zip_entry *e) +{ + _zip_unchange_data(e); + _zip_dirent_free(e->orig); + _zip_dirent_free(e->changes); +} + void -_zip_entry_free(struct zip_entry *ze) +_zip_entry_init(struct zip_entry *e) { - free(ze->ch_filename); - ze->ch_filename = NULL; - free(ze->ch_extra); - ze->ch_extra = NULL; - ze->ch_extra_len = -1; - free(ze->ch_comment); - ze->ch_comment = NULL; - ze->ch_comment_len = -1; - - _zip_unchange_data(ze); + e->orig = NULL; + e->changes = NULL; + e->source = NULL; + e->deleted = 0; } diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c index b8d907abf4d9a..4b1f27921a256 100644 --- a/ext/zip/lib/zip_error.c +++ b/ext/zip/lib/zip_error.c @@ -1,6 +1,6 @@ /* zip_error.c -- struct zip_error helper functions - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,6 +42,9 @@ void _zip_error_clear(struct zip_error *err) { + if (err == NULL) + return; + err->zip_err = ZIP_ER_OK; err->sys_err = 0; } @@ -49,7 +52,7 @@ _zip_error_clear(struct zip_error *err) void -_zip_error_copy(struct zip_error *dst, struct zip_error *src) +_zip_error_copy(struct zip_error *dst, const struct zip_error *src) { dst->zip_err = src->zip_err; dst->sys_err = src->sys_err; @@ -67,7 +70,7 @@ _zip_error_fini(struct zip_error *err) void -_zip_error_get(struct zip_error *err, int *zep, int *sep) +_zip_error_get(const struct zip_error *err, int *zep, int *sep) { if (zep) *zep = err->zip_err; diff --git a/ext/zip/lib/zip_error_clear.c b/ext/zip/lib/zip_error_clear.c index 34e7dea48ebba..b4ff10391290a 100644 --- a/ext/zip/lib/zip_error_clear.c +++ b/ext/zip/lib/zip_error_clear.c @@ -37,8 +37,11 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_error_clear(struct zip *za) { + if (za == NULL) + return; + _zip_error_clear(&za->error); } diff --git a/ext/zip/lib/zip_error_get.c b/ext/zip/lib/zip_error_get.c index c15705e32fccd..6d1c958c17766 100644 --- a/ext/zip/lib/zip_error_get.c +++ b/ext/zip/lib/zip_error_get.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_error_get(struct zip *za, int *zep, int *sep) { _zip_error_get(&za->error, zep, sep); diff --git a/ext/zip/lib/zip_error_get_sys_type.c b/ext/zip/lib/zip_error_get_sys_type.c index 47aa93e69b927..6c6f38074040e 100644 --- a/ext/zip/lib/zip_error_get_sys_type.c +++ b/ext/zip/lib/zip_error_get_sys_type.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_error_get_sys_type(int ze) { if (ze < 0 || ze >= _zip_nerr_str) diff --git a/ext/zip/lib/zip_error_to_str.c b/ext/zip/lib/zip_error_to_str.c index bafe74335a049..11a0cd2bb0e6d 100644 --- a/ext/zip/lib/zip_error_to_str.c +++ b/ext/zip/lib/zip_error_to_str.c @@ -42,7 +42,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { const char *zs, *ss; diff --git a/ext/zip/lib/zip_extra_field.c b/ext/zip/lib/zip_extra_field.c new file mode 100644 index 0000000000000..41fd2b1d901af --- /dev/null +++ b/ext/zip/lib/zip_extra_field.c @@ -0,0 +1,386 @@ +/* + zip_extra_field.c -- manipulate extra fields + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + +#include +#include +#include + + + +struct zip_extra_field * +_zip_ef_clone(const struct zip_extra_field *ef, struct zip_error *error) +{ + struct zip_extra_field *head, *prev, *def; + + head = prev = NULL; + + while (ef) { + if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_ef_free(head); + return NULL; + } + + if (head == NULL) + head = def; + if (prev) + prev->next = def; + prev = def; + + ef = ef->next; + } + + return head; +} + + +struct zip_extra_field * +_zip_ef_delete_by_id(struct zip_extra_field *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) +{ + struct zip_extra_field *head, *prev; + int i; + + i = 0; + head = ef; + prev = NULL; + for (; ef; ef=(prev ? prev->next : head)) { + if ((ef->flags & flags & ZIP_EF_BOTH) && ef->id == id) { + if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) { + ef->flags &= ~(flags & ZIP_EF_BOTH); + if ((ef->flags & ZIP_EF_BOTH) == 0) { + if (prev) + prev->next = ef->next; + else + head = ef->next; + ef->next = NULL; + _zip_ef_free(ef); + + if (id_idx == ZIP_EXTRA_FIELD_ALL) + continue; + } + } + + i++; + if (i > id_idx) + break; + } + prev = ef; + } + + return head; +} + + + + +void +_zip_ef_free(struct zip_extra_field *ef) +{ + struct zip_extra_field *ef2; + + while (ef) { + ef2 = ef->next; + free(ef->data); + free(ef); + ef = ef2; + } +} + + + +const zip_uint8_t * +_zip_ef_get_by_id(const struct zip_extra_field *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, struct zip_error *error) +{ + static const zip_uint8_t empty[1] = { '\0' }; + + int i; + + i = 0; + for (; ef; ef=ef->next) { + if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) { + if (i < id_idx) { + i++; + continue; + } + + if (lenp) + *lenp = ef->size; + if (ef->size > 0) + return ef->data; + else + return empty; + } + } + + _zip_error_set(error, ZIP_ER_NOENT, 0); + return NULL; +} + + + +struct zip_extra_field * +_zip_ef_merge(struct zip_extra_field *to, struct zip_extra_field *from) +{ + struct zip_extra_field *ef2, *tt, *tail; + int duplicate; + + if (to == NULL) + return from; + + for (tail=to; tail->next; tail=tail->next) + ; + + for (; from; from=ef2) { + ef2 = from->next; + + duplicate = 0; + for (tt=to; tt; tt=tt->next) { + if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) { + tt->flags |= (from->flags & ZIP_EF_BOTH); + duplicate = 1; + break; + } + } + + from->next = NULL; + if (duplicate) + _zip_ef_free(from); + else + tail = tail->next = from; + } + + return to; +} + + + +struct zip_extra_field * +_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) +{ + struct zip_extra_field *ef; + + if ((ef=(struct zip_extra_field *)malloc(sizeof(*ef))) == NULL) + return NULL; + + ef->next = NULL; + ef->flags = flags; + ef->id = id; + ef->size = size; + if (size > 0) { + if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) { + free(ef); + return NULL; + } + } + else + ef->data = NULL; + + return ef; +} + + + +struct zip_extra_field * +_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, struct zip_error *error) +{ + struct zip_extra_field *ef, *ef2, *ef_head; + const zip_uint8_t *p; + zip_uint16_t fid, flen; + + ef_head = NULL; + for (p=data; p data+len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_ef_free(ef_head); + return NULL; + } + + fid = _zip_read2(&p); + flen = _zip_read2(&p); + + if (p+flen > data+len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_ef_free(ef_head); + return NULL; + } + + if ((ef2=_zip_ef_new(fid, flen, p, flags)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_ef_free(ef_head); + return NULL; + } + + if (ef_head) { + ef->next = ef2; + ef = ef2; + } + else + ef_head = ef = ef2; + } + + return ef_head; +} + + + +struct zip_extra_field * +_zip_ef_remove_internal(struct zip_extra_field *ef) +{ + struct zip_extra_field *ef_head; + struct zip_extra_field *prev, *next; + + ef_head = ef; + prev = NULL; + + while (ef) { + if (ZIP_EF_IS_INTERNAL(ef->id)) { + next = ef->next; + if (ef_head == ef) + ef_head = next; + ef->next = NULL; + _zip_ef_free(ef); + if (prev) + prev->next = next; + ef = next; + } + else { + prev = ef; + ef = ef->next; + } + } + + return ef_head; +} + + +zip_uint16_t +_zip_ef_size(const struct zip_extra_field *ef, zip_flags_t flags) +{ + zip_uint16_t size; + + size = 0; + for (; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) + size += 4+ef->size; + } + + return size; +} + + + +void +_zip_ef_write(const struct zip_extra_field *ef, zip_flags_t flags, FILE *f) +{ + for (; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) { + _zip_write2(ef->id, f); + _zip_write2(ef->size, f); + if (ef->size > 0) + fwrite(ef->data, ef->size, 1, f); + } + } +} + + + +int +_zip_read_local_ef(struct zip *za, zip_uint64_t idx) +{ + struct zip_entry *e; + unsigned char b[4]; + const unsigned char *p; + zip_uint16_t fname_len, ef_len; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + e = za->entry+idx; + + if (e->orig == NULL || e->orig->local_extra_fields_read) + return 0; + + + if (fseeko(za->zp, (off_t)(e->orig->offset + 26), SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fread(b, sizeof(b), 1, za->zp) != 1) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + + p = b; + fname_len = _zip_read2(&p); + ef_len = _zip_read2(&p); + + if (ef_len > 0) { + struct zip_extra_field *ef; + zip_uint8_t *ef_raw; + + if (fseek(za->zp, fname_len, SEEK_CUR) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + ef_raw = _zip_read_data(NULL, za->zp, ef_len, 0, &za->error); + + if (ef_raw == NULL) + return -1; + + if ((ef=_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &za->error)) == NULL) { + free(ef_raw); + return -1; + } + free(ef_raw); + + ef = _zip_ef_remove_internal(ef); + e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef); + } + + e->orig->local_extra_fields_read = 1; + + if (e->changes && e->changes->local_extra_fields_read == 0) { + e->changes->extra_fields = e->orig->extra_fields; + e->changes->local_extra_fields_read = 1; + } + + return 0; +} diff --git a/ext/zip/lib/zip_extra_field_api.c b/ext/zip/lib/zip_extra_field_api.c new file mode 100644 index 0000000000000..02ed4555e0c0d --- /dev/null +++ b/ext/zip/lib/zip_extra_field_api.c @@ -0,0 +1,364 @@ +/* + zip_extra_field_api.c -- public extra fields API functions + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_extra_field_delete(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags); + return 0; +} + + + +ZIP_EXTERN int +zip_file_extra_field_delete_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags); + return 0; +} + + + +ZIP_EXTERN const zip_uint8_t * +zip_file_extra_field_get(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) +{ + static const zip_uint8_t empty[1] = { '\0' }; + + struct zip_dirent *de; + struct zip_extra_field *ef; + int i; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return NULL; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return NULL; + + i = 0; + for (ef=de->extra_fields; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) { + if (i < ef_idx) { + i++; + continue; + } + + if (idp) + *idp = ef->id; + if (lenp) + *lenp = ef->size; + if (ef->size > 0) + return ef->data; + else + return empty; + } + } + + _zip_error_set(&za->error, ZIP_ER_NOENT, 0); + return NULL; + +} + + + +ZIP_EXTERN const zip_uint8_t * +zip_file_extra_field_get_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return NULL; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return NULL; + + return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error); +} + + + +ZIP_EXTERN zip_int16_t +zip_file_extra_fields_count(struct zip *za, zip_uint64_t idx, zip_flags_t flags) +{ + struct zip_dirent *de; + struct zip_extra_field *ef; + zip_uint16_t n; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return -1; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return -1; + + n = 0; + for (ef=de->extra_fields; ef; ef=ef->next) + if (ef->flags & flags & ZIP_EF_BOTH) + n++; + + return (zip_int16_t)n; +} + + + +ZIP_EXTERN zip_int16_t +zip_file_extra_fields_count_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) +{ + struct zip_dirent *de; + struct zip_extra_field *ef; + zip_uint16_t n; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return -1; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return -1; + + n = 0; + for (ef=de->extra_fields; ef; ef=ef->next) + if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) + n++; + + return (zip_int16_t)n; +} + + + +ZIP_EXTERN int +zip_file_extra_field_set(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) +{ + struct zip_dirent *de; + zip_uint16_t ls, cs; + struct zip_extra_field *ef, *ef_prev, *ef_new; + int i, found, new_len; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (ZIP_EF_IS_INTERNAL(ef_id)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + ef = de->extra_fields; + ef_prev = NULL; + i = 0; + found = 0; + + for (; ef; ef=ef->next) { + if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) { + if (i == ef_idx) { + found = 1; + break; + } + i++; + } + ef_prev = ef; + } + + if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (flags & ZIP_EF_LOCAL) + ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL); + else + ls = 0; + if (flags & ZIP_EF_CENTRAL) + cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL); + else + cs = 0; + + new_len = ls > cs ? ls : cs; + if (found) + new_len -= ef->size + 4; + new_len += len + 4; + + if (new_len > ZIP_UINT16_MAX) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + + if (found) { + if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) { + ef_new->next = ef->next; + ef->next = NULL; + _zip_ef_free(ef); + if (ef_prev) + ef_prev->next = ef_new; + else + de->extra_fields = ef_new; + } + else { + ef->flags &= ~(flags & ZIP_EF_BOTH); + ef_new->next = ef->next; + ef->next = ef_new; + } + } + else if (ef_prev) { + ef_new->next = ef_prev->next; + ef_prev->next = ef_new; + } + else + de->extra_fields = ef_new; + + return 0; +} + + + +int +_zip_file_extra_field_prepare_for_change(struct zip *za, zip_uint64_t idx) +{ + struct zip_entry *e; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + e = za->entry+idx; + + if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD)) + return 0; + + if (e->orig) { + if (_zip_read_local_ef(za, idx) < 0) + return -1; + } + + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + if (e->orig && e->orig->extra_fields) { + if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL) + return -1; + } + e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD; + + return 0; +} + diff --git a/ext/zip/lib/zip_fclose.c b/ext/zip/lib/zip_fclose.c index eb55ddbcea455..093c30eada9f1 100644 --- a/ext/zip/lib/zip_fclose.c +++ b/ext/zip/lib/zip_fclose.c @@ -39,20 +39,23 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_fclose(struct zip_file *zf) { - int i, ret; + int ret; + unsigned int i; if (zf->src) zip_source_free(zf->src); - for (i=0; iza->nfile; i++) { - if (zf->za->file[i] == zf) { - zf->za->file[i] = zf->za->file[zf->za->nfile-1]; - zf->za->nfile--; - break; - } + if (zf->za) { + for (i=0; iza->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; + } + } } ret = 0; diff --git a/ext/zip/lib/zip_fdopen.c b/ext/zip/lib/zip_fdopen.c index df70f27561ace..bda9aabac4915 100644 --- a/ext/zip/lib/zip_fdopen.c +++ b/ext/zip/lib/zip_fdopen.c @@ -37,11 +37,24 @@ -ZIP_EXTERN(struct zip *) -zip_fdopen(int fd_orig, int flags, int *zep) +ZIP_EXTERN struct zip * +zip_fdopen(int fd_orig, int _flags, int *zep) { int fd; FILE *fp; + unsigned int flags; + + if (_flags < 0) { + if (zep) + *zep = ZIP_ER_INVAL; + return NULL; + } + flags = (unsigned int)_flags; + + if (flags & ZIP_TRUNCATE) { + *zep = ZIP_ER_INVAL; + return NULL; + } /* We dup() here to avoid messing with the passed in fd. We could not restore it to the original state in case of error. */ @@ -58,5 +71,5 @@ zip_fdopen(int fd_orig, int flags, int *zep) } close(fd_orig); - return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep); + return _zip_open(NULL, fp, flags, zep); } diff --git a/ext/zip/lib/zip_file_add.c b/ext/zip/lib/zip_file_add.c new file mode 100644 index 0000000000000..995cb91c1a287 --- /dev/null +++ b/ext/zip/lib/zip_file_add.c @@ -0,0 +1,55 @@ +/* + zip_file_add.c -- add file via callback function + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + + +/* + NOTE: Return type is signed so we can return -1 on error. + The index can not be larger than ZIP_INT64_MAX since the size + of the central directory cannot be larger than + ZIP_UINT64_MAX, and each entry is larger than 2 bytes. +*/ + +ZIP_EXTERN zip_int64_t +zip_file_add(struct zip *za, const char *name, struct zip_source *source, zip_flags_t flags) +{ + if (name == NULL || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags); +} diff --git a/ext/zip/lib/zip_file_error_clear.c b/ext/zip/lib/zip_file_error_clear.c index 6c9c2a02b3f0f..ce8b6cbd9403a 100644 --- a/ext/zip/lib/zip_file_error_clear.c +++ b/ext/zip/lib/zip_file_error_clear.c @@ -37,8 +37,11 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_file_error_clear(struct zip_file *zf) { + if (zf == NULL) + return; + _zip_error_clear(&zf->error); } diff --git a/ext/zip/lib/zip_file_error_get.c b/ext/zip/lib/zip_file_error_get.c index a53fa7e003324..f20e011fc747e 100644 --- a/ext/zip/lib/zip_file_error_get.c +++ b/ext/zip/lib/zip_file_error_get.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_file_error_get(struct zip_file *zf, int *zep, int *sep) { _zip_error_get(&zf->error, zep, sep); diff --git a/ext/zip/lib/zip_get_file_extra.c b/ext/zip/lib/zip_file_get_comment.c similarity index 72% rename from ext/zip/lib/zip_get_file_extra.c rename to ext/zip/lib/zip_file_get_comment.c index a27edd8ee9452..766731ea268ef 100644 --- a/ext/zip/lib/zip_get_file_extra.c +++ b/ext/zip/lib/zip_file_get_comment.c @@ -1,6 +1,6 @@ /* - zip_get_file_extra.c -- get file extra field - Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner + zip_file_get_comment.c -- get file comment + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -17,7 +17,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,28 +31,28 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #include "zipint.h" + +/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */ - -ZIP_EXTERN(const char *) -zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags) +ZIP_EXTERN const char * +zip_file_get_comment(struct zip *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) { - if (idx >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + struct zip_dirent *de; + zip_uint32_t len; + const zip_uint8_t *str; + + if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_extra_len == -1)) { - if (lenp != NULL) - *lenp = za->cdir->entry[idx].extrafield_len; - return za->cdir->entry[idx].extrafield; - } - - if (lenp != NULL) - *lenp = za->entry[idx].ch_extra_len; - return za->entry[idx].ch_extra; + + if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL) + return NULL; + + if (lenp) + *lenp = len; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_file_get_offset.c b/ext/zip/lib/zip_file_get_offset.c index b96fd5e480907..65a011fc077c3 100644 --- a/ext/zip/lib/zip_file_get_offset.c +++ b/ext/zip/lib/zip_file_get_offset.c @@ -50,25 +50,27 @@ On error, fills in za->error and returns 0. */ -unsigned int -_zip_file_get_offset(struct zip *za, int idx) +zip_uint64_t +_zip_file_get_offset(const struct zip *za, zip_uint64_t idx, struct zip_error *error) { - struct zip_dirent de; - unsigned int offset; + zip_uint64_t offset; + zip_int32_t size; - offset = za->cdir->entry[idx].offset; + offset = za->entry[idx].orig->offset; - if (fseeko(za->zp, offset, SEEK_SET) != 0) { - _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + if (fseeko(za->zp, (off_t)offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); return 0; } - if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0) + /* XXX: cache? */ + if ((size=_zip_dirent_size(za->zp, ZIP_EF_LOCAL, error)) < 0) return 0; - offset += LENTRYSIZE + de.filename_len + de.extrafield_len; - - _zip_dirent_finalize(&de); - - return offset; + if (offset+(zip_uint32_t)size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; + } + + return offset + (zip_uint32_t)size; } diff --git a/ext/zip/lib/zip_set_file_extra.c b/ext/zip/lib/zip_file_rename.c similarity index 70% rename from ext/zip/lib/zip_set_file_extra.c rename to ext/zip/lib/zip_file_rename.c index db829e2e0a842..383a52adae714 100644 --- a/ext/zip/lib/zip_set_file_extra.c +++ b/ext/zip/lib/zip_file_rename.c @@ -1,6 +1,6 @@ /* - zip_set_file_extra.c -- set extra field for file in archive - Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner + zip_file_rename.c -- rename file in zip archive + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -17,7 +17,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,23 +31,21 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + - -#include +#include #include "zipint.h" + - -ZIP_EXTERN(int) -zip_set_file_extra(struct zip *za, zip_uint64_t idx, - const char *extra, int len) +ZIP_EXTERN int +zip_file_rename(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - char *tmpext; - - if (idx >= za->nentry - || len < 0 || len > MAXEXTLEN - || (len > 0 && extra == NULL)) { + const char *old_name; + int old_is_dir, new_is_dir; + + if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } @@ -57,16 +55,16 @@ zip_set_file_extra(struct zip *za, zip_uint64_t idx, return -1; } - if (len > 0) { - if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL) - return -1; - } - else - tmpext = NULL; + if ((old_name=zip_get_name(za, idx, 0)) == NULL) + return -1; + + new_is_dir = (name != NULL && name[strlen(name)-1] == '/'); + old_is_dir = (old_name[strlen(old_name)-1] == '/'); - free(za->entry[idx].ch_extra); - za->entry[idx].ch_extra = tmpext; - za->entry[idx].ch_extra_len = len; + if (new_is_dir != old_is_dir) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } - return 0; + return _zip_set_name(za, idx, name, flags); } diff --git a/ext/zip/lib/zip_file_replace.c b/ext/zip/lib/zip_file_replace.c new file mode 100644 index 0000000000000..7e7e942168478 --- /dev/null +++ b/ext/zip/lib/zip_file_replace.c @@ -0,0 +1,111 @@ +/* + zip_file_replace.c -- replace file via callback function + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source, zip_flags_t flags) +{ + if (idx >= za->nentry || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_file_replace(za, idx, NULL, source, flags) == -1) + return -1; + + return 0; +} + + + + +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +zip_int64_t +_zip_file_replace(struct zip *za, zip_uint64_t idx, const char *name, struct zip_source *source, zip_flags_t flags) +{ + zip_uint64_t za_nentry_prev; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + za_nentry_prev = za->nentry; + if (idx == ZIP_UINT64_MAX) { + zip_int64_t i = -1; + + if (flags & ZIP_FL_OVERWRITE) + i = _zip_name_locate(za, name, flags, NULL); + + if (i == -1) { + /* create and use new entry, used by zip_add */ + if ((i=_zip_add_entry(za)) < 0) + return -1; + } + idx = (zip_uint64_t)i; + } + + if (name && _zip_set_name(za, idx, name, flags) != 0) { + if (za->nentry != za_nentry_prev) { + _zip_entry_finalize(za->entry+idx); + za->nentry = za_nentry_prev; + } + return -1; + } + + /* does not change any name related data, so we can do it here; + * needed for a double add of the same file name */ + _zip_unchange_data(za->entry+idx); + + if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) { + if (za->entry[idx].changes == NULL) { + if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT; + za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD; + } + + za->entry[idx].source = source; + + return (zip_int64_t)idx; +} diff --git a/ext/zip/lib/zip_file_set_comment.c b/ext/zip/lib/zip_file_set_comment.c new file mode 100644 index 0000000000000..722f3d43cc3d3 --- /dev/null +++ b/ext/zip/lib/zip_file_set_comment.c @@ -0,0 +1,105 @@ +/* + zip_file_set_comment.c -- set comment for file in archive + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_set_comment(struct zip *za, zip_uint64_t idx, + const char *comment, zip_uint16_t len, zip_flags_t flags) +{ + struct zip_entry *e; + struct zip_string *cstr; + int changed; + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (len > 0 && comment == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL) + return -1; + if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) + cstr->encoding = ZIP_ENCODING_UTF8_KNOWN; + } + else + cstr = NULL; + + e = za->entry+idx; + + if (e->changes) { + _zip_string_free(e->changes->comment); + e->changes->comment = NULL; + e->changes->changed &= ~ZIP_DIRENT_COMMENT; + } + + if (e->orig && e->orig->comment) + changed = !_zip_string_equal(e->orig->comment, cstr); + else + changed = (cstr != NULL); + + if (changed) { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + _zip_string_free(cstr); + return -1; + } + } + e->changes->comment = cstr; + e->changes->changed |= ZIP_DIRENT_COMMENT; + } + else { + _zip_string_free(cstr); + if (e->changes && e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } + + return 0; +} diff --git a/ext/zip/lib/zip_file_strerror.c b/ext/zip/lib/zip_file_strerror.c index c2864f2ba1aaf..9ba70f14ff52b 100644 --- a/ext/zip/lib/zip_file_strerror.c +++ b/ext/zip/lib/zip_file_strerror.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(const char *) +ZIP_EXTERN const char * zip_file_strerror(struct zip_file *zf) { return _zip_error_strerror(&zf->error); diff --git a/ext/zip/lib/zip_filerange_crc.c b/ext/zip/lib/zip_filerange_crc.c index 4d1ad566929f8..3b1c868407ef9 100644 --- a/ext/zip/lib/zip_filerange_crc.c +++ b/ext/zip/lib/zip_filerange_crc.c @@ -1,6 +1,6 @@ /* zip_filerange_crc.c -- compute CRC32 for a range of a file - Copyright (C) 2008 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -56,13 +56,13 @@ _zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp, } while (len > 0) { - n = len > BUFSIZE ? BUFSIZE : len; - if ((n=fread(buf, 1, n, fp)) <= 0) { + n = len > BUFSIZE ? BUFSIZE : (size_t)len; + if ((n=fread(buf, 1, n, fp)) == 0) { _zip_error_set(errp, ZIP_ER_READ, errno); return -1; } - *crcp = crc32(*crcp, buf, n); + *crcp = crc32(*crcp, buf, (uInt)n); len-= n; } diff --git a/ext/zip/lib/zip_fopen.c b/ext/zip/lib/zip_fopen.c index f62adbbf92692..331f79ea36149 100644 --- a/ext/zip/lib/zip_fopen.c +++ b/ext/zip/lib/zip_fopen.c @@ -37,13 +37,13 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen(struct zip *za, const char *fname, int flags) +ZIP_EXTERN struct zip_file * +zip_fopen(struct zip *za, const char *fname, zip_flags_t flags) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return NULL; - return zip_fopen_index_encrypted(za, idx, flags, za->default_password); + return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_encrypted.c b/ext/zip/lib/zip_fopen_encrypted.c index 8aba0625672bc..34230f00d7c0a 100644 --- a/ext/zip/lib/zip_fopen_encrypted.c +++ b/ext/zip/lib/zip_fopen_encrypted.c @@ -37,14 +37,13 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen_encrypted(struct zip *za, const char *fname, int flags, - const char *password) +ZIP_EXTERN struct zip_file * +zip_fopen_encrypted(struct zip *za, const char *fname, zip_flags_t flags, const char *password) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return NULL; - return zip_fopen_index_encrypted(za, idx, flags, password); + return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password); } diff --git a/ext/zip/lib/zip_fopen_index.c b/ext/zip/lib/zip_fopen_index.c index b60fd33e8f53e..30466ffa19a59 100644 --- a/ext/zip/lib/zip_fopen_index.c +++ b/ext/zip/lib/zip_fopen_index.c @@ -1,6 +1,6 @@ /* zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -41,8 +41,8 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags) +ZIP_EXTERN struct zip_file * +zip_fopen_index(struct zip *za, zip_uint64_t index, zip_flags_t flags) { - return zip_fopen_index_encrypted(za, fileno, flags, za->default_password); + return zip_fopen_index_encrypted(za, index, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_index_encrypted.c b/ext/zip/lib/zip_fopen_index_encrypted.c index 988a78fe03f9a..cc81ca7f53b67 100644 --- a/ext/zip/lib/zip_fopen_index_encrypted.c +++ b/ext/zip/lib/zip_fopen_index_encrypted.c @@ -1,6 +1,6 @@ /* zip_fopen_index_encrypted.c -- open file for reading by index w/ password - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -43,103 +43,15 @@ static struct zip_file *_zip_file_new(struct zip *za); -ZIP_EXTERN(struct zip_file *) -zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags, +ZIP_EXTERN struct zip_file * +zip_fopen_index_encrypted(struct zip *za, zip_uint64_t index, zip_flags_t flags, const char *password) { struct zip_file *zf; - zip_compression_implementation comp_impl; - zip_encryption_implementation enc_impl; - struct zip_source *src, *s2; - zip_uint64_t start; - struct zip_stat st; - - if (fileno >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } + struct zip_source *src; - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) { - _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) return NULL; - } - - if (fileno >= za->cdir->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (flags & ZIP_FL_ENCRYPTED) - flags |= ZIP_FL_COMPRESSED; - - zip_stat_index(za, fileno, flags, &st); - - enc_impl = NULL; - if ((flags & ZIP_FL_ENCRYPTED) == 0) { - if (st.encryption_method != ZIP_EM_NONE) { - if (password == NULL) { - _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); - return NULL; - } - if ((enc_impl=zip_get_encryption_implementation( - st.encryption_method)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - } - } - - comp_impl = NULL; - if ((flags & ZIP_FL_COMPRESSED) == 0) { - if (st.comp_method != ZIP_CM_STORE) { - if ((comp_impl=zip_get_compression_implementation( - st.comp_method)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - return NULL; - } - } - } - - if ((start=_zip_file_get_offset(za, fileno)) == 0) - return NULL; - - if (st.comp_size == 0) { - if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) - return NULL; - } - else { - if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size, - 0, &st)) == NULL) - return NULL; - if (enc_impl) { - if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0, - password)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - if (comp_impl) { - if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method, - 0)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - if ((flags & ZIP_FL_COMPRESSED) == 0 - || st.comp_method == ZIP_CM_STORE ) { - if ((s2=zip_source_crc(za, src, 1)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - } if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); @@ -147,7 +59,10 @@ zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags, return NULL; } - zf = _zip_file_new(za); + if ((zf=_zip_file_new(za)) == NULL) { + zip_source_free(src); + return NULL; + } zf->src = src; @@ -160,14 +75,14 @@ static struct zip_file * _zip_file_new(struct zip *za) { struct zip_file *zf, **file; - int n; if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } - if (za->nfile >= za->nfile_alloc-1) { + if (za->nfile+1 >= za->nfile_alloc) { + unsigned int n; n = za->nfile_alloc + 10; file = (struct zip_file **)realloc(za->file, n*sizeof(struct zip_file *)); diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index a6c0851b0aaac..8235c6dfacf80 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread) { zip_int64_t n; diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index fe97e6e8c18a1..202f761f4e852 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -1,6 +1,6 @@ /* zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,28 +33,29 @@ +#include + #include "zipint.h" -ZIP_EXTERN(const char *) -zip_get_archive_comment(struct zip *za, int *lenp, int flags) +ZIP_EXTERN const char * +zip_get_archive_comment(struct zip *za, int *lenp, zip_flags_t flags) { - if ((flags & ZIP_FL_UNCHANGED) - || (za->ch_comment_len == -1)) { - if (za->cdir) { - if (lenp != NULL) - *lenp = za->cdir->comment_len; - return za->cdir->comment; - } - else { - if (lenp != NULL) - *lenp = -1; - return NULL; - } - } - - if (lenp != NULL) - *lenp = za->ch_comment_len; - return za->ch_comment; + struct zip_string *comment; + zip_uint32_t len; + const zip_uint8_t *str; + + if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL)) + comment = za->comment_orig; + else + comment = za->comment_changes; + + if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL) + return NULL; + + if (lenp) + *lenp = (int)len; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_get_archive_flag.c b/ext/zip/lib/zip_get_archive_flag.c index 2d46aa39ffbb4..c3be5c14fec38 100644 --- a/ext/zip/lib/zip_get_archive_flag.c +++ b/ext/zip/lib/zip_get_archive_flag.c @@ -37,10 +37,10 @@ -ZIP_EXTERN(int) -zip_get_archive_flag(struct zip *za, int flag, int flags) +ZIP_EXTERN int +zip_get_archive_flag(struct zip *za, unsigned int flag, zip_flags_t flags) { - int fl; + unsigned int fl; fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags; diff --git a/ext/zip/lib/zip_get_compression_implementation.c b/ext/zip/lib/zip_get_compression_implementation.c index 197cd49635d41..aa4a1605c0f36 100644 --- a/ext/zip/lib/zip_get_compression_implementation.c +++ b/ext/zip/lib/zip_get_compression_implementation.c @@ -37,10 +37,10 @@ -ZIP_EXTERN(zip_compression_implementation) -zip_get_compression_implementation(zip_uint16_t cm) +zip_compression_implementation +_zip_get_compression_implementation(zip_int32_t cm) { - if (cm == ZIP_CM_DEFLATE) + if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm)) return zip_source_deflate; return NULL; } diff --git a/ext/zip/lib/zip_get_encryption_implementation.c b/ext/zip/lib/zip_get_encryption_implementation.c index 783d538d3f6ff..7dcb99210d498 100644 --- a/ext/zip/lib/zip_get_encryption_implementation.c +++ b/ext/zip/lib/zip_get_encryption_implementation.c @@ -37,8 +37,8 @@ -ZIP_EXTERN(zip_encryption_implementation) -zip_get_encryption_implementation(zip_uint16_t em) +zip_encryption_implementation +_zip_get_encryption_implementation(zip_uint16_t em) { if (em == ZIP_EM_TRAD_PKWARE) return zip_source_pkware; diff --git a/ext/zip/lib/zip_get_file_comment.c b/ext/zip/lib/zip_get_file_comment.c index 43c1520e1d438..3be459d4da6b0 100644 --- a/ext/zip/lib/zip_get_file_comment.c +++ b/ext/zip/lib/zip_get_file_comment.c @@ -1,6 +1,6 @@ /* zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,26 +33,21 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(const char *) +ZIP_EXTERN const char * zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags) { - if (idx >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } + zip_uint32_t len; + const char *s; - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_comment_len == -1)) { - if (lenp != NULL) - *lenp = za->cdir->entry[idx].comment_len; - return za->cdir->entry[idx].comment; + if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) { + if (lenp) + *lenp = (int)len; } - - if (lenp != NULL) - *lenp = za->entry[idx].ch_comment_len; - return za->entry[idx].ch_comment; + + return s; } diff --git a/ext/zip/lib/zip_get_name.c b/ext/zip/lib/zip_get_name.c index 945e24e1501d5..f67c7caf4305f 100644 --- a/ext/zip/lib/zip_get_name.c +++ b/ext/zip/lib/zip_get_name.c @@ -1,6 +1,6 @@ /* zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,12 +33,14 @@ +#include + #include "zipint.h" -ZIP_EXTERN(const char *) -zip_get_name(struct zip *za, zip_uint64_t idx, int flags) +ZIP_EXTERN const char * +zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags) { return _zip_get_name(za, idx, flags, &za->error); } @@ -46,27 +48,16 @@ zip_get_name(struct zip *za, zip_uint64_t idx, int flags) const char * -_zip_get_name(struct zip *za, zip_uint64_t idx, int flags, - struct zip_error *error) +_zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error) { - if (idx >= za->nentry) { - _zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } + struct zip_dirent *de; + const zip_uint8_t *str; - if ((flags & ZIP_FL_UNCHANGED) == 0) { - if (za->entry[idx].state == ZIP_ST_DELETED) { - _zip_error_set(error, ZIP_ER_DELETED, 0); - return NULL; - } - if (za->entry[idx].ch_filename) - return za->entry[idx].ch_filename; - } + if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL) + return NULL; - if (za->cdir == NULL || idx >= za->cdir->nentry) { - _zip_error_set(error, ZIP_ER_INVAL, 0); + if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL) return NULL; - } - - return za->cdir->entry[idx].filename; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_get_num_entries.c b/ext/zip/lib/zip_get_num_entries.c index dd392e909592e..26484baff22a6 100644 --- a/ext/zip/lib/zip_get_num_entries.c +++ b/ext/zip/lib/zip_get_num_entries.c @@ -37,16 +37,19 @@ -ZIP_EXTERN(zip_uint64_t) -zip_get_num_entries(struct zip *za, int flags) +ZIP_EXTERN zip_int64_t +zip_get_num_entries(struct zip *za, zip_flags_t flags) { + zip_uint64_t n; + if (za == NULL) return -1; if (flags & ZIP_FL_UNCHANGED) { - if (za->cdir == NULL) - return 0; - return za->cdir->nentry; + n = za->nentry; + while (n>0 && za->entry[n-1].orig == NULL) + --n; + return (zip_int64_t)n; } - return za->nentry; + return (zip_int64_t)za->nentry; } diff --git a/ext/zip/lib/zip_get_num_files.c b/ext/zip/lib/zip_get_num_files.c index a442f293ec350..29b06dc8193ff 100644 --- a/ext/zip/lib/zip_get_num_files.c +++ b/ext/zip/lib/zip_get_num_files.c @@ -33,15 +33,17 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_get_num_files(struct zip *za) { if (za == NULL) return -1; - return za->nentry; + /* XXX: check for overflow */ + return (int)za->nentry; } diff --git a/ext/zip/lib/zip_memdup.c b/ext/zip/lib/zip_memdup.c index 641125ed2d1b2..06af2dabd36c7 100644 --- a/ext/zip/lib/zip_memdup.c +++ b/ext/zip/lib/zip_memdup.c @@ -1,6 +1,6 @@ /* zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -43,6 +43,9 @@ _zip_memdup(const void *mem, size_t len, struct zip_error *error) { void *ret; + if (len == 0) + return NULL; + ret = malloc(len); if (!ret) { _zip_error_set(error, ZIP_ER_MEMORY, 0); diff --git a/ext/zip/lib/zip_name_locate.c b/ext/zip/lib/zip_name_locate.c index 8cdd2c4d7ea0b..3cac110543672 100644 --- a/ext/zip/lib/zip_name_locate.c +++ b/ext/zip/lib/zip_name_locate.c @@ -34,26 +34,28 @@ #include +#ifdef HAVE_STRINGS_H +#include +#endif #include "zipint.h" -ZIP_EXTERN(int) -zip_name_locate(struct zip *za, const char *fname, int flags) +ZIP_EXTERN zip_int64_t +zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags) { return _zip_name_locate(za, fname, flags, &za->error); } -int -_zip_name_locate(struct zip *za, const char *fname, int flags, - struct zip_error *error) +zip_int64_t +_zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags, struct zip_error *error) { int (*cmp)(const char *, const char *); const char *fn, *p; - int i, n; + zip_uint64_t i; if (za == NULL) return -1; @@ -63,21 +65,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, return -1; } - if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) { - _zip_error_set(error, ZIP_ER_NOENT, 0); - return -1; - } - - cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp; + cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; - n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; - for (i=0; icdir->entry[i].filename; - else - fn = _zip_get_name(za, i, flags, error); + for (i=0; inentry; i++) { + fn = _zip_get_name(za, i, flags, error); - /* newly added (partially filled) entry */ + /* newly added (partially filled) entry or error */ if (fn == NULL) continue; @@ -87,11 +80,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, fn = p+1; } - if (cmp(fname, fn) == 0) - return i; + if (cmp(fname, fn) == 0) { + _zip_error_clear(error); + return (zip_int64_t)i; + } } -/* Look for an entry should not raise an error */ -/* _zip_error_set(error, ZIP_ER_NOENT, 0);*/ + _zip_error_set(error, ZIP_ER_NOENT, 0); return -1; } diff --git a/ext/zip/lib/zip_new.c b/ext/zip/lib/zip_new.c index 7ce1237cdbabd..f77634a389f36 100644 --- a/ext/zip/lib/zip_new.c +++ b/ext/zip/lib/zip_new.c @@ -1,6 +1,6 @@ /* zip_new.c -- create and init struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -56,16 +56,17 @@ _zip_new(struct zip_error *error) za->zn = NULL; za->zp = NULL; + za->open_flags = 0; _zip_error_init(&za->error); - za->cdir = NULL; - za->ch_comment = NULL; - za->ch_comment_len = -1; + za->flags = za->ch_flags = 0; + za->default_password = NULL; + za->comment_orig = za->comment_changes = NULL; + za->comment_changed = 0; za->nentry = za->nentry_alloc = 0; za->entry = NULL; za->nfile = za->nfile_alloc = 0; za->file = NULL; - za->flags = za->ch_flags = 0; - za->default_password = NULL; + za->tempdir = NULL; return za; } diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index 5ce1c1070ae03..e6a30d5ae7066 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -1,6 +1,6 @@ /* zip_open.c -- open zip archive by name - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,38 +42,53 @@ #include "zipint.h" -static void set_error(int *, struct zip_error *, int); -static struct zip *_zip_allocate_new(const char *, int *); -static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); -static void _zip_check_torrentzip(struct zip *); -static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); -static int _zip_file_exists(const char *, int, int *); -static int _zip_headercomp(struct zip_dirent *, int, - struct zip_dirent *, int); -static unsigned char *_zip_memmem(const unsigned char *, int, - const unsigned char *, int); -static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, unsigned char *, - int, int, struct zip_error *); +static void set_error(int *, const struct zip_error *, int); +static struct zip *_zip_allocate_new(const char *, unsigned int, int *); +static zip_int64_t _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static void _zip_check_torrentzip(struct zip *, const struct zip_cdir *); +static struct zip_cdir *_zip_find_central_dir(FILE *, unsigned int, int *, off_t); +static int _zip_file_exists(const char *, unsigned int, int *); +static int _zip_headercomp(const struct zip_dirent *, const struct zip_dirent *); +static unsigned char *_zip_memmem(const unsigned char *, size_t, + const unsigned char *, size_t); +static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, const unsigned char *, + size_t, unsigned int, struct zip_error *); +static struct zip_cdir *_zip_read_eocd(const unsigned char *, const unsigned char *, off_t, + size_t, unsigned int, struct zip_error *); +static struct zip_cdir *_zip_read_eocd64(FILE *, const unsigned char *, const unsigned char *, + off_t, size_t, unsigned int, struct zip_error *); -ZIP_EXTERN(struct zip *) -zip_open(const char *fn, int flags, int *zep) +ZIP_EXTERN struct zip * +zip_open(const char *fn, int _flags, int *zep) { FILE *fp; - - if (flags & ZIP_OVERWRITE) { - return _zip_allocate_new(fn, zep); + unsigned int flags; + + if (_flags < 0) { + if (zep) + *zep = ZIP_ER_INVAL; + return NULL; } - + flags = (unsigned int)_flags; + switch (_zip_file_exists(fn, flags, zep)) { case -1: - if (!(flags & ZIP_OVERWRITE)) { - return NULL; - } + return NULL; case 0: - return _zip_allocate_new(fn, zep); + return _zip_allocate_new(fn, flags, zep); default: + if (flags & ZIP_TRUNCATE) { + FILE *f; + + if ((f = fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + fclose(f); + return _zip_allocate_new(fn, flags, zep); + } break; } @@ -82,17 +97,36 @@ zip_open(const char *fn, int flags, int *zep) return NULL; } - return _zip_open(fn, fp, flags, 0, zep); + return _zip_open(fn, fp, flags, zep); } + +ZIP_EXTERN int +zip_archive_set_tempdir(struct zip *za, const char *tempdir) +{ + char *new_tempdir; + + if (tempdir) { + if ((new_tempdir = strdup(tempdir)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, errno); + return -1; + } + } + else + new_tempdir = NULL; + + free(za->tempdir); + za->tempdir = new_tempdir; + + return 0; +} struct zip * -_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) +_zip_open(const char *fn, FILE *fp, unsigned int flags, int *zep) { struct zip *za; struct zip_cdir *cdir; - int i; off_t len; if (fseeko(fp, 0, SEEK_END) < 0) { @@ -103,7 +137,7 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) /* treat empty files as empty archives */ if (len == 0) { - if ((za=_zip_allocate_new(fn, zep)) == NULL) + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) fclose(fp); else za->zp = fp; @@ -116,34 +150,32 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) return NULL; } - if ((za=_zip_allocate_new(fn, zep)) == NULL) { + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) { _zip_cdir_free(cdir); fclose(fp); return NULL; } - za->cdir = cdir; + za->entry = cdir->entry; + za->nentry = cdir->nentry; + za->nentry_alloc = cdir->nentry_alloc; + za->comment_orig = cdir->comment; + za->zp = fp; - if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) - * cdir->nentry)) == NULL) { - set_error(zep, NULL, ZIP_ER_MEMORY); - _zip_free(za); - return NULL; - } - for (i=0; inentry; i++) - _zip_entry_new(za); + _zip_check_torrentzip(za, cdir); - _zip_check_torrentzip(za); za->ch_flags = za->flags; + free(cdir); + return za; } static void -set_error(int *zep, struct zip_error *err, int ze) +set_error(int *zep, const struct zip_error *err, int ze) { int se; @@ -166,16 +198,17 @@ set_error(int *zep, struct zip_error *err, int ze) entries, or NULL if unsuccessful. */ static struct zip_cdir * -_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eocd, int buflen, - int flags, struct zip_error *error) +_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, const unsigned char *eocd, size_t buflen, + unsigned int flags, struct zip_error *error) { struct zip_cdir *cd; - unsigned char *cdp, **bufp; - int i, comlen, nentry; - zip_uint32_t left; + const unsigned char *cdp; + const unsigned char **bufp; + zip_int64_t tail_len, comment_len; + zip_uint64_t i, left; - comlen = buf + buflen - eocd - EOCDLEN; - if (comlen < 0) { + tail_len = buf + buflen - eocd - EOCDLEN; + if (tail_len < 0) { /* not enough bytes left for comment */ _zip_error_set(error, ZIP_ER_NOZIP, 0); return NULL; @@ -192,46 +225,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc return NULL; } - cdp = eocd + 8; - /* number of cdir-entries on this disk */ - i = _zip_read2(&cdp); - /* number of cdir-entries */ - nentry = _zip_read2(&cdp); + if (eocd-EOCD64LOCLEN >= buf && memcmp(eocd-EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) + cd = _zip_read_eocd64(fp, eocd-EOCD64LOCLEN, buf, buf_offset, buflen, flags, error); + else + cd = _zip_read_eocd(eocd, buf, buf_offset, buflen, flags, error); - if ((cd=_zip_cdir_new(nentry, error)) == NULL) + if (cd == NULL) return NULL; - cd->size = _zip_read4(&cdp); - cd->offset = _zip_read4(&cdp); - cd->comment = NULL; - cd->comment_len = _zip_read2(&cdp); + cdp = eocd + 20; + comment_len = _zip_read2(&cdp); - if (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) { + if ((zip_uint64_t)cd->offset+(zip_uint64_t)cd->size > (zip_uint64_t)buf_offset + (zip_uint64_t)(eocd-buf)) { /* cdir spans past EOCD record */ _zip_error_set(error, ZIP_ER_INCONS, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } - if ((comlen < cd->comment_len) || (cd->nentry != i)) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); - cd->nentry = 0; - _zip_cdir_free(cd); - return NULL; - } - if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { + if (tail_len < comment_len || ((flags & ZIP_CHECKCONS) && tail_len != comment_len)) { _zip_error_set(error, ZIP_ER_INCONS, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } - if (cd->comment_len) { - if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, - cd->comment_len, error)) - == NULL) { - cd->nentry = 0; + if (comment_len) { + if ((cd->comment=_zip_string_new(eocd+EOCDLEN, (zip_uint16_t)comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { _zip_cdir_free(cd); return NULL; } @@ -249,40 +268,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc fseeko(fp, cd->offset, SEEK_SET); /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */ - if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) { + if (ferror(fp) || (ftello(fp) != cd->offset)) { /* seek error or offset of cdir wrong */ if (ferror(fp)) _zip_error_set(error, ZIP_ER_SEEK, errno); else _zip_error_set(error, ZIP_ER_NOZIP, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } } - left = cd->size; + left = (zip_uint64_t)cd->size; i=0; while (inentry && left > 0) { - if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { - cd->nentry = i; + if ((cd->entry[i].orig=_zip_dirent_new()) == NULL + || (_zip_dirent_read(cd->entry[i].orig, fp, bufp, &left, 0, error)) < 0) { _zip_cdir_free(cd); return NULL; } i++; - - if (i == cd->nentry && left > 0) { - /* Infozip extension for more than 64k entries: - nentries wraps around, size indicates correct EOCD */ - if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) { - cd->nentry = i; - _zip_cdir_free(cd); - return NULL; - } - } } - - cd->nentry = i; + if (i != cd->nentry || ((flags & ZIP_CHECKCONS) && left != 0)) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_cdir_free(cd); + return NULL; + } return cd; } @@ -295,84 +306,88 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc file and header offsets. Returns -1 if not plausible, else the difference between the lowest and the highest fileposition reached */ -static int +static zip_int64_t _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) { - int i; - unsigned int min, max, j; + zip_uint64_t i; + zip_uint64_t min, max, j; struct zip_dirent temp; if (cd->nentry) { - max = cd->entry[0].offset; - min = cd->entry[0].offset; + max = cd->entry[0].orig->offset; + min = cd->entry[0].orig->offset; } else min = max = 0; for (i=0; inentry; i++) { - if (cd->entry[i].offset < min) - min = cd->entry[i].offset; - if (min > cd->offset) { + if (cd->entry[i].orig->offset < min) + min = cd->entry[i].orig->offset; + if (min > (zip_uint64_t)cd->offset) { _zip_error_set(error, ZIP_ER_NOZIP, 0); return -1; } - j = cd->entry[i].offset + cd->entry[i].comp_size - + cd->entry[i].filename_len + LENTRYSIZE; + j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size + + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE; if (j > max) max = j; - if (max > cd->offset) { + if (max > (zip_uint64_t)cd->offset) { _zip_error_set(error, ZIP_ER_NOZIP, 0); return -1; } - if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) { - _zip_error_set(error, ZIP_ER_SEEK, 0); + if (fseeko(fp, (off_t)cd->entry[i].orig->offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); return -1; } if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1) return -1; - if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { + if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) { _zip_error_set(error, ZIP_ER_INCONS, 0); _zip_dirent_finalize(&temp); return -1; } + + cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields); + cd->entry[i].orig->local_extra_fields_read = 1; + temp.extra_fields = NULL; + _zip_dirent_finalize(&temp); } - return max - min; + return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX; } /* _zip_check_torrentzip: - check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ static void -_zip_check_torrentzip(struct zip *za) +_zip_check_torrentzip(struct zip *za, const struct zip_cdir *cdir) { uLong crc_got, crc_should; char buf[8+1]; char *end; - if (za->zp == NULL || za->cdir == NULL) + if (za->zp == NULL || cdir == NULL) return; - if (za->cdir->comment_len != TORRENT_SIG_LEN+8 - || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0) + if (_zip_string_length(cdir->comment) != TORRENT_SIG_LEN+8 + || strncmp((const char *)cdir->comment->raw, TORRENT_SIG, TORRENT_SIG_LEN) != 0) return; - memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8); + memcpy(buf, cdir->comment->raw+TORRENT_SIG_LEN, 8); buf[8] = '\0'; errno = 0; crc_should = strtoul(buf, &end, 16); if ((crc_should == UINT_MAX && errno != 0) || (end && *end)) return; - if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size, - &crc_got, NULL) < 0) + if (_zip_filerange_crc(za->zp, cdir->offset, cdir->size, &crc_got, NULL) < 0) return; if (crc_got == crc_should) @@ -383,68 +398,32 @@ _zip_check_torrentzip(struct zip *za) /* _zip_headercomp: - compares two headers h1 and h2; if they are local headers, set - local1p or local2p respectively to 1, else 0. Return 0 if they - are identical, -1 if not. */ + compares a central directory entry and a local file header + Return 0 if they are consistent, -1 if not. */ static int -_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, - int local2p) +_zip_headercomp(const struct zip_dirent *central, const struct zip_dirent *local) { - if ((h1->version_needed != h2->version_needed) + if ((central->version_needed != local->version_needed) #if 0 /* some zip-files have different values in local and global headers for the bitflags */ - || (h1->bitflags != h2->bitflags) + || (central->bitflags != local->bitflags) #endif - || (h1->comp_method != h2->comp_method) - || (h1->last_mod != h2->last_mod) - || (h1->filename_len != h2->filename_len) - || !h1->filename || !h2->filename - || strcmp(h1->filename, h2->filename)) + || (central->comp_method != local->comp_method) + || (central->last_mod != local->last_mod) + || !_zip_string_equal(central->filename, local->filename)) return -1; - /* check that CRC and sizes are zero if data descriptor is used */ - if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p - && (h1->crc != 0 - || h1->comp_size != 0 - || h1->uncomp_size != 0)) - return -1; - if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p - && (h2->crc != 0 - || h2->comp_size != 0 - || h2->uncomp_size != 0)) - return -1; - - /* check that CRC and sizes are equal if no data descriptor is used */ - if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0) - && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) { - if ((h1->crc != h2->crc) - || (h1->comp_size != h2->comp_size) - || (h1->uncomp_size != h2->uncomp_size)) + + if ((central->crc != local->crc) || (central->comp_size != local->comp_size) + || (central->uncomp_size != local->uncomp_size)) { + /* InfoZip stores valid values in local header even when data descriptor is used. + This is in violation of the appnote. */ + if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 + || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) return -1; } - - if ((local1p == local2p) - && ((h1->extrafield_len != h2->extrafield_len) - || (h1->extrafield_len && h2->extrafield - && memcmp(h1->extrafield, h2->extrafield, - h1->extrafield_len)))) - return -1; - - /* if either is local, nothing more to check */ - if (local1p || local2p) - return 0; - - if ((h1->version_madeby != h2->version_madeby) - || (h1->disk_number != h2->disk_number) - || (h1->int_attrib != h2->int_attrib) - || (h1->ext_attrib != h2->ext_attrib) - || (h1->offset != h2->offset) - || (h1->comment_len != h2->comment_len) - || (h1->comment_len && h2->comment - && memcmp(h1->comment, h2->comment, h1->comment_len))) - return -1; return 0; } @@ -452,7 +431,7 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, static struct zip * -_zip_allocate_new(const char *fn, int *zep) +_zip_allocate_new(const char *fn, unsigned int flags, int *zep) { struct zip *za; struct zip_error error; @@ -467,18 +446,19 @@ _zip_allocate_new(const char *fn, int *zep) else { za->zn = strdup(fn); if (!za->zn) { - _zip_free(za); + zip_discard(za); set_error(zep, NULL, ZIP_ER_MEMORY); return NULL; } } + za->open_flags = flags; return za; } static int -_zip_file_exists(const char *fn, int flags, int *zep) +_zip_file_exists(const char *fn, unsigned int flags, int *zep) { struct stat st; @@ -488,7 +468,7 @@ _zip_file_exists(const char *fn, int flags, int *zep) } if (stat(fn, &st) != 0) { - if (flags & ZIP_CREATE || flags & ZIP_OVERWRITE) + if (flags & ZIP_CREATE) return 0; else { set_error(zep, NULL, ZIP_ER_OPEN); @@ -508,12 +488,14 @@ _zip_file_exists(const char *fn, int flags, int *zep) static struct zip_cdir * -_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) +_zip_find_central_dir(FILE *fp, unsigned int flags, int *zep, off_t len) { struct zip_cdir *cdir, *cdirnew; unsigned char *buf, *match; off_t buf_offset; - int a, best, buflen, i; + size_t buflen; + zip_int64_t a, i; + zip_int64_t best; struct zip_error zerr; i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); @@ -541,10 +523,10 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) best = -1; cdir = NULL; - match = buf; + match = buf+ (buflen < CDBUFSIZE ? 0 : EOCD64LOCLEN); _zip_error_set(&zerr, ZIP_ER_NOZIP, 0); - while ((match=_zip_memmem(match, buflen-(match-buf)-18, + while ((match=_zip_memmem(match, buflen-(size_t)(match-buf)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { /* found match -- check, if good */ /* to avoid finding the same match all over again */ @@ -589,8 +571,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) static unsigned char * -_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, - int littlelen) +_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { const unsigned char *p; @@ -598,11 +579,159 @@ _zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, return NULL; p = big-1; while ((p=(const unsigned char *) - memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1))) - != NULL) { + memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) { if (memcmp(p+1, little+1, littlelen-1)==0) return (unsigned char *)p; } return NULL; } + + + +static struct zip_cdir * +_zip_read_eocd(const unsigned char *eocd, const unsigned char *buf, off_t buf_offset, size_t buflen, + unsigned int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + const unsigned char *cdp; + zip_uint64_t i, nentry, size, offset; + + if (eocd+EOCDLEN > buf+buflen) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + cdp = eocd + 8; + + /* number of cdir-entries on this disk */ + i = _zip_read2(&cdp); + /* number of cdir-entries */ + nentry = _zip_read2(&cdp); + + if (nentry != i) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + size = _zip_read4(&cdp); + offset = _zip_read4(&cdp); + + if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + + if (offset+size > (zip_uint64_t)(buf_offset + (eocd-buf))) { + /* cdir spans past EOCD record */ + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((flags & ZIP_CHECKCONS) && offset+size != (zip_uint64_t)(buf_offset + (eocd-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + cd->size = (off_t)size; + cd->offset = (off_t)offset; + + return cd; +} + + + +static struct zip_cdir * +_zip_read_eocd64(FILE *f, const zip_uint8_t *eocd64loc, const zip_uint8_t *buf, + off_t buf_offset, size_t buflen, unsigned int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + zip_uint64_t offset; + const zip_uint8_t *cdp; + zip_uint8_t eocd[EOCD64LEN]; + zip_uint64_t eocd_offset; + zip_uint64_t size, nentry, i; + + cdp = eocd64loc+8; + eocd_offset = _zip_read8(&cdp); + + if (eocd_offset > ZIP_OFF_MAX || eocd_offset + EOCD64LEN > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + + if (eocd64loc < buf || (off_t)eocd_offset+EOCD64LEN > (buf_offset+(eocd64loc-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((off_t)eocd_offset >= buf_offset && (off_t)eocd_offset+EOCD64LEN <= buf_offset+(ssize_t)buflen) + cdp = buf+((off_t)eocd_offset-buf_offset); + else { + if (fseeko(f, (off_t)eocd_offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); + return NULL; + } + + clearerr(f); + if (fread(eocd, 1, EOCD64LEN, f) < EOCD64LEN) { + _zip_error_set(error, ZIP_ER_READ, errno); + return NULL; + } + + if (ferror(f)) { + _zip_error_set(error, ZIP_ER_READ, errno); + return NULL; + } + + cdp = eocd; + } + + if (memcmp(cdp, EOCD64_MAGIC, 4) != 0) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + cdp += 4; + + size = _zip_read8(&cdp); + + if ((flags & ZIP_CHECKCONS) && size+eocd_offset+12 != (zip_uint64_t)(buf_offset+(eocd64loc-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + cdp += 4; /* skip version made by/needed */ + cdp += 8; /* skip num disks */ + + nentry = _zip_read8(&cdp); + i = _zip_read8(&cdp); + + if (nentry != i) { + _zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } + + size = _zip_read8(&cdp); + offset = _zip_read8(&cdp); + + if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + + cd->size = (off_t)size; + cd->offset = (off_t)offset; + + return cd; +} diff --git a/ext/zip/lib/zip_rename.c b/ext/zip/lib/zip_rename.c index 6b5a0359172da..8841caeca9a9e 100644 --- a/ext/zip/lib/zip_rename.c +++ b/ext/zip/lib/zip_rename.c @@ -1,6 +1,6 @@ /* zip_rename.c -- rename file in zip archive - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,36 +35,13 @@ #include +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_rename(struct zip *za, zip_uint64_t idx, const char *name) { - const char *old_name; - int old_is_dir, new_is_dir; - - if (idx >= za->nentry || name[0] == '\0') { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if ((old_name=zip_get_name(za, idx, 0)) == NULL) - return -1; - - new_is_dir = (name[strlen(name)-1] == '/'); - old_is_dir = (old_name[strlen(old_name)-1] == '/'); - - if (new_is_dir != old_is_dir) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_set_name(za, idx, name); + return zip_file_rename(za, idx, name, 0); } diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c index 6dc3dd5ab508f..de717afec7dd1 100644 --- a/ext/zip/lib/zip_replace.c +++ b/ext/zip/lib/zip_replace.c @@ -1,6 +1,6 @@ /* zip_replace.c -- replace file via callback function - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,53 +33,13 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source) { - if (idx >= za->nentry || source == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_replace(za, idx, NULL, source) == -1) - return -1; - - return 0; -} - - - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -zip_int64_t -_zip_replace(struct zip *za, zip_uint64_t idx, const char *name, - struct zip_source *source) -{ - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (idx == ZIP_UINT64_MAX) { - if (_zip_entry_new(za) == NULL) - return -1; - - idx = za->nentry - 1; - } - - _zip_unchange_data(za->entry+idx); - - if (name && _zip_set_name(za, idx, name) != 0) - return -1; - - za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) - ? ZIP_ST_ADDED : ZIP_ST_REPLACED); - za->entry[idx].source = source; - - return idx; + return zip_file_replace(za, idx, source, 0); } diff --git a/ext/zip/lib/zip_set_archive_comment.c b/ext/zip/lib/zip_set_archive_comment.c index 3cd069c7577c9..df1caee06b116 100644 --- a/ext/zip/lib/zip_set_archive_comment.c +++ b/ext/zip/lib/zip_set_archive_comment.c @@ -1,6 +1,6 @@ /* zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -39,32 +39,46 @@ -ZIP_EXTERN(int) -zip_set_archive_comment(struct zip *za, const char *comment, int len) +ZIP_EXTERN int +zip_set_archive_comment(struct zip *za, const char *comment, zip_uint16_t len) { - char *tmpcom; + struct zip_string *cstr; - if (len < 0 || len > MAXCOMLEN - || (len > 0 && comment == NULL)) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + if (len > 0 && comment == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if (len > 0) { - if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL) return -1; + + if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) { + _zip_string_free(cstr); + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } } else - tmpcom = NULL; + cstr = NULL; + + _zip_string_free(za->comment_changes); + za->comment_changes = NULL; - free(za->ch_comment); - za->ch_comment = tmpcom; - za->ch_comment_len = len; + if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr)) + || (za->comment_orig == NULL && cstr == NULL))) { + _zip_string_free(cstr); + za->comment_changed = 0; + } + else { + za->comment_changes = cstr; + za->comment_changed = 1; + } return 0; } diff --git a/ext/zip/lib/zip_set_archive_flag.c b/ext/zip/lib/zip_set_archive_flag.c index 07bcfbe304d85..b6cdab120ddb2 100644 --- a/ext/zip/lib/zip_set_archive_flag.c +++ b/ext/zip/lib/zip_set_archive_flag.c @@ -37,8 +37,8 @@ -ZIP_EXTERN(int) -zip_set_archive_flag(struct zip *za, int flag, int value) +ZIP_EXTERN int +zip_set_archive_flag(struct zip *za, unsigned int flag, int value) { unsigned int new_flags; diff --git a/ext/zip/lib/zip_set_default_password.c b/ext/zip/lib/zip_set_default_password.c index c274d1100bb3a..b9aa80acffc25 100644 --- a/ext/zip/lib/zip_set_default_password.c +++ b/ext/zip/lib/zip_set_default_password.c @@ -40,7 +40,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_set_default_password(struct zip *za, const char *passwd) { if (za == NULL) diff --git a/ext/zip/lib/zip_set_file_comment.c b/ext/zip/lib/zip_set_file_comment.c index 5e63dc2730ad4..7acd0eb36de29 100644 --- a/ext/zip/lib/zip_set_file_comment.c +++ b/ext/zip/lib/zip_set_file_comment.c @@ -1,6 +1,6 @@ /* zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,38 +35,17 @@ #include +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) -zip_set_file_comment(struct zip *za, zip_uint64_t idx, - const char *comment, int len) +ZIP_EXTERN int +zip_set_file_comment(struct zip *za, zip_uint64_t idx, const char *comment, int len) { - char *tmpcom; - - if (idx >= za->nentry - || len < 0 || len > MAXCOMLEN - || (len > 0 && comment == NULL)) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; + if (len < 0 || len > ZIP_UINT16_MAX) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - - if (len > 0) { - if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) - return -1; - } - else - tmpcom = NULL; - - free(za->entry[idx].ch_comment); - za->entry[idx].ch_comment = tmpcom; - za->entry[idx].ch_comment_len = len; - - return 0; + return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0); } diff --git a/ext/zip/lib/zip_set_file_compression.c b/ext/zip/lib/zip_set_file_compression.c new file mode 100644 index 0000000000000..ea8517d70e602 --- /dev/null +++ b/ext/zip/lib/zip_set_file_compression.c @@ -0,0 +1,90 @@ +/* + zip_set_file_compression.c -- set compression for file in archive + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_set_file_compression(struct zip *za, zip_uint64_t idx, + zip_int32_t method, zip_uint32_t flags) +{ + struct zip_entry *e; + zip_int32_t old_method; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return -1; + } + + e = za->entry+idx; + + old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method); + + /* XXX: revisit this when flags are supported, since they may require a recompression */ + + if (method == old_method) { + if (e->changes) { + e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; + if (e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } + } + else { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + e->changes->comp_method = method; + e->changes->changed |= ZIP_DIRENT_COMP_METHOD; + } + + return 0; +} diff --git a/ext/zip/lib/zip_set_name.c b/ext/zip/lib/zip_set_name.c index 2a90601bfec35..60c9e7d5bf59a 100644 --- a/ext/zip/lib/zip_set_name.c +++ b/ext/zip/lib/zip_set_name.c @@ -1,6 +1,6 @@ /* zip_set_name.c -- rename helper function - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -41,35 +41,77 @@ int -_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name) +_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - char *s; + struct zip_entry *e; + struct zip_string *str; + int changed; zip_int64_t i; - - if (idx >= za->nentry || name == NULL) { + + if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) { + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (name && strlen(name) > 0) { + /* XXX: check for string too long */ + if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL) + return -1; + if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) + str->encoding = ZIP_ENCODING_UTF8_KNOWN; + } + else + str = NULL; + + /* XXX: encoding flags needed for CP437? */ + if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) { + _zip_string_free(str); _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); return -1; } /* no effective name change */ - if (i == idx) + if (i>=0 && (zip_uint64_t)i == idx) { + _zip_string_free(str); return 0; - - if ((s=strdup(name)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; } - - if (za->entry[idx].state == ZIP_ST_UNCHANGED) - za->entry[idx].state = ZIP_ST_RENAMED; - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = s; + e = za->entry+idx; + + if (e->changes) { + _zip_string_free(e->changes->filename); + e->changes->filename = NULL; + e->changes->changed &= ~ZIP_DIRENT_FILENAME; + } + + if (e->orig) + changed = !_zip_string_equal(e->orig->filename, str); + else + changed = 1; + + if (changed) { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + _zip_string_free(str); + return -1; + } + } + e->changes->filename = str; + e->changes->changed |= ZIP_DIRENT_FILENAME; + } + else { + _zip_string_free(str); + if (e->changes && e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } return 0; } diff --git a/ext/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c index 8c9154ce3c5ba..8a13e7602d195 100644 --- a/ext/zip/lib/zip_source_buffer.c +++ b/ext/zip/lib/zip_source_buffer.c @@ -48,7 +48,7 @@ static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep) { struct read_data *f; @@ -98,9 +98,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) return 0; case ZIP_SOURCE_READ: - /* XXX: return error if (len > ZIP_INT64_MAX) */ - - n = z->end - z->buf; + n = (zip_uint64_t)(z->end - z->buf); if (n > len) n = len; @@ -109,7 +107,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) z->buf += n; } - return n; + return (zip_int64_t)n; case ZIP_SOURCE_CLOSE: return 0; @@ -125,7 +123,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) zip_stat_init(st); st->mtime = z->mtime; - st->size = z->end - z->data; + st->size = (zip_uint64_t)(z->end - z->data); st->comp_size = st->size; st->comp_method = ZIP_CM_STORE; st->encryption_method = ZIP_EM_NONE; diff --git a/ext/zip/lib/zip_source_close.c b/ext/zip/lib/zip_source_close.c index a3bf7e5e1d9bd..7b89d5fc15f68 100644 --- a/ext/zip/lib/zip_source_close.c +++ b/ext/zip/lib/zip_source_close.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +void zip_source_close(struct zip_source *src) { if (!src->is_open) diff --git a/ext/zip/lib/zip_source_crc.c b/ext/zip/lib/zip_source_crc.c index 7fd78f56970cf..99bc965228898 100644 --- a/ext/zip/lib/zip_source_crc.c +++ b/ext/zip/lib/zip_source_crc.c @@ -38,7 +38,7 @@ #include "zipint.h" -struct crc { +struct crc_context { int eof; int validate; int e[2]; @@ -51,23 +51,27 @@ static zip_int64_t crc_read(struct zip_source *, void *, void * -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_crc(struct zip *za, struct zip_source *src, int validate) { - struct crc *ctx; + struct crc_context *ctx; if (src == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } - if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) { + if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } + ctx->eof = 0; ctx->validate = validate; - + ctx->e[0] = ctx->e[1] = 0; + ctx->size = 0; + ctx->crc = 0; + return zip_source_layered(za, src, crc_read, ctx); } @@ -77,15 +81,15 @@ static zip_int64_t crc_read(struct zip_source *src, void *_ctx, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { - struct crc *ctx; + struct crc_context *ctx; zip_int64_t n; - ctx = (struct crc *)_ctx; + ctx = (struct crc_context *)_ctx; switch (cmd) { case ZIP_SOURCE_OPEN: ctx->eof = 0; - ctx->crc = crc32(0, NULL, 0); + ctx->crc = (zip_uint32_t)crc32(0, NULL, 0); ctx->size = 0; return 0; @@ -120,8 +124,8 @@ crc_read(struct zip_source *src, void *_ctx, void *data, } } else { - ctx->size += n; - ctx->crc = crc32(ctx->crc, data, n); + ctx->size += (zip_uint64_t)n; + ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data, (uInt)n); /* XXX: check for overflow, use multiple crc calls if needed */ } return n; @@ -139,7 +143,10 @@ crc_read(struct zip_source *src, void *_ctx, void *data, After all, this only works for uncompressed data. */ st->size = ctx->size; st->crc = ctx->crc; - st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC; + st->comp_size = ctx->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;; } } return 0; diff --git a/ext/zip/lib/zip_source_deflate.c b/ext/zip/lib/zip_source_deflate.c index 5d9c5e67bb605..879953144ce56 100644 --- a/ext/zip/lib/zip_source_deflate.c +++ b/ext/zip/lib/zip_source_deflate.c @@ -60,14 +60,14 @@ static void deflate_free(struct deflate *); -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_deflate(struct zip *za, struct zip_source *src, - zip_uint16_t cm, int flags) + zip_int32_t cm, int flags) { struct deflate *ctx; struct zip_source *s2; - if (src == NULL || cm != ZIP_CM_DEFLATE) { + if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } @@ -113,7 +113,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, return 0; ctx->zstr.next_out = (Bytef *)data; - ctx->zstr.avail_out = len; + ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */ end = 0; while (!end) { @@ -136,8 +136,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, break; } - if ((n=zip_source_read(src, ctx->buffer, - sizeof(ctx->buffer))) < 0) { + if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { zip_source_error(src, ctx->e, ctx->e+1); end = 1; break; @@ -149,7 +148,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, } else { ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n; } continue; } @@ -167,7 +166,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, } if (ctx->zstr.avail_out < len) - return len - ctx->zstr.avail_out; + return (zip_int64_t)(len - ctx->zstr.avail_out); return (ctx->e[0] == 0) ? 0 : -1; } @@ -188,7 +187,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, return 0; ctx->zstr.next_out = (Bytef *)data; - ctx->zstr.avail_out = len; + ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */ end = 0; while (!end && ctx->zstr.avail_out) { @@ -210,8 +209,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, break; } - if ((n=zip_source_read(src, ctx->buffer, - sizeof(ctx->buffer))) < 0) { + if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { zip_source_error(src, ctx->e, ctx->e+1); end = 1; break; @@ -220,7 +218,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, ctx->eof = 1; else { ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n; } continue; } @@ -237,7 +235,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, } if (ctx->zstr.avail_out < len) - return len - ctx->zstr.avail_out; + return (zip_int64_t)(len - ctx->zstr.avail_out); return (ctx->e[0] == 0) ? 0 : -1; } @@ -334,7 +332,7 @@ deflate_decompress(struct zip_source *src, void *ud, void *data, ctx->zstr.zfree = Z_NULL; ctx->zstr.opaque = NULL; ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n /* XXX: check for overflow */; /* negative value to tell zlib that there is no header */ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) { diff --git a/ext/zip/lib/zip_source_error.c b/ext/zip/lib/zip_source_error.c index 70ec8bc5d452f..a1efd551ea3dd 100644 --- a/ext/zip/lib/zip_source_error.c +++ b/ext/zip/lib/zip_source_error.c @@ -1,6 +1,6 @@ /* zip_source_error.c -- get last error from zip_source - Copyright (C) 2009 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -37,24 +37,21 @@ -ZIP_EXTERN(void) +void zip_source_error(struct zip_source *src, int *ze, int *se) { - int e[2] = { 0, 0 }; + int e[2]; if (src->src == NULL) { + if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { + e[0] = ZIP_ER_INTERNAL; + e[1] = 0; + } } else { switch (src->error_source) { case ZIP_LES_NONE: - if (src->src == NULL) { - if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { - e[0] = ZIP_ER_INTERNAL; - e[1] = 0; - } - } - else - e[0] = e[1] = 0; + e[0] = e[1] = 0; break; case ZIP_LES_INVAL: @@ -67,8 +64,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se) return; case ZIP_LES_UPPER: - if (src->cb.l(src->src, src->ud, e, sizeof(e), - ZIP_SOURCE_ERROR) < 0) { + if (src->cb.l(src->src, src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { e[0] = ZIP_ER_INTERNAL; e[1] = 0; } @@ -77,6 +73,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se) default: e[0] = ZIP_ER_INTERNAL; e[1] = 0; + break; } } diff --git a/ext/zip/lib/zip_source_file.c b/ext/zip/lib/zip_source_file.c index 681cc2f3ea643..79c8ee5aca22b 100644 --- a/ext/zip/lib/zip_source_file.c +++ b/ext/zip/lib/zip_source_file.c @@ -40,7 +40,7 @@ -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_file(struct zip *za, const char *fname, zip_uint64_t start, zip_int64_t len) { diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c index 4d896a4c01bfc..0bd2d6846e5a3 100644 --- a/ext/zip/lib/zip_source_filep.c +++ b/ext/zip/lib/zip_source_filep.c @@ -58,14 +58,14 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start, zip_int64_t len) { if (za == NULL) return NULL; - if (file == NULL || start < 0 || len < -1) { + if (file == NULL || len < -1) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } @@ -125,7 +125,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct read_file *z; char *buf; - int i, n; + size_t i, n; z = (struct read_file *)state; buf = (char *)data; @@ -140,7 +140,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) } } - if (z->closep) { + if (z->closep && z->off > 0) { if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) { z->e[0] = ZIP_ER_SEEK; z->e[1] = errno; @@ -153,30 +153,31 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) case ZIP_SOURCE_READ: /* XXX: return INVAL if len > size_t max */ if (z->remain != -1) - n = len > z->remain ? z->remain : len; + n = len > (zip_uint64_t)z->remain ? (zip_uint64_t)z->remain : len; else n = len; if (!z->closep) { /* we might share this file with others, so let's be safe */ - if (fseeko(z->f, (off_t)(z->off + z->len-z->remain), - SEEK_SET) < 0) { + if (fseeko(z->f, (off_t)(z->off + (zip_uint64_t)(z->len-z->remain)), SEEK_SET) < 0) { z->e[0] = ZIP_ER_SEEK; z->e[1] = errno; return -1; } } - if ((i=fread(buf, 1, n, z->f)) < 0) { - z->e[0] = ZIP_ER_READ; - z->e[1] = errno; - return -1; + if ((i=fread(buf, 1, n, z->f)) == 0) { + if (ferror(z->f)) { + z->e[0] = ZIP_ER_READ; + z->e[1] = errno; + return -1; + } } if (z->remain != -1) z->remain -= i; - return i; + return (zip_int64_t)i; case ZIP_SOURCE_CLOSE: if (z->fname) { @@ -214,11 +215,11 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) st->mtime = fst.st_mtime; st->valid |= ZIP_STAT_MTIME; if (z->len != -1) { - st->size = z->len; + st->size = (zip_uint64_t)z->len; st->valid |= ZIP_STAT_SIZE; } else if ((fst.st_mode&S_IFMT) == S_IFREG) { - st->size = fst.st_size; + st->size = (zip_uint64_t)fst.st_size; st->valid |= ZIP_STAT_SIZE; } } diff --git a/ext/zip/lib/zip_source_free.c b/ext/zip/lib/zip_source_free.c index f71c71ed6c577..b1e78404965c2 100644 --- a/ext/zip/lib/zip_source_free.c +++ b/ext/zip/lib/zip_source_free.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_source_free(struct zip_source *src) { if (src == NULL) diff --git a/ext/zip/lib/zip_source_function.c b/ext/zip/lib/zip_source_function.c index 984b107f7baa6..cb92e339b4bb2 100644 --- a/ext/zip/lib/zip_source_function.c +++ b/ext/zip/lib/zip_source_function.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_function(struct zip *za, zip_source_callback zcb, void *ud) { struct zip_source *zs; diff --git a/ext/zip/lib/zip_source_layered.c b/ext/zip/lib/zip_source_layered.c index 86ed420407071..ad2870333cdee 100644 --- a/ext/zip/lib/zip_source_layered.c +++ b/ext/zip/lib/zip_source_layered.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_layered(struct zip *za, struct zip_source *src, zip_source_layered_callback cb, void *ud) { diff --git a/ext/zip/lib/zip_source_open.c b/ext/zip/lib/zip_source_open.c index 2c768f7f3a4e5..a5010393e7b9c 100644 --- a/ext/zip/lib/zip_source_open.c +++ b/ext/zip/lib/zip_source_open.c @@ -1,6 +1,6 @@ /* zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +int zip_source_open(struct zip_source *src) { zip_int64_t ret; @@ -60,7 +60,7 @@ zip_source_open(struct zip_source *src) ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN); if (ret < 0) { - (void)zip_source_close(src->src); + zip_source_close(src->src); if (ret == ZIP_SOURCE_ERR_LOWER) src->error_source = ZIP_LES_LOWER; diff --git a/ext/zip/lib/zip_source_pkware.c b/ext/zip/lib/zip_source_pkware.c index 83b5cc5ad5b22..ec53dfeef0468 100644 --- a/ext/zip/lib/zip_source_pkware.c +++ b/ext/zip/lib/zip_source_pkware.c @@ -49,10 +49,6 @@ struct trad_pkware { #define KEY1 591751049 #define KEY2 878082192 -static const uLongf *crc = NULL; - -#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8)) - static void decrypt(struct trad_pkware *, zip_uint8_t *, @@ -64,7 +60,7 @@ static void pkware_free(struct trad_pkware *); -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_pkware(struct zip *za, struct zip_source *src, zip_uint16_t em, int flags, const char *password) { @@ -80,9 +76,6 @@ zip_source_pkware(struct zip *za, struct zip_source *src, return NULL; } - if (crc == NULL) - crc = get_crc_table(); - if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; @@ -118,7 +111,7 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, if (!update_only) { /* decrypt next byte */ - tmp = ctx->key[2] | 2; + tmp = (zip_uint16_t)(ctx->key[2] | 2); tmp = (tmp * (tmp ^ 1)) >> 8; b ^= tmp; } @@ -128,10 +121,10 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, out[i] = b; /* update keys */ - ctx->key[0] = CRC32(ctx->key[0], b); + ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1; b = ctx->key[1] >> 24; - ctx->key[2] = CRC32(ctx->key[2], b); + ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; } } @@ -196,7 +189,7 @@ pkware_decrypt(struct zip_source *src, void *ud, void *data, if ((n=zip_source_read(src, data, len)) < 0) return ZIP_SOURCE_ERR_LOWER; - decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, + decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0); return n; diff --git a/ext/zip/lib/zip_source_pop.c b/ext/zip/lib/zip_source_pop.c index 406093869b962..cd9cb529b5cc7 100644 --- a/ext/zip/lib/zip_source_pop.c +++ b/ext/zip/lib/zip_source_pop.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_pop(struct zip_source *src) { struct zip_source *lower; diff --git a/ext/zip/lib/zip_source_read.c b/ext/zip/lib/zip_source_read.c index 7246f9ccb5367..81b90ba42de35 100644 --- a/ext/zip/lib/zip_source_read.c +++ b/ext/zip/lib/zip_source_read.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(zip_int64_t) +zip_int64_t zip_source_read(struct zip_source *src, void *data, zip_uint64_t len) { zip_int64_t ret; diff --git a/ext/zip/lib/zip_source_stat.c b/ext/zip/lib/zip_source_stat.c index 662779eb6cfba..85ae6a2fd6a26 100644 --- a/ext/zip/lib/zip_source_stat.c +++ b/ext/zip/lib/zip_source_stat.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +int zip_source_stat(struct zip_source *src, struct zip_stat *st) { zip_int64_t ret; diff --git a/ext/zip/lib/zip_source_window.c b/ext/zip/lib/zip_source_window.c new file mode 100644 index 0000000000000..fd202099b5aa8 --- /dev/null +++ b/ext/zip/lib/zip_source_window.c @@ -0,0 +1,150 @@ +/* + zip_source_window.c -- return part of lower source + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include +#include + +#include "zipint.h" + +struct window { + zip_uint64_t skip; + zip_uint64_t len; + zip_uint64_t left; + int e[2]; +}; + +static zip_int64_t window_read(struct zip_source *, void *, void *, + zip_uint64_t, enum zip_source_cmd); + + + +struct zip_source * +zip_source_window(struct zip *za, struct zip_source *src, zip_uint64_t start, zip_uint64_t len) +{ + struct window *ctx; + + if (src == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((ctx=(struct window *)malloc(sizeof(*ctx))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + ctx->skip = start; + ctx->len = len; + ctx->left = len; + + return zip_source_layered(za, src, window_read, ctx); +} + + + +static zip_int64_t +window_read(struct zip_source *src, void *_ctx, void *data, + zip_uint64_t len, enum zip_source_cmd cmd) +{ + struct window *ctx; + zip_int64_t ret; + zip_uint64_t n, i; + char b[8192]; + + ctx = (struct window *)_ctx; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + for (n=0; nskip; n+=(zip_uint64_t)ret) { + i = (ctx->skip-n > sizeof(b) ? sizeof(b) : ctx->skip-n); + if ((ret=zip_source_read(src, b, i)) < 0) + return ZIP_SOURCE_ERR_LOWER; + if (ret==0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return 0; + + case ZIP_SOURCE_READ: + if (len > ctx->left) + len = ctx->left; + + if (len == 0) + return 0; + + if ((ret=zip_source_read(src, data, len)) < 0) + return ZIP_SOURCE_ERR_LOWER; + + ctx->left -= (zip_uint64_t)ret; + + if (ret == 0) { + if (ctx->left > 0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return ret; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + + st = (struct zip_stat *)data; + + st->size = ctx->len; + st->valid |= ZIP_STAT_SIZE; + st->valid &= ~(ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE); + } + return 0; + + case ZIP_SOURCE_ERROR: + memcpy(data, ctx->e, sizeof(ctx->e)); + return 0; + + case ZIP_SOURCE_FREE: + free(ctx); + return 0; + + default: + return -1; + } + +} diff --git a/ext/zip/lib/zip_source_zip.c b/ext/zip/lib/zip_source_zip.c index 228803c717f6a..e4fc2229f782c 100644 --- a/ext/zip/lib/zip_source_zip.c +++ b/ext/zip/lib/zip_source_zip.c @@ -38,153 +38,24 @@ #include "zipint.h" -struct read_zip { - struct zip_file *zf; - struct zip_stat st; - zip_uint64_t off; - zip_int64_t len; -}; - -static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len, - enum zip_source_cmd cmd); - -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, - int flags, zip_uint64_t start, zip_int64_t len) + zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { - struct zip_error error; - struct zip_source *zs; - struct read_zip *p; - - /* XXX: ZIP_FL_RECOMPRESS */ - - if (za == NULL) - return NULL; - - if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; + if (len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; } - - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) { - _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return NULL; - } - - if (len == 0) - len = -1; - - if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0) + + if (len == -1) + len = 0; + + if (start == 0 && len == 0) flags |= ZIP_FL_COMPRESSED; else flags &= ~ZIP_FL_COMPRESSED; - if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - _zip_error_copy(&error, &srcza->error); - - if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0 - || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) { - free(p); - _zip_error_copy(&za->error, &srcza->error); - _zip_error_copy(&srcza->error, &error); - - return NULL; - } - p->off = start; - p->len = len; - - if ((flags & ZIP_FL_COMPRESSED) == 0) { - p->st.size = p->st.comp_size = len; - p->st.comp_method = ZIP_CM_STORE; - p->st.crc = 0; - } - - if ((zs=zip_source_function(za, read_zip, p)) == NULL) { - free(p); - return NULL; - } - - return zs; -} - - - -static zip_int64_t -read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) -{ - struct read_zip *z; - char b[8192], *buf; - int i; - zip_uint64_t n; - - z = (struct read_zip *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - for (n=0; noff; n+= i) { - i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n); - if ((i=zip_fread(z->zf, b, i)) < 0) { - zip_fclose(z->zf); - z->zf = NULL; - return -1; - } - } - return 0; - - case ZIP_SOURCE_READ: - if (z->len != -1) - n = len > z->len ? z->len : len; - else - n = len; - - - if ((i=zip_fread(z->zf, buf, n)) < 0) - return -1; - - if (z->len != -1) - z->len -= i; - - return i; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: - if (len < sizeof(z->st)) - return -1; - len = sizeof(z->st); - - memcpy(data, &z->st, len); - return len; - - case ZIP_SOURCE_ERROR: - { - int *e; - - if (len < sizeof(int)*2) - return -1; - - e = (int *)data; - zip_file_error_get(z->zf, e, e+1); - } - return sizeof(int)*2; - - case ZIP_SOURCE_FREE: - zip_fclose(z->zf); - free(z); - return 0; - - default: - ; - } - - return -1; + return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL); } diff --git a/ext/zip/lib/zip_source_zip_new.c b/ext/zip/lib/zip_source_zip_new.c new file mode 100644 index 0000000000000..8e48f6f3faa0c --- /dev/null +++ b/ext/zip/lib/zip_source_zip_new.c @@ -0,0 +1,172 @@ +/* + zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include + +#include "zipint.h" + + + +struct zip_source * +_zip_source_zip_new(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, zip_flags_t flags, + zip_uint64_t start, zip_uint64_t len, const char *password) +{ + zip_compression_implementation comp_impl; + zip_encryption_implementation enc_impl; + struct zip_source *src, *s2; + zip_uint64_t offset; + struct zip_stat st; + + if (za == NULL) + return NULL; + + if (srcza == NULL || srcidx >= srcza->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].deleted)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if (flags & ZIP_FL_ENCRYPTED) + flags |= ZIP_FL_COMPRESSED; + + if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + /* overflow or past end of file */ + if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + enc_impl = NULL; + if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) { + if (password == NULL) { + _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); + return NULL; + } + if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + return NULL; + } + } + + comp_impl = NULL; + if ((flags & ZIP_FL_COMPRESSED) == 0) { + if (st.comp_method != ZIP_CM_STORE) { + if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return NULL; + } + } + } + + if ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0) + return NULL; + + if (st.comp_size == 0) { + if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) + return NULL; + } + else { + if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) { + struct zip_stat st2; + + st2.size = len ? len : st.size-start; + st2.comp_size = st2.size; + st2.comp_method = ZIP_CM_STORE; + st2.mtime = st.mtime; + st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME; + + /* XXX: check for overflow of st2.size */ + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset+start, (zip_int64_t)st2.size, 0, &st2)) == NULL) + return NULL; + } + else { + /* XXX: check for overflow of st.comp_size */ + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset, (zip_int64_t)st.comp_size, 0, &st)) == NULL) + return NULL; + } + + if (enc_impl) { + if ((s2=enc_impl(za, src, st.encryption_method, 0, password)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + if (comp_impl) { + if ((s2=comp_impl(za, src, st.comp_method, 0)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + if (((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) + && (len == 0 || len == st.comp_size)) { + /* when reading the whole file, check for crc errors */ + if ((s2=zip_source_crc(za, src, 1)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + + if (start+len > 0 && (comp_impl || enc_impl)) { + if ((s2=zip_source_window(za, src, start, len ? len : st.size-start)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) (why?) */ + return NULL; + } + src = s2; + } + } + + return src; +} diff --git a/ext/zip/lib/zip_stat.c b/ext/zip/lib/zip_stat.c index c8a25e1d84ac3..8254627d929f4 100644 --- a/ext/zip/lib/zip_stat.c +++ b/ext/zip/lib/zip_stat.c @@ -37,13 +37,13 @@ -ZIP_EXTERN(int) -zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) +ZIP_EXTERN int +zip_stat(struct zip *za, const char *fname, zip_flags_t flags, struct zip_stat *st) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return -1; - return zip_stat_index(za, idx, flags, st); + return zip_stat_index(za, (zip_uint64_t)idx, flags, st); } diff --git a/ext/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c index 8faa8cc394972..f4ce72aaa82d8 100644 --- a/ext/zip/lib/zip_stat_index.c +++ b/ext/zip/lib/zip_stat_index.c @@ -37,16 +37,15 @@ -ZIP_EXTERN(int) -zip_stat_index(struct zip *za, zip_uint64_t index, int flags, +ZIP_EXTERN int +zip_stat_index(struct zip *za, zip_uint64_t index, zip_flags_t flags, struct zip_stat *st) { const char *name; - - if (index >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + struct zip_dirent *de; + + if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL) return -1; - } if ((name=zip_get_name(za, index, flags)) == NULL) return -1; @@ -60,20 +59,15 @@ zip_stat_index(struct zip *za, zip_uint64_t index, int flags, } } else { - if (za->cdir == NULL || index >= za->cdir->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - zip_stat_init(st); - st->crc = za->cdir->entry[index].crc; - st->size = za->cdir->entry[index].uncomp_size; - st->mtime = za->cdir->entry[index].last_mod; - st->comp_size = za->cdir->entry[index].comp_size; - st->comp_method = za->cdir->entry[index].comp_method; - if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) { - if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { + st->crc = de->crc; + st->size = de->uncomp_size; + st->mtime = de->last_mod; + st->comp_size = de->comp_size; + st->comp_method = (zip_uint16_t)de->comp_method; + if (de->bitflags & ZIP_GPBF_ENCRYPTED) { + if (de->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { /* XXX */ st->encryption_method = ZIP_EM_UNKNOWN; } diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c index 74e1ffd0b0dce..d17613bf5e7e8 100644 --- a/ext/zip/lib/zip_stat_init.c +++ b/ext/zip/lib/zip_stat_init.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_stat_init(struct zip_stat *st) { st->valid = 0; diff --git a/ext/zip/lib/zip_strerror.c b/ext/zip/lib/zip_strerror.c index ad23bafed6c62..9ebee144f908a 100644 --- a/ext/zip/lib/zip_strerror.c +++ b/ext/zip/lib/zip_strerror.c @@ -36,7 +36,8 @@ #include "zipint.h" -ZIP_EXTERN(const char *) + +ZIP_EXTERN const char * zip_strerror(struct zip *za) { return _zip_error_strerror(&za->error); diff --git a/ext/zip/lib/zip_string.c b/ext/zip/lib/zip_string.c new file mode 100644 index 0000000000000..a2d5eb5d3fdae --- /dev/null +++ b/ext/zip/lib/zip_string.c @@ -0,0 +1,196 @@ +/* + zip_string.c -- string handling (with encoding) + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include +#include + +#include "zipint.h" + + + +zip_uint32_t +_zip_string_crc32(const struct zip_string *s) +{ + zip_uint32_t crc; + + crc = (zip_uint32_t)crc32(0L, Z_NULL, 0); + + if (s != NULL) + crc = (zip_uint32_t)crc32(crc, s->raw, s->length); + + return crc; +} + + + +int +_zip_string_equal(const struct zip_string *a, const struct zip_string *b) +{ + if (a == NULL || b == NULL) + return a == b; + + if (a->length != b->length) + return 0; + + /* XXX: encoding */ + + return (memcmp(a->raw, b->raw, a->length) == 0); +} + + + +void +_zip_string_free(struct zip_string *s) +{ + if (s == NULL) + return; + + free(s->raw); + free(s->converted); + free(s); +} + + + +const zip_uint8_t * +_zip_string_get(struct zip_string *string, zip_uint32_t *lenp, zip_flags_t flags, struct zip_error *error) +{ + static const zip_uint8_t empty[1] = ""; + + if (string == NULL) { + if (lenp) + *lenp = 0; + return empty; + } + + if ((flags & ZIP_FL_ENC_RAW) == 0) { + /* start guessing */ + if (string->encoding == ZIP_ENCODING_UNKNOWN) + _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN); + + if (((flags & ZIP_FL_ENC_STRICT) + && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) + || (string->encoding == ZIP_ENCODING_CP437)) { + if (string->converted == NULL) { + if ((string->converted=_zip_cp437_to_utf8(string->raw, string->length, + &string->converted_length, error)) == NULL) + return NULL; + } + if (lenp) + *lenp = string->converted_length; + return string->converted; + } + } + + if (lenp) + *lenp = string->length; + return string->raw; +} + + + +zip_uint16_t +_zip_string_length(const struct zip_string *s) +{ + if (s == NULL) + return 0; + + return s->length; +} + + + +struct zip_string * +_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, struct zip_error *error) +{ + struct zip_string *s; + enum zip_encoding_type expected_encoding; + + if (length == 0) + return NULL; + + switch (flags & ZIP_FL_ENCODING_ALL) { + case ZIP_FL_ENC_GUESS: + expected_encoding = ZIP_ENCODING_UNKNOWN; + break; + case ZIP_FL_ENC_UTF_8: + expected_encoding = ZIP_ENCODING_UTF8_KNOWN; + break; + case ZIP_FL_ENC_CP437: + expected_encoding = ZIP_ENCODING_CP437; + break; + default: + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((s=(struct zip_string *)malloc(sizeof(*s))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((s->raw=(zip_uint8_t *)malloc(length+1)) == NULL) { + free(s); + return NULL; + } + + memcpy(s->raw, raw, length); + s->raw[length] = '\0'; + s->length = length; + s->encoding = ZIP_ENCODING_UNKNOWN; + s->converted = NULL; + s->converted_length = 0; + + if (expected_encoding != ZIP_ENCODING_UNKNOWN) { + if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) { + _zip_string_free(s); + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + } + + return s; +} + + + +void +_zip_string_write(const struct zip_string *s, FILE *f) +{ + if (s == NULL) + return; + + fwrite(s->raw, s->length, 1, f); +} diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c index 550e8b99031f2..5f0e753b78634 100644 --- a/ext/zip/lib/zip_unchange.c +++ b/ext/zip/lib/zip_unchange.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange(struct zip *za, zip_uint64_t idx) { return _zip_unchange(za, idx, 0); @@ -50,34 +50,23 @@ zip_unchange(struct zip *za, zip_uint64_t idx) int _zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates) { - int i; + zip_int64_t i; if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - if (za->entry[idx].ch_filename) { - if (!allow_duplicates) { - i = _zip_name_locate(za, - _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), - 0, NULL); - if (i != -1 && i != idx) { - _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); - return -1; - } + if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) { + i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), 0, NULL); + if (i >= 0 && (zip_uint64_t)i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; } - - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = NULL; } - free(za->entry[idx].ch_extra); - za->entry[idx].ch_extra = NULL; - za->entry[idx].ch_extra_len = -1; - free(za->entry[idx].ch_comment); - za->entry[idx].ch_comment = NULL; - za->entry[idx].ch_comment_len = -1; + _zip_dirent_free(za->entry[idx].changes); + za->entry[idx].changes = NULL; _zip_unchange_data(za->entry+idx); diff --git a/ext/zip/lib/zip_unchange_all.c b/ext/zip/lib/zip_unchange_all.c index 01282f89dbbaf..bbc2825eb6265 100644 --- a/ext/zip/lib/zip_unchange_all.c +++ b/ext/zip/lib/zip_unchange_all.c @@ -39,10 +39,11 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange_all(struct zip *za) { - int ret, i; + int ret; + zip_uint64_t i; ret = 0; for (i=0; inentry; i++) diff --git a/ext/zip/lib/zip_unchange_archive.c b/ext/zip/lib/zip_unchange_archive.c index ca2b67854435a..e24ee21727002 100644 --- a/ext/zip/lib/zip_unchange_archive.c +++ b/ext/zip/lib/zip_unchange_archive.c @@ -39,13 +39,15 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange_archive(struct zip *za) { - free(za->ch_comment); - za->ch_comment = NULL; - za->ch_comment_len = -1; - + if (za->comment_changed) { + _zip_string_free(za->comment_changes); + za->comment_changes = NULL; + za->comment_changed = 0; + } + za->ch_flags = za->flags; return 0; diff --git a/ext/zip/lib/zip_unchange_data.c b/ext/zip/lib/zip_unchange_data.c index 7dd93b768a87a..fa25feb03885f 100644 --- a/ext/zip/lib/zip_unchange_data.c +++ b/ext/zip/lib/zip_unchange_data.c @@ -1,8 +1,6 @@ /* - $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $ - zip_unchange_data.c -- undo helper function - Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,8 +33,6 @@ -#include - #include "zipint.h" void @@ -46,7 +42,15 @@ _zip_unchange_data(struct zip_entry *ze) zip_source_free(ze->source); ze->source = NULL; } - - ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; + + if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) { + ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; + if (ze->changes->changed == 0) { + _zip_dirent_free(ze->changes); + ze->changes = NULL; + } + } + + ze->deleted = 0; } diff --git a/ext/zip/lib/zip_utf-8.c b/ext/zip/lib/zip_utf-8.c new file mode 100644 index 0000000000000..c36fad13f5f45 --- /dev/null +++ b/ext/zip/lib/zip_utf-8.c @@ -0,0 +1,255 @@ +/* + zip_utf-8.c -- UTF-8 support functions for libzip + Copyright (C) 2011-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. +*/ + + + +#include "zipint.h" + +#include + + + +static const zip_uint16_t _cp437_to_unicode[256] = { + /* 0x00 - 0x0F */ + 0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + + /* 0x10 - 0x1F */ + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + + /* 0x20 - 0x2F */ + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + + /* 0x30 - 0x3F */ + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + + /* 0x40 - 0x4F */ + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + + /* 0x50 - 0x5F */ + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + + /* 0x60 - 0x6F */ + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + + /* 0x70 - 0x7F */ + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, + + /* 0x80 - 0x8F */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + + /* 0x90 - 0x9F */ + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + + /* 0xA0 - 0xAF */ + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + + /* 0xB0 - 0xBF */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + + /* 0xC0 - 0xCF */ + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + + /* 0xD0 - 0xDF */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + + /* 0xE0 - 0xEF */ + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + + /* 0xF0 - 0xFF */ + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#define UTF_8_LEN_2_MASK 0xe0 +#define UTF_8_LEN_2_MATCH 0xc0 +#define UTF_8_LEN_3_MASK 0xf0 +#define UTF_8_LEN_3_MATCH 0xe0 +#define UTF_8_LEN_4_MASK 0xf8 +#define UTF_8_LEN_4_MATCH 0xf0 +#define UTF_8_CONTINUE_MASK 0xc0 +#define UTF_8_CONTINUE_MATCH 0x80 + + + +enum zip_encoding_type +_zip_guess_encoding(struct zip_string *str, enum zip_encoding_type expected_encoding) +{ + enum zip_encoding_type enc; + const zip_uint8_t *name; + zip_uint32_t i, j, ulen; + + if (str == NULL) + return ZIP_ENCODING_ASCII; + + name = str->raw; + + if (str->encoding != ZIP_ENCODING_UNKNOWN) + enc = str->encoding; + else { + enc = ZIP_ENCODING_ASCII; + for (i=0; ilength; i++) { + if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t') + continue; + + enc = ZIP_ENCODING_UTF8_GUESSED; + if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH) + ulen = 1; + else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH) + ulen = 2; + else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH) + ulen = 3; + else { + enc = ZIP_ENCODING_CP437; + break; + } + + if (i + ulen >= str->length) { + enc = ZIP_ENCODING_CP437; + break; + } + + for (j=1; j<=ulen; j++) { + if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) { + enc = ZIP_ENCODING_CP437; + goto done; + } + } + i += ulen; + } + } + +done: + str->encoding = enc; + + if (expected_encoding != ZIP_ENCODING_UNKNOWN) { + if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED) + str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN; + + if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII) + return ZIP_ENCODING_ERROR; + } + + return enc; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8_len(zip_uint32_t codepoint) +{ + if (codepoint < 0x0080) + return 1; + if (codepoint < 0x0800) + return 2; + if (codepoint < 0x10000) + return 3; + return 4; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) +{ + if (codepoint < 0x0080) { + buf[0] = codepoint & 0xff; + return 1; + } + if (codepoint < 0x0800) { + buf[0] = UTF_8_LEN_2_MATCH | ((codepoint >> 6) & 0x1f); + buf[1] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 2; + } + if (codepoint < 0x10000) { + buf[0] = UTF_8_LEN_3_MATCH | ((codepoint >> 12) & 0x0f); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 3; + } + buf[0] = UTF_8_LEN_4_MATCH | ((codepoint >> 18) & 0x07); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 12) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[3] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 4; +} + + + +zip_uint8_t * +_zip_cp437_to_utf8(const zip_uint8_t * const _cp437buf, zip_uint32_t len, + zip_uint32_t *utf8_lenp, struct zip_error *error) +{ + zip_uint8_t *cp437buf = (zip_uint8_t *)_cp437buf; + zip_uint8_t *utf8buf; + zip_uint32_t buflen, i, offset; + + if (len == 0) { + if (utf8_lenp) + *utf8_lenp = 0; + return NULL; + } + + buflen = 1; + for (i=0; i -#include -#include -#include -#include - -#ifndef strcasecmp -# define strcmpi _strcmpi -#endif - -#ifndef ssize_t -# define ssize_t SSIZE_T -#endif - -#ifndef mode_t -# define mode_t int -#endif - -#ifndef snprintf -# define snprintf _snprintf -#endif - -#ifndef mkstemp -# define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE) -#endif -/* -#ifndef fseeko -# define fseeko fseek -#endif -*/ diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h index 2b4340c861c51..1cb5c0467aeb8 100644 --- a/ext/zip/lib/zipconf.h +++ b/ext/zip/lib/zipconf.h @@ -1,51 +1,129 @@ -#ifndef _HAD_ZIPCONF_H -#define _HAD_ZIPCONF_H - -/* - zipconf.h -- platform specific include file - - This file was generated automatically by ./make_zipconf.sh - based on ../config.h. - */ - -#define LIBZIP_VERSION "0.10.1" -#define LIBZIP_VERSION_MAJOR 0 -#define LIBZIP_VERSION_MINOR 10 -#define LIBZIP_VERSION_MICRO 0 - -#ifdef PHP_WIN32 -#include -#else -#include -#endif - -typedef int8_t zip_int8_t; -#define ZIP_INT8_MIN INT8_MIN -#define ZIP_INT8_MAX INT8_MAX - -typedef uint8_t zip_uint8_t; -#define ZIP_UINT8_MAX UINT8_MAX - -typedef int16_t zip_int16_t; -#define ZIP_INT16_MIN INT16_MIN -#define ZIP_INT16_MAX INT16_MAX - -typedef uint16_t zip_uint16_t; -#define ZIP_UINT16_MAX UINT16_MAX - -typedef int32_t zip_int32_t; -#define ZIP_INT32_MIN INT32_MIN -#define ZIP_INT32_MAX INT32_MAX - -typedef uint32_t zip_uint32_t; -#define ZIP_UINT32_MAX UINT32_MAX - -typedef int64_t zip_int64_t; -#define ZIP_INT64_MIN INT64_MIN -#define ZIP_INT64_MAX INT64_MAX - -typedef uint64_t zip_uint64_t; -#define ZIP_UINT64_MAX UINT64_MAX - - -#endif /* zipconf.h */ +#ifndef _HAD_ZIPCONF_H +#define _HAD_ZIPCONF_H + +/* + zipconf.h -- platform specific include file + + This file was generated automatically by CMake + based on ../cmake-zipconf.h.in. + */ +#define LIBZIP_VERSION "0.11.1" +/* #undef HAVE_INTTYPES_H_LIBZIP */ + +#if defined(_WIN32) +# if _MSC_VER > 1500 +# define HAVE_STDINT_H_LIBZIP +# else +# include "win32/php_stdint.h" +# endif +#else +# include +#endif +#define HAVE_SYS_TYPES_H_LIBZIP +#define HAVE___INT8_LIBZIP +#define HAVE_INT8_T_LIBZIP +#define HAVE_UINT8_T_LIBZIP +#define HAVE___INT16_LIBZIP +#define HAVE_INT16_T_LIBZIP +#define HAVE_UINT16_T_LIBZIP +#define HAVE___INT32_LIBZIP +#define HAVE_INT32_T_LIBZIP +#define HAVE_UINT32_T_LIBZIP +#define HAVE___INT64_LIBZIP +#define HAVE_INT64_T_LIBZIP +#define HAVE_UINT64_T_LIBZIP +#define SHORT_LIBZIP 2 +#define INT_LIBZIP 4 +#define LONG_LIBZIP 4 +#define LONG_LONG_LIBZIP 8 + +#if defined(HAVE_STDINT_H_LIBZIP) +#include +#elif defined(HAVE_INTTYPES_H_LIBZIP) +#include +#elif defined(HAVE_SYS_TYPES_H_LIBZIP) +#include +#endif + +#if defined(HAVE_INT8_T_LIBZIP) +typedef int8_t zip_int8_t; +#elif defined(HAVE___INT8_LIBZIP) +typedef __int8 zip_int8_t; +#else +typedef signed char zip_int8_t; +#endif +#if defined(HAVE_UINT8_T_LIBZIP) +typedef uint8_t zip_uint8_t; +#elif defined(HAVE___INT8_LIBZIP) +typedef unsigned __int8 zip_uint8_t; +#else +typedef unsigned char zip_uint8_t; +#endif +#if defined(HAVE_INT16_T_LIBZIP) +typedef int16_t zip_int16_t; +#elif defined(HAVE___INT16_LIBZIP) +typedef __int16 zip_int16_t; +#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 +typedef signed short zip_int16_t; +#endif +#if defined(HAVE_UINT16_T_LIBZIP) +typedef uint16_t zip_uint16_t; +#elif defined(HAVE___INT16_LIBZIP) +typedef unsigned __int16 zip_uint16_t; +#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 +typedef unsigned short zip_uint16_t; +#endif +#if defined(HAVE_INT32_T_LIBZIP) +typedef int32_t zip_int32_t; +#elif defined(HAVE___INT32_LIBZIP) +typedef __int32 zip_int32_t; +#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 +typedef signed int zip_int32_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 +typedef signed long zip_int32_t; +#endif +#if defined(HAVE_UINT32_T_LIBZIP) +typedef uint32_t zip_uint32_t; +#elif defined(HAVE___INT32_LIBZIP) +typedef unsigned __int32 zip_uint32_t; +#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 +typedef unsigned int zip_uint32_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 +typedef unsigned long zip_uint32_t; +#endif +#if defined(HAVE_INT64_T_LIBZIP) +typedef int64_t zip_int64_t; +#elif defined(HAVE___INT64_LIBZIP) +typedef __int64 zip_int64_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 8 +typedef signed long zip_int64_t; +#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef signed long long zip_int64_t; +#endif +#if defined(HAVE_UINT64_T_LIBZIP) +typedef uint64_t zip_uint64_t; +#elif defined(HAVE___INT64_LIBZIP) +typedef unsigned __int64 zip_uint64_t; +#elif defined(LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef unsigned long zip_uint64_t; +#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef unsigned long long zip_uint64_t; +#endif + +#define ZIP_INT8_MIN -0x80 +#define ZIP_INT8_MAX 0x7f +#define ZIP_UINT8_MAX 0xff + +#define ZIP_INT16_MIN -0x8000 +#define ZIP_INT16_MAX 0x7fff +#define ZIP_UINT16_MAX 0xffff + +#define ZIP_INT32_MIN -0x80000000L +#define ZIP_INT32_MAX 0x7fffffffL +#define ZIP_UINT32_MAX 0xffffffffLU + +#define ZIP_INT64_MIN -0x8000000000000000LL +#define ZIP_INT64_MAX 0x7fffffffffffffffLL +#define ZIP_UINT64_MAX 0xffffffffffffffffULL + +#endif /* zipconf.h */ diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index ea21dddcd4257..e8765c5b6619f 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -3,7 +3,7 @@ /* zipint.h -- internal declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -20,7 +20,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -34,69 +34,123 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +/* to have *_MAX definitions for all types when compiling with g++ */ +#define __STDC_LIMIT_MACROS -#include "zip.h" +#include -#ifndef HAVE_FSEEKO -#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) +#ifdef PHP_WIN32 +/* for dup(), close(), etc. */ +#include +#include "config.w32.h" #endif -#ifndef HAVE_FTELLO -#define ftello(s) ((long)ftell((s))) +#ifndef _ZIP_COMPILING_DEPRECATED +#define ZIP_DISABLE_DEPRECATED #endif -#ifndef PHP_WIN32 -#ifndef HAVE_MKSTEMP -int _zip_mkstemp(char *); -#define mkstemp _zip_mkstemp -#endif +#include "zip.h" +#ifdef PHP_WIN32 +# include "php_zip_config.w32.h" +#else +# include "config.h" #endif -#ifdef PHP_WIN32 +#if defined(HAVE_MOVEFILEEXA) && defined(_WIN32) #include -#include #define _zip_rename(s, t) \ - (!MoveFileExA((s), (t), \ - MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) + (!MoveFileExA((s), (t), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) +#else +#define _zip_rename rename +#endif -/* for dup(), close(), etc. */ -#include +#ifdef _WIN32 +#undef strcasecmp +# define strcasecmp _strcmpi +#endif -#if !defined(HAVE_OPEN) +#if defined(HAVE__CLOSE) +#define close _close +#endif +#if defined(HAVE__DUP) +#define dup _dup +#endif +/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */ +#if defined(HAVE__FDOPEN) +#define fdopen _fdopen +#endif +#if defined(HAVE__FILENO) +#define fileno _fileno +#endif +/* Windows' open() doesn't understand Unix permissions */ #if defined(HAVE__OPEN) #define open(a, b, c) _open((a), (b)) #endif +#if defined(HAVE__SNPRINTF) +#define snprintf _snprintf +#endif +#if defined(HAVE__STRDUP) && !defined(strdup) +#define strdup _strdup #endif -#else -#define _zip_rename rename +#ifndef HAVE_FSEEKO +#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) #endif -#ifndef strcasecmp -# define strcmpi strcasecmp +#ifndef HAVE_FTELLO +#define ftello(s) ((long)ftell((s))) #endif +#ifndef HAVE_MKSTEMP +int _zip_mkstemp(char *); +#define mkstemp _zip_mkstemp +#endif - +#if !defined(HAVE_STRCASECMP) +#if defined(HAVE__STRICMP) +#define strcasecmp _stricmp +#endif +#endif + +#if SIZEOF_OFF_T == 8 +#define ZIP_OFF_MAX ZIP_INT64_MAX +#elif SIZEOF_OFF_T == 4 +#define ZIP_OFF_MAX ZIP_INT32_MAX +#elif SIZEOF_OFF_T == 2 +#define ZIP_OFF_MAX ZIP_INT16_MAX +#else +#error unsupported size of off_t +#endif #define CENTRAL_MAGIC "PK\1\2" #define LOCAL_MAGIC "PK\3\4" #define EOCD_MAGIC "PK\5\6" #define DATADES_MAGIC "PK\7\8" +#define EOCD64LOC_MAGIC "PK\6\7" +#define EOCD64_MAGIC "PK\6\6" #define TORRENT_SIG "TORRENTZIPPED-" #define TORRENT_SIG_LEN 14 #define TORRENT_CRC_LEN 8 #define TORRENT_MEM_LEVEL 8 #define CDENTRYSIZE 46u #define LENTRYSIZE 30 -#undef MAXCOMLEN /* defined as 19 on BSD for max command name */ #define MAXCOMLEN 65536 #define MAXEXTLEN 65536 #define EOCDLEN 22 -#define CDBUFSIZE (MAXCOMLEN+EOCDLEN) +#define EOCD64LOCLEN 20 +#define EOCD64LEN 56 +#define CDBUFSIZE (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN) #define BUFSIZE 8192 +#define ZIP_CM_REPLACED_DEFAULT (-2) + +#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) + +#define ZIP_EF_UTF_8_COMMENT 0x6375 +#define ZIP_EF_UTF_8_NAME 0x7075 +#define ZIP_EF_ZIP64 0x0001 + +#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64) /* This section contains API that won't materialize like this. It's @@ -104,20 +158,22 @@ int _zip_mkstemp(char *); typedef struct zip_source *(*zip_compression_implementation)(struct zip *, struct zip_source *, - zip_uint16_t, int); + zip_int32_t, int); typedef struct zip_source *(*zip_encryption_implementation)(struct zip *, struct zip_source *, zip_uint16_t, int, const char *); -ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation( - zip_uint16_t); -ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation( - zip_uint16_t); +zip_compression_implementation _zip_get_compression_implementation(zip_int32_t); +zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t); +/* This API is not final yet, but we need it internally, so it's private for now. */ + +const zip_uint8_t *zip_get_extra_field_by_id(struct zip *, int, int, zip_uint16_t, int, zip_uint16_t *); + /* This section contains API that is of limited use until support for user-supplied compression/encryption implementation is finished. Thus we will keep it private for now. */ @@ -126,40 +182,37 @@ typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(void) zip_source_close(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *, - int); -ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *, - struct zip_source *, - zip_uint16_t, int); -ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *); -ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *, - struct zip_source *, - zip_source_layered_callback, - void *); -ZIP_EXTERN(int) zip_source_open(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *, - struct zip_source *, - zip_uint16_t, int, - const char *); -ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *, - zip_uint64_t); -ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *); +void zip_source_close(struct zip_source *); +struct zip_source *zip_source_crc(struct zip *, struct zip_source *, + int); +struct zip_source *zip_source_deflate(struct zip *, + struct zip_source *, + zip_int32_t, int); +void zip_source_error(struct zip_source *, int *, int *); +struct zip_source *zip_source_layered(struct zip *, + struct zip_source *, + zip_source_layered_callback, + void *); +int zip_source_open(struct zip_source *); +struct zip_source *zip_source_pkware(struct zip *, + struct zip_source *, + zip_uint16_t, int, + const char *); +zip_int64_t zip_source_read(struct zip_source *, void *, + zip_uint64_t); +int zip_source_stat(struct zip_source *, struct zip_stat *); +struct zip_source *zip_source_window(struct zip *, struct zip_source *, + zip_uint64_t, zip_uint64_t); /* This function will probably remain private. It is not needed to implement compression/encryption routines. (We should probably rename it to _zip_source_pop.) */ -ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *); +struct zip_source *zip_source_pop(struct zip_source *); -/* state of change of a file in zip archive */ - -enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, - ZIP_ST_ADDED, ZIP_ST_RENAMED }; - /* error source for layered sources */ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; @@ -169,6 +222,28 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; #define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ #define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ #define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ +#define ZIP_GPBF_ENCODING_UTF_8 0x0800 /* file name encoding is UTF-8 */ + + +/* extra fields */ +#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */ +#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ +#define ZIP_EF_BOTH (ZIP_EF_LOCAL|ZIP_EF_CENTRAL) /* include in both */ + +#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ + +#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS|ZIP_FL_ENC_CP437|ZIP_FL_ENC_UTF_8) + + +/* encoding type */ +enum zip_encoding_type { + ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ + ZIP_ENCODING_ASCII, /* plain ASCII */ + ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */ + ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */ + ZIP_ENCODING_CP437, /* Code Page 437 */ + ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */ +}; /* error information */ @@ -181,25 +256,29 @@ struct zip_error { /* zip archive, part of API */ struct zip { - char *zn; /* file name */ - FILE *zp; /* file */ - struct zip_error error; /* error information */ + char *zn; /* file name */ + FILE *zp; /* file */ + unsigned int open_flags; /* flags passed to zip_open */ + struct zip_error error; /* error information */ - unsigned int flags; /* archive global flags */ - unsigned int ch_flags; /* changed archive global flags */ - - char *default_password; /* password used when no other supplied */ - - struct zip_cdir *cdir; /* central directory */ - char *ch_comment; /* changed archive comment */ - int ch_comment_len; /* length of changed zip archive - * comment, -1 if unchanged */ - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - struct zip_entry *entry; /* entries */ - int nfile; /* number of opened files within archive */ - int nfile_alloc; /* number of files allocated */ - struct zip_file **file; /* opened files within archive */ + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ + + char *default_password; /* password used when no other supplied */ + + struct zip_string *comment_orig; /* archive comment */ + struct zip_string *comment_changes; /* changed archive comment */ + int comment_changed; /* whether archive comment was changed */ + + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ + struct zip_entry *entry; /* entries */ + + unsigned int nfile; /* number of opened files within archive */ + unsigned int nfile_alloc; /* number of files allocated */ + struct zip_file **file; /* opened files within archive */ + + char *tempdir; /* custom temp dir (needed e.g. for OS X sandboxing) */ }; /* file in zip archive, part of API */ @@ -213,37 +292,52 @@ struct zip_file { /* zip archive directory entry (central or local) */ +#define ZIP_DIRENT_COMP_METHOD 0x0001u +#define ZIP_DIRENT_FILENAME 0x0002u +#define ZIP_DIRENT_COMMENT 0x0004u +#define ZIP_DIRENT_EXTRA_FIELD 0x0008u +#define ZIP_DIRENT_ALL 0xffffu + struct zip_dirent { - unsigned short version_madeby; /* (c) version of creator */ - unsigned short version_needed; /* (cl) version needed to extract */ - unsigned short bitflags; /* (cl) general purpose bit flag */ - unsigned short comp_method; /* (cl) compression method used */ - time_t last_mod; /* (cl) time of last modification */ - unsigned int crc; /* (cl) CRC-32 of uncompressed data */ - unsigned int comp_size; /* (cl) size of commpressed data */ - unsigned int uncomp_size; /* (cl) size of uncommpressed data */ - char *filename; /* (cl) file name (NUL-terminated) */ - unsigned short filename_len; /* (cl) length of filename (w/o NUL) */ - char *extrafield; /* (cl) extra field */ - unsigned short extrafield_len; /* (cl) length of extra field */ - char *comment; /* (c) file comment */ - unsigned short comment_len; /* (c) length of file comment */ - unsigned short disk_number; /* (c) disk number start */ - unsigned short int_attrib; /* (c) internal file attributes */ - unsigned int ext_attrib; /* (c) external file attributes */ - unsigned int offset; /* (c) offset of local header */ + zip_uint32_t changed; + int local_extra_fields_read; /* whether we already read in local header extra fields */ + int cloned; /* wether this instance is cloned, and thus shares non-changed strings */ + + zip_uint16_t version_madeby; /* (c) version of creator */ + zip_uint16_t version_needed; /* (cl) version needed to extract */ + zip_uint16_t bitflags; /* (cl) general purpose bit flag */ + zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ + time_t last_mod; /* (cl) time of last modification */ + zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */ + zip_uint64_t comp_size; /* (cl) size of compressed data */ + zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */ + struct zip_string *filename; /* (cl) file name (NUL-terminated) */ + struct zip_extra_field *extra_fields; /* (cl) extra fields, parsed */ + struct zip_string *comment; /* (c) file comment */ + zip_uint32_t disk_number; /* (c) disk number start */ + zip_uint16_t int_attrib; /* (c) internal file attributes */ + zip_uint32_t ext_attrib; /* (c) external file attributes */ + zip_uint64_t offset; /* (c) offset of local header */ }; /* zip archive central directory */ struct zip_cdir { - struct zip_dirent *entry; /* directory entries */ - int nentry; /* number of entries */ + struct zip_entry *entry; /* directory entries */ + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ - unsigned int size; /* size of central direcotry */ - unsigned int offset; /* offset of central directory in file */ - char *comment; /* zip archive comment */ - unsigned short comment_len; /* length of zip archive comment */ + off_t size; /* size of central directory */ + off_t offset; /* offset of central directory in file */ + struct zip_string *comment; /* zip archive comment */ +}; + +struct zip_extra_field { + struct zip_extra_field *next; + zip_flags_t flags; /* in local/central header */ + zip_uint16_t id; /* header id */ + zip_uint16_t size; /* data size */ + zip_uint8_t *data; }; @@ -262,13 +356,31 @@ struct zip_source { /* entry in zip archive directory */ struct zip_entry { - enum zip_state state; + struct zip_dirent *orig; + struct zip_dirent *changes; struct zip_source *source; - char *ch_filename; - char *ch_extra; - int ch_extra_len; - char *ch_comment; - int ch_comment_len; + int deleted; +}; + + + +/* file or archive comment, or filename */ + +struct zip_string { + zip_uint8_t *raw; /* raw string */ + zip_uint16_t length; /* length of raw string */ + enum zip_encoding_type encoding; /* autorecognized encoding */ + zip_uint8_t *converted; /* autoconverted string */ + zip_uint32_t converted_length; /* length of converted */ +}; + + + +/* which files to write, and in which order (name is for torrentzip sorting) */ + +struct zip_filelist { + zip_uint64_t idx; + const char *name; }; @@ -279,66 +391,111 @@ extern const int _zip_err_type[]; -#define ZIP_ENTRY_DATA_CHANGED(x) \ - ((x)->state == ZIP_ST_REPLACED \ - || (x)->state == ZIP_ST_ADDED) +#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f))) + +#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL) #define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) +zip_int64_t _zip_add_entry(struct zip *); + int _zip_cdir_compute_crc(struct zip *, uLong *); void _zip_cdir_free(struct zip_cdir *); -int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *); -struct zip_cdir *_zip_cdir_new(int, struct zip_error *); -int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); +int _zip_cdir_grow(struct zip_cdir *, zip_uint64_t, struct zip_error *); +struct zip_cdir *_zip_cdir_new(zip_uint64_t, struct zip_error *); +zip_int64_t _zip_cdir_write(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *); +struct zip_dirent *_zip_dirent_clone(const struct zip_dirent *); +void _zip_dirent_free(struct zip_dirent *); void _zip_dirent_finalize(struct zip_dirent *); void _zip_dirent_init(struct zip_dirent *); -int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **, - zip_uint32_t *, int, struct zip_error *); +int _zip_dirent_needs_zip64(const struct zip_dirent *, zip_flags_t); +struct zip_dirent *_zip_dirent_new(void); +int _zip_dirent_read(struct zip_dirent *, FILE *, const unsigned char **, + zip_uint64_t *, int, struct zip_error *); +zip_int32_t _zip_dirent_size(FILE *, zip_uint16_t, struct zip_error *); void _zip_dirent_torrent_normalize(struct zip_dirent *); -int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); - -void _zip_entry_free(struct zip_entry *); -void _zip_entry_init(struct zip *, int); -struct zip_entry *_zip_entry_new(struct zip *); +int _zip_dirent_write(struct zip_dirent *, FILE *, zip_flags_t, struct zip_error *); + +struct zip_extra_field *_zip_ef_clone(const struct zip_extra_field *, struct zip_error *); +struct zip_extra_field *_zip_ef_delete_by_id(struct zip_extra_field *, zip_uint16_t, zip_uint16_t, zip_flags_t); +void _zip_ef_free(struct zip_extra_field *); +const zip_uint8_t *_zip_ef_get_by_id(const struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, struct zip_error *); +struct zip_extra_field *_zip_ef_merge(struct zip_extra_field *, struct zip_extra_field *); +struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t); +struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *); +struct zip_extra_field *_zip_ef_remove_internal(struct zip_extra_field *); +zip_uint16_t _zip_ef_size(const struct zip_extra_field *, zip_flags_t); +void _zip_ef_write(const struct zip_extra_field *, zip_flags_t, FILE *); + +void _zip_entry_finalize(struct zip_entry *); +void _zip_entry_init(struct zip_entry *); void _zip_error_clear(struct zip_error *); -void _zip_error_copy(struct zip_error *, struct zip_error *); +void _zip_error_copy(struct zip_error *, const struct zip_error *); void _zip_error_fini(struct zip_error *); -void _zip_error_get(struct zip_error *, int *, int *); +void _zip_error_get(const struct zip_error *, int *, int *); void _zip_error_init(struct zip_error *); void _zip_error_set(struct zip_error *, int, int); void _zip_error_set_from_source(struct zip_error *, struct zip_source *); const char *_zip_error_strerror(struct zip_error *); +const zip_uint8_t *_zip_extract_extra_field_by_id(struct zip_error *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *); + +int _zip_file_extra_field_prepare_for_change(struct zip *, zip_uint64_t); int _zip_file_fillbuf(void *, size_t, struct zip_file *); -unsigned int _zip_file_get_offset(struct zip *, int); +zip_uint64_t _zip_file_get_offset(const struct zip *, zip_uint64_t, struct zip_error *); int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); -struct zip *_zip_open(const char *, FILE *, int, int, int *); +struct zip_dirent *_zip_get_dirent(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *); + +enum zip_encoding_type _zip_guess_encoding(struct zip_string *, enum zip_encoding_type); +zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t * const, zip_uint32_t, + zip_uint32_t *, struct zip_error *error); + +struct zip *_zip_open(const char *, FILE *, unsigned int, int *); + +int _zip_read_local_ef(struct zip *, zip_uint64_t); struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, zip_uint64_t, zip_int64_t, int, const struct zip_stat *); struct zip_source *_zip_source_new(struct zip *); - -int _zip_changed(struct zip *, int *); -void _zip_free(struct zip *); -const char *_zip_get_name(struct zip *, zip_uint64_t, int, struct zip_error *); +struct zip_source *_zip_source_zip_new(struct zip *, struct zip *, zip_uint64_t, zip_flags_t, + zip_uint64_t, zip_uint64_t, const char *); + +int _zip_string_equal(const struct zip_string *, const struct zip_string *); +void _zip_string_free(struct zip_string *); +zip_uint32_t _zip_string_crc32(const struct zip_string *); +const zip_uint8_t *_zip_string_get(struct zip_string *, zip_uint32_t *, zip_flags_t, struct zip_error *); +zip_uint16_t _zip_string_length(const struct zip_string *); +struct zip_string *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *); +void _zip_string_write(const struct zip_string *, FILE *); + +int _zip_changed(const struct zip *, zip_uint64_t *); +const char *_zip_get_name(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *); int _zip_local_header_read(struct zip *, int); void *_zip_memdup(const void *, size_t, struct zip_error *); -int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); +zip_int64_t _zip_name_locate(struct zip *, const char *, zip_flags_t, struct zip_error *); struct zip *_zip_new(struct zip_error *); -unsigned short _zip_read2(unsigned char **); -unsigned int _zip_read4(unsigned char **); -zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *, - struct zip_source *); -int _zip_set_name(struct zip *, zip_uint64_t, const char *); -void _zip_u2d_time(time_t, unsigned short *, unsigned short *); +zip_uint16_t _zip_read2(const zip_uint8_t **); +zip_uint32_t _zip_read4(const zip_uint8_t **); +zip_uint64_t _zip_read8(const zip_uint8_t **); +zip_uint8_t *_zip_read_data(const zip_uint8_t **, FILE *, size_t, int, struct zip_error *); +zip_int64_t _zip_file_replace(struct zip *, zip_uint64_t, const char *, struct zip_source *, zip_flags_t); +int _zip_set_name(struct zip *, zip_uint64_t, const char *, zip_flags_t); +void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *); int _zip_unchange(struct zip *, zip_uint64_t, int); void _zip_unchange_data(struct zip_entry *); +void _zip_poke4(zip_uint32_t, zip_uint8_t **); +void _zip_poke8(zip_uint64_t, zip_uint8_t **); +void _zip_write2(zip_uint16_t, FILE *); +void _zip_write4(zip_uint32_t, FILE *); +void _zip_write8(zip_uint64_t, FILE *); + + #endif /* zipint.h */ diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index d3ec27bafeaf3..cd1d7cd425f74 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -30,8 +30,6 @@ #include "ext/pcre/php_pcre.h" #include "ext/standard/php_filestat.h" #include "php_zip.h" -#include "lib/zip.h" -#include "lib/zipint.h" /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */ static PHP_NAMED_FUNCTION(zif_zip_open); @@ -53,6 +51,24 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_close); #endif #endif +#if PHP_VERSION_ID < 50400 +#define ARG_PATH "s" +#define KEY_ARG_DC +#define KEY_ARG_CC +#else +#define ARG_PATH "p" +#define KEY_ARG_DC , const zend_literal *key +#define KEY_ARG_CC , key +#endif + +#if PHP_VERSION_ID < 50500 +#define TYPE_ARG_DC +#define TYPE_ARG_CC +#else +#define TYPE_ARG_DC , int type +#define TYPE_ARG_CC , type +#endif + /* {{{ Resource le */ static int le_zip_dir; #define le_zip_dir_name "Zip Directory" @@ -154,7 +170,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil size_t path_cleaned_len; cwd_state new_state; - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); new_state.cwd[0] = '\0'; new_state.cwd_length = 0; @@ -191,7 +207,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } } @@ -215,7 +231,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(file_dirname_fullpath); if (!is_dir_only) { efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); } return 0; } @@ -224,7 +240,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil /* it is a standalone directory, job done */ if (is_dir_only) { efree(file_dirname_fullpath); - free(new_state.cwd); + efree(new_state.cwd); return 1; } @@ -232,13 +248,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (!len) { efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } else if (len > MAXPATHLEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } @@ -250,7 +266,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } @@ -285,7 +301,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_basename); efree(file_dirname_fullpath); - free(new_state.cwd); + efree(new_state.cwd); if (n<0) { return 0; @@ -299,7 +315,6 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */ { struct zip_source *zs; - int cur_idx; char resolved_path[MAXPATHLEN]; zval exists_flag; @@ -321,25 +336,11 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam if (!zs) { return -1; } - - cur_idx = zip_name_locate(za, (const char *)entry_name, 0); - /* TODO: fix _zip_replace */ - if (cur_idx<0) { - /* reset the error */ - if (za->error.str) { - _zip_error_fini(&za->error); - } - _zip_error_init(&za->error); - } else { - if (zip_delete(za, cur_idx) == -1) { - zip_source_free(zs); - return -1; - } - } - - if (zip_add(za, entry_name, zs) == -1) { + if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) { + zip_source_free(zs); return -1; } else { + zip_error_clear(za); return 1; } } @@ -417,7 +418,7 @@ static int php_zip_parse_options(zval *options, long *remove_all_path, ze_zip_object *obj = (ze_zip_object*) zend_object_store_get_object(object TSRMLS_CC); \ intern = obj->za; \ if (!intern) { \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized Zip object"); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or uninitialized Zip object"); \ RETURN_FALSE; \ } \ } @@ -780,7 +781,11 @@ static const zend_function_entry zip_functions[] = { PHP_FE(zip_entry_name, arginfo_zip_entry_name) PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize) PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod) +#ifdef PHP_FE_END PHP_FE_END +#else + {NULL,NULL,NULL} +#endif }; /* }}} */ @@ -869,7 +874,7 @@ static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zv } /* }}} */ -static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member TYPE_ARG_DC KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -884,24 +889,27 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == FAILURE) { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC); + retval = std_hnd->get_property_ptr_ptr(object, member TYPE_ARG_CC KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -911,7 +919,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, } /* }}} */ -static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval* php_zip_read_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -925,18 +933,21 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == SUCCESS) { @@ -949,7 +960,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z } } else { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->read_property(object, member, type, key TSRMLS_CC); + retval = std_hnd->read_property(object, member, type KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -959,7 +970,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z } /* }}} */ -static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static int php_zip_has_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -972,18 +983,21 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == SUCCESS) { @@ -1005,7 +1019,7 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend zval_ptr_dtor(&tmp); } else { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->has_property(object, member, type, key TSRMLS_CC); + retval = std_hnd->has_property(object, member, type KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -1059,7 +1073,8 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */ } if (intern->za) { if (zip_close(intern->za) != 0) { - _zip_free(intern->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context"); + return; } intern->za = NULL; } @@ -1096,6 +1111,9 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { +#if PHP_VERSION_ID < 50400 + zval *tmp; +#endif ze_zip_object *intern; zend_object_value retval; @@ -1116,8 +1134,13 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_ intern->zo.ce = class_type; #endif - object_properties_init(&intern->zo, class_type); +#if PHP_VERSION_ID < 50400 + zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, + (void *) &tmp, sizeof(zval *)); +#else + object_properties_init(&intern->zo, class_type); +#endif retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_zip_object_free_storage, @@ -1140,7 +1163,7 @@ static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC) if (zip_int) { if (zip_int->za) { if (zip_close(zip_int->za) != 0) { - _zip_free(zip_int->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context"); } zip_int->za = NULL; } @@ -1159,13 +1182,7 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) if (zr_rsrc) { if (zr_rsrc->zf) { - if (zr_rsrc->zf->za) { - zip_fclose(zr_rsrc->zf); - } else { - if (zr_rsrc->zf->src) - zip_source_free(zr_rsrc->zf->src); - free(zr_rsrc->zf); - } + zip_fclose(zr_rsrc->zf); zr_rsrc->zf = NULL; } efree(zr_rsrc); @@ -1195,7 +1212,7 @@ zend_module_entry zip_module_entry = { NULL, NULL, PHP_MINFO(zip), - PHP_ZIP_VERSION_STRING, + PHP_ZIP_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -1215,7 +1232,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open) zip_rsrc *rsrc_int; int err = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) { return; } @@ -1498,7 +1515,7 @@ static ZIPARCHIVE_METHOD(open) zval *this = getThis(); ze_zip_object *ze_obj = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &filename, &filename_len, &flags) == FAILURE) { return; } @@ -1523,7 +1540,8 @@ static ZIPARCHIVE_METHOD(open) if (ze_obj->za) { /* we already have an opened zip, free it */ if (zip_close(ze_obj->za) != 0) { - _zip_free(ze_obj->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source"); + RETURN_FALSE; } ze_obj->za = NULL; } @@ -1543,6 +1561,38 @@ static ZIPARCHIVE_METHOD(open) } /* }}} */ +/* {{{ proto resource ZipArchive::setPassword(string password) +Set the password for the active archive */ +static ZIPARCHIVE_METHOD(setPassword) +{ + struct zip *intern; + zval *this = getThis(); + char *password; + int password_len; + + if (!this) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, this); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &password, &password_len) == FAILURE) { + return; + } + + if (password_len < 1) { + RETURN_FALSE; + } else { + int res = zip_set_default_password(intern, (const char *)password); + if (res == 0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } + } +} +/* }}} */ + /* {{{ proto bool ZipArchive::close() close the zip archive */ static ZIPARCHIVE_METHOD(close) @@ -1552,7 +1602,7 @@ static ZIPARCHIVE_METHOD(close) ze_zip_object *ze_obj; if (!this) { - RETURN_FALSE; + RETURN_FALSE; } ZIP_FROM_OBJECT(intern, this); @@ -1560,7 +1610,7 @@ static ZIPARCHIVE_METHOD(close) ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC); if (zip_close(intern)) { - RETURN_FALSE; + zip_discard(intern); } efree(ze_obj->filename); @@ -1637,6 +1687,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir) if (zip_add_dir(intern, (const char *)s) == -1) { RETVAL_FALSE; } + zip_error_clear(intern); RETVAL_TRUE; } @@ -1654,7 +1705,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* char *path = NULL; char *remove_path = NULL; char *add_path = NULL; - int pattern_len, add_path_len = 0, remove_path_len = 0, path_len = 0; + int pattern_len, add_path_len, remove_path_len = 0, path_len = 0; long remove_all_path = 0; long flags = 0; zval *options = NULL; @@ -1667,12 +1718,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* ZIP_FROM_OBJECT(intern, this); /* 1 == glob, 2==pcre */ if (type == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|la", &pattern, &pattern_len, &flags, &options) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sa", &pattern, &pattern_len, &path, &path_len, &options) == FAILURE) { return; } @@ -1703,13 +1754,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* zval **zval_file = NULL; for (i = 0; i < found; i++) { - char *file, *file_stripped, *entry_name; + char *file_stripped, *entry_name; size_t entry_name_len, file_stripped_len; char entry_name_buf[MAXPATHLEN]; char *basename = NULL; if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) { - file = Z_STRVAL_PP(zval_file); if (remove_all_path) { php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0, &basename, (size_t *)&file_stripped_len TSRMLS_CC); @@ -1786,7 +1836,7 @@ static ZIPARCHIVE_METHOD(addFile) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sll", &filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) { return; } @@ -1856,16 +1906,18 @@ static ZIPARCHIVE_METHOD(addFromString) /* TODO: fix _zip_replace */ if (cur_idx >= 0) { if (zip_delete(intern, cur_idx) == -1) { - goto fail; + zip_source_free(zs); + RETURN_FALSE; } } - if (zip_add(intern, name, zs) != -1) { + if (zip_add(intern, name, zs) == -1) { + zip_source_free(zs); + RETURN_FALSE; + } else { + zip_error_clear(intern); RETURN_TRUE; } -fail: - zip_source_free(zs); - RETURN_FALSE; } /* }}} */ @@ -1886,7 +1938,7 @@ static ZIPARCHIVE_METHOD(statName) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &name, &name_len, &flags) == FAILURE) { return; } @@ -1942,7 +1994,7 @@ static ZIPARCHIVE_METHOD(locateName) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &name, &name_len, &flags) == FAILURE) { return; } @@ -2522,7 +2574,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ ZIP_FROM_OBJECT(intern, this); if (type == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|ll", &filename, &filename_len, &len, &flags) == FAILURE) { return; } PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb); @@ -2598,7 +2650,7 @@ static ZIPARCHIVE_METHOD(getStream) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) { return; } @@ -2621,6 +2673,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0) ZEND_END_ARG_INFO() @@ -2733,6 +2789,7 @@ ZEND_END_ARG_INFO() /* {{{ ze_zip_object_class_functions */ static const zend_function_entry zip_class_functions[] = { ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC) + ZIPARCHIVE_ME(setPassword, arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC) @@ -2875,7 +2932,7 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_row(2, "Zip", "enabled"); php_info_print_table_row(2, "Extension Version","$Id$"); - php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING); + php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION); php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION); php_info_print_table_end(); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 7dd9ff09d0b51..c8da941b7a82d 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -28,9 +28,17 @@ extern zend_module_entry zip_module_entry; #include "TSRM.h" #endif +#if defined(HAVE_LIBZIP) +#include +#else #include "lib/zip.h" +#endif -#define PHP_ZIP_VERSION_STRING "1.11.0" +#ifndef ZIP_OVERWRITE +#define ZIP_OVERWRITE ZIP_TRUNCATE +#endif + +#define PHP_ZIP_VERSION "1.12.3" #if ((PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6) # define PHP_ZIP_USE_OO 1 @@ -67,8 +75,9 @@ typedef struct _ze_zip_read_rsrc { } zip_read_rsrc; #ifdef PHP_ZIP_USE_OO -#define ZIPARCHIVE_ME(name, arg_info, flags) ZEND_FENTRY(name, c_ziparchive_ ##name, arg_info, flags) -#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_##name) +#define ZIPARCHIVE_ME(name, arg_info, flags) {#name, c_ziparchive_ ##name, arg_info,(zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags }, +#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_ ##name) + /* Extends zend object */ typedef struct _ze_zip_object { @@ -81,8 +90,8 @@ typedef struct _ze_zip_object { int filename_len; } ze_zip_object; -php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_DC TSRMLS_DC); +php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +php_stream *php_stream_zip_open(const char *filename, const char *path, const char *mode STREAMS_DC TSRMLS_DC); extern php_stream_wrapper php_stream_zip_wrapper; #endif diff --git a/ext/zip/tests/bug38943.inc b/ext/zip/tests/bug38943.inc new file mode 100644 index 0000000000000..a6f45e8294eff --- /dev/null +++ b/ext/zip/tests/bug38943.inc @@ -0,0 +1,16 @@ +testarray[] = 1; + var_dump($this->testarray); + } +} + +$z = new myZip; +$z->testp = "foobar"; +var_dump($z); + diff --git a/ext/zip/tests/bug38943_2.phpt b/ext/zip/tests/bug38943_2.phpt new file mode 100644 index 0000000000000..bdbad94517cc9 --- /dev/null +++ b/ext/zip/tests/bug38943_2.phpt @@ -0,0 +1,38 @@ +--TEST-- +#38943, properties in extended class cannot be set (5.3) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + int(1) +} +object(myZip)#1 (%d) { + ["test":"myZip":private]=> + int(0) + ["testp"]=> + string(6) "foobar" + ["testarray":"myZip":private]=> + array(1) { + [0]=> + int(1) + } + ["status"]=> + int(0) + ["statusSys"]=> + int(0) + ["numFiles"]=> + int(0) + ["filename"]=> + string(0) "" + ["comment"]=> + string(0) "" +} diff --git a/ext/zip/tests/doubleclose.phpt b/ext/zip/tests/doubleclose.phpt new file mode 100644 index 0000000000000..abc62c8434789 --- /dev/null +++ b/ext/zip/tests/doubleclose.phpt @@ -0,0 +1,43 @@ +--TEST-- +close() called twice +--SKIPIF-- + +--FILE-- +open(dirname(__FILE__) . '/test.zip')) { + die('Failure'); +} +if ($zip->status == ZIPARCHIVE::ER_OK) { + var_dump($zip->close()); + var_dump($zip->close()); +} else { + die("Failure"); +} + +?> +Done +--EXPECTF-- +Procedural +NULL + +Warning: zip_close(): %i is not a valid Zip Directory resource in %s +bool(false) +Object +bool(true) + +Warning: ZipArchive::close(): Invalid or uninitialized Zip object in %s +bool(false) +Done diff --git a/ext/zip/tests/zip_entry_close.phpt b/ext/zip/tests/zip_entry_close.phpt new file mode 100644 index 0000000000000..82b7819054f49 --- /dev/null +++ b/ext/zip/tests/zip_entry_close.phpt @@ -0,0 +1,24 @@ +--TEST-- +zip_entry_close() function: simple and double call +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +entry_open: bool(true) +entry_close: bool(true) +entry_close: +Warning: zip_entry_close(): %d is not a valid Zip Entry resource in %s +bool(false) +Done diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index 400edd6e6c0b9..02fbc70f85e60 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -1,3 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 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_01.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: Piere-Alain Joye | + +----------------------------------------------------------------------+ +*/ + /* $Id$ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -6,8 +24,6 @@ #if HAVE_ZIP #ifdef ZEND_ENGINE_2 -#include "lib/zip.h" - #include "php_streams.h" #include "ext/standard/file.h" #include "ext/standard/php_string.h" @@ -185,7 +201,7 @@ php_stream_ops php_stream_zipio_ops = { }; /* {{{ php_stream_zip_open */ -php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_DC TSRMLS_DC) +php_stream *php_stream_zip_open(const char *filename, const char *path, const char *mode STREAMS_DC TSRMLS_DC) { struct zip_file *zf = NULL; int err = 0; @@ -235,8 +251,8 @@ php_stream *php_stream_zip_open(char *filename, char *path, char *mode STREAMS_D /* {{{ php_stream_zip_opener */ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper, - char *path, - char *mode, + const char *path, + const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) diff --git a/ext/zlib/php_zlib.h b/ext/zlib/php_zlib.h index 6b1d0cd80c510..3e4b9381e7c81 100644 --- a/ext/zlib/php_zlib.h +++ b/ext/zlib/php_zlib.h @@ -58,7 +58,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zlib) zend_bool handler_registered; ZEND_END_MODULE_GLOBALS(zlib); -php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); extern php_stream_ops php_stream_gzio_ops; extern php_stream_wrapper php_stream_gzip_wrapper; extern php_stream_filter_factory php_zlib_filter_factory; diff --git a/ext/zlib/tests/bug65391.phpt b/ext/zlib/tests/bug65391.phpt index 3ba5350810f55..439473fc5d0f2 100644 --- a/ext/zlib/tests/bug65391.phpt +++ b/ext/zlib/tests/bug65391.phpt @@ -25,4 +25,3 @@ Array [2] => Vary: Accept-Encoding ) Done - diff --git a/ext/zlib/tests/gzseek_basic2.phpt b/ext/zlib/tests/gzseek_basic2.phpt index a815b8ff4173b..82d305d0fb419 100644 --- a/ext/zlib/tests/gzseek_basic2.phpt +++ b/ext/zlib/tests/gzseek_basic2.phpt @@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) { ?> --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- post_handler(SG(request_info).content_type_dup, arg TSRMLS_CC); - if (SG(request_info).post_data) { - efree(SG(request_info).post_data); - SG(request_info).post_data = NULL; - } efree(SG(request_info).content_type_dup); SG(request_info).content_type_dup = NULL; } @@ -249,39 +241,63 @@ static void sapi_read_post_data(TSRMLS_D) } } - -SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) +SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC) { int read_bytes; - int allocated_bytes=SAPI_POST_BLOCK_SIZE+1; + if (!sapi_module.read_post) { + return -1; + } + + read_bytes = sapi_module.read_post(buffer, buflen TSRMLS_CC); + + if (read_bytes > 0) { + /* gogo */ + SG(read_post_bytes) += read_bytes; + } + if (read_bytes < buflen) { + /* done */ + SG(post_read) = 1; + } + + return read_bytes; +} + +SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) +{ if ((SG(post_max_size) > 0) && (SG(request_info).content_length > SG(post_max_size))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); return; } - SG(request_info).post_data = emalloc(allocated_bytes); - for (;;) { - read_bytes = sapi_module.read_post(SG(request_info).post_data+SG(read_post_bytes), SAPI_POST_BLOCK_SIZE TSRMLS_CC); - if (read_bytes<=0) { - break; - } - SG(read_post_bytes) += read_bytes; - if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Actual POST length does not match Content-Length, and exceeds %ld bytes", SG(post_max_size)); - break; - } - if (read_bytes < SAPI_POST_BLOCK_SIZE) { - break; - } - if (SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE >= allocated_bytes) { - allocated_bytes = SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE+1; - SG(request_info).post_data = erealloc(SG(request_info).post_data, allocated_bytes); + + SG(request_info).request_body = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE); + + if (sapi_module.read_post) { + int read_bytes; + + for (;;) { + char buffer[SAPI_POST_BLOCK_SIZE]; + + read_bytes = sapi_read_post_block(buffer, SAPI_POST_BLOCK_SIZE TSRMLS_CC); + + if (read_bytes > 0) { + php_stream_write(SG(request_info).request_body, buffer, read_bytes); + } + + if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Actual POST length does not match Content-Length, and exceeds %ld bytes", SG(post_max_size)); + break; + } + + if (read_bytes < SAPI_POST_BLOCK_SIZE) { + /* done */ + break; + } } + php_stream_rewind(SG(request_info).request_body); } - SG(request_info).post_data[SG(read_post_bytes)] = 0; /* terminating NULL */ - SG(request_info).post_data_length = SG(read_post_bytes); } @@ -387,8 +403,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) SG(sapi_headers).http_status_line = NULL; SG(sapi_headers).mimetype = NULL; SG(read_post_bytes) = 0; - SG(request_info).post_data = NULL; - SG(request_info).raw_post_data = NULL; + SG(request_info).request_body = NULL; SG(request_info).current_user = NULL; SG(request_info).current_user_length = 0; SG(request_info).no_headers = 0; @@ -433,8 +448,7 @@ SAPI_API void sapi_activate(TSRMLS_D) SG(callback_run) = 0; SG(callback_func) = NULL; SG(read_post_bytes) = 0; - SG(request_info).post_data = NULL; - SG(request_info).raw_post_data = NULL; + SG(request_info).request_body = NULL; SG(request_info).current_user = NULL; SG(request_info).current_user_length = 0; SG(request_info).no_headers = 0; @@ -452,20 +466,13 @@ SAPI_API void sapi_activate(TSRMLS_D) /* Handle request method */ if (SG(server_context)) { - if (PG(enable_post_data_reading) && SG(request_info).request_method) { - if (SG(request_info).content_type && !strcmp(SG(request_info).request_method, "POST")) { - /* HTTP POST may contain form data to be processed into variables - * depending on given content type */ - sapi_read_post_data(TSRMLS_C); - } else { - /* Any other method with content payload will fill $HTTP_RAW_POST_DATA - * if it is enabled by always_populate_raw_post_data. - * It's up to the webserver to decide whether to allow a method or not. */ - SG(request_info).content_type_dup = NULL; - if (sapi_module.default_post_reader) { - sapi_module.default_post_reader(TSRMLS_C); - } - } + if (PG(enable_post_data_reading) + && SG(request_info).content_type + && SG(request_info).request_method + && !strcmp(SG(request_info).request_method, "POST")) { + /* HTTP POST may contain form data to be processed into variables + * depending on given content type */ + sapi_read_post_data(TSRMLS_C); } else { SG(request_info).content_type_dup = NULL; } @@ -494,22 +501,19 @@ static void sapi_send_headers_free(TSRMLS_D) SAPI_API void sapi_deactivate(TSRMLS_D) { zend_llist_destroy(&SG(sapi_headers).headers); - if (SG(request_info).post_data) { - efree(SG(request_info).post_data); - } else if (SG(server_context)) { - if(sapi_module.read_post) { + if (SG(request_info).request_body) { + SG(request_info).request_body = NULL; + } else if (SG(server_context)) { + if (!SG(post_read)) { /* make sure we've consumed all request input data */ char dummy[SAPI_POST_BLOCK_SIZE]; int read_bytes; - while((read_bytes = sapi_module.read_post(dummy, sizeof(dummy)-1 TSRMLS_CC)) > 0) { - SG(read_post_bytes) += read_bytes; - } + do { + read_bytes = sapi_read_post_block(dummy, SAPI_POST_BLOCK_SIZE TSRMLS_CC); + } while (SAPI_POST_BLOCK_SIZE == read_bytes); } } - if (SG(request_info).raw_post_data) { - efree(SG(request_info).raw_post_data); - } if (SG(request_info).auth_user) { efree(SG(request_info).auth_user); } diff --git a/main/SAPI.h b/main/SAPI.h index 92b7329dbc16c..928fca95da72e 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -27,12 +27,12 @@ #include "zend_operators.h" #ifdef PHP_WIN32 #include "win95nt.h" +#include "win32/php_stdint.h" #endif #include #define SAPI_OPTION_NO_CHDIR 1 - -#define SAPI_POST_BLOCK_SIZE 4000 +#define SAPI_POST_BLOCK_SIZE 0x4000 #ifdef PHP_WIN32 # ifdef SAPI_EXPORTS @@ -79,14 +79,15 @@ END_EXTERN_C() typedef struct { const char *request_method; char *query_string; - char *post_data, *raw_post_data; char *cookie_data; long content_length; - uint post_data_length, raw_post_data_length; char *path_translated; char *request_uri; + /* Do not use request_body directly, but the php://input stream wrapper instead */ + struct _php_stream *request_body; + const char *content_type; zend_bool headers_only; @@ -119,7 +120,8 @@ typedef struct _sapi_globals_struct { void *server_context; sapi_request_info request_info; sapi_headers_struct sapi_headers; - int read_post_bytes; + int64_t read_post_bytes; + unsigned char post_read; unsigned char headers_sent; struct stat global_stat; char *default_mimetype; @@ -188,7 +190,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo SAPI_API int sapi_send_headers(TSRMLS_D); SAPI_API void sapi_free_header(sapi_header_struct *sapi_header); SAPI_API void sapi_handle_post(void *arg TSRMLS_DC); - +SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC); SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry TSRMLS_DC); SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC); SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC); diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 9b8645a061e7e..6722798598af5 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -475,7 +475,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c char resolved_path[MAXPATHLEN]; char trypath[MAXPATHLEN]; const char *ptr, *end, *p; - char *actual_path; + const char *actual_path; php_stream_wrapper *wrapper; if (!filename || CHECK_NULL_PATH(filename, filename_length)) { @@ -791,11 +791,11 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co } } - new_state.cwd = strdup(cwd); + new_state.cwd = estrdup(cwd); new_state.cwd_length = strlen(cwd); if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode TSRMLS_CC)) { - free(new_state.cwd); + efree(new_state.cwd); return NULL; } @@ -806,7 +806,7 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co } else { real_path = estrndup(new_state.cwd, new_state.cwd_length); } - free(new_state.cwd); + efree(new_state.cwd); return real_path; } diff --git a/main/main.c b/main/main.c index 5942b23f729a1..f2bf878426cb0 100644 --- a/main/main.c +++ b/main/main.c @@ -562,7 +562,6 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_post_data_reading", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, enable_post_data_reading, php_core_globals, core_globals) - STD_PHP_INI_BOOLEAN("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, always_populate_raw_post_data, php_core_globals, core_globals) STD_PHP_INI_ENTRY("realpath_cache_size", "16K", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_size_limit, virtual_cwd_globals, cwd_globals) STD_PHP_INI_ENTRY("realpath_cache_ttl", "120", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_ttl, virtual_cwd_globals, cwd_globals) @@ -1340,7 +1339,7 @@ PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *h handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; handle->handle.stream.fsizer = php_zend_stream_fsizer; handle->handle.stream.isatty = 0; - /* can we mmap immeadiately? */ + /* can we mmap immediately? */ memset(&handle->handle.stream.mmap, 0, sizeof(handle->handle.stream.mmap)); len = php_zend_stream_fsizer(stream TSRMLS_CC); if (len != 0 @@ -1817,6 +1816,9 @@ void php_request_shutdown(void *dummy) sapi_deactivate(TSRMLS_C); } zend_end_try(); + /* 9.5 free virtual CWD memory */ + virtual_cwd_deactivate(TSRMLS_C); + /* 10. Destroy stream hashes */ zend_try { php_shutdown_stream_hashes(TSRMLS_C); @@ -2192,7 +2194,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zend_set_utility_values(&zuv); php_startup_sapi_content_types(TSRMLS_C); - /* startup extensions staticly compiled in */ + /* startup extensions statically compiled in */ if (php_register_internal_extensions_func(TSRMLS_C) == FAILURE) { php_printf("Unable to start builtin modules\n"); return FAILURE; @@ -2244,9 +2246,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } #endif -#ifdef ZTS zend_post_startup(TSRMLS_C); -#endif module_initialized = 1; @@ -2316,6 +2316,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod shutdown_memory_manager(1, 0 TSRMLS_CC); zend_interned_strings_snapshot(TSRMLS_C); + virtual_cwd_activate(TSRMLS_C); /* we're done */ return retval; diff --git a/main/php.h b/main/php.h index 7c1f8fd0c7b96..ed8a2bb08e5dc 100644 --- a/main/php.h +++ b/main/php.h @@ -26,7 +26,7 @@ #include #endif -#define PHP_API_VERSION 20121113 +#define PHP_API_VERSION 20131106 #define PHP_HAVE_STREAMS #define YYDEBUG 0 @@ -180,6 +180,8 @@ typedef unsigned int socklen_t; # endif #endif +#include "php_stdint.h" + #include "zend_hash.h" #include "zend_alloc.h" #include "zend_stack.h" @@ -398,7 +400,7 @@ END_EXTERN_C() /* Virtual current working directory support */ -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_constants.h" diff --git a/main/php_content_types.c b/main/php_content_types.c index c4433978ed2be..3346efc50ec6e 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -37,34 +37,11 @@ static sapi_post_entry php_post_entries[] = { */ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader) { - char *data; - int length; - - /* $HTTP_RAW_POST_DATA registration */ if (!strcmp(SG(request_info).request_method, "POST")) { if (NULL == SG(request_info).post_entry) { /* no post handler registered, so we just swallow the data */ sapi_read_standard_form_data(TSRMLS_C); } - - /* For unknown content types we create HTTP_RAW_POST_DATA even if always_populate_raw_post_data off, - * this is in-effecient, but we need to keep doing it for BC reasons (for now) */ - if ((PG(always_populate_raw_post_data) || NULL == SG(request_info).post_entry) && SG(request_info).post_data) { - length = SG(request_info).post_data_length; - data = estrndup(SG(request_info).post_data, length); - SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, length); - } - } - - /* for php://input stream: - some post handlers modify the content of request_info.post_data - so for now we need a copy for the php://input stream - in the long run post handlers should be changed to not touch - request_info.post_data for memory preservation reasons - */ - if (SG(request_info).post_data) { - SG(request_info).raw_post_data = estrndup(SG(request_info).post_data, SG(request_info).post_data_length); - SG(request_info).raw_post_data_length = SG(request_info).post_data_length; } } /* }}} */ diff --git a/main/php_globals.h b/main/php_globals.h index 256765d665a53..fa2fe3b232962 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -131,7 +131,6 @@ struct _php_core_globals { zend_bool during_request_startup; zend_bool allow_url_fopen; zend_bool enable_post_data_reading; - zend_bool always_populate_raw_post_data; zend_bool report_zend_debug; int last_error_type; diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index 054d497be6d5c..8315297738165 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -124,11 +124,11 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** cwd[0] = '\0'; } - new_state.cwd = strdup(cwd); + new_state.cwd = estrdup(cwd); new_state.cwd_length = strlen(cwd); if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - free(new_state.cwd); + efree(new_state.cwd); return -1; } @@ -140,7 +140,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { efree(opened_path); - free(new_state.cwd); + efree(new_state.cwd); return -1; } @@ -151,7 +151,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** * which means that opening it will fail... */ if (VCWD_CHMOD(opened_path, 0600)) { efree(opened_path); - free(new_state.cwd); + efree(new_state.cwd); return -1; } fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600); @@ -170,7 +170,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** } else { *opened_path_p = opened_path; } - free(new_state.cwd); + efree(new_state.cwd); return fd; } /* }}} */ diff --git a/main/php_stdint.h b/main/php_stdint.h new file mode 100644 index 0000000000000..87edb0fde085a --- /dev/null +++ b/main/php_stdint.h @@ -0,0 +1,206 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 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_01.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: Michael Wallner | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_STDINT_H +#define PHP_STDINT_H + +#if defined(_MSC_VER) +/* Make sure the regular stdint.h wasn't included already and prevent it to be + included afterwards. Though if some other library needs some stuff from + stdint.h included afterwards and misses it, we'd have to extend ours. On + the other hand, if stdint.h was included before, some conflicts might + happen so we'd likewise have to fix ours. */ +# if !defined(_STDINT) +# define _STDINT +# include "win32/php_stdint.h" +# endif +# define HAVE_INT8_T 1 +# define HAVE_UINT8_T 1 +# define HAVE_INT16_T 1 +# define HAVE_UINT16_T 1 +# define HAVE_INT32_T 1 +# define HAVE_UINT32_T 1 +# define HAVE_INT64_T 1 +# define HAVE_UINT64_T 1 +#else + +#include "php_config.h" + +#if HAVE_SYS_TYPES_H +# include +#endif + +#if HAVE_INTTYPES_H +# include +#endif + +#if HAVE_STDINT_H +# include +#endif + +#ifndef HAVE_INT8_T +# ifdef HAVE_INT8 +typedef int8 int8_t; +# else +typedef signed char int8_t; +# endif +#endif + +#ifndef INT8_C +# define INT8_C(c) c +#endif + +#ifndef HAVE_UINT8_T +# ifdef HAVE_UINT8 +typedef uint8 uint8_t +# elif HAVE_U_INT8_T +typedef u_int8_t uint8_t; +# else +typedef unsigned char uint8_t; +# endif +#endif + +#ifndef UINT8_C +# define UINT8_C(c) c +#endif + +#ifndef HAVE_INT16_T +# ifdef HAVE_INT16 +typedef int16 int16_t; +# elif SIZEOF_SHORT >= 2 +typedef signed short int16_t; +# else +# error "No suitable 16bit integer type found" +# endif +#endif + +#ifndef INT16_C +# define INT16_C(c) c +#endif + +#ifndef HAVE_UINT16_T +# ifdef HAVE_UINT16 +typedef uint16 uint16_t +# elif HAVE_U_INT16_T +typedef u_int16_t uint16_t; +# elif SIZEOF_SHORT >= 2 +typedef unsigned short uint16_t; +# else +# error "No suitable 16bit integer type found" +# endif +#endif + +#ifndef UINT16_C +# define UINT16_C(c) c +#endif + +#ifndef HAVE_INT32_T +# ifdef HAVE_INT32 +typedef int32 int32_t; +# elif SIZEOF_INT >= 4 +typedef int int32_t; +# elif SIZEOF_LONG >= 4 +typedef long int32_t; +# else +# error "No suitable 32bit integer type found" +# endif +#endif + +#ifndef INT32_C +# define INT32_C(c) c +#endif + +#ifndef HAVE_UINT32_T +# ifdef HAVE_UINT32 +typedef uint32 uint32_t +# elif HAVE_U_INT32_T +typedef u_int32_t uint32_t; +# elif SIZEOF_INT >= 4 +typedef unsigned int uint32_t; +# elif SIZEOF_LONG >= 4 +typedef unsigned long uint32_t; +# else +# error "No suitable 32bit integer type found" +# endif +#endif + +#ifndef UINT32_C +# define UINT32_C(c) c ## U +#endif + +#ifndef HAVE_INT64_T +# ifdef HAVE_INT64 +typedef int64 int64_t; +# elif SIZEOF_INT >= 8 +typedef int int64_t; +# elif SIZEOF_LONG >= 8 +typedef long int64_t; +# elif SIZEOF_LONG_LONG >= 8 +typedef long long int64_t; +# else +# error "No suitable 64bit integer type found" +# endif +#endif + +#ifndef INT64_C +# if SIZEOF_INT >= 8 +# define INT64_C(c) c +# elif SIZEOF_LONG >= 8 +# define INT64_C(c) c ## L +# elif SIZEOF_LONG_LONG >= 8 +# define INT64_C(c) c ## LL +# endif +#endif + +#ifndef HAVE_UINT64_T +# ifdef HAVE_UINT64 +typedef uint64 uint64_t +# elif HAVE_U_INT64_T +typedef u_int64_t uint64_t; +# elif SIZEOF_INT >= 8 +typedef unsigned int uint64_t; +# elif SIZEOF_LONG >= 8 +typedef unsigned long uint64_t; +# elif SIZEOF_LONG_LONG >= 8 +typedef unsigned long long uint64_t; +# else +# error "No suitable 64bit integer type found" +# endif +#endif + +#ifndef UINT64_C +# if SIZEOF_INT >= 8 +# define UINT64_C(c) c ## U +# elif SIZEOF_LONG >= 8 +# define UINT64_C(c) c ## UL +# elif SIZEOF_LONG_LONG >= 8 +# define UINT64_C(c) c ## ULL +# endif +#endif + +#endif /* !PHP_WIN32 */ +#endif /* PHP_STDINT_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/main/php_streams.h b/main/php_streams.h index 5acf942e434bb..c9732b484849a 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -131,31 +131,31 @@ typedef struct _php_stream_ops { typedef struct _php_stream_wrapper_ops { /* open/create a wrapped stream */ - php_stream *(*stream_opener)(php_stream_wrapper *wrapper, char *filename, char *mode, + php_stream *(*stream_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); /* close/destroy a wrapped stream */ int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); /* stat a wrapped stream */ int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); /* stat a URL */ - int (*url_stat)(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); + int (*url_stat)(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); /* open a "directory" stream */ - php_stream *(*dir_opener)(php_stream_wrapper *wrapper, char *filename, char *mode, + php_stream *(*dir_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); const char *label; /* delete a file */ - int (*unlink)(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); + int (*unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); /* rename a file */ - int (*rename)(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC); + int (*rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); /* Create/Remove directory */ - int (*stream_mkdir)(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC); - int (*stream_rmdir)(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); + int (*stream_mkdir)(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC); + int (*stream_rmdir)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); /* Metadata handling */ - int (*stream_metadata)(php_stream_wrapper *wrapper, char *url, int options, void *value, php_stream_context *context TSRMLS_DC); + int (*stream_metadata)(php_stream_wrapper *wrapper, const char *url, int options, void *value, php_stream_context *context TSRMLS_DC); } php_stream_wrapper_ops; struct _php_stream_wrapper { @@ -242,7 +242,7 @@ PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, END_EXTERN_C() #define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC) -#define php_stream_get_resource_id(stream) (stream)->rsrc_id +#define php_stream_get_resource_id(stream) ((php_stream *)(stream))->rsrc_id #if ZEND_DEBUG /* use this to tell the stream that it is OK if we don't explicitly close it */ # define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } @@ -322,26 +322,26 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, #define php_stream_gets(stream, buf, maxlen) _php_stream_get_line((stream), (buf), (maxlen), NULL TSRMLS_CC) #define php_stream_get_line(stream, buf, maxlen, retlen) _php_stream_get_line((stream), (buf), (maxlen), (retlen) TSRMLS_CC) -PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, char *delim, size_t delim_len TSRMLS_DC); +PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC); /* CAREFUL! this is equivalent to puts NOT fputs! */ -PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC); +PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC); #define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf) TSRMLS_CC) PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); #define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) -PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); +PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); #define php_stream_stat_path(path, ssb) _php_stream_stat_path((path), 0, (ssb), NULL TSRMLS_CC) #define php_stream_stat_path_ex(path, flags, ssb, context) _php_stream_stat_path((path), (flags), (ssb), (context) TSRMLS_CC) -PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_context *context TSRMLS_DC); +PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC); #define php_stream_mkdir(path, mode, options, context) _php_stream_mkdir(path, mode, options, context TSRMLS_CC) -PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *context TSRMLS_DC); +PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC); #define php_stream_rmdir(path, options, context) _php_stream_rmdir(path, options, context TSRMLS_CC) -PHPAPI php_stream *_php_stream_opendir(char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_opendir(const char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); #define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC) PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC); #define php_stream_readdir(dirstream, dirent) _php_stream_readdir((dirstream), (dirent) TSRMLS_CC) @@ -351,7 +351,7 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b); PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b); -PHPAPI int _php_stream_scandir(char *dirname, char **namelist[], int flags, php_stream_context *context, +PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, int (*compare) (const char **a, const char **b) TSRMLS_DC); #define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare) TSRMLS_CC) @@ -540,13 +540,13 @@ void php_shutdown_stream_hashes(TSRMLS_D); PHP_RSHUTDOWN_FUNCTION(streams); BEGIN_EXTERN_C() -PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); -PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC); -PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); -PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC); -PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC); -PHPAPI char *php_stream_locate_eol(php_stream *stream, char *buf, size_t buf_len TSRMLS_DC); +PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); +PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC); +PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); +PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC); +PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC); +PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC); #define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC TSRMLS_CC) #define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC TSRMLS_CC) diff --git a/main/php_variables.c b/main/php_variables.c index 7018eae57bbd8..ab9aee3ae3c42 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -23,11 +23,15 @@ #include "php.h" #include "ext/standard/php_standard.h" #include "ext/standard/credits.h" +#include "ext/standard/php_smart_str.h" #include "php_variables.h" #include "php_globals.h" #include "php_content_types.h" #include "SAPI.h" #include "zend_globals.h" +#ifdef PHP_WIN32 +# include "win32/php_inttypes.h" +#endif /* for systems that need to override reading of environment variables */ void _php_import_environment_variables(zval *array_ptr TSRMLS_DC); @@ -228,44 +232,115 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars free_alloca(var_orig, use_heap); } +typedef struct post_var_data { + smart_str str; + char *ptr; + char *end; + uint64_t cnt; +} post_var_data_t; + +static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSRMLS_DC) +{ + char *ksep, *vsep; + size_t klen, vlen; + /* FIXME: string-size_t */ + unsigned int new_vlen; + + if (var->ptr >= var->end) { + return 0; + } + + vsep = memchr(var->ptr, '&', var->end - var->ptr); + if (!vsep) { + if (!eof) { + return 0; + } else { + vsep = var->end; + } + } + + ksep = memchr(var->ptr, '=', vsep - var->ptr); + if (ksep) { + *ksep = '\0'; + /* "foo=bar&" or "foo=&" */ + klen = ksep - var->ptr; + vlen = vsep - ++ksep; + } else { + ksep = ""; + /* "foo&" */ + klen = vsep - var->ptr; + vlen = 0; + } + + + php_url_decode(var->ptr, klen); + if (vlen) { + vlen = php_url_decode(ksep, vlen); + } + + if (sapi_module.input_filter(PARSE_POST, var->ptr, &ksep, vlen, &new_vlen TSRMLS_CC)) { + php_register_variable_safe(var->ptr, ksep, new_vlen, arr TSRMLS_CC); + } + + var->ptr = vsep + (vsep != var->end); + return 1; +} + +static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof TSRMLS_DC) +{ + uint64_t max_vars = PG(max_input_vars); + + vars->ptr = vars->str.c; + vars->end = vars->str.c + vars->str.len; + while (add_post_var(arr, vars, eof TSRMLS_CC)) { + if (++vars->cnt > max_vars) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Input variables exceeded %" PRIu64 ". " + "To increase the limit change max_input_vars in php.ini.", + max_vars); + return FAILURE; + } + } + + if (!eof) { + memmove(vars->str.c, vars->ptr, vars->str.len = vars->end - vars->ptr); + } + return SUCCESS; +} + SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) { - char *var, *val, *e, *s, *p; - zval *array_ptr = (zval *) arg; - long count = 0; + zval *arr = (zval *) arg; + php_stream *s = SG(request_info).request_body; + post_var_data_t post_data; - if (SG(request_info).post_data == NULL) { - return; - } + if (s && SUCCESS == php_stream_rewind(s)) { + memset(&post_data, 0, sizeof(post_data)); - s = SG(request_info).post_data; - e = s + SG(request_info).post_data_length; + while (!php_stream_eof(s)) { + char buf[BUFSIZ] = {0}; + size_t len = php_stream_read(s, buf, BUFSIZ); - while (s < e && (p = memchr(s, '&', (e - s)))) { -last_value: - if ((val = memchr(s, '=', (p - s)))) { /* have a value */ - unsigned int val_len, new_val_len; + if (len && len != (size_t) -1) { + smart_str_appendl(&post_data.str, buf, len); - if (++count > PG(max_input_vars)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); - return; + if (SUCCESS != add_post_vars(arr, &post_data, 0 TSRMLS_CC)) { + if (post_data.str.c) { + efree(post_data.str.c); + } + return; + } } - var = s; - php_url_decode(var, (val - s)); - val++; - val_len = php_url_decode(val, (p - val)); - val = estrndup(val, val_len); - if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); + if (len != BUFSIZ){ + break; } - efree(val); } - s = p + 1; - } - if (s < e) { - p = e; - goto last_value; + + add_post_vars(arr, &post_data, 1 TSRMLS_CC); + if (post_data.str.c) { + efree(post_data.str.c); + } } } diff --git a/main/php_version.h b/main/php_version.h index 2d98a3f80789a..d48bf13c6f7ff 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -1,8 +1,8 @@ /* automatically generated by configure */ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 -#define PHP_MINOR_VERSION 5 -#define PHP_RELEASE_VERSION 6 +#define PHP_MINOR_VERSION 6 +#define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.5.6-dev" -#define PHP_VERSION_ID 50506 +#define PHP_VERSION "5.6.0-dev" +#define PHP_VERSION_ID 50600 diff --git a/main/rfc1867.c b/main/rfc1867.c index 7c208c368c976..4adc25767db07 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -34,6 +34,10 @@ #include "rfc1867.h" #include "ext/standard/php_string.h" +#if defined(PHP_WIN32) && !defined(HAVE_ATOLL) +# define atoll(s) _atoi64(s) +#endif + #define DEBUG_FILE_UPLOAD ZEND_DEBUG static int dummy_encoding_translation(TSRMLS_D) @@ -676,8 +680,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ { char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL; - int boundary_len = 0, total_bytes = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; - int max_file_size = 0, skip_upload = 0, anonindex = 0, is_anonymous; + int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; + int64_t total_bytes = 0, max_file_size = 0; + int skip_upload = 0, anonindex = 0, is_anonymous; zval *http_post_files = NULL; HashTable *uploaded_files = NULL; multipart_buffer *mbuff; @@ -898,7 +903,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } if (!strcasecmp(param, "MAX_FILE_SIZE")) { - max_file_size = atol(value); + max_file_size = atoll(value); } efree(param); @@ -1210,17 +1215,32 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ { zval file_size, error_type; + int size_overflow = 0; + char file_size_buf[65]; - error_type.value.lval = cancel_upload; - error_type.type = IS_LONG; + ZVAL_LONG(&error_type, cancel_upload); /* Add $foo[error] */ if (cancel_upload) { - file_size.value.lval = 0; - file_size.type = IS_LONG; + ZVAL_LONG(&file_size, 0); } else { - file_size.value.lval = total_bytes; - file_size.type = IS_LONG; + if (total_bytes > LONG_MAX) { +#ifdef PHP_WIN32 + if (_i64toa_s(total_bytes, file_size_buf, 65, 10)) { + file_size_buf[0] = '0'; + file_size_buf[1] = '\0'; + } +#else + { + int __len = snprintf(file_size_buf, 65, "%lld", total_bytes); + file_size_buf[__len] = '\0'; + } +#endif + size_overflow = 1; + + } else { + ZVAL_LONG(&file_size, total_bytes); + } } if (is_arr_upload) { @@ -1237,7 +1257,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ snprintf(lbuf, llen, "%s_size", param); } if (!is_anonymous) { - safe_php_register_variable_ex(lbuf, &file_size, NULL, 0 TSRMLS_CC); + if (size_overflow) { + ZVAL_STRING(&file_size, file_size_buf, 1); + } + safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow TSRMLS_CC); } /* Add $foo[size] */ @@ -1246,7 +1269,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } else { snprintf(lbuf, llen, "%s[size]", param); } - register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, 0 TSRMLS_CC); + if (size_overflow) { + ZVAL_STRING(&file_size, file_size_buf, 1); + } + register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, size_overflow TSRMLS_CC); } efree(param); } diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index 9c051a59210ab..8c3836fea02a0 100644 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -109,9 +109,9 @@ PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC } /* }}} */ -static void php_glob_stream_path_split(glob_s_t *pglob, char *path, int get_path, char **p_file TSRMLS_DC) /* {{{ */ +static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int get_path, const char **p_file TSRMLS_DC) /* {{{ */ { - char *pos, *gpath = path; + const char *pos, *gpath = path; if ((pos = strrchr(path, '/')) != NULL) { path = pos+1; @@ -141,7 +141,7 @@ static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count T { glob_s_t *pglob = (glob_s_t *)stream->abstract; php_stream_dirent *ent = (php_stream_dirent*)buf; - char *path; + const char *path; /* avoid problems if someone mis-uses the stream */ if (count == sizeof(php_stream_dirent) && pglob) { @@ -206,12 +206,12 @@ php_stream_ops php_glob_stream_ops = { }; /* {{{ php_glob_stream_opener */ -static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode, +static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { glob_s_t *pglob; int ret; - char *tmp, *pos; + const char *tmp, *pos; if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { return NULL; diff --git a/main/streams/memory.c b/main/streams/memory.c index 328d3be399018..90780ea78ffed 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -598,7 +598,9 @@ PHPAPI php_stream_ops php_stream_rfc2397_ops = { php_stream_temp_set_option }; -static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ +static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, const char *path, + const char *mode, int options, char **opened_path, + php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *stream; php_stream_temp_data *ts; @@ -640,11 +642,11 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, cha MAKE_STD_ZVAL(meta); array_init(meta); if (!semi) { /* there is only a mime type */ - add_assoc_stringl(meta, "mediatype", path, mlen, 1); + add_assoc_stringl(meta, "mediatype", (char *) path, mlen, 1); mlen = 0; } else if (sep && sep < semi) { /* there is a mime type */ plen = semi - path; - add_assoc_stringl(meta, "mediatype", path, plen, 1); + add_assoc_stringl(meta, "mediatype", (char *) path, plen, 1); mlen -= plen; path += plen; } else if (semi != path || mlen != sizeof(";base64")-1 || memcmp(path, ";base64", sizeof(";base64")-1)) { /* must be error since parameters are only allowed after mediatype */ diff --git a/main/streams/php_stream_plain_wrapper.h b/main/streams/php_stream_plain_wrapper.h index d88b30c4791cf..6700df0b29a03 100644 --- a/main/streams/php_stream_plain_wrapper.h +++ b/main/streams/php_stream_plain_wrapper.h @@ -30,7 +30,7 @@ BEGIN_EXTERN_C() PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, char **opened_path, int options STREAMS_DC TSRMLS_DC); #define php_stream_fopen(filename, mode, opened) _php_stream_fopen((filename), (mode), (opened), 0 STREAMS_CC TSRMLS_CC) -PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC); #define php_stream_fopen_with_path(filename, mode, path, opened) _php_stream_fopen_with_path((filename), (mode), (path), (opened), 0 STREAMS_CC TSRMLS_CC) PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC); diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h index c2d911032ef8a..15ba09430f981 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -26,16 +26,16 @@ # include #endif -typedef php_stream *(php_stream_transport_factory_func)(const char *proto, long protolen, - char *resourcename, long resourcenamelen, +typedef php_stream *(php_stream_transport_factory_func)(const char *proto, size_t protolen, + const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, php_stream_context *context STREAMS_DC TSRMLS_DC); typedef php_stream_transport_factory_func *php_stream_transport_factory; BEGIN_EXTERN_C() -PHPAPI int php_stream_xport_register(char *protocol, php_stream_transport_factory factory TSRMLS_DC); -PHPAPI int php_stream_xport_unregister(char *protocol TSRMLS_DC); +PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory TSRMLS_DC); +PHPAPI int php_stream_xport_unregister(const char *protocol TSRMLS_DC); #define STREAM_XPORT_CLIENT 0 #define STREAM_XPORT_SERVER 1 @@ -46,7 +46,7 @@ PHPAPI int php_stream_xport_unregister(char *protocol TSRMLS_DC); #define STREAM_XPORT_CONNECT_ASYNC 16 /* Open a client or server socket connection */ -PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int options, +PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, int options, int flags, const char *persistent_id, struct timeval *timeout, php_stream_context *context, @@ -59,13 +59,13 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int /* Bind the stream to a local address */ PHPAPI int php_stream_xport_bind(php_stream *stream, - const char *name, long namelen, + const char *name, size_t namelen, char **error_text TSRMLS_DC); /* Connect to a remote address */ PHPAPI int php_stream_xport_connect(php_stream *stream, - const char *name, long namelen, + const char *name, size_t namelen, int asynchronous, struct timeval *timeout, char **error_text, @@ -141,7 +141,7 @@ typedef struct _php_stream_xport_param { struct { char *name; - long namelen; + size_t namelen; int backlog; struct timeval *timeout; struct sockaddr *addr; @@ -170,10 +170,14 @@ typedef enum { STREAM_CRYPTO_METHOD_SSLv3_CLIENT, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_TLS_CLIENT, + STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, + STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_SERVER, STREAM_CRYPTO_METHOD_SSLv3_SERVER, STREAM_CRYPTO_METHOD_SSLv23_SERVER, - STREAM_CRYPTO_METHOD_TLS_SERVER + STREAM_CRYPTO_METHOD_TLS_SERVER, + STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, + STREAM_CRYPTO_METHOD_TLSv1_2_SERVER } php_stream_xport_crypt_method_t; BEGIN_EXTERN_C() diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 39df31a170503..4dbf6889d7c11 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -851,7 +851,7 @@ static php_stream_ops php_plain_files_dirstream_ops = { NULL /* set_option */ }; -static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char *path, char *mode, +static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { DIR *dir = NULL; @@ -989,7 +989,7 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha /* }}} */ -static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode, +static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { @@ -999,7 +999,7 @@ static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, ch return php_stream_fopen_rel(path, mode, opened_path, options); } -static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +static int php_plain_files_url_stater(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) { char *p; @@ -1029,7 +1029,7 @@ static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, in return VCWD_STAT(url, &ssb->sb); } -static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) { char *p; int ret; @@ -1058,7 +1058,7 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, int op return 1; } -static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC) { char *p; int ret; @@ -1147,7 +1147,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, c return 1; } -static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mode, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, int mode, int options, php_stream_context *context TSRMLS_DC) { int ret, recursive = options & PHP_STREAM_MKDIR_RECURSIVE; char *p; @@ -1235,7 +1235,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod } } -static int php_plain_files_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) { #if PHP_WIN32 int url_len = strlen(url); @@ -1262,7 +1262,7 @@ static int php_plain_files_rmdir(php_stream_wrapper *wrapper, char *url, int opt return 1; } -static int php_plain_files_metadata(php_stream_wrapper *wrapper, char *url, int option, void *value, php_stream_context *context TSRMLS_DC) +static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context TSRMLS_DC) { struct utimbuf *newtime; char *p; @@ -1371,10 +1371,11 @@ php_stream_wrapper php_plain_files_wrapper = { }; /* {{{ php_stream_fopen_with_path */ -PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC) { /* code ripped off from fopen_wrappers.c */ - char *pathbuf, *ptr, *end; + char *pathbuf, *end; + const char *ptr; const char *exec_fname; char trypath[MAXPATHLEN]; php_stream *stream; @@ -1435,7 +1436,7 @@ PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); } - free(cwd); + efree(cwd); if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) { return NULL; diff --git a/main/streams/streams.c b/main/streams/streams.c index 823b8859bf3da..d74f9fd04aa75 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -803,7 +803,7 @@ PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC) return EOF; } -PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC) +PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC) { int len; char newline[2] = "\n"; /* is this OK for Win? */ @@ -835,11 +835,11 @@ PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_D return (stream->ops->stat)(stream, ssb TSRMLS_CC); } -PHPAPI char *php_stream_locate_eol(php_stream *stream, char *buf, size_t buf_len TSRMLS_DC) +PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC) { size_t avail; - char *cr, *lf, *eol = NULL; - char *readptr; + const char *cr, *lf, *eol = NULL; + const char *readptr; if (!buf) { readptr = stream->readbuf + stream->readpos; @@ -911,7 +911,7 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, if (avail > 0) { size_t cpysz = 0; char *readptr; - char *eol; + const char *eol; int done = 0; readptr = stream->readbuf + stream->readpos; @@ -994,11 +994,11 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, #define STREAM_BUFFERED_AMOUNT(stream) \ ((size_t)(((stream)->writepos) - (stream)->readpos)) -static char *_php_stream_search_delim(php_stream *stream, - size_t maxlen, - size_t skiplen, - char *delim, /* non-empty! */ - size_t delim_len TSRMLS_DC) +static const char *_php_stream_search_delim(php_stream *stream, + size_t maxlen, + size_t skiplen, + const char *delim, /* non-empty! */ + size_t delim_len TSRMLS_DC) { size_t seek_len; @@ -1018,10 +1018,10 @@ static char *_php_stream_search_delim(php_stream *stream, } } -PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, char *delim, size_t delim_len TSRMLS_DC) +PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC) { - char *ret_buf, /* returned buffer */ - *found_delim = NULL; + char *ret_buf; /* returned buffer */ + const char *found_delim = NULL; size_t buffered_len, tent_ret_len; /* tentative returned length */ int has_delim = delim_len > 0; @@ -1676,9 +1676,9 @@ int php_shutdown_stream_wrappers(int module_number TSRMLS_DC) /* Validate protocol scheme names during registration * Must conform to /^[a-zA-Z0-9+.-]+$/ */ -static inline int php_stream_wrapper_scheme_validate(char *protocol, int protocol_len) +static inline int php_stream_wrapper_scheme_validate(const char *protocol, unsigned int protocol_len) { - int i; + unsigned int i; for(i = 0; i < protocol_len; i++) { if (!isalnum((int)protocol[i]) && @@ -1693,9 +1693,9 @@ static inline int php_stream_wrapper_scheme_validate(char *protocol, int protoco } /* API for registering GLOBAL wrappers */ -PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) { - int protocol_len = strlen(protocol); + unsigned int protocol_len = strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; @@ -1704,7 +1704,7 @@ PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *w return zend_hash_add(&url_stream_wrappers_hash, protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); } -PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC) { return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol) + 1); } @@ -1719,9 +1719,9 @@ static void clone_wrapper_hash(TSRMLS_D) } /* API for registering VOLATILE wrappers */ -PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) { - int protocol_len = strlen(protocol); + unsigned int protocol_len = strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; @@ -1734,7 +1734,7 @@ PHPAPI int php_register_url_stream_wrapper_volatile(char *protocol, php_stream_w return zend_hash_add(FG(stream_wrappers), protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); } -PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC) { if (!FG(stream_wrappers)) { clone_wrapper_hash(TSRMLS_C); @@ -1745,7 +1745,7 @@ PHPAPI int php_unregister_url_stream_wrapper_volatile(char *protocol TSRMLS_DC) /* }}} */ /* {{{ php_stream_locate_url_wrapper */ -PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char **path_for_open, int options TSRMLS_DC) +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC) { HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); php_stream_wrapper **wrapperpp = NULL; @@ -1880,7 +1880,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char /* {{{ _php_stream_mkdir */ -PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC) { php_stream_wrapper *wrapper = NULL; @@ -1895,7 +1895,7 @@ PHPAPI int _php_stream_mkdir(char *path, int mode, int options, php_stream_conte /* {{{ _php_stream_rmdir */ -PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC) { php_stream_wrapper *wrapper = NULL; @@ -1909,10 +1909,10 @@ PHPAPI int _php_stream_rmdir(char *path, int options, php_stream_context *contex /* }}} */ /* {{{ _php_stream_stat_path */ -PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) { php_stream_wrapper *wrapper = NULL; - char *path_to_open = path; + const char *path_to_open = path; int ret; /* Try to hit the cache first */ @@ -1954,12 +1954,12 @@ PHPAPI int _php_stream_stat_path(char *path, int flags, php_stream_statbuf *ssb, /* }}} */ /* {{{ php_stream_opendir */ -PHPAPI php_stream *_php_stream_opendir(char *path, int options, +PHPAPI php_stream *_php_stream_opendir(const char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; - char *path_to_open; + const char *path_to_open; if (!path || !*path) { return NULL; @@ -2003,12 +2003,12 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ /* }}} */ /* {{{ php_stream_open_wrapper_ex */ -PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options, +PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; - char *path_to_open; + const char *path_to_open; int persistent = options & STREAM_OPEN_PERSISTENT; char *resolved_path = NULL; char *copy_of_path = NULL; @@ -2264,7 +2264,7 @@ PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b) /* {{{ php_stream_scandir */ -PHPAPI int _php_stream_scandir(char *dirname, char **namelist[], int flags, php_stream_context *context, +PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, int (*compare) (const char **a, const char **b) TSRMLS_DC) { php_stream *stream; diff --git a/main/streams/transports.c b/main/streams/transports.c index c24bf97ce6e9e..2d31074ded807 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -29,12 +29,12 @@ PHPAPI HashTable *php_stream_xport_get_hash(void) return &xport_hash; } -PHPAPI int php_stream_xport_register(char *protocol, php_stream_transport_factory factory TSRMLS_DC) +PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory TSRMLS_DC) { return zend_hash_update(&xport_hash, protocol, strlen(protocol) + 1, &factory, sizeof(factory), NULL); } -PHPAPI int php_stream_xport_unregister(char *protocol TSRMLS_DC) +PHPAPI int php_stream_xport_unregister(const char *protocol TSRMLS_DC) { return zend_hash_del(&xport_hash, protocol, strlen(protocol) + 1); } @@ -49,7 +49,7 @@ PHPAPI int php_stream_xport_unregister(char *protocol TSRMLS_DC) if (local_err) { efree(local_err); local_err = NULL; } \ } -PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int options, +PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, int options, int flags, const char *persistent_id, struct timeval *timeout, php_stream_context *context, @@ -194,7 +194,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, long namelen, int /* Bind the stream to a local address */ PHPAPI int php_stream_xport_bind(php_stream *stream, - const char *name, long namelen, + const char *name, size_t namelen, char **error_text TSRMLS_DC) { @@ -222,7 +222,7 @@ PHPAPI int php_stream_xport_bind(php_stream *stream, /* Connect to a remote address */ PHPAPI int php_stream_xport_connect(php_stream *stream, - const char *name, long namelen, + const char *name, size_t namelen, int asynchronous, struct timeval *timeout, char **error_text, diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 69edbaafa91d4..1e626e4b4c779 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -45,14 +45,14 @@ struct php_user_stream_wrapper { php_stream_wrapper wrapper; }; -static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -static int user_wrapper_stat_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*url,%20int%20flags,%20php_stream_statbuf%20*ssb,%20php_stream_context%20*context%20TSRMLS_DC); -static int user_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_metadata(php_stream_wrapper *wrapper, char *url, int option, void *value, php_stream_context *context TSRMLS_DC); -static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode, +static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); +static int user_wrapper_stat_url(https://github.com/php_stream_wrapper%20*wrapper,%20const%20char%20*url,%20int%20flags,%20php_stream_statbuf%20*ssb,%20php_stream_context%20*context%20TSRMLS_DC); +static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); +static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); +static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC); +static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); +static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context TSRMLS_DC); +static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); static php_stream_wrapper_ops user_stream_wops = { @@ -332,7 +332,8 @@ static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, ph return object; } -static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *filename, const char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; php_userstream_data_t *us; @@ -437,7 +438,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena return stream; } -static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, char *filename, char *mode, +static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; @@ -1151,7 +1152,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value } -static int user_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zfilename, *zfuncname, *zretval; @@ -1198,7 +1199,8 @@ static int user_wrapper_unlink(php_stream_wrapper *wrapper, char *url, int optio return ret; } -static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char *url_to, int options, php_stream_context *context TSRMLS_DC) +static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, + int options, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zold_name, *znew_name, *zfuncname, *zretval; @@ -1250,7 +1252,8 @@ static int user_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char return ret; } -static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, int options, php_stream_context *context TSRMLS_DC) +static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, + int options, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zfilename, *zmode, *zoptions, *zfuncname, *zretval; @@ -1308,7 +1311,8 @@ static int user_wrapper_mkdir(php_stream_wrapper *wrapper, char *url, int mode, return ret; } -static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) +static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, + int options, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zfilename, *zoptions, *zfuncname, *zretval; @@ -1361,7 +1365,8 @@ static int user_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int option return ret; } -static int user_wrapper_metadata(php_stream_wrapper *wrapper, char *url, int option, void *value, php_stream_context *context TSRMLS_DC) +static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, + void *value, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zfilename, *zoption, *zvalue, *zfuncname, *zretval; @@ -1444,7 +1449,8 @@ static int user_wrapper_metadata(php_stream_wrapper *wrapper, char *url, int opt } -static int user_wrapper_stat_url(https://github.com/php_stream_wrapper%20*wrapper,%20char%20*url,%20int%20flags,%20php_stream_statbuf%20*ssb,%20php_stream_context%20*context%20TSRMLS_DC) +static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, int flags, + php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; zval *zfilename, *zfuncname, *zretval, *zflags; diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index a9c050f2672d2..4edc68b015f82 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -230,7 +230,7 @@ static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC #endif } -static inline int sock_sendto(php_netstream_data_t *sock, char *buf, size_t buflen, int flags, +static inline int sock_sendto(php_netstream_data_t *sock, const char *buf, size_t buflen, int flags, struct sockaddr *addr, socklen_t addrlen TSRMLS_DC) { @@ -521,7 +521,7 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock } #endif -static inline char *parse_ip_address_ex(const char *str, int str_len, int *portno, int get_err, char **err TSRMLS_DC) +static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *portno, int get_err, char **err TSRMLS_DC) { char *colon; char *host = NULL; @@ -774,8 +774,8 @@ static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, } -PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, long protolen, - char *resourcename, long resourcenamelen, +PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, size_t protolen, + const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, php_stream_context *context STREAMS_DC TSRMLS_DC) diff --git a/php.ini-development b/php.ini-development index 2ef47a40a2448..2a01555b7f6a7 100644 --- a/php.ini-development +++ b/php.ini-development @@ -78,9 +78,9 @@ ; compatibility with older or less security conscience applications. We ; recommending using the production ini in production and testing environments. -; php.ini-development is very similar to its production variant, except it's -; much more verbose when it comes to errors. We recommending using the -; development version only in development environments as errors shown to +; php.ini-development is very similar to its production variant, except it is +; much more verbose when it comes to errors. We recommend using the +; development version only in development environments, as errors shown to ; application users can inadvertently leak otherwise secure information. ; This is php.ini-development INI file. @@ -433,7 +433,7 @@ memory_limit = 128M ; E_NOTICE - run-time notices (these are warnings which often result ; from a bug in your code, but it's possible that it was ; intentional (e.g., using an uninitialized variable and -; relying on the fact it's automatically initialized to an +; relying on the fact it is automatically initialized to an ; empty string) ; E_STRICT - run-time notices, enable to have PHP suggest changes ; to your code which will ensure the best interoperability @@ -466,8 +466,8 @@ error_reporting = E_ALL ; it could be very dangerous in production environments. Depending on the code ; which is triggering the error, sensitive information could potentially leak ; out of your application such as database usernames and passwords or worse. -; It's recommended that errors be logged on production servers rather than -; having the errors sent to STDOUT. +; For production environments, we recommend logging errors rather than +; sending them to STDOUT. ; Possible Values: ; Off = Do not display any errors ; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) @@ -481,8 +481,8 @@ display_errors = On ; The display of errors which occur during PHP's startup sequence are handled ; separately from display_errors. PHP's default behavior is to suppress those ; errors from clients. Turning the display of startup errors on can be useful in -; debugging configuration problems. But, it's strongly recommended that you -; leave this setting off on production servers. +; debugging configuration problems. We strongly recommend you +; set this to 'off' for production servers. ; Default Value: Off ; Development Value: On ; Production Value: Off @@ -780,8 +780,8 @@ enable_dl = Off ;fastcgi.logging = 0 ; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If it's set 0 PHP sends Status: header that -; is supported by Apache. When this option is set to 1 PHP will send +; use when sending HTTP response code. If set to 0, PHP sends Status: header that +; is supported by Apache. When this option is set to 1, PHP will send ; RFC2616 compliant header. ; Default is zero. ; http://php.net/cgi.rfc2616-headers @@ -884,8 +884,7 @@ default_socket_timeout = 60 ;extension=php_exif.dll ; Must be after mbstring as it depends on it ;extension=php_mysql.dll ;extension=php_mysqli.dll -;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client -;extension=php_oci8_11g.dll ; Use with Oracle 11gR2 Instant Client +;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client ;extension=php_openssl.dll ;extension=php_pdo_firebird.dll ;extension=php_pdo_mysql.dll @@ -1380,9 +1379,9 @@ session.save_handler = files ; ; where N is an integer. Instead of storing all the session files in ; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if you -; or your OS have problems with lots of files in one directory, and is -; a more efficient layout for servers that handle lots of sessions. +; store the session data in those directories. This is useful if +; your OS has problems with many files in one directory, and is +; a more efficient layout for servers that handle many sessions. ; ; NOTE 1: PHP will not create this directory structure automatically. ; You can use the script in the ext/session dir for that purpose. @@ -1417,7 +1416,7 @@ session.use_cookies = 1 ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating ; session hijacking when not specifying and managing your own session id. It is -; not the end all be all of session hijacking defense, but it's a good start. +; not the be-all and end-all of session hijacking defense, but it's a good start. ; http://php.net/session.use-only-cookies session.use_only_cookies = 1 @@ -1490,14 +1489,14 @@ session.gc_maxlifetime = 1440 ; PHP 4.2 and less have an undocumented feature/bug that allows you to ; to initialize a session variable in the global scope. -; PHP 4.3 and later will warn you, if this feature is used. +; PHP 4.3 and later will warn you if this feature is used. ; You can disable the feature and the warning separately. At this time, ; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you +; introduces some serious security problems if not handled correctly. We +; recommend you not use this feature on production servers. You ; should enable this on development servers and enable the warning as well. If you ; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. +; used, so debugging errors caused by this can be difficult to track down. ; Default Value: On ; Development Value: On ; Production Value: Off @@ -1542,7 +1541,7 @@ session.cache_limiter = nocache session.cache_expire = 180 ; trans sid support is disabled by default. -; Use of trans sid may risk your users security. +; Use of trans sid may risk your users' security. ; Use this option with caution. ; - User may send URL contains active session ID ; to other person via. email/irc/etc. diff --git a/php.ini-production b/php.ini-production index c39de742db8b1..d78cdcbe41ec5 100644 --- a/php.ini-production +++ b/php.ini-production @@ -78,9 +78,9 @@ ; compatibility with older or less security conscience applications. We ; recommending using the production ini in production and testing environments. -; php.ini-development is very similar to its production variant, except it's -; much more verbose when it comes to errors. We recommending using the -; development version only in development environments as errors shown to +; php.ini-development is very similar to its production variant, except it is +; much more verbose when it comes to errors. We recommend using the +; development version only in development environments, as errors shown to ; application users can inadvertently leak otherwise secure information. ; This is php.ini-production INI file. @@ -433,7 +433,7 @@ memory_limit = 128M ; E_NOTICE - run-time notices (these are warnings which often result ; from a bug in your code, but it's possible that it was ; intentional (e.g., using an uninitialized variable and -; relying on the fact it's automatically initialized to an +; relying on the fact it is automatically initialized to an ; empty string) ; E_STRICT - run-time notices, enable to have PHP suggest changes ; to your code which will ensure the best interoperability @@ -466,8 +466,8 @@ error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT ; it could be very dangerous in production environments. Depending on the code ; which is triggering the error, sensitive information could potentially leak ; out of your application such as database usernames and passwords or worse. -; It's recommended that errors be logged on production servers rather than -; having the errors sent to STDOUT. +; For production environments, we recommend logging errors rather than +; sending them to STDOUT. ; Possible Values: ; Off = Do not display any errors ; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) @@ -481,8 +481,8 @@ display_errors = Off ; The display of errors which occur during PHP's startup sequence are handled ; separately from display_errors. PHP's default behavior is to suppress those ; errors from clients. Turning the display of startup errors on can be useful in -; debugging configuration problems. But, it's strongly recommended that you -; leave this setting off on production servers. +; debugging configuration problems. We strongly recommend you +; set this to 'off' for production servers. ; Default Value: Off ; Development Value: On ; Production Value: Off @@ -780,8 +780,8 @@ enable_dl = Off ;fastcgi.logging = 0 ; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If it's set 0 PHP sends Status: header that -; is supported by Apache. When this option is set to 1 PHP will send +; use when sending HTTP response code. If set to 0, PHP sends Status: header that +; is supported by Apache. When this option is set to 1, PHP will send ; RFC2616 compliant header. ; Default is zero. ; http://php.net/cgi.rfc2616-headers @@ -884,8 +884,7 @@ default_socket_timeout = 60 ;extension=php_exif.dll ; Must be after mbstring as it depends on it ;extension=php_mysql.dll ;extension=php_mysqli.dll -;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client -;extension=php_oci8_11g.dll ; Use with Oracle 11gR2 Instant Client +;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client ;extension=php_openssl.dll ;extension=php_pdo_firebird.dll ;extension=php_pdo_mysql.dll @@ -1380,9 +1379,9 @@ session.save_handler = files ; ; where N is an integer. Instead of storing all the session files in ; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if you -; or your OS have problems with lots of files in one directory, and is -; a more efficient layout for servers that handle lots of sessions. +; store the session data in those directories. This is useful if +; your OS has problems with many files in one directory, and is +; a more efficient layout for servers that handle many sessions. ; ; NOTE 1: PHP will not create this directory structure automatically. ; You can use the script in the ext/session dir for that purpose. @@ -1417,7 +1416,7 @@ session.use_cookies = 1 ; This option forces PHP to fetch and use a cookie for storing and maintaining ; the session id. We encourage this operation as it's very helpful in combating ; session hijacking when not specifying and managing your own session id. It is -; not the end all be all of session hijacking defense, but it's a good start. +; not the be-all and end-all of session hijacking defense, but it's a good start. ; http://php.net/session.use-only-cookies session.use_only_cookies = 1 @@ -1490,14 +1489,14 @@ session.gc_maxlifetime = 1440 ; PHP 4.2 and less have an undocumented feature/bug that allows you to ; to initialize a session variable in the global scope. -; PHP 4.3 and later will warn you, if this feature is used. +; PHP 4.3 and later will warn you if this feature is used. ; You can disable the feature and the warning separately. At this time, ; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you +; introduces some serious security problems if not handled correctly. We +; recommend you not use this feature on production servers. You ; should enable this on development servers and enable the warning as well. If you ; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. +; used, so debugging errors caused by this can be difficult to track down. ; Default Value: On ; Development Value: On ; Production Value: Off @@ -1542,7 +1541,7 @@ session.cache_limiter = nocache session.cache_expire = 180 ; trans sid support is disabled by default. -; Use of trans sid may risk your users security. +; Use of trans sid may risk your users' security. ; Use this option with caution. ; - User may send URL contains active session ID ; to other person via. email/irc/etc. diff --git a/run-tests.php b/run-tests.php index 7eb445eeb812f..d37c18b1fcaa9 100755 --- a/run-tests.php +++ b/run-tests.php @@ -1289,16 +1289,20 @@ function run_test($php, $file, $env) unset($section_text['FILEEOF']); } - if (@count($section_text['FILE_EXTERNAL']) == 1) { - // don't allow tests to retrieve files from anywhere but this subdirectory - $section_text['FILE_EXTERNAL'] = dirname($file) . '/' . trim(str_replace('..', '', $section_text['FILE_EXTERNAL'])); + foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { + $key = $prefix . '_EXTERNAL'; - if (file_exists($section_text['FILE_EXTERNAL'])) { - $section_text['FILE'] = file_get_contents($section_text['FILE_EXTERNAL'], FILE_BINARY); - unset($section_text['FILE_EXTERNAL']); - } else { - $bork_info = "could not load --FILE_EXTERNAL-- " . dirname($file) . '/' . trim($section_text['FILE_EXTERNAL']); - $borked = true; + if (@count($section_text[$key]) == 1) { + // don't allow tests to retrieve files from anywhere but this subdirectory + $section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key])); + + if (file_exists($section_text[$key])) { + $section_text[$prefix] = file_get_contents($section_text[$key], FILE_BINARY); + unset($section_text[$key]); + } else { + $bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]); + $borked = true; + } } } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 4c78fcafec08f..3ffdc1eaf06d8 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -508,7 +508,7 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) uint read_bytes = 0; int tmp_read_bytes; - count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes)); + count_bytes = MIN(count_bytes, SG(request_info).content_length - SG(read_post_bytes)); while (read_bytes < count_bytes) { tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes); if (tmp_read_bytes <= 0) { @@ -524,8 +524,11 @@ static int sapi_fcgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) uint read_bytes = 0; int tmp_read_bytes; fcgi_request *request = (fcgi_request*) SG(server_context); + size_t remaining = SG(request_info).content_length - SG(read_post_bytes); - count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes)); + if (remaining < count_bytes) { + count_bytes = remaining; + } while (read_bytes < count_bytes) { tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes); if (tmp_read_bytes <= 0) { @@ -815,7 +818,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha } if (real_path) { - free(real_path); + efree(real_path); } entry->expires = request_time + PG(user_ini_cache_ttl); } @@ -1396,7 +1399,7 @@ static void init_request_info(fcgi_request *request TSRMLS_DC) } else { SG(request_info).request_uri = env_script_name; } - free(real_path); + efree(real_path); } } else { /* pre 4.3 behaviour, shouldn't be used but provides BC */ diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 1315a62b87010..ab4ac4341b723 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -1725,8 +1725,7 @@ static void php_cli_server_client_populate_request_info(const php_cli_server_cli request_info->request_uri = client->request.request_uri; request_info->path_translated = client->request.path_translated; request_info->query_string = client->request.query_string; - request_info->post_data = client->request.content; - request_info->content_length = request_info->post_data_length = client->request.content_len; + request_info->content_length = client->request.content_len; request_info->auth_user = request_info->auth_password = request_info->auth_digest = NULL; if (SUCCESS == zend_hash_find(&client->request.headers, "content-type", sizeof("content-type"), (void**)&val)) { request_info->content_type = *val; diff --git a/sapi/cli/php_http_parser.h b/sapi/cli/php_http_parser.h index 2bf2356725a29..31502e213af7b 100644 --- a/sapi/cli/php_http_parser.h +++ b/sapi/cli/php_http_parser.h @@ -29,15 +29,13 @@ extern "C" { #include #if defined(_WIN32) && !defined(__MINGW32__) # include -# include "win32/php_stdint.h" # include "config.w32.h" #else # include "php_config.h" -# ifdef HAVE_STDINT_H -# include -# endif #endif +#include "php_stdint.h" + /* Compile with -DPHP_HTTP_PARSER_STRICT=0 to make less checks, but run * faster */ diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc index 40c53619957fd..77a79e0f0493e 100644 --- a/sapi/cli/tests/php_cli_server.inc +++ b/sapi/cli/tests/php_cli_server.inc @@ -3,7 +3,7 @@ define ("PHP_CLI_SERVER_HOSTNAME", "localhost"); define ("PHP_CLI_SERVER_PORT", 8964); define ("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT); -function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE) { +function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE, $cmd_args = null) { $php_executable = getenv('TEST_PHP_EXECUTABLE'); $doc_root = __DIR__; $router = "index.php"; @@ -19,14 +19,14 @@ function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE) ); if (substr(PHP_OS, 0, 3) == 'WIN') { - $cmd = "{$php_executable} -t {$doc_root} -n -S " . PHP_CLI_SERVER_ADDRESS; + $cmd = "{$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS; if (!$no_router) { $cmd .= " {$router}"; } $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true)); } else { - $cmd = "exec {$php_executable} -t {$doc_root} -n -S " . PHP_CLI_SERVER_ADDRESS; + $cmd = "exec {$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS; if (!$no_router) { $cmd .= " {$router}"; } diff --git a/sapi/cli/tests/upload_2G.phpt b/sapi/cli/tests/upload_2G.phpt new file mode 100644 index 0000000000000..b8416ea730972 --- /dev/null +++ b/sapi/cli/tests/upload_2G.phpt @@ -0,0 +1,99 @@ +--TEST-- +file upload greater than 2G +--SKIPIF-- +=8"); +} + +if ($f = fopen("/proc/meminfo","r")) { + while (!feof($f)) { + if (!strncmp($line = fgets($f), "MemFree", 7)) { + if (substr($line,8)/1024/1024 > 3) { + $enough_free_ram = true; + } + } + } +} + +if (empty($enough_free_ram)) { + die("need +3G free RAM"); +} +?> +--FILE-- + +Done +--EXPECTF-- +Test + +HTTP/1.1 200 OK +Host: %s +Connection: close +X-Powered-By: PHP/%s +Content-type: text/html + +array(1) { + ["file1"]=> + array(5) { + ["name"]=> + string(9) "file1.txt" + ["type"]=> + string(10) "text/plain" + ["tmp_name"]=> + string(%d) "%s" + ["error"]=> + int(0) + ["size"]=> + int(2150000000) + } +} +Done diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 043e0e00a47c0..91abfea959f3a 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -498,8 +498,11 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) { uint read_bytes = 0; int tmp_read_bytes; + size_t remaining = SG(request_info).content_length - SG(read_post_bytes); - count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes)); + if (remaining < count_bytes) { + count_bytes = remaining; + } while (read_bytes < count_bytes) { fcgi_request *request = (fcgi_request*) SG(server_context); if (request_body_fd == -1) { @@ -1982,8 +1985,9 @@ consult the installation file that came with this distribution, or visit \n\ out: SG(server_context) = NULL; + php_module_shutdown(TSRMLS_C); + if (parent) { - php_module_shutdown(TSRMLS_C); sapi_shutdown(); } diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index d95d66a754c3e..925f2de64e93f 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -138,7 +138,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog TSRMLS_DC void fpm_php_trace(struct fpm_child_s *child) /* {{{ */ { TSRMLS_FETCH(); - fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_SET, child->wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); FILE *slowlog; zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid); diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 24463a90dddfd..8d0868182d763 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -111,7 +111,7 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request scoreboard->max_children_reached = max_children_reached; } if (slow_rq > 0) { - scoreboard->slow_rq += slow_rq; + scoreboard->slow_rq = slow_rq; } } else { if (scoreboard->idle + idle > 0) { @@ -137,6 +137,12 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request } else { scoreboard->max_children_reached = 0; } + + if (scoreboard->slow_rq + slow_rq > 0) { + scoreboard->slow_rq += slow_rq; + } else { + scoreboard->slow_rq = 0; + } } if (scoreboard->active > scoreboard->active_max) { diff --git a/sapi/litespeed/Makefile.frag b/sapi/litespeed/Makefile.frag index b70e5e8702933..767c2e5eb1719 100644 --- a/sapi/litespeed/Makefile.frag +++ b/sapi/litespeed/Makefile.frag @@ -4,6 +4,6 @@ $(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_LITESPEED_OB $(BUILD_LITESPEED) install-litespeed: $(SAPI_LITESPEED_PATH) - @echo "Installing PHP LitSpeed binary: $(INSTALL_ROOT)$(bindir)/" + @echo "Installing PHP LiteSpeed binary: $(INSTALL_ROOT)$(bindir)/" @$(INSTALL) -m 0755 $(SAPI_LITESPEED_PATH) $(INSTALL_ROOT)$(bindir)/lsphp diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 19364c66e06f2..33ebb988a66b1 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id$ */ +/* $Id: lsapi_main.c,v 1.57 2013/08/23 14:50:25 gwang Exp $ */ #include "php.h" #include "SAPI.h" @@ -75,7 +75,9 @@ static int lsapi_mode = 1; static char *php_self = ""; static char *script_filename = ""; static int source_highlight = 0; - +static int ignore_php_ini = 0; +static char * argv0 = NULL; +static int engine = 1; #ifdef ZTS zend_compiler_globals *compiler_globals; zend_executor_globals *executor_globals; @@ -90,40 +92,65 @@ zend_module_entry litespeed_module_entry; */ static int php_lsapi_startup(sapi_module_struct *sapi_module) { - if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { - return FAILURE; - } - return SUCCESS; + if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { + return FAILURE; + } + argv0 = sapi_module->executable_location; + return SUCCESS; } /* }}} */ +/* {{{ sapi_lsapi_ini_defaults */ + +/* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */ +#define INI_DEFAULT(name,value)\ + ZVAL_STRING(tmp, value, 0);\ + zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\ + Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)) + +static void sapi_lsapi_ini_defaults(HashTable *configuration_hash) +{ + zval *tmp, *entry; + +#if PHP_MAJOR_VERSION > 4 +/* + MAKE_STD_ZVAL(tmp); + + INI_DEFAULT("register_long_arrays", "0"); + + FREE_ZVAL(tmp); +*/ +#endif + +} +/* }}} */ /* {{{ sapi_lsapi_ub_write */ static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC) { - int ret; - int remain; - if ( lsapi_mode ) { - ret = LSAPI_Write( str, str_length ); - if ( ret < str_length ) { - php_handle_aborted_connection(); - return str_length - ret; - } - } else { - remain = str_length; - while( remain > 0 ) { - ret = write( 1, str, remain ); - if ( ret <= 0 ) { - php_handle_aborted_connection(); - return str_length - remain; - } - str += ret; - remain -= ret; - } - } - return str_length; + int ret; + int remain; + if ( lsapi_mode ) { + ret = LSAPI_Write( str, str_length ); + if ( ret < str_length ) { + php_handle_aborted_connection(); + return str_length - ret; + } + } else { + remain = str_length; + while( remain > 0 ) { + ret = write( 1, str, remain ); + if ( ret <= 0 ) { + php_handle_aborted_connection(); + return str_length - remain; + } + str += ret; + remain -= ret; + } + } + return str_length; } /* }}} */ @@ -132,11 +159,11 @@ static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC) */ static void sapi_lsapi_flush( void * server_context ) { - if ( lsapi_mode ) { - if ( LSAPI_Flush() == -1) { - php_handle_aborted_connection(); - } - } + if ( lsapi_mode ) { + if ( LSAPI_Flush() == -1) { + php_handle_aborted_connection(); + } + } } /* }}} */ @@ -145,8 +172,12 @@ static void sapi_lsapi_flush( void * server_context ) */ static int sapi_lsapi_deactivate(TSRMLS_D) { - LSAPI_Finish(); - return SUCCESS; + if ( SG(request_info).path_translated ) + { + efree( SG(request_info).path_translated ); + } + + return SUCCESS; } /* }}} */ @@ -157,46 +188,99 @@ static int sapi_lsapi_deactivate(TSRMLS_D) */ static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC ) { - if ( lsapi_mode ) { - return LSAPI_GetEnv( name ); - } else { - return getenv( name ); - } + if ( lsapi_mode ) { + return LSAPI_GetEnv( name ); + } else { + return getenv( name ); + } } /* }}} */ +/* +static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, + void * arg ) +{ + php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); + return 1; +} +*/ static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); - return 1; + zval * gpc_element, **gpc_element_p; + HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); + register char * pKey1 = (char *)pKey; + + MAKE_STD_ZVAL(gpc_element); + Z_STRLEN_P( gpc_element ) = valLen; + Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen); + Z_TYPE_P( gpc_element ) = IS_STRING; +#if PHP_MAJOR_VERSION > 4 + zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#else + zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#endif + return 1; } +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) +static int add_variable_magic_quote( const char * pKey, int keyLen, const char * pValue, int valLen, + void * arg ) +{ + zval * gpc_element, **gpc_element_p; + HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); + register char * pKey1 = (char *)pKey; + + MAKE_STD_ZVAL(gpc_element); + Z_STRLEN_P( gpc_element ) = valLen; + Z_STRVAL_P( gpc_element ) = php_addslashes((char *)pValue, valLen, &Z_STRLEN_P( gpc_element ), 0 ); + Z_TYPE_P( gpc_element ) = IS_STRING; +#if PHP_MAJOR_VERSION > 4 + zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#else + zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#endif + return 1; +} + +#endif /* {{{ sapi_lsapi_register_variables */ static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) { + char * php_self = ""; + if ( lsapi_mode ) { + if ( (SG(request_info).request_uri ) ) + php_self = (SG(request_info).request_uri ); - if ( lsapi_mode ) { - LSAPI_ForeachHeader( add_variable, track_vars_array ); - LSAPI_ForeachEnv( add_variable, track_vars_array ); - php_import_environment_variables(track_vars_array TSRMLS_CC); - - php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC); - } else { - php_import_environment_variables(track_vars_array TSRMLS_CC); +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) + if (!PG(magic_quotes_gpc)) { +#endif + LSAPI_ForeachHeader( add_variable, track_vars_array ); + LSAPI_ForeachEnv( add_variable, track_vars_array ); + add_variable("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array ); +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) + } else { + LSAPI_ForeachHeader( add_variable_magic_quote, track_vars_array ); + LSAPI_ForeachEnv( add_variable_magic_quote, track_vars_array ); + add_variable_magic_quote("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array ); + } +#endif + php_import_environment_variables(track_vars_array TSRMLS_CC); + } else { + php_import_environment_variables(track_vars_array TSRMLS_CC); - php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); + php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); + php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); + php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); + php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); + php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); - } + } } /* }}} */ @@ -205,11 +289,11 @@ static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) */ static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) { - if ( lsapi_mode ) { - return LSAPI_ReadReqBody( buffer, count_bytes ); - } else { - return 0; - } + if ( lsapi_mode ) { + return LSAPI_ReadReqBody( buffer, (unsigned long long)count_bytes ); + } else { + return 0; + } } /* }}} */ @@ -220,11 +304,11 @@ static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) */ static char *sapi_lsapi_read_cookies(TSRMLS_D) { - if ( lsapi_mode ) { - return LSAPI_GetHeader( H_COOKIE ); - } else { - return NULL; - } + if ( lsapi_mode ) { + return LSAPI_GetHeader( H_COOKIE ); + } else { + return NULL; + } } /* }}} */ @@ -233,33 +317,33 @@ static char *sapi_lsapi_read_cookies(TSRMLS_D) */ static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { - sapi_header_struct *h; - zend_llist_position pos; - if ( lsapi_mode ) { - LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); - - h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - LSAPI_AppendRespHeader(h->header, h->header_len); - } - h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); - } - if (SG(sapi_headers).send_default_content_type) { - char *hd; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - hd = sapi_get_default_content_type(TSRMLS_C); - len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, - "Content-type: %s", hd ); - efree(hd); - - LSAPI_AppendRespHeader( headerBuf, len ); - } - } - LSAPI_FinalizeRespHeaders(); - return SAPI_HEADER_SENT_SUCCESSFULLY; + sapi_header_struct *h; + zend_llist_position pos; + if ( lsapi_mode ) { + LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); + + h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); + while (h) { + if ( h->header_len > 0 ) { + LSAPI_AppendRespHeader(h->header, h->header_len); + } + h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); + } + if (SG(sapi_headers).send_default_content_type) { + char *hd; + int len; + char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; + + hd = sapi_get_default_content_type(TSRMLS_C); + len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, + "Content-type: %s", hd ); + efree(hd); + + LSAPI_AppendRespHeader( headerBuf, len ); + } + } + LSAPI_FinalizeRespHeaders(); + return SAPI_HEADER_SENT_SUCCESSFULLY; } @@ -270,8 +354,15 @@ static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) */ static void sapi_lsapi_log_message(char *message TSRMLS_DC) { - int len = strlen( message ); - LSAPI_Write_Stderr( message, len); + char buf[8192]; + int len = strlen( message ); + if ( *(message + len - 1 ) != '\n' ) + { + snprintf( buf, 8191, "%s\n", message ); + message = buf; + ++len; + } + LSAPI_Write_Stderr( message, len); } /* }}} */ @@ -280,158 +371,251 @@ static void sapi_lsapi_log_message(char *message TSRMLS_DC) */ static sapi_module_struct lsapi_sapi_module = { - "litespeed", - "LiteSpeed", + "litespeed", + "LiteSpeed V6.4", - php_lsapi_startup, /* startup */ - php_module_shutdown_wrapper, /* shutdown */ + php_lsapi_startup, /* startup */ + php_module_shutdown_wrapper, /* shutdown */ - NULL, /* activate */ - sapi_lsapi_deactivate, /* deactivate */ + NULL, /* activate */ + sapi_lsapi_deactivate, /* deactivate */ - sapi_lsapi_ub_write, /* unbuffered write */ - sapi_lsapi_flush, /* flush */ - NULL, /* get uid */ - sapi_lsapi_getenv, /* getenv */ + sapi_lsapi_ub_write, /* unbuffered write */ + sapi_lsapi_flush, /* flush */ + NULL, /* get uid */ + sapi_lsapi_getenv, /* getenv */ - php_error, /* error handler */ + php_error, /* error handler */ - NULL, /* header handler */ - sapi_lsapi_send_headers, /* send headers handler */ - NULL, /* send header handler */ + NULL, /* header handler */ + sapi_lsapi_send_headers, /* send headers handler */ + NULL, /* send header handler */ - sapi_lsapi_read_post, /* read POST data */ - sapi_lsapi_read_cookies, /* read Cookies */ + sapi_lsapi_read_post, /* read POST data */ + sapi_lsapi_read_cookies, /* read Cookies */ - sapi_lsapi_register_variables, /* register server variables */ - sapi_lsapi_log_message, /* Log message */ + sapi_lsapi_register_variables, /* register server variables */ + sapi_lsapi_log_message, /* Log message */ - NULL, /* php.ini path override */ - NULL, /* block interruptions */ - NULL, /* unblock interruptions */ - NULL, /* default post reader */ - NULL, /* treat data */ - NULL, /* executable location */ + NULL, /* php.ini path override */ + NULL, /* block interruptions */ + NULL, /* unblock interruptions */ + NULL, /* default post reader */ + NULL, /* treat data */ + NULL, /* executable location */ - 0, /* php.ini ignore */ + 0, /* php.ini ignore */ - STANDARD_SAPI_MODULE_PROPERTIES + STANDARD_SAPI_MODULE_PROPERTIES }; /* }}} */ static int init_request_info( TSRMLS_D ) { - char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); - char * pAuth; - - SG(request_info).content_type = pContentType ? pContentType : ""; - SG(request_info).request_method = LSAPI_GetRequestMethod(); - SG(request_info).query_string = LSAPI_GetQueryString(); - SG(request_info).request_uri = LSAPI_GetScriptName(); - SG(request_info).content_length = LSAPI_GetReqBodyLen(); - SG(request_info).path_translated = LSAPI_GetScriptFileName(); + char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); + char * pAuth; + + SG(request_info).content_type = pContentType ? pContentType : ""; + SG(request_info).request_method = LSAPI_GetRequestMethod(); + SG(request_info).query_string = LSAPI_GetQueryString(); + SG(request_info).request_uri = LSAPI_GetScriptName(); + SG(request_info).content_length = LSAPI_GetReqBodyLen(); + SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName()); + + /* It is not reset by zend engine, set it to 0. */ + SG(sapi_headers).http_response_code = 0; + + pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); + php_handle_auth_data(pAuth TSRMLS_CC); +} - /* It is not reset by zend engine, set it to 0. */ - SG(sapi_headers).http_response_code = 0; - - pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); - php_handle_auth_data(pAuth TSRMLS_CC); +static char s_cur_chdir[4096] = ""; + +static int lsapi_chdir_primary_script( zend_file_handle * file_handle ) +{ +#if PHP_MAJOR_VERSION > 4 + char * p; + char ch; + + SG(options) |= SAPI_OPTION_NO_CHDIR; + getcwd( s_cur_chdir, sizeof( s_cur_chdir ) ); + + p = strrchr( file_handle->filename, '/' ); + if ( *p ) + { + *p = 0; + if ( strcmp( file_handle->filename, s_cur_chdir ) != 0 ) { + chdir( file_handle->filename ); + } + *p++ = '/'; + ch = *p; + *p = 0; + if ( !CWDG(cwd).cwd || + ( strcmp( file_handle->filename, CWDG(cwd).cwd ) != 0 ) ) { + CWDG(cwd).cwd_length = p - file_handle->filename; + CWDG(cwd).cwd = (char *) realloc(CWDG(cwd).cwd, CWDG(cwd).cwd_length+1); + memmove( CWDG(cwd).cwd, file_handle->filename, CWDG(cwd).cwd_length+1 ); + } + *p = ch; + } + /* virtual_file_ex(&CWDG(cwd), file_handle->filename, NULL, CWD_REALPATH); */ +#else + VCWD_CHDIR_FILE( file_handle->filename ); +#endif + return 0; } -static int lsapi_module_main(int show_source TSRMLS_DC) +static int lsapi_fopen_primary_script( zend_file_handle * file_handle ) +{ + FILE * fp; + char * p; + fp = fopen( SG(request_info).path_translated, "rb" ); + if ( !fp ) + { + return -1; + } + file_handle->type = ZEND_HANDLE_FP; + file_handle->handle.fp = fp; + file_handle->filename = SG(request_info).path_translated; + file_handle->free_filename = 0; + file_handle->opened_path = NULL; + + lsapi_chdir_primary_script( file_handle ); + + return 0; +} + +static int lsapi_execute_script( zend_file_handle * file_handle TSRMLS_DC) { - zend_file_handle file_handle = {0}; + char *p; + int len; + file_handle->type = ZEND_HANDLE_FILENAME; + file_handle->handle.fd = 0; + file_handle->filename = SG(request_info).path_translated; + file_handle->free_filename = 0; + file_handle->opened_path = NULL; + + p = argv0; + *p++ = ':'; + len = strlen( SG(request_info).path_translated ); + if ( len > 45 ) + len = len - 45; + else + len = 0; + memccpy( p, SG(request_info).path_translated + len, 0, 46 ); + + php_execute_script(file_handle TSRMLS_CC); + return 0; - if (php_request_startup(TSRMLS_C) == FAILURE ) { - return -1; - } - if (show_source) { - zend_syntax_highlighter_ini syntax_highlighter_ini; +} - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.handle.fd = 0; - file_handle.filename = SG(request_info).path_translated; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - php_execute_script(&file_handle TSRMLS_CC); - } - zend_try { - php_request_shutdown(NULL); - } zend_end_try(); - return 0; +static int lsapi_module_main(int show_source TSRMLS_DC) +{ + zend_file_handle file_handle = {0}; + + if (php_request_startup(TSRMLS_C) == FAILURE ) { + return -1; + } + if (show_source) { + zend_syntax_highlighter_ini syntax_highlighter_ini; + + php_get_highlight_struct(&syntax_highlighter_ini); + highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); + } else { + lsapi_execute_script( &file_handle TSRMLS_CC); + } + zend_try { + php_request_shutdown(NULL); + memset( argv0, 0, 46 ); + } zend_end_try(); + return 0; } static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - int type = ZEND_INI_PERDIR; - if ( '\001' == *pKey ) { - ++pKey; - if ( *pKey == 4 ) { - type = ZEND_INI_SYSTEM; - } - ++pKey; - --keyLen; - zend_alter_ini_entry((char *)pKey, keyLen, - (char *)pValue, valLen, - type, PHP_INI_STAGE_ACTIVATE); - } - return 1; + int type = ZEND_INI_PERDIR; + if ( '\001' == *pKey ) { + ++pKey; + if ( *pKey == 4 ) { + type = ZEND_INI_SYSTEM; + } + ++pKey; + --keyLen; + if (( keyLen == 7 )&&( strncasecmp( pKey, "engine", 6 )== 0 )) + { + if ( *pValue == '0' ) + engine = 0; + } + else + zend_alter_ini_entry((char *)pKey, keyLen, + (char *)pValue, valLen, + type, PHP_INI_STAGE_ACTIVATE); + } + return 1; } static void override_ini() { - LSAPI_ForeachSpecialEnv( alter_ini, NULL ); + LSAPI_ForeachSpecialEnv( alter_ini, NULL ); } + static int processReq( TSRMLS_D ) { - int ret = 0; - zend_first_try { - /* avoid server_context==NULL checks */ - SG(server_context) = (void *) 1; - - init_request_info( TSRMLS_C ); - - override_ini(); - - if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { - ret = -1; - } - } zend_end_try(); - return ret; + int ret = 0; + zend_first_try { + + /* avoid server_context==NULL checks */ + SG(server_context) = (void *) 1; + + engine = 1; + override_ini(); + + if ( engine ) { + init_request_info( TSRMLS_C ); + + if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { + ret = -1; + } + } else { + LSAPI_AppendRespHeader( "status: 403", 11 ); + LSAPI_AppendRespHeader( "content-type: text/html", 23 ); + LSAPI_Write( "Forbidden: PHP engine is disable.\n", 34 ); + } + } zend_end_try(); + return ret; } static void cli_usage( TSRMLS_D ) { - static const char * usage = - "Usage: php\n" - " php -[b|c|h|i|q|s|v|?] [] [args...]\n" - " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" - " Run in Command Line Interpreter mode when parameters are specified\n" - "\n" - " -b | Bind Path for external LSAPI Server mode\n" - " -c | Look for php.ini file in this directory\n" - " -h This help\n" - " -i PHP information\n" - " -q Quiet-mode. Suppress HTTP Header output.\n" - " -s Display colour syntax highlighted source.\n" - " -v Version number\n" - " -? This help\n" - "\n" - " args... Arguments passed to script.\n"; - php_output_startup(); - php_output_activate(TSRMLS_C); - php_printf( "%s", usage ); + static const char * usage = + "Usage: php\n" + " php -[b|c|n|h|i|q|s|v|?] [] [args...]\n" + " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" + " Run in Command Line Interpreter mode when parameters are specified\n" + "\n" + " -b | Bind Path for external LSAPI Server mode\n" + " -c | Look for php.ini file in this directory\n" + " -n No php.ini file will be used\n" + " -h This help\n" + " -i PHP information\n" + " -l Syntax check\n" + " -q Quiet-mode. Suppress HTTP Header output.\n" + " -s Display colour syntax highlighted source.\n" + " -v Version number\n" + " -? This help\n" + "\n" + " args... Arguments passed to script.\n"; + php_output_startup(); + php_output_activate(TSRMLS_C); + php_printf( usage ); #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else @@ -440,349 +624,419 @@ static void cli_usage( TSRMLS_D ) } static int parse_opt( int argc, char * argv[], int *climode, - char **php_ini_path, char ** php_bind ) -{ - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int c; - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'b': - if ( p >= argend ) { - fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); - return -1; - } - *php_bind = *p++; - break; - - case 'c': - if ( p >= argend ) { - fprintf( stderr, " or must be specified following '-c' option.\n"); - - return -1; - } - *php_ini_path = *p++; - break; - case 's': - source_highlight = 1; - break; - case 'h': - case 'i': - case 'q': - case 'v': - case '?': - default: - *climode = 1; - break; - } - } - if ( p - argv < argc ) { - *climode = 1; - } - return 0; + char **php_ini_path, char ** php_bind ) +{ + char ** p = &argv[1]; + char ** argend= &argv[argc]; + int c; + while (( p < argend )&&(**p == '-' )) { + c = *((*p)+1); + ++p; + switch( c ) { + case 'b': + if ( p >= argend ) { + fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); + return -1; + } + *php_bind = strdup(*p++); + break; + + case 'c': + if ( p >= argend ) { + fprintf( stderr, " or must be specified following '-c' option.\n"); + + return -1; + } + *php_ini_path = strdup( *p++ ); + break; + case 's': + source_highlight = 1; + break; + case 'n': + ignore_php_ini = 1; + break; + case '?': + if ( *((*(p-1))+2) == 's' ) + exit( 99 ); + case 'h': + case 'i': + case 'l': + case 'q': + case 'v': + default: + *climode = 1; + break; + } + } + if ( p - argv < argc ) { + *climode = 1; + } + return 0; } static int cli_main( int argc, char * argv[] ) { - static const char * ini_defaults[] = { - "report_zend_debug", "0", - "display_errors", "1", - "register_argc_argv", "1", - "html_errors", "0", - "implicit_flush", "1", - "output_buffering", "0", - "max_execution_time", "0", - "max_input_time", "-1", - NULL - }; - - const char ** ini; - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int ret = 0; - int c; - lsapi_mode = 0; /* enter CLI mode */ + static const char * ini_defaults[] = { + "report_zend_debug", "0", + "display_errors", "1", + "register_argc_argv", "1", + "html_errors", "0", + "implicit_flush", "1", + "output_buffering", "0", + "max_execution_time", "0", + "max_input_time", "-1", + NULL + }; + + const char ** ini; + char ** p = &argv[1]; + char ** argend= &argv[argc]; + int ret = -1; + int c; + lsapi_mode = 0; /* enter CLI mode */ #ifdef PHP_WIN32 - _fmode = _O_BINARY; /*sets default for file streams to binary */ - setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ + _fmode = _O_BINARY; /*sets default for file streams to binary */ + setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ #endif - zend_first_try { - SG(server_context) = (void *) 1; - - zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ - CG(in_compilation) = 0; /* not initialized but needed for several options */ - EG(uninitialized_zval_ptr) = NULL; - - for( ini = ini_defaults; *ini; ini+=2 ) { - zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, - (char *)*(ini+1), strlen( *(ini+1) ), - PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - } - - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'q': - break; - case 'i': - if (php_request_startup(TSRMLS_C) != FAILURE) { - php_print_info(0xFFFFFFFF TSRMLS_CC); + zend_first_try { + SG(server_context) = (void *) 1; + + zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ + CG(in_compilation) = 0; /* not initialized but needed for several options */ + EG(uninitialized_zval_ptr) = NULL; + + for( ini = ini_defaults; *ini; ini+=2 ) { + zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, + (char *)*(ini+1), strlen( *(ini+1) ), + PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); + } + + while (( p < argend )&&(**p == '-' )) { + c = *((*p)+1); + ++p; + switch( c ) { + case 'q': + break; + case 'i': + if (php_request_startup(TSRMLS_C) != FAILURE) { + php_print_info(0xFFFFFFFF TSRMLS_CC); #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else php_end_ob_buffers(1 TSRMLS_CC); #endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'v': - if (php_request_startup(TSRMLS_C) != FAILURE) { + php_request_shutdown( NULL ); + ret = 0; + } + break; + case 'v': + if (php_request_startup(TSRMLS_C) != FAILURE) { #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #endif #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else php_end_ob_buffers(1 TSRMLS_CC); #endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'c': - ++p; - /* fall through */ - case 's': - break; - - case 'h': - case '?': - default: - cli_usage(TSRMLS_C); - ret = 1; - break; - - } - } - if ( !ret ) { - if ( *p ) { - zend_file_handle file_handle = {0}; - - file_handle.type = ZEND_HANDLE_FP; - file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); - - if ( file_handle.handle.fp ) { - script_filename = *p; - php_self = *p; - - SG(request_info).path_translated = *p; - SG(request_info).argc = argc - (p - argv); - SG(request_info).argv = p; - - if (php_request_startup(TSRMLS_C) == FAILURE ) { - fclose( file_handle.handle.fp ); - ret = 2; - } else { - if (source_highlight) { - zend_syntax_highlighter_ini syntax_highlighter_ini; - - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.filename = *p; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - - php_execute_script(&file_handle TSRMLS_CC); - } - - php_request_shutdown( NULL ); - } - } else { - php_printf("Could not open input file: %s.\n", *p); - } - } else { - cli_usage(TSRMLS_C); - } - } - - }zend_end_try(); - - php_module_shutdown(TSRMLS_C); + php_request_shutdown( NULL ); + ret = 0; + } + break; + case 'c': + ++p; + /* fall through */ + case 's': + break; + case 'l': + source_highlight = 2; + break; + case 'h': + case '?': + default: + cli_usage(TSRMLS_C); + ret = 0; + break; + + } + } + if ( ret == -1 ) { + if ( *p ) { + zend_file_handle file_handle = {0}; + + file_handle.type = ZEND_HANDLE_FP; + file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); + + if ( file_handle.handle.fp ) { + script_filename = *p; + php_self = *p; + + SG(request_info).path_translated = estrdup(*p); + SG(request_info).argc = argc - (p - argv); + SG(request_info).argv = p; + + if (php_request_startup(TSRMLS_C) == FAILURE ) { + fclose( file_handle.handle.fp ); + ret = 2; + } else { + if (source_highlight == 1) { + zend_syntax_highlighter_ini syntax_highlighter_ini; + + php_get_highlight_struct(&syntax_highlighter_ini); + highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); + } else if (source_highlight == 2) { + file_handle.filename = *p; + file_handle.free_filename = 0; + file_handle.opened_path = NULL; + ret = php_lint_script(&file_handle TSRMLS_CC); + if (ret==SUCCESS) { + zend_printf("No syntax errors detected in %s\n", file_handle.filename); + } else { + zend_printf("Errors parsing %s\n", file_handle.filename); + } + + } else { + file_handle.filename = *p; + file_handle.free_filename = 0; + file_handle.opened_path = NULL; + + php_execute_script(&file_handle TSRMLS_CC); + ret = EG(exit_status); + } + + php_request_shutdown( NULL ); + } + } else { + php_printf("Could not open input file: %s.\n", *p); + } + } else { + cli_usage(TSRMLS_C); + } + } + + }zend_end_try(); + + php_module_shutdown(TSRMLS_C); #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return ret; + return ret; } static int s_stop; void litespeed_cleanup(int signal) { - s_stop = signal; + s_stop = signal; } void start_children( int children ) { - struct sigaction act, old_term, old_quit, old_int, old_usr1; - int running = 0; - int status; - pid_t pid; - - /* Create a process group */ - setsid(); - - /* Set up handler to kill children upon exit */ - act.sa_flags = 0; - act.sa_handler = litespeed_cleanup; - if( sigaction( SIGTERM, &act, &old_term ) || - sigaction( SIGINT, &act, &old_int ) || - sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { - perror( "Can't set signals" ); - exit( 1 ); - } - s_stop = 0; - while( 1 ) { - while((!s_stop )&&( running < children )) { - pid = fork(); - switch( pid ) { - case 0: /* children process */ - - /* don't catch our signals */ - sigaction( SIGTERM, &old_term, 0 ); - sigaction( SIGQUIT, &old_quit, 0 ); - sigaction( SIGINT, &old_int, 0 ); - sigaction( SIGUSR1, &old_usr1, 0 ); - return ; - case -1: - perror( "php (pre-forking)" ); - exit( 1 ); - break; - default: /* parent process */ - running++; - break; - } - } - if ( s_stop ) { - break; - } - pid = wait( &status ); - running--; - } - kill( -getpgrp(), SIGUSR1 ); - exit( 0 ); + struct sigaction act, old_term, old_quit, old_int, old_usr1; + int running = 0; + int status; + pid_t pid; + + /* Create a process group */ + setsid(); + + /* Set up handler to kill children upon exit */ + act.sa_flags = 0; + act.sa_handler = litespeed_cleanup; + if( sigaction( SIGTERM, &act, &old_term ) || + sigaction( SIGINT, &act, &old_int ) || + sigaction( SIGUSR1, &act, &old_usr1 ) || + sigaction( SIGQUIT, &act, &old_quit )) { + perror( "Can't set signals" ); + exit( 1 ); + } + s_stop = 0; + while( 1 ) { + while((!s_stop )&&( running < children )) { + pid = fork(); + switch( pid ) { + case 0: /* children process */ + + /* don't catch our signals */ + sigaction( SIGTERM, &old_term, 0 ); + sigaction( SIGQUIT, &old_quit, 0 ); + sigaction( SIGINT, &old_int, 0 ); + sigaction( SIGUSR1, &old_usr1, 0 ); + return ; + case -1: + perror( "php (pre-forking)" ); + exit( 1 ); + break; + default: /* parent process */ + running++; + break; + } + } + if ( s_stop ) { + break; + } + pid = wait( &status ); + running--; + } + kill( -getpgrp(), SIGUSR1 ); + exit( 0 ); } - +void setArgv0( int argc, char * argv[] ) +{ + char * p; + int i; + argv0 = argv[0] + strlen( argv[0] ); + p = argv0; + while(( p > argv[0] )&&( p[-1] != '/')) + --p; + if ( p > argv[0] ) + { + memmove( argv[0], p, argv0 - p ); + memset( argv[0] + ( argv0 - p ), 0, p - argv[0] ); + argv0 = argv[0] + (argv0 - p); + } + for( i = 1; i < argc; ++i ) + { + memset( argv[i], 0, strlen( argv[i] ) ); + } +} #include int main( int argc, char * argv[] ) { - int ret; - int bindFd; - - char * php_ini_path = NULL; - char * php_bind = NULL; - char * p; - int n; - int climode = 0; - + int ret; + int bindFd; + + char * php_ini_path = NULL; + char * php_bind = NULL; + int n; + int climode = 0; + struct timeval tv_req_begin; + struct timeval tv_req_end; + int slow_script_msec = 0; + char time_buf[40]; + #ifdef HAVE_SIGNAL_H #if defined(SIGPIPE) && defined(SIG_IGN) - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); + tsrm_startup(1, 1, 0, NULL); #endif - if (argc > 1 ) { - if ( parse_opt( argc, argv, &climode, - &php_ini_path, &php_bind ) == -1 ) { - return 1; - } - } - if ( climode ) { - lsapi_sapi_module.phpinfo_as_text = 1; - } - sapi_startup(&lsapi_sapi_module); + if (argc > 1 ) { + if ( parse_opt( argc, argv, &climode, + &php_ini_path, &php_bind ) == -1 ) { + return 1; + } + } + if ( climode ) { + lsapi_sapi_module.phpinfo_as_text = 1; + } else { + setArgv0(argc, argv ); + } + + sapi_startup(&lsapi_sapi_module); #ifdef ZTS - compiler_globals = ts_resource(compiler_globals_id); - executor_globals = ts_resource(executor_globals_id); - core_globals = ts_resource(core_globals_id); - sapi_globals = ts_resource(sapi_globals_id); - tsrm_ls = ts_resource(0); + compiler_globals = ts_resource(compiler_globals_id); + executor_globals = ts_resource(executor_globals_id); + core_globals = ts_resource(core_globals_id); + sapi_globals = ts_resource(sapi_globals_id); + tsrm_ls = ts_resource(0); - SG(request_info).path_translated = NULL; + SG(request_info).path_translated = NULL; #endif - lsapi_sapi_module.executable_location = argv[0]; + lsapi_sapi_module.executable_location = argv[0]; + + if ( ignore_php_ini ) + lsapi_sapi_module.php_ini_ignore = 1; + + if ( php_ini_path ) { + lsapi_sapi_module.php_ini_path_override = php_ini_path; + } - if ( php_ini_path ) { - lsapi_sapi_module.php_ini_path_override = php_ini_path; - } - if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { + lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults; + + if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return FAILURE; - } - - if ( climode ) { - return cli_main(argc, argv); - } - - - if ( php_bind ) { - bindFd = LSAPI_CreateListenSock( php_bind, 10 ); - if ( bindFd == -1 ) { - fprintf( stderr, - "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); - exit( 2 ); - } - if ( bindFd != 0 ) { - dup2( bindFd, 0 ); - close( bindFd ); - } - } - - LSAPI_Init(); + return FAILURE; + } + + if ( climode ) { + return cli_main(argc, argv); + } + + if ( php_bind ) { + bindFd = LSAPI_CreateListenSock( php_bind, 10 ); + if ( bindFd == -1 ) { + fprintf( stderr, + "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); + exit( 2 ); + } + if ( bindFd != 0 ) { + dup2( bindFd, 0 ); + close( bindFd ); + } + } + + LSAPI_Init(); - LSAPI_Init_Env_Parameters( NULL ); - - if ( php_bind ) { - LSAPI_No_Check_ppid(); - } - - while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { - ret = processReq(TSRMLS_C); - LSAPI_Finish(); - if ( ret ) { - break; - } - } - php_module_shutdown(TSRMLS_C); + LSAPI_Init_Env_Parameters( NULL ); + + slow_script_msec = LSAPI_Get_Slow_Req_Msecs(); + + if ( php_bind ) { + LSAPI_No_Check_ppid(); + free( php_bind ); + php_bind = NULL; + } + + while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { + if ( slow_script_msec ) { + gettimeofday( &tv_req_begin, NULL ); + } + ret = processReq(TSRMLS_C); + if ( slow_script_msec ) { + gettimeofday( &tv_req_end, NULL ); + n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000 + + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000; + if ( n > slow_script_msec ) + { + strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) ); + fprintf( stderr, "[%s] Slow PHP script: %d ms\n URL: %s %s\n Query String: %s\n Script: %s\n", + time_buf, n, LSAPI_GetRequestMethod(), + LSAPI_GetScriptName(), LSAPI_GetQueryString(), + LSAPI_GetScriptFileName() ); + + } + } + LSAPI_Finish(); + if ( ret ) { + break; + } + } + php_module_shutdown(TSRMLS_C); #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return ret; + return ret; } @@ -795,49 +1049,51 @@ ZEND_END_ARG_INFO() PHP_FUNCTION(litespeed_request_headers); PHP_FUNCTION(litespeed_response_headers); +PHP_FUNCTION(apache_get_modules); PHP_MINFO_FUNCTION(litespeed); zend_function_entry litespeed_functions[] = { - PHP_FE(litespeed_request_headers, arginfo_litespeed__void) - PHP_FE(litespeed_response_headers, arginfo_litespeed__void) - PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) - PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) - PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) - {NULL, NULL, NULL} + PHP_FE(litespeed_request_headers, arginfo_litespeed__void) + PHP_FE(litespeed_response_headers, arginfo_litespeed__void) + PHP_FE(apache_get_modules, arginfo_litespeed__void) + PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) + PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) + PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) + {NULL, NULL, NULL} }; static PHP_MINIT_FUNCTION(litespeed) { - /* REGISTER_INI_ENTRIES(); */ - return SUCCESS; + /* REGISTER_INI_ENTRIES(); */ + return SUCCESS; } static PHP_MSHUTDOWN_FUNCTION(litespeed) { - /* UNREGISTER_INI_ENTRIES(); */ - return SUCCESS; + /* UNREGISTER_INI_ENTRIES(); */ + return SUCCESS; } zend_module_entry litespeed_module_entry = { - STANDARD_MODULE_HEADER, - "litespeed", - litespeed_functions, - PHP_MINIT(litespeed), - PHP_MSHUTDOWN(litespeed), - NULL, - NULL, - NULL, - NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + STANDARD_MODULE_HEADER, + "litespeed", + litespeed_functions, + PHP_MINIT(litespeed), + PHP_MSHUTDOWN(litespeed), + NULL, + NULL, + NULL, + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES }; static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); - return 1; + add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); + return 1; } @@ -845,13 +1101,13 @@ static int add_associate_array( const char * pKey, int keyLen, const char * pVal Fetch all HTTP request headers */ PHP_FUNCTION(litespeed_request_headers) { - /* TODO: */ - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - array_init(return_value); + /* TODO: */ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + array_init(return_value); - LSAPI_ForeachOrgHeader( add_associate_array, return_value ); + LSAPI_ForeachOrgHeader( add_associate_array, return_value ); } /* }}} */ @@ -862,45 +1118,62 @@ PHP_FUNCTION(litespeed_request_headers) Fetch all HTTP response headers */ PHP_FUNCTION(litespeed_response_headers) { - sapi_header_struct *h; - zend_llist_position pos; - char * p; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - - if (!&SG(sapi_headers).headers) { - RETURN_FALSE; - } - array_init(return_value); - - h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - p = strchr( h->header, ':' ); - len = p - h->header; - if (( p )&&( len > 0 )) { - memmove( headerBuf, h->header, len ); - while( len > 0 && (isspace( headerBuf[len-1])) ) { - --len; - } - headerBuf[len] = 0; - if ( len ) { - while( isspace(*++p)); - add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); - } - } - } - h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); - } + sapi_header_struct *h; + zend_llist_position pos; + char * p; + int len; + char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + if (!&SG(sapi_headers).headers) { + RETURN_FALSE; + } + array_init(return_value); + + h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); + while (h) { + if ( h->header_len > 0 ) { + p = strchr( h->header, ':' ); + len = p - h->header; + if (( p )&&( len > 0 )) { + memmove( headerBuf, h->header, len ); + while( len > 0 && (isspace( headerBuf[len-1])) ) { + --len; + } + headerBuf[len] = 0; + if ( len ) { + while( isspace(*++p)); + add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); + } + } + } + h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); + } } /* }}} */ +/* {{{ proto array apache_get_modules(void) + Fetch all loaded module names */ +PHP_FUNCTION(apache_get_modules) +{ + /* TODO: */ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + array_init(return_value); + add_next_index_string(return_value, "mod_rewrite", 1); + add_next_index_string(return_value, "mod_mime", 1); + add_next_index_string(return_value, "mod_headers", 1); + add_next_index_string(return_value, "mod_expires", 1); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/sapi/litespeed/lsapidef.h b/sapi/litespeed/lsapidef.h index c8940a930e947..5d5b4c1687a6c 100644 --- a/sapi/litespeed/lsapidef.h +++ b/sapi/litespeed/lsapidef.h @@ -1,25 +1,5 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: George Wang | - +----------------------------------------------------------------------+ -*/ - - /* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2005, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,6 +30,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*************************************************************************** + $Id: lsapidef.h,v 1.17 2012/12/01 19:23:31 gwang Exp $ + ------------------- + begin : Thu Feb 10 2005 + author : George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ #ifndef _LSAPIDEF_H_ #define _LSAPIDEF_H_ @@ -113,12 +100,14 @@ enum #define LSAPI_RESP_END 5 #define LSAPI_STDERR_STREAM 6 #define LSAPI_REQ_RECEIVED 7 +#define LSAPI_CONN_CLOSE 8 +#define LSAPI_INTERNAL_ERROR 9 #define LSAPI_MAX_HEADER_LEN 65535 #define LSAPI_MAX_DATA_PACKET_LEN 16384 -#define LSAPI_RESP_HTTP_HEADER_MAX 4096 +#define LSAPI_RESP_HTTP_HEADER_MAX 32768 #define LSAPI_PACKET_HEADER_LEN 8 diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 3a13000e11f28..4a9affc60f213 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1,25 +1,5 @@ /* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: George Wang | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -/* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2013, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,17 +30,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +/*************************************************************************** + lsapilib.c - description + ------------------- + begin : Mon Feb 21 2005 + copyright : (C) 2005 by George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ + #include +#include #include #include -#include -#include -#include -#include -#include +#include #include #include #include @@ -71,8 +55,48 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include + +#include "lsapilib.h" + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +#include +#endif + +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +#include +#endif + +#include +#ifndef uint32 +#define uint32 uint32_t +#endif + +struct lsapi_MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void lsapi_MD5Init(struct lsapi_MD5Context *context); +void lsapi_MD5Update(struct lsapi_MD5Context *context, unsigned char const *buf, + unsigned len); +void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *context); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct lsapi_MD5Context lsapi_MD5_CTX; + #define LSAPI_ST_REQ_HEADER 1 #define LSAPI_ST_REQ_BODY 2 @@ -83,11 +107,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define LSAPI_INIT_RESP_HEADER_LEN 4096 + static int g_inited = 0; static int g_running = 1; static int s_ppid; +static int s_slow_req_msecs = 0; +static int s_keepListener = 0; +static int s_dump_debug_info = 0; +static int s_pid_dump_debug_info = 0; + LSAPI_Request g_req = { -1, -1 }; +static char s_pSecret[24]; + + void Flush_RespBuf_r( LSAPI_Request * pReq ); static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] = @@ -111,13 +144,13 @@ static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] = "HTTP_TRANSFER_ENCODING" }; -static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18, - 22, 13, 18, 13, 24, 15, 10, 20, 8, 22 -}; +static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = +{ 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18, + 22, 13, 18, 13, 24, 15, 10, 20, 8, 22 }; -static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = { +static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = +{ "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Authorization", @@ -137,8 +170,8 @@ static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = { "Transfer-Encoding" }; -static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, /* user-agent */ +static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = +{ 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, //user-agent 13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17 }; @@ -160,7 +193,8 @@ static void lsapi_signal(int signo, sighandler_t handler) sigaction(signo, NULL, &sa); - if (sa.sa_handler == SIG_DFL) { + if (sa.sa_handler == SIG_DFL) + { sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; @@ -169,6 +203,34 @@ static void lsapi_signal(int signo, sighandler_t handler) } +static int s_enable_core_dump = 0; +static void lsapi_enable_core_dump() +{ +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + int mib[2]; + size_t len; + + len = 2; + if ( sysctlnametomib("kern.sugid_coredump", mib, &len) == 0 ) + { + len = sizeof(s_enable_core_dump); + if (sysctl(mib, 2, NULL, 0, &s_enable_core_dump, len) == -1) + perror( "sysctl: Failed to set 'kern.sugid_coredump', " + "core dump may not be available!"); + } + + +#endif + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if (prctl(PR_SET_DUMPABLE, s_enable_core_dump,0,0,0) == -1) + perror( "prctl: Failed to set dumpable, " + "core dump may not be available!"); +#endif +} + + static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader, char type, int len ) { @@ -199,75 +261,115 @@ static int lsapi_set_nblock( int fd, int nonblock ) return 0; } - static int lsapi_close( int fd ) { int ret; - while( 1 ) { + while( 1 ) + { ret = close( fd ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { + if (( ret == -1 )&&( errno == EINTR )&&(g_running)) continue; - } return ret; } } -static inline int lsapi_read( int fd, void * pBuf, int len ) +static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len ) { - int ret; - while( 1 ) { + ssize_t ret; + while( 1 ) + { ret = read( fd, (char *)pBuf, len ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { + if (( ret == -1 )&&( errno == EINTR )&&(g_running)) continue; - } return ret; } } +/* +static int lsapi_write( int fd, const void * pBuf, int len ) +{ + int ret; + const char * pCur; + const char * pEnd; + if ( len == 0 ) + return 0; + pCur = (const char *)pBuf; + pEnd = pCur + len; + while( g_running && (pCur < pEnd) ) + { + ret = write( fd, pCur, pEnd - pCur ); + if ( ret >= 0) + pCur += ret; + else if (( ret == -1 )&&( errno != EINTR )) + return ret; + } + return pCur - (const char *)pBuf; +} +*/ static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen ) { int ret; int left = totalLen; int n = count; - while(( left > 0 )&&g_running ) { + while(( left > 0 )&&g_running ) + { ret = writev( fd, *pVec, n ); - if ( ret > 0 ) { + if ( ret > 0 ) + { left -= ret; - if (( left <= 0)||( !g_running )) { + if (( left <= 0)||( !g_running )) return totalLen - left; - } - while( ret > 0 ) { - if ( (*pVec)->iov_len <= ret ) { + while( ret > 0 ) + { + if ( (*pVec)->iov_len <= (unsigned int )ret ) + { ret -= (*pVec)->iov_len; ++(*pVec); - } else { + } + else + { (*pVec)->iov_base = (char *)(*pVec)->iov_base + ret; (*pVec)->iov_len -= ret; break; } } - } else if ( ret == -1 ) { - if ( errno == EAGAIN ) { - if ( totalLen - left > 0 ) { + } + else if ( ret == -1 ) + { + if ( errno == EAGAIN ) + { + if ( totalLen - left > 0 ) return totalLen - left; - } else { + else return -1; - } - } else { - if ( errno != EINTR ) { - return ret; - } } + else if ( errno != EINTR ) + return ret; } } return totalLen - left; } +/* +static int getTotalLen( struct iovec * pVec, int count ) +{ + struct iovec * pEnd = pVec + count; + int total = 0; + while( pVec < pEnd ) + { + total += pVec->iov_len; + ++pVec; + } + return total; +} +*/ + static inline int allocateBuf( LSAPI_Request * pReq, int size ) { char * pBuf = (char *)realloc( pReq->m_pReqBuf, size ); - if ( pBuf ) { + if ( pBuf ) + { pReq->m_pReqBuf = pBuf; pReq->m_reqBufSize = size; pReq->m_pHeader = (struct lsapi_req_header *)pReq->m_pReqBuf; @@ -281,9 +383,8 @@ static int allocateIovec( LSAPI_Request * pReq, int n ) { struct iovec * p = (struct iovec *)realloc( pReq->m_pIovec, sizeof(struct iovec) * n ); - if ( !p ) { + if ( !p ) return -1; - } pReq->m_pIovecToWrite = p + ( pReq->m_pIovecToWrite - pReq->m_pIovec ); pReq->m_pIovecCur = p + ( pReq->m_pIovecCur - pReq->m_pIovec ); pReq->m_pIovec = p; @@ -294,9 +395,8 @@ static int allocateIovec( LSAPI_Request * pReq, int n ) static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size ) { char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size ); - if ( !p ) { + if ( !p ) return -1; - } pReq->m_pRespHeaderBufPos = p + ( pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf ); pReq->m_pRespHeaderBuf = p; pReq->m_pRespHeaderBufEnd = p + size; @@ -308,10 +408,10 @@ static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktTy { if (( LSAPI_VERSION_B0 != pHeader->m_versionB0 )|| ( LSAPI_VERSION_B1 != pHeader->m_versionB1 )|| - ( pktType != pHeader->m_type )) { + ( pktType != pHeader->m_type )) return -1; - } - if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) { + if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) + { register char b; b = pHeader->m_packetLen.m_bytes[0]; pHeader->m_packetLen.m_bytes[0] = pHeader->m_packetLen.m_bytes[3]; @@ -327,21 +427,20 @@ static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList, int *curSize, int newSize ) { struct LSAPI_key_value_pair * pBuf; - if ( *curSize >= newSize ) { + if ( *curSize >= newSize ) return 0; - } - if ( newSize > 8192 ) { + if ( newSize > 8192 ) return -1; - } pBuf = (struct LSAPI_key_value_pair *)realloc( *pEnvList, newSize * sizeof(struct LSAPI_key_value_pair) ); - if ( pBuf ) { + if ( pBuf ) + { *pEnvList = pBuf; *curSize = newSize; return 0; - } else { - return -1; } + else + return -1; } @@ -350,36 +449,32 @@ static inline int isPipe( int fd ) char achPeer[128]; socklen_t len = 128; if (( getpeername( fd, (struct sockaddr *)achPeer, &len ) != 0 )&& - ( errno == ENOTCONN )) { + ( errno == ENOTCONN )) return 0; - } else { + else return 1; - } } static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count, char **pBegin, char * pEnd ) { struct LSAPI_key_value_pair * pEnvEnd; - int keyLen = 0, valLen = 0; - if ( count > 8192 ) { + int keyLen = 0, valLen = 0; + if ( count > 8192 ) return -1; - } pEnvEnd = pEnvList + count; - while( pEnvList != pEnvEnd ) { - if ( pEnd - *pBegin < 4 ) { + while( pEnvList != pEnvEnd ) + { + if ( pEnd - *pBegin < 4 ) return -1; - } keyLen = *((unsigned char *)((*pBegin)++)); keyLen = (keyLen << 8) + *((unsigned char *)((*pBegin)++)); valLen = *((unsigned char *)((*pBegin)++)); valLen = (valLen << 8) + *((unsigned char *)((*pBegin)++)); - if ( *pBegin + keyLen + valLen > pEnd ) { + if ( *pBegin + keyLen + valLen > pEnd ) return -1; - } - if (( !keyLen )||( !valLen )) { + if (( !keyLen )||( !valLen )) return -1; - } pEnvList->pKey = *pBegin; *pBegin += keyLen; @@ -390,9 +485,8 @@ static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count, pEnvList->valLen = valLen - 1; ++pEnvList; } - if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) { + if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) return -1; - } *pBegin += 4; return 0; } @@ -427,8 +521,10 @@ static inline void fixEndian( LSAPI_Request * pReq ) static void fixHeaderIndexEndian( LSAPI_Request * pReq ) { int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { register char b; char * p = (char *)(&pReq->m_pHeaderIndex->m_headerLen[i]); b = p[0]; @@ -437,20 +533,434 @@ static void fixHeaderIndexEndian( LSAPI_Request * pReq ) swapIntEndian( &pReq->m_pHeaderIndex->m_headerOff[i] ); } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { swapIntEndian( &pCur->nameOff ); swapIntEndian( &pCur->nameLen ); swapIntEndian( &pCur->valueOff ); swapIntEndian( &pCur->valueLen ); ++pCur; } - } + } +} + +static uid_t s_uid = 0; +static uid_t s_defaultUid; //web server need set this +static gid_t s_defaultGid; + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + +#define LSAPI_LVE_DISABLED 0 +#define LSAPI_LVE_ENABLED 1 +#define LSAPI_CAGEFS_ENABLED 2 +#define LSAPI_CAGEFS_NO_SUEXEC 3 +struct liblve; +static int s_enable_lve = LSAPI_LVE_DISABLED; +static struct liblve * s_lve = NULL; + +static void *s_liblve; +static int (*fp_lve_is_available)(void) = NULL; +static int (*fp_lve_instance_init)(struct liblve *) = NULL; +static int (*fp_lve_destroy)(struct liblve *) = NULL; +static int (*fp_lve_enter)(struct liblve *, uint32_t, int32_t, int32_t, uint32_t *) = NULL; +static int (*fp_lve_leave)(struct liblve *, uint32_t *) = NULL; +static int (*fp_lve_jail)( struct passwd *, char *) = NULL; +static int lsapi_load_lve_lib() +{ + s_liblve = dlopen("liblve.so.0", RTLD_LAZY); + if (s_liblve) + { + fp_lve_is_available = dlsym(s_liblve, "lve_is_available"); + if (dlerror() == NULL) + { + if ( !(*fp_lve_is_available)() ) + { + int uid = getuid(); + if ( uid ) + { + setreuid( s_uid, uid ); + if ( !(*fp_lve_is_available)() ) + s_enable_lve = 0; + setreuid( uid, s_uid ); + } + } + } + } + else + { + s_enable_lve = LSAPI_LVE_DISABLED; + } + return (s_liblve)? 0 : -1; } +static int init_lve_ex() +{ + int rc; + if ( !s_liblve ) + return -1; + fp_lve_instance_init = dlsym(s_liblve, "lve_instance_init"); + fp_lve_destroy = dlsym(s_liblve, "lve_destroy"); + fp_lve_enter = dlsym(s_liblve, "lve_enter"); + fp_lve_leave = dlsym(s_liblve, "lve_leave"); + if ( s_enable_lve >= LSAPI_CAGEFS_ENABLED ) + fp_lve_jail = dlsym(s_liblve, "jail" ); + + if ( s_lve == NULL ) + { + rc = (*fp_lve_instance_init)(NULL); + s_lve = malloc(rc); + } + rc = (*fp_lve_instance_init)(s_lve); + if (rc != 0) + { + perror( "LSAPI: Unable to initialize LVE" ); + free( s_lve ); + s_lve = NULL; + return -1; + } + return 0; + +} + +#endif + + + +static int readSecret( const char * pSecretFile ) +{ + struct stat st; + int fd = open( pSecretFile, O_RDONLY , 0600 ); + if ( fd == -1 ) + { + fprintf( stderr, "LSAPI: failed to open secret file: %s!\n", pSecretFile ); + return -1; + } + if ( fstat( fd, &st ) == -1 ) + { + fprintf( stderr, "LSAPI: failed to check state of file: %s!\n", pSecretFile ); + close( fd ); + return -1; + } +/* + if ( st.st_uid != s_uid ) + { + fprintf( stderr, "LSAPI: file owner check failure: %s!\n", pSecretFile ); + close( fd ); + return -1; + } +*/ + if ( st.st_mode & 0077 ) + { + fprintf( stderr, "LSAPI: file permission check failure: %s\n", pSecretFile ); + close( fd ); + return -1; + } + if ( read( fd, s_pSecret, 16 ) < 16 ) + { + fprintf( stderr, "LSAPI: failed to read secret from secret file: %s\n", pSecretFile ); + close( fd ); + return -1; + } + close( fd ); + return 0; +} + +int LSAPI_is_suEXEC_Daemon() +{ + if (( !s_uid )&&( s_pSecret[0] )) + return 1; + else + return 0; +} + +static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 ) +{ + char achError[1024]; + int n = snprintf(achError, 1024, "%s:%s: %s\n", pErr1, (pErr2)?pErr2:"", strerror( errno ) ); + if ( pReq ) + LSAPI_Write_Stderr_r( pReq, achError, n ); + else + write( STDERR_FILENO, achError, n ); + return 0; +} + +static int lsapi_lve_error( LSAPI_Request * pReq ) +{ + static const char * headers[] = + { + "Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0", + "Pragma: no-cache", + "Retry-After: 60", + "Content-Type: text/html", + NULL + }; + static const char achBody[] = + "\n" + "\n508 Resource Limit Is Reached\n" + "\n" "

Resource Limit Is Reached

\n" + "The website is temporarily unable to service your request as it exceeded resource limit.\n" + "Please try again later.\n" + "
\n" + "\n"; + + LSAPI_ErrResponse_r( pReq, 508, headers, achBody, sizeof( achBody ) - 1 ); + return 0; +} + +static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid ) +{ +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_lve && uid ) //root user should not do that + { + uint32_t cookie; + int ret = -1; + ret = (*fp_lve_enter)(s_lve, uid, -1, -1, &cookie); + if ( ret < 0 ) + { + fprintf( stderr, "Pid (%d): enter LVE (%d) : ressult: %d !\n", getpid(), uid, ret ); + LSAPI_perror_r(pReq, "LSAPI: lve_enter() failure, reached resource limit.", NULL ); + lsapi_lve_error( pReq ); + return -1; + } + } +#endif + + return 0; +} + +static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw ) +{ + int ret = 0; +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + char error_msg[1024] = ""; + ret = (*fp_lve_jail)( pw, error_msg ); + if ( ret < 0 ) + { + fprintf( stderr, "LSAPI (%d): LVE jail(%d) ressult: %d, error: %s !\n", + getpid(), uid, ret, error_msg ); + LSAPI_perror_r( pReq, "LSAPI: jail() failure.", NULL ); + return -1; + } +#endif + return ret; +} + + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +static int lsapi_initLVE() +{ + const char * pEnv; + if ( (pEnv = getenv( "LSAPI_LVE_ENABLE" ))!= NULL ) + { + s_enable_lve = atol( pEnv ); + pEnv = NULL; + } + else if ( (pEnv = getenv( "LVE_ENABLE" ))!= NULL ) + { + s_enable_lve = atol( pEnv ); + pEnv = NULL; + } + if ( s_enable_lve && !s_uid ) + { + lsapi_load_lve_lib(); + if ( s_enable_lve ) + { + return init_lve_ex(); + } + + } + return 0; +} +#endif + + +static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * pChroot) +{ + int rv; + struct passwd * pw; + pw = getpwuid( uid ); +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_lve ) + { + if( lsapi_enterLVE( pReq, uid ) == -1 ) + return -1; + if ( pw && fp_lve_jail) + { + rv = lsapi_jailLVE( pReq, uid, pw ); + if ( rv == -1 ) + return -1; + if (( rv == 1 )&&(s_enable_lve == LSAPI_CAGEFS_NO_SUEXEC )) //this mode only use cageFS, does not use suEXEC + { + uid = s_defaultUid; + gid = s_defaultGid; + pw = getpwuid( uid ); + } + } + } +#endif + //if ( !uid || !gid ) //do not allow root + //{ + // return -1; + //} + +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + if ( s_enable_core_dump ) + lsapi_enable_core_dump(); +#endif + + rv = setgid(gid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setgid()", NULL); + return -1; + } + if ( pw && (pw->pw_gid == gid )) + { + rv = initgroups( pw->pw_name, gid ); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: initgroups()", NULL); + return -1; + } + } + else + { + rv = setgroups(1, &gid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setgroups()", NULL); + } + } + if ( pChroot ) + { + rv = chroot( pChroot ); + if ( rv == -1 ) + { + LSAPI_perror_r(pReq, "LSAPI: chroot()", NULL); + return -1; + } + } + rv = setuid(uid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setuid()", NULL); + return -1; + } +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_enable_core_dump ) + lsapi_enable_core_dump(); +#endif + return 0; +} + +static int lsapi_suexec_auth( LSAPI_Request *pReq, + char * pAuth, int len, char * pUgid, int ugidLen ) +{ + lsapi_MD5_CTX md5ctx; + unsigned char achMD5[16]; + if ( len < 32 ) + return -1; + memmove( achMD5, pAuth + 16, 16 ); + memmove( pAuth + 16, s_pSecret, 16 ); + lsapi_MD5Init( &md5ctx ); + lsapi_MD5Update( &md5ctx, (unsigned char *)pAuth, 32 ); + lsapi_MD5Update( &md5ctx, (unsigned char *)pUgid, 8 ); + lsapi_MD5Final( (unsigned char *)pAuth + 16, &md5ctx); + if ( memcmp( achMD5, pAuth + 16, 16 ) == 0 ) + return 0; + return 1; +} + + +static int lsapi_changeUGid( LSAPI_Request * pReq ) +{ + int uid = s_defaultUid; + int gid = s_defaultGid; + const char * pChroot = NULL; + struct LSAPI_key_value_pair * pEnv; + struct LSAPI_key_value_pair * pAuth; + int i; + if ( s_uid ) + return 0; + //with special ID 0x00 + //authenticate the suEXEC request; + //first one should be MD5( nonce + lscgid secret ) + //remember to clear the secret after verification + //it should be set at the end of special env + i = pReq->m_pHeader->m_cntSpecialEnv - 1; + if ( i >= 0 ) + { + pEnv = pReq->m_pSpecialEnvList + i; + if (( *pEnv->pKey == '\000' )&& + ( strcmp( pEnv->pKey+1, "SUEXEC_AUTH" ) == 0 )) + { + --pReq->m_pHeader->m_cntSpecialEnv; + pAuth = pEnv--; + if (( *pEnv->pKey == '\000' )&& + ( strcmp( pEnv->pKey+1, "SUEXEC_UGID" ) == 0 )) + { + --pReq->m_pHeader->m_cntSpecialEnv; + uid = *(uint32_t *)pEnv->pValue; + gid = *(((uint32_t *)pEnv->pValue) + 1 ); + //fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid ); + } + else + { + fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" ); + pEnv = NULL; + } + if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 ) + { + //read UID, GID from specialEnv + + } + else + { + //authentication error + fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" ); + uid = 0; + } + } + else + { + //fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" ); + } + } + + + if ( !uid ) + { + uid = s_defaultUid; + gid = s_defaultGid; + } + + //change uid + if ( setUID_LVE( pReq, uid, gid, pChroot ) == -1 ) + { + return -1; + } + + s_uid = uid; + + return 0; + +} + +static int parseContentLenFromHeader(LSAPI_Request * pReq) +{ + const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH ); + if ( pContentLen ) + pReq->m_reqBodyLen = strtoll( pContentLen, NULL, 10 ); + return 0; +} + + static int parseRequest( LSAPI_Request * pReq, int totalLen ) { int shouldFixEndian; @@ -458,29 +968,28 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen ) char * pEnd = pReq->m_pReqBuf + totalLen; shouldFixEndian = ( LSAPI_ENDIAN != ( pReq->m_pHeader->m_pktHeader.m_flag & LSAPI_ENDIAN_BIT ) ); - if ( shouldFixEndian ) { + if ( shouldFixEndian ) + { fixEndian( pReq ); } if ( (pReq->m_specialEnvListSize < pReq->m_pHeader->m_cntSpecialEnv )&& allocateEnvList( &pReq->m_pSpecialEnvList, - &pReq->m_specialEnvListSize, - pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) { + &pReq->m_specialEnvListSize, + pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) return -1; - } if ( (pReq->m_envListSize < pReq->m_pHeader->m_cntEnv )&& allocateEnvList( &pReq->m_pEnvList, &pReq->m_envListSize, - pReq->m_pHeader->m_cntEnv ) == -1 ) { + pReq->m_pHeader->m_cntEnv ) == -1 ) return -1; - } + if ( parseEnv( pReq->m_pSpecialEnvList, - pReq->m_pHeader->m_cntSpecialEnv, - &pBegin, pEnd ) == -1 ) { + pReq->m_pHeader->m_cntSpecialEnv, + &pBegin, pEnd ) == -1 ) return -1; - } if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, - &pBegin, pEnd ) == -1 ) { + &pBegin, pEnd ) == -1 ) return -1; - } + pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff; pReq->m_pScriptName = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff; pReq->m_pQueryString = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff; @@ -496,85 +1005,183 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen ) pReq->m_pHttpHeader = pBegin; pBegin += pReq->m_pHeader->m_httpHeaderLen; - if ( pBegin != pEnd ) { + if ( pBegin != pEnd ) + { + fprintf( stderr, "%d: request header does match total size, total: %d, real: %ld\n", getpid(), totalLen, + pBegin - pReq->m_pReqBuf ); return -1; } - - if ( shouldFixEndian ) { + if ( shouldFixEndian ) + { fixHeaderIndexEndian( pReq ); } - + pReq->m_reqBodyLen = pReq->m_pHeader->m_reqBodyLen; + if ( pReq->m_reqBodyLen == -2 ) + { + parseContentLenFromHeader(pReq); + } + return 0; } -static struct lsapi_packet_header ack = {'L', 'S', +//OPTIMIZATION +static char s_accept_notify = 0; +static char s_schedule_notify = 0; +static char s_notify_scheduled = 0; +static char s_notified_pid = 0; + +static struct lsapi_packet_header s_ack = {'L', 'S', LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }; -static inline int notify_req_received( LSAPI_Request * pReq ) + + +static inline int write_req_received_notification( int fd ) { - if ( write( pReq->m_fd, &ack, LSAPI_PACKET_HEADER_LEN ) - < LSAPI_PACKET_HEADER_LEN ) { + if ( write( fd, &s_ack, LSAPI_PACKET_HEADER_LEN ) + < LSAPI_PACKET_HEADER_LEN ) return -1; + return 0; +} + +static void lsapi_sigalarm( int sig ) +{ + if ( s_notify_scheduled ) + { + s_notify_scheduled = 0; + if ( g_req.m_fd != -1 ) + write_req_received_notification( g_req.m_fd ); + } +} + +static inline int lsapi_schedule_notify() +{ + if ( !s_notify_scheduled ) + { + alarm( 2 ); + s_notify_scheduled = 1; } return 0; } +static inline int notify_req_received( int fd ) +{ + if ( s_schedule_notify ) + return lsapi_schedule_notify(); + return write_req_received_notification( fd ); + +} + + +static inline int lsapi_notify_pid( int fd ) +{ + char achBuf[16]; + lsapi_buildPacketHeader( (struct lsapi_packet_header *)achBuf, LSAPI_STDERR_STREAM, + 8 + LSAPI_PACKET_HEADER_LEN ); + memmove( &achBuf[8], "\0PID", 4 ); + *((int *)&achBuf[12]) = getpid(); + + if ( write( fd, achBuf, 16 ) < 16 ) + return -1; + return 0; +} + +static char s_conn_key_packet[16]; +static inline int init_conn_key( int fd ) +{ + struct lsapi_packet_header * pHeader = (struct lsapi_packet_header *)s_conn_key_packet; + struct timeval tv; + int i; + gettimeofday( &tv, NULL ); + srand( (tv.tv_sec % 0x1000 + tv.tv_usec) ^ rand() ); + for( i = 8; i < 16; ++i ) + { + s_conn_key_packet[i]=(int) (256.0*rand()/(RAND_MAX+1.0)); + } + lsapi_buildPacketHeader( pHeader, LSAPI_REQ_RECEIVED, + 8 + LSAPI_PACKET_HEADER_LEN ); + if ( write( fd, s_conn_key_packet, LSAPI_PACKET_HEADER_LEN+8 ) + < LSAPI_PACKET_HEADER_LEN+8 ) + return -1; + return 0; + + +} static int readReq( LSAPI_Request * pReq ) { int len; int packetLen; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if ( pReq->m_reqBufSize < 8192 ) { - if ( allocateBuf( pReq, 8192 ) == -1 ) { + if ( pReq->m_reqBufSize < 8192 ) + { + if ( allocateBuf( pReq, 8192 ) == -1 ) return -1; - } } - while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) { + while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) + { len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf, pReq->m_reqBufSize ); - if ( len <= 0 ) { + if ( len <= 0 ) return -1; - } pReq->m_bufRead += len; } pReq->m_reqState = LSAPI_ST_REQ_HEADER; packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST ); - if ( packetLen < 0 ) { + if ( packetLen < 0 ) + { + fprintf( stderr, "%d: packetLen < 0\n", getpid() ); return -1; } - if ( packetLen > LSAPI_MAX_HEADER_LEN ) { + if ( packetLen > LSAPI_MAX_HEADER_LEN ) + { + fprintf( stderr, "%d: packetLen > %d\n", getpid(), LSAPI_MAX_HEADER_LEN ); return -1; } - if ( packetLen + 1024 > pReq->m_reqBufSize ) { - if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) { + if ( packetLen + 1024 > pReq->m_reqBufSize ) + { + if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) return -1; - } } - while( packetLen > pReq->m_bufRead ) { + while( packetLen > pReq->m_bufRead ) + { len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, packetLen - pReq->m_bufRead ); - if ( len <= 0 ) { + if ( len <= 0 ) return -1; - } pReq->m_bufRead += len; } - if ( parseRequest( pReq, packetLen ) < 0 ) { + if ( parseRequest( pReq, packetLen ) < 0 ) + { + fprintf( stderr, "%d: parseRequest error\n", getpid() ); return -1; } - pReq->m_bufProcessed = packetLen; + pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER; - return notify_req_received( pReq ); + if ( !s_uid ) + if ( lsapi_changeUGid( pReq ) ) + return -1; + pReq->m_bufProcessed = packetLen; + + //OPTIMIZATION + if ( !s_accept_notify && !s_notified_pid ) + return notify_req_received( pReq->m_fd ); + else + { + s_notified_pid = 0; + return 0; + } } int LSAPI_Init(void) { - if ( !g_inited ) { + if ( !g_inited ) + { + s_uid = geteuid(); + s_pSecret[0] = 0; lsapi_signal(SIGPIPE, lsapi_sigpipe); lsapi_signal(SIGUSR1, lsapi_siguser1); @@ -583,11 +1190,9 @@ int LSAPI_Init(void) #endif /* let STDOUT function as STDERR, just in case writing to STDOUT directly */ - dup2( 2, 1 ); - - if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) { + dup2( 2, 1 ); + if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) return -1; - } g_inited = 1; s_ppid = getppid(); } @@ -606,28 +1211,27 @@ int LSAPI_IsRunning(void) int LSAPI_InitRequest( LSAPI_Request * pReq, int fd ) { - if ( !pReq ) { + if ( !pReq ) return -1; - } memset( pReq, 0, sizeof( LSAPI_Request ) ); - if ( allocateIovec( pReq, 16 ) == -1 ) { + if ( allocateIovec( pReq, 16 ) == -1 ) return -1; - } pReq->m_pRespBuf = pReq->m_pRespBufPos = (char *)malloc( LSAPI_RESP_BUF_SIZE ); - if ( !pReq->m_pRespBuf ) { + if ( !pReq->m_pRespBuf ) return -1; - } pReq->m_pRespBufEnd = pReq->m_pRespBuf + LSAPI_RESP_BUF_SIZE; pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1; pReq->m_respPktHeaderEnd = &pReq->m_respPktHeader[5]; - if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) { + if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) return -1; - } - if ( isPipe( fd ) ) { + if ( isPipe( fd ) ) + { pReq->m_fdListen = -1; pReq->m_fd = fd; - } else { + } + else + { pReq->m_fdListen = fd; pReq->m_fd = -1; lsapi_set_nblock( fd, 1 ); @@ -653,38 +1257,48 @@ int LSAPI_Accept_r( LSAPI_Request * pReq ) socklen_t len; int nodelay = 1; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if ( LSAPI_Finish_r( pReq ) == -1 ) { + if ( LSAPI_Finish_r( pReq ) == -1 ) return -1; - } - while( g_running ) { - if ( pReq->m_fd == -1 ) { - if ( pReq->m_fdListen != -1) { + lsapi_set_nblock( pReq->m_fdListen , 0 ); + while( g_running ) + { + if ( pReq->m_fd == -1 ) + { + if ( pReq->m_fdListen != -1) + { len = sizeof( achPeer ); pReq->m_fd = accept( pReq->m_fdListen, (struct sockaddr *)&achPeer, &len ); - if ( pReq->m_fd == -1 ) { - if (( errno == EINTR )||( errno == EAGAIN)) { + if ( pReq->m_fd == -1 ) + { + if (( errno == EINTR )||( errno == EAGAIN)) continue; - } else { + else return -1; - } - } else { + } + else + { lsapi_set_nblock( pReq->m_fd , 0 ); - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { + if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) + { setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&nodelay, sizeof(nodelay)); + (char *)&nodelay, sizeof(nodelay)); } + //init_conn_key( pReq->m_fd ); + //OPTIMIZATION + if ( s_accept_notify ) + if ( notify_req_received( pReq->m_fd ) == -1 ) + return -1; } - } else { - return -1; } + else + return -1; } - if ( !readReq( pReq ) ) { + if ( !readReq( pReq ) ) break; - } + //abort(); lsapi_close( pReq->m_fd ); pReq->m_fd = -1; LSAPI_Reset_r( pReq ); @@ -698,15 +1312,18 @@ static struct lsapi_packet_header finish = {'L', 'S', int LSAPI_Finish_r( LSAPI_Request * pReq ) { /* finish req body */ - if ( !pReq ) { + if ( !pReq ) return -1; - } - if (pReq->m_reqState) { - if ( pReq->m_fd != -1 ) { - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { + if (pReq->m_reqState) + { + if ( pReq->m_fd != -1 ) + { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { LSAPI_FinalizeRespHeaders_r( pReq ); } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { Flush_RespBuf_r( pReq ); } @@ -735,18 +1352,14 @@ void LSAPI_Reset_r( LSAPI_Request * pReq ) int LSAPI_Release_r( LSAPI_Request * pReq ) { - if ( pReq->m_pReqBuf ) { + if ( pReq->m_pReqBuf ) free( pReq->m_pReqBuf ); - } - if ( pReq->m_pSpecialEnvList ) { + if ( pReq->m_pSpecialEnvList ) free( pReq->m_pSpecialEnvList ); - } - if ( pReq->m_pEnvList ) { + if ( pReq->m_pEnvList ) free( pReq->m_pEnvList ); - } - if ( pReq->m_pRespHeaderBuf ) { + if ( pReq->m_pRespHeaderBuf ) free( pReq->m_pRespHeaderBuf ); - } return 0; } @@ -754,55 +1367,48 @@ int LSAPI_Release_r( LSAPI_Request * pReq ) char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ) { int off; - if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) { + if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) return NULL; - } off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ]; - if ( !off ) { + if ( !off ) return NULL; - } - if ( *(pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) { - *( pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; - } + if ( *(pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) + *( pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; return pReq->m_pHttpHeader + off; } static int readBodyToReqBuf( LSAPI_Request * pReq ) { - int bodyLeft; - int len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { + off_t bodyLeft; + ssize_t len = pReq->m_bufRead - pReq->m_bufProcessed; + if ( len > 0 ) return len; - } pReq->m_bufRead = pReq->m_bufProcessed = pReq->m_pHeader->m_pktHeader.m_packetLen.m_iLen; - bodyLeft = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + bodyLeft = pReq->m_reqBodyLen - pReq->m_reqBodyRead; len = pReq->m_reqBufSize - pReq->m_bufRead; - if ( len < 0 ) { + if ( len < 0 ) return -1; - } - if ( len > bodyLeft ) { + if ( len > bodyLeft ) len = bodyLeft; - } + len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, len ); - if ( len > 0 ) { + if ( len > 0 ) pReq->m_bufRead += len; - } return len; } int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ) { - if (!pReq || (pReq->m_fd ==-1) ) { + if (!pReq || (pReq->m_fd ==-1) ) return EOF; - } - if ( pReq->m_bufProcessed >= pReq->m_bufRead ) { - if ( readBodyToReqBuf( pReq ) <= 0 ) { + if ( pReq->m_bufProcessed >= pReq->m_bufRead ) + { + if ( readBodyToReqBuf( pReq ) <= 0 ) return EOF; - } } ++pReq->m_reqBodyRead; return (unsigned char)*(pReq->m_pReqBuf + pReq->m_bufProcessed++); @@ -810,42 +1416,43 @@ int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ) -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ) +int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF ) { - int len; - int left; + ssize_t len; + ssize_t left; char * pBufEnd = pBuf + bufLen - 1; char * pBufCur = pBuf; char * pCur; char * p; - if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) { + if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) return -1; - } *getLF = 0; - while( (left = pBufEnd - pBufCur ) > 0 ) { + while( (left = pBufEnd - pBufCur ) > 0 ) + { len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len <= 0 ) { - if ( (len = readBodyToReqBuf( pReq )) <= 0 ) { + if ( len <= 0 ) + { + if ( (len = readBodyToReqBuf( pReq )) <= 0 ) + { *getLF = 1; break; } } - if ( len > left ) { + if ( len > left ) len = left; - } pCur = pReq->m_pReqBuf + pReq->m_bufProcessed; p = memchr( pCur, '\n', len ); - if ( p ) { + if ( p ) len = p - pCur + 1; - } memmove( pBufCur, pCur, len ); pBufCur += len; pReq->m_bufProcessed += len; pReq->m_reqBodyRead += len; - if ( p ) { + if ( p ) + { *getLF = 1; break; } @@ -856,48 +1463,47 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int * } -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen ) +ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen ) { - int len; - int total; + ssize_t len; + off_t total; /* char *pOldBuf = pBuf; */ - if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) { + if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) return -1; - } - total = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + + total = pReq->m_reqBodyLen - pReq->m_reqBodyRead; - if ( total <= 0 ) { + if ( total <= 0 ) return 0; - } - if ( total < bufLen ) { + if ( total < bufLen ) bufLen = total; - } total = 0; len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { - if ( len > bufLen ) { + if ( len > 0 ) + { + if ( len > bufLen ) len = bufLen; - } memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len ); pReq->m_bufProcessed += len; total += len; pBuf += len; bufLen -= len; } - while( bufLen > 0 ) { + while( bufLen > 0 ) + { len = lsapi_read( pReq->m_fd, pBuf, bufLen ); - if ( len > 0 ) { + if ( len > 0 ) + { total += len; pBuf += len; bufLen -= len; - } else { - if ( len <= 0 ) { - if ( !total) { - return -1; - } - break; - } + } + else if ( len <= 0 ) + { + if ( !total) + return -1; + break; } } pReq->m_reqBodyRead += total; @@ -906,37 +1512,52 @@ int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen ) } -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) +ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) { struct lsapi_packet_header * pHeader; const char * pEnd; const char * p; - int bufLen; - int toWrite; - int packetLen; + ssize_t bufLen; + ssize_t toWrite; + ssize_t packetLen; + int skip = 0; - if ( !pReq || !pBuf || (pReq->m_fd == -1) ) { + if ( !pReq || !pBuf || (pReq->m_fd == -1) ) return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); +/* + if ( *pBuf == '\r' ) + { + ++skip; + } + if ( *pBuf == '\n' ) + { + ++skip; + } +*/ } - if ( len < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) { - memmove( pReq->m_pRespBufPos, pBuf, len ); - pReq->m_pRespBufPos += len; + pReq->m_reqState |= LSAPI_ST_RESP_BODY; + + if ( (len - skip) < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) + { + memmove( pReq->m_pRespBufPos, pBuf + skip, len - skip ); + pReq->m_pRespBufPos += len - skip; return len; } - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { - LSAPI_FinalizeRespHeaders_r( pReq ); - } - pReq->m_reqState |= LSAPI_ST_RESP_BODY; pHeader = pReq->m_respPktHeader; - p = pBuf; + p = pBuf + skip; pEnd = pBuf + len; bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf; - while( ( toWrite = pEnd - p ) > 0 ) { + while( ( toWrite = pEnd - p ) > 0 ) + { packetLen = toWrite + bufLen; - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { + if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) + { packetLen = LSAPI_MAX_DATA_PACKET_LEN; toWrite = packetLen - bufLen; } @@ -949,7 +1570,8 @@ int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; ++pReq->m_pIovecCur; ++pHeader; - if ( bufLen > 0 ) { + if ( bufLen > 0 ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; pReq->m_pIovecCur->iov_len = bufLen; pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -962,21 +1584,108 @@ int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) ++pReq->m_pIovecCur; p += toWrite; - if ( pHeader >= pReq->m_respPktHeaderEnd - 1) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { + if ( pHeader >= pReq->m_respPktHeaderEnd - 1) + { + if ( LSAPI_Flush_r( pReq ) == -1 ) return -1; - } pHeader = pReq->m_respPktHeader; } } - if ( pHeader != pReq->m_respPktHeader ) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { + if ( pHeader != pReq->m_respPktHeader ) + if ( LSAPI_Flush_r( pReq ) == -1 ) return -1; - } - } return p - pBuf; } +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) +ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size ) +{ + ssize_t ret; + off_t written; + ret = sendfile( fdIn, fdOut, *off, size, NULL, &written, 0 ); + if ( written > 0 ) + { + ret = written; + *off += ret; + } + return ret; +} +#endif + +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size ) +{ + ssize_t ret; + off_t len = size; + ret = sendfile( fdIn, fdOut, *off, &len, NULL, 0 ); + if (( ret == 0 )&&( len > 0 )) + { + ret = len; + *off += len; + } + return ret; +} +#endif + +#if defined(sun) || defined(__sun) +#include +ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size ) +{ + int n = 0 ; + sendfilevec_t vec[1]; + + vec[n].sfv_fd = fdIn; + vec[n].sfv_flag = 0; + vec[n].sfv_off = *off; + vec[n].sfv_len = size; + ++n; + + size_t written; + ssize_t ret = sendfilev( fdOut, vec, n, &written ); + if (( !ret )||( errno == EAGAIN )) + ret = written; + if ( ret > 0 ) + *off += ret; + return ret; +} +#endif + +#if defined(linux) || defined(__linux) || defined(__linux__) || \ + defined(__gnu_linux__) +#include +#define gsendfile sendfile +#endif +#if defined(HPUX) +ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size ) +{ + return sendfile( fdOut, fdIn, off, size, NULL, 0 ); +} +#endif + +ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size ) +{ + struct lsapi_packet_header * pHeader = pReq->m_respPktHeader; + if ( !pReq || (pReq->m_fd == -1) || fdIn == -1 ) + return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); + } + pReq->m_reqState |= LSAPI_ST_RESP_BODY; + + LSAPI_Flush_r(pReq); + + lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM, + size + LSAPI_PACKET_HEADER_LEN ); + + + if (write(pReq->m_fd, (const char *) pHeader, LSAPI_PACKET_HEADER_LEN ) != LSAPI_PACKET_HEADER_LEN) + return -1; + + return gsendfile( pReq->m_fd, fdIn, off, size ); +} + + void Flush_RespBuf_r( LSAPI_Request * pReq ) { struct lsapi_packet_header * pHeader = pReq->m_respPktHeader; @@ -990,7 +1699,8 @@ void Flush_RespBuf_r( LSAPI_Request * pReq ) pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; ++pReq->m_pIovecCur; ++pHeader; - if ( bufLen > 0 ) { + if ( bufLen > 0 ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; pReq->m_pIovecCur->iov_len = bufLen; pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -1006,32 +1716,35 @@ int LSAPI_Flush_r( LSAPI_Request * pReq ) { int ret = 0; int n; - if ( !pReq ) { + if ( !pReq ) return -1; - } n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) { + if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) return 0; - } - if ( pReq->m_fd == -1 ) { + if ( pReq->m_fd == -1 ) + { pReq->m_pRespBufPos = pReq->m_pRespBuf; pReq->m_totalLen = 0; pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec; return -1; } - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { LSAPI_FinalizeRespHeaders_r( pReq ); } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { Flush_RespBuf_r( pReq ); } n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if ( n > 0 ) { + if ( n > 0 ) + { ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite, n, pReq->m_totalLen ); - if ( ret < pReq->m_totalLen ) { + if ( ret < pReq->m_totalLen ) + { lsapi_close( pReq->m_fd ); pReq->m_fd = -1; ret = -1; @@ -1043,32 +1756,33 @@ int LSAPI_Flush_r( LSAPI_Request * pReq ) } -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) +ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) { struct lsapi_packet_header header; const char * pEnd; const char * p; - int packetLen; - int totalLen; + ssize_t packetLen; + ssize_t totalLen; int ret; struct iovec iov[2]; struct iovec *pIov; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) { + if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) return write( 2, pBuf, len ); - } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { LSAPI_Flush_r( pReq ); } p = pBuf; pEnd = pBuf + len; - while( ( packetLen = pEnd - p ) > 0 ) { - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { + while( ( packetLen = pEnd - p ) > 0 ) + { + if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) + { packetLen = LSAPI_MAX_DATA_PACKET_LEN; } @@ -1085,7 +1799,8 @@ int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) pIov = iov; ret = lsapi_writev( pReq->m_fd, &pIov, 2, totalLen ); - if ( ret < totalLen ) { + if ( ret < totalLen ) + { lsapi_close( pReq->m_fd ); pReq->m_fd = -1; ret = -1; @@ -1097,14 +1812,16 @@ int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) { int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { + if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; - } } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { const char *p; char *pKey; char *pKeyEnd; @@ -1112,22 +1829,22 @@ static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; pKeyEnd = pKey + keyLen; p = &name[5]; - while(( pKey < pKeyEnd )&&( *p )) { + while(( pKey < pKeyEnd )&&( *p )) + { char ch = toupper( *pKey ); - if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) { + if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) break; - } ++p; ++pKey; } - if (( pKey == pKeyEnd )&& (!*p )) { + if (( pKey == pKeyEnd )&& (!*p )) return pReq->m_pHttpHeader + pCur->valueOff; - } ++pCur; } } @@ -1139,21 +1856,35 @@ char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ) { struct LSAPI_key_value_pair * pBegin = pReq->m_pEnvList; struct LSAPI_key_value_pair * pEnd = pBegin + pReq->m_pHeader->m_cntEnv; - if ( !pReq || !name ) { + if ( !pReq || !name ) return NULL; - } - if ( strncmp( name, "HTTP_", 5 ) == 0 ) { + if ( strncmp( name, "HTTP_", 5 ) == 0 ) + { return GetHeaderVar( pReq, name ); } - while( pBegin < pEnd ) { - if ( strcmp( name, pBegin->pKey ) == 0 ) { + while( pBegin < pEnd ) + { + if ( strcmp( name, pBegin->pKey ) == 0 ) return pBegin->pValue; - } ++pBegin; } return NULL; } +struct _headerInfo +{ + const char * _name; + int _nameLen; + const char * _value; + int _valueLen; +}; + +int compareValueLocation(const void * v1, const void *v2 ) +{ + return ((const struct _headerInfo *)v1)->_value - + ((const struct _headerInfo *)v2)->_value; +} + int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { @@ -1162,43 +1893,66 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, char * pValue; int ret; int count = 0; - if ( !pReq || !fn ) { + struct _headerInfo headers[512]; + if ( !pReq || !fn ) return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { len = pReq->m_pHeaderIndex->m_headerLen[i]; pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; *(pValue + len ) = 0; - ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i], - pValue, len, arg ); + headers[count]._name = HTTP_HEADERS[i]; + headers[count]._nameLen = HTTP_HEADER_LEN[i]; + headers[count]._value = pValue; + headers[count]._valueLen = len; ++count; - if ( ret <= 0 ) { - return ret; - } + + //ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i], + // pValue, len, arg ); + //if ( ret <= 0 ) + // return ret; } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { char *pKey; int keyLen; struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; pValue = pReq->m_pHttpHeader + pCur->valueOff; *(pValue + pCur->valueLen ) = 0; - ret = (*fn)( pKey, keyLen, - pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { - return ret; - } + headers[count]._name = pKey; + headers[count]._nameLen = keyLen; + headers[count]._value = pValue; + headers[count]._valueLen = pCur->valueLen; + ++count; + if ( count == 512 ) + break; + //ret = (*fn)( pKey, keyLen, + // pValue, pCur->valueLen, arg ); + //if ( ret <= 0 ) + // return ret; ++pCur; } } - return count + pReq->m_pHeader->m_cntUnknownHeaders; + qsort( headers, count, sizeof( struct _headerInfo ), compareValueLocation ); + for( i = 0; i < count; ++i ) + { + ret = (*fn)( headers[i]._name, headers[i]._nameLen, + headers[i]._value, headers[i]._valueLen, arg ); + if ( ret <= 0 ) + return ret; + } + return count; } @@ -1211,23 +1965,24 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, char * pValue; int ret; int count = 0; - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { len = pReq->m_pHeaderIndex->m_headerLen[i]; pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; *(pValue + len ) = 0; ret = (*fn)( CGI_HEADERS[i], CGI_HEADER_LEN[i], pValue, len, arg ); ++count; - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { char achHeaderName[256]; char *p; char *pKey; @@ -1236,23 +1991,23 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; + if ( keyLen > 250 ) + keyLen = 250; pKeyEnd = pKey + keyLen; memcpy( achHeaderName, "HTTP_", 5 ); p = &achHeaderName[5]; - if ( keyLen > 250 ) { - keyLen = 250; - } - while( pKey < pKeyEnd ) { + while( pKey < pKeyEnd ) + { char ch = *pKey++; - if ( ch == '-' ) { + if ( ch == '-' ) *p++ = '_'; - } else { + else *p++ = toupper( ch ); - } } *p = 0; keyLen += 5; @@ -1261,9 +2016,8 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, *(pValue + pCur->valueLen ) = 0; ret = (*fn)( achHeaderName, keyLen, pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } ++pCur; } } @@ -1276,15 +2030,14 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv, { struct LSAPI_key_value_pair * pEnd = pEnv + n; int ret; - if ( !pEnv || !fn ) { + if ( !pEnv || !fn ) return -1; - } - while( pEnv < pEnd ) { + while( pEnv < pEnd ) + { ret = (*fn)( pEnv->pKey, pEnv->keyLen, pEnv->pValue, pEnv->valLen, arg ); - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } ++pEnv; } return n; @@ -1295,10 +2048,10 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv, int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - if ( pReq->m_pHeader->m_cntEnv > 0 ) { + if ( pReq->m_pHeader->m_cntEnv > 0 ) + { return EnvForeach( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, fn, arg ); } @@ -1310,10 +2063,10 @@ int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) { + if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) + { return EnvForeach( pReq->m_pSpecialEnvList, pReq->m_pHeader->m_cntSpecialEnv, fn, arg ); @@ -1326,14 +2079,13 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ) { - if ( !pReq || !pReq->m_pIovec ) { + if ( !pReq || !pReq->m_pIovec ) return -1; - } - if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) { + if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) return 0; - } pReq->m_reqState &= ~LSAPI_ST_RESP_HEADER; - if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) { + if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespHeaderBuf; pReq->m_pIovecCur->iov_len = pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf; pReq->m_totalLen += pReq->m_pIovecCur->iov_len; @@ -1352,25 +2104,87 @@ int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ) } - - -int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len ) +int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName, + const char * pHeaderValue ) { - if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) { + int nameLen, valLen, len; + if ( !pReq || !pHeaderName || !pHeaderValue ) + return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) + return -1; + if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) + return -1; + nameLen = strlen( pHeaderName ); + valLen = strlen( pHeaderValue ); + if ( nameLen == 0 ) return -1; + while( nameLen > 0 ) + { + char ch = *(pHeaderName + nameLen - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --nameLen; + else + break; + } + if ( nameLen <= 0 ) + return 0; + while( valLen > 0 ) + { + char ch = *(pHeaderValue + valLen - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --valLen; + else + break; } - if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) { + len = nameLen + valLen + 1; + if ( len > LSAPI_RESP_HTTP_HEADER_MAX ) return -1; + + if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) + { + int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf; + newlen -= newlen % 4096; + if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) + return -1; } - if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) { + memmove( pReq->m_pRespHeaderBufPos, pHeaderName, nameLen ); + pReq->m_pRespHeaderBufPos += nameLen; + *pReq->m_pRespHeaderBufPos++ = ':'; + memmove( pReq->m_pRespHeaderBufPos, pHeaderValue, valLen ); + pReq->m_pRespHeaderBufPos += valLen; + *pReq->m_pRespHeaderBufPos++ = 0; + ++len; /* add one byte padding for \0 */ + pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len; + ++pReq->m_respHeader.m_respInfo.m_cntHeaders; + return 0; +} + + + +int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len ) +{ + if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) + return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) return -1; + if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) + return -1; + while( len > 0 ) + { + char ch = *(pBuf + len - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --len; + else + break; } - if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) { + if ( len <= 0 ) + return 0; + if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) + { int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf; newlen -= newlen % 4096; - if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) { + if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) return -1; - } } memmove( pReq->m_pRespHeaderBufPos, pBuf, len ); pReq->m_pRespHeaderBufPos += len; @@ -1389,7 +2203,8 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog ) int flag = 1; int addr_len; - switch( pServerAddr->sa_family ) { + switch( pServerAddr->sa_family ) + { case AF_INET: addr_len = 16; break; @@ -1405,20 +2220,20 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog ) } fd = socket( pServerAddr->sa_family, SOCK_STREAM, 0 ); - if ( fd == -1 ) { + if ( fd == -1 ) return -1; - } fcntl( fd, F_SETFD, FD_CLOEXEC ); if(setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, - (char *)( &flag ), sizeof(flag)) == 0) { + (char *)( &flag ), sizeof(flag)) == 0) + { ret = bind( fd, pServerAddr, addr_len ); - if ( !ret ) { + if ( !ret ) + { ret = listen( fd, backlog ); - if ( !ret ) { + if ( !ret ) return fd; - } } } @@ -1438,17 +2253,16 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) int doAddrInfo = 0; int port; - if ( !pBind ) { + if ( !pBind ) return -1; - } - while( isspace( *pBind ) ) { + while( isspace( *pBind ) ) ++pBind; - } strncpy( achAddr, pBind, 256 ); - switch( *p ) { + switch( *p ) + { case '/': pAddr->sa_family = AF_UNIX; strncpy( ((struct sockaddr_un *)pAddr)->sun_path, p, @@ -1463,7 +2277,8 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) return -1; *pEnd++ = 0; - if ( *p == '*' ) { + if ( *p == '*' ) + { strcpy( achAddr, "::" ); p = achAddr; } @@ -1473,35 +2288,35 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) default: pAddr->sa_family = AF_INET; pEnd = strchr( p, ':' ); - if ( !pEnd ) { + if ( !pEnd ) return -1; - } *pEnd++ = 0; doAddrInfo = 0; - if ( *p == '*' ) { + if ( *p == '*' ) + { ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl(INADDR_ANY); - } else { - if (!strcasecmp( p, "localhost" ) ) { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK ); - } else { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p ); - if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) { - doAddrInfo = 1; - } + } + else if (!strcasecmp( p, "localhost" ) ) + ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK ); + else + { + ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p ); + if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) + { + doAddrInfo = 1; } } break; } - if ( *pEnd == ':' ) { + if ( *pEnd == ':' ) ++pEnd; - } port = atoi( pEnd ); - if (( port <= 0 )||( port > 65535 )) { + if (( port <= 0 )||( port > 65535 )) return -1; - } - if ( doAddrInfo ) { + if ( doAddrInfo ) + { memset(&hints, 0, sizeof(hints)); @@ -1509,7 +2324,8 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - if ( getaddrinfo(p, NULL, &hints, &res) ) { + if ( getaddrinfo(p, NULL, &hints, &res) ) + { return -1; } @@ -1517,11 +2333,10 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) freeaddrinfo(res); } - if ( pAddr->sa_family == AF_INET ) { + if ( pAddr->sa_family == AF_INET ) ((struct sockaddr_in *)pAddr)->sin_port = htons( port ); - } else { + else ((struct sockaddr_in6 *)pAddr)->sin6_port = htons( port ); - } return 0; } @@ -1532,7 +2347,8 @@ int LSAPI_CreateListenSock( const char * pBind, int backlog ) int ret; int fd = -1; ret = LSAPI_ParseSockAddr( pBind, (struct sockaddr *)serverAddr ); - if ( !ret ) { + if ( !ret ) + { fd = LSAPI_CreateListenSock2( (struct sockaddr *)serverAddr, backlog ); } return fd; @@ -1543,9 +2359,11 @@ static fn_select_t g_fnSelect = select; typedef struct _lsapi_child_status { int m_pid; + long m_tmStart; volatile short m_iKillSent; volatile short m_inProcess; + volatile int m_iReqCounter; volatile long m_tmWaitBegin; volatile long m_tmReqBegin; @@ -1575,43 +2393,42 @@ static lsapi_prefork_server * g_prefork_server = NULL; int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ) { - if ( g_prefork_server ) { + int pid; + if ( g_prefork_server ) return 0; - } - if ( max_children <= 1 ) { + if ( max_children <= 1 ) return -1; - } - if ( max_children >= 10000) { + if ( max_children >= 10000) max_children = 10000; - } g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) ); - if ( !g_prefork_server ) { + if ( !g_prefork_server ) return -1; - } memset( g_prefork_server, 0, sizeof( lsapi_prefork_server ) ); - if ( fp != NULL ) { + if ( fp != NULL ) g_fnSelect = fp; - } s_ppid = getppid(); + pid = getpid(); + setpgid( pid, pid ); g_prefork_server->m_iAvoidFork = avoidFork; g_prefork_server->m_iMaxChildren = max_children; g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ; g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3); + if ( g_prefork_server->m_iMaxIdleChildren == 0 ) + g_prefork_server->m_iMaxIdleChildren = 1; g_prefork_server->m_iChildrenMaxIdleTime = 300; - g_prefork_server->m_iMaxReqProcessTime = 300; + g_prefork_server->m_iMaxReqProcessTime = 3600; return 0; } void LSAPI_Set_Server_fd( int fd ) { - if( g_prefork_server ) { + if( g_prefork_server ) g_prefork_server->m_fd = fd; - } } @@ -1624,11 +2441,17 @@ static int lsapi_accept( int fdListen ) len = sizeof( achPeer ); fd = accept( fdListen, (struct sockaddr *)&achPeer, &len ); - if ( fd != -1 ) { - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { + if ( fd != -1 ) + { + if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) + { setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); } + + //OPTIMIZATION + //if ( s_accept_notify ) + // notify_req_received( fd ); } return fd; @@ -1652,10 +2475,10 @@ static lsapi_child_status * find_child_status( int pid ) { lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - if ( pStatus->m_pid == pid ) { + while( pStatus < pEnd ) + { + if ( pStatus->m_pid == pid ) return pStatus; - } ++pStatus; } return NULL; @@ -1667,16 +2490,30 @@ static void lsapi_sigchild( int signal ) { int status, pid; lsapi_child_status * child_status; - while( 1 ) { + while( 1 ) + { pid = waitpid( -1, &status, WNOHANG|WUNTRACED ); - if ( pid <= 0 ) { + if ( pid <= 0 ) + { break; } + if ( WIFSIGNALED( status )) + { + int sig_num = WTERMSIG( status ); + int dump = WCOREDUMP( status ); + fprintf( stderr, "Child process with pid: %d was killed by signal: %d, core dump: %d\n", pid, sig_num, dump ); + } + if ( pid == s_pid_dump_debug_info ) + { + pid = 0; + continue; + } child_status = find_child_status( pid ); - if ( child_status ) { + if ( child_status ) + { child_status->m_pid = 0; + --g_prefork_server->m_iCurChildren; } - --g_prefork_server->m_iCurChildren; } } @@ -1690,76 +2527,108 @@ static int lsapi_init_children_status() size = (size + 4095 ) / 4096 * 4096; pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0 ); - if ( pBuf == MAP_FAILED ) { + if ( pBuf == MAP_FAILED ) + { perror( "Anonymous mmap() failed" ); return -1; } memset( pBuf, 0, size ); - g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf; + g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf; return 0; } +static void dump_debug_info( lsapi_child_status * pStatus, long tmCur ) +{ + char achCmd[1024]; + if ( s_pid_dump_debug_info ) + { + if ( kill( s_pid_dump_debug_info, 0 ) == 0 ) + return; + } + s_pid_dump_debug_info = fork(); + + fprintf( stderr, "[%s] Possible runaway process, PPID: %d, PID: %d, reqCount: %d, process time: %ld, checkpoint time: %ld, start time: %ld\n", + ctime(&tmCur), getpid(), pStatus->m_pid, pStatus->m_iReqCounter, + tmCur - pStatus->m_tmReqBegin, tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart ); + snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" -ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2", pStatus->m_pid, pStatus->m_pid ); + if ( system( achCmd ) == -1 ) + perror( "system()" ); + exit( 0 ); +} + static void lsapi_check_child_status( long tmCur ) { int idle = 0; int tobekilled; int dying = 0; + int count = 0; lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - tobekilled = pStatus->m_iKillSent; - if ( pStatus->m_pid != 0 ) { - if ( !tobekilled ) { - if ( !pStatus->m_inProcess ) { - - if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)|| - ( idle >= g_prefork_server->m_iMaxIdleChildren )) { - - tobekilled = 1; - } else { - if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) { - tobekilled = 1; - } - } - if ( !tobekilled ) { - ++idle; - } - } else { - if ( tmCur - pStatus->m_tmReqBegin > - g_prefork_server->m_iMaxReqProcessTime ) { - tobekilled = 1; - } + while( pStatus < pEnd ) + { + tobekilled = 0; + if ( pStatus->m_pid != 0 ) + { + ++count; + if ( !pStatus->m_inProcess ) + { + + if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)|| + ( idle > g_prefork_server->m_iMaxIdleChildren )) + { + tobekilled = SIGUSR1; } - } else { - if ( pStatus->m_inProcess ) { - tobekilled = pStatus->m_iKillSent = 0; + else + { + if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) + { + tobekilled = SIGUSR1; + } } + if ( !tobekilled ) + ++idle; } - if ( tobekilled ) { - tobekilled = 0; - if ( pStatus->m_iKillSent > 5 ) { - tobekilled = SIGKILL; - } else { - if ( pStatus->m_iKillSent == 3 ) { + else + { + if ( tmCur - pStatus->m_tmReqBegin > + g_prefork_server->m_iMaxReqProcessTime ) + { + if (( ( pStatus->m_iKillSent % 5 ) == 0 )&&( s_dump_debug_info )) + dump_debug_info( pStatus, tmCur ); + if ( pStatus->m_iKillSent > 5 ) + { + tobekilled = SIGKILL; + fprintf( stderr, "Force killing runaway process PID: %d with SIGKILL\n", pStatus->m_pid ); + } + else + { tobekilled = SIGTERM; - } else { - if ( pStatus->m_iKillSent == 1 ) { - tobekilled = SIGUSR1; - } + fprintf( stderr, "Killing runaway process PID: %d with SIGTERM\n", pStatus->m_pid ); } } - if ( tobekilled ) { - kill( pStatus->m_pid, tobekilled ); + } + if ( tobekilled ) + { + if (( kill( pStatus->m_pid, tobekilled ) == -1 )&&( errno == ESRCH )) + { + pStatus->m_pid = 0; + --count; + } + else + { + ++pStatus->m_iKillSent; + ++dying; } - ++pStatus->m_iKillSent; - ++dying; } - - } else { - ++dying; } ++pStatus; } + if ( abs( g_prefork_server->m_iCurChildren - count ) > 1 ) + { + fprintf( stderr, "Children tracking is wrong: PID: %d, Cur Childen: %d, count: %d, idle: %d, dying: %d\n", getpid(), + g_prefork_server->m_iCurChildren, count, idle, dying ); + + } } static int lsapi_all_children_must_die() @@ -1770,14 +2639,14 @@ static int lsapi_all_children_must_die() g_prefork_server->m_iMaxIdleChildren = -1; maxWait = 15; - while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) { + while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) + { lsapi_check_child_status(time(NULL)); sleep( 1 ); sec++; } - if ( g_prefork_server->m_iCurChildren != 0 ) { + if ( g_prefork_server->m_iCurChildren != 0 ) kill( -getpgrp(), SIGKILL ); - } return 0; } @@ -1796,13 +2665,17 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re fd_set readfds; struct timeval timeout; + sigset_t mask; + sigset_t orig_mask; + lsapi_init_children_status(); setsid(); act.sa_flags = 0; act.sa_handler = lsapi_sigchild; - if( sigaction( SIGCHLD, &act, &old_child ) ) { + if( sigaction( SIGCHLD, &act, &old_child ) ) + { perror( "Can't set signal handler for SIGCHILD" ); return -1; } @@ -1813,36 +2686,36 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re if( sigaction( SIGTERM, &act, &old_term ) || sigaction( SIGINT, &act, &old_int ) || sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { + sigaction( SIGQUIT, &act, &old_quit )) + { perror( "Can't set signals" ); return -1; } s_stop = 0; - while( !s_stop ) { - if ( ret ) { - curTime = time( NULL ); - } else { - ++curTime; - } - if (curTime != lastTime ) { + while( !s_stop ) + { + curTime = time( NULL ); + if (curTime != lastTime ) + { lastTime = curTime; - if (s_ppid && (getppid() != s_ppid )) { + if (s_ppid && (getppid() != s_ppid )) break; - } lsapi_check_child_status(curTime ); - if (pServer->m_iServerMaxIdle) { - if ( pServer->m_iCurChildren <= 0 ) { + if (pServer->m_iServerMaxIdle) + { + if ( pServer->m_iCurChildren <= 0 ) + { ++wait_secs; - if ( wait_secs > pServer->m_iServerMaxIdle ) { + if ( wait_secs > pServer->m_iServerMaxIdle ) return -1; - } - } else { - wait_secs = 0; } + else + wait_secs = 0; } } - if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) { + if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) + { usleep( 100000 ); continue; } @@ -1850,66 +2723,100 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 1; timeout.tv_usec = 0; - if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) { - if ( pServer->m_iCurChildren >= 0 ) { + if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) + { + /* + if ( pServer->m_iCurChildren >= 0 ) + { usleep( 10 ); FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 0; timeout.tv_usec = 0; - if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) { - continue; - } - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { + if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) continue; - } - /* perror( "select()" ); */ - break; - } else { + }*/ + } + else if ( ret == -1 ) + { + if ( errno == EINTR ) continue; - } + /* perror( "select()" ); */ + break; + } + else + { + continue; } pReq->m_fd = lsapi_accept( pServer->m_fd ); - if ( pReq->m_fd != -1 ) { + if ( pReq->m_fd != -1 ) + { child_status = find_child_status( 0 ); + if ( child_status ) + memset( child_status, 0, sizeof( *child_status ) ); + + sigemptyset( &mask ); + sigaddset( &mask, SIGCHLD ); + + if ( sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0 ) + { + perror( "sigprocmask(SIG_BLOCK) to block SIGCHLD" ); + } + pid = fork(); - if ( !pid ) { + + if ( !pid ) + { + if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) + perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK in child" ); g_prefork_server = NULL; s_ppid = getppid(); s_req_processed = 0; s_pChildStatus = child_status; - child_status->m_iKillSent = 0; lsapi_set_nblock( pReq->m_fd, 0 ); - + if ( pReq->m_fdListen != -1 ) + { + close( pReq->m_fdListen ); + pReq->m_fdListen = -1; + } /* don't catch our signals */ sigaction( SIGCHLD, &old_child, 0 ); sigaction( SIGTERM, &old_term, 0 ); sigaction( SIGQUIT, &old_quit, 0 ); sigaction( SIGINT, &old_int, 0 ); sigaction( SIGUSR1, &old_usr1, 0 ); + //init_conn_key( pReq->m_fd ); + lsapi_notify_pid( pReq->m_fd ); + s_notified_pid = 1; + //if ( s_accept_notify ) + // return notify_req_received( pReq->m_fd ); return 0; - } else { - if ( pid == -1 ) { - perror( "fork() failed, please increase process limit" ); - } else { - ++pServer->m_iCurChildren; - if ( child_status ) { - child_status->m_pid = pid; - child_status->m_iKillSent = 0; - child_status->m_tmWaitBegin = time(NULL); - } + } + else if ( pid == -1 ) + { + perror( "fork() failed, please increase process limit" ); + } + else + { + ++pServer->m_iCurChildren; + if ( child_status ) + { + child_status->m_pid = pid; + child_status->m_tmWaitBegin = curTime; + child_status->m_tmStart = curTime; } } close( pReq->m_fd ); pReq->m_fd = -1; - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { + if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) + perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK" ); + + } + else + { + if (( errno == EINTR )||( errno == EAGAIN)) continue; - } perror( "accept() failed" ); return -1; } @@ -1921,6 +2828,11 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re } +void lsapi_error( const char * pMessage, int err_no ) +{ + fprintf( stderr, "%d: %s, errno: %d (%s)\n", getpid(), pMessage, err_no, strerror( err_no ) ); +} + int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) { int fd; @@ -1932,88 +2844,105 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) LSAPI_Finish_r( pReq ); - if ( g_prefork_server ) { - if ( g_prefork_server->m_fd != -1 ) { - if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) { + if ( g_prefork_server ) + { + if ( g_prefork_server->m_fd != -1 ) + if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) return -1; - } - } } - if ( s_req_processed >= s_max_reqs ) { + if ( s_req_processed >= s_max_reqs ) return -1; - } - if ( s_pChildStatus ) { + if ( s_pChildStatus ) + { s_pChildStatus->m_tmWaitBegin = time( NULL ); } + - while( g_running ) { - if ( pReq->m_fd != -1 ) { + while( g_running ) + { + if ( pReq->m_fd != -1 ) + { fd = pReq->m_fd; - } else { - if ( pReq->m_fdListen != -1 ) { - fd = pReq->m_fdListen; - } else { - return -1; - } + } + else if ( pReq->m_fdListen != -1 ) + fd = pReq->m_fdListen; + else + { + break; } wait_secs = 0; - while( 1 ) { - if ( !g_running ) { + while( 1 ) + { + if ( !g_running ) return -1; - } - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { + if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) return -1; - } FD_ZERO( &readfds ); FD_SET( fd, &readfds ); timeout.tv_sec = 1; timeout.tv_usec = 0; ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout); - if ( ret == 0 ) { - if ( s_pChildStatus ) { + if ( ret == 0 ) + { + if ( s_pChildStatus ) + { s_pChildStatus->m_inProcess = 0; } ++wait_secs; - if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) { + if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) return -1; - } - if ( s_ppid &&( getppid() != s_ppid)) { + if ( s_ppid &&( getppid() != s_ppid)) return -1; - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { - continue; - } else { - return -1; - } - } else { - if ( ret >= 1 ) { - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { - return -1; + } + else if ( ret == -1 ) + { + if ( errno == EINTR ) + continue; + else + return -1; + } + else if ( ret >= 1 ) + { + if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) + return -1; + if ( fd == pReq->m_fdListen ) + { + pReq->m_fd = lsapi_accept( pReq->m_fdListen ); + if ( pReq->m_fd != -1 ) + { + fd = pReq->m_fd; + lsapi_set_nblock( fd, 0 ); + //init_conn_key( pReq->m_fd ); + if ( !s_keepListener ) + { + close( pReq->m_fdListen ); + pReq->m_fdListen = -1; } - if ( fd == pReq->m_fdListen ) { - pReq->m_fd = lsapi_accept( pReq->m_fdListen ); - if ( pReq->m_fd != -1 ) { - fd = pReq->m_fd; - lsapi_set_nblock( fd, 0 ); - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { - continue; - } + if ( s_accept_notify ) + if ( notify_req_received( pReq->m_fd ) == -1 ) return -1; - } - } else { - break; - } + } + else + { + if (( errno == EINTR )||( errno == EAGAIN)) + continue; + lsapi_error( "lsapi_accept() error", errno ); + return -1; } } + else + break; } } - if ( !readReq( pReq ) ) { - if ( s_pChildStatus ) { + + if ( !readReq( pReq ) ) + { + if ( s_pChildStatus ) + { + s_pChildStatus->m_iKillSent = 0; s_pChildStatus->m_inProcess = 1; + ++s_pChildStatus->m_iReqCounter; s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL); } ++s_req_processed; @@ -2028,49 +2957,50 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) } void LSAPI_Set_Max_Reqs( int reqs ) -{ - s_max_reqs = reqs; -} +{ s_max_reqs = reqs; } void LSAPI_Set_Max_Idle( int secs ) -{ - s_max_idle_secs = secs; -} +{ s_max_idle_secs = secs; } void LSAPI_Set_Max_Children( int maxChildren ) { - if ( g_prefork_server ) { + if ( g_prefork_server ) g_prefork_server->m_iMaxChildren = maxChildren; - } } void LSAPI_Set_Extra_Children( int extraChildren ) { - if (( g_prefork_server )&&( extraChildren >= 0 )) { + if (( g_prefork_server )&&( extraChildren >= 0 )) g_prefork_server->m_iExtraChildren = extraChildren; - } } void LSAPI_Set_Max_Process_Time( int secs ) { - if (( g_prefork_server )&&( secs > 0 )) { + if (( g_prefork_server )&&( secs > 0 )) g_prefork_server->m_iMaxReqProcessTime = secs; - } } void LSAPI_Set_Max_Idle_Children( int maxIdleChld ) { - if (( g_prefork_server )&&( maxIdleChld > 0 )) { + if (( g_prefork_server )&&( maxIdleChld > 0 )) g_prefork_server->m_iMaxIdleChildren = maxIdleChld; - } } void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ) { - if ( g_prefork_server ) { + if ( g_prefork_server ) g_prefork_server->m_iServerMaxIdle = serverMaxIdle; - } +} + +void LSAPI_Set_Slow_Req_Msecs( int msecs ) +{ + s_slow_req_msecs = msecs; +} + +int LSAPI_Get_Slow_Req_Msecs() +{ + return s_slow_req_msecs; } @@ -2092,101 +3022,419 @@ static void unset_lsapi_envs() #else env = environ; #endif - while( env != NULL && *env != NULL ) { - if ( !strncmp(*env, "LSAPI_", 6) || - !strncmp( *env, "PHP_LSAPI_", 10 ) ) { + while( env != NULL && *env != NULL ) + { + if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 ) + || (!strncmp( *env, "PHPRC=", 6 )&&(!s_uid))) + { char ** del = env; - do { + do *del = del[1]; - } while( *del++ ); - } else { - ++env; + while( *del++ ); } + else + ++env; } } -void LSAPI_Init_Env_Parameters( fn_select_t fp ) +static int lsapi_initSuEXEC() +{ + int i; + struct passwd * pw; + s_defaultUid = 0; + s_defaultGid = 0; + if ( s_uid == 0 ) + { + const char * p = getenv( "LSAPI_DEFAULT_UID" ); + if ( p ) + { + i = atoi( p ); + if ( i > 0 ) + s_defaultUid = i; + } + p = getenv( "LSAPI_DEFAULT_GID" ); + if ( p ) + { + i = atoi( p ); + if ( i > 0 ) + s_defaultGid = i; + } + p = getenv( "LSAPI_SECRET" ); + if (( !p )||( readSecret(p) == -1 )) + return -1; + if ( g_prefork_server ) + { + if ( g_prefork_server->m_iMaxChildren < 100 ) + g_prefork_server->m_iMaxChildren = 100; + } + } + if ( !s_defaultUid || !s_defaultGid ) + { + pw = getpwnam( "nobody" ); + if ( !s_defaultUid ) + s_defaultUid = pw->pw_uid; + if ( !s_defaultGid ) + s_defaultGid = pw->pw_gid; + } + return 0; +} + + +int LSAPI_Init_Env_Parameters( fn_select_t fp ) { const char *p; int n; int avoidFork = 0; p = getenv( "PHP_LSAPI_MAX_REQUESTS" ); - if ( !p ) { + if ( !p ) p = getenv( "LSAPI_MAX_REQS" ); - } - if ( p ) { + if ( p ) + { n = atoi( p ); - if ( n > 0 ) { + if ( n > 0 ) LSAPI_Set_Max_Reqs( n ); - } } p = getenv( "LSAPI_AVOID_FORK" ); - if ( p ) { + if ( p ) + { avoidFork = atoi( p ); } + p = getenv( "LSAPI_ACCEPT_NOTIFY" ); + if ( p ) + { + s_accept_notify = atoi( p ); + } + + p = getenv( "LSAPI_SLOW_REQ_MSECS" ); + if ( p ) + { + n = atoi( p ); + LSAPI_Set_Slow_Req_Msecs( n ); + } + #if defined( RLIMIT_CORE ) p = getenv( "LSAPI_ALLOW_CORE_DUMP" ); - if ( !p ) { + if ( !p ) + { struct rlimit limit = { 0, 0 }; setrlimit( RLIMIT_CORE, &limit ); } -#endif + else + s_enable_core_dump = 1; + +#endif p = getenv( "LSAPI_MAX_IDLE" ); - if ( p ) { + if ( p ) + { n = atoi( p ); LSAPI_Set_Max_Idle( n ); } - if ( LSAPI_Is_Listen() ) { + p = getenv( "LSAPI_KEEP_LISTEN" ); + if ( p ) + { + n = atoi( p ); + s_keepListener = n; + } + + + if ( LSAPI_Is_Listen() ) + { n = 0; p = getenv( "PHP_LSAPI_CHILDREN" ); - if ( !p ) { + if ( !p ) p = getenv( "LSAPI_CHILDREN" ); - } - if ( p ) { + if ( p ) n = atoi( p ); - } - if ( n > 1 ) { + if ( n > 1 ) + { LSAPI_Init_Prefork_Server( n, fp, avoidFork ); LSAPI_Set_Server_fd( g_req.m_fdListen ); } p = getenv( "LSAPI_EXTRA_CHILDREN" ); - if ( p ) { + if ( p ) LSAPI_Set_Extra_Children( atoi( p ) ); - } p = getenv( "LSAPI_MAX_IDLE_CHILDREN" ); - if ( p ) { + if ( p ) LSAPI_Set_Max_Idle_Children( atoi( p ) ); - } + p = getenv( "LSAPI_PGRP_MAX_IDLE" ); - if ( p ) { + if ( p ) + { LSAPI_Set_Server_Max_Idle_Secs( atoi( p ) ); } p = getenv( "LSAPI_MAX_PROCESS_TIME" ); - if ( p ) { + if ( p ) LSAPI_Set_Max_Process_Time( atoi( p ) ); - } - if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) { + + if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) + { LSAPI_No_Check_ppid(); } + + p = getenv( "LSAPI_DUMP_DEBUG_INFO" ); + if ( p ) + s_dump_debug_info = atoi( p ); + + if ( lsapi_initSuEXEC() == -1 ) + return -1; +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + lsapi_initLVE(); +#endif } unset_lsapi_envs(); + return 0; +} + + +int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders, + const char * pBody, int bodyLen ) +{ + LSAPI_SetRespStatus_r( pReq, code ); + if ( pRespHeaders ) + { + while( *pRespHeaders ) + { + LSAPI_AppendRespHeader_r( pReq, *pRespHeaders, strlen( *pRespHeaders ) ); + ++pRespHeaders; + } + } + if ( pBody &&( bodyLen > 0 )) + { + LSAPI_Write_r( pReq, pBody, bodyLen ); + } + LSAPI_Finish_r( pReq ); + return 0; +} + + +static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void lsapi_MD5Init(struct lsapi_MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; } +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void lsapi_MD5Update(struct lsapi_MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + register uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memmove(p, buf, len); + return; + } + memmove(p, buf, t); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memmove(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memmove(ctx->in, buf, len); +} /* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) */ +void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *ctx) +{ + unsigned int count; + unsigned char *p; + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memmove(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h index 538a170b44cd8..b0638fd436a09 100644 --- a/sapi/litespeed/lsapilib.h +++ b/sapi/litespeed/lsapilib.h @@ -1,24 +1,5 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: George Wang | - +----------------------------------------------------------------------+ -*/ - /* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2013, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,6 +30,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*************************************************************************** + lsapilib.h - description + ------------------- + begin : Mon Feb 21 2005 + copyright : (C) 2005 by George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ #ifndef _LSAPILIB_H_ @@ -118,7 +106,8 @@ typedef struct lsapi_request char * m_pRequestMethod; int m_totalLen; int m_reqState; - int m_reqBodyRead; + off_t m_reqBodyLen; + off_t m_reqBodyRead; int m_bufProcessed; int m_bufRead; @@ -126,6 +115,7 @@ typedef struct lsapi_request struct lsapi_resp_header m_respHeader; short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS]; + void * m_pAppData; }LSAPI_Request; @@ -170,22 +160,30 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ); -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int len ); +ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t len ); int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ); -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ); +int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF ); int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ); -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ); +ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ); -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ); +ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size ); + +ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t len ); int LSAPI_Flush_r( LSAPI_Request * pReq ); -int LSAPI_AppendRespHeader_r( LSAPI_Request * pHeader, char * pBuf, int len ); +int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len ); + +int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName, + const char * pHeaderValue ); + +int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders, + const char * pBody, int bodyLen ); static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) { @@ -195,6 +193,21 @@ static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) return 0; } +static inline int LSAPI_SetAppData_r( LSAPI_Request * pReq, void * data ) +{ + if ( !pReq ) + return -1; + pReq->m_pAppData = data; + return 0; +} + +static inline void * LSAPI_GetAppData_r( LSAPI_Request * pReq ) +{ + if ( !pReq ) + return NULL; + return pReq->m_pAppData; +} + static inline char * LSAPI_GetQueryString_r( LSAPI_Request * pReq ) { if ( pReq ) @@ -228,21 +241,22 @@ static inline char * LSAPI_GetRequestMethod_r( LSAPI_Request * pReq) -static inline int LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) +static inline off_t LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) { if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen; + return pReq->m_reqBodyLen; return -1; } -static inline int LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) +static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) { if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + return pReq->m_reqBodyLen - pReq->m_reqBodyRead; return -1; } + int LSAPI_Is_Listen(void); static inline int LSAPI_Accept( void ) @@ -282,13 +296,13 @@ static inline char * LSAPI_GetScriptName() static inline char * LSAPI_GetRequestMethod() { return LSAPI_GetRequestMethod_r( &g_req ); } -static inline int LSAPI_GetReqBodyLen() +static inline off_t LSAPI_GetReqBodyLen() { return LSAPI_GetReqBodyLen_r( &g_req ); } -static inline int LSAPI_GetReqBodyRemain() +static inline off_t LSAPI_GetReqBodyRemain() { return LSAPI_GetReqBodyRemain_r( &g_req ); } -static inline int LSAPI_ReadReqBody( char * pBuf, int len ) +static inline ssize_t LSAPI_ReadReqBody( char * pBuf, size_t len ) { return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); } static inline int LSAPI_ReqBodyGetChar() @@ -302,10 +316,15 @@ static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF ) static inline int LSAPI_FinalizeRespHeaders(void) { return LSAPI_FinalizeRespHeaders_r( &g_req ); } -static inline int LSAPI_Write( const char * pBuf, int len ) +static inline ssize_t LSAPI_Write( const char * pBuf, ssize_t len ) { return LSAPI_Write_r( &g_req, pBuf, len ); } -static inline int LSAPI_Write_Stderr( const char * pBuf, int len ) +static inline ssize_t LSAPI_sendfile( int fdIn, off_t* off, size_t size ) +{ + return LSAPI_sendfile_r(&g_req, fdIn, off, size ); +} + +static inline ssize_t LSAPI_Write_Stderr( const char * pBuf, ssize_t len ) { return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); } static inline int LSAPI_Flush() @@ -317,6 +336,9 @@ static inline int LSAPI_AppendRespHeader( char * pBuf, int len ) static inline int LSAPI_SetRespStatus( int code ) { return LSAPI_SetRespStatus_r( &g_req, code ); } +static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen ) +{ return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); } + int LSAPI_IsRunning(void); int LSAPI_CreateListenSock( const char * pBind, int backlog ); @@ -341,7 +363,13 @@ void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ); void LSAPI_Set_Max_Process_Time( int secs ); -void LSAPI_Init_Env_Parameters( fn_select_t fp ); +int LSAPI_Init_Env_Parameters( fn_select_t fp ); + +void LSAPI_Set_Slow_Req_Msecs( int msecs ); + +int LSAPI_Get_Slow_Req_Msecs( ); + +int LSAPI_is_suEXEC_Daemon(); #if defined (c_plusplus) || defined (__cplusplus) } diff --git a/scripts/dev/conv_proto b/scripts/dev/conv_proto deleted file mode 100755 index fad9cfaa83845..0000000000000 --- a/scripts/dev/conv_proto +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/sh -# -# do some automatic conversion of prototypes -# - -if test "$1" = "" ; then - echo "usage: $0 list-of-files" - exit 1 -fi - -tmpfile=`mktemp -q /tmp/asd.XXXXXX` - -if test "$?" != "0" ; then - echo "$0: cannot create temporary file" - exit 1 -fi - -for file in ${1+"$@"} ; do - echo "working on $file" - cat $file | \ - sed -e \ - 's/void php3_\(.*\)(INTERNAL_FUNCTION_PARAMETERS)/PHP_FUNCTION(\1)/' \ - -e 's/^extern void /void /' \ - -e 's/^extern PHP_FUNCTION/PHP_FUNCTION/' > $tmpfile - cp $tmpfile $file -done - -rm -f $tmpfile - -exit 0 diff --git a/scripts/dev/conv_z_macros b/scripts/dev/conv_z_macros deleted file mode 100755 index ea45bc2ef98ba..0000000000000 --- a/scripts/dev/conv_z_macros +++ /dev/null @@ -1,61 +0,0 @@ -#! /bin/sh -# -# +----------------------------------------------------------------------+ -# | PHP Version 5 | -# +----------------------------------------------------------------------+ -# | Copyright (c) 1997-2007 The PHP Group | -# +----------------------------------------------------------------------+ -# | This source file is subject to version 3.01 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_01.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: Sascha Schumann | -# +----------------------------------------------------------------------+ -# -# $Id$ - -for i in $@; do - echo -n "Processing $i... " - sed \ - -e 's/(\*\([^()]\+\))->type/Z_TYPE_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->type/Z_TYPE_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.type/Z_TYPE(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.dval/Z_DVAL_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.dval/Z_DVAL_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.dval/Z_DVAL(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.lval/Z_LVAL_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.lval/Z_LVAL_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.lval/Z_LVAL(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.ht/Z_ARRVAL_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.ht/Z_ARRVAL_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.ht/Z_ARRVAL(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.str\.val/Z_STRVAL_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.str\.val/Z_STRVAL_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.str\.val/Z_STRVAL(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.str\.len/Z_STRLEN_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.str\.len/Z_STRLEN_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.str\.len/Z_STRLEN(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.obj\.properties/Z_OBJPROP_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.obj\.properties/Z_OBJPROP_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.obj\.properties/Z_OBJPROP(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.obj\.ce/Z_OBJCE_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.obj\.ce/Z_OBJCE_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.obj\.ce/Z_OBJCE(\1)/g' \ - -e 's/(\*\([^()]\+\))->value\.obj/Z_OBJ_PP(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)->value\.obj/Z_OBJ_P(\1)/g' \ - -e 's/\([a-z_][]a-z_0-9\[]*\)\.value\.obj/Z_OBJ(\1)/g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)->Z_\([A-Z_]\+\)(/Z_\2(\1->/g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)->Z_\([A-Z_]\+\)(/Z_\2(\1->/g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)->Z_\([A-Z_]\+\)(/Z_\2(\1->/g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)\.Z_\([A-Z_]\+\)(/Z_\2(\1./g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)\.Z_\([A-Z_]\+\)(/Z_\2(\1./g' \ - -e 's/\([a-zA-Z_][a-zA-Z_0-9]*\)\.Z_\([A-Z_]\+\)(/Z_\2(\1./g' \ - < $i > tmp && cp tmp $i - echo "DONE" -done - -rm -f tmp diff --git a/scripts/dev/extern_c.php b/scripts/dev/extern_c.php deleted file mode 100644 index 72c7edcd3288c..0000000000000 --- a/scripts/dev/extern_c.php +++ /dev/null @@ -1,45 +0,0 @@ - $line) { - if (ereg("^[[:space:]]*BEGIN_EXTERN_C", $line)) { -# echo "$file:".($nr+1)." $line"; - $flag = true; - } else if (ereg("^[[:space:]]*END_EXTERN_C", $line)) { -# echo "$file:".($nr+1)." $line"; - $flag = false; - } else if ( (ereg("^[[:space:]]*PHPAPI[[:space:]]*", $line)) - ||(ereg("^[[:space:]]*ZEND_API[[:space:]]*", $line))) { - if (strstr($line,"(")) { - if (!$flag) echo "$file:".($nr+1)." $line"; - } - } - } -} - -array_shift($_SERVER["argv"]); - -if (count($_SERVER["argv"])) { - foreach ($_SERVER["argv"] as $dir) { - scan_dir($dir); - } -} else { - scan_dir("."); -} -?> \ No newline at end of file diff --git a/tests/basic/024.phpt b/tests/basic/024.phpt deleted file mode 100644 index bf8a206b3ac9d..0000000000000 --- a/tests/basic/024.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Test HTTP_RAW_POST_DATA creation ---INI-- -always_populate_raw_post_data=1 -max_input_vars=1000 ---POST-- -a=ABC&y=XYZ&c[]=1&c[]=2&c[a]=3 ---FILE-- - ---EXPECT-- -array(3) { - ["a"]=> - string(3) "ABC" - ["y"]=> - string(3) "XYZ" - ["c"]=> - array(3) { - [0]=> - string(1) "1" - [1]=> - string(1) "2" - ["a"]=> - string(1) "3" - } -} -string(30) "a=ABC&y=XYZ&c[]=1&c[]=2&c[a]=3" diff --git a/tests/basic/026.phpt b/tests/basic/026.phpt deleted file mode 100644 index b98a31f430772..0000000000000 --- a/tests/basic/026.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Registration of HTTP_RAW_POST_DATA due to unknown content-type ---INI-- -always_populate_raw_post_data=0 ---POST_RAW-- -Content-Type: unknown/type -a=1&b=ZYX ---FILE-- - ---EXPECT-- -array(0) { -} -string(9) "a=1&b=ZYX" diff --git a/tests/basic/enable_post_data_reading_01.phpt b/tests/basic/enable_post_data_reading_01.phpt index 1a0e33f617480..19ee5d583f762 100644 --- a/tests/basic/enable_post_data_reading_01.phpt +++ b/tests/basic/enable_post_data_reading_01.phpt @@ -11,6 +11,7 @@ var_dump($_FILES); var_dump($_POST); var_dump($HTTP_RAW_POST_DATA); var_dump(file_get_contents("php://input")); +var_dump(file_get_contents("php://input")); --EXPECTF-- array(0) { } @@ -20,3 +21,4 @@ array(0) { Notice: Undefined variable: HTTP_RAW_POST_DATA in %s on line %d NULL string(9) "a=1&b=ZYX" +string(9) "a=1&b=ZYX" diff --git a/tests/basic/enable_post_data_reading_02.phpt b/tests/basic/enable_post_data_reading_02.phpt index dc7f6b127ad8e..4e1643ebd02d5 100644 --- a/tests/basic/enable_post_data_reading_02.phpt +++ b/tests/basic/enable_post_data_reading_02.phpt @@ -15,6 +15,7 @@ Content-Type: text/plain-file var_dump($_FILES); var_dump($_POST); var_dump(file_get_contents("php://input")); +var_dump(file_get_contents("php://input")); --EXPECTF-- array(0) { } @@ -26,3 +27,9 @@ Content-Type: text/plain-file 1 -----------------------------20896060251896012921717172737--" +string(%d) "-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; name="file1"; filename="file1.txt" +Content-Type: text/plain-file + +1 +-----------------------------20896060251896012921717172737--" diff --git a/tests/basic/enable_post_data_reading_03.phpt b/tests/basic/enable_post_data_reading_03.phpt index cdabe910ca45c..6a62282ea2e56 100644 --- a/tests/basic/enable_post_data_reading_03.phpt +++ b/tests/basic/enable_post_data_reading_03.phpt @@ -12,6 +12,7 @@ var_dump($_FILES); var_dump($_POST); var_dump($HTTP_RAW_POST_DATA); var_dump(file_get_contents("php://input")); +var_dump(file_get_contents("php://input")); --EXPECTF-- array(0) { } @@ -21,3 +22,4 @@ array(0) { Notice: Undefined variable: HTTP_RAW_POST_DATA in %s on line %d NULL string(9) "a=1&b=ZYX" +string(9) "a=1&b=ZYX" diff --git a/tests/basic/enable_post_data_reading_04.phpt b/tests/basic/enable_post_data_reading_04.phpt index a1685040bb957..a7c7e496d8c16 100644 --- a/tests/basic/enable_post_data_reading_04.phpt +++ b/tests/basic/enable_post_data_reading_04.phpt @@ -12,6 +12,7 @@ var_dump($_FILES); var_dump($_POST); var_dump($HTTP_RAW_POST_DATA); var_dump(file_get_contents("php://input")); +var_dump(file_get_contents("php://input")); --EXPECTF-- array(0) { } @@ -21,3 +22,4 @@ array(0) { Notice: Undefined variable: HTTP_RAW_POST_DATA in %s on line %d NULL string(9) "a=1&b=ZYX" +string(9) "a=1&b=ZYX" diff --git a/tests/basic/enable_post_data_reading_05.phpt b/tests/basic/enable_post_data_reading_05.phpt new file mode 100644 index 0000000000000..d8efa0129eaae --- /dev/null +++ b/tests/basic/enable_post_data_reading_05.phpt @@ -0,0 +1,26 @@ +--TEST-- +enable_post_data_reading: using multiple input streams +--INI-- +enable_post_data_reading=0 +max_execution_time=2 +--POST_RAW-- +Content-Type: application/unknown +One line of data +--FILE-- + + +Done +--EXPECT-- +Test +OOnnee lliinnee ooff ddaattaa +Done diff --git a/tests/basic/enable_post_data_reading_06.phpt b/tests/basic/enable_post_data_reading_06.phpt new file mode 100644 index 0000000000000..fbed195c03d1e --- /dev/null +++ b/tests/basic/enable_post_data_reading_06.phpt @@ -0,0 +1,271 @@ +--TEST-- +enable_post_data_reading: using multiple input streams (more than 8k data) +--INI-- +enable_post_data_reading=0 +--POST_RAW-- +Content-Type: application/unknown +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +. +--FILE-- + + +Done +--EXPECT-- +Test +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +.. +Done diff --git a/tests/run-test/test011.phpt b/tests/run-test/test011.phpt new file mode 100644 index 0000000000000..17f1f7aee6c9e --- /dev/null +++ b/tests/run-test/test011.phpt @@ -0,0 +1,6 @@ +--TEST-- +EXPECT_EXTERNAL +--FILE-- +abc +--EXPECT_EXTERNAL-- +test011.txt diff --git a/tests/run-test/test011.txt b/tests/run-test/test011.txt new file mode 100644 index 0000000000000..8baef1b4abc47 --- /dev/null +++ b/tests/run-test/test011.txt @@ -0,0 +1 @@ +abc diff --git a/tests/run-test/test012.phpt b/tests/run-test/test012.phpt new file mode 100644 index 0000000000000..8213aa2a5610e --- /dev/null +++ b/tests/run-test/test012.phpt @@ -0,0 +1,12 @@ +--TEST-- +EXPECTF_EXTERNAL +--FILE-- +123 +-123 ++123 ++1.1 +abc +0abc +x +--EXPECTF_EXTERNAL-- +test012.txt diff --git a/tests/run-test/test012.txt b/tests/run-test/test012.txt new file mode 100644 index 0000000000000..bb293214b1da9 --- /dev/null +++ b/tests/run-test/test012.txt @@ -0,0 +1,7 @@ +%d +%i +%i +%f +%s +%x +%c diff --git a/tests/run-test/test013.phpt b/tests/run-test/test013.phpt new file mode 100644 index 0000000000000..79ccd20de218c --- /dev/null +++ b/tests/run-test/test013.phpt @@ -0,0 +1,6 @@ +--TEST-- +EXPECTREGEX_EXTERNAL +--FILE-- +abcde12314235xyz34264768286abcde +--EXPECTREGEX_EXTERNAL-- +test013.txt diff --git a/tests/run-test/test013.txt b/tests/run-test/test013.txt new file mode 100644 index 0000000000000..6c280ece4d44f --- /dev/null +++ b/tests/run-test/test013.txt @@ -0,0 +1 @@ +[abcde]+[0-5]*xyz[2-8]+abcde diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 3401205c8fc1e..af92eb0d4c050 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -364,7 +364,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \ zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \ - zend_float.c zend_string.c zend_generators.c"); + zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c"); if (VCVERS == 1200) { AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1); diff --git a/win32/php_inttypes.h b/win32/php_inttypes.h new file mode 100644 index 0000000000000..25542771f591c --- /dev/null +++ b/win32/php_inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/win32/time.h b/win32/time.h index f841a2b601fe3..d5d86eb1ed781 100644 --- a/win32/time.h +++ b/win32/time.h @@ -50,4 +50,6 @@ PHPAPI extern int setitimer(int which, const struct itimerval *value, PHPAPI int nanosleep( const struct timespec * rqtp, struct timespec * rmtp ); +PHPAPI int usleep(unsigned int useconds); + #endif