mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-09 10:10:50 +00:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52ace952a1 | ||
|
|
3cafea6901 | ||
|
|
360efc59e6 | ||
|
|
f7275963cd | ||
|
|
648fc1e369 | ||
|
|
d8b25b34a2 | ||
|
|
0f658b38e8 | ||
|
|
ea302f8b08 | ||
|
|
3a144d3f7f | ||
|
|
bf36d811f1 | ||
|
|
69895e8ab3 |
No files matched your search
+1
-1
@@ -16,7 +16,7 @@ environment:
|
||||
PHP_BUILD_CACHE_BASE_DIR: c:\build-cache
|
||||
PHP_BUILD_OBJ_DIR: c:\obj
|
||||
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta6
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.1.9beta1
|
||||
PHP_BUILD_CRT: vc15
|
||||
# ext and env setup for tests
|
||||
#MYSQL_TEST_PASSWD: Password12!
|
||||
|
||||
+19
-18
@@ -1,34 +1,35 @@
|
||||
# https://editorconfig.org/
|
||||
# http://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
[*.{c,h,awk,w32,bat,mk,frag}]
|
||||
charset = utf-8
|
||||
tab_width = 4
|
||||
|
||||
[{*.{awk,bat,c,cpp,d,h,l,mk,re,skl,w32,y},Makefile*}]
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{dtd,html,inc,php,phpt,rng,wsdl,xml,xsd,xsl}]
|
||||
[*.{php,phpt}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{ac,m4,sh,yml}]
|
||||
[*.{yml,m4,sh}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
max_line_length = 80
|
||||
|
||||
[COMMIT_EDITMSG]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
max_line_length = 80
|
||||
|
||||
[*.patch]
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
||||
+1
-5
@@ -1,6 +1,3 @@
|
||||
git:
|
||||
quiet: true
|
||||
|
||||
dist: trusty
|
||||
language: c
|
||||
sudo: required
|
||||
@@ -67,8 +64,7 @@ before_script:
|
||||
|
||||
# Run PHPs run-tests.php
|
||||
script:
|
||||
- ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
|
||||
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
|
||||
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
|
||||
|
||||
after_success:
|
||||
- ccache --show-stats
|
||||
@@ -387,7 +387,6 @@ SINCE: 5.5.0
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net> (2001 - 2006)
|
||||
Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
|
||||
Jakub Zelenka <bukka@php.net> (2015 - 2019)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
|
||||
@@ -1,491 +1,5 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
20 Jun 2019, PHP 7.3.7RC2
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #78106 (Path resolution fails if opcache disabled during request).
|
||||
(Nikita)
|
||||
|
||||
13 Jun 2019, PHP 7.3.7RC1
|
||||
|
||||
- Core:
|
||||
. Fixed bug #76980 (Interface gets skipped if autoloader throws an exception).
|
||||
(Nikita)
|
||||
|
||||
- DOM:
|
||||
. Fixed bug #78025 (segfault when accessing properties of DOMDocumentType).
|
||||
(cmb)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #77956 (When mysqli.allow_local_infile = Off, use a meaningful
|
||||
error message). (Sjon Hortensius)
|
||||
. Fixed bug #38546 (bindParam incorrect processing of bool types).
|
||||
(camporter)
|
||||
|
||||
- MySQLnd:
|
||||
. Fixed bug #77955 (Random segmentation fault in mysqlnd from php-fpm).
|
||||
(Nikita)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #78015 (Incorrect evaluation of expressions involving partials
|
||||
arrays in SCCP). (Nikita)
|
||||
|
||||
- OpenSSL:
|
||||
. Fixed bug #78079 (openssl_encrypt_ccm.phpt fails with OpenSSL 1.1.1c).
|
||||
(Jakub Zelenka)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #78050 (SegFault phpdbg + opcache on include file twice).
|
||||
(Nikita)
|
||||
|
||||
- Sockets:
|
||||
. Fixed bug #78038 (Socket_select fails when resource array contains
|
||||
references). (Nikita)
|
||||
|
||||
- Sodium:
|
||||
. Fixed bug #78114 (segfault when calling sodium_* functions from eval). (cmb)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77135 (Extract with EXTR_SKIP should skip $this).
|
||||
(Craig Duncan, Dmitry)
|
||||
. Fixed bug ##77937 (preg_match failed). (cmb, Anatol)
|
||||
|
||||
- Zip:
|
||||
. Fixed bug #76345 (zip.h not found). (Michael Maroszek)
|
||||
|
||||
30 May 2019, PHP 7.3.6
|
||||
|
||||
- cURL:
|
||||
. Implemented FR #72189 (Add missing CURL_VERSION_* constants). (Javier
|
||||
Spagnoletti)
|
||||
|
||||
- EXIF:
|
||||
. Fixed bug #77988 (heap-buffer-overflow on php_jpg_get16).
|
||||
(CVE-2019-11040) (Stas)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #77934 (php-fpm kill -USR2 not working). (Jakub Zelenka)
|
||||
. Fixed bug #77921 (static.php.net doesn't work anymore). (Peter Kokot)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #77943 (imageantialias($image, false); does not work). (cmb)
|
||||
. Fixed bug #77973 (Uninitialized read in gdImageCreateFromXbm).
|
||||
(CVE-2019-11038) (cmb)
|
||||
|
||||
- Iconv:
|
||||
. Fixed bug #78069 (Out-of-bounds read in iconv.c:_php_iconv_mime_decode()
|
||||
due to integer overflow). (CVE-2019-11039). (maris dot adam)
|
||||
|
||||
- JSON:
|
||||
. Fixed bug #77843 (Use after free with json serializer). (Nikita)
|
||||
|
||||
- Opcache:
|
||||
. Fixed possible crashes, because of inconsistent PCRE cache and opcache
|
||||
SHM reset. (Alexey Kalinin, Dmitry)
|
||||
|
||||
- PDO_MySQL:
|
||||
. Fixed bug #77944 (Wrong meta pdo_type for bigint on LLP64). (cmb)
|
||||
|
||||
- Reflection:
|
||||
. Fixed bug #75186 (Inconsistent reflection of Closure:::__invoke()). (Nikita)
|
||||
|
||||
- Session:
|
||||
. Fixed bug #77911 (Wrong warning for session.sid_bits_per_character). (cmb)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #77945 (Segmentation fault when constructing SoapClient with
|
||||
WSDL_CACHE_BOTH). (Nikita)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #77024 (SplFileObject::__toString() may return array). (Craig
|
||||
Duncan)
|
||||
|
||||
- SQLite:
|
||||
. Fixed bug #77967 (Bypassing open_basedir restrictions via file uris). (Stas)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77931 (Warning for array_map mentions wrong type). (Nikita)
|
||||
. Fixed bug #78003 (strip_tags output change since PHP 7.3). (cmb)
|
||||
|
||||
02 May 2019, PHP 7.3.5
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77903 (ArrayIterator stops iterating after offsetSet call).
|
||||
(Nikita)
|
||||
|
||||
- CLI:
|
||||
. Fixed bug #77794 (Incorrect Date header format in built-in server).
|
||||
(kelunik)
|
||||
|
||||
- EXIF
|
||||
. Fixed bug #77950 (Heap-buffer-overflow in _estrndup via exif_process_IFD_TAG).
|
||||
(CVE-2019-11036) (Stas)
|
||||
|
||||
- Interbase:
|
||||
. Fixed bug #72175 (Impossibility of creating multiple connections to
|
||||
Interbase with php 7.x). (Nikita)
|
||||
|
||||
- Intl:
|
||||
. Fixed bug #77895 (IntlDateFormatter::create fails in strict mode if $locale
|
||||
= null). (Nikita)
|
||||
|
||||
- LDAP:
|
||||
. Fixed bug #77869 (Core dump when using server controls) (mcmic)
|
||||
|
||||
- Mail
|
||||
. Fixed bug #77821 (Potential heap corruption in TSendMail()). (cmb)
|
||||
|
||||
- mbstring:
|
||||
. Implemented FR #72777 (Implement regex stack limits for mbregex functions).
|
||||
(Yasuo Ohgaki, Stas)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #77773 (Unbuffered queries leak memory - MySQLi / mysqlnd).
|
||||
(Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #77827 (preg_match does not ignore \r in regex flags). (requinix,
|
||||
cmb)
|
||||
|
||||
- PDO:
|
||||
. Fixed bug #77849 (Disable cloning of PDO handle/connection objects).
|
||||
(camporter)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #76801 (too many open files). (alekitto)
|
||||
. Fixed bug #77800 (phpdbg segfaults on listing some conditional breakpoints).
|
||||
(krakjoe)
|
||||
. Fixed bug #77805 (phpdbg build fails when readline is shared). (krakjoe)
|
||||
|
||||
- Reflection:
|
||||
. Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
|
||||
. Fixed bug #77882 (Different behavior: always calls destructor). (Nikita)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77793 (Segmentation fault in extract() when overwriting
|
||||
reference with itself). (Nikita)
|
||||
. Fixed bug #77844 (Crash due to null pointer in parse_ini_string with
|
||||
INI_SCANNER_TYPED). (Nikita)
|
||||
. Fixed bug #77853 (Inconsistent substr_compare behaviour with empty
|
||||
haystack). (Nikita)
|
||||
|
||||
04 Apr 2019, PHP 7.3.4
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77738 (Nullptr deref in zend_compile_expr). (Laruence)
|
||||
. Fixed bug #77660 (Segmentation fault on break 2147483648). (Laruence)
|
||||
. Fixed bug #77652 (Anonymous classes can lose their interface information).
|
||||
(Nikita)
|
||||
. Fixed bug #77345 (Stack Overflow caused by circular reference in garbage
|
||||
collection). (Alexandru Patranescu, Nikita, Dmitry)
|
||||
. Fixed bug #76956 (Wrong value for 'syslog.filter' documented in php.ini).
|
||||
(cmb)
|
||||
|
||||
- Apache2Handler:
|
||||
. Fixed bug #77648 (BOM in sapi/apache2handler/php_functions.c). (cmb)
|
||||
|
||||
- Bcmath:
|
||||
. Fixed bug #77742 (bcpow() implementation related to gcc compiler
|
||||
optimization). (Nikita)
|
||||
|
||||
- CLI Server:
|
||||
. Fixed bug #77722 (Incorrect IP set to $_SERVER['REMOTE_ADDR'] on the
|
||||
localhost). (Nikita)
|
||||
|
||||
- COM:
|
||||
. Fixed bug #77578 (Crash when php unload). (cmb)
|
||||
|
||||
- EXIF:
|
||||
. Fixed bug #77753 (Heap-buffer-overflow in php_ifd_get32s). (CVE-2019-11034)
|
||||
(Stas)
|
||||
. Fixed bug #77831 (Heap-buffer-overflow in exif_iif_add_value).
|
||||
(CVE-2019-11035) (Stas)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #77677 (FPM fails to build on AIX due to missing WCOREDUMP).
|
||||
(Kevin Adler)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #77700 (Writing truecolor images as GIF ignores interlace flag).
|
||||
(cmb)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #77743 (Incorrect pi node insertion for jmpznz with identical
|
||||
successors). (Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #76127 (preg_split does not raise an error on invalid UTF-8).
|
||||
(Nikita)
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #77697 (Crash on Big_Endian platform). (Laruence)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #77767 (phpdbg break cmd aliases listed in help do not match
|
||||
actual aliases). (Miriam Lauter)
|
||||
|
||||
- sodium:
|
||||
. Fixed bug #77646 (sign_detached() strings not terminated). (Frank)
|
||||
|
||||
- SQLite3:
|
||||
. Added sqlite3.defensive INI directive. (BohwaZ)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77664 (Segmentation fault when using undefined constant in
|
||||
custom wrapper). (Laruence)
|
||||
. Fixed bug #77669 (Crash in extract() when overwriting extracted array).
|
||||
(Nikita)
|
||||
. Fixed bug #76717 (var_export() does not create a parsable value for
|
||||
PHP_INT_MIN). (Nikita)
|
||||
. Fixed bug #77765 (FTP stream wrapper should set the directory as
|
||||
executable). (Vlad Temian)
|
||||
|
||||
07 Mar 2019, PHP 7.3.3
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77589 (Core dump using parse_ini_string with numeric sections).
|
||||
(Laruence)
|
||||
. Fixed bug #77329 (Buffer Overflow via overly long Error Messages).
|
||||
(Dmitry)
|
||||
. Fixed bug #77494 (Disabling class causes segfault on member access).
|
||||
(Dmitry)
|
||||
. Fixed bug #77498 (Custom extension Segmentation fault when declare static
|
||||
property). (Nikita)
|
||||
. Fixed bug #77530 (PHP crashes when parsing `(2)::class`). (Ekin)
|
||||
. Fixed bug #77546 (iptcembed broken function). (gdegoulet)
|
||||
. Fixed bug #77630 (rename() across the device may allow unwanted access
|
||||
during processing). (Stas)
|
||||
|
||||
- COM:
|
||||
. Fixed bug #77621 (Already defined constants are not properly reported).
|
||||
(cmb)
|
||||
. Fixed bug #77626 (Persistence confusion in php_com_import_typelib()). (cmb)
|
||||
|
||||
- EXIF:
|
||||
. Fixed bug #77509 (Uninitialized read in exif_process_IFD_in_TIFF). (Stas)
|
||||
. Fixed bug #77540 (Invalid Read on exif_process_SOFn). (Stas)
|
||||
. Fixed bug #77563 (Uninitialized read in exif_process_IFD_in_MAKERNOTE). (Stas)
|
||||
. Fixed bug #77659 (Uninitialized read in exif_process_IFD_in_MAKERNOTE). (Stas)
|
||||
|
||||
- Mbstring:
|
||||
. Fixed bug #77514 (mb_ereg_replace() with trailing backslash adds null byte).
|
||||
(Nikita)
|
||||
|
||||
- MySQL
|
||||
. Disabled LOCAL INFILE by default, can be enabled using php.ini directive
|
||||
mysqli.allow_local_infile for mysqli, or PDO::MYSQL_ATTR_LOCAL_INFILE
|
||||
attribute for pdo_mysql. (Darek Slusarczyk)
|
||||
|
||||
- OpenSSL:
|
||||
. Fixed bug #77390 (feof might hang on TLS streams in case of fragmented TLS
|
||||
records). (Abyl Valg, Jakub Zelenka)
|
||||
|
||||
- PDO_OCI:
|
||||
. Support Oracle Database tracing attributes ACTION, MODULE,
|
||||
CLIENT_INFO, and CLIENT_IDENTIFIER. (Cameron Porter)
|
||||
|
||||
- PHAR:
|
||||
. Fixed bug #77396 (Null Pointer Dereference in phar_create_or_parse_filename).
|
||||
(bishop)
|
||||
. Fixed bug #77586 (phar_tar_writeheaders_int() buffer overflow). (bishop)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #76596 (phpdbg support for display_errors=stderr). (kabel)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #51068 (DirectoryIterator glob:// don't support current path
|
||||
relative queries). (Ahmed Abdou)
|
||||
. Fixed bug #77431 (openFile() silently truncates after a null byte). (cmb)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77552 (Unintialized php_stream_statbuf in stat functions).
|
||||
(John Stevenson)
|
||||
. Fixed bug #77612 (setcookie() sets incorrect SameSite header if all of its
|
||||
options filled). (Nikita)
|
||||
|
||||
07 Feb 2019, PHP 7.3.2
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77369 (memcpy with negative length via crafted DNS response). (Stas)
|
||||
. Fixed bug #77387 (Recursion detection broken when printing GLOBALS).
|
||||
(Laruence)
|
||||
. Fixed bug #77376 ("undefined function" message no longer includes
|
||||
namespace). (Laruence)
|
||||
. Fixed bug #77357 (base64_encode / base64_decode doest not work on nested
|
||||
VM). (Nikita)
|
||||
. Fixed bug #77339 (__callStatic may get incorrect arguments). (Dmitry)
|
||||
. Fixed bug #77317 (__DIR__, __FILE__, realpath() reveal physical path for
|
||||
subst virtual drive). (Anatol)
|
||||
. Fixed bug #77263 (Segfault when using 2 RecursiveFilterIterator). (Dmitry)
|
||||
. Fixed bug #77447 (PHP 7.3 built with ASAN crashes in
|
||||
zend_cpu_supports_avx2). (Nikita)
|
||||
. Fixed bug #77484 (Zend engine crashes when calling realpath in invalid
|
||||
working dir). (Anatol)
|
||||
|
||||
- Curl:
|
||||
. Fixed bug #76675 (Segfault with H2 server push). (Pedro Magalhães)
|
||||
|
||||
- Fileinfo:
|
||||
. Fixed bug #77346 (webm files incorrectly detected as
|
||||
application/octet-stream). (Anatol)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #77430 (php-fpm crashes with Main process exited, code=dumped,
|
||||
status=11/SEGV). (Jakub Zelenka)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #73281 (imagescale(…, IMG_BILINEAR_FIXED) can cause black border).
|
||||
(cmb)
|
||||
. Fixed bug #73614 (gdImageFilledArc() doesn't properly draw pies). (cmb)
|
||||
. Fixed bug #77272 (imagescale() may return image resource on failure). (cmb)
|
||||
. Fixed bug #77391 (1bpp BMPs may fail to be loaded). (Romain Déoux, cmb)
|
||||
. Fixed bug #77479 (imagewbmp() segfaults with very large images). (cmb)
|
||||
|
||||
- ldap:
|
||||
. Fixed bug #77440 (ldap_bind using ldaps or ldap_start_tls()=exception in
|
||||
libcrypto-1_1-x64.dll). (Anatol)
|
||||
|
||||
- Mbstring:
|
||||
. Fixed bug #77428 (mb_ereg_replace() doesn't replace a substitution
|
||||
variable). (Nikita)
|
||||
. Fixed bug #77454 (mb_scrub() silently truncates after a null byte).
|
||||
(64796c6e69 at gmail dot com)
|
||||
|
||||
- MySQLnd:
|
||||
. Fixed bug #77308 (Unbuffered queries memory leak). (Dmitry)
|
||||
. Fixed bug #75684 (In mysqlnd_ext_plugin.h the plugin methods family has
|
||||
no external visibility). (Anatol)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #77266 (Assertion failed in dce_live_ranges). (Laruence)
|
||||
. Fixed bug #77257 (value of variable assigned in a switch() construct gets
|
||||
lost). (Nikita)
|
||||
. Fixed bug #77434 (php-fpm workers are segfaulting in zend_gc_addre).
|
||||
(Nikita)
|
||||
. Fixed bug #77361 (configure fails on 64-bit AIX when opcache enabled).
|
||||
(Kevin Adler)
|
||||
. Fixed bug #77287 (Opcache literal compaction is incompatible with EXT
|
||||
opcodes). (Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #77338 (get_browser with empty string). (Nikita)
|
||||
|
||||
- PDO:
|
||||
. Fixed bug #77273 (array_walk_recursive corrupts value types leading to PDO
|
||||
failure). (Nikita)
|
||||
|
||||
- PDO MySQL:
|
||||
. Fixed bug #77289 (PDO MySQL segfaults with persistent connection).
|
||||
(Lauri Kenttä)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #77410 (Segmentation Fault when executing method with an empty
|
||||
parameter). (Nikita)
|
||||
|
||||
- Sockets:
|
||||
. Fixed bug #76839 (socket_recvfrom may return an invalid 'from' address
|
||||
on MacOS). (Michael Meyer)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #77298 (segfault occurs when add property to unserialized empty
|
||||
ArrayObject). (jhdxr)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77395 (segfault about array_multisort). (Laruence)
|
||||
. Fixed bug #77439 (parse_str segfaults when inserting item into existing
|
||||
array). (Nikita)
|
||||
|
||||
10 Jan 2019, PHP 7.3.1
|
||||
|
||||
- Core:
|
||||
. Fixed bug #76654 (Build failure on Mac OS X on 32-bit Intel). (Ryandesign)
|
||||
. Fixed bug #71041 (zend_signal_startup() needs ZEND_API).
|
||||
(Valentin V. Bartenev)
|
||||
. Fixed bug #76046 (PHP generates "FE_FREE" opcode on the wrong line).
|
||||
(Nikita)
|
||||
. Fixed bug #77291 (magic methods inherited from a trait may be ignored).
|
||||
(cmb)
|
||||
|
||||
- CURL:
|
||||
. Fixed bug #77264 (curl_getinfo returning microseconds, not seconds).
|
||||
(Pierrick)
|
||||
|
||||
- COM:
|
||||
. Fixed bug #77177 (Serializing or unserializing COM objects crashes). (cmb)
|
||||
|
||||
- Exif:
|
||||
. Fixed bug #77184 (Unsigned rational numbers are written out as signed
|
||||
rationals). (Colin Basnett)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #77195 (Incorrect error handling of imagecreatefromjpeg()). (cmb)
|
||||
. Fixed bug #77198 (auto cropping has insufficient precision). (cmb)
|
||||
. Fixed bug #77200 (imagecropauto(…, GD_CROP_SIDES) crops left but not right).
|
||||
(cmb)
|
||||
. Fixed bug #77269 (efree() on uninitialized Heap data in imagescale leads to
|
||||
use-after-free). (cmb)
|
||||
. Fixed bug #77270 (imagecolormatch Out Of Bounds Write on Heap). (cmb)
|
||||
|
||||
- MBString:
|
||||
. Fixed bug #77367 (Negative size parameter in mb_split). (Stas)
|
||||
. Fixed bug #77370 (Buffer overflow on mb regex functions - fetch_token).
|
||||
(Stas)
|
||||
. Fixed bug #77371 (heap buffer overflow in mb regex functions
|
||||
- compile_string_node). (Stas)
|
||||
. Fixed bug #77381 (heap buffer overflow in multibyte match_at). (Stas)
|
||||
. Fixed bug #77382 (heap buffer overflow due to incorrect length in
|
||||
expand_case_fold_string). (Stas)
|
||||
. Fixed bug #77385 (buffer overflow in fetch_token). (Stas)
|
||||
. Fixed bug #77394 (Buffer overflow in multibyte case folding - unicode).
|
||||
(Stas)
|
||||
. Fixed bug #77418 (Heap overflow in utf32be_mbc_to_code). (Stas)
|
||||
|
||||
- OCI8:
|
||||
. Fixed bug #76804 (oci_pconnect with OCI_CRED_EXT not working). (KoenigsKind)
|
||||
. Added oci_set_call_timeout() for call timeouts.
|
||||
. Added oci_set_db_operation() for the DBOP end-to-end-tracing attribute.
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #77215 (CFG assertion failure on multiple finalizing switch
|
||||
frees in one block). (Nikita)
|
||||
. Fixed bug #77275 (OPcache optimization problem for ArrayAccess->offsetGet).
|
||||
(Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #77193 (Infinite loop in preg_replace_callback). (Anatol)
|
||||
|
||||
- PDO:
|
||||
. Handle invalid index passed to PDOStatement::fetchColumn() as error. (Sergei
|
||||
Morozov)
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #77247 (heap buffer overflow in phar_detect_phar_fname_ext). (Stas)
|
||||
|
||||
- Soap:
|
||||
. Fixed bug #77088 (Segfault when using SoapClient with null options).
|
||||
(Laruence)
|
||||
|
||||
- Sockets:
|
||||
. Fixed bug #77136 (Unsupported IPV6_RECVPKTINFO constants on macOS).
|
||||
(Mizunashi Mana)
|
||||
|
||||
- Sodium:
|
||||
. Fixed bug #77297 (SodiumException segfaults on PHP 7.3). (Nikita, Scott)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #77359 (spl_autoload causes segfault). (Lauri Kenttä)
|
||||
. Fixed bug #77360 (class_uses causes segfault). (Lauri Kenttä)
|
||||
|
||||
- SQLite3:
|
||||
. Fixed bug #77051 (Issue with re-binding on SQLite3). (BohwaZ)
|
||||
|
||||
- Xmlrpc:
|
||||
. Fixed bug #77242 (heap out of bounds read in xmlrpc_decode()). (cmb)
|
||||
. Fixed bug #77380 (Global out of bounds read in xmlrpc base64 code). (Stas)
|
||||
|
||||
06 Dec 2018, PHP 7.3.0
|
||||
|
||||
- Core:
|
||||
@@ -496,7 +10,6 @@ PHP NEWS
|
||||
. Removed support for BeOS. (Kalle)
|
||||
. Add PHP_VERSION to phpinfo() <title/>. (github/MattJeevas)
|
||||
. Add net_get_interfaces(). (Sara, Joe, Anatol)
|
||||
. Added gc_status(). (Benjamin Eberlei)
|
||||
. Implemented flexible heredoc and nowdoc syntax, per
|
||||
RFC https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes.
|
||||
(Thomas Punt)
|
||||
@@ -504,7 +17,7 @@ PHP NEWS
|
||||
RFC https://wiki.php.net/rfc/list_reference_assignment.
|
||||
(David Walker)
|
||||
. Improved effectiveness of ZEND_SECURE_ZERO for NetBSD and systems
|
||||
without native similar feature. (devnexen)
|
||||
without native similar feature (devnexen).
|
||||
. Added syslog.facility and syslog.ident INI entries for customizing syslog
|
||||
logging. (Philip Prindeville)
|
||||
. Fixed bug #75683 (Memory leak in zend_register_functions() in ZTS mode).
|
||||
@@ -550,9 +63,9 @@ PHP NEWS
|
||||
(Laruence)
|
||||
. Fixed bug #76030 (RE2C_FLAGS rarely honoured) (Cristian Rodríguez)
|
||||
. Fixed broken zend_read_static_property (Laruence)
|
||||
. Fixed bug #76773 (Traits used on the parent are ignored for child classes).
|
||||
. Fixed #76773 (Traits used on the parent are ignored for child classes).
|
||||
(daverandom)
|
||||
. Fixed bug #76767 (‘asm’ operand has impossible constraints in zend_operators.h).
|
||||
. Fixed #76767 (‘asm’ operand has impossible constraints in zend_operators.h).
|
||||
(ondrej)
|
||||
. Fixed bug #76752 (Crash in ZEND_COALESCE_SPEC_TMP_HANDLER - assertion in
|
||||
_get_zval_ptr_tmp failed). (Laruence)
|
||||
@@ -569,10 +82,12 @@ PHP NEWS
|
||||
. Fixed bug #76825 (Undefined symbols ___cpuid_count). (Laruence, cmb)
|
||||
. Fixed bug #77110 (undefined symbol zend_string_equal_val in C++ build).
|
||||
(Remi)
|
||||
. Fixed bug #77231 (Segfault when using convert.quoted-printable-encode
|
||||
filter). (Stas)
|
||||
|
||||
- BCMath:
|
||||
. Implemented FR #67855 (No way to get current scale in use). (Chris Wright,
|
||||
cmb)
|
||||
. Implemented request #67855 (No way to get current scale in use). (Chris
|
||||
Wright, cmb)
|
||||
. Fixed bug #66364 (BCMath bcmul ignores scale parameter). (cmb)
|
||||
. Fixed bug #75164 (split_bc_num() is pointless). (cmb)
|
||||
. Fixed bug #75169 (BCMath errors/warnings bypass PHP's error handling). (cmb)
|
||||
@@ -595,11 +110,13 @@ PHP NEWS
|
||||
. Fixed bug #68406 (calling var_dump on a DateTimeZone object modifies it).
|
||||
(jhdxr)
|
||||
. Fixed bug #76131 (mismatch arginfo for date_create). (carusogabriel)
|
||||
. Updated timelib to 2018.01RC1 to address several bugs:
|
||||
. Updated timelib to 2018.01RC1 to address several bugs: (Derick)
|
||||
. Fixed bug #75577 (DateTime::createFromFormat does not accept 'v' format
|
||||
specifier). (Derick)
|
||||
. Fixed bug #75642 (Wrap around behaviour for microseconds is not working).
|
||||
(Derick)
|
||||
. Fixed bug #77097 (DateTime::diff gives wrong diff when the actual diff is
|
||||
less than 1 second). (Derick)
|
||||
|
||||
- DBA:
|
||||
. Fixed bug #75264 (compiler warnings emitted). (petk)
|
||||
@@ -627,7 +144,7 @@ PHP NEWS
|
||||
. Fixed bug #77151 (ftp_close(): SSL_read on shutdown). (Remi)
|
||||
|
||||
- GD:
|
||||
. Added support for WebP in imagecreatefromstring(). (Andreas Treichel, cmb)
|
||||
. Added support for WebP in imagecreatefromstring() (Andreas Treichel, cmb).
|
||||
|
||||
- GMP:
|
||||
. Export internal structures and accessor helpers for GMP object. (Sara)
|
||||
@@ -642,9 +159,9 @@ PHP NEWS
|
||||
(cmb)
|
||||
|
||||
- IMAP:
|
||||
. Fixed bug #77020 (null pointer dereference in imap_mail). (cmb)
|
||||
. Fixed bug #77153 (imap_open allows to run arbitrary shell commands via
|
||||
mailbox parameter). (Stas)
|
||||
. Fixed bug #77020 (null pointer dereference in imap_mail). (cmb)
|
||||
|
||||
- Interbase:
|
||||
. Fixed bug #75453 (Incorrect reflection for ibase_[p]connect). (villfa)
|
||||
@@ -663,7 +180,7 @@ PHP NEWS
|
||||
- LDAP:
|
||||
. Added ldap_exop_refresh helper for EXOP REFRESH operation with dds overlay.
|
||||
(Come)
|
||||
. Added full support for sending and parsing ldap controls. (Come)
|
||||
. Added full support for sending and parsing ldap controls (Come)
|
||||
. Fixed bug #49876 (Fix LDAP path lookup on 64-bit distros). (dzuelke)
|
||||
|
||||
- libxml2:
|
||||
@@ -678,7 +195,7 @@ PHP NEWS
|
||||
. Updated to Oniguruma 6.9.0. (cmb)
|
||||
. Fixed bug #65544 (mb title case conversion-first word in quotation isn't
|
||||
capitalized). (Nikita)
|
||||
. Fixed bug #71298 (MB_CASE_TITLE misbehaves with curled apostrophe/quote).
|
||||
. Fixed bug #71298 (MB_CASE_TITLE misbehaves with curled apostrophe/quote.
|
||||
(Nikita)
|
||||
. Fixed bug #73528 (Crash in zif_mb_send_mail). (Nikita)
|
||||
. Fixed bug #74929 (mbstring functions version 7.1.1 are slow compared to 5.3
|
||||
@@ -721,7 +238,7 @@ PHP NEWS
|
||||
related constants for possible TLS protocol values. (Jakub Zelenka)
|
||||
|
||||
- PCRE:
|
||||
. Implemented https://wiki.php.net/rfc/pcre2-migration. (Anatol, Dmitry)
|
||||
. Implemented https://wiki.php.net/rfc/pcre2-migration (Anatol, Dmitry)
|
||||
. Upgrade PCRE2 to 10.32. (Anatol)
|
||||
. Fixed bug #75355 (preg_quote() does not quote # control character).
|
||||
(Michael Moravec)
|
||||
@@ -731,8 +248,8 @@ PHP NEWS
|
||||
. Fixed bug #76909 (preg_match difference between 7.3 and < 7.3). (Anatol)
|
||||
|
||||
- PDO_DBlib:
|
||||
. Implemented FR #69592 (allow 0-column rowsets to be skipped automatically).
|
||||
(fandrieu)
|
||||
. Implemented request #69592 (allow 0-column rowsets to be skipped
|
||||
automatically). (fandrieu)
|
||||
. Expose TDS version as \PDO::DBLIB_ATTR_TDS_VERSION attribute on \PDO
|
||||
instance. (fandrieu)
|
||||
. Treat DATETIME2 columns like DATETIME. (fandrieu)
|
||||
@@ -750,9 +267,15 @@ PHP NEWS
|
||||
. Add support for additional open flags
|
||||
|
||||
- pgsql:
|
||||
. Added new error constants for pg_result_error(): PGSQL_DIAG_SCHEMA_NAME,
|
||||
PGSQL_DIAG_TABLE_NAME, PGSQL_DIAG_COLUMN_NAME, PGSQL_DIAG_DATATYPE_NAME,
|
||||
PGSQL_DIAG_CONSTRAINT_NAME and PGSQL_DIAG_SEVERITY_NONLOCALIZED. (Kalle)
|
||||
. Added new error constants for pg_result_error(): (Kalle)
|
||||
. Requires Postgres 9.3
|
||||
. PGSQL_DIAG_SCHEMA_NAME
|
||||
. PGSQL_DIAG_TABLE_NAME
|
||||
. PGSQL_DIAG_COLUMN_NAME
|
||||
. PGSQL_DIAG_DATATYPE_NAME
|
||||
. PGSQL_DIAG_CONSTRAINT_NAME
|
||||
. Requires Postgres 9.6
|
||||
. PGSQL_DIAG_SEVERITY_NONLOCALIZED
|
||||
. Fixed bug #77047 (pg_convert has a broken regex for the 'TIME WITHOUT
|
||||
TIMEZONE' data type). (Andy Gajetzki)
|
||||
|
||||
@@ -761,6 +284,9 @@ PHP NEWS
|
||||
(bwbroersma)
|
||||
. Fixed bug #65414 (deal with leading slash when adding files correctly).
|
||||
(bishopb)
|
||||
. Fixed bug #77022 (PharData always creates new files with mode 0666). (Stas)
|
||||
. Fixed bug #77143 (Heap Buffer Overflow (READ: 4) in phar_parse_pharfile).
|
||||
(Stas)
|
||||
|
||||
- readline:
|
||||
. Added completion_append_character and completion_suppress_append options
|
||||
@@ -837,10 +363,11 @@ PHP NEWS
|
||||
. Fixed bug #77081 (ftruncate() changes seek pointer in c mode). (cmb, Anatol)
|
||||
|
||||
- Testing:
|
||||
. Implemented FR #62055 (Make run-tests.php support --CGI-- sections). (cmb)
|
||||
. Implemented request #62055 (Make run-tests.php support --CGI-- sections).
|
||||
(cmb)
|
||||
|
||||
- Tidy:
|
||||
. Support using tidyp instead of tidy. (devnexen)
|
||||
. Support using tidyp instead of tidy (devnexen).
|
||||
. Fixed bug #74707 (Tidy has incorrect ReflectionFunction param counts for
|
||||
functions taking tidy). (Gabriel Caruso)
|
||||
. Fixed arginfo for tidy::__construct(). (Tyson Andre)
|
||||
@@ -856,7 +383,7 @@ PHP NEWS
|
||||
heredoc strings). (Nikita)
|
||||
|
||||
- XML:
|
||||
. Fixed bug #71592 (External entity processing never fails). (cmb)
|
||||
. Fixed bug 71592 (External entity processing never fails). (cmb)
|
||||
|
||||
- Zlib:
|
||||
. Added zlib/level context option for compress.zlib wrapper. (Sara)
|
||||
|
||||
@@ -167,7 +167,13 @@ TSRM_API const char *tsrm_api_name(void);
|
||||
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
|
||||
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
|
||||
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
|
||||
#if ZEND_DEBUG
|
||||
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
|
||||
#define TSRMLS_CACHE_RESET()
|
||||
#else
|
||||
#define TSRMLS_CACHE_UPDATE() if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
|
||||
#define TSRMLS_CACHE_RESET() TSRMLS_CACHE = NULL
|
||||
#endif
|
||||
#define TSRMLS_CACHE _tsrm_ls_cache
|
||||
|
||||
/* BC only */
|
||||
|
||||
@@ -53,7 +53,7 @@ Core:
|
||||
case "baz":
|
||||
continue;
|
||||
// Warning: "continue" targeting switch is equivalent to
|
||||
// "break". Did you mean to use "continue 2"?
|
||||
"break". Did you mean to use "continue 2"?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +112,6 @@ BCMath:
|
||||
. bcmul() and bcpow() now return numbers with the requested scale. Formerly,
|
||||
the returned numbers may have omitted trailing decimal zeroes.
|
||||
|
||||
IMAP:
|
||||
rsh/ssh logins are disabled by default. Use imap.enable_insecure_rsh if you want
|
||||
to enable them. Note that the IMAP library does not filter mailbox names before
|
||||
passing them to rsh/ssh command, thus passing untrusted data to this function
|
||||
with rsh/ssh enabled is insecure.
|
||||
|
||||
MBString:
|
||||
. Due to added support for named captures, mb_ereg_*() patterns using named
|
||||
captures will behave differently. In particular named captures will be part
|
||||
@@ -251,10 +245,6 @@ Standard:
|
||||
PHP be linked against libargon2 reference library >= 20161029.
|
||||
(RFC: https://wiki.php.net/rfc/argon2_password_hash_enhancements).
|
||||
|
||||
LDAP:
|
||||
. Full support for LDAP Controls has been added to LDAP querying functions
|
||||
and ldap_parse_result
|
||||
|
||||
========================================
|
||||
3. Changes in SAPI modules
|
||||
========================================
|
||||
@@ -264,14 +254,6 @@ phpdbg:
|
||||
PHPDBG_FUNC have been removed.
|
||||
|
||||
FPM:
|
||||
. A new global option log_limit has been added. It can be used for setting
|
||||
log limit for logged line which allows to log messages longer than 1024
|
||||
characters without wrapping. It also fixes various wrapping issues.
|
||||
. A new global option log_buffering has been added. It allows an experimental
|
||||
logging without extra buffering.
|
||||
. A new pool option decorate_workers_output has been added. It allows
|
||||
disabling output decoration for workers output when catch_workers_output
|
||||
enabled.
|
||||
. The getallheaders() function is now also available.
|
||||
|
||||
========================================
|
||||
@@ -327,7 +309,7 @@ Standard:
|
||||
. Passing a non-string needle to string search functions is deprecated. In the
|
||||
future the needle will be interpreted as a string instead of an ASCII codepoint.
|
||||
Depending on the intended behavior, you should either explicitly cast the
|
||||
needle to string or perform an explicit call to chr(). The following functions
|
||||
needle to string or perform an explicit call to ord(). The following functions
|
||||
are affected:
|
||||
. strpos()
|
||||
. strrpos()
|
||||
@@ -373,16 +355,6 @@ Standard:
|
||||
PCRE:
|
||||
. preg_quote() now also escapes the '#' character.
|
||||
|
||||
LDAP:
|
||||
. Added a serverctrls parameter to send controls to the server in ldap_add,
|
||||
ldap_mod_replace, ldap_mod_add, ldap_mod_del, ldap_rename,
|
||||
ldap_compare, ldap_delete, ldap_modify_batch,
|
||||
ldap_search, ldap_list, ldap_read
|
||||
. Added an out parameter to get controls from the server in ldap_parse_result
|
||||
. Fixed support for LDAP_OPT_SERVER_CONTROLS and LDAP_OPT_CLIENT_CONTROLS in
|
||||
ldap_get_option and ldap_set_option.
|
||||
|
||||
|
||||
========================================
|
||||
6. New Functions
|
||||
========================================
|
||||
@@ -397,10 +369,6 @@ Core:
|
||||
are available under Linux, FreeBSD, Windows, Mac, SunOS, AIX and their
|
||||
derivatives. If no required timers are provided by a corresponding
|
||||
platform, the function returns false.
|
||||
. Added net_get_interfaces() to retrieve an array of available network
|
||||
interfaces including several details.
|
||||
. Added the gc_status() function to retrieve status information regarding the
|
||||
cyclic GC.
|
||||
|
||||
Date:
|
||||
. Added the DateTime::createFromImmutable() method, which mirrors
|
||||
@@ -430,10 +398,6 @@ Intl:
|
||||
. Added Normalizer::getRawDecomposition() and normalizer_get_raw_decomposition(),
|
||||
to retrieve the Decomposition_Mapping property of a character.
|
||||
|
||||
LDAP:
|
||||
. Added ldap_exop_refresh() to conveniently perform a Refresh extended
|
||||
operation.
|
||||
|
||||
OpenSSL:
|
||||
. Added openssl_pkey_derive that derives a shared secret for DH, ECDH and
|
||||
possibly other future algorithms supported by EVP_PKEY_derive.
|
||||
@@ -461,13 +425,6 @@ Standard:
|
||||
last key of an array, respectively.
|
||||
(RFC: <https://wiki.php.net/rfc/array_key_first_last>)
|
||||
|
||||
LDAP:
|
||||
. Added functions ldap_add_ext, ldap_bind_ext, ldap_delete_ext, ldap_mod_add_ext,
|
||||
ldap_mod_replace_ext, ldap_mod_del_ext, ldap_rename_ext
|
||||
which gives access to the result object to be able to parse it
|
||||
with ldap_parse_result and get more information than just success/failure.
|
||||
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
========================================
|
||||
@@ -492,7 +449,7 @@ JSON:
|
||||
is fully backward compatible with former PHP versions.
|
||||
. FILTER_SANITIZE_ADD_SLASHES has been added as an alias of the 'magic_quotes'
|
||||
filter (FILTER_SANITIZE_MAGIC_QUOTES). The 'magic_quotes' filter is subject
|
||||
to removal in future versions of PHP.
|
||||
to removal in future versions of PHP.
|
||||
|
||||
FTP:
|
||||
. Set default transfer mode to binary
|
||||
@@ -514,22 +471,12 @@ JSON:
|
||||
related constants for possible TLS protocol values have been added.
|
||||
See <https://github.com/php/php-src/pull/3317>.
|
||||
|
||||
PCRE:
|
||||
PCRE:
|
||||
. The PCRE extension has been upgraded to PCRE2, which may cause minor
|
||||
behavioral changes (for instance, character ranges in classes are now more
|
||||
strictly interpreted), and augments the existing regular expression syntax.
|
||||
See <https://wiki.php.net/rfc/pcre2-migration> for details.
|
||||
|
||||
PDO_DBLIB:
|
||||
. Added the attribute PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS to enable automatic
|
||||
skipping of empty rowsets.
|
||||
. Exposed the TDS version via the PDO::DBLIB_ATTR_TDS_VERSION attribute.
|
||||
. DATETIME2 columns are now treated like DATETIME columns.
|
||||
|
||||
PDO_SQLite:
|
||||
. SQLite3 databases can now be opened in read-only mode by setting the
|
||||
new PDO::SQLITE_ATTR_OPEN_FLAGS attribute to PDO::SQLITE_READONLY.
|
||||
|
||||
Standard:
|
||||
. var_export() now exports stdClass objects as an array casted to an object
|
||||
(`(object) array( ... )`), rather than using the nonexistent method
|
||||
@@ -549,10 +496,6 @@ JSON:
|
||||
. Building against the bundled libzip is discouraged, but still possible by
|
||||
adding `--without-libzip` to the configuration.
|
||||
|
||||
zlib:
|
||||
. Added the zlib/level context option for the compress.zlib wrapper to
|
||||
facilitate setting the desired compression level.
|
||||
|
||||
========================================
|
||||
10. New Global Constants
|
||||
========================================
|
||||
@@ -622,37 +565,27 @@ Curl:
|
||||
. CURL_SSLVERSION_MAX_TLSv1_2
|
||||
. CURL_SSLVERSION_MAX_TLSv1_3
|
||||
. CURL_SSLVERSION_TLSv1_3
|
||||
. CURL_VERSION_ALTSVC
|
||||
. CURL_VERSION_ASYNCHDNS
|
||||
. CURL_VERSION_BROTLI
|
||||
. CURL_VERSION_CONV
|
||||
. CURL_VERSION_CURLDEBUG
|
||||
. CURL_VERSION_DEBUG
|
||||
. CURL_VERSION_GSSAPI
|
||||
. CURL_VERSION_GSSNEGOTIATE
|
||||
. CURL_VERSION_HTTPS_PROXY
|
||||
. CURL_VERSION_IDN
|
||||
. CURL_VERSION_KERBEROS5
|
||||
. CURL_VERSION_LARGEFILE
|
||||
. CURL_VERSION_MULTI_SSL
|
||||
. CURL_VERSION_NTLM
|
||||
. CURL_VERSION_NTLM_WB
|
||||
. CURL_VERSION_PSL
|
||||
. CURL_VERSION_SPNEGO
|
||||
. CURL_VERSION_SSPI
|
||||
. CURL_VERSION_TLSAUTH_SRP
|
||||
|
||||
Filter:
|
||||
. FILTER_SANITIZE_ADD_SLASHES
|
||||
. CURL_VERSION_UNIX_SOCKETS
|
||||
|
||||
JSON:
|
||||
. JSON_THROW_ON_ERROR
|
||||
|
||||
OpenSSL:
|
||||
. STREAM_CRYPTO_PROTO_SSLv3
|
||||
. STREAM_CRYPTO_PROTO_TLSv1_0
|
||||
. STREAM_CRYPTO_PROTO_TLSv1_1
|
||||
. STREAM_CRYPTO_PROTO_TLSv1_2
|
||||
|
||||
MBString:
|
||||
. MB_CASE_FOLD
|
||||
. MB_CASE_LOWER_SIMPLE
|
||||
@@ -673,34 +606,6 @@ PGSQL:
|
||||
Standard:
|
||||
. PASSWORD_ARGON2ID
|
||||
|
||||
LDAP:
|
||||
. LDAP_CONTROL_MANAGEDSAIT
|
||||
. LDAP_CONTROL_PROXY_AUTHZ
|
||||
. LDAP_CONTROL_SUBENTRIES
|
||||
. LDAP_CONTROL_VALUESRETURNFILTER
|
||||
. LDAP_CONTROL_ASSERT
|
||||
. LDAP_CONTROL_PRE_READ
|
||||
. LDAP_CONTROL_POST_READ
|
||||
. LDAP_CONTROL_SORTREQUEST
|
||||
. LDAP_CONTROL_SORTRESPONSE
|
||||
. LDAP_CONTROL_PAGEDRESULTS
|
||||
. LDAP_CONTROL_AUTHZID_REQUEST
|
||||
. LDAP_CONTROL_AUTHZID_RESPONSE
|
||||
. LDAP_CONTROL_SYNC
|
||||
. LDAP_CONTROL_SYNC_STATE
|
||||
. LDAP_CONTROL_SYNC_DONE
|
||||
. LDAP_CONTROL_DONTUSECOPY
|
||||
. LDAP_CONTROL_PASSWORDPOLICYREQUEST
|
||||
. LDAP_CONTROL_PASSWORDPOLICYRESPONSE
|
||||
. LDAP_CONTROL_X_INCREMENTAL_VALUES
|
||||
. LDAP_CONTROL_X_DOMAIN_SCOPE
|
||||
. LDAP_CONTROL_X_PERMISSIVE_MODIFY
|
||||
. LDAP_CONTROL_X_SEARCH_OPTIONS
|
||||
. LDAP_CONTROL_X_TREE_DELETE
|
||||
. LDAP_CONTROL_X_EXTENDED_DN
|
||||
. LDAP_CONTROL_VLVREQUEST
|
||||
. LDAP_CONTROL_VLVRESPONSE
|
||||
|
||||
========================================
|
||||
11. Changes to INI File Handling
|
||||
========================================
|
||||
@@ -730,10 +635,6 @@ LDAP:
|
||||
. New INI to set syslog ident string which is prepended to every message. It
|
||||
is used only when error_log is set syslog.
|
||||
|
||||
- mbstring.regex_stack_limit
|
||||
. New INI directive (since 7.3.5) limiting stack depth of mbstring/oniguruma
|
||||
regular expressions.
|
||||
|
||||
========================================
|
||||
12. Windows Support
|
||||
========================================
|
||||
@@ -748,6 +649,3 @@ LDAP:
|
||||
========================================
|
||||
13. Other Changes
|
||||
========================================
|
||||
|
||||
. The cyclic GC has been enhanced, which may result in considerable performance
|
||||
improvements.
|
||||
@@ -13,22 +13,18 @@ spl_autoload_register(function ($className) {
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
new Foo();
|
||||
} catch (Exception $e) { }
|
||||
|
||||
// We never reach here.
|
||||
var_dump(new Foo());
|
||||
new Foo;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(3) "Foo"
|
||||
string(3) "Bar"
|
||||
|
||||
Fatal error: During class fetch: Uncaught Exception: Bar in %s:%d
|
||||
Fatal error: Uncaught Exception: Bar in %s:%d
|
||||
Stack trace:
|
||||
#0 [internal function]: {closure}('Bar')
|
||||
#1 %s(%d): spl_autoload_call('Bar')
|
||||
#2 [internal function]: {closure}('Foo')
|
||||
#3 %s(%d): spl_autoload_call('Foo')
|
||||
#4 {main} in %s on line %d
|
||||
#4 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -45,13 +45,6 @@ elseif (PHP_OS == 'FreeBSD') {
|
||||
if ($freeMemory < 2100*1024*1024) {
|
||||
die('skip Not enough memory.');
|
||||
}
|
||||
} elseif (PHP_OS == "WINNT") {
|
||||
$s = trim(shell_exec("wmic OS get FreeVirtualMemory /Value 2>nul"));
|
||||
$freeMemory = explode('=', $s)[1]*1;
|
||||
|
||||
if ($freeMemory < 2.1*1024*1024) {
|
||||
die('skip Not enough memory.');
|
||||
}
|
||||
}
|
||||
?>
|
||||
--INI--
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
--TEST--
|
||||
Bug #75426: "Cannot use empty array elements" reports wrong position
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
,
|
||||
5,
|
||||
6,
|
||||
];
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot use empty array elements in arrays in %s on line 5
|
||||
@@ -1,42 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77291 (magic methods inherited from a trait may be ignored)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
trait AccessibleProperties
|
||||
{
|
||||
public function __isset($property)
|
||||
{
|
||||
return property_exists($this, $property);
|
||||
}
|
||||
|
||||
public function __get($property)
|
||||
{
|
||||
if (property_exists($this, $property)) {
|
||||
return $this->$property;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Foo4567 {
|
||||
use AccessibleProperties;
|
||||
|
||||
protected $a = 'Some value';
|
||||
}
|
||||
|
||||
class Foo45 {
|
||||
use AccessibleProperties;
|
||||
|
||||
protected $a = 'Some value';
|
||||
}
|
||||
|
||||
$foo = new Foo4567;
|
||||
var_dump(isset($foo->a));
|
||||
$foo = new Foo45;
|
||||
var_dump($foo->a);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
string(10) "Some value"
|
||||
===DONE===
|
||||
@@ -1,33 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77339 (__callStatic may get incorrect arguments)
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo
|
||||
{
|
||||
static function __callStatic($name, $arguments) {
|
||||
if ($name === 'get') {
|
||||
if (!isset($arguments[0])) {
|
||||
var_dump(['getSomeWhat']);
|
||||
var_dump($arguments);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo "OK\n";
|
||||
}
|
||||
|
||||
protected function get ($key) {
|
||||
echo "BUG!!!\n";
|
||||
}
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
static function __callStatic($name, $arguments) {
|
||||
echo Foo::get('getSomeWhat');
|
||||
}
|
||||
}
|
||||
|
||||
Bar::someUndefinedStaticFunction();
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
@@ -1,42 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
|
||||
--INI--
|
||||
zend.enable_gc = 1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Node
|
||||
{
|
||||
/** @var Node */
|
||||
public $previous;
|
||||
/** @var Node */
|
||||
public $next;
|
||||
}
|
||||
|
||||
var_dump(gc_enabled());
|
||||
var_dump('start');
|
||||
|
||||
$firstNode = new Node();
|
||||
$firstNode->previous = $firstNode;
|
||||
$firstNode->next = $firstNode;
|
||||
|
||||
$circularDoublyLinkedList = $firstNode;
|
||||
|
||||
for ($i = 0; $i < 200000; $i++) {
|
||||
$currentNode = $circularDoublyLinkedList;
|
||||
$nextNode = $circularDoublyLinkedList->next;
|
||||
|
||||
$newNode = new Node();
|
||||
|
||||
$newNode->previous = $currentNode;
|
||||
$currentNode->next = $newNode;
|
||||
$newNode->next = $nextNode;
|
||||
$nextNode->previous = $newNode;
|
||||
|
||||
$circularDoublyLinkedList = $nextNode;
|
||||
}
|
||||
var_dump('end');
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
string(5) "start"
|
||||
string(3) "end"
|
||||
@@ -1,48 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
|
||||
--INI--
|
||||
zend.enable_gc = 1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Node
|
||||
{
|
||||
/** @var Node */
|
||||
public $previous;
|
||||
/** @var Node */
|
||||
public $next;
|
||||
}
|
||||
|
||||
var_dump(gc_enabled());
|
||||
var_dump('start');
|
||||
|
||||
function xxx() {
|
||||
$firstNode = new Node();
|
||||
$firstNode->previous = $firstNode;
|
||||
$firstNode->next = $firstNode;
|
||||
|
||||
$circularDoublyLinkedList = $firstNode;
|
||||
|
||||
for ($i = 0; $i < 300000; $i++) {
|
||||
$currentNode = $circularDoublyLinkedList;
|
||||
$nextNode = $circularDoublyLinkedList->next;
|
||||
|
||||
$newNode = new Node();
|
||||
|
||||
$newNode->previous = $currentNode;
|
||||
$currentNode->next = $newNode;
|
||||
$newNode->next = $nextNode;
|
||||
$nextNode->previous = $newNode;
|
||||
|
||||
$circularDoublyLinkedList = $nextNode;
|
||||
}
|
||||
}
|
||||
|
||||
xxx();
|
||||
gc_collect_cycles();
|
||||
|
||||
var_dump('end');
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
string(5) "start"
|
||||
string(3) "end"
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77376 ("undefined function" message no longer includes namespace)
|
||||
--FILE--
|
||||
<?php
|
||||
namespace Hello;
|
||||
World();
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to undefined function Hello\World() %sbug77376.php:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sbug77376.php on line %d
|
||||
@@ -1,16 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77494 (Disabling class causes segfault on member access)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?>
|
||||
--INI--
|
||||
disable_classes=CURLFile
|
||||
--FILE--
|
||||
<?php
|
||||
$a = new CURLFile();
|
||||
var_dump($a->name);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: CURLFile() has been disabled for security reasons in %sbug77494.php on line 2
|
||||
|
||||
Notice: Undefined property: CURLFile::$name in %sbug77494.php on line 3
|
||||
NULL
|
||||
@@ -1,10 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77530: PHP crashes when parsing '(2)::class'
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo (2)::class;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Illegal class name in %s on line %d
|
||||
@@ -1,40 +0,0 @@
|
||||
--TEST--
|
||||
BUG #77589 (Core dump using parse_ini_string with numeric sections)
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(
|
||||
parse_ini_string(<<<INI
|
||||
[0]
|
||||
a = 1
|
||||
b = on
|
||||
c = true
|
||||
|
||||
["true"]
|
||||
a = 100
|
||||
b = null
|
||||
c = yes
|
||||
INI
|
||||
, TRUE, INI_SCANNER_TYPED));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(3) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
bool(true)
|
||||
["c"]=>
|
||||
bool(true)
|
||||
}
|
||||
["true"]=>
|
||||
array(3) {
|
||||
["a"]=>
|
||||
int(100)
|
||||
["b"]=>
|
||||
NULL
|
||||
["c"]=>
|
||||
bool(true)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<?php
|
||||
return [
|
||||
'I' => function() {
|
||||
return new class implements I {};
|
||||
},
|
||||
];
|
||||
@@ -1,16 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77652: Anonymous classes can lose their interface information
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface I {}
|
||||
require __DIR__ . '/bug77652.inc';
|
||||
$data = require __DIR__ . '/bug77652.inc';
|
||||
print_r(class_implements($data['I']()));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[I] => I
|
||||
)
|
||||
@@ -1,10 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77660 (Segmentation fault on break 2147483648)
|
||||
--SKIPIF--
|
||||
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
for(;;) break 2147483648;
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot 'break' 2147483648 levels in %sbug77660.php on line %d
|
||||
@@ -1,8 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77738 (Nullptr deref in zend_compile_expr)
|
||||
--FILE--
|
||||
<?php
|
||||
__COMPILER_HALT_OFFSET__;
|
||||
; // <- important
|
||||
--EXPECTF--
|
||||
Warning: Use of undefined constant __COMPILER_HALT_OFFSET__ - assumed '__COMPILER_HALT_OFFSET__' %sbug77738.php on line %d
|
||||
@@ -1,7 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77993 (Wrong parse error for invalid hex literal on Windows)
|
||||
--FILE--
|
||||
<?php
|
||||
0xg10;
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected 'xg10' (T_STRING) in %s on line %d
|
||||
@@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
Calling exception getters when properties hold references
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyException extends Exception {
|
||||
public function __construct(&$refMsg, &$refCode, &$refFile, &$refLine) {
|
||||
$this->message =& $refMsg;
|
||||
$this->code =& $refCode;
|
||||
$this->file =& $refFile;
|
||||
$this->line =& $refLine;
|
||||
}
|
||||
}
|
||||
|
||||
$refMsg = "foo";
|
||||
$refCode = 0;
|
||||
$refFile = "foobar";
|
||||
$refLine = 42;
|
||||
$ex = new MyException($refMsg, $refCode, $refFile, $refLine);
|
||||
var_dump($ex->getMessage());
|
||||
var_dump($ex->getCode());
|
||||
var_dump($ex->getFile());
|
||||
var_dump($ex->getLine());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "foo"
|
||||
int(0)
|
||||
string(6) "foobar"
|
||||
int(42)
|
||||
@@ -1,18 +0,0 @@
|
||||
--TEST--
|
||||
Perform a packed to hash insert when the iterator is at the end of the array
|
||||
--FILE--
|
||||
|
||||
<?php
|
||||
$a = [];
|
||||
$a[1] = 1;
|
||||
foreach ($a as $k => &$v) {
|
||||
var_dump($v);
|
||||
if ($k == 1) $a[4] = 4;
|
||||
if ($k == 4) $a[2] = 2;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(4)
|
||||
int(2)
|
||||
@@ -1,18 +0,0 @@
|
||||
--TEST--
|
||||
Inherit internal static property into userland class
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip requires zend-test'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test extends _ZendTestClass {
|
||||
}
|
||||
|
||||
var_dump(Test::$_StaticProp);
|
||||
_ZendTestClass::$_StaticProp = 42;
|
||||
var_dump(Test::$_StaticProp);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
int(42)
|
||||
@@ -1,14 +0,0 @@
|
||||
--TEST--
|
||||
Bug object gc not working in shutdown
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set('memory_limit', '2M');
|
||||
register_shutdown_function(function () {
|
||||
for ($n = 1000 * 1000; $n--;) {
|
||||
new stdClass;
|
||||
}
|
||||
echo "OK\n";
|
||||
});
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Use of self::class inside a constant in an unknown scope
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public function foobar() {
|
||||
eval("
|
||||
const FOO = self::class;
|
||||
var_dump(FOO);
|
||||
");
|
||||
}
|
||||
}
|
||||
(new Test)->foobar();
|
||||
|
||||
// This should error, but doesn't
|
||||
const BAR = self::class;
|
||||
var_dump(BAR);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "Test"
|
||||
string(0) ""
|
||||
@@ -1,17 +0,0 @@
|
||||
--TEST--
|
||||
The parent class is not necessarily the class of the prototype
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
function test(): B {}
|
||||
}
|
||||
class B extends A {}
|
||||
class C extends B {
|
||||
function test(): parent {}
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
+16
-16
@@ -373,17 +373,17 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
|
||||
switch (Z_TYPE_P(expr)) {
|
||||
case IS_ARRAY:
|
||||
ZEND_PUTS("Array (");
|
||||
if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
|
||||
if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
|
||||
if (Z_REFCOUNTED_P(expr)) {
|
||||
if (Z_IS_RECURSIVE_P(expr)) {
|
||||
ZEND_PUTS(" *RECURSION*");
|
||||
return;
|
||||
}
|
||||
GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
|
||||
Z_PROTECT_RECURSION_P(expr);
|
||||
}
|
||||
print_flat_hash(Z_ARRVAL_P(expr));
|
||||
ZEND_PUTS(")");
|
||||
if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
|
||||
GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
|
||||
if (Z_REFCOUNTED_P(expr)) {
|
||||
Z_UNPROTECT_RECURSION_P(expr);
|
||||
}
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
@@ -393,7 +393,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
|
||||
zend_printf("%s Object (", ZSTR_VAL(class_name));
|
||||
zend_string_release_ex(class_name, 0);
|
||||
|
||||
if (GC_IS_RECURSIVE(Z_OBJ_P(expr))) {
|
||||
if (Z_IS_RECURSIVE_P(expr)) {
|
||||
ZEND_PUTS(" *RECURSION*");
|
||||
return;
|
||||
}
|
||||
@@ -402,9 +402,9 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
|
||||
properties = Z_OBJPROP_P(expr);
|
||||
}
|
||||
if (properties) {
|
||||
GC_PROTECT_RECURSION(Z_OBJ_P(expr));
|
||||
Z_PROTECT_RECURSION_P(expr);
|
||||
print_flat_hash(properties);
|
||||
GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
|
||||
Z_UNPROTECT_RECURSION_P(expr);
|
||||
}
|
||||
ZEND_PUTS(")");
|
||||
break;
|
||||
@@ -424,16 +424,16 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
|
||||
switch (Z_TYPE_P(expr)) {
|
||||
case IS_ARRAY:
|
||||
smart_str_appends(buf, "Array\n");
|
||||
if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
|
||||
if (GC_IS_RECURSIVE(Z_ARRVAL_P(expr))) {
|
||||
if (Z_REFCOUNTED_P(expr)) {
|
||||
if (Z_IS_RECURSIVE_P(expr)) {
|
||||
smart_str_appends(buf, " *RECURSION*");
|
||||
return;
|
||||
}
|
||||
GC_PROTECT_RECURSION(Z_ARRVAL_P(expr));
|
||||
Z_PROTECT_RECURSION_P(expr);
|
||||
}
|
||||
print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
|
||||
if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) {
|
||||
GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr));
|
||||
if (Z_REFCOUNTED_P(expr)) {
|
||||
Z_UNPROTECT_RECURSION_P(expr);
|
||||
}
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
@@ -446,7 +446,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
|
||||
zend_string_release_ex(class_name, 0);
|
||||
|
||||
smart_str_appends(buf, " Object\n");
|
||||
if (GC_IS_RECURSIVE(Z_OBJ_P(expr))) {
|
||||
if (Z_IS_RECURSIVE_P(expr)) {
|
||||
smart_str_appends(buf, " *RECURSION*");
|
||||
return;
|
||||
}
|
||||
@@ -454,9 +454,9 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
|
||||
break;
|
||||
}
|
||||
|
||||
GC_PROTECT_RECURSION(Z_OBJ_P(expr));
|
||||
Z_PROTECT_RECURSION_P(expr);
|
||||
print_hash(buf, properties, indent, 1);
|
||||
GC_UNPROTECT_RECURSION(Z_OBJ_P(expr));
|
||||
Z_UNPROTECT_RECURSION_P(expr);
|
||||
|
||||
if (is_temp) {
|
||||
zend_hash_destroy(properties);
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
#ifndef ZEND_H
|
||||
#define ZEND_H
|
||||
|
||||
#define ZEND_VERSION "3.3.7RC2"
|
||||
#define ZEND_VERSION "3.3.0-dev"
|
||||
|
||||
#define ZEND_ENGINE_3
|
||||
|
||||
|
||||
+13
-34
@@ -2051,13 +2051,13 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
|
||||
}
|
||||
|
||||
name_len = strlen(module->name);
|
||||
lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT);
|
||||
lcname = zend_string_alloc(name_len, 1);
|
||||
zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len);
|
||||
|
||||
lcname = zend_new_interned_string(lcname);
|
||||
if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
|
||||
zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
|
||||
zend_string_release(lcname);
|
||||
zend_string_release_ex(lcname, 1);
|
||||
return NULL;
|
||||
}
|
||||
module = module_ptr;
|
||||
@@ -2065,14 +2065,14 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
|
||||
|
||||
if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
|
||||
zend_hash_del(&module_registry, lcname);
|
||||
zend_string_release(lcname);
|
||||
zend_string_release_ex(lcname, 1);
|
||||
EG(current_module) = NULL;
|
||||
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EG(current_module) = NULL;
|
||||
zend_string_release(lcname);
|
||||
zend_string_release_ex(lcname, 1);
|
||||
return module;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -2279,14 +2279,14 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
lowercase_name = zend_string_tolower_ex(internal_function->function_name, type == MODULE_PERSISTENT);
|
||||
lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
reg_function = malloc(sizeof(zend_internal_function));
|
||||
memcpy(reg_function, &function, sizeof(zend_internal_function));
|
||||
if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) {
|
||||
unload=1;
|
||||
free(reg_function);
|
||||
zend_string_release(lowercase_name);
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2378,7 +2378,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
|
||||
}
|
||||
ptr++;
|
||||
count++;
|
||||
zend_string_release(lowercase_name);
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
}
|
||||
if (unload) { /* before unloading, display all remaining bad function in the module */
|
||||
if (scope) {
|
||||
@@ -2724,10 +2724,10 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
|
||||
class_entry->info.internal.module = EG(current_module);
|
||||
|
||||
if (class_entry->info.internal.builtin_functions) {
|
||||
zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, EG(current_module)->type);
|
||||
zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
|
||||
}
|
||||
|
||||
lowercase_name = zend_string_tolower_ex(orig_class_entry->name, EG(current_module)->type == MODULE_PERSISTENT);
|
||||
lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry);
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
@@ -2786,11 +2786,6 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
|
||||
{
|
||||
zend_string *lcname;
|
||||
|
||||
/* TODO: Move this out of here in 7.4. */
|
||||
if (persistent && EG(current_module) && EG(current_module)->type == MODULE_TEMPORARY) {
|
||||
persistent = 0;
|
||||
}
|
||||
|
||||
if (name[0] == '\\') {
|
||||
lcname = zend_string_alloc(name_len-1, persistent);
|
||||
zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1);
|
||||
@@ -2848,7 +2843,7 @@ ZEND_API int zend_disable_function(char *function_name, size_t function_name_len
|
||||
{
|
||||
zend_internal_function *func;
|
||||
if ((func = zend_hash_str_find_ptr(CG(function_table), function_name, function_name_length))) {
|
||||
func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_RETURN_TYPE);
|
||||
func->fn_flags &= ~(ZEND_ACC_VARIADIC | ZEND_ACC_HAS_TYPE_HINTS);
|
||||
func->num_args = 0;
|
||||
func->arg_info = NULL;
|
||||
func->handler = ZEND_FN(display_disabled_function);
|
||||
@@ -2866,17 +2861,6 @@ static zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{
|
||||
zend_object *intern;
|
||||
|
||||
intern = zend_objects_new(class_type);
|
||||
|
||||
/* Initialize default properties */
|
||||
if (EXPECTED(class_type->default_properties_count != 0)) {
|
||||
zval *p = intern->properties_table;
|
||||
zval *end = p + class_type->default_properties_count;
|
||||
do {
|
||||
ZVAL_UNDEF(p);
|
||||
p++;
|
||||
} while (p != end);
|
||||
}
|
||||
|
||||
zend_error(E_WARNING, "%s() has been disabled for security reasons", ZSTR_VAL(class_type->name));
|
||||
return intern;
|
||||
}
|
||||
@@ -3701,11 +3685,6 @@ static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */
|
||||
return Z_STR_P(zv);
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool is_persistent_class(zend_class_entry *ce) {
|
||||
return (ce->type & ZEND_INTERNAL_CLASS)
|
||||
&& ce->info.internal.module->type == MODULE_PERSISTENT;
|
||||
}
|
||||
|
||||
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
|
||||
{
|
||||
zend_property_info *property_info, *property_info_ptr;
|
||||
@@ -3771,10 +3750,10 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
if (access_type & ZEND_ACC_PUBLIC) {
|
||||
property_info->name = zend_string_copy(name);
|
||||
} else if (access_type & ZEND_ACC_PRIVATE) {
|
||||
property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce));
|
||||
property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
|
||||
} else {
|
||||
ZEND_ASSERT(access_type & ZEND_ACC_PROTECTED);
|
||||
property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce));
|
||||
property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
|
||||
}
|
||||
|
||||
property_info->name = zend_new_interned_string(property_info->name);
|
||||
@@ -3789,7 +3768,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
|
||||
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */
|
||||
{
|
||||
zend_string *key = zend_string_init(name, name_length, is_persistent_class(ce));
|
||||
zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
|
||||
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
|
||||
zend_string_release(key);
|
||||
return ret;
|
||||
|
||||
+8
-7
@@ -191,7 +191,9 @@ typedef struct _zend_mm_free_slot zend_mm_free_slot;
|
||||
typedef struct _zend_mm_chunk zend_mm_chunk;
|
||||
typedef struct _zend_mm_huge_list zend_mm_huge_list;
|
||||
|
||||
#ifdef MAP_HUGETLB
|
||||
int zend_mm_use_huge_pages = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory is retrived from OS by chunks of fixed size 2MB.
|
||||
@@ -712,9 +714,7 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
|
||||
return NULL;
|
||||
} else if (ZEND_MM_ALIGNED_OFFSET(ptr, alignment) == 0) {
|
||||
#ifdef MADV_HUGEPAGE
|
||||
if (zend_mm_use_huge_pages) {
|
||||
madvise(ptr, size, MADV_HUGEPAGE);
|
||||
}
|
||||
madvise(ptr, size, MADV_HUGEPAGE);
|
||||
#endif
|
||||
return ptr;
|
||||
} else {
|
||||
@@ -745,9 +745,7 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
|
||||
zend_mm_munmap((char*)ptr + size, alignment - REAL_PAGE_SIZE);
|
||||
}
|
||||
# ifdef MADV_HUGEPAGE
|
||||
if (zend_mm_use_huge_pages) {
|
||||
madvise(ptr, size, MADV_HUGEPAGE);
|
||||
}
|
||||
madvise(ptr, size, MADV_HUGEPAGE);
|
||||
# endif
|
||||
#endif
|
||||
return ptr;
|
||||
@@ -2670,7 +2668,9 @@ ZEND_API void shutdown_memory_manager(int silent, int full_shutdown)
|
||||
|
||||
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
|
||||
{
|
||||
#if ZEND_MM_CUSTOM || MAP_HUGETLB
|
||||
char *tmp;
|
||||
#endif
|
||||
|
||||
#if ZEND_MM_CUSTOM
|
||||
tmp = getenv("USE_ZEND_ALLOC");
|
||||
@@ -2684,11 +2684,12 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAP_HUGETLB
|
||||
tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES");
|
||||
if (tmp && zend_atoi(tmp, 0)) {
|
||||
zend_mm_use_huge_pages = 1;
|
||||
}
|
||||
#endif
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
alloc_globals->mm_heap = zend_mm_init();
|
||||
}
|
||||
|
||||
@@ -110,17 +110,6 @@ static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *
|
||||
arena->ptr = (char*)checkpoint;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool zend_arena_contains(zend_arena *arena, void *ptr)
|
||||
{
|
||||
while (arena) {
|
||||
if ((char*)ptr > (char*)arena && (char*)ptr <= arena->ptr) {
|
||||
return 1;
|
||||
}
|
||||
arena = arena->prev;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _ZEND_ARENA_H_ */
|
||||
|
||||
/*
|
||||
|
||||
+23
-76
@@ -480,12 +480,10 @@ static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */
|
||||
/* Common part of zend_add_literal and zend_append_individual_literal */
|
||||
static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
|
||||
{
|
||||
zval *lit = CT_CONSTANT_EX(op_array, literal_position);
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
zval_make_interned_string(zv);
|
||||
}
|
||||
ZVAL_COPY_VALUE(lit, zv);
|
||||
Z_EXTRA_P(lit) = 0;
|
||||
ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1480,7 +1478,6 @@ static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
|
||||
static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast, zend_ast *name_ast, zend_bool constant) /* {{{ */
|
||||
{
|
||||
uint32_t fetch_type;
|
||||
zval *class_name;
|
||||
|
||||
if (name_ast->kind != ZEND_AST_ZVAL) {
|
||||
return 0;
|
||||
@@ -1495,18 +1492,12 @@ static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_a
|
||||
"Dynamic class names are not allowed in compile-time ::class fetch");
|
||||
}
|
||||
|
||||
class_name = zend_ast_get_zval(class_ast);
|
||||
|
||||
if (Z_TYPE_P(class_name) != IS_STRING) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
|
||||
}
|
||||
|
||||
fetch_type = zend_get_class_fetch_type(Z_STR_P(class_name));
|
||||
fetch_type = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
|
||||
zend_ensure_valid_class_fetch_type(fetch_type);
|
||||
|
||||
switch (fetch_type) {
|
||||
case ZEND_FETCH_CLASS_SELF:
|
||||
if (CG(active_class_entry) && zend_is_scope_known()) {
|
||||
if (constant || (CG(active_class_entry) && zend_is_scope_known())) {
|
||||
ZVAL_STR_COPY(zv, CG(active_class_entry)->name);
|
||||
} else {
|
||||
ZVAL_NULL(zv);
|
||||
@@ -2453,6 +2444,7 @@ static inline void zend_handle_numeric_dim(zend_op *opline, znode *dim_node) /*
|
||||
return;
|
||||
}
|
||||
}
|
||||
Z_EXTRA_P(CT_CONSTANT(opline->op2)) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3658,7 +3650,7 @@ int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcnam
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc) /* {{{ */
|
||||
static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc) /* {{{ */
|
||||
{
|
||||
if (EG(assertions) >= 0) {
|
||||
znode name_node;
|
||||
@@ -3701,6 +3693,8 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_TRUE(&result->u.constant);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3907,6 +3901,10 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (zend_string_equals_literal(lcname, "assert")) {
|
||||
return zend_compile_assert(result, args, lcname, fbc);
|
||||
}
|
||||
|
||||
if (CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS) {
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -4009,16 +4007,8 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
|
||||
zend_op *opline;
|
||||
|
||||
lcname = zend_string_tolower(Z_STR_P(name));
|
||||
|
||||
fbc = zend_hash_find_ptr(CG(function_table), lcname);
|
||||
|
||||
/* Special assert() handling should apply independently of compiler flags. */
|
||||
if (fbc && zend_string_equals_literal(lcname, "assert")) {
|
||||
zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc);
|
||||
zend_string_release(lcname);
|
||||
zval_ptr_dtor(&name_node.u.constant);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fbc
|
||||
|| (fbc->type == ZEND_INTERNAL_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
|
||||
|| (fbc->type == ZEND_USER_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS))
|
||||
@@ -4162,14 +4152,6 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{
|
||||
if (ce) {
|
||||
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
|
||||
fbc = zend_hash_find_ptr(&ce->function_table, lcname);
|
||||
if (fbc && !(fbc->common.fn_flags & ZEND_ACC_PUBLIC)) {
|
||||
if (ce != CG(active_class_entry)
|
||||
&&((fbc->common.fn_flags & ZEND_ACC_PRIVATE)
|
||||
|| !zend_check_protected(zend_get_function_root_class(fbc), CG(active_class_entry)))) {
|
||||
/* incompatibe function */
|
||||
fbc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4528,7 +4510,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
zend_ast *depth_ast = ast->child[0];
|
||||
|
||||
zend_op *opline;
|
||||
zend_long depth;
|
||||
int depth;
|
||||
|
||||
ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
|
||||
|
||||
@@ -4555,7 +4537,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
|
||||
} else {
|
||||
if (!zend_handle_loops_and_finally_ex(depth, NULL)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' " ZEND_LONG_FMT " level%s",
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s",
|
||||
ast->kind == ZEND_AST_BREAK ? "break" : "continue",
|
||||
depth, depth == 1 ? "" : "s");
|
||||
}
|
||||
@@ -4572,12 +4554,12 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
if (depth == 1) {
|
||||
zend_error(E_WARNING,
|
||||
"\"continue\" targeting switch is equivalent to \"break\". " \
|
||||
"Did you mean to use \"continue " ZEND_LONG_FMT "\"?",
|
||||
"Did you mean to use \"continue %d\"?",
|
||||
depth + 1);
|
||||
} else {
|
||||
zend_error(E_WARNING,
|
||||
"\"continue " ZEND_LONG_FMT "\" targeting switch is equivalent to \"break " ZEND_LONG_FMT "\". " \
|
||||
"Did you mean to use \"continue " ZEND_LONG_FMT "\"?",
|
||||
"\"continue %d\" targeting switch is equivalent to \"break %d\". " \
|
||||
"Did you mean to use \"continue %d\"?",
|
||||
depth, depth, depth + 1);
|
||||
}
|
||||
}
|
||||
@@ -4863,10 +4845,6 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
|
||||
|
||||
zend_compile_stmt(stmt_ast);
|
||||
|
||||
/* Place JMP and FE_FREE on the line where foreach starts. It would be
|
||||
* better to use the end line, but this information is not available
|
||||
* currently. */
|
||||
CG(zend_lineno) = ast->lineno;
|
||||
zend_emit_jump(opnum_fetch);
|
||||
|
||||
opline = &CG(active_op_array)->opcodes[opnum_reset];
|
||||
@@ -4965,10 +4943,6 @@ static zend_uchar determine_switch_jumptable_type(zend_ast_list *cases) {
|
||||
}
|
||||
|
||||
static zend_bool should_use_jumptable(zend_ast_list *cases, zend_uchar jumptable_type) {
|
||||
if (CG(compiler_options) & ZEND_COMPILE_NO_JUMPTABLES) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Thresholds are chosen based on when the average switch time for equidistributed
|
||||
* input becomes smaller when using the jumptable optimization. */
|
||||
if (jumptable_type == IS_LONG) {
|
||||
@@ -6440,32 +6414,10 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
|
||||
if (!zend_hash_exists(CG(class_table), lcname)) {
|
||||
zend_hash_add_ptr(CG(class_table), lcname, ce);
|
||||
} else {
|
||||
/* This anonymous class has been included, reuse the existing definition.
|
||||
* NB: This behavior is buggy, and this should always result in a separate
|
||||
* class declaration. However, until the problem of RTD key collisions is
|
||||
* solved, this gives a behavior close to what is expected. */
|
||||
/* this anonymous class has been included */
|
||||
zval zv;
|
||||
ZVAL_PTR(&zv, ce);
|
||||
destroy_zend_class(&zv);
|
||||
ce = zend_hash_find_ptr(CG(class_table), lcname);
|
||||
|
||||
/* Manually replicate emission of necessary inheritance opcodes here. We cannot
|
||||
* reuse the general code, as we only want to emit the opcodes, without modifying
|
||||
* the reused class definition. */
|
||||
if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
|
||||
zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL);
|
||||
}
|
||||
if (implements_ast) {
|
||||
zend_ast_list *iface_list = zend_ast_get_list(implements_ast);
|
||||
uint32_t i;
|
||||
for (i = 0; i < iface_list->children; i++) {
|
||||
opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, &declare_node, NULL);
|
||||
opline->op2_type = IS_CONST;
|
||||
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
|
||||
zend_resolve_class_name_ast(iface_list->child[i]));
|
||||
}
|
||||
zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -7030,7 +6982,6 @@ static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval *
|
||||
static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
|
||||
{
|
||||
zend_ast_list *list = zend_ast_get_list(ast);
|
||||
zend_ast *last_elem_ast = NULL;
|
||||
uint32_t i;
|
||||
zend_bool is_constant = 1;
|
||||
|
||||
@@ -7043,10 +6994,6 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
|
||||
zend_ast *elem_ast = list->child[i];
|
||||
|
||||
if (elem_ast == NULL) {
|
||||
/* Report error at line of last non-empty element */
|
||||
if (last_elem_ast) {
|
||||
CG(zend_lineno) = zend_ast_get_lineno(last_elem_ast);
|
||||
}
|
||||
zend_error(E_COMPILE_ERROR, "Cannot use empty array elements in arrays");
|
||||
}
|
||||
|
||||
@@ -7058,8 +7005,6 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
|
||||
) {
|
||||
is_constant = 0;
|
||||
}
|
||||
|
||||
last_elem_ast = elem_ast;
|
||||
}
|
||||
|
||||
if (!is_constant) {
|
||||
@@ -7761,11 +7706,11 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
|
||||
if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__") || (name_ast->attr != ZEND_NAME_RELATIVE && zend_string_equals_literal(orig_name, "__COMPILER_HALT_OFFSET__"))) {
|
||||
zend_ast *last = CG(ast);
|
||||
|
||||
while (last && last->kind == ZEND_AST_STMT_LIST) {
|
||||
while (last->kind == ZEND_AST_STMT_LIST) {
|
||||
zend_ast_list *list = zend_ast_get_list(last);
|
||||
last = list->child[list->children-1];
|
||||
}
|
||||
if (last && last->kind == ZEND_AST_HALT_COMPILER) {
|
||||
if (last->kind == ZEND_AST_HALT_COMPILER) {
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_LONG(&result->u.constant, Z_LVAL_P(zend_ast_get_zval(last->child[0])));
|
||||
zend_string_release_ex(resolved_name, 0);
|
||||
@@ -8121,7 +8066,9 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
|
||||
zend_ast *ast = *ast_ptr;
|
||||
|
||||
/* Other cases already resolved by constant folding */
|
||||
ZEND_ASSERT(ast->attr == T_CLASS_C);
|
||||
ZEND_ASSERT(ast->attr == T_CLASS_C &&
|
||||
CG(active_class_entry) &&
|
||||
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
|
||||
|
||||
zend_ast_destroy(ast);
|
||||
*ast_ptr = zend_ast_create(ZEND_AST_CONSTANT_CLASS);
|
||||
|
||||
@@ -1048,9 +1048,6 @@ END_EXTERN_C()
|
||||
/* result of compilation may be stored in file cache */
|
||||
#define ZEND_COMPILE_WITH_FILE_CACHE (1<<11)
|
||||
|
||||
/* disable jumptable optimization for switch statements */
|
||||
#define ZEND_COMPILE_NO_JUMPTABLES (1<<12)
|
||||
|
||||
/* The default value for CG(compiler_options) */
|
||||
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
|
||||
|
||||
|
||||
@@ -378,9 +378,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
|
||||
ret_constant = NULL;
|
||||
} else {
|
||||
if (!zend_verify_const_access(c, scope)) {
|
||||
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
|
||||
zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
|
||||
}
|
||||
zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
|
||||
goto failure;
|
||||
}
|
||||
ret_constant = &c->value;
|
||||
|
||||
+3
-23
@@ -36,23 +36,11 @@ static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo
|
||||
}
|
||||
# else
|
||||
static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) {
|
||||
#if defined(__i386__) && (defined(__pic__) || defined(__PIC__))
|
||||
/* PIC on i386 uses %ebx, so preserve it. */
|
||||
__asm__ __volatile__ (
|
||||
"pushl %%ebx\n"
|
||||
"cpuid\n"
|
||||
"mov %%ebx,%1\n"
|
||||
"popl %%ebx"
|
||||
: "=a"(cpuinfo->eax), "=r"(cpuinfo->ebx), "=c"(cpuinfo->ecx), "=d"(cpuinfo->edx)
|
||||
: "a"(func), "c"(subfunc)
|
||||
);
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a"(cpuinfo->eax), "=b"(cpuinfo->ebx), "=c"(cpuinfo->ecx), "=d"(cpuinfo->edx)
|
||||
: "a"(func), "c"(subfunc)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
# endif
|
||||
#elif defined(ZEND_WIN32) && !defined(__clang__)
|
||||
@@ -77,24 +65,16 @@ void zend_cpu_startup(void)
|
||||
{
|
||||
if (!cpuinfo.initialized) {
|
||||
zend_cpu_info ebx;
|
||||
int max_feature;
|
||||
|
||||
cpuinfo.initialized = 1;
|
||||
__zend_cpuid(0, 0, &cpuinfo);
|
||||
max_feature = cpuinfo.eax;
|
||||
if (max_feature == 0) {
|
||||
if (cpuinfo.eax == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
__zend_cpuid(1, 0, &cpuinfo);
|
||||
|
||||
/* for avx2 */
|
||||
if (max_feature >= 7) {
|
||||
__zend_cpuid(7, 0, &ebx);
|
||||
cpuinfo.ebx = ebx.ebx;
|
||||
} else {
|
||||
cpuinfo.ebx = 0;
|
||||
}
|
||||
__zend_cpuid(7, 0, &ebx);
|
||||
cpuinfo.ebx = ebx.ebx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,22 +100,12 @@ typedef enum _zend_cpu_feature {
|
||||
void zend_cpu_startup();
|
||||
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
|
||||
|
||||
/* Address sanitizer is incompatible with ifunc resolvers, so exclude the
|
||||
* CPU support helpers from asan.
|
||||
* See also https://github.com/google/sanitizers/issues/342. */
|
||||
#if __has_attribute(no_sanitize_address)
|
||||
# define ZEND_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
|
||||
#else
|
||||
# define ZEND_NO_SANITIZE_ADDRESS
|
||||
#endif
|
||||
|
||||
#if PHP_HAVE_BUILTIN_CPU_SUPPORTS
|
||||
/* NOTE: you should use following inline function in
|
||||
* resolver functions (ifunc), as it could be called
|
||||
* before all PLT symbols are resloved. in other words,
|
||||
* resolver functions should not depends any external
|
||||
* functions */
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_sse2() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -123,7 +113,6 @@ static zend_always_inline int zend_cpu_supports_sse2() {
|
||||
return __builtin_cpu_supports("sse2");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_sse3() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -131,7 +120,6 @@ static zend_always_inline int zend_cpu_supports_sse3() {
|
||||
return __builtin_cpu_supports("sse3");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_ssse3() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -139,7 +127,6 @@ static zend_always_inline int zend_cpu_supports_ssse3() {
|
||||
return __builtin_cpu_supports("ssse3");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_sse41() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -147,7 +134,6 @@ static zend_always_inline int zend_cpu_supports_sse41() {
|
||||
return __builtin_cpu_supports("sse4.1");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_sse42() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -155,7 +141,6 @@ static zend_always_inline int zend_cpu_supports_sse42() {
|
||||
return __builtin_cpu_supports("sse4.2");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_avx() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
@@ -163,7 +148,6 @@ static zend_always_inline int zend_cpu_supports_avx() {
|
||||
return __builtin_cpu_supports("avx");
|
||||
}
|
||||
|
||||
ZEND_NO_SANITIZE_ADDRESS
|
||||
static zend_always_inline int zend_cpu_supports_avx2() {
|
||||
#if PHP_HAVE_BUILTIN_CPU_INIT
|
||||
__builtin_cpu_init();
|
||||
|
||||
+12
-24
@@ -400,13 +400,11 @@ ZEND_METHOD(error_exception, __construct)
|
||||
Get the file in which the exception occurred */
|
||||
ZEND_METHOD(exception, getFile)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_FILE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_FILE));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -414,13 +412,11 @@ ZEND_METHOD(exception, getFile)
|
||||
Get the line in which the exception occurred */
|
||||
ZEND_METHOD(exception, getLine)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_LINE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_LINE));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -428,13 +424,11 @@ ZEND_METHOD(exception, getLine)
|
||||
Get the exception message */
|
||||
ZEND_METHOD(exception, getMessage)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_MESSAGE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_MESSAGE));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -442,13 +436,11 @@ ZEND_METHOD(exception, getMessage)
|
||||
Get the exception code */
|
||||
ZEND_METHOD(exception, getCode)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_CODE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_CODE));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -456,13 +448,11 @@ ZEND_METHOD(exception, getCode)
|
||||
Get the stack trace for the location in which the exception occurred */
|
||||
ZEND_METHOD(exception, getTrace)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_TRACE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_TRACE));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -470,13 +460,11 @@ ZEND_METHOD(exception, getTrace)
|
||||
Get the exception severity */
|
||||
ZEND_METHOD(error_exception, getSeverity)
|
||||
{
|
||||
zval *prop, rv;
|
||||
zval rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_SEVERITY);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_SEVERITY));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+3
-13
@@ -170,9 +170,9 @@ ZEND_API const zend_internal_function zend_pass_function = {
|
||||
|
||||
#define ZEND_VM_STACK_PAGE_SIZE (ZEND_VM_STACK_PAGE_SLOTS * sizeof(zval))
|
||||
|
||||
#define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size, page_size) \
|
||||
#define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size) \
|
||||
(((size) + ZEND_VM_STACK_HEADER_SLOTS * sizeof(zval) \
|
||||
+ ((page_size) - 1)) & ~((page_size) - 1))
|
||||
+ (ZEND_VM_STACK_PAGE_SIZE - 1)) & ~(ZEND_VM_STACK_PAGE_SIZE - 1))
|
||||
|
||||
static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) {
|
||||
zend_vm_stack page = (zend_vm_stack)emalloc(size);
|
||||
@@ -192,16 +192,6 @@ ZEND_API void zend_vm_stack_init(void)
|
||||
EG(vm_stack_end) = EG(vm_stack)->end;
|
||||
}
|
||||
|
||||
ZEND_API void zend_vm_stack_init_ex(size_t page_size)
|
||||
{
|
||||
/* page_size must be a power of 2 */
|
||||
ZEND_ASSERT(page_size > 0 && (page_size & (page_size - 1)) == 0);
|
||||
EG(vm_stack_page_size) = page_size;
|
||||
EG(vm_stack) = zend_vm_stack_new_page(page_size, NULL);
|
||||
EG(vm_stack_top) = EG(vm_stack)->top;
|
||||
EG(vm_stack_end) = EG(vm_stack)->end;
|
||||
}
|
||||
|
||||
ZEND_API void zend_vm_stack_destroy(void)
|
||||
{
|
||||
zend_vm_stack stack = EG(vm_stack);
|
||||
@@ -222,7 +212,7 @@ ZEND_API void* zend_vm_stack_extend(size_t size)
|
||||
stack->top = EG(vm_stack_top);
|
||||
EG(vm_stack) = stack = zend_vm_stack_new_page(
|
||||
EXPECTED(size < EG(vm_stack_page_size) - (ZEND_VM_STACK_HEADER_SLOTS * sizeof(zval))) ?
|
||||
EG(vm_stack_page_size) : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size, EG(vm_stack_page_size)),
|
||||
EG(vm_stack_page_size) : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size),
|
||||
stack);
|
||||
ptr = stack->top;
|
||||
EG(vm_stack_top) = (void*)(((char*)ptr) + size);
|
||||
|
||||
@@ -168,7 +168,6 @@ struct _zend_vm_stack {
|
||||
#endif
|
||||
|
||||
ZEND_API void zend_vm_stack_init(void);
|
||||
ZEND_API void zend_vm_stack_init_ex(size_t page_size);
|
||||
ZEND_API void zend_vm_stack_destroy(void);
|
||||
ZEND_API void* zend_vm_stack_extend(size_t size);
|
||||
|
||||
|
||||
+7
-21
@@ -1359,28 +1359,14 @@ zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *
|
||||
if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
|
||||
return zend_lookup_class_ex(class_name, key, 0);
|
||||
} else if ((ce = zend_lookup_class_ex(class_name, key, 1)) == NULL) {
|
||||
if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
|
||||
return NULL;
|
||||
}
|
||||
if (EG(exception)) {
|
||||
if (!(fetch_type & ZEND_FETCH_CLASS_EXCEPTION)) {
|
||||
zend_string *exception_str;
|
||||
zval exception_zv;
|
||||
ZVAL_OBJ(&exception_zv, EG(exception));
|
||||
Z_ADDREF(exception_zv);
|
||||
zend_clear_exception();
|
||||
exception_str = zval_get_string(&exception_zv);
|
||||
zend_error_noreturn(E_ERROR,
|
||||
"During class fetch: Uncaught %s", ZSTR_VAL(exception_str));
|
||||
if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) {
|
||||
if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
|
||||
zend_throw_or_error(fetch_type, NULL, "Interface '%s' not found", ZSTR_VAL(class_name));
|
||||
} else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
|
||||
zend_throw_or_error(fetch_type, NULL, "Trait '%s' not found", ZSTR_VAL(class_name));
|
||||
} else {
|
||||
zend_throw_or_error(fetch_type, NULL, "Class '%s' not found", ZSTR_VAL(class_name));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
|
||||
zend_throw_or_error(fetch_type, NULL, "Interface '%s' not found", ZSTR_VAL(class_name));
|
||||
} else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
|
||||
zend_throw_or_error(fetch_type, NULL, "Trait '%s' not found", ZSTR_VAL(class_name));
|
||||
} else {
|
||||
zend_throw_or_error(fetch_type, NULL, "Class '%s' not found", ZSTR_VAL(class_name));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+89
-241
@@ -48,7 +48,7 @@
|
||||
* gc_scan_roots will be called, and each root will be called with
|
||||
* gc_scan(root->ref)
|
||||
*
|
||||
* gc_scan checks the colors of possible members.
|
||||
* gc_scan checkes the colors of possible members.
|
||||
*
|
||||
* If the node is marked as grey and the refcount > 0
|
||||
* gc_scan_black will be called on that node to scan it's subgraph.
|
||||
@@ -245,73 +245,6 @@ static zend_gc_globals gc_globals;
|
||||
# define GC_TRACE(str)
|
||||
#endif
|
||||
|
||||
|
||||
#define GC_STACK_SEGMENT_SIZE (((4096 - ZEND_MM_OVERHEAD) / sizeof(void*)) - 2)
|
||||
|
||||
typedef struct _gc_stack gc_stack;
|
||||
|
||||
struct _gc_stack {
|
||||
gc_stack *prev;
|
||||
gc_stack *next;
|
||||
zend_refcounted *data[GC_STACK_SEGMENT_SIZE];
|
||||
};
|
||||
|
||||
#define GC_STACK_DCL(init) \
|
||||
gc_stack *_stack = init; \
|
||||
size_t _top = 0;
|
||||
|
||||
#define GC_STACK_PUSH(ref) \
|
||||
gc_stack_push(&_stack, &_top, ref);
|
||||
|
||||
#define GC_STACK_POP() \
|
||||
gc_stack_pop(&_stack, &_top)
|
||||
|
||||
static zend_never_inline gc_stack* gc_stack_next(gc_stack *stack)
|
||||
{
|
||||
if (UNEXPECTED(!stack->next)) {
|
||||
gc_stack *segment = emalloc(sizeof(gc_stack));
|
||||
segment->prev = stack;
|
||||
segment->next = NULL;
|
||||
stack->next = segment;
|
||||
}
|
||||
return stack->next;
|
||||
}
|
||||
|
||||
static zend_always_inline void gc_stack_push(gc_stack **stack, size_t *top, zend_refcounted *ref)
|
||||
{
|
||||
if (UNEXPECTED(*top == GC_STACK_SEGMENT_SIZE)) {
|
||||
(*stack) = gc_stack_next(*stack);
|
||||
(*top) = 0;
|
||||
}
|
||||
(*stack)->data[(*top)++] = ref;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_refcounted* gc_stack_pop(gc_stack **stack, size_t *top)
|
||||
{
|
||||
if (UNEXPECTED((*top) == 0)) {
|
||||
if (!(*stack)->prev) {
|
||||
return NULL;
|
||||
} else {
|
||||
(*stack) = (*stack)->prev;
|
||||
(*top) = GC_STACK_SEGMENT_SIZE - 1;
|
||||
return (*stack)->data[GC_STACK_SEGMENT_SIZE - 1];
|
||||
}
|
||||
} else {
|
||||
return (*stack)->data[--(*top)];
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_stack_free(gc_stack *stack)
|
||||
{
|
||||
gc_stack *p = stack->next;
|
||||
|
||||
while (p) {
|
||||
stack = p->next;
|
||||
efree(p);
|
||||
p = stack;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t gc_compress(uint32_t idx)
|
||||
{
|
||||
return idx % GC_MAX_UNCOMPRESSED;
|
||||
@@ -673,14 +606,16 @@ ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref)
|
||||
gc_remove_from_roots(root);
|
||||
}
|
||||
|
||||
static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
|
||||
static void gc_scan_black(zend_refcounted *ref)
|
||||
{
|
||||
HashTable *ht = NULL;
|
||||
HashTable *ht;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
ht = NULL;
|
||||
GC_REF_SET_BLACK(ref);
|
||||
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
@@ -695,9 +630,9 @@ tail_call:
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) goto next;
|
||||
if (!n) return;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) goto next;
|
||||
if (zv == end) return;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
@@ -705,8 +640,7 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
gc_scan_black(ref);
|
||||
}
|
||||
}
|
||||
zv++;
|
||||
@@ -715,35 +649,33 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if ((zend_array*)ref != &EG(symbol_table)) {
|
||||
ht = (zend_array*)ref;
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
goto next;
|
||||
return;
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) goto next;
|
||||
if (!ht->nNumUsed) return;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -755,7 +687,7 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) goto next;
|
||||
if (p == end) return;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -766,8 +698,7 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
gc_scan_black(ref);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
@@ -779,33 +710,28 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
if (ref) {
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
static void gc_mark_grey(zend_refcounted *ref)
|
||||
{
|
||||
HashTable *ht = NULL;
|
||||
HashTable *ht;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
do {
|
||||
tail_call:
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
ht = NULL;
|
||||
GC_BENCH_INC(zval_marked_grey);
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -814,38 +740,31 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) goto next;
|
||||
if (!n) return;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) goto next;
|
||||
if (zv == end) return;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
gc_mark_grey(ref);
|
||||
}
|
||||
zv++;
|
||||
}
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
goto next;
|
||||
goto tail_call;
|
||||
}
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if (((zend_array*)ref) == &EG(symbol_table)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto next;
|
||||
return;
|
||||
} else {
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
@@ -853,17 +772,14 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
return;
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) goto next;
|
||||
if (!ht->nNumUsed) return;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -875,7 +791,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) goto next;
|
||||
if (p == end) return;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -885,10 +801,7 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
gc_mark_grey(ref);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@@ -898,14 +811,8 @@ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
} while (ref);
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
/* Two-Finger compaction algorithm */
|
||||
@@ -945,7 +852,7 @@ static void gc_compact(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_roots(gc_stack *stack)
|
||||
static void gc_mark_roots(void)
|
||||
{
|
||||
gc_root_buffer *current, *last;
|
||||
|
||||
@@ -956,41 +863,31 @@ static void gc_mark_roots(gc_stack *stack)
|
||||
while (current != last) {
|
||||
if (GC_IS_ROOT(current->ref)) {
|
||||
if (GC_REF_CHECK_COLOR(current->ref, GC_PURPLE)) {
|
||||
GC_REF_SET_COLOR(current->ref, GC_GREY);
|
||||
gc_mark_grey(current->ref, stack);
|
||||
gc_mark_grey(current->ref);
|
||||
}
|
||||
}
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_scan(zend_refcounted *ref, gc_stack *stack)
|
||||
static void gc_scan(zend_refcounted *ref)
|
||||
{
|
||||
HashTable *ht = NULL;
|
||||
HashTable *ht;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
if (GC_REFCOUNT(ref) > 0) {
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
if (UNEXPECTED(!_stack->next)) {
|
||||
gc_stack_next(_stack);
|
||||
}
|
||||
/* Split stack and reuse the tail */
|
||||
_stack->next->prev = NULL;
|
||||
gc_scan_black(ref, _stack->next);
|
||||
_stack->next->prev = _stack;
|
||||
}
|
||||
gc_scan_black(ref);
|
||||
} else {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -999,53 +896,43 @@ tail_call:
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) goto next;
|
||||
if (!n) return;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) goto next;
|
||||
if (zv == end) return;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
gc_scan(ref);
|
||||
}
|
||||
zv++;
|
||||
}
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
goto tail_call;
|
||||
}
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if ((zend_array*)ref == &EG(symbol_table)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto next;
|
||||
return;
|
||||
} else {
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
return;
|
||||
} else {
|
||||
goto next;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) goto next;
|
||||
if (!ht->nNumUsed) return;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -1057,7 +944,7 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) goto next;
|
||||
if (p == end) return;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -1066,10 +953,7 @@ tail_call:
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
gc_scan(ref);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@@ -1078,31 +962,19 @@ tail_call:
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
if (ref) {
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_scan_roots(gc_stack *stack)
|
||||
static void gc_scan_roots(void)
|
||||
{
|
||||
gc_root_buffer *current = GC_IDX2PTR(GC_FIRST_ROOT);
|
||||
gc_root_buffer *last = GC_IDX2PTR(GC_G(first_unused));
|
||||
|
||||
while (current != last) {
|
||||
if (GC_IS_ROOT(current->ref)) {
|
||||
if (GC_REF_CHECK_COLOR(current->ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(current->ref, GC_WHITE);
|
||||
gc_scan(current->ref, stack);
|
||||
}
|
||||
gc_scan(current->ref);
|
||||
}
|
||||
current++;
|
||||
}
|
||||
@@ -1133,15 +1005,18 @@ static void gc_add_garbage(zend_refcounted *ref)
|
||||
GC_G(num_roots)++;
|
||||
}
|
||||
|
||||
static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *stack)
|
||||
static int gc_collect_white(zend_refcounted *ref, uint32_t *flags)
|
||||
{
|
||||
int count = 0;
|
||||
HashTable *ht = NULL;
|
||||
HashTable *ht;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
do {
|
||||
tail_call:
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
ht = NULL;
|
||||
GC_REF_SET_BLACK(ref);
|
||||
|
||||
/* don't count references for compatibility ??? */
|
||||
if (GC_TYPE(ref) != IS_REFERENCE) {
|
||||
count++;
|
||||
@@ -1152,7 +1027,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -1162,31 +1037,28 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
gc_add_garbage(ref);
|
||||
}
|
||||
if (obj->handlers->dtor_obj &&
|
||||
((obj->handlers->dtor_obj != zend_objects_destroy_object) ||
|
||||
(obj->ce->destructor != NULL))) {
|
||||
((obj->handlers->dtor_obj != zend_objects_destroy_object) ||
|
||||
(obj->ce->destructor != NULL))) {
|
||||
*flags |= GC_HAS_DESTRUCTORS;
|
||||
}
|
||||
ZVAL_OBJ(&tmp, obj);
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) goto next;
|
||||
if (!n) return count;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
}
|
||||
if (zv == end) goto next;
|
||||
if (zv == end) return count;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
count += gc_collect_white(ref, flags);
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
} else if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
@@ -1196,14 +1068,10 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
goto next;
|
||||
goto tail_call;
|
||||
}
|
||||
} else {
|
||||
goto next;
|
||||
return count;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
/* optimization: color is GC_BLACK (0) */
|
||||
@@ -1215,17 +1083,14 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
return count;
|
||||
} else {
|
||||
goto next;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) goto next;
|
||||
if (!ht->nNumUsed) return count;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -1241,7 +1106,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
}
|
||||
if (p == end) goto next;
|
||||
if (p == end) return count;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -1251,10 +1116,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
count += gc_collect_white(ref, flags);
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
} else if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
@@ -1267,19 +1129,12 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
} while (ref);
|
||||
|
||||
goto tail_call;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int gc_collect_roots(uint32_t *flags, gc_stack *stack)
|
||||
static int gc_collect_roots(uint32_t *flags)
|
||||
{
|
||||
uint32_t idx, end;
|
||||
zend_refcounted *ref;
|
||||
@@ -1310,8 +1165,7 @@ static int gc_collect_roots(uint32_t *flags, gc_stack *stack)
|
||||
ZEND_ASSERT(GC_IS_ROOT(ref));
|
||||
current->ref = GC_MAKE_GARBAGE(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
count += gc_collect_white(ref, flags, stack);
|
||||
count += gc_collect_white(ref, flags);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
@@ -1426,10 +1280,6 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
zend_refcounted *p;
|
||||
uint32_t gc_flags = 0;
|
||||
uint32_t idx, end;
|
||||
gc_stack stack;
|
||||
|
||||
stack.prev = NULL;
|
||||
stack.next = NULL;
|
||||
|
||||
if (GC_G(gc_active)) {
|
||||
return 0;
|
||||
@@ -1440,14 +1290,12 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
GC_G(gc_active) = 1;
|
||||
|
||||
GC_TRACE("Marking roots");
|
||||
gc_mark_roots(&stack);
|
||||
gc_mark_roots();
|
||||
GC_TRACE("Scanning roots");
|
||||
gc_scan_roots(&stack);
|
||||
gc_scan_roots();
|
||||
|
||||
GC_TRACE("Collecting roots");
|
||||
count = gc_collect_roots(&gc_flags, &stack);
|
||||
|
||||
gc_stack_free(&stack);
|
||||
count = gc_collect_roots(&gc_flags);
|
||||
|
||||
if (!GC_G(num_roots)) {
|
||||
/* nothing to free */
|
||||
|
||||
@@ -123,7 +123,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
/* always free the CV's, in the symtable are only not-free'd IS_INDIRECT's */
|
||||
zend_free_compiled_variables(execute_data);
|
||||
|
||||
if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) {
|
||||
if ((EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) &&
|
||||
EXPECTED(GC_TYPE(Z_OBJ(execute_data->This)) == IS_OBJECT)) {
|
||||
OBJ_RELEASE(Z_OBJ(execute_data->This));
|
||||
}
|
||||
|
||||
@@ -143,7 +144,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
}
|
||||
|
||||
/* Free closure object */
|
||||
if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
|
||||
if ((EX_CALL_INFO() & ZEND_CALL_CLOSURE) &&
|
||||
EXPECTED(GC_TYPE(ZEND_CLOSURE_OBJECT(EX(func))) == IS_OBJECT)) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -233,9 +233,8 @@ struct _zend_executor_globals {
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
#define EG_FLAGS_INITIAL (0)
|
||||
#define EG_FLAGS_IN_SHUTDOWN (1<<0)
|
||||
#define EG_FLAGS_OBJECT_STORE_NO_REUSE (1<<1)
|
||||
#define EG_FLAGS_INITIAL 0x00
|
||||
#define EG_FLAGS_IN_SHUTDOWN 0x01
|
||||
|
||||
struct _zend_ini_scanner_globals {
|
||||
zend_file_handle *yy_in;
|
||||
|
||||
+52
-27
@@ -64,7 +64,7 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
|
||||
zend_output_debug_string(1, "%s(%d) : ht=%p is inconsistent", file, line, ht);
|
||||
break;
|
||||
}
|
||||
ZEND_ASSERT(0);
|
||||
zend_bailout();
|
||||
}
|
||||
#define IS_CONSISTENT(a) _zend_is_inconsistent(a, __FILE__, __LINE__);
|
||||
#define SET_INCONSISTENT(n) do { \
|
||||
@@ -377,8 +377,10 @@ ZEND_API uint32_t zend_array_count(HashTable *ht)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline HashPosition _zend_hash_get_valid_pos(const HashTable *ht, HashPosition pos)
|
||||
static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable *ht)
|
||||
{
|
||||
HashPosition pos = 0;
|
||||
|
||||
while (pos < ht->nNumUsed && Z_ISUNDEF(ht->arData[pos].val)) {
|
||||
pos++;
|
||||
}
|
||||
@@ -387,7 +389,12 @@ static zend_always_inline HashPosition _zend_hash_get_valid_pos(const HashTable
|
||||
|
||||
static zend_always_inline HashPosition _zend_hash_get_current_pos(const HashTable *ht)
|
||||
{
|
||||
return _zend_hash_get_valid_pos(ht, ht->nInternalPointer);
|
||||
HashPosition pos = ht->nInternalPointer;
|
||||
|
||||
if (pos == 0) {
|
||||
pos = _zend_hash_get_first_pos(ht);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *ht)
|
||||
@@ -481,7 +488,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
|
||||
|
||||
if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
|
||||
&& EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
|
||||
ZEND_ASSERT(HT_ITERATORS_COUNT(iter->ht) != 0);
|
||||
HT_DEC_ITERATORS_COUNT(iter->ht);
|
||||
}
|
||||
iter->ht = NULL;
|
||||
@@ -1071,7 +1077,6 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
||||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
} else {
|
||||
uint32_t old_num_used = ht->nNumUsed;
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) {
|
||||
uint32_t j = i;
|
||||
@@ -1128,12 +1133,6 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
||||
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i);
|
||||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
|
||||
/* Migrate pointer to one past the end of the array to the new one past the end, so that
|
||||
* newly inserted elements are picked up correctly. */
|
||||
if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
|
||||
_zend_hash_iterators_update(ht, old_num_used, ht->nNumUsed);
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -1929,8 +1928,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->pDestructor = ZVAL_PTR_DTOR;
|
||||
|
||||
if (source->nNumOfElements == 0) {
|
||||
uint32_t mask = HASH_FLAG_MASK & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED);
|
||||
HT_FLAGS(target) = (HT_FLAGS(source) & mask) | HASH_FLAG_STATIC_KEYS;
|
||||
HT_FLAGS(target) = (HT_FLAGS(source) & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED)) | HASH_FLAG_STATIC_KEYS;
|
||||
target->nTableMask = HT_MIN_MASK;
|
||||
target->nNumUsed = 0;
|
||||
target->nNumOfElements = 0;
|
||||
@@ -1938,7 +1936,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->nInternalPointer = 0;
|
||||
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
|
||||
} else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
target->nTableMask = source->nTableMask;
|
||||
target->nNumUsed = source->nNumUsed;
|
||||
target->nNumOfElements = source->nNumOfElements;
|
||||
@@ -1947,7 +1945,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->nInternalPointer = source->nInternalPointer;
|
||||
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
|
||||
} else if (HT_FLAGS(source) & HASH_FLAG_PACKED) {
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
target->nTableMask = HT_MIN_MASK;
|
||||
target->nNumUsed = source->nNumUsed;
|
||||
target->nNumOfElements = source->nNumOfElements;
|
||||
@@ -1965,7 +1963,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
zend_array_dup_packed_elements(source, target, 1);
|
||||
}
|
||||
} else {
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
target->nTableMask = source->nTableMask;
|
||||
target->nNextFreeElement = source->nNextFreeElement;
|
||||
target->nInternalPointer =
|
||||
@@ -2191,7 +2189,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, H
|
||||
{
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
*pos = _zend_hash_get_valid_pos(ht, 0);
|
||||
*pos = _zend_hash_get_first_pos(ht);
|
||||
}
|
||||
|
||||
|
||||
@@ -2219,13 +2217,19 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, Has
|
||||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t idx = *pos;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
*pos = idx;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
idx++;
|
||||
if (idx >= ht->nNumUsed) {
|
||||
@@ -2268,12 +2272,17 @@ ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPositi
|
||||
/* This function should be made binary safe */
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t idx = *pos;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
*str_index = p->key;
|
||||
@@ -2288,14 +2297,20 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zen
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t idx = *pos;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
} else {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
ZVAL_STR_COPY(key, p->key);
|
||||
@@ -2307,12 +2322,17 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h
|
||||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t idx = *pos;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
return HASH_KEY_IS_STRING;
|
||||
@@ -2326,12 +2346,17 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, Hash
|
||||
|
||||
ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t idx = *pos;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
return &p->val;
|
||||
} else {
|
||||
|
||||
@@ -40,9 +40,6 @@
|
||||
#define HASH_FLAG_HAS_EMPTY_IND (1<<5)
|
||||
#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
|
||||
|
||||
/* Only the low byte are real flags */
|
||||
#define HASH_FLAG_MASK 0xff
|
||||
|
||||
#define HT_FLAGS(ht) (ht)->u.flags
|
||||
|
||||
#define HT_IS_PACKED(ht) \
|
||||
|
||||
+14
-17
@@ -208,8 +208,8 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
|
||||
fe_class_name = ZEND_TYPE_NAME(fe_arg_info->type);
|
||||
class_name = ZSTR_VAL(fe_class_name);
|
||||
class_name_len = ZSTR_LEN(fe_class_name);
|
||||
if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && fe->common.scope && fe->common.scope->parent) {
|
||||
fe_class_name = zend_string_copy(fe->common.scope->parent->name);
|
||||
if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && proto->common.scope) {
|
||||
fe_class_name = zend_string_copy(proto->common.scope->name);
|
||||
} else if (class_name_len == sizeof("self")-1 && !strcasecmp(class_name, "self") && fe->common.scope) {
|
||||
fe_class_name = zend_string_copy(fe->common.scope->name);
|
||||
} else {
|
||||
@@ -894,9 +894,6 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
||||
}
|
||||
if (UNEXPECTED(parent_ce->type != ce->type)) {
|
||||
/* User class extends internal */
|
||||
if (CE_STATIC_MEMBERS(parent_ce) == NULL) {
|
||||
zend_class_init_statics(parent_ce);
|
||||
}
|
||||
if (UNEXPECTED(zend_update_class_constants(parent_ce) != SUCCESS)) {
|
||||
ZEND_ASSERT(0);
|
||||
}
|
||||
@@ -1129,7 +1126,18 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_
|
||||
|
||||
static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zend_function* fe) /* {{{ */
|
||||
{
|
||||
if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) {
|
||||
if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) {
|
||||
zend_string *lowercase_name = zend_string_tolower(ce->name);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) {
|
||||
if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name));
|
||||
}
|
||||
ce->constructor = fe;
|
||||
fe->common.fn_flags |= ZEND_ACC_CTOR;
|
||||
}
|
||||
zend_string_release_ex(lowercase_name, 0);
|
||||
} else if (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_') {
|
||||
/* pass */
|
||||
} else if (zend_string_equals_literal(mname, ZEND_CLONE_FUNC_NAME)) {
|
||||
ce->clone = fe;
|
||||
@@ -1160,17 +1168,6 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen
|
||||
ce->__tostring = fe;
|
||||
} else if (zend_string_equals_literal(mname, ZEND_DEBUGINFO_FUNC_NAME)) {
|
||||
ce->__debugInfo = fe;
|
||||
} else if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) {
|
||||
zend_string *lowercase_name = zend_string_tolower(ce->name);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) {
|
||||
if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name));
|
||||
}
|
||||
ce->constructor = fe;
|
||||
fe->common.fn_flags |= ZEND_ACC_CTOR;
|
||||
}
|
||||
zend_string_release_ex(lowercase_name, 0);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
+16
-18
@@ -46,22 +46,6 @@ int ini_parse(void);
|
||||
|
||||
#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors)
|
||||
|
||||
static int get_int_val(zval *op) {
|
||||
switch (Z_TYPE_P(op)) {
|
||||
case IS_LONG:
|
||||
return Z_LVAL_P(op);
|
||||
case IS_DOUBLE:
|
||||
return (int)Z_DVAL_P(op);
|
||||
case IS_STRING:
|
||||
{
|
||||
int val = atoi(Z_STRVAL_P(op));
|
||||
zend_string_free(Z_STR_P(op));
|
||||
return val;
|
||||
}
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ zend_ini_do_op()
|
||||
*/
|
||||
static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
@@ -71,8 +55,22 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
int str_len;
|
||||
char str_result[MAX_LENGTH_OF_LONG+1];
|
||||
|
||||
i_op1 = get_int_val(op1);
|
||||
i_op2 = op2 ? get_int_val(op2) : 0;
|
||||
if (IS_LONG == Z_TYPE_P(op1)) {
|
||||
i_op1 = Z_LVAL_P(op1);
|
||||
} else {
|
||||
i_op1 = atoi(Z_STRVAL_P(op1));
|
||||
zend_string_free(Z_STR_P(op1));
|
||||
}
|
||||
if (op2) {
|
||||
if (IS_LONG == Z_TYPE_P(op2)) {
|
||||
i_op2 = Z_LVAL_P(op2);
|
||||
} else {
|
||||
i_op2 = atoi(Z_STRVAL_P(op2));
|
||||
zend_string_free(Z_STR_P(op2));
|
||||
}
|
||||
} else {
|
||||
i_op2 = 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case '|':
|
||||
|
||||
+121
-122
@@ -143,14 +143,13 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
ZVAL_NEW_STR(retval, zend_string_init(str, len, ZEND_SYSTEM_INI))
|
||||
|
||||
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED && \
|
||||
(YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW))) {\
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED) { \
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
}
|
||||
|
||||
static inline int convert_to_number(zval *retval, const char *str, const int str_len)
|
||||
@@ -383,7 +382,7 @@ restart:
|
||||
}
|
||||
}
|
||||
|
||||
#line 387 "Zend/zend_ini_scanner.c"
|
||||
#line 386 "Zend/zend_ini_scanner.c"
|
||||
{
|
||||
YYCTYPE yych;
|
||||
unsigned int yyaccept = 0;
|
||||
@@ -505,7 +504,7 @@ yy4:
|
||||
yy5:
|
||||
YYDEBUG(5, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 482 "Zend/zend_ini_scanner.l"
|
||||
#line 481 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get option name */
|
||||
/* Eat leading whitespace */
|
||||
EAT_LEADING_WHITESPACE();
|
||||
@@ -515,7 +514,7 @@ yy5:
|
||||
|
||||
RETURN_TOKEN(TC_LABEL, yytext, yyleng);
|
||||
}
|
||||
#line 519 "Zend/zend_ini_scanner.c"
|
||||
#line 518 "Zend/zend_ini_scanner.c"
|
||||
yy6:
|
||||
YYDEBUG(6, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -539,24 +538,24 @@ yy6:
|
||||
yy8:
|
||||
YYDEBUG(8, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 635 "Zend/zend_ini_scanner.l"
|
||||
#line 634 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
/* eat whitespace */
|
||||
goto restart;
|
||||
}
|
||||
#line 548 "Zend/zend_ini_scanner.c"
|
||||
#line 547 "Zend/zend_ini_scanner.c"
|
||||
yy9:
|
||||
YYDEBUG(9, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
yy10:
|
||||
YYDEBUG(10, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 640 "Zend/zend_ini_scanner.l"
|
||||
#line 639 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 560 "Zend/zend_ini_scanner.c"
|
||||
#line 559 "Zend/zend_ini_scanner.c"
|
||||
yy11:
|
||||
YYDEBUG(11, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -617,11 +616,11 @@ yy14:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(15, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 563 "Zend/zend_ini_scanner.l"
|
||||
#line 562 "Zend/zend_ini_scanner.l"
|
||||
{ /* Disallow these chars outside option values */
|
||||
return yytext[0];
|
||||
}
|
||||
#line 625 "Zend/zend_ini_scanner.c"
|
||||
#line 624 "Zend/zend_ini_scanner.c"
|
||||
yy16:
|
||||
YYDEBUG(16, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -643,7 +642,7 @@ yy18:
|
||||
if (yych == ' ') goto yy18;
|
||||
YYDEBUG(20, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 492 "Zend/zend_ini_scanner.l"
|
||||
#line 491 "Zend/zend_ini_scanner.l"
|
||||
{ /* Start option value */
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
|
||||
BEGIN(ST_RAW);
|
||||
@@ -652,7 +651,7 @@ yy18:
|
||||
}
|
||||
return '=';
|
||||
}
|
||||
#line 656 "Zend/zend_ini_scanner.c"
|
||||
#line 655 "Zend/zend_ini_scanner.c"
|
||||
yy21:
|
||||
YYDEBUG(21, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -708,7 +707,7 @@ yy26:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(27, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 407 "Zend/zend_ini_scanner.l"
|
||||
#line 406 "Zend/zend_ini_scanner.l"
|
||||
{ /* Section start */
|
||||
/* Enter section data lookup state */
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
|
||||
@@ -718,7 +717,7 @@ yy26:
|
||||
}
|
||||
return TC_SECTION;
|
||||
}
|
||||
#line 722 "Zend/zend_ini_scanner.c"
|
||||
#line 721 "Zend/zend_ini_scanner.c"
|
||||
yy28:
|
||||
YYDEBUG(28, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -729,7 +728,7 @@ yy28:
|
||||
if (yych == ' ') goto yy28;
|
||||
YYDEBUG(30, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 432 "Zend/zend_ini_scanner.l"
|
||||
#line 431 "Zend/zend_ini_scanner.l"
|
||||
{ /* Start of option with offset */
|
||||
/* Eat leading whitespace */
|
||||
EAT_LEADING_WHITESPACE();
|
||||
@@ -742,20 +741,20 @@ yy28:
|
||||
|
||||
RETURN_TOKEN(TC_OFFSET, yytext, yyleng);
|
||||
}
|
||||
#line 746 "Zend/zend_ini_scanner.c"
|
||||
#line 745 "Zend/zend_ini_scanner.c"
|
||||
yy31:
|
||||
YYDEBUG(31, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
yy32:
|
||||
YYDEBUG(32, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 645 "Zend/zend_ini_scanner.l"
|
||||
#line 644 "Zend/zend_ini_scanner.l"
|
||||
{ /* Comment */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 759 "Zend/zend_ini_scanner.c"
|
||||
#line 758 "Zend/zend_ini_scanner.c"
|
||||
yy33:
|
||||
YYDEBUG(33, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -810,11 +809,11 @@ yy35:
|
||||
yy36:
|
||||
YYDEBUG(36, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 474 "Zend/zend_ini_scanner.l"
|
||||
#line 473 "Zend/zend_ini_scanner.l"
|
||||
{ /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
RETURN_TOKEN(BOOL_FALSE, "", 0);
|
||||
}
|
||||
#line 818 "Zend/zend_ini_scanner.c"
|
||||
#line 817 "Zend/zend_ini_scanner.c"
|
||||
yy37:
|
||||
YYDEBUG(37, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -871,11 +870,11 @@ yy39:
|
||||
yy41:
|
||||
YYDEBUG(41, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 470 "Zend/zend_ini_scanner.l"
|
||||
#line 469 "Zend/zend_ini_scanner.l"
|
||||
{ /* TRUE value (when used outside option value/offset this causes parse error!) */
|
||||
RETURN_TOKEN(BOOL_TRUE, "1", 1);
|
||||
}
|
||||
#line 879 "Zend/zend_ini_scanner.c"
|
||||
#line 878 "Zend/zend_ini_scanner.c"
|
||||
yy42:
|
||||
YYDEBUG(42, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -1022,11 +1021,11 @@ yy54:
|
||||
yy56:
|
||||
YYDEBUG(56, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 478 "Zend/zend_ini_scanner.l"
|
||||
#line 477 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
RETURN_TOKEN(NULL_NULL, "", 0);
|
||||
}
|
||||
#line 1030 "Zend/zend_ini_scanner.c"
|
||||
#line 1029 "Zend/zend_ini_scanner.c"
|
||||
yy57:
|
||||
YYDEBUG(57, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1135,11 +1134,11 @@ yy62:
|
||||
yy63:
|
||||
YYDEBUG(63, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 581 "Zend/zend_ini_scanner.l"
|
||||
#line 580 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get rest as section/offset value */
|
||||
RETURN_TOKEN(TC_STRING, yytext, yyleng);
|
||||
}
|
||||
#line 1143 "Zend/zend_ini_scanner.c"
|
||||
#line 1142 "Zend/zend_ini_scanner.c"
|
||||
yy64:
|
||||
YYDEBUG(64, *YYCURSOR);
|
||||
yyaccept = 0;
|
||||
@@ -1179,22 +1178,22 @@ yy66:
|
||||
yy67:
|
||||
YYDEBUG(67, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 656 "Zend/zend_ini_scanner.l"
|
||||
#line 655 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#line 1187 "Zend/zend_ini_scanner.c"
|
||||
#line 1186 "Zend/zend_ini_scanner.c"
|
||||
yy68:
|
||||
YYDEBUG(68, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(69, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 585 "Zend/zend_ini_scanner.l"
|
||||
#line 584 "Zend/zend_ini_scanner.l"
|
||||
{ /* Double quoted '"' string start */
|
||||
yy_push_state(ST_DOUBLE_QUOTES);
|
||||
return '"';
|
||||
}
|
||||
#line 1198 "Zend/zend_ini_scanner.c"
|
||||
#line 1197 "Zend/zend_ini_scanner.c"
|
||||
yy70:
|
||||
YYDEBUG(70, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -1259,11 +1258,11 @@ yy73:
|
||||
yy75:
|
||||
YYDEBUG(75, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 559 "Zend/zend_ini_scanner.l"
|
||||
#line 558 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get number option value as string */
|
||||
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
|
||||
}
|
||||
#line 1267 "Zend/zend_ini_scanner.c"
|
||||
#line 1266 "Zend/zend_ini_scanner.c"
|
||||
yy76:
|
||||
YYDEBUG(76, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -1296,11 +1295,11 @@ yy76:
|
||||
yy78:
|
||||
YYDEBUG(78, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 555 "Zend/zend_ini_scanner.l"
|
||||
#line 554 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get constant option value */
|
||||
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
|
||||
}
|
||||
#line 1304 "Zend/zend_ini_scanner.c"
|
||||
#line 1303 "Zend/zend_ini_scanner.c"
|
||||
yy79:
|
||||
YYDEBUG(79, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1312,12 +1311,12 @@ yy80:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(81, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 445 "Zend/zend_ini_scanner.l"
|
||||
#line 444 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of section or an option offset */
|
||||
BEGIN(INITIAL);
|
||||
return ']';
|
||||
}
|
||||
#line 1321 "Zend/zend_ini_scanner.c"
|
||||
#line 1320 "Zend/zend_ini_scanner.c"
|
||||
yy82:
|
||||
YYDEBUG(82, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1357,12 +1356,12 @@ yy86:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(87, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 450 "Zend/zend_ini_scanner.l"
|
||||
#line 449 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable start */
|
||||
yy_push_state(ST_VARNAME);
|
||||
return TC_DOLLAR_CURLY;
|
||||
}
|
||||
#line 1366 "Zend/zend_ini_scanner.c"
|
||||
#line 1365 "Zend/zend_ini_scanner.c"
|
||||
yy88:
|
||||
YYDEBUG(88, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1416,7 +1415,7 @@ yy92:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(93, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 417 "Zend/zend_ini_scanner.l"
|
||||
#line 416 "Zend/zend_ini_scanner.l"
|
||||
{ /* Raw string */
|
||||
/* Eat leading and trailing single quotes */
|
||||
if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
|
||||
@@ -1425,7 +1424,7 @@ yy92:
|
||||
}
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
#line 1429 "Zend/zend_ini_scanner.c"
|
||||
#line 1428 "Zend/zend_ini_scanner.c"
|
||||
}
|
||||
/* *********************************** */
|
||||
yyc_ST_SECTION_VALUE:
|
||||
@@ -1525,11 +1524,11 @@ yy97:
|
||||
yy98:
|
||||
YYDEBUG(98, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 581 "Zend/zend_ini_scanner.l"
|
||||
#line 580 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get rest as section/offset value */
|
||||
RETURN_TOKEN(TC_STRING, yytext, yyleng);
|
||||
}
|
||||
#line 1533 "Zend/zend_ini_scanner.c"
|
||||
#line 1532 "Zend/zend_ini_scanner.c"
|
||||
yy99:
|
||||
YYDEBUG(99, *YYCURSOR);
|
||||
yyaccept = 0;
|
||||
@@ -1569,22 +1568,22 @@ yy101:
|
||||
yy102:
|
||||
YYDEBUG(102, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 656 "Zend/zend_ini_scanner.l"
|
||||
#line 655 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#line 1577 "Zend/zend_ini_scanner.c"
|
||||
#line 1576 "Zend/zend_ini_scanner.c"
|
||||
yy103:
|
||||
YYDEBUG(103, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(104, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 585 "Zend/zend_ini_scanner.l"
|
||||
#line 584 "Zend/zend_ini_scanner.l"
|
||||
{ /* Double quoted '"' string start */
|
||||
yy_push_state(ST_DOUBLE_QUOTES);
|
||||
return '"';
|
||||
}
|
||||
#line 1588 "Zend/zend_ini_scanner.c"
|
||||
#line 1587 "Zend/zend_ini_scanner.c"
|
||||
yy105:
|
||||
YYDEBUG(105, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -1649,11 +1648,11 @@ yy108:
|
||||
yy110:
|
||||
YYDEBUG(110, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 559 "Zend/zend_ini_scanner.l"
|
||||
#line 558 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get number option value as string */
|
||||
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
|
||||
}
|
||||
#line 1657 "Zend/zend_ini_scanner.c"
|
||||
#line 1656 "Zend/zend_ini_scanner.c"
|
||||
yy111:
|
||||
YYDEBUG(111, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -1686,11 +1685,11 @@ yy111:
|
||||
yy113:
|
||||
YYDEBUG(113, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 555 "Zend/zend_ini_scanner.l"
|
||||
#line 554 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get constant option value */
|
||||
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
|
||||
}
|
||||
#line 1694 "Zend/zend_ini_scanner.c"
|
||||
#line 1693 "Zend/zend_ini_scanner.c"
|
||||
yy114:
|
||||
YYDEBUG(114, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1714,13 +1713,13 @@ yy115:
|
||||
yy117:
|
||||
YYDEBUG(117, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 426 "Zend/zend_ini_scanner.l"
|
||||
#line 425 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of section */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return ']';
|
||||
}
|
||||
#line 1724 "Zend/zend_ini_scanner.c"
|
||||
#line 1723 "Zend/zend_ini_scanner.c"
|
||||
yy118:
|
||||
YYDEBUG(118, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1760,12 +1759,12 @@ yy122:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(123, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 450 "Zend/zend_ini_scanner.l"
|
||||
#line 449 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable start */
|
||||
yy_push_state(ST_VARNAME);
|
||||
return TC_DOLLAR_CURLY;
|
||||
}
|
||||
#line 1769 "Zend/zend_ini_scanner.c"
|
||||
#line 1768 "Zend/zend_ini_scanner.c"
|
||||
yy124:
|
||||
YYDEBUG(124, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -1828,7 +1827,7 @@ yy130:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(131, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 417 "Zend/zend_ini_scanner.l"
|
||||
#line 416 "Zend/zend_ini_scanner.l"
|
||||
{ /* Raw string */
|
||||
/* Eat leading and trailing single quotes */
|
||||
if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
|
||||
@@ -1837,7 +1836,7 @@ yy130:
|
||||
}
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
#line 1841 "Zend/zend_ini_scanner.c"
|
||||
#line 1840 "Zend/zend_ini_scanner.c"
|
||||
}
|
||||
/* *********************************** */
|
||||
yyc_ST_VALUE:
|
||||
@@ -1973,12 +1972,12 @@ yy134:
|
||||
yy135:
|
||||
YYDEBUG(135, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 651 "Zend/zend_ini_scanner.l"
|
||||
#line 650 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of option value (if EOF is reached before EOL */
|
||||
BEGIN(INITIAL);
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 1982 "Zend/zend_ini_scanner.c"
|
||||
#line 1981 "Zend/zend_ini_scanner.c"
|
||||
yy136:
|
||||
YYDEBUG(136, *YYCURSOR);
|
||||
yyaccept = 0;
|
||||
@@ -1995,11 +1994,11 @@ yy137:
|
||||
yy138:
|
||||
YYDEBUG(138, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 577 "Zend/zend_ini_scanner.l"
|
||||
#line 576 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get everything else as option/offset value */
|
||||
RETURN_TOKEN(TC_STRING, yytext, yyleng);
|
||||
}
|
||||
#line 2003 "Zend/zend_ini_scanner.c"
|
||||
#line 2002 "Zend/zend_ini_scanner.c"
|
||||
yy139:
|
||||
YYDEBUG(139, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -2023,24 +2022,24 @@ yy139:
|
||||
yy141:
|
||||
YYDEBUG(141, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 631 "Zend/zend_ini_scanner.l"
|
||||
#line 630 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng);
|
||||
}
|
||||
#line 2031 "Zend/zend_ini_scanner.c"
|
||||
#line 2030 "Zend/zend_ini_scanner.c"
|
||||
yy142:
|
||||
YYDEBUG(142, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
yy143:
|
||||
YYDEBUG(143, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 549 "Zend/zend_ini_scanner.l"
|
||||
#line 548 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of option value */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 2044 "Zend/zend_ini_scanner.c"
|
||||
#line 2043 "Zend/zend_ini_scanner.c"
|
||||
yy144:
|
||||
YYDEBUG(144, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -2056,22 +2055,22 @@ yy145:
|
||||
if (yych == ' ') goto yy145;
|
||||
YYDEBUG(147, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 567 "Zend/zend_ini_scanner.l"
|
||||
#line 566 "Zend/zend_ini_scanner.l"
|
||||
{ /* Boolean operators */
|
||||
return yytext[0];
|
||||
}
|
||||
#line 2064 "Zend/zend_ini_scanner.c"
|
||||
#line 2063 "Zend/zend_ini_scanner.c"
|
||||
yy148:
|
||||
YYDEBUG(148, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(149, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 585 "Zend/zend_ini_scanner.l"
|
||||
#line 584 "Zend/zend_ini_scanner.l"
|
||||
{ /* Double quoted '"' string start */
|
||||
yy_push_state(ST_DOUBLE_QUOTES);
|
||||
return '"';
|
||||
}
|
||||
#line 2075 "Zend/zend_ini_scanner.c"
|
||||
#line 2074 "Zend/zend_ini_scanner.c"
|
||||
yy150:
|
||||
YYDEBUG(150, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -2145,11 +2144,11 @@ yy153:
|
||||
yy155:
|
||||
YYDEBUG(155, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 559 "Zend/zend_ini_scanner.l"
|
||||
#line 558 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get number option value as string */
|
||||
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
|
||||
}
|
||||
#line 2153 "Zend/zend_ini_scanner.c"
|
||||
#line 2152 "Zend/zend_ini_scanner.c"
|
||||
yy156:
|
||||
YYDEBUG(156, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -2166,13 +2165,13 @@ yy158:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(159, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 571 "Zend/zend_ini_scanner.l"
|
||||
#line 570 "Zend/zend_ini_scanner.l"
|
||||
{ /* Make = used in option value to trigger error */
|
||||
yyless(0);
|
||||
BEGIN(INITIAL);
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 2176 "Zend/zend_ini_scanner.c"
|
||||
#line 2175 "Zend/zend_ini_scanner.c"
|
||||
yy160:
|
||||
YYDEBUG(160, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -2219,11 +2218,11 @@ yy160:
|
||||
yy162:
|
||||
YYDEBUG(162, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 555 "Zend/zend_ini_scanner.l"
|
||||
#line 554 "Zend/zend_ini_scanner.l"
|
||||
{ /* Get constant option value */
|
||||
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
|
||||
}
|
||||
#line 2227 "Zend/zend_ini_scanner.c"
|
||||
#line 2226 "Zend/zend_ini_scanner.c"
|
||||
yy163:
|
||||
YYDEBUG(163, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -2557,12 +2556,12 @@ yy171:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(172, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 450 "Zend/zend_ini_scanner.l"
|
||||
#line 449 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable start */
|
||||
yy_push_state(ST_VARNAME);
|
||||
return TC_DOLLAR_CURLY;
|
||||
}
|
||||
#line 2566 "Zend/zend_ini_scanner.c"
|
||||
#line 2565 "Zend/zend_ini_scanner.c"
|
||||
yy173:
|
||||
YYDEBUG(173, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -2628,13 +2627,13 @@ yy177:
|
||||
yy178:
|
||||
YYDEBUG(178, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 645 "Zend/zend_ini_scanner.l"
|
||||
#line 644 "Zend/zend_ini_scanner.l"
|
||||
{ /* Comment */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 2638 "Zend/zend_ini_scanner.c"
|
||||
#line 2637 "Zend/zend_ini_scanner.c"
|
||||
yy179:
|
||||
YYDEBUG(179, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -2745,11 +2744,11 @@ yy181:
|
||||
yy182:
|
||||
YYDEBUG(182, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 474 "Zend/zend_ini_scanner.l"
|
||||
#line 473 "Zend/zend_ini_scanner.l"
|
||||
{ /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
RETURN_TOKEN(BOOL_FALSE, "", 0);
|
||||
}
|
||||
#line 2753 "Zend/zend_ini_scanner.c"
|
||||
#line 2752 "Zend/zend_ini_scanner.c"
|
||||
yy183:
|
||||
YYDEBUG(183, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -2896,11 +2895,11 @@ yy185:
|
||||
yy186:
|
||||
YYDEBUG(186, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 470 "Zend/zend_ini_scanner.l"
|
||||
#line 469 "Zend/zend_ini_scanner.l"
|
||||
{ /* TRUE value (when used outside option value/offset this causes parse error!) */
|
||||
RETURN_TOKEN(BOOL_TRUE, "1", 1);
|
||||
}
|
||||
#line 2904 "Zend/zend_ini_scanner.c"
|
||||
#line 2903 "Zend/zend_ini_scanner.c"
|
||||
yy187:
|
||||
YYDEBUG(187, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -3020,7 +3019,7 @@ yy191:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(192, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 417 "Zend/zend_ini_scanner.l"
|
||||
#line 416 "Zend/zend_ini_scanner.l"
|
||||
{ /* Raw string */
|
||||
/* Eat leading and trailing single quotes */
|
||||
if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
|
||||
@@ -3029,7 +3028,7 @@ yy191:
|
||||
}
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
#line 3033 "Zend/zend_ini_scanner.c"
|
||||
#line 3032 "Zend/zend_ini_scanner.c"
|
||||
yy193:
|
||||
YYDEBUG(193, *YYCURSOR);
|
||||
yyaccept = 2;
|
||||
@@ -3344,11 +3343,11 @@ yy202:
|
||||
yy203:
|
||||
YYDEBUG(203, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 478 "Zend/zend_ini_scanner.l"
|
||||
#line 477 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
RETURN_TOKEN(NULL_NULL, "", 0);
|
||||
}
|
||||
#line 3352 "Zend/zend_ini_scanner.c"
|
||||
#line 3351 "Zend/zend_ini_scanner.c"
|
||||
yy204:
|
||||
YYDEBUG(204, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -3415,21 +3414,21 @@ yy208:
|
||||
}
|
||||
YYDEBUG(210, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 545 "Zend/zend_ini_scanner.l"
|
||||
#line 544 "Zend/zend_ini_scanner.l"
|
||||
{ /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
#line 3423 "Zend/zend_ini_scanner.c"
|
||||
#line 3422 "Zend/zend_ini_scanner.c"
|
||||
yy211:
|
||||
YYDEBUG(211, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(212, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 656 "Zend/zend_ini_scanner.l"
|
||||
#line 655 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#line 3433 "Zend/zend_ini_scanner.c"
|
||||
#line 3432 "Zend/zend_ini_scanner.c"
|
||||
yy213:
|
||||
YYDEBUG(213, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -3445,13 +3444,13 @@ yy213:
|
||||
yy215:
|
||||
YYDEBUG(215, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 426 "Zend/zend_ini_scanner.l"
|
||||
#line 425 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of section */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return ']';
|
||||
}
|
||||
#line 3455 "Zend/zend_ini_scanner.c"
|
||||
#line 3454 "Zend/zend_ini_scanner.c"
|
||||
yy216:
|
||||
YYDEBUG(216, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -3509,7 +3508,7 @@ yyc_ST_DOUBLE_QUOTES:
|
||||
yy221:
|
||||
YYDEBUG(221, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 595 "Zend/zend_ini_scanner.l"
|
||||
#line 594 "Zend/zend_ini_scanner.l"
|
||||
{ /* Escape double quoted string contents */
|
||||
if (YYCURSOR > YYLIMIT) {
|
||||
return 0;
|
||||
@@ -3545,7 +3544,7 @@ yy221:
|
||||
zend_ini_escape_string(ini_lval, yytext, yyleng, '"');
|
||||
return TC_QUOTED_STRING;
|
||||
}
|
||||
#line 3549 "Zend/zend_ini_scanner.c"
|
||||
#line 3548 "Zend/zend_ini_scanner.c"
|
||||
yy222:
|
||||
YYDEBUG(222, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
@@ -3557,12 +3556,12 @@ yy222:
|
||||
}
|
||||
YYDEBUG(224, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 590 "Zend/zend_ini_scanner.l"
|
||||
#line 589 "Zend/zend_ini_scanner.l"
|
||||
{ /* Double quoted '"' string ends */
|
||||
yy_pop_state();
|
||||
return '"';
|
||||
}
|
||||
#line 3566 "Zend/zend_ini_scanner.c"
|
||||
#line 3565 "Zend/zend_ini_scanner.c"
|
||||
yy225:
|
||||
YYDEBUG(225, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -3571,12 +3570,12 @@ yy225:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(227, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 450 "Zend/zend_ini_scanner.l"
|
||||
#line 449 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable start */
|
||||
yy_push_state(ST_VARNAME);
|
||||
return TC_DOLLAR_CURLY;
|
||||
}
|
||||
#line 3580 "Zend/zend_ini_scanner.c"
|
||||
#line 3579 "Zend/zend_ini_scanner.c"
|
||||
}
|
||||
/* *********************************** */
|
||||
yyc_ST_VARNAME:
|
||||
@@ -3634,7 +3633,7 @@ yy230:
|
||||
}
|
||||
YYDEBUG(232, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 455 "Zend/zend_ini_scanner.l"
|
||||
#line 454 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable name */
|
||||
/* Eat leading whitespace */
|
||||
EAT_LEADING_WHITESPACE();
|
||||
@@ -3644,28 +3643,28 @@ yy230:
|
||||
|
||||
RETURN_TOKEN(TC_VARNAME, yytext, yyleng);
|
||||
}
|
||||
#line 3648 "Zend/zend_ini_scanner.c"
|
||||
#line 3647 "Zend/zend_ini_scanner.c"
|
||||
yy233:
|
||||
YYDEBUG(233, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(234, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 656 "Zend/zend_ini_scanner.l"
|
||||
#line 655 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#line 3658 "Zend/zend_ini_scanner.c"
|
||||
#line 3657 "Zend/zend_ini_scanner.c"
|
||||
yy235:
|
||||
YYDEBUG(235, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
YYDEBUG(236, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 465 "Zend/zend_ini_scanner.l"
|
||||
#line 464 "Zend/zend_ini_scanner.l"
|
||||
{ /* Variable end */
|
||||
yy_pop_state();
|
||||
return '}';
|
||||
}
|
||||
#line 3669 "Zend/zend_ini_scanner.c"
|
||||
#line 3668 "Zend/zend_ini_scanner.c"
|
||||
}
|
||||
/* *********************************** */
|
||||
yyc_ST_RAW:
|
||||
@@ -3729,19 +3728,19 @@ yyc_ST_RAW:
|
||||
++YYCURSOR;
|
||||
YYDEBUG(240, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 651 "Zend/zend_ini_scanner.l"
|
||||
#line 650 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of option value (if EOF is reached before EOL */
|
||||
BEGIN(INITIAL);
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 3738 "Zend/zend_ini_scanner.c"
|
||||
#line 3737 "Zend/zend_ini_scanner.c"
|
||||
yy241:
|
||||
YYDEBUG(241, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
yy242:
|
||||
YYDEBUG(242, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 501 "Zend/zend_ini_scanner.l"
|
||||
#line 500 "Zend/zend_ini_scanner.l"
|
||||
{ /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
|
||||
unsigned char *sc = NULL;
|
||||
EAT_LEADING_WHITESPACE();
|
||||
@@ -3785,7 +3784,7 @@ end_raw_value_chars:
|
||||
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
#line 3789 "Zend/zend_ini_scanner.c"
|
||||
#line 3788 "Zend/zend_ini_scanner.c"
|
||||
yy243:
|
||||
YYDEBUG(243, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -3809,13 +3808,13 @@ yy244:
|
||||
yy245:
|
||||
YYDEBUG(245, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 549 "Zend/zend_ini_scanner.l"
|
||||
#line 548 "Zend/zend_ini_scanner.l"
|
||||
{ /* End of option value */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 3819 "Zend/zend_ini_scanner.c"
|
||||
#line 3818 "Zend/zend_ini_scanner.c"
|
||||
yy246:
|
||||
YYDEBUG(246, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -3852,25 +3851,25 @@ yy250:
|
||||
yy251:
|
||||
YYDEBUG(251, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 635 "Zend/zend_ini_scanner.l"
|
||||
#line 634 "Zend/zend_ini_scanner.l"
|
||||
{
|
||||
/* eat whitespace */
|
||||
goto restart;
|
||||
}
|
||||
#line 3861 "Zend/zend_ini_scanner.c"
|
||||
#line 3860 "Zend/zend_ini_scanner.c"
|
||||
yy252:
|
||||
YYDEBUG(252, *YYCURSOR);
|
||||
++YYCURSOR;
|
||||
yy253:
|
||||
YYDEBUG(253, *YYCURSOR);
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
#line 645 "Zend/zend_ini_scanner.l"
|
||||
#line 644 "Zend/zend_ini_scanner.l"
|
||||
{ /* Comment */
|
||||
BEGIN(INITIAL);
|
||||
SCNG(lineno)++;
|
||||
return END_OF_LINE;
|
||||
}
|
||||
#line 3874 "Zend/zend_ini_scanner.c"
|
||||
#line 3873 "Zend/zend_ini_scanner.c"
|
||||
yy254:
|
||||
YYDEBUG(254, *YYCURSOR);
|
||||
yych = *++YYCURSOR;
|
||||
@@ -3878,6 +3877,6 @@ yy254:
|
||||
goto yy253;
|
||||
}
|
||||
}
|
||||
#line 660 "Zend/zend_ini_scanner.l"
|
||||
#line 659 "Zend/zend_ini_scanner.l"
|
||||
|
||||
}
|
||||
@@ -140,14 +140,13 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
ZVAL_NEW_STR(retval, zend_string_init(str, len, ZEND_SYSTEM_INI))
|
||||
|
||||
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED && \
|
||||
(YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW))) {\
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED) { \
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
}
|
||||
|
||||
static inline int convert_to_number(zval *retval, const char *str, const int str_len)
|
||||
|
||||
+220
-221
File diff suppressed because it is too large.
Load diff
@@ -1781,8 +1781,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
|
||||
char *end;
|
||||
if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
|
||||
errno = 0;
|
||||
/* base must be passed explicitly for correct parse error on Windows */
|
||||
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, yytext[0] == '0' ? 8 : 10));
|
||||
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
|
||||
/* This isn't an assert, we need to ensure 019 isn't valid octal
|
||||
* Because the lexing itself doesn't do that for us
|
||||
*/
|
||||
|
||||
@@ -1374,14 +1374,14 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_class_init_statics(zend_class_entry *class_type) /* {{{ */
|
||||
static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
zval *p;
|
||||
|
||||
if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
|
||||
if (class_type->parent) {
|
||||
zend_class_init_statics(class_type->parent);
|
||||
zend_intenal_class_init_statics(class_type->parent);
|
||||
}
|
||||
|
||||
#if ZTS
|
||||
@@ -1431,7 +1431,7 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
|
||||
/* check if static properties were destoyed */
|
||||
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
zend_class_init_statics(ce);
|
||||
zend_intenal_class_init_statics(ce);
|
||||
} else {
|
||||
undeclared_property:
|
||||
if (!silent) {
|
||||
|
||||
@@ -175,7 +175,6 @@ extern const ZEND_API zend_object_handlers std_object_handlers;
|
||||
#define ZEND_PROPERTY_NOT_EMPTY ZEND_ISEMPTY /* Property is not empty */
|
||||
#define ZEND_PROPERTY_EXISTS 0x2 /* Property exists */
|
||||
|
||||
ZEND_API void zend_class_init_statics(zend_class_entry *ce);
|
||||
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name_strval, const zval *key);
|
||||
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent);
|
||||
ZEND_API ZEND_COLD zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name);
|
||||
|
||||
+6
-12
@@ -41,7 +41,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objec
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects)
|
||||
{
|
||||
EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE;
|
||||
if (objects->top > 1) {
|
||||
uint32_t i;
|
||||
for (i = 1; i < objects->top; i++) {
|
||||
@@ -132,10 +131,10 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
|
||||
{
|
||||
int handle;
|
||||
|
||||
/* When in shutdown sequence - do not reuse previously freed handles, to make sure
|
||||
/* When in shutdown sequesnce - do not reuse previously freed handles, to make sure
|
||||
* the dtors for newly created objects are called in zend_objects_store_call_destructors() loop
|
||||
*/
|
||||
if (EG(objects_store).free_list_head != -1 && EXPECTED(!(EG(flags) & EG_FLAGS_OBJECT_STORE_NO_REUSE))) {
|
||||
if (!(EG(flags) & EG_FLAGS_IN_SHUTDOWN) && EG(objects_store).free_list_head != -1) {
|
||||
handle = EG(objects_store).free_list_head;
|
||||
EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
|
||||
} else {
|
||||
@@ -153,17 +152,14 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */
|
||||
{
|
||||
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
||||
|
||||
/* GC might have released this object already. */
|
||||
if (UNEXPECTED(GC_TYPE(object) == IS_NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure we hold a reference count during the destructor call
|
||||
otherwise, when the destructor ends the storage might be freed
|
||||
when the refcount reaches 0 a second time
|
||||
*/
|
||||
ZEND_ASSERT(EG(objects_store).object_buckets != NULL);
|
||||
ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]));
|
||||
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
||||
|
||||
if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||
GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED);
|
||||
|
||||
@@ -180,8 +176,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ *
|
||||
uint32_t handle = object->handle;
|
||||
void *ptr;
|
||||
|
||||
ZEND_ASSERT(EG(objects_store).object_buckets != NULL);
|
||||
ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]));
|
||||
EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
|
||||
if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
|
||||
GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED);
|
||||
|
||||
@@ -440,8 +440,12 @@ char *alloca();
|
||||
#define MAX(a, b) (((a)>(b))?(a):(b))
|
||||
#define MIN(a, b) (((a)<(b))?(a):(b))
|
||||
|
||||
#define ZEND_BIT_TEST(bits, bit) \
|
||||
(((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
|
||||
/* x86 instructions BT, SHL, SHR don't require masking */
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) || defined(ZEND_WIN32)
|
||||
# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> (bit)) & 1)
|
||||
#else
|
||||
# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
|
||||
#endif
|
||||
|
||||
/* We always define a function, even if there's a macro or expression we could
|
||||
* alias, so that using it in contexts where we can't make function calls
|
||||
@@ -573,7 +577,7 @@ static zend_always_inline double _zend_get_nan(void) /* {{{ */
|
||||
# define ZEND_INTRIN_SSSE3_FUNC_DECL(func)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SSE4_2_DEF) || (defined(ZEND_WIN32) && defined(__SSE4_2__))
|
||||
#ifdef __SSE4_2__
|
||||
/* Instructions compiled directly. */
|
||||
# define ZEND_INTRIN_SSE4_2_NATIVE 1
|
||||
#elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2)) || defined(ZEND_WIN32)
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ void zend_signal_init(void) /* {{{ */
|
||||
|
||||
/* {{{ zend_signal_startup
|
||||
* alloc zend signal globals */
|
||||
ZEND_API void zend_signal_startup(void)
|
||||
void zend_signal_startup(void)
|
||||
{
|
||||
|
||||
#ifdef ZTS
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ ZEND_API void zend_signal_handler_unblock(void);
|
||||
void zend_signal_activate(void);
|
||||
void zend_signal_deactivate(void);
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_signal_startup(void);
|
||||
void zend_signal_startup(void);
|
||||
END_EXTERN_C()
|
||||
void zend_signal_init(void);
|
||||
|
||||
|
||||
@@ -155,12 +155,7 @@ ZEND_API void ZEND_FASTCALL _smart_string_alloc(smart_string *str, size_t len)
|
||||
str->c = emalloc(SMART_STRING_START_LEN + 1);
|
||||
} else {
|
||||
str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_OVERHEAD, SMART_STRING_PAGE) - SMART_STRING_OVERHEAD;
|
||||
if (EXPECTED(str->a < (ZEND_MM_CHUNK_SIZE - SMART_STRING_OVERHEAD))) {
|
||||
str->c = emalloc_large(str->a + 1);
|
||||
} else {
|
||||
/* allocate a huge chunk */
|
||||
str->c = emalloc(str->a + 1);
|
||||
}
|
||||
str->c = emalloc_large(str->a + 1);
|
||||
}
|
||||
} else {
|
||||
if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) {
|
||||
|
||||
+1
-15
@@ -234,13 +234,7 @@ static zend_string* ZEND_FASTCALL zend_new_interned_string_request(zend_string *
|
||||
}
|
||||
|
||||
/* Create a short living interned, freed after the request. */
|
||||
#if ZEND_RC_DEBUG
|
||||
if (zend_rc_debug) {
|
||||
/* PHP shouldn't create persistent interned string during request,
|
||||
* but at least dl() may do this */
|
||||
ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT));
|
||||
}
|
||||
#endif
|
||||
ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT));
|
||||
if (GC_REFCOUNT(str) > 1) {
|
||||
zend_ulong h = ZSTR_H(str);
|
||||
zend_string_delref(str);
|
||||
@@ -263,7 +257,6 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_permanent(const char
|
||||
return ret;
|
||||
}
|
||||
|
||||
ZEND_ASSERT(permanent);
|
||||
ret = zend_string_init(str, size, permanent);
|
||||
ZSTR_H(ret) = h;
|
||||
return zend_add_interned_string(ret, &interned_strings_permanent, IS_STR_PERMANENT);
|
||||
@@ -285,13 +278,6 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_request(const char *
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ZEND_RC_DEBUG
|
||||
if (zend_rc_debug) {
|
||||
/* PHP shouldn't create persistent interned string during request,
|
||||
* but at least dl() may do this */
|
||||
ZEND_ASSERT(!permanent);
|
||||
}
|
||||
#endif
|
||||
ret = zend_string_init(str, size, permanent);
|
||||
ZSTR_H(ret) = h;
|
||||
|
||||
|
||||
+55
-1
@@ -764,7 +764,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
|
||||
if (i == len ||
|
||||
(i + 1 == len && path[i] == '.')) {
|
||||
/* remove double slashes and '.' */
|
||||
len = EXPECTED(i > 0) ? i - 1 : 0;
|
||||
len = i - 1;
|
||||
is_dir = 1;
|
||||
continue;
|
||||
} else if (i + 2 == len && path[i] == '.' && path[i+1] == '.') {
|
||||
@@ -1207,6 +1207,40 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
static size_t tsrm_win32_realpath_quick(char *path, size_t len, time_t *t) /* {{{ */
|
||||
{
|
||||
char tmp_resolved_path[MAXPATHLEN];
|
||||
int tmp_resolved_path_len;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
realpath_cache_bucket *bucket;
|
||||
|
||||
if (!*t) {
|
||||
*t = time(0);
|
||||
}
|
||||
|
||||
if (CWDG(realpath_cache_size_limit) && (bucket = realpath_cache_find(path, len, *t)) != NULL) {
|
||||
memcpy(path, bucket->realpath, bucket->realpath_len + 1);
|
||||
return bucket->realpath_len;
|
||||
}
|
||||
|
||||
if (!php_win32_ioutil_realpath_ex0(path, tmp_resolved_path, &info)) {
|
||||
DWORD err = GetLastError();
|
||||
SET_ERRNO_FROM_WIN32_CODE(err);
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
tmp_resolved_path_len = strlen(tmp_resolved_path);
|
||||
if (CWDG(realpath_cache_size_limit)) {
|
||||
realpath_cache_add(path, len, tmp_resolved_path, tmp_resolved_path_len, info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY, *t);
|
||||
}
|
||||
memmove(path, tmp_resolved_path, tmp_resolved_path_len + 1);
|
||||
|
||||
return tmp_resolved_path_len;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
/* Resolve path relatively to state and put the real path into state */
|
||||
/* returns 0 for ok, 1 for error */
|
||||
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) /* {{{ */
|
||||
@@ -1334,7 +1368,27 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
|
||||
add_slash = (use_realpath != CWD_REALPATH) && path_length > 0 && IS_SLASH(resolved_path[path_length-1]);
|
||||
t = CWDG(realpath_cache_ttl) ? 0 : -1;
|
||||
#ifdef ZEND_WIN32
|
||||
if (CWD_EXPAND != use_realpath) {
|
||||
size_t tmp_len = tsrm_win32_realpath_quick(resolved_path, path_length, &t);
|
||||
if ((size_t)-1 != tmp_len) {
|
||||
path_length = tmp_len;
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
/* The access denied error can mean something completely else,
|
||||
fallback to complicated way. */
|
||||
if (CWD_REALPATH == use_realpath && ERROR_ACCESS_DENIED != err) {
|
||||
SET_ERRNO_FROM_WIN32_CODE(err);
|
||||
return 1;
|
||||
}
|
||||
path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL);
|
||||
}
|
||||
} else {
|
||||
path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL);
|
||||
}
|
||||
#else
|
||||
path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL);
|
||||
#endif
|
||||
|
||||
if (path_length == (size_t)-1) {
|
||||
errno = ENOENT;
|
||||
|
||||
+4
-7
@@ -3099,10 +3099,6 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -3447,10 +3443,11 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
|
||||
|
||||
fbc = CACHED_PTR(opline->result.num);
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
func_name = (zval *)RT_CONSTANT(opline, opline->op2);
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 1), 1);
|
||||
func_name = RT_CONSTANT(opline, opline->op2) + 1;
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1);
|
||||
if (func == NULL) {
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 2), 1);
|
||||
func_name++;
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1);
|
||||
if (UNEXPECTED(func == NULL)) {
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper, function_name, func_name);
|
||||
}
|
||||
|
||||
+4
-51
@@ -2153,10 +2153,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
|
||||
|
||||
fbc = CACHED_PTR(opline->result.num);
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
func_name = (zval *)RT_CONSTANT(opline, opline->op2);
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 1), 1);
|
||||
func_name = RT_CONSTANT(opline, opline->op2) + 1;
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1);
|
||||
if (func == NULL) {
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name + 2), 1);
|
||||
func_name++;
|
||||
func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1);
|
||||
if (UNEXPECTED(func == NULL)) {
|
||||
ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(func_name ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
|
||||
}
|
||||
@@ -5148,10 +5149,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -7329,10 +7326,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -10429,10 +10422,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -14161,10 +14150,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -15775,10 +15760,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -17656,10 +17637,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -32105,10 +32082,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -33840,10 +33813,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -36219,10 +36188,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -41244,10 +41209,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -45011,10 +44972,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
@@ -50813,10 +50770,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
|
||||
/* Reset "object" to trigger reference counting */
|
||||
object = NULL;
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
|
||||
+10
-13
@@ -992,7 +992,7 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_sp
|
||||
}
|
||||
|
||||
/* Remove unused free_op1 and free_op2 declarations */
|
||||
if ($spec && preg_match_all('/^\s*zend_free_op\s+[^;]+;\s*$/m', $code, $matches, PREG_SET_ORDER)) {
|
||||
if ($spec && preg_match_all('/^\s*zend_free_op\s+[^;]+;\s*$/me', $code, $matches, PREG_SET_ORDER)) {
|
||||
$n = 0;
|
||||
foreach ($matches as $match) {
|
||||
$code = preg_replace('/'.preg_quote($match[0],'/').'/', "\$D$n", $code);
|
||||
@@ -1757,7 +1757,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
|
||||
gen_null_handler($f);
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,"default: ZEND_NULL_LABEL:\n");
|
||||
out($f,"default:\n");
|
||||
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
|
||||
out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
|
||||
break;
|
||||
@@ -2069,7 +2069,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
||||
$prolog = $m[1];
|
||||
out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
|
||||
out($f,$prolog."\tstatic const void * const labels[] = {\n");
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
|
||||
gen_labels($f, $spec, ZEND_VM_KIND_GOTO, $prolog."\t\t", $specs);
|
||||
out($f,$prolog."\t};\n");
|
||||
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
|
||||
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
@@ -2184,7 +2184,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
||||
out($f,$prolog.$executor_name."_ex(NULL);\n");
|
||||
} else {
|
||||
out($f,$prolog."static const void * const labels[] = {\n");
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
|
||||
gen_labels($f, $spec, ZEND_VM_KIND_CALL, $prolog."\t", $specs, $switch_labels);
|
||||
out($f,$prolog."};\n");
|
||||
out($f,$prolog."static const uint32_t specs[] = {\n");
|
||||
gen_specs($f, $prolog."\t", $specs);
|
||||
@@ -2528,15 +2528,13 @@ function gen_vm($def, $skel) {
|
||||
|
||||
// Search for opcode handlers those are used by other opcode handlers
|
||||
foreach ($opcodes as $dsc) {
|
||||
if (preg_match_all("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $mm, PREG_SET_ORDER)) {
|
||||
foreach ($mm as $m) {
|
||||
$op = $m[1];
|
||||
if (!isset($opnames[$op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
|
||||
}
|
||||
$code = $opnames[$op];
|
||||
$opcodes[$code]['use'] = 1;
|
||||
if (preg_match("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $m)) {
|
||||
$op = $m[1];
|
||||
if (!isset($opnames[$op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
|
||||
}
|
||||
$code = $opnames[$op];
|
||||
$opcodes[$code]['use'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2673,7 +2671,6 @@ function gen_vm($def, $skel) {
|
||||
|
||||
// Generate specialized executor
|
||||
gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_vm_init");
|
||||
out($f, "\n");
|
||||
|
||||
// Generate zend_vm_get_opcode_handler() function
|
||||
out($f, "static const void* ZEND_FASTCALL zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* op)\n");
|
||||
|
||||
+45
-75
@@ -833,11 +833,15 @@ dnl from object_var in build-dir.
|
||||
dnl
|
||||
AC_DEFUN([PHP_SHARED_MODULE],[
|
||||
install_modules="install-modules"
|
||||
suffix=la
|
||||
|
||||
case $host_alias in
|
||||
*aix*[)]
|
||||
additional_flags="-Wl,-G"
|
||||
suffix=so
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -Wl,-G -o '$3'/$1.la -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD) && mv -f '$3'/.libs/$1.so '$3'/$1.so'
|
||||
;;
|
||||
*[)]
|
||||
suffix=la
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o [$]@ -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)'
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -852,7 +856,7 @@ AC_DEFUN([PHP_SHARED_MODULE],[
|
||||
\$(LIBTOOL) --mode=install cp $3/$1.$suffix \$(phplibdir)
|
||||
|
||||
$3/$1.$suffix: \$($2) \$(translit($1,a-z_-,A-Z__)_SHARED_DEPENDENCIES)
|
||||
\$(LIBTOOL) --mode=link ifelse($4,,[\$(CC)],[\$(CXX)]) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) $additional_flags -o [\$]@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$($2) \$(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)
|
||||
$link_cmd
|
||||
|
||||
EOF
|
||||
])
|
||||
@@ -968,7 +972,7 @@ dnl ---------------------------------------------- Shared module
|
||||
dnl ---------------------------------------------- CLI static module
|
||||
[PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
|
||||
case "$PHP_SAPI" in
|
||||
cgi|embed|phpdbg[)]
|
||||
cgi|embed[)]
|
||||
PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
|
||||
EXT_STATIC="$EXT_STATIC $1;$ext_dir"
|
||||
;;
|
||||
@@ -2169,84 +2173,50 @@ AC_DEFUN([PHP_SETUP_ICU],[
|
||||
PHP_ICU_DIR=DEFAULT
|
||||
fi
|
||||
|
||||
if test "$PHP_ICU_DIR" = "DEFAULT"; then
|
||||
dnl Try to find icu-config
|
||||
AC_PATH_PROG(ICU_CONFIG, icu-config, no, [$PATH:/usr/local/bin])
|
||||
else
|
||||
ICU_CONFIG="$PHP_ICU_DIR/bin/icu-config"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for location of ICU headers and libraries])
|
||||
found_icu=no
|
||||
|
||||
dnl First try to find pkg-config
|
||||
if test -z "$PKG_CONFIG"; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
fi
|
||||
dnl Trust icu-config to know better what the install prefix is..
|
||||
icu_install_prefix=`$ICU_CONFIG --prefix 2> /dev/null`
|
||||
if test "$?" != "0" || test -z "$icu_install_prefix"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Unable to detect ICU prefix or $ICU_CONFIG failed. Please verify ICU install prefix and make sure icu-config works.])
|
||||
else
|
||||
AC_MSG_RESULT([$icu_install_prefix])
|
||||
|
||||
dnl If pkg-config is found try using it
|
||||
if test "$PHP_ICU_DIR" = "DEFAULT" && test -x "$PKG_CONFIG" && $PKG_CONFIG --exists icu-uc icu-io icu-i18n; then
|
||||
if $PKG_CONFIG --atleast-version=40 icu-uc; then
|
||||
found_icu=yes
|
||||
icu_version_full=`$PKG_CONFIG --modversion icu-uc`
|
||||
ac_IFS=$IFS
|
||||
IFS="."
|
||||
set $icu_version_full
|
||||
IFS=$ac_IFS
|
||||
icu_version=`expr [$]1 \* 1000 + [$]2`
|
||||
AC_MSG_RESULT([found $icu_version_full])
|
||||
dnl Check ICU version
|
||||
AC_MSG_CHECKING([for ICU 4.0 or greater])
|
||||
icu_version_full=`$ICU_CONFIG --version`
|
||||
ac_IFS=$IFS
|
||||
IFS="."
|
||||
set $icu_version_full
|
||||
IFS=$ac_IFS
|
||||
icu_version=`expr [$]1 \* 1000 + [$]2`
|
||||
AC_MSG_RESULT([found $icu_version_full])
|
||||
|
||||
ICU_LIBS=`$PKG_CONFIG --libs icu-uc icu-io icu-i18n`
|
||||
ICU_INCS=`$PKG_CONFIG --cflags-only-I icu-uc icu-io icu-i18n`
|
||||
ICU_CXXFLAGS="-DU_USING_ICU_NAMESPACE=1"
|
||||
|
||||
AC_MSG_RESULT([found $ICU_VERSION])
|
||||
|
||||
PHP_EVAL_LIBLINE($ICU_LIBS, $1)
|
||||
PHP_EVAL_INCLINE($ICU_INCS)
|
||||
else
|
||||
AC_MSG_ERROR([ICU version 4.0 or later required.])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl If pkg-config fails for some reason, revert to the old method
|
||||
if test "$found_icu" = "no"; then
|
||||
if test "$PHP_ICU_DIR" = "DEFAULT"; then
|
||||
dnl Try to find icu-config
|
||||
AC_PATH_PROG(ICU_CONFIG, icu-config, no, [$PATH:/usr/local/bin])
|
||||
else
|
||||
ICU_CONFIG="$PHP_ICU_DIR/bin/icu-config"
|
||||
if test "$icu_version" -lt "4000"; then
|
||||
AC_MSG_ERROR([ICU version 4.0 or later is required])
|
||||
fi
|
||||
|
||||
dnl Trust icu-config to know better what the install prefix is..
|
||||
icu_install_prefix=`$ICU_CONFIG --prefix 2> /dev/null`
|
||||
if test "$?" != "0" || test -z "$icu_install_prefix"; then
|
||||
AC_MSG_RESULT([not found])
|
||||
AC_MSG_ERROR([Unable to detect ICU prefix or $ICU_CONFIG failed. Please verify ICU install prefix and make sure icu-config works.])
|
||||
else
|
||||
AC_MSG_RESULT([$icu_install_prefix])
|
||||
ICU_VERSION=$icu_version
|
||||
ICU_INCS=`$ICU_CONFIG --cppflags-searchpath`
|
||||
ICU_LIBS=`$ICU_CONFIG --ldflags --ldflags-icuio`
|
||||
PHP_EVAL_INCLINE($ICU_INCS)
|
||||
PHP_EVAL_LIBLINE($ICU_LIBS, $1)
|
||||
|
||||
dnl Check ICU version
|
||||
AC_MSG_CHECKING([for ICU 4.0 or greater])
|
||||
icu_version_full=`$ICU_CONFIG --version`
|
||||
ac_IFS=$IFS
|
||||
IFS="."
|
||||
set $icu_version_full
|
||||
IFS=$ac_IFS
|
||||
icu_version=`expr [$]1 \* 1000 + [$]2`
|
||||
AC_MSG_RESULT([found $icu_version_full])
|
||||
|
||||
if test "$icu_version" -lt "4000"; then
|
||||
AC_MSG_ERROR([ICU version 4.0 or later is required])
|
||||
fi
|
||||
|
||||
ICU_VERSION=$icu_version
|
||||
ICU_INCS=`$ICU_CONFIG --cppflags-searchpath`
|
||||
ICU_LIBS=`$ICU_CONFIG --ldflags --ldflags-icuio`
|
||||
PHP_EVAL_INCLINE($ICU_INCS)
|
||||
PHP_EVAL_LIBLINE($ICU_LIBS, $1)
|
||||
|
||||
ICU_CXXFLAGS=`$ICU_CONFIG --cxxflags`
|
||||
if test "$icu_version" -ge "49000"; then
|
||||
ICU_CXXFLAGS="$ICU_CXXFLAGS -DUNISTR_FROM_CHAR_EXPLICIT=explicit -DUNISTR_FROM_STRING_EXPLICIT=explicit"
|
||||
ICU_CFLAGS="-DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
|
||||
fi
|
||||
if test "$icu_version" -ge "60000"; then
|
||||
ICU_CFLAGS="$ICU_CFLAGS -DU_HIDE_OBSOLETE_UTF_OLD_H=1"
|
||||
fi
|
||||
ICU_CXXFLAGS=`$ICU_CONFIG --cxxflags`
|
||||
if test "$icu_version" -ge "49000"; then
|
||||
ICU_CXXFLAGS="$ICU_CXXFLAGS -DUNISTR_FROM_CHAR_EXPLICIT=explicit -DUNISTR_FROM_STRING_EXPLICIT=explicit"
|
||||
ICU_CFLAGS="-DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
|
||||
fi
|
||||
if test "$icu_version" -ge "60000"; then
|
||||
ICU_CFLAGS="$ICU_CFLAGS -DU_HIDE_OBSOLETE_UTF_OLD_H=1"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
|
||||
set SDK_REMOTE=https://github.com/Microsoft/php-sdk-binary-tools.git
|
||||
set SDK_REMOTE=https://github.com/OSTC/php-sdk-binary-tools.git
|
||||
set SDK_BRANCH=%PHP_BUILD_SDK_BRANCH%
|
||||
set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ if /i "%APPVEYOR_REPO_BRANCH:~0,4%" equ "php-" (
|
||||
set BRANCH=master
|
||||
)
|
||||
set STABILITY=staging
|
||||
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VS%-%PHP_SDK_ARCH%
|
||||
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VC%-%PHP_SDK_ARCH%
|
||||
rem SDK is cached, deps info is cached as well
|
||||
echo Updating dependencies in %DEPS_DIR%
|
||||
cmd /c phpsdk_deps --update --no-backup --branch %BRANCH% --stability %STABILITY% --deps %DEPS_DIR% --crt %PHP_BUILD_CRT%
|
||||
|
||||
@@ -11,7 +11,7 @@ if /i "%APPVEYOR_REPO_BRANCH:~0,4%" equ "php-" (
|
||||
set BRANCH=master
|
||||
set STABILITY=staging
|
||||
)
|
||||
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VS%-%PHP_SDK_ARCH%
|
||||
set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%BRANCH%-%PHP_SDK_VC%-%PHP_SDK_ARCH%
|
||||
if not exist "%DEPS_DIR%" (
|
||||
echo "%DEPS_DIR%" doesn't exist
|
||||
exit /b 3
|
||||
@@ -27,7 +27,7 @@ set PDO_MYSQL_TEST_USER=%MYSQL_TEST_USER%
|
||||
set PDO_MYSQL_TEST_PASS=%MYSQL_PWD%
|
||||
set PDO_MYSQL_TEST_HOST=%MYSQL_TEST_HOST%
|
||||
set PDO_MYSQL_TEST_PORT=%MYSQL_TEST_PORT%
|
||||
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST%;port=%PDO_MYSQL_TEST_PORT%;dbname=test;user=%PDO_MYSQL_TEST_USER%;password=%MYSQL_PW%
|
||||
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST% port=%PDO_MYSQL_TEST_PORT% dbname=test user=%PDO_MYSQL_TEST_USER% password=%MYSQL_PW%
|
||||
"C:\Program Files\MySql\MySQL Server 5.7\bin\mysql.exe" --user=%MYSQL_TEST_USER% -e "CREATE DATABASE IF NOT EXISTS test"
|
||||
if %errorlevel% neq 0 exit /b 3
|
||||
|
||||
@@ -58,7 +58,7 @@ rem set OPENSSL_CONF=
|
||||
rem set SSLEAY_CONF=
|
||||
|
||||
rem prepare for Opcache
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enabled=1 -d opcache.enable_cli=1
|
||||
|
||||
rem prepare for enchant
|
||||
mkdir c:\enchant_plugins
|
||||
|
||||
+3
-24
@@ -107,8 +107,8 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
|
||||
PHP_MAJOR_VERSION=7
|
||||
PHP_MINOR_VERSION=3
|
||||
PHP_RELEASE_VERSION=7
|
||||
PHP_EXTRA_VERSION="RC2"
|
||||
PHP_RELEASE_VERSION=0
|
||||
PHP_EXTRA_VERSION=""
|
||||
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`
|
||||
|
||||
@@ -565,24 +565,6 @@ PHP_CHECK_CPU_SUPPORTS([sse4.2])
|
||||
PHP_CHECK_CPU_SUPPORTS([avx])
|
||||
PHP_CHECK_CPU_SUPPORTS([avx2])
|
||||
|
||||
dnl The ABI of php_addslashes in PHP 7.3 is dependent on __SSE4_2__,
|
||||
dnl which depends on target attributes. Use this check to make sure that
|
||||
dnl SSE 4.2 availability during the PHP compilation is used, independently
|
||||
dnl of whether extensions are compiled with SSE 4.2 support.
|
||||
AC_MSG_CHECKING([whether __SSE4_2__ is defined])
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
int main() {
|
||||
#if defined(__SSE4_2__)
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_SSE4_2_DEF, 1, [Define if __SSE4_2__ has been defined])
|
||||
], [AC_MSG_RESULT([no])], [AC_MSG_RESULT([no])])
|
||||
|
||||
dnl Check for members of the stat structure
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev])
|
||||
dnl AC_STRUCT_ST_BLOCKS will screw QNX because fileblocks.o does not exist
|
||||
@@ -603,10 +585,7 @@ PHP_SOCKADDR_CHECKS
|
||||
|
||||
dnl Checks for GCC function attributes on all systems except ones without glibc
|
||||
dnl Fix for these systems is already included in GCC 7, but not on GCC 6
|
||||
dnl
|
||||
dnl At least some versions of FreeBSD seem to have buggy ifunc support, see
|
||||
dnl bug #77284. Conservatively don't use ifuncs on FreeBSD.
|
||||
AS_CASE([$host_alias], [*-*-*android*|*-*-*uclibc*|*-*-*musl*|*freebsd*], [true], [
|
||||
AS_CASE([$host_alias], [*-*-*android*|*-*-*uclibc*|*-*-*musl*], [true], [
|
||||
AX_GCC_FUNC_ATTRIBUTE([ifunc])
|
||||
AX_GCC_FUNC_ATTRIBUTE([target])
|
||||
])
|
||||
|
||||
@@ -54,19 +54,12 @@ bc_num2long (num)
|
||||
/* Extract the int value, ignore the fraction. */
|
||||
val = 0;
|
||||
nptr = num->n_value;
|
||||
for (index = num->n_len; index > 0; index--) {
|
||||
char n = *nptr++;
|
||||
for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--)
|
||||
val = val*BASE + *nptr++;
|
||||
|
||||
if (val > LONG_MAX/BASE) {
|
||||
return 0;
|
||||
}
|
||||
val *= BASE;
|
||||
|
||||
if (val > LONG_MAX - n) {
|
||||
return 0;
|
||||
}
|
||||
val += n;
|
||||
}
|
||||
/* Check for overflow. If overflow, return zero. */
|
||||
if (index>0) val = 0;
|
||||
if (val < 0) val = 0;
|
||||
|
||||
/* Return the value. */
|
||||
if (num->n_sign == PLUS)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "php_com_dotnet.h"
|
||||
#include "php_com_dotnet_internal.h"
|
||||
#include "Zend/zend_exceptions.h"
|
||||
#include "Zend/zend_interfaces.h"
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(com_dotnet)
|
||||
static PHP_GINIT_FUNCTION(com_dotnet);
|
||||
@@ -311,15 +310,11 @@ PHP_MINIT_FUNCTION(com_dotnet)
|
||||
ce.create_object = php_com_object_new;
|
||||
php_com_variant_class_entry = zend_register_internal_class(&ce);
|
||||
php_com_variant_class_entry->get_iterator = php_com_iter_get;
|
||||
php_com_variant_class_entry->serialize = zend_class_serialize_deny;
|
||||
php_com_variant_class_entry->unserialize = zend_class_unserialize_deny;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "com", NULL);
|
||||
ce.create_object = php_com_object_new;
|
||||
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry);
|
||||
tmp->get_iterator = php_com_iter_get;
|
||||
tmp->serialize = zend_class_serialize_deny;
|
||||
tmp->unserialize = zend_class_unserialize_deny;
|
||||
|
||||
zend_ts_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 1);
|
||||
|
||||
@@ -328,8 +323,6 @@ PHP_MINIT_FUNCTION(com_dotnet)
|
||||
ce.create_object = php_com_object_new;
|
||||
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry);
|
||||
tmp->get_iterator = php_com_iter_get;
|
||||
tmp->serialize = zend_class_serialize_deny;
|
||||
tmp->unserialize = zend_class_unserialize_deny;
|
||||
#endif
|
||||
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
@@ -229,7 +229,7 @@ static HashTable *com_properties_get(zval *object)
|
||||
* infinite recursion when the hash is displayed via var_dump().
|
||||
* Perhaps it is best to leave it un-implemented.
|
||||
*/
|
||||
return &zend_empty_array;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void function_dtor(zval *zv)
|
||||
|
||||
@@ -184,7 +184,7 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa
|
||||
}
|
||||
|
||||
const_name = php_com_olestring_to_string(bstr_ids, &len, codepage);
|
||||
c.name = zend_string_init(const_name, len, mode & CONST_PERSISTENT);
|
||||
c.name = zend_string_init(const_name, len, 1);
|
||||
// TODO: avoid reallocation???
|
||||
efree(const_name);
|
||||
if(c.name == NULL) {
|
||||
@@ -195,17 +195,17 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa
|
||||
SysFreeString(bstr_ids);
|
||||
|
||||
/* sanity check for the case where the constant is already defined */
|
||||
php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage);
|
||||
if ((exists = zend_get_constant(c.name)) != NULL) {
|
||||
if (COMG(autoreg_verbose) && !compare_function(&results, &value, exists)) {
|
||||
php_error_docref(NULL, E_WARNING, "Type library constant %s is already defined", ZSTR_VAL(c.name));
|
||||
if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, exists)) {
|
||||
php_error_docref(NULL, E_WARNING, "Type library constant %s is already defined", c.name);
|
||||
}
|
||||
zend_string_release_ex(c.name, mode & CONST_PERSISTENT);
|
||||
zend_string_release_ex(c.name, 1);
|
||||
ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* register the constant */
|
||||
php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage);
|
||||
if (Z_TYPE(value) == IS_LONG) {
|
||||
ZEND_CONSTANT_SET_FLAGS(&c, mode, 0);
|
||||
ZVAL_LONG(&c.value, Z_LVAL(value));
|
||||
@@ -222,8 +222,8 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa
|
||||
/* Type-library stuff */
|
||||
void php_com_typelibrary_dtor(zval *pDest)
|
||||
{
|
||||
ITypeLib *Lib = (ITypeLib*)Z_PTR_P(pDest);
|
||||
ITypeLib_Release(Lib);
|
||||
ITypeLib **Lib = (ITypeLib**)Z_PTR_P(pDest);
|
||||
ITypeLib_Release(*Lib);
|
||||
}
|
||||
|
||||
PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77177 (Serializing or unserializing COM objects crashes)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$com = new COM("WScript.Shell");
|
||||
$dotnet = new DOTNET("mscorlib", "System.Collections.Stack");
|
||||
$variant = new VARIANT;
|
||||
foreach ([$com, $dotnet, $variant] as $object) {
|
||||
try {
|
||||
serialize($object);
|
||||
} catch (Exception $ex) {
|
||||
echo "Exception: {$ex->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
|
||||
$strings = ['C:3:"com":0:{}', 'C:6:"dotnet":0:{}', 'C:7:"variant":0:{}'];
|
||||
foreach ($strings as $string) {
|
||||
try {
|
||||
unserialize($string);
|
||||
} catch (Exception $ex) {
|
||||
echo "Exception: {$ex->getMessage()}\n";
|
||||
}
|
||||
}
|
||||
|
||||
$strings = ['O:3:"com":0:{}', 'O:6:"dotnet":0:{}', 'O:7:"variant":0:{}'];
|
||||
foreach ($strings as $string) {
|
||||
var_dump(unserialize($string));
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Exception: Serialization of 'com' is not allowed
|
||||
Exception: Serialization of 'dotnet' is not allowed
|
||||
Exception: Serialization of 'variant' is not allowed
|
||||
Exception: Unserialization of 'com' is not allowed
|
||||
Exception: Unserialization of 'dotnet' is not allowed
|
||||
Exception: Unserialization of 'variant' is not allowed
|
||||
|
||||
Warning: Erroneous data format for unserializing 'com' in %s on line %d
|
||||
|
||||
Notice: unserialize(): Error at offset 13 of 14 bytes in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Erroneous data format for unserializing 'dotnet' in %s on line %d
|
||||
|
||||
Notice: unserialize(): Error at offset 16 of 17 bytes in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: Erroneous data format for unserializing 'variant' in %s on line %d
|
||||
|
||||
Notice: unserialize(): Error at offset 17 of 18 bytes in %s on line %d
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77578 (Crash when php unload)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
// To actually be able to verify the crash during shutdown on Windows, we have
|
||||
// to execute a PHP subprocess, and check its exit status.
|
||||
$php = PHP_BINARY;
|
||||
$ini = php_ini_loaded_file();
|
||||
$iniopt = $ini ? "-c $ini" : '';
|
||||
$command = "$php $iniopt -d com.autoregister_typelib=1 -r \"new COM('WbemScripting.SWbemLocator');\"";
|
||||
exec($command, $output, $status);
|
||||
var_dump($output, $status);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
int(0)
|
||||
===DONE===
|
||||
@@ -1,18 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77621 (Already defined constants are not properly reported)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
|
||||
?>
|
||||
--INI--
|
||||
com.autoregister_verbose=1
|
||||
--FILE--
|
||||
<?php
|
||||
define('ADSTYPE_INVALID', 0);
|
||||
$root = dirname(array_change_key_case($_SERVER, CASE_UPPER)['COMSPEC']);
|
||||
com_load_typelib("$root\activeds.tlb");
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Warning: com_load_typelib(): Type library constant ADSTYPE_INVALID is already defined in %s on line %d
|
||||
===DONE===
|
||||
+34
-19
@@ -1130,7 +1130,6 @@ PHP_MINIT_FUNCTION(curl)
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071306 /* Available since 7.19.6 */
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_CURLDEBUG);
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_SSH_KNOWNHOSTS);
|
||||
#endif
|
||||
|
||||
@@ -1335,7 +1334,6 @@ PHP_MINIT_FUNCTION(curl)
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x072f00 /* Available since 7.47.0 */
|
||||
REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2TLS);
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_PSL);
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
|
||||
@@ -1454,10 +1452,6 @@ PHP_MINIT_FUNCTION(curl)
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS);
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x074001 /* Available since 7.64.1 */
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_ALTSVC);
|
||||
#endif
|
||||
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
|
||||
|
||||
#ifdef PHP_CURL_NEED_OPENSSL_TSL
|
||||
@@ -3300,27 +3294,52 @@ PHP_FUNCTION(curl_getinfo)
|
||||
CAAS("scheme", s_code);
|
||||
}
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700 /* Available since 7.55.0 */
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("content_length_download", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("content_length_upload", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_DOWNLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("size_download", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_SIZE_UPLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("size_upload", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_DOWNLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("speed_download", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_SPEED_UPLOAD_T, &co) == CURLE_OK) {
|
||||
CAAL("speed_upload", co);
|
||||
}
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x073b00 /* Available since 7.59.0 */
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_FILETIME_T, &co) == CURLE_OK) {
|
||||
CAAL("filetime", co);
|
||||
}
|
||||
#endif
|
||||
#if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_APPCONNECT_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("appconnect_time_us", co);
|
||||
CAAL("appconnect_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_CONNECT_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("connect_time_us", co);
|
||||
CAAL("connect_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_NAMELOOKUP_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("namelookup_time_us", co);
|
||||
CAAL("namelookup_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_PRETRANSFER_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("pretransfer_time_us", co);
|
||||
CAAL("pretransfer_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("redirect_time_us", co);
|
||||
CAAL("redirect_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_STARTTRANSFER_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("starttransfer_time_us", co);
|
||||
CAAL("starttransfer_time", co);
|
||||
}
|
||||
if (curl_easy_getinfo(ch->cp, CURLINFO_TOTAL_TIME_T, &co) == CURLE_OK) {
|
||||
CAAL("total_time_us", co);
|
||||
CAAL("total_time", co);
|
||||
}
|
||||
#endif
|
||||
if (ch->header.str) {
|
||||
@@ -3435,12 +3454,8 @@ PHP_FUNCTION(curl_error)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (ch->err.no) {
|
||||
ch->err.str[CURL_ERROR_SIZE] = 0;
|
||||
RETURN_STRING(ch->err.str);
|
||||
} else {
|
||||
RETURN_EMPTY_STRING();
|
||||
}
|
||||
ch->err.str[CURL_ERROR_SIZE] = 0;
|
||||
RETURN_STRING(ch->err.str);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+6
-3
@@ -228,7 +228,7 @@ PHP_FUNCTION(curl_multi_select)
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071c00 /* Available since 7.28.0 */
|
||||
error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) (timeout * 1000.0), &numfds);
|
||||
error = curl_multi_wait(mh->multi, NULL, 0, (unsigned long) timeout * 1000.0, &numfds);
|
||||
if (CURLM_OK != error) {
|
||||
SAVE_CURLM_ERROR(mh, error);
|
||||
RETURN_LONG(-1);
|
||||
@@ -420,7 +420,6 @@ void _php_curl_multi_close(zend_resource *rsrc) /* {{{ */
|
||||
curl_multi_cleanup(mh->multi);
|
||||
zend_llist_clean(&mh->easyh);
|
||||
if (mh->handlers->server_push) {
|
||||
zval_ptr_dtor(&mh->handlers->server_push->func_name);
|
||||
efree(mh->handlers->server_push);
|
||||
}
|
||||
if (mh->handlers) {
|
||||
@@ -503,7 +502,6 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
|
||||
Z_ADDREF_P(pz_parent_ch);
|
||||
|
||||
res = zend_register_resource(ch, le_curl);
|
||||
ch->res = res;
|
||||
ZVAL_RES(&pz_ch, res);
|
||||
|
||||
size_t i;
|
||||
@@ -578,6 +576,11 @@ static int _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue,
|
||||
|
||||
ZVAL_COPY(&mh->handlers->server_push->func_name, zvalue);
|
||||
mh->handlers->server_push->method = PHP_CURL_USER;
|
||||
if (!Z_ISUNDEF(mh->handlers->server_push->func_name)) {
|
||||
zval_ptr_dtor(&mh->handlers->server_push->func_name);
|
||||
mh->handlers->server_push->fci_cache = empty_fcall_info_cache;
|
||||
|
||||
}
|
||||
error = curl_multi_setopt(mh->multi, option, _php_server_push_callback);
|
||||
if (error != CURLM_OK) {
|
||||
return 0;
|
||||
|
||||
@@ -17,8 +17,6 @@ const IGNORED_CONSTANTS = [
|
||||
'CURLOPT_PROGRESSDATA'
|
||||
];
|
||||
|
||||
const CONSTANTS_REGEX_PATTERN = '~^CURL(?:OPT|_VERSION)_[A-Z0-9_]+$~';
|
||||
|
||||
$curlConstants = getCurlConstants();
|
||||
$sourceConstants = getSourceConstants();
|
||||
|
||||
@@ -159,8 +157,13 @@ function getCurlConstants() : array
|
||||
$deprecated = $match[3] ?? null;
|
||||
$removed = $match[4] ?? null;
|
||||
|
||||
if (in_array($name, IGNORED_CONSTANTS, true) || !preg_match(CONSTANTS_REGEX_PATTERN, $name)) {
|
||||
// not a wanted constant
|
||||
if (strpos($name, 'CURLOPT_') !== 0) {
|
||||
// not a CURLOPT_* constant
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($name, IGNORED_CONSTANTS)) {
|
||||
// purposefully ignored constant
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -194,8 +197,8 @@ function getSourceConstants() : array
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!preg_match(CONSTANTS_REGEX_PATTERN, $name)) {
|
||||
// not a wanted constant
|
||||
if (strpos($name, 'CURLOPT_') !== 0) {
|
||||
// not a CURLOPT_* constant
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
--TEST--
|
||||
Request #72189 (Add missing CURL_VERSION_* constants)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
|
||||
include 'skipif.inc';
|
||||
|
||||
$version = curl_version();
|
||||
|
||||
if ($version['version_number'] < 0x071306) {
|
||||
exit('skip: test works only with curl >= 7.19.6');
|
||||
}
|
||||
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$version = curl_version();
|
||||
|
||||
$bitfields = [
|
||||
CURL_VERSION_ASYNCHDNS,
|
||||
CURL_VERSION_CONV,
|
||||
CURL_VERSION_CURLDEBUG,
|
||||
CURL_VERSION_DEBUG,
|
||||
CURL_VERSION_GSSNEGOTIATE,
|
||||
CURL_VERSION_IDN,
|
||||
CURL_VERSION_IPV6,
|
||||
CURL_VERSION_KERBEROS4,
|
||||
CURL_VERSION_LARGEFILE,
|
||||
CURL_VERSION_LIBZ,
|
||||
CURL_VERSION_NTLM,
|
||||
CURL_VERSION_SPNEGO,
|
||||
CURL_VERSION_SSL,
|
||||
CURL_VERSION_SSPI,
|
||||
];
|
||||
|
||||
$matchesCount = 0;
|
||||
|
||||
foreach ($bitfields as $feature) {
|
||||
if ($version['features'] & $feature) {
|
||||
++$matchesCount;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($matchesCount > 0);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -1,53 +0,0 @@
|
||||
--TEST--
|
||||
Bug #76675 (Segfault with H2 server push write/writeheader handlers)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include 'skipif.inc';
|
||||
if (getenv("SKIP_ONLINE_TESTS")) {
|
||||
die("skip online test");
|
||||
}
|
||||
$curl_version = curl_version();
|
||||
if ($curl_version['version_number'] < 0x073d00) {
|
||||
exit("skip: test may crash with curl < 7.61.0");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$transfers = 1;
|
||||
$callback = function($parent, $passed) use (&$transfers) {
|
||||
curl_setopt($passed, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
|
||||
echo "Received ".strlen($data);
|
||||
return strlen($data);
|
||||
});
|
||||
$transfers++;
|
||||
return CURL_PUSH_OK;
|
||||
};
|
||||
$mh = curl_multi_init();
|
||||
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback);
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, 'https://http2.golang.org/serverpush');
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
$active = null;
|
||||
do {
|
||||
$status = curl_multi_exec($mh, $active);
|
||||
do {
|
||||
$info = curl_multi_info_read($mh);
|
||||
if (false !== $info && $info['msg'] == CURLMSG_DONE) {
|
||||
$handle = $info['handle'];
|
||||
if ($handle !== null) {
|
||||
$transfers--;
|
||||
curl_multi_remove_handle($mh, $handle);
|
||||
curl_close($handle);
|
||||
}
|
||||
}
|
||||
} while ($info);
|
||||
} while ($transfers);
|
||||
curl_multi_close($mh);
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
(Received \d+)+
|
||||
@@ -1,77 +0,0 @@
|
||||
--TEST--
|
||||
Bug #77535 (Invalid callback, h2 server push)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include 'skipif.inc';
|
||||
if (getenv("SKIP_ONLINE_TESTS")) {
|
||||
die("skip online test");
|
||||
}
|
||||
$curl_version = curl_version();
|
||||
if ($curl_version['version_number'] < 0x073d00) {
|
||||
exit("skip: test may crash with curl < 7.61.0");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class MyHttpClient
|
||||
{
|
||||
private $mh;
|
||||
private $curl;
|
||||
|
||||
public function sendRequest()
|
||||
{
|
||||
if (false === $this->mh = curl_multi_init()) {
|
||||
throw new \RuntimeException('Unable to create a new cURL multi handle');
|
||||
}
|
||||
|
||||
$this->addServerPushCallback();
|
||||
|
||||
$this->curl = curl_init();
|
||||
curl_setopt($this->curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
curl_setopt($this->curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
curl_setopt($this->curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, false);
|
||||
curl_setopt($this->curl, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($this->curl, CURLOPT_URL, 'https://http2.golang.org/serverpush');
|
||||
curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, function ($ch, $data) {
|
||||
return \strlen($data);
|
||||
});
|
||||
curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
|
||||
return \strlen($data);
|
||||
});
|
||||
curl_multi_add_handle($this->mh, $this->curl);
|
||||
|
||||
$stillRunning = null;
|
||||
while (true) {
|
||||
do {
|
||||
$mrc = curl_multi_exec($this->mh, $stillRunning);
|
||||
} while (CURLM_CALL_MULTI_PERFORM === $mrc);
|
||||
|
||||
$info = curl_multi_info_read($this->mh);
|
||||
while (false !== $info && $info['msg'] == CURLMSG_DONE) {
|
||||
if (CURLMSG_DONE !== $info['msg']) {
|
||||
continue;
|
||||
}
|
||||
die("Start handle request.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addServerPushCallback(): void
|
||||
{
|
||||
|
||||
$callback = static function () {
|
||||
return CURL_PUSH_OK;
|
||||
};
|
||||
|
||||
curl_multi_setopt($this->mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt($this->mh, CURLMOPT_PUSHFUNCTION, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
$buzz = new MyHttpClient();
|
||||
$buzz->sendRequest();
|
||||
--EXPECT--
|
||||
Start handle request.
|
||||
|
||||
@@ -43,12 +43,12 @@ TLS-SRP => No
|
||||
HTTP2 => Yes
|
||||
GSSAPI => No
|
||||
KERBEROS5 => Yes
|
||||
UNIX_SOCKETS => %r(Yes|No)%r
|
||||
UNIX_SOCKETS => No
|
||||
PSL => No
|
||||
HTTPS_PROXY => Yes
|
||||
MULTI_SSL => %s
|
||||
BROTLI => %s
|
||||
Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
|
||||
Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
|
||||
Host => %s-pc-win32
|
||||
SSL Version => OpenSSL/%s
|
||||
ZLib Version => %s
|
||||
|
||||
@@ -18,6 +18,6 @@ curl_close($ch);
|
||||
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
string\(\d+\) "([^\r\n]*rotocol[^\r\n]+|Could not resolve host: .+)"
|
||||
int\(\d\)
|
||||
--EXPECTF--
|
||||
string(%d) "%Srotocol%s"
|
||||
int(1)
|
||||
@@ -26,5 +26,5 @@ curl_close($ch);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:|Could not resolve:|Unsupported proxy syntax in)%r %s"
|
||||
string(%d) "%r(Couldn't resolve proxy|Could not resolve proxy:|Could not resolve host:|Could not resolve:)%r %s"
|
||||
int(5)
|
||||
+2
-8
@@ -1,13 +1,7 @@
|
||||
dnl config.m4 for date extension
|
||||
|
||||
dnl Check for headers needed by timelib
|
||||
AC_CHECK_HEADERS([ \
|
||||
strings.h \
|
||||
io.h
|
||||
])
|
||||
|
||||
dnl Check for strtoll, atoll
|
||||
AC_CHECK_FUNCS(strtoll atoll)
|
||||
sinclude(ext/date/lib/timelib.m4)
|
||||
sinclude(lib/timelib.m4)
|
||||
|
||||
PHP_DATE_CFLAGS="-I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1"
|
||||
timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c
|
||||
|
||||
+128
-165
@@ -51,37 +51,17 @@ static inline uint32_t timelib_conv_int_unsigned(uint32_t value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline uint64_t timelib_conv_int64_unsigned(uint64_t value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
static inline uint32_t timelib_conv_int_unsigned(uint32_t value)
|
||||
{
|
||||
return
|
||||
((value & 0x000000ff) << 24) +
|
||||
((value & 0x0000ff00) << 8) +
|
||||
((value & 0x00ff0000) >> 8) +
|
||||
return ((value & 0x000000ff) << 24) +
|
||||
((value & 0x0000ff00) << 8) +
|
||||
((value & 0x00ff0000) >> 8) +
|
||||
((value & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
static inline uint64_t timelib_conv_int64_unsigned(uint64_t value)
|
||||
{
|
||||
return
|
||||
((value & 0x00000000000000ff) << 56) +
|
||||
((value & 0x000000000000ff00) << 40) +
|
||||
((value & 0x0000000000ff0000) << 24) +
|
||||
((value & 0x00000000ff000000) << 8) +
|
||||
((value & 0x000000ff00000000) >> 8) +
|
||||
((value & 0x0000ff0000000000) >> 24) +
|
||||
((value & 0x00ff000000000000) >> 40) +
|
||||
((value & 0xff00000000000000) >> 56);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define timelib_conv_int_signed(value) ((int32_t) timelib_conv_int_unsigned((int32_t) value))
|
||||
#define timelib_conv_int64_signed(value) ((int64_t) timelib_conv_int64_unsigned((int64_t) value))
|
||||
|
||||
static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
@@ -152,49 +132,56 @@ static int read_preamble(const unsigned char **tzf, timelib_tzinfo *tz, unsigned
|
||||
}
|
||||
}
|
||||
|
||||
static void read_32bit_header(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
static void read_header(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
uint32_t buffer[6];
|
||||
|
||||
memcpy(&buffer, *tzf, sizeof(buffer));
|
||||
tz->_bit32.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]);
|
||||
tz->_bit32.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]);
|
||||
tz->_bit32.leapcnt = timelib_conv_int_unsigned(buffer[2]);
|
||||
tz->_bit32.timecnt = timelib_conv_int_unsigned(buffer[3]);
|
||||
tz->_bit32.typecnt = timelib_conv_int_unsigned(buffer[4]);
|
||||
tz->_bit32.charcnt = timelib_conv_int_unsigned(buffer[5]);
|
||||
|
||||
tz->bit32.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]);
|
||||
tz->bit32.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]);
|
||||
tz->bit32.leapcnt = timelib_conv_int_unsigned(buffer[2]);
|
||||
tz->bit32.timecnt = timelib_conv_int_unsigned(buffer[3]);
|
||||
tz->bit32.typecnt = timelib_conv_int_unsigned(buffer[4]);
|
||||
tz->bit32.charcnt = timelib_conv_int_unsigned(buffer[5]);
|
||||
*tzf += sizeof(buffer);
|
||||
}
|
||||
|
||||
static int read_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
static void skip_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
int64_t *buffer = NULL;
|
||||
if (tz->bit64.timecnt) {
|
||||
*tzf += (sizeof(int64_t) * tz->bit64.timecnt);
|
||||
*tzf += (sizeof(unsigned char) * tz->bit64.timecnt);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
int32_t *buffer = NULL;
|
||||
uint32_t i;
|
||||
unsigned char *cbuffer = NULL;
|
||||
|
||||
if (tz->bit64.timecnt) {
|
||||
buffer = (int64_t*) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t));
|
||||
if (tz->bit32.timecnt) {
|
||||
buffer = (int32_t*) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t));
|
||||
if (!buffer) {
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(buffer, *tzf, sizeof(int64_t) * tz->bit64.timecnt);
|
||||
*tzf += (sizeof(int64_t) * tz->bit64.timecnt);
|
||||
for (i = 0; i < tz->bit64.timecnt; i++) {
|
||||
buffer[i] = timelib_conv_int64_signed(buffer[i]);
|
||||
memcpy(buffer, *tzf, sizeof(int32_t) * tz->bit32.timecnt);
|
||||
*tzf += (sizeof(int32_t) * tz->bit32.timecnt);
|
||||
for (i = 0; i < tz->bit32.timecnt; i++) {
|
||||
buffer[i] = timelib_conv_int_signed(buffer[i]);
|
||||
/* Sanity check to see whether TS is just increasing */
|
||||
if (i > 0 && !(buffer[i] > buffer[i - 1])) {
|
||||
return TIMELIB_ERROR_CORRUPT_TRANSITIONS_DONT_INCREASE;
|
||||
}
|
||||
}
|
||||
|
||||
cbuffer = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char));
|
||||
cbuffer = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char));
|
||||
if (!cbuffer) {
|
||||
timelib_free(buffer);
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit64.timecnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit64.timecnt;
|
||||
memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit32.timecnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit32.timecnt;
|
||||
}
|
||||
|
||||
tz->trans = buffer;
|
||||
@@ -203,35 +190,41 @@ static int read_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void skip_32bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
static void skip_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
if (tz->_bit32.timecnt) {
|
||||
*tzf += (sizeof(int32_t) * tz->_bit32.timecnt);
|
||||
*tzf += sizeof(unsigned char) * tz->_bit32.timecnt;
|
||||
*tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt;
|
||||
*tzf += sizeof(char) * tz->bit64.charcnt;
|
||||
if (tz->bit64.leapcnt) {
|
||||
*tzf += sizeof(int64_t) * tz->bit64.leapcnt * 2;
|
||||
}
|
||||
if (tz->bit64.ttisstdcnt) {
|
||||
*tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt;
|
||||
}
|
||||
if (tz->bit64.ttisgmtcnt) {
|
||||
*tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt;
|
||||
}
|
||||
}
|
||||
|
||||
static int read_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
static int read_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
unsigned char *buffer;
|
||||
int32_t *leap_buffer;
|
||||
unsigned int i, j;
|
||||
|
||||
/* Offset Types */
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit64.typecnt * sizeof(unsigned char) * 6);
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit32.typecnt * sizeof(unsigned char) * 6);
|
||||
if (!buffer) {
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit64.typecnt);
|
||||
*tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt;
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit32.typecnt);
|
||||
*tzf += sizeof(unsigned char) * 6 * tz->bit32.typecnt;
|
||||
|
||||
tz->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo));
|
||||
tz->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(ttinfo));
|
||||
if (!tz->type) {
|
||||
timelib_free(buffer);
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
|
||||
for (i = 0; i < tz->bit64.typecnt; i++) {
|
||||
for (i = 0; i < tz->bit32.typecnt; i++) {
|
||||
j = i * 6;
|
||||
tz->type[i].offset = 0;
|
||||
tz->type[i].offset += (int32_t) (((uint32_t) buffer[j]) << 24) + (buffer[j + 1] << 16) + (buffer[j + 2] << 8) + tz->type[i].offset + buffer[j + 3];
|
||||
@@ -240,60 +233,56 @@ static int read_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
}
|
||||
timelib_free(buffer);
|
||||
|
||||
/* Abbreviations */
|
||||
tz->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt);
|
||||
tz->timezone_abbr = (char*) timelib_malloc(tz->bit32.charcnt);
|
||||
if (!tz->timezone_abbr) {
|
||||
return TIMELIB_ERROR_CORRUPT_NO_ABBREVIATION;
|
||||
}
|
||||
memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit64.charcnt);
|
||||
*tzf += sizeof(char) * tz->bit64.charcnt;
|
||||
memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit32.charcnt);
|
||||
*tzf += sizeof(char) * tz->bit32.charcnt;
|
||||
|
||||
/* Leap seconds (only use in 'right/') format */
|
||||
if (tz->bit64.leapcnt) {
|
||||
leap_buffer = (int32_t *) timelib_malloc(tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t)));
|
||||
if (tz->bit32.leapcnt) {
|
||||
leap_buffer = (int32_t *) timelib_malloc(tz->bit32.leapcnt * 2 * sizeof(int32_t));
|
||||
if (!leap_buffer) {
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(leap_buffer, *tzf, tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t)));
|
||||
*tzf += tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t));
|
||||
memcpy(leap_buffer, *tzf, sizeof(int32_t) * tz->bit32.leapcnt * 2);
|
||||
*tzf += sizeof(int32_t) * tz->bit32.leapcnt * 2;
|
||||
|
||||
tz->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo));
|
||||
tz->leap_times = (tlinfo*) timelib_malloc(tz->bit32.leapcnt * sizeof(tlinfo));
|
||||
if (!tz->leap_times) {
|
||||
timelib_free(leap_buffer);
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
for (i = 0; i < tz->bit64.leapcnt; i++) {
|
||||
tz->leap_times[i].trans = timelib_conv_int64_signed(leap_buffer[i * 3 + 1] * 4294967296 + leap_buffer[i * 3]);
|
||||
tz->leap_times[i].offset = timelib_conv_int_signed(leap_buffer[i * 3 + 2]);
|
||||
for (i = 0; i < tz->bit32.leapcnt; i++) {
|
||||
tz->leap_times[i].trans = timelib_conv_int_signed(leap_buffer[i * 2]);
|
||||
tz->leap_times[i].offset = timelib_conv_int_signed(leap_buffer[i * 2 + 1]);
|
||||
}
|
||||
timelib_free(leap_buffer);
|
||||
}
|
||||
|
||||
/* Standard/Wall Indicators (unused) */
|
||||
if (tz->bit64.ttisstdcnt) {
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisstdcnt * sizeof(unsigned char));
|
||||
if (tz->bit32.ttisstdcnt) {
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit32.ttisstdcnt * sizeof(unsigned char));
|
||||
if (!buffer) {
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisstdcnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt;
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisstdcnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit32.ttisstdcnt;
|
||||
|
||||
for (i = 0; i < tz->bit64.ttisstdcnt; i++) {
|
||||
for (i = 0; i < tz->bit32.ttisstdcnt; i++) {
|
||||
tz->type[i].isstdcnt = buffer[i];
|
||||
}
|
||||
timelib_free(buffer);
|
||||
}
|
||||
|
||||
/* UT/Local Time Indicators (unused) */
|
||||
if (tz->bit64.ttisgmtcnt) {
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisgmtcnt * sizeof(unsigned char));
|
||||
if (tz->bit32.ttisgmtcnt) {
|
||||
buffer = (unsigned char*) timelib_malloc(tz->bit32.ttisgmtcnt * sizeof(unsigned char));
|
||||
if (!buffer) {
|
||||
return TIMELIB_ERROR_CANNOT_ALLOCATE;
|
||||
}
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisgmtcnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt;
|
||||
memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisgmtcnt);
|
||||
*tzf += sizeof(unsigned char) * tz->bit32.ttisgmtcnt;
|
||||
|
||||
for (i = 0; i < tz->bit64.ttisgmtcnt; i++) {
|
||||
for (i = 0; i < tz->bit32.ttisgmtcnt; i++) {
|
||||
tz->type[i].isgmtcnt = buffer[i];
|
||||
}
|
||||
timelib_free(buffer);
|
||||
@@ -302,30 +291,6 @@ static int read_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void skip_32bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
/* Offset Types */
|
||||
*tzf += sizeof(unsigned char) * 6 * tz->_bit32.typecnt;
|
||||
|
||||
/* Abbreviations */
|
||||
*tzf += sizeof(char) * tz->_bit32.charcnt;
|
||||
|
||||
/* Leap seconds (only use in 'right/') format */
|
||||
if (tz->_bit32.leapcnt) {
|
||||
*tzf += sizeof(int32_t) * tz->_bit32.leapcnt * 2;
|
||||
}
|
||||
|
||||
/* Standard/Wall Indicators (unused) */
|
||||
if (tz->_bit32.ttisstdcnt) {
|
||||
*tzf += sizeof(unsigned char) * tz->_bit32.ttisstdcnt;
|
||||
}
|
||||
|
||||
/* UT/Local Time Indicators (unused) */
|
||||
if (tz->_bit32.ttisgmtcnt) {
|
||||
*tzf += sizeof(unsigned char) * tz->_bit32.ttisgmtcnt;
|
||||
}
|
||||
}
|
||||
|
||||
static void skip_posix_string(const unsigned char **tzf, timelib_tzinfo *tz)
|
||||
{
|
||||
int n_count = 0;
|
||||
@@ -374,16 +339,14 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
|
||||
printf("Geo Location: %f,%f\n", tz->location.latitude, tz->location.longitude);
|
||||
printf("Comments:\n%s\n", tz->location.comments);
|
||||
printf("BC: %s\n", tz->bc ? "" : "yes");
|
||||
printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisgmtcnt);
|
||||
printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisstdcnt);
|
||||
printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.leapcnt);
|
||||
printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.timecnt);
|
||||
printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.typecnt);
|
||||
printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.charcnt);
|
||||
|
||||
printf("\n64-bit:\n");
|
||||
printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisgmtcnt);
|
||||
printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisstdcnt);
|
||||
printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.leapcnt);
|
||||
printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.timecnt);
|
||||
printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.typecnt);
|
||||
printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.charcnt);
|
||||
|
||||
printf ("%16s (%20s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
|
||||
printf ("%8s (%12s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
|
||||
"", "", 0,
|
||||
(long int) tz->type[0].offset,
|
||||
tz->type[0].isdst,
|
||||
@@ -392,8 +355,8 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
|
||||
tz->type[0].isstdcnt,
|
||||
tz->type[0].isgmtcnt
|
||||
);
|
||||
for (i = 0; i < tz->bit64.timecnt; i++) {
|
||||
printf ("%016lX (%20ld) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
|
||||
for (i = 0; i < tz->bit32.timecnt; i++) {
|
||||
printf ("%08X (%12d) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
|
||||
tz->trans[i], tz->trans[i], tz->trans_idx[i],
|
||||
(long int) tz->type[tz->trans_idx[i]].offset,
|
||||
tz->type[tz->trans_idx[i]].isdst,
|
||||
@@ -403,8 +366,8 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
|
||||
tz->type[tz->trans_idx[i]].isgmtcnt
|
||||
);
|
||||
}
|
||||
for (i = 0; i < tz->bit64.leapcnt; i++) {
|
||||
printf ("%016lX (%20ld) = %d\n",
|
||||
for (i = 0; i < tz->bit32.leapcnt; i++) {
|
||||
printf ("%08X (%12ld) = %d\n",
|
||||
tz->leap_times[i].trans,
|
||||
(long) tz->leap_times[i].trans,
|
||||
tz->leap_times[i].offset);
|
||||
@@ -507,35 +470,31 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i
|
||||
timelib_tzinfo_dtor(tmp);
|
||||
return NULL;
|
||||
}
|
||||
if (version < 2 || version > 3) {
|
||||
*error_code = TIMELIB_ERROR_UNSUPPORTED_VERSION;
|
||||
timelib_tzinfo_dtor(tmp);
|
||||
return NULL;
|
||||
}
|
||||
//printf("- timezone: %s, version: %0d\n", timezone, version);
|
||||
|
||||
read_32bit_header(&tzf, tmp);
|
||||
skip_32bit_transitions(&tzf, tmp);
|
||||
skip_32bit_types(&tzf, tmp);
|
||||
|
||||
if (!skip_64bit_preamble(&tzf, tmp)) {
|
||||
/* 64 bit preamble is not in place */
|
||||
*error_code = TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE;
|
||||
return NULL;
|
||||
}
|
||||
read_64bit_header(&tzf, tmp);
|
||||
if ((transitions_result = read_64bit_transitions(&tzf, tmp)) != 0) {
|
||||
read_header(&tzf, tmp);
|
||||
if ((transitions_result = read_transitions(&tzf, tmp)) != 0) {
|
||||
/* Corrupt file as transitions do not increase */
|
||||
*error_code = transitions_result;
|
||||
timelib_tzinfo_dtor(tmp);
|
||||
return NULL;
|
||||
}
|
||||
if ((types_result = read_64bit_types(&tzf, tmp)) != 0) {
|
||||
if ((types_result = read_types(&tzf, tmp)) != 0) {
|
||||
*error_code = types_result;
|
||||
timelib_tzinfo_dtor(tmp);
|
||||
return NULL;
|
||||
}
|
||||
skip_posix_string(&tzf, tmp);
|
||||
if (version == 2 || version == 3) {
|
||||
if (!skip_64bit_preamble(&tzf, tmp)) {
|
||||
/* 64 bit preamble is not in place */
|
||||
*error_code = TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE;
|
||||
return NULL;
|
||||
}
|
||||
read_64bit_header(&tzf, tmp);
|
||||
skip_64bit_transitions(&tzf, tmp);
|
||||
skip_64bit_types(&tzf, tmp);
|
||||
skip_posix_string(&tzf, tmp);
|
||||
}
|
||||
|
||||
if (type == TIMELIB_TZINFO_PHP) {
|
||||
read_location(&tzf, tmp);
|
||||
@@ -566,35 +525,29 @@ void timelib_tzinfo_dtor(timelib_tzinfo *tz)
|
||||
timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
|
||||
{
|
||||
timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
|
||||
tmp->_bit32.ttisgmtcnt = tz->_bit32.ttisgmtcnt;
|
||||
tmp->_bit32.ttisstdcnt = tz->_bit32.ttisstdcnt;
|
||||
tmp->_bit32.leapcnt = tz->_bit32.leapcnt;
|
||||
tmp->_bit32.timecnt = tz->_bit32.timecnt;
|
||||
tmp->_bit32.typecnt = tz->_bit32.typecnt;
|
||||
tmp->_bit32.charcnt = tz->_bit32.charcnt;
|
||||
tmp->bit64.ttisgmtcnt = tz->bit64.ttisgmtcnt;
|
||||
tmp->bit64.ttisstdcnt = tz->bit64.ttisstdcnt;
|
||||
tmp->bit64.leapcnt = tz->bit64.leapcnt;
|
||||
tmp->bit64.timecnt = tz->bit64.timecnt;
|
||||
tmp->bit64.typecnt = tz->bit64.typecnt;
|
||||
tmp->bit64.charcnt = tz->bit64.charcnt;
|
||||
tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt;
|
||||
tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt;
|
||||
tmp->bit32.leapcnt = tz->bit32.leapcnt;
|
||||
tmp->bit32.timecnt = tz->bit32.timecnt;
|
||||
tmp->bit32.typecnt = tz->bit32.typecnt;
|
||||
tmp->bit32.charcnt = tz->bit32.charcnt;
|
||||
|
||||
if (tz->bit64.timecnt) {
|
||||
tmp->trans = (int64_t *) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t));
|
||||
tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char));
|
||||
memcpy(tmp->trans, tz->trans, tz->bit64.timecnt * sizeof(int64_t));
|
||||
memcpy(tmp->trans_idx, tz->trans_idx, tz->bit64.timecnt * sizeof(unsigned char));
|
||||
if (tz->bit32.timecnt) {
|
||||
tmp->trans = (int32_t *) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t));
|
||||
tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char));
|
||||
memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t));
|
||||
memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char));
|
||||
}
|
||||
|
||||
tmp->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo));
|
||||
memcpy(tmp->type, tz->type, tz->bit64.typecnt * sizeof(ttinfo));
|
||||
tmp->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(ttinfo));
|
||||
memcpy(tmp->type, tz->type, tz->bit32.typecnt * sizeof(ttinfo));
|
||||
|
||||
tmp->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt);
|
||||
memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit64.charcnt);
|
||||
tmp->timezone_abbr = (char*) timelib_malloc(tz->bit32.charcnt);
|
||||
memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit32.charcnt);
|
||||
|
||||
if (tz->bit64.leapcnt) {
|
||||
tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo));
|
||||
memcpy(tmp->leap_times, tz->leap_times, tz->bit64.leapcnt * sizeof(tlinfo));
|
||||
if (tz->bit32.leapcnt) {
|
||||
tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit32.leapcnt * sizeof(tlinfo));
|
||||
memcpy(tmp->leap_times, tz->leap_times, tz->bit32.leapcnt * sizeof(tlinfo));
|
||||
}
|
||||
|
||||
return tmp;
|
||||
@@ -606,9 +559,9 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
|
||||
|
||||
/* If there is no transition time, we pick the first one, if that doesn't
|
||||
* exist we return NULL */
|
||||
if (!tz->bit64.timecnt || !tz->trans) {
|
||||
if (!tz->bit32.timecnt || !tz->trans) {
|
||||
*transition_time = 0;
|
||||
if (tz->bit64.typecnt == 1) {
|
||||
if (tz->bit32.typecnt == 1) {
|
||||
return &(tz->type[0]);
|
||||
}
|
||||
return NULL;
|
||||
@@ -619,30 +572,40 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
|
||||
* one in case there are only DST entries. Not sure which smartass came up
|
||||
* with this idea in the first though :) */
|
||||
if (ts < tz->trans[0]) {
|
||||
return &(tz->type[0]);
|
||||
uint32_t j;
|
||||
|
||||
*transition_time = 0;
|
||||
j = 0;
|
||||
while (j < tz->bit32.timecnt && tz->type[tz->trans_idx[j]].isdst) {
|
||||
++j;
|
||||
}
|
||||
if (j == tz->bit32.timecnt) {
|
||||
j = 0;
|
||||
}
|
||||
return &(tz->type[tz->trans_idx[j]]);
|
||||
}
|
||||
|
||||
/* In all other cases we loop through the available transition times to find
|
||||
* the correct entry */
|
||||
for (i = 0; i < tz->bit64.timecnt; i++) {
|
||||
for (i = 0; i < tz->bit32.timecnt; i++) {
|
||||
if (ts < tz->trans[i]) {
|
||||
*transition_time = tz->trans[i - 1];
|
||||
return &(tz->type[tz->trans_idx[i - 1]]);
|
||||
}
|
||||
}
|
||||
*transition_time = tz->trans[tz->bit64.timecnt - 1];
|
||||
return &(tz->type[tz->trans_idx[tz->bit64.timecnt - 1]]);
|
||||
*transition_time = tz->trans[tz->bit32.timecnt - 1];
|
||||
return &(tz->type[tz->trans_idx[tz->bit32.timecnt - 1]]);
|
||||
}
|
||||
|
||||
static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!tz->bit64.leapcnt || !tz->leap_times) {
|
||||
if (!tz->bit32.leapcnt || !tz->leap_times) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = tz->bit64.leapcnt - 1; i > 0; i--) {
|
||||
for (i = tz->bit32.leapcnt - 1; i > 0; i--) {
|
||||
if (ts > tz->leap_times[i].trans) {
|
||||
return &(tz->leap_times[i]);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ typedef struct _timelib_tzinfo
|
||||
uint32_t timecnt;
|
||||
uint32_t typecnt;
|
||||
uint32_t charcnt;
|
||||
} _bit32;
|
||||
} bit32;
|
||||
struct {
|
||||
uint64_t ttisgmtcnt;
|
||||
uint64_t ttisstdcnt;
|
||||
@@ -163,7 +163,7 @@ typedef struct _timelib_tzinfo
|
||||
uint64_t charcnt;
|
||||
} bit64;
|
||||
|
||||
int64_t *trans;
|
||||
int32_t *trans;
|
||||
unsigned char *trans_idx;
|
||||
|
||||
ttinfo *type;
|
||||
@@ -322,8 +322,8 @@ typedef struct _timelib_tzdb {
|
||||
#endif
|
||||
|
||||
#define TIMELIB_VERSION 201801
|
||||
#define TIMELIB_EXTENDED_VERSION 20180105
|
||||
#define TIMELIB_ASCII_VERSION "2018.01RC3"
|
||||
#define TIMELIB_EXTENDED_VERSION 20180104
|
||||
#define TIMELIB_ASCII_VERSION "2018.01RC2"
|
||||
|
||||
#define TIMELIB_NONE 0x00
|
||||
#define TIMELIB_OVERRIDE_TIME 0x01
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
dnl
|
||||
dnl TL_DEF_HAVE(what [, why])
|
||||
dnl
|
||||
dnl Generates 'AC_DEFINE(HAVE_WHAT, 1, [WHY])'
|
||||
dnl
|
||||
AC_DEFUN([TL_DEF_HAVE],[AC_DEFINE([HAVE_]translit($1,a-z_.-,A-Z___),1,[ $2 ])])dnl
|
||||
|
||||
dnl
|
||||
dnl TL_CHECK_INT_TYPE(type)
|
||||
dnl
|
||||
AC_DEFUN([TL_CHECK_INT_TYPE],[
|
||||
AC_CACHE_CHECK([for $1], ac_cv_int_type_$1, [
|
||||
AC_TRY_COMPILE([
|
||||
#if HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif],
|
||||
[if (($1 *) 0)
|
||||
return 0;
|
||||
if (sizeof ($1))
|
||||
return 0;
|
||||
], [ac_cv_int_type_$1=yes], [ac_cv_int_type_$1=no])
|
||||
])
|
||||
if test "$ac_cv_int_type_$1" = "yes"; then
|
||||
TL_DEF_HAVE($1, [Define if $1 type is present.])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl
|
||||
dnl AC_TIMELIB_C_BIGENDIAN
|
||||
dnl Replacement macro for AC_C_BIGENDIAN
|
||||
dnl
|
||||
AC_DEFUN([AC_TIMELIB_C_BIGENDIAN],
|
||||
[AC_CACHE_CHECK([whether byte ordering is bigendian], ac_cv_c_bigendian_php,
|
||||
[
|
||||
ac_cv_c_bigendian_php=unknown
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
int main(void)
|
||||
{
|
||||
short one = 1;
|
||||
char *cp = (char *)&one;
|
||||
|
||||
if (*cp == 0) {
|
||||
return(0);
|
||||
} else {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
], [ac_cv_c_bigendian_php=yes], [ac_cv_c_bigendian_php=no], [ac_cv_c_bigendian_php=unknown])
|
||||
])
|
||||
if test $ac_cv_c_bigendian_php = yes; then
|
||||
AC_DEFINE(WORDS_BIGENDIAN, [], [Define if processor uses big-endian word])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Check for types, sizes, etc. needed by timelib
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
TL_CHECK_INT_TYPE(int32_t)
|
||||
TL_CHECK_INT_TYPE(uint32_t)
|
||||
|
||||
dnl Check for headers needed by timelib
|
||||
AC_CHECK_HEADERS([ \
|
||||
sys/time.h \
|
||||
sys/types.h \
|
||||
stdint.h \
|
||||
dirent.h \
|
||||
string.h \
|
||||
strings.h \
|
||||
unistd.h \
|
||||
io.h
|
||||
])
|
||||
|
||||
dnl Check for strtoll, atoll
|
||||
AC_CHECK_FUNCS(strtoll atoll strftime gettimeofday)
|
||||
@@ -123,7 +123,7 @@ struct _ttinfo
|
||||
|
||||
struct _tlinfo
|
||||
{
|
||||
int64_t trans;
|
||||
int32_t trans;
|
||||
int32_t offset;
|
||||
};
|
||||
|
||||
|
||||
+31017
-31000
File diff suppressed because it is too large.
Load diff
+18
-77
@@ -551,7 +551,6 @@ static const zend_function_entry date_funcs_period[] = {
|
||||
PHP_ME(DatePeriod, getStartDate, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getEndDate, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getDateInterval, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getRecurrences, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
@@ -4033,7 +4032,7 @@ PHP_FUNCTION(timezone_transitions_get)
|
||||
add_assoc_string(&element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].abbr_idx]); \
|
||||
add_next_index_zval(return_value, &element);
|
||||
|
||||
#define add_last() add(tzobj->tzi.tz->bit64.timecnt - 1, timestamp_begin)
|
||||
#define add_last() add(tzobj->tzi.tz->bit32.timecnt - 1, timestamp_begin)
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
@@ -4044,7 +4043,7 @@ PHP_FUNCTION(timezone_transitions_get)
|
||||
} else {
|
||||
begin = 0;
|
||||
found = 0;
|
||||
if (tzobj->tzi.tz->bit64.timecnt > 0) {
|
||||
if (tzobj->tzi.tz->bit32.timecnt > 0) {
|
||||
do {
|
||||
if (tzobj->tzi.tz->trans[begin] > timestamp_begin) {
|
||||
if (begin > 0) {
|
||||
@@ -4056,19 +4055,19 @@ PHP_FUNCTION(timezone_transitions_get)
|
||||
break;
|
||||
}
|
||||
begin++;
|
||||
} while (begin < tzobj->tzi.tz->bit64.timecnt);
|
||||
} while (begin < tzobj->tzi.tz->bit32.timecnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (tzobj->tzi.tz->bit64.timecnt > 0) {
|
||||
if (tzobj->tzi.tz->bit32.timecnt > 0) {
|
||||
add_last();
|
||||
} else {
|
||||
add_nominal();
|
||||
}
|
||||
} else {
|
||||
unsigned int i;
|
||||
for (i = begin; i < tzobj->tzi.tz->bit64.timecnt; ++i) {
|
||||
for (i = begin; i < tzobj->tzi.tz->bit32.timecnt; ++i) {
|
||||
if (tzobj->tzi.tz->trans[i] < timestamp_end) {
|
||||
add(i, tzobj->tzi.tz->trans[i]);
|
||||
}
|
||||
@@ -4431,21 +4430,12 @@ PHP_FUNCTION(date_interval_create_from_date_string)
|
||||
Z_PARAM_STR(time_str)
|
||||
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
|
||||
|
||||
time = timelib_strtotime(ZSTR_VAL(time_str), ZSTR_LEN(time_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
|
||||
|
||||
if (err->error_count > 0) {
|
||||
php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s) at position %d (%c): %s", ZSTR_VAL(time_str),
|
||||
err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message);
|
||||
RETVAL_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
php_date_instantiate(date_ce_interval, return_value);
|
||||
|
||||
time = timelib_strtotime(ZSTR_VAL(time_str), ZSTR_LEN(time_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
|
||||
diobj = Z_PHPINTERVAL_P(return_value);
|
||||
diobj->diff = timelib_rel_time_clone(&time->relative);
|
||||
diobj->initialized = 1;
|
||||
|
||||
cleanup:
|
||||
timelib_time_dtor(time);
|
||||
timelib_error_container_dtor(err);
|
||||
}
|
||||
@@ -4639,10 +4629,6 @@ PHP_METHOD(DatePeriod, __construct)
|
||||
dpobj->end = clone;
|
||||
}
|
||||
}
|
||||
|
||||
if (dpobj->end == NULL && recurrences < 1) {
|
||||
php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences);
|
||||
}
|
||||
|
||||
/* options */
|
||||
dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE);
|
||||
@@ -4735,27 +4721,6 @@ PHP_METHOD(DatePeriod, getDateInterval)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int DatePeriod::getRecurrences()
|
||||
Get recurrences.
|
||||
*/
|
||||
PHP_METHOD(DatePeriod, getRecurrences)
|
||||
{
|
||||
php_period_obj *dpobj;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
dpobj = Z_PHPPERIOD_P(getThis());
|
||||
|
||||
if (0 == dpobj->recurrences - dpobj->include_start_date) {
|
||||
return;
|
||||
}
|
||||
|
||||
RETURN_LONG(dpobj->recurrences - dpobj->include_start_date);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int check_id_allowed(char *id, zend_long what) /* {{{ */
|
||||
{
|
||||
if (what & PHP_DATE_TIMEZONE_GROUP_AFRICA && strncasecmp(id, "Africa/", 7) == 0) return 1;
|
||||
@@ -5307,55 +5272,31 @@ PHP_METHOD(DatePeriod, __wakeup)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ date_period_is_magic_property
|
||||
* Common for date_period_read_property() and date_period_write_property() functions
|
||||
*/
|
||||
static int date_period_is_magic_property(zend_string *name)
|
||||
{
|
||||
if (zend_string_equals_literal(name, "recurrences")
|
||||
|| zend_string_equals_literal(name, "include_start_date")
|
||||
|| zend_string_equals_literal(name, "start")
|
||||
|| zend_string_equals_literal(name, "current")
|
||||
|| zend_string_equals_literal(name, "end")
|
||||
|| zend_string_equals_literal(name, "interval")
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ date_period_read_property */
|
||||
static zval *date_period_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv)
|
||||
{
|
||||
zval *zv;
|
||||
if (type != BP_VAR_IS && type != BP_VAR_R) {
|
||||
zend_string *name = zval_get_string(member);
|
||||
if (date_period_is_magic_property(name)) {
|
||||
zend_throw_error(NULL, "Retrieval of DatePeriod->%s for modification is unsupported", ZSTR_VAL(name));
|
||||
zend_string_release(name);
|
||||
return &EG(uninitialized_zval);
|
||||
}
|
||||
zend_string_release(name);
|
||||
zend_throw_error(NULL, "Retrieval of DatePeriod properties for modification is unsupported");
|
||||
return &EG(uninitialized_zval);
|
||||
}
|
||||
|
||||
Z_OBJPROP_P(object); /* build properties hash table */
|
||||
|
||||
return zend_std_read_property(object, member, type, cache_slot, rv);
|
||||
zv = zend_std_read_property(object, member, type, cache_slot, rv);
|
||||
if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJ_HANDLER_P(zv, clone_obj)) {
|
||||
/* defensive copy */
|
||||
ZVAL_OBJ(zv, Z_OBJ_HANDLER_P(zv, clone_obj)(zv));
|
||||
}
|
||||
|
||||
return zv;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ date_period_write_property */
|
||||
static void date_period_write_property(zval *object, zval *member, zval *value, void **cache_slot)
|
||||
{
|
||||
zend_string *name = zval_get_string(member);
|
||||
if (date_period_is_magic_property(name)) {
|
||||
zend_throw_error(NULL, "Writing to DatePeriod->%s is unsupported", ZSTR_VAL(name));
|
||||
zend_string_release(name);
|
||||
return;
|
||||
}
|
||||
zend_string_release(name);
|
||||
|
||||
std_object_handlers.write_property(object, member, value, cache_slot);
|
||||
zend_throw_error(NULL, "Writing to DatePeriod properties is unsupported");
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -111,7 +111,6 @@ PHP_METHOD(DatePeriod, __set_state);
|
||||
PHP_METHOD(DatePeriod, getStartDate);
|
||||
PHP_METHOD(DatePeriod, getEndDate);
|
||||
PHP_METHOD(DatePeriod, getDateInterval);
|
||||
PHP_METHOD(DatePeriod, getRecurrences);
|
||||
|
||||
/* Options and Configuration */
|
||||
PHP_FUNCTION(date_default_timezone_set);
|
||||
|
||||
@@ -8,7 +8,6 @@ $start = new DateTime('2000-01-01 00:00:00', new DateTimeZone('Europe/Berlin'));
|
||||
$end = new DateTime('2000-01-31 00:00:00', new DateTimeZone('UTC'));
|
||||
$interval = new DateInterval('P1D');
|
||||
$period = new DatePeriod($start, $interval, $end);
|
||||
$recurrences = 4;
|
||||
|
||||
var_dump($period->getStartDate()->format('Y-m-d H:i:s'));
|
||||
var_dump($period->getStartDate()->getTimeZone()->getName());
|
||||
@@ -17,17 +16,6 @@ var_dump($period->getEndDate()->format('Y-m-d H:i:s'));
|
||||
var_dump($period->getEndDate()->getTimeZone()->getName());
|
||||
|
||||
var_dump($period->getDateInterval()->format('%R%y-%m-%d-%h-%i-%s'));
|
||||
var_dump($period->getRecurrences());
|
||||
|
||||
$periodWithRecurrences = new DatePeriod($start, $interval, $recurrences);
|
||||
|
||||
var_dump($periodWithRecurrences->getRecurrences());
|
||||
var_dump($periodWithRecurrences->getEndDate());
|
||||
|
||||
$periodWithRecurrencesWithoutStart = new DatePeriod($start, $interval, $recurrences, DatePeriod::EXCLUDE_START_DATE);
|
||||
|
||||
var_dump($periodWithRecurrences->getRecurrences());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(19) "2000-01-01 00:00:00"
|
||||
@@ -35,7 +23,3 @@ string(13) "Europe/Berlin"
|
||||
string(19) "2000-01-31 00:00:00"
|
||||
string(3) "UTC"
|
||||
string(12) "+0-0-1-0-0-0"
|
||||
NULL
|
||||
int(4)
|
||||
NULL
|
||||
int(4)
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
DatePeriod: Test read only properties
|
||||
--INI--
|
||||
date.timezone=UTC
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$start = new DateTime;
|
||||
$interval = new DateInterval('P1D');
|
||||
$end = new DateTime;
|
||||
$period = new DatePeriod($start, $interval, $end);
|
||||
|
||||
echo "recurrences: ";
|
||||
var_dump($period->recurrences);
|
||||
|
||||
echo "include_start_date: ";
|
||||
var_dump($period->include_start_date);
|
||||
|
||||
echo "start: ";
|
||||
var_dump($period->start == $start);
|
||||
|
||||
echo "current: ";
|
||||
var_dump($period->current);
|
||||
|
||||
echo "end: ";
|
||||
var_dump($period->end == $end);
|
||||
|
||||
echo "interval: ";
|
||||
var_dump($period->interval->format("%R%d"));
|
||||
?>
|
||||
--EXPECT--
|
||||
recurrences: int(1)
|
||||
include_start_date: bool(true)
|
||||
start: bool(true)
|
||||
current: NULL
|
||||
end: bool(true)
|
||||
interval: string(2) "+1"
|
||||
@@ -1,46 +0,0 @@
|
||||
--TEST--
|
||||
DatePeriod: Test cannot modify read only properties
|
||||
--INI--
|
||||
date.timezone=UTC
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$period = new DatePeriod(new DateTime, new DateInterval('P1D'), new DateTime);
|
||||
|
||||
$properties = [
|
||||
"recurrences",
|
||||
"include_start_date",
|
||||
"start",
|
||||
"current",
|
||||
"end",
|
||||
"interval",
|
||||
];
|
||||
|
||||
foreach ($properties as $property) {
|
||||
try {
|
||||
$period->$property = "new";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
$period->$property[] = "extra";
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Writing to DatePeriod->recurrences is unsupported
|
||||
Retrieval of DatePeriod->recurrences for modification is unsupported
|
||||
Writing to DatePeriod->include_start_date is unsupported
|
||||
Retrieval of DatePeriod->include_start_date for modification is unsupported
|
||||
Writing to DatePeriod->start is unsupported
|
||||
Retrieval of DatePeriod->start for modification is unsupported
|
||||
Writing to DatePeriod->current is unsupported
|
||||
Retrieval of DatePeriod->current for modification is unsupported
|
||||
Writing to DatePeriod->end is unsupported
|
||||
Retrieval of DatePeriod->end for modification is unsupported
|
||||
Writing to DatePeriod->interval is unsupported
|
||||
Retrieval of DatePeriod->interval for modification is unsupported
|
||||
@@ -1,19 +0,0 @@
|
||||
--TEST--
|
||||
DatePeriod: Test wrong recurrence parameter on __construct
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'), 0);
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'),-1);
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
DatePeriod::__construct(): The recurrence count '0' is invalid. Needs to be > 0
|
||||
DatePeriod::__construct(): The recurrence count '-1' is invalid. Needs to be > 0
|
||||
@@ -95,11 +95,11 @@ print "wanted=Friday 00:00:00\n\n";
|
||||
|
||||
print "TZ=Pacific/Kwajalein - wrong day.\n";
|
||||
date_default_timezone_set("Pacific/Kwajalein");
|
||||
$tStamp = mktime (17, 17, 17, 1, 8627, 1970);
|
||||
$tStamp = mktime (17, 17, 17, 1, 8626, 1970);
|
||||
print "tStamp=". date("l Y-m-d H:i:s T I", $tStamp). "\n";
|
||||
$strtotime_tstamp = strtotime("next Saturday", $tStamp);
|
||||
$strtotime_tstamp = strtotime("next Friday", $tStamp);
|
||||
print "result=".date("l Y-m-d H:i:s T I", $strtotime_tstamp)."\n";
|
||||
print "wanted=Sunday 00:00:00\n\n";
|
||||
print "wanted=Friday 00:00:00\n\n";
|
||||
|
||||
print "TZ=Asia/Ulan_Bator - wrong day.\n";
|
||||
date_default_timezone_set("Asia/Ulan_Bator");
|
||||
@@ -256,9 +256,9 @@ result=Friday 2003-04-04 00:00:00 EEST 1
|
||||
wanted=Friday 00:00:00
|
||||
|
||||
TZ=Pacific/Kwajalein - wrong day.
|
||||
tStamp=Saturday 1993-08-14 17:17:17 -12 0
|
||||
result=Sunday 1993-08-22 00:00:00 +12 0
|
||||
wanted=Sunday 00:00:00
|
||||
tStamp=Friday 1993-08-13 17:17:17 -12 0
|
||||
result=Saturday 1993-08-21 00:00:00 +12 0
|
||||
wanted=Friday 00:00:00
|
||||
|
||||
TZ=Asia/Ulan_Bator - wrong day.
|
||||
tStamp=Saturday 2001-09-22 17:17:17 +09 1
|
||||
|
||||
Loaded 100 of 580 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user