diff options
334 files changed, 8842 insertions, 6122 deletions
diff --git a/.gitignore b/.gitignore index c427f0da64..81e339a82f 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,6 @@ config.cache config.h.in config.log config.nice -config.nice.bat config.status config.sub config_vars.mk @@ -285,3 +284,4 @@ win32/*.positions win32/ext win32/phpts.def win32/wsyslog.h +config.*.bat diff --git a/EXTENSIONS b/EXTENSIONS index 3f5be8eaf0..371590907e 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -262,6 +262,12 @@ PRIMARY MAINTAINER: Derick Rethans <derick@php.net> MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- +EXTENSION: enchant +PRIMARY MAINTAINER: Unknown +MAINTENANCE: Maintained +STATUS: Working +SINCE: 5.3 +------------------------------------------------------------------------------- EXTENSION: exif PRIMARY MAINTAINER: Marcus Boerger <helly@php.net> MAINTENANCE: Maintained @@ -281,7 +287,7 @@ STATUS: Working SINCE: 5.2 ------------------------------------------------------------------------------- EXTENSION: ftp -PRIMARY MAINTAINER: Stefan Esser <sesser@php.net> +PRIMARY MAINTAINER: Unknown MAINTENANCE: Odd fixes STATUS: Working ------------------------------------------------------------------------------- @@ -1,940 +1,60 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 7.1.0RC6 +?? ??? 2016, PHP 7.2.0alpha1 - Core: - . Fixded bug #72736 (Slow performance when fetching large dataset with mysqli - / PDO). (Dmitry) - -27 Oct 2016, PHP 7.1.0RC5 - -- Core: - . Fixed bug #73350 (Exception::__toString() cause circular references). - (Laruence) - . Fixed bug #73329 ((Float)"Nano" == NAN). (Anatol) - -- CLI Server: - . Fixed bug #73360 (Unable to work in root with unicode chars). (Anatol) - -- SQLite3: - . Fixed bug #73333 (2147483647 is fetched as string). (cmb) - -19 Oct 2016, PHP 7.1.0RC4 - -- Core: - . Fixed bug #73288 (Segfault in __clone > Exception.toString > __get). - (Laruence) - . Fixed for #73240 (Write out of bounds at number_format). (Stas) + . Removed the sql.safe_mode directive. (Kalle) + . Fixed bug #54535 (WSA cleanup executes before MSHUTDOWN). (Kalle) + . Implemented FR #69791 (Disallow mail header injections by extra headers) + (Yasuo) + . Implemented FR #49806 (proc_nice() for Windows). (Kalle) . Fix pthreads detection when cross-compiling (ffontaine) + . Fixed bug #73215 (uniqid() should use better random source). (Yasuo) . Fixed bug #73337 (try/catch not working with two exceptions inside a same operation). (Dmitry) -- BCmath: - . Fix bug #73190 (memcpy negative parameter _bc_new_num_ex). (Stas) - -- Date: - . Fixed bug #45554 (Inconsistent behavior of the u format char). (Derick) - . Fixed bug #48225 (DateTime parser doesn't set microseconds for "now"). - (Derick) - . Fixed bug #52514 (microseconds are missing in DateTime class). (Derick) - . Fixed bug #52519 (microseconds in DateInterval are missing). (Derick) - . Fixed bug #60089 (DateTime::createFromFormat() U after u nukes microtime). - (Derick) - . Fixed bug #64887 (Allow DateTime modification with subsecond items). - (Derick) - . Fixed bug #68506 (General DateTime improvments needed for microseconds to - become useful). (Derick) - . Fixed bug #73109 (timelib_meridian doesn't parse dots correctly). (Derick) - . Fixed bug #73247 (DateTime constructor does not initialise microseconds - property). (Derick) - . Fixed bug #73147 (Use After Free in PHP7 unserialize()). (Stas) - . Fixed bug #73189 (Memcpy negative size parameter php_resolve_path). (Stas) - -- DOM: - . Fixed bug #73150 (missing NULL check in dom_document_save_html). (Stas) - -- GD: - . Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb) - . Fixed bug #73272 (imagescale() is not affected by, but affects - imagesetinterpolation()). (cmb) - . Fixed bug #73279 (Integer overflow in gdImageScaleBilinearPalette()). (cmb) - . Fixed bug #73280 (Stack Buffer Overflow in GD dynamicGetbuf). (cmb) - -- Intl: - . Fixed bug #73007 (add locale length check). (Stas) - . Fixed bug #73218 (add mitigation for ICU int overflow). (Stas) - -- OCI8 - . Fixed bug #71148 (Bind reference overwritten on PHP 7). (Oracle Corp.) - -- OpenSSL: - . Fixed bug #73276 (crash in openssl_random_pseudo_bytes function). (Stas) - -- Session: - . Fixed bug #73273 (session_unset() empties values from all variables in which - is $_session stored). (Nikita) - -- SOAP: - . Fixed bug #73037 (SoapServer reports Bad Request when gzipped). (Anatol) - . Fixed bug #73237 (Nested object in "any" element overwrites other fields). - (Keith Smiley) - . Fixed bug #69137 (Peer verification fails when using a proxy with SoapClient) - (Keith Smiley) - -- SimpleXML: - . Fixed bug #73293 (NULL pointer dereference in SimpleXMLElement::asXML()). - (Stas) - -- SQLite3: - . Updated to SQLite3 3.15.0. (cmb) - -- Standard: - . Fixed bug #73203 (passing additional_parameters causes mail to fail). (cmb) - -29 Sep 2016, PHP 7.1.0RC3 - -- Core: - . Fixed bug #73156 (segfault on undefined function). (Dmitry) - . Fixed bug #73163 (PHP hangs if error handler throws while accessing undef - const in default value). (Nikita) - . Fixed bug #73172 (parse error: Invalid numeric literal). (Nikita, Anatol) - . Fixed bug #73181 (parse_str() without a second argument leads to crash). - (Nikita) - -- COM: - . Fixed bug #73126 (Cannot pass parameter 1 by reference). (Anatol) - . Fixed bug #69579 (Invalid free in extension trait). (John Boehr) +- EXIF: + . Added support for vendor specific tags for the following formats: + Samsung, DJI, Panasonic, Sony, Pentax, Minolta & Sigma/Foveon. (Kalle) + . Fixed bug #72682 (exif_read_data() fails to read all data for some + images). (Kalle) + . Fixed bug #71534 (Type confusion in exif_read_data() leading to heap + overflow in debug mode). (hlt99 at blinkenshell dot org, Kalle) + . Fixed bug #68547 (Exif Header component value check error). + (sjh21a at gmail dot com, Kalle) + . Fixed bug #66443 (Corrupt EXIF header: maximum directory nesting level + reached for some cameras). (Kalle) + . Fixed Redhat bug #1362571 (PHP not returning full results for + exif_read_data function). (Kalle) - GD: - . Fixed bug #50194 (imagettftext broken on transparent background w/o - alphablending). (cmb) - . Fixed bug #73003 (Integer Overflow in gdImageWebpCtx of gd_webp.c). (trylab, - cmb) - . Fixed bug #53504 (imagettfbbox gives incorrect values for bounding box). - (Mark Plomer, cmb) - . Fixed bug #73157 (imagegd2() ignores 3rd param if 4 are given). (cmb) - . Fixed bug #73155 (imagegd2() writes wrong chunk sizes on boundaries). (cmb) - . Fixed bug #73159 (imagegd2(): unrecognized formats may result in corrupted - files). (cmb) - . Fixed bug #73161 (imagecreatefromgd2() may leak memory). (cmb) + . Implemented imageresolution as getter and setter (Christoph) -- JSON: - . Fixed bug #73113 (Segfault with throwing JsonSerializable). (julien) +- GMP: + . Fixed bug #70896 (gmp_fact() silently ignores non-integer input). (Sara) -- PCRE: - . Fixed bug #73121 (Bundled PCRE doesn't compile because JIT isn't supported - on s390). (Anatol) +- Mbstring: + . Implemented request #66024 (mb_chr() and mb_ord()). (Masakielastic, Yasuo) + . Implemented request #65081 (mb_scrub()). (Masakielastic, Yasuo) + . Implemented request #69086 (enhancement for mb_convert_encoding() that + handles multibyte replacement char nicely). (Masakielastic, Yasuo) + . Added array input support to mb_convert_encoding(). (Yasuo) + . Added array input support to mb_check_encoding(). (Yasuo) - PDO_DBlib: - . Fixed bug #72414 (Never quote values as raw binary data). (Adam Baratz) - . Allow \PDO::setAttribute() to set query timeouts. (Adam Baratz) - . Handle SQLDECIMAL/SQLNUMERIC types, which are used by later TDS versions. - (Adam Baratz) - . Add common PDO test suite. (Adam Baratz) - . Free error and message strings when cleaning up PDO instances. + . Fixed bug #73234 (Emulated statements let value dictate parameter type). (Adam Baratz) - . Fixed bug #67130 (\PDOStatement::nextRowset() should succeed when all rows - in current rowset haven't been fetched). (Peter LeBrun) - . Ignore potentially misleading dberr values. (Chris Kings-Lynne) - -- phpdbg: - . Added generator command for inspection of currently alive generators. (Bob) - -- Reflection - . Undo backwards compatiblity break in ReflectionType->__toString() and - deprecate via documentation instead. (Nikita) - -- Session: - . Fixed bug #73100 (session_destroy null dereference in ps_files_path_create). - (cmb) - -- Standard: - . Fixed bug #73203 (passing additional_parameters causes mail to fail). (cmb) - -15 Sep 2016, PHP 7.1.0RC2 - -- Core: - . Fixed bug #73025 (Heap Buffer Overflow in virtual_popen of - zend_virtual_cwd.c). (cmb) - . Fixed bug #73058 (crypt broken when salt is 'too' long). (Anatol) - -- Filter: - . Fixed bug #72972 (Bad filter for the flags FILTER_FLAG_NO_RES_RANGE and - FILTER_FLAG_NO_PRIV_RANGE). (julien) - . Fixed bug #73054 (default option ignored when object passed to int filter). - (cmb) - --GD: - . Fixed bug #67325 (imagetruecolortopalette: white is duplicated in palette). - (cmb) - -- Mbstring - . Fixed bug #66964 (mb_convert_variables() cannot detect recursion) (Yasuo) - . Fixed bug #72992 (mbstring.internal_encoding doesn't inherit default_charset). - (Yasuo) - -- Opcache: - . Fixed bug #72982 (Memory leak in zend_accel_blacklist_update_regexp() - function). (Laruence) - -- OpenSSL: - . Fixed bug #73072 (Invalid path SNI_server_certs causes segfault). - (Jakub Zelenka) - -- Session: - . Fixed bug #68015 (Session does not report invalid uid for files save handler). - (Yasuo) - -- SQLite3: - . Updated to SQLite3 3.14.2. (cmb) - -01 Sep 2016, PHP 7.1.0RC1 - -- Core: - . Fixed bug #72944 (Null pointer deref in zval_delref_p). (Dmitry) - . Fixed bug #72943 (assign_dim on string doesn't reset hval). (Laruence) - . Fixed bug #72598 (Reference is lost after array_slice()) (Nikita) - . Fixed bug #72703 (Out of bounds global memory read in BF_crypt triggered by - password_verify). (Anatol) - . Implement \ArgumentCountError when passing in too few arguments (Davey) - -- COM: - . Fixed bug #72922 (COM called from PHP does not return out parameters). - (Anatol) - -- Dba: - . Fixed bug #70825 (Cannot fetch multiple values with group in ini file). - (cmb) - -- GD: - . Fixed bug #66005 (imagecopy does not support 1bit transparency on truecolor - images). (cmb) - . Fixed bug #72913 (imagecopy() loses single-color transparency on palette - images). (cmb) - . Fixed bug #68716 (possible resource leaks in _php_image_convert()). (cmb) - -- iconv: - . Fixed bug #72320 (iconv_substr returns false for empty strings). (cmb) - -- Intl: - . Fixed bug #65732 (grapheme_*() is not Unicode compliant on CR LF - sequence). (cmb) - . Fixed bug #73007 (add locale length check). (Stas) - -- JSON: - . Implemented earlier return when json_encode fails, fixes bugs #68992 - (Stacking exceptions thrown by JsonSerializable) and #70275 (On recursion - error, json_encode can eat up all system memory). (Jakub Zelenka) - -- mbstring: - . Fixed bug #66797 (mb_substr only takes 32-bit signed integer). (cmb) - -- Opcache: - . Fixed bug #72949 (Typo in opcache error message). (cmb) - -- PDO_DBlib: - . Implemented stringify 'uniqueidentifier' fields. - (Alexander Zhuravlev, Adam Baratz) - -- Phar: - . Fixed bug #72928 (Out of bound when verify signature of zip phar in - phar_parse_zipfile). (Stas) - . Fixed bug #73035 (Out of bound when verify signature of tar phar in - phar_parse_tarfile). (Stas) - -- Reflection: - . Reverted prepending \ for class names. (Trowski) - -- Session: - . Fixed bug #72940 (SID always return "name=ID", even if session - cookie exist). (Yasuo) - . Implemented session_gc() (Yasuo) - https://wiki.php.net/rfc/session-create-id - . Implemented session_create_id() (Yasuo) - https://wiki.php.net/rfc/session-gc - -- SimpleXML: - . Fixed bug #72971 (SimpleXML isset/unset do not respect namespace). (Nikita) - . Fixed bug #72957 (Null coalescing operator doesn't behave as expected with - SimpleXMLElement). (Nikita) + . Fixed bug #73396 (bigint columns are returned as strings). - SOAP: - . Fixed bug #71711 (Soap Server Member variables reference bug). (Nikita) - . Fixed bug #71996 (Using references in arrays doesn't work like expected). - (Nikita) - -- Standard: - . Fixed bug #72920 (Accessing a private constant using constant() creates - an exception AND warning). (Laruence) - . Fixed bug #65550 (get_browser() incorrectly parses entries with "+" sign). - (cmb) - . Fixed bug #71882 (Negative ftruncate() on php://memory exhausts memory). - (cmb) - -- XML: - . Fixed bug #72714 (_xml_startElementHandler() segmentation fault). (cmb) - -18 Aug 2016, PHP 7.1.0beta3 - -- Core: - . Fixed bug #72813 (Segfault with __get returned by ref). (Laruence) - . Fixed bug #72767 (PHP Segfaults when trying to expand an infinite operator). - (Nikita) - . TypeError messages for arg_info type checks will now say "must be ... - or null" where the parameter or return type accepts null. (Andrea) - . Fixed bug #72857 (stream_socket_recvfrom read access violation). (Anatol) - . Fixed bug #72663 (Create an Unexpected Object and Don't Invoke - __wakeup() in Deserialization). (Stas) - . Fixed bug #72681 (PHP Session Data Injection Vulnerability). (Stas) - . Fixed bug #72742 (memory allocator fails to realloc small block to large - one). (Stas) - . Fixed URL rewriter. It would not rewrite '//example.com/' URL - unconditionally. URL rewrite target hosts whitelist is implemented. (Yasuo) - -- Bz2: - . Fixed bug #72837 (integer overflow in bzdecompress caused heap - corruption). (Stas) - -- Curl - . Fixed bug #72674 (Heap overflow in curl_escape). (Stas) - -- EXIF: - . Fixed bug #72735 (Samsung picture thumb not read (zero size)). (Kalle, Remi) - . Fixed bug #72627 (Memory Leakage In exif_process_IFD_in_TIFF). (Stas) - -- FTP: - . Fixed bug #70195 (Cannot upload file using ftp_put to FTPES with - require_ssl_reuse). (Benedict Singer) - -- mbstring: - . Fixed bug #72711 (`mb_ereg` does not clear the `$regs` parameter on - failure). (ju1ius) - -- Mcrypt: - . Fixed bug #72782 (Heap Overflow due to integer overflows). (Stas) - -- OCI8 - . Fixed invalid handle error with Implicit Result Sets. (Chris Jones) - . Fixed bug #72524 (Binding null values triggers ORA-24816 error). (Chris Jones) - -- Opcache: - . Fixed bug #72762 (Infinite loop while parsing a file with opcache enabled). - (Nikita) - -- PDO: - . Fixed bug #72788 (Invalid memory access when using persistent PDO - connection). (Keyur) - . Fixed bug #72791 (Memory leak in PDO persistent connection handling). (Keyur) - . Fixed bug #60665 (call to empty() on NULL result using PDO::FETCH_LAZY - returns false). (cmb) - -- Reflection: - . Implemented request #38992 (invoke() and invokeArgs() static method calls - should match). (cmb). - . Add ReflectionNamedType::getName(). This method should be used instead of - ReflectionType::__toString() - . Prepend \ for class names and ? for nullable types returned from - ReflectionType::__toString(). (Trowski) - -- Session: - . Implemented RFC: Session ID without hashing. (Yasuo) - https://wiki.php.net/rfc/session-id-without-hashing - -- SPL: - . Fixed bug #72888 (Segfault on clone on splFileObject). (Laruence) - . Fixed bug #73029 (Missing type check when unserializing SplArray). (Stas) - -- SQLite3: - . Updated to SQLite3 3.14.0. (cmb) - -- Standard: - . Fixed bug #55451 (substr_compare NULL length interpreted as 0). (Lauri - Kenttä) - . Fixed bug #72278 (getimagesize returning FALSE on valid jpg). (cmb) - -- Stream: - . Fixed bug #72853 (stream_set_blocking doesn't work). (Laruence) - . Fixed bug #72743 (Out-of-bound read in php_stream_filter_create). - (Loianhtuan) - . Implemented FR #27814 (Multiple small packets send for HTTP request). - (vhuk) - . Fixed bug #72764 (ftps:// opendir wrapper data channel encryption fails - with IIS FTP 7.5, 8.5). (vhuk) - . Fixed bug #72810 (Missing SKIP_ONLINE_TESTS checks). (vhuk) - -- sysvshm: - . Fixed bug #72858 (shm_attach null dereference). (Anatol) + . Fixed bug #69137 (Peer verification fails when using a proxy with SoapClient) + (Keith Smiley) - XML: - . Fixed bug #72085 (SEGV on unknown address zif_xml_parse). (cmb) - -- ZIP: - . Fixed bug #68302 (impossible to compile php with zip support). (cmb) - -04 Aug 2016, PHP 7.1.0beta2 - -- Core: - . Implemented FR #72614 (Support "nmake test" on building extensions by - phpize). (Yuji Uchiyama) - . Fixed bug #72641 (phpize (on Windows) ignores PHP_PREFIX). - (Yuji Uchiyama) - . Fixed bug #72683 (getmxrr broken). (Anatol) - -- Calendar: - . Fixed bug #67976 (cal_days_month() fails for final month of the French - calendar). (cmb) - . Fixed bug #71894 (AddressSanitizer: global-buffer-overflow in - zif_cal_from_jd). (cmb) - -- CURL: - . Fixed bug #71709 (curl_setopt segfault with empty CURLOPT_HTTPHEADER). - (Pierrick) - . Fixed bug #71929 (CURLINFO_CERTINFO data parsing error). (Pierrick) - -- Intl: - . Fixed bug #72639 (Segfault when instantiating class that extends - IntlCalendar and adds a property). (Laruence) - . Fixed bug #72658 (Locale::lookup() / locale_lookup() hangs if no match - found). (Anatol) - -- GD: - . Fixed bug #72709 (imagesetstyle() causes OOB read for empty $styles). (cmb) - . Fixed bug #72697 (select_colors write out-of-bounds). (Stas) - . Fixed bug #72730 (imagegammacorrect allows arbitrary write access). (Stas) - -- mbstring: - . Fixed bug #72691 (mb_ereg_search raises a warning if a match zero-width). - (cmb) - . Fixed bug #72693 (mb_ereg_search increments search position when a match - zero-width). (cmb) - . Fixed bug #72694 (mb_ereg_search_setpos does not accept a string's last - position). (cmb) - . Fixed bug #72710 (`mb_ereg` causes buffer overflow on regexp compile error). - (ju1ius) - -- Mysqlnd: - . Fixed bug #71863 (Segfault when EXPLAIN with "Unknown column" error when - using MariaDB). (Andrey) - . Fixed bug #72701 (mysqli_get_host_info() wrong output). (Anatol) - -- PCRE: - . Fixed bug #72688 (preg_match missing group names in matches). (cmb) - . Downgraded to PCRE 8.38. (Anatol) - -- Reflection: - . Fixed bug #72661 (ReflectionType::__toString crashes with iterable). - (Laruence) - -- SNMP: - . Fixed bug #72708 (php_snmp_parse_oid integer overflow in memory - allocation). (djodjo at gmail dot com) - -- SPL: - . Fixed bug #72646 (SplFileObject::getCsvControl does not return the escape - character). (cmb) - . Fixed bug #72684 (AppendIterator segfault with closed generator). (Pierrick) - -- SQLite3: - . Fixed bug #72668 (Spurious warning when exception is thrown in user defined - function). (Laruence) - . Implemented FR #72653 (SQLite should allow opening with empty filename). - (cmb) - -- Standard: - . Fixed bug #61967 (unset array item in array_walk_recursive cause - inconsistent array). (Nikita) - . Fixed bug #62607 (array_walk_recursive move internal pointer). (Nikita) - . Fixed bug #69068 (Exchanging array during array_walk -> memory errors). - (Nikita) - . Fixed bug #70713 (Use After Free Vulnerability in array_walk()/ - array_walk_recursive()). (Nikita) - -- Streams: - . Fixed bug #41021 (Problems with the ftps wrapper). (vhuk) - . Fixed bug #54431 (opendir() does not work with ftps:// wrapper). (vhuk) - . Fixed bug #72667 (opendir() with ftp:// attempts to open data stream for - non-existent directories). (vhuk) - . Fixed bug #72771 (ftps:// wrapper is vulnerable to protocol downgrade - attack). (Stas) - -- Wddx: - . Fixed bug #72142 (WDDX Packet Injection Vulnerability in - wddx_serialize_value()). (Taoguang Chen) - . Fixed bug #72749 (wddx_deserialize allows illegal memory access) (Stas) - . Fixed bug #72750 (wddx_deserialize null dereference). (Stas) - . Fixed bug #72790 (wddx_deserialize null dereference with invalid xml). - (Stas) - . Fixed bug #72799 (wddx_deserialize null dereference in - php_wddx_pop_element). (Stas) - . Fixed bug #72860 (wddx_deserialize use-after-free). (Stas) - . Fixed bug #73065 (Out-Of-Bounds Read in php_wddx_push_element). (Stas) - -- XMLRPC: - . Fixed bug #72647 (xmlrpc_encode() unexpected output after referencing - array elements). (Laruence) - -- Zip: - . Fixed bug #72660 (NULL Pointer dereference in zend_virtual_cwd). - (Laruence) - -21 Jul 2016, PHP 7.1.0beta1 - -- Core: - . Fixed bug #72629 (Caught exception assignment to variables ignores - references). (Laruence) - . Fixed bug #72594 (Calling an earlier instance of an included anonymous - class fatals). (Laruence) - . Fixed bug #72581 (previous property undefined in Exception after - deserialization). (Laruence) - . Fixed bug #72543 (Different references behavior comparing to PHP 5) - (Laruence, Dmitry, Nikita) - . Fixed bug #72347 (VERIFY_RETURN type casts visible in finally). (Dmitry) - . Fixed bug #72216 (Return by reference with finally is not memory safe). - (Dmitry) - . Fixed bug #72215 (Wrong return value if var modified in finally). (Dmitry) - . Fixed bug #71818 (Memory leak when array altered in destructor). (Dmitry) - . Fixed bug #71539 (Memory error on $arr[$a] =& $arr[$b] if RHS rehashes) - (Dmitry, Nikita) - . Added new constant PHP_FD_SETSIZE. (cmb) - . Added optind parameter to getopt(). (as) - . Added PHP to SAPI error severity mapping for logs. (Martin Vobruba) - . Fixed bug #71911 (Unable to set --enable-debug on building extensions by - phpize on Windows). (Yuji Uchiyama) - . Fixed bug #29368 (The destructor is called when an exception is thrown from - the constructor). (Dmitry) - . Implemented RFC: RNG Fixes. (Leigh) - . Implemented email validation as per RFC 6531. (Leo Feyer, Anatol) - . Fixed bug #72513 (Stack-based buffer overflow vulnerability in - virtual_file_ex). (Stas) - . Fixed bug #72573 (HTTP_PROXY is improperly trusted by some PHP libraries - and applications). (Stas) - -- bz2: - . Fixed bug #72613 (Inadequate error handling in bzread()). (Stas) - -- COM: - . Fixed bug #72569 (DOTNET/COM array parameters broke in PHP7). (Anatol) - -- Curl: - . Fixed bug #72541 (size_t overflow lead to heap corruption). (Stas) - -- Date: - . Fixed bug #66836 (DateTime::createFromFormat 'U' with pre 1970 dates fails - parsing). (derick) - -- DOM: - . Fixed bug #66502 (DOM document dangling reference). (Sean Heelan, cmb) - -- Exif: - . Fixed bug #72603 (Out of bound read in exif_process_IFD_in_MAKERNOTE). - (Stas) - . Fixed bug #72618 (NULL Pointer Dereference in exif_process_user_comment). - (Stas) - -- Filter: - . Fixed bug #71745 (FILTER_FLAG_NO_RES_RANGE does not cover whole 127.0.0.0/8 - range). (bugs dot php dot net at majkl578 dot cz) - -- FPM: - . Fixed bug #72575 (using --allow-to-run-as-root should ignore missing user). - (gooh) - -- GD: - . Fixed bug #72596 (imagetypes function won't advertise WEBP support). (cmb) - . Fixed bug #72604 (imagearc() ignores thickness for full arcs). (cmb) - . Fixed bug #70315 (500 Server Error but page is fully rendered). (cmb) - . Fixed bug #43828 (broken transparency of imagearc for truecolor in - blendingmode). (cmb) - . Fixed bug #72512 (gdImageTrueColorToPaletteBody allows arbitrary write/read - access). (Pierre) - . Fixed bug #72519 (imagegif/output out-of-bounds access). (Pierre) - . Fixed bug #72558 (Integer overflow error within _gdContributionsAlloc()). - (Pierre) - . Fixed bug #72482 (Ilegal write/read access caused by gdImageAALine - overflow). (Pierre) - . Fixed bug #72494 (imagecropauto out-of-bounds access). (Fernando, Pierre, - cmb) - -- Intl: - . Partially fixed #72506 (idn_to_ascii for UTS #46 incorrect for long domain - names). (cmb) - . Fixed bug #72533 (locale_accept_from_http out-of-bounds access). (Stas) - -- Mbstring: - . Deprecated mb_ereg_replace() eval option. (Rouven Weßling, cmb) - . Fixed bug #69151 (mb_ereg should reject ill-formed byte sequence). - (Masaki Kagaya) - -- MCrypt: - . Deprecated ext/mcrypt. (Scott Arciszewski, cmb) - . Fixed bug #72551, bug #72552 (In correct casting from size_t to int lead to - heap overflow in mdecrypt_generic). (Stas) - -- Opcache: - . Fixed bug #72590 (Opcache restart with kill_all_lockers does not work). - (Keyur) - -- OpenSSL: - . Fixed bug #72360 (ext/openssl build failure with OpenSSL 1.1.0). - (Jakub Zelenka) - . Bumped a minimal version to 1.0.1. (Jakub Zelenka) - . Dropped support for SSL2. (Remi) - -- PDO_pgsql: - . Fixed bug #70313 (PDO statement fails to throw exception). (Matteo) - . Fixed bug #72570 (Segmentation fault when binding parameters on a query - without placeholders). (Matteo) - . Implemented FR #72633 (Postgres PDO lastInsertId() should work without - specifying a sequence). (Pablo Santiago Sánchez, Matteo) - -- Pcntl - . Implemented asynchronous signal handling without TICKS. (Dmitry) - . Added pcntl_signal_get_handler() that returns the current signal handler - for a particular signal. Addresses FR #72409. (David Walker) - . Add signinfo to pcntl_signal() handler args (Bishop Bettini, David Walker) - -- Reflection: - . Fixed bug #72222 (ReflectionClass::export doesn't handle array constants). - (Nikita Nefedov) - -- SimpleXML: - . Fixed bug #72588 (Using global var doesn't work while accessing SimpleXML - element). (Laruence) - -- Standard: - . Fixed bug #72622 (array_walk + array_replace_recursive create references - from nothing). (Laruence) - . Fixed bug #72330 (CSV fields incorrectly split if escape char followed by - UTF chars). (cmb) - -- Tidy: - . Implemented support for libtidy 5.0.0 and above. (Michael Orlitzky, Anatol) - -- Wddx: - . Fixed bug #72564 (boolean always deserialized as "true") (Remi) + . Moved utf8_encode() and utf8_decode() to the Standard extension. (Andrea) - XMLRPC: - . Fixed bug #72606 (heap-buffer-overflow (write) simplestring_addn - simplestring.c). (Stas) - -- Zip: - . Fixed bug #72520 (Stack-based buffer overflow vulnerability in - php_stream_zip_opener). (Stas) - -07 Jul 2016, PHP 7.1.0alpha3 - -- Core: - . Implemented RFC: Iterable. (Aaron Piotrowski) - . Fixed bug #72523 (dtrace issue with reflection (failed test)). (Laruence) - . Fixed bug #72508 (strange references after recursive function call and - "switch" statement). (Laruence) - . Implemented RFC: Closure::fromCallable (Danack) - -- COM: - . Fixed bug #72498 (variant_date_from_timestamp null dereference). (Anatol) - -- CURL: - . Add curl_multi_errno(), curl_share_errno() and curl_share_strerror() - functions. (Pierrick) - . Add support for HTTP/2 Server Push (davey) - -- Date: - . Invalid serialization data for a DateTime or DatePeriod object will now - throw an instance of Error from __wakeup() or __set_state() instead of - resulting in a fatal error. (Aaron Piotrowski) - . Timezone initialization failure from serialized data will now throw an - instance of Error from __wakeup() or __set_state() instead of resulting in - a fatal error. (Aaron Piotrowski) - . Export date_get_interface_ce() for extension use. (Jeremy Mikola) - -- DBA: - . Data modification functions (e.g.: dba_insert()) now throw an instance of - Error instead of triggering a catchable fatal error if the key is does not - contain exactly two elements. (Aaron Piotrowski) - -- DOM: - . Invalid schema or RelaxNG validation contexts will throw an instance of - Error instead of resulting in a fatal error. (Aaron Piotrowski) - . Attempting to register a node class that does not extend the appropriate - base class will now throw an instance of Error instead of resulting in a - fatal error. (Aaron Piotrowski) - . Attempting to read an invalid or write to a readonly property will throw - an instance of Error instead of resulting in a fatal error. (Aaron - Piotrowski) - -- GD: - . Fixed bug #72404 (imagecreatefromjpeg fails on selfie). (cmb) - -- IMAP: - . An email address longer than 16385 bytes will throw an instance of Error - instead of resulting in a fatal error. (Aaron Piotrowski) - -- Intl: - . Failure to call the parent constructor in a class extending Collator - before invoking the parent methods will throw an instance of Error - instead of resulting in a recoverable fatal error. (Aaron Piotrowski) - . Cloning a Transliterator object may will now throw an instance of Error - instead of resulting in a fatal error if cloning the internal - transliterator fails. (Aaron Piotrowski) - -- LDAP: - . Providing an unknown modification type to ldap_batch_modify() will now - throw an instance of Error instead of resulting in a fatal error. - (Aaron Piotrowski) - -- Mbstring: - . mb_ereg() and mb_eregi() will now throw an instance of ParseError if an - invalid PHP expression is provided and the 'e' option is used. (Aaron - Piotrowski) - -- Mcrypt: - . mcrypt_encrypt() and mcrypt_decrypt() will throw an instance of Error - instead of resulting in a fatal error if mcrypt cannot be initialized. - (Aaron Piotrowski) - -- Mysqli: - . Attempting to read an invalid or write to a readonly property will throw - an instance of Error instead of resulting in a fatal error. (Aaron - Piotrowski) - -- OpenSSL: - . Implemented FR #61204 (Add elliptic curve support for OpenSSL). - (Dominic Luechinger) - -- PCRE: - . Fixed bug #72476 (Memleak in jit_stack). (Laruence) - . Fixed bug #72463 (mail fails with invalid argument). (Anatol) - -- Readline: - . Fixed bug #72538 (readline_redisplay crashes php). (Laruence) - -- Reflection: - . Failure to retrieve a reflection object or retrieve an object property - will now throw an instance of Error instead of resulting in a fatal error. - (Aaron Piotrowski) - -- SQLite3: - . Fixed bug #70628 (Clearing bindings on an SQLite3 statement doesn't work). - (cmb) - -- Session: - . Fixed bug #72531 (ps_files_cleanup_dir Buffer overflow). (Laruence) - . Custom session handlers that do not return strings for session IDs will - now throw an instance of Error instead of resulting in a fatal error - when a function is called that must generate a session ID. - (Aaron Piotrowski) - . An invalid setting for session.hash_function will throw an instance of - Error instead of resulting in a fatal error when a session ID is created. - (Aaron Piotrowski) - . Fixed bug #72562 (Use After Free in unserialize() with Unexpected Session - Deserialization). (Stas) - -- SimpleXML: - . Creating an unnamed or duplicate attribute will throw an instance of Error - instead of resulting in a fatal error. (Aaron Piotrowski) - -- SNMP: - . Fixed bug #72479 (Use After Free Vulnerability in SNMP with GC and - unserialize()). (Stas) - -- SPL: - . Attempting to clone an SplDirectory object will throw an instance of Error - instead of resulting in a fatal error. (Aaron Piotrowski) - . Calling ArrayIterator::append() when iterating over an object will throw an - instance of Error instead of resulting in a fatal error. (Aaron Piotrowski) - . Fixed bug #55701 (GlobIterator throws LogicException). (Valentin VĂLCIU) - -- Standard: - . Implemented RFC: More precise float values. (Jakub Zelenka, Yasuo) - . array_multisort now uses zend_sort instead zend_qsort. (Laruence) - . Fixed bug #72505 (readfile() mangles files larger than 2G). (Cschneid) - . assert() will throw a ParseError when evaluating a string given as the first - argument if the PHP code is invalid instead of resulting in a catchable - fatal error. (Aaron Piotrowski) - . Calling forward_static_call() outside of a class scope will now throw an - instance of Error instead of resulting in a fatal error. (Aaron Piotrowski) - -- Streams: - . Fixed bug #72534 (stream_socket_get_name crashes). (Anatol) - -- Tidy: - . Creating a tidyNode manually will now throw an instance of Error instead of - resulting in a fatal error. (Aaron Piotrowski) - -- WDDX: - . A circular reference when serializing will now throw an instance of Error - instead of resulting in a fatal error. (Aaron Piotrowski) - -- XML-RPC: - . A circular reference when serializing will now throw an instance of Error - instead of resulting in a fatal error. (Aaron Piotrowski) - -- Zip: - . ZipArchive::addGlob() will throw an instance of Error instead of resulting - in a fatal error if glob support is not available. (Aaron Piotrowski) - -23 Jun 2016, PHP 7.1.0alpha2 - -- Core: - . Implemented RFC: Replace "Missing argument" warning with "Too few - arguments" exception. (Dmitry) - . Implemented RFC: Fix inconsistent behavior of $this variable. (Dmitry) - . Fixed bug #72441 (Segmentation fault: RFC list_keys). (Laruence) - . Fixed bug #72395 (list() regression). (Laruence) - . Fixed bug #72373 (TypeError after Generator function w/declared return type - finishes). (Nikita) - . Fixed bug #69489 (tempnam() should raise notice if falling back to temp dir). - (Laruence, Anatol) - . Fixed UTF-8 and long path support on Windows. (Anatol) - -- Date: - . Fixed bug #63740 (strtotime seems to use both sunday and monday as start of - week). (Derick) - -- GD: - . Fixed bug #43475 (Thick styled lines have scrambled patterns). (cmb) - . Fixed bug #53640 (XBM images require width to be multiple of 8). (cmb) - . Fixed bug #64641 (imagefilledpolygon doesn't draw horizontal line). (cmb) - -- JSON - . Implemented FR #46600 ("_empty_" key in objects). (Jakub Zelenka) - -- Mbstring: - . Fixed bug #72405 (mb_ereg_replace - mbc_to_code (oniguruma) - - oob read access). (Laruence) - . Fixed bug #72399 (Use-After-Free in MBString (search_re)). (Laruence) - -- OpenSSL: - . Implemented FR #67304 (Added AEAD support [CCM and GCM modes] to - openssl_encrypt and openssl_decrypt). (Jakub Zelenka) - . Implemented error storing to the global queue and cleaning up the OpenSSL - error queue (resolves bugs #68276 and #69882). (Jakub Zelenka) - -- PCRE: - . Upgraded to PCRE 8.39. (Anatol) - -- Sqlite3: - . Implemented FR #72385 (Update SQLite bundle lib(3.13.0)). (Laruence) - -- Standard: - . Added is_iterable() function. (Aaron Piotrowski) - . Fixed bug #72306 (Heap overflow through proc_open and $env parameter). - (Laruence) - -- Streams: - . Fixed bug #72439 (Stream socket with remote address leads to a segmentation - fault). (Laruence) - -09 Jun 2016, PHP 7.1.0alpha1 - -- Core: - . Added nullable types. (Levi, Dmitry) - . Added DFA optimization framework based on e-SSA form. (Dmitry, Nikita) - . Added specialized opcode handlers (e.g. ZEND_ADD_LONG_NO_OVERFLOW). - (Dmitry) - . Change statement and fcall extension handlers to accept frame. (Joe) - . Implemented safe execution timeout handling, that prevents random crashes - after "Maximum execution time exceeded" error. (Dmitry) - . Fixed bug #53432 (Assignment via string index access on an empty string - converts to array). (Nikita) - . Fixed bug #62210 (Exceptions can leak temporary variables). (Dmitry, Bob) - . Fixed bug #62814 (It is possible to stiffen child class members visibility). - (Nikita) - . Fixed bug #69989 (Generators don't participate in cycle GC). (Nikita) - . Fixed bug #70228 (Memleak if return in finally block). (Dmitry) - . Fixed bug #71266 (Missing separation of properties HT in foreach etc). - (Dmitry) - . Fixed bug #71604 (Aborted Generators continue after nested finally). - (Nikita) - . Fixed bug #71572 (String offset assignment from an empty string inserts - null byte). (Francois) - . Fixed bug #71897 (ASCII 0x7F Delete control character permitted in - identifiers). (Andrea) - . Fixed bug #72188 (Nested try/finally blocks losing return value). (Dmitry) - . Fixed bug #72213 (Finally leaks on nested exceptions). (Dmitry, Nikita) - . Implemented the RFC `Support Class Constant Visibility`. (Sean DuBois, - Reeze Xia, Dmitry) - . Added void return type. (Andrea) - . Added support for negative string offsets in string offset syntax and - various string functions. (Francois) - . Added a form of the list() construct where keys can be specified. (Andrea) - . Number operators taking numeric strings now emit E_NOTICEs or E_WARNINGs - when given malformed numeric strings. (Andrea) - . (int), intval() where $base is 10 or unspecified, settype(), decbin(), - decoct(), dechex(), integer operators and other conversions now always - respect scientific notation in numeric strings. (Andrea) - . Implemented the RFC `Catching multiple exception types`. (Bronislaw Bialek, - Pierrick) - . Raise a compile-time warning on octal escape sequence overflow. (Sara) - . Added [] = as alternative construct to list() =. (Bob) - . Implemented logging to syslog with dynamic error levels. (Jani Ollikainen) - . Fixed bug #47517 (php-cgi.exe missing UAC manifest). - (maxdax15801 at users noreply github com) - -- Apache2handler: - . Enable per-module logging in Apache 2.4+. (Martin Vobruba) - -- CLI Server: - . Fixed bug #71276 (Built-in webserver does not send Date header). - (see at seos fr) - -- FTP: - . Implemented FR #55651 (Option to ignore the returned FTP PASV address). - (abrender at elitehosts dot com) - -- Intl: - . Added IntlTimeZone::getWindowsID() and - IntlTimeZone::getIDForWindowsID(). (Sara) - . Fixed bug #69374 (IntlDateFormatter formatObject returns wrong utf8 value). - (lenhatanh86 at gmail com) - . Fixed bug #69398 (IntlDateFormatter formatObject returns wrong value when - time style is NONE). (lenhatanh86 at gmail com) - -- Hash: - . Added SHA3 fixed mode algorithms (224, 256, 384, and 512 bit). (Sara) - . Added SHA512/256 and SHA512/224 algorithms. (Sara) - -- JSON: - . Exported JSON parser API including json_parser_method that can be used - for implementing custom logic when parsing JSON. (Jakub Zelenka) - . Escaped U+2028 and U+2029 when JSON_UNESCAPED_UNICODE is supplied as - json_encode options and added JSON_UNESCAPED_LINE_TERMINATORS to restore - the previous behaviour. (Eddie Kohler) - -- PDO_Firebird: - . Fixed bug #60052 (Integer returned as a 64bit integer on X86_64). (Mariuz) - -- Pgsql: - . Implemented FR #31021 (pg_last_notice() is needed to get all notice - messages). (Yasuo) - . Implemented FR #48532 (Allow pg_fetch_all() to index numerically). (Yasuo) - -- Reflection: - . Fix #72209 (ReflectionProperty::getValue() doesn't fail if object doesn't match type). (Joe) - -- Session: - . Improved fix for bug #68063 (Empty session IDs do still start sessions). - (Yasuo) - . Fixed bug #71038 (session_start() returns TRUE on failure). - Session save handlers must return 'string' always for successful read. - i.e. Non-existing session read must return empty string. PHP 7.0 is made - not to tolerate buggy return value. (Yasuo) - . Fixed bug #71394 (session_regenerate_id() must close opened session on - errors). (Yasuo) - -- SQLite3: - . Implemented FR #71159 (Upgraded bundled SQLite lib to 3.9.2). (Laruence) - -- Standard: - . Fixed bug #71100 (long2ip() doesn't accept integers in strict mode). - (Laruence) - . Implemented FR #55716 (Add an option to pass a custom stream context to - get_headers()). (Ferenc) - . Additional validation for parse_url() for login/pass components). - (Ilia) (Julien) - . Implemented FR #69359 (Provide a way to fetch the current environment - variables). (Ferenc) - . unpack() function accepts an additional optional argument $offset. (Dmitry) - . Implemented #51879 stream context socket option tcp_nodelay (Joe) + . Use Zend MM for allocation in bundled libxmlrpc (Joe) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> + diff --git a/README.GIT-RULES b/README.GIT-RULES index a88a8c9f32..d7143e6b9d 100644 --- a/README.GIT-RULES +++ b/README.GIT-RULES @@ -38,21 +38,26 @@ Having said that, here are the organizational rules:: 6. Test your changes before committing them. We mean it. Really. To do so use "make test". - 7. For development use the --enable-maintainer-zts switch to ensure your - code handles TSRM correctly and doesn't break for those who need that. + 7. For development use the --enable-debug switch to avoid memory leaks + and the --enable-maintainer-zts switch to ensure your code handles + TSRM correctly and doesn't break for those who need that. Currently we have the following branches in use:: master The active development branch. + PHP-7.1 Is used to release the PHP 7.1.x series. This is a prerelease + version. + + PHP-7.0 Is used to release the PHP 7.0.x series. This is a current + stable version and is open for bugfixes only. + PHP-5.6 Is used to release the PHP 5.6.x series. This is a current stable version and is open for bugfixes only. - PHP-5.5 Is used to release the PHP 5.5.x series. This is an old - stable version and is open for security fixes only. + PHP-5.5 This branch is closed. - PHP-5.4 Is used to release the PHP 5.4.x series. This is an old - stable version and is open for security fixes only. + PHP-5.4 This branch is closed. PHP-5.3 This branch is closed. diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index ae92e1fbf1..7fa38198de 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -208,6 +208,7 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0; BYTE * psec_desc = NULL; BOOL fAccess = FALSE; + realpath_cache_bucket * bucket = NULL; char * real_path = NULL; @@ -425,7 +426,7 @@ static process_pair *process_get(FILE *stream) return ptr; } -static shm_pair *shm_get(int key, void *addr) +static shm_pair *shm_get(key_t key, void *addr) { shm_pair *ptr; shm_pair *newptr; @@ -638,17 +639,13 @@ TSRM_API int pclose(FILE *stream) return termstat; } -TSRM_API int shmget(int key, int size, int flags) +TSRM_API int shmget(key_t key, size_t size, int flags) { shm_pair *shm; char shm_segment[26], shm_info[29]; HANDLE shm_handle, info_handle; BOOL created = FALSE; - if (size < 0) { - return -1; - } - snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key); snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key); @@ -657,7 +654,14 @@ TSRM_API int shmget(int key, int size, int flags) if (!shm_handle && !info_handle) { if (flags & IPC_CREAT) { - shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment); +#if SIZEOF_SIZE_T == 8 + DWORD high = size >> 32; + DWORD low = (DWORD)size; +#else + DWORD high = 0; + DWORD low = size; +#endif + shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment); info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info); created = TRUE; } diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h index fbeac07b01..ae0ea58c96 100644 --- a/TSRM/tsrm_win32.h +++ b/TSRM/tsrm_win32.h @@ -26,9 +26,10 @@ #if HAVE_UTIME # include <sys/utime.h> #endif +#include "win32/ipc.h" struct ipc_perm { - int key; + key_t key; unsigned short uid; unsigned short gid; unsigned short cuid; @@ -39,7 +40,7 @@ struct ipc_perm { struct shmid_ds { struct ipc_perm shm_perm; - int shm_segsz; + size_t shm_segsz; time_t shm_atime; time_t shm_dtime; time_t shm_ctime; @@ -105,7 +106,7 @@ TSRM_API int pclose(FILE *stream); TSRM_API int tsrm_win32_access(const char *pathname, int mode); TSRM_API int win32_utime(const char *filename, struct utimbuf *buf); -TSRM_API int shmget(int key, int size, int flags); +TSRM_API int shmget(key_t key, size_t size, int flags); TSRM_API void *shmat(int key, const void *shmaddr, int flags); TSRM_API int shmdt(const void *shmaddr); TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf); @@ -1,4 +1,4 @@ -PHP 7.1 UPGRADE NOTES +PHP 7.2 UPGRADE NOTES 1. Backward Incompatible Changes 2. New Features @@ -20,246 +20,70 @@ PHP 7.1 UPGRADE NOTES ======================================== - Core: - . 'void' can no longer be used as the name of a class, interface, or trait. - This applies to declarations, class_alias() and use statements. - . 'iterable' can no longer be used as the name of a class, interface, or - trait. This applies to declarations, class_alias() and use statements. - (RFC: https://wiki.php.net/rfc/iterable) - . (int), intval() where $base is 10 or unspecified, settype(), decbin(), - decoct(), dechex(), integer operators and other conversions now always - respect scientific notation in numeric strings. - (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic) - . The ASCII 0x7F Delete control character is no longer permitted in unquoted - identifiers in source code. - . The following functions may no longer be called dynamically using $func(), - call_user_func(), array_map() or similar: - . extract() - . compact() - . get_defined_vars() - . func_get_args() - . func_get_arg() - . func_num_args() - . parse_str() with one argument - . mb_parse_str() with one argument - . assert() with a string argument - (RFC: https://wiki.php.net/rfc/forbid_dynamic_scope_introspection) - . If the error_log is set to syslog, the PHP error levels are mapped to the - syslog error levels. This brings finer differentiation in the error logs - in contrary to the previous approach where all the errors are loggged with - the notice level only. - . Don't call destructors of incompletely constructed objects, even if they - are kept referenced. See bug #29368 and Zend/tests/bug29368_1.phpt. - . call_user_func() will now consistently throw a warning if a function with - reference arguments is called. However, call_user_func() will no longer - abort the call in this case. - . rand() and srand() are now aliases of mt_rand() and mt_srand(). - Consequently the output of the following functions has changed: - . rand() - . shuffle() - . str_shuffle() - . array_rand() - . Fixes to random number generators mean that mt_rand() now produces a - different sequence of outputs to previous versions. If you relied on - mt_srand() to produce a deterministic sequence, it can be called using - mt_srand($seed, MT_RAND_PHP) to produce the old sequences. - . URL rewriter has been improved. - . Use dedicated buffer for Session module rewrite and User rewrite. - . Full path URL rewrite is supported. Allowed domain can be specified. - $_SERVER['HTTP_HOST'] is allowed by default when host whitelist is empty. - . Use session.trans_sid_tags and session.trans_sid_hosts to control - session rewrite. - . Use url_rewriter.tags and url_rewriter.hosts to control user rewrite. - . <form>'s "action" attribute is used to check if URL rewrite is allowed - and listed under hosts whitelist. - . <fieldset> is no longer considered as a special tag. <form> is the - only tag considered special. - . Calling a function with less arguments than mandatory declared ones in - signature now issues a Fatal Error (Error Exception) instead of a Warning. - (RFC https://wiki.php.net/rfc/too_few_args). - . The error message for E_RECOVERABLE errors has been changed from "Catchable - fatal error" to "Recoverable fatal error". - . The empty index operator (e.g. $str[] = $x) is not supported for strings - anymore, and throws a fatal error instead of silently converting to array. - . Array elements or object properties that are automatically created during - by-reference assignments will now result in a different order. For example - - $array = []; - $array["a"] =& $array["b"]; - $array["b"] = 1; - var_dump($array); - - now results in the array ["b" => 1, "a" => 1], while for PHP 7.0 the result - was ["a" => 1, "b" => 1]. - -- JSON: - . The serialize_precision is used instead of precision when encoding double - values. - . An empty key is decoded as an empty property name instead of using _empty_ - property name when decoding object to stdClass. - . When calling json_encode with JSON_UNESCAPED_UNICODE option, U+2028 and - U+2029 are escaped. - -- mbstring: - . mb_ereg() and mb_eregi() will now set the $regs argument to an empty array, - if nothing matched. Formerly, $regs was not modified in that case. - -- OpenSSL: - . Dropped sslv2 stream. - -- Session: - . Session ID is generated from CSPNG directly. As a result, Session ID length - could be any length between 22 and 256. Note: Max size of session ID depends - on save handler you are using. - . Following INIs are removed - . session.hash_function - . session.hash_bits_per_charactor - . session.entropy_file - . session.entropy_length - . New INIs and defaults - . session.sid_length (Number of session ID characters - 22 to 256. - (php.ini-* default: 26 Compiled default: 32) - . session.sid_bits_per_character (Bits used per character. 4 to 6. - php.ini-* default: 5 Compiled default: 4) - Length of old session ID string is determined as follows - . Used hash function's bits. - . session.hash_function=0 - MD5 128 bits (This was default) - . session.hash_function=1 - SHA1 192 bits - . Bits per character. (4, 5 or 6 bits per character) - . Examples - MD5 and 4 bits = 32 chars, ceil(128/4)=32 - MD5 and 5 bits = 26 chars, ceil(128/5)=26 - MD5 and 6 bits = 22 chars, ceil(128/6)=22 - SHA1 and 4 bits = 48 chars, ceil(192/4)=48 - SHA2 and 5 bits = 39 chars, ceil(192/5)=39 - SHA1 and 6 bits = 32 chars, ceil(192/6)=32 - and so on. - . session_start() returns FALSE and no longer initializes $_SESSION when - it failed to start session. - -- Reflection: - . The behavior of ReflectionMethod::invoke() and ::invokeArgs() has been - aligned, which causes slightly different behavior than before for some - pathological cases. + . gettype() will now return "resource (closed)" instead of "unknown type" for + closed resources. + . is_object() will now return true for objects of class + __PHP_Incomplete_Class. ======================================== 2. New Features ======================================== -- Core - . Added void return type, which requires that a function not return a value. - (RFC: https://wiki.php.net/rfc/void_return_type) - . Added iterable pseudo-type accepting any array or object implementing - Traversable. - (RFC: https://wiki.php.net/rfc/iterable) - . String offset access now supports negative references, which will be - counted from the end of the string. - (RFC: https://wiki.php.net/rfc/negative-string-offsets) - . Added a form of the list() construct where keys can be specified. - (RFC: https://wiki.php.net/rfc/list_keys) - . Added [] = as alternative construct to list() =. - (RFC: https://wiki.php.net/rfc/short_list_syntax) - . Number operators taking numeric strings now emit "A non well formed numeric - value encountered" E_NOTICEs for leading-numeric strings, and "A - non-numeric value encountered" E_WARNINGs for non-numeric strings. - This always applies to the +, -, *, /, **, %, << and >> operators, and - their assignment counterparts +=, -=, *=, /=, **=, %=, <<= and >>=. - For the bitwise operators |, & and ^, and their assignment counterparts - |=, &= and ^=, this only applies where only one operand is a string. - Note that this never applies to the bitwise NOT operator, ~, which does not - handle numeric strings, nor to the increment and decrement operators - ++ and --, which have a unique approach to handling numeric strings. - (RFC: https://wiki.php.net/rfc/invalid_strings_in_arithmetic) - . Closure::fromCallable (RFC: https://wiki.php.net/rfc/closurefromcallable) - . Added support for class constant visibility modifiers. - (RFC: https://wiki.php.net/rfc/class_const_visibility) - . TypeError messages for arg_info type checks will now say "must be ... - or null", or "must ... or be null" where the parameter or return type - accepts null. arg_info type checks are used by all userland functions with - type declarations, and some internal functions. Both nullable type - declarations (?int) and parameters with default values of null - (int $foo = NULL) are considered to "accept null" for this purpose. - . The simple syntax for variable parsing inside of string literals now - supports negative offsets. + +- PCRE: + . Added `J` modifier for setting PCRE_DUPNAMES. + +- Standard: + . Simplified password hashing API updated to support Argon2i hashes when PHP is compiled with libargon2 + (https://wiki.php.net/rfc/argon2_password_hash). + . proc_nice() is now supported on Windows platforms. ======================================== 3. Changes in SAPI modules ======================================== -- apache2handler: - . Implemented per module logging. - . Implemented error level mapping between PHP and Apache for the error logs. ======================================== 4. Deprecated Functionality ======================================== -- 'e' option of mb_ereg_replace() and mb_eregi_replace(). -- ext/mcrypt is now fully deprecated. - ======================================== 5. Changed Functions ======================================== -- get_headers() has an extra parameter which allows passing a custom stream - context. -- The first $varname argument for getenv() is no longer mandatory, the - current environment variables will be returned as an associative array - when omitted. -- json_encode() accepts new option JSON_UNESCAPED_LINE_TERMINATORS that - disables escaping of U+2028 and U+2029 characters when - JSON_UNESCAPED_UNICODE is supplied. -- long2ip() accepts integer as parameter now -- pg_last_notice() accepts optional long parameter to specify operation. - PGSQL_NOTICE_LAST - Get last notice (Default) - PGSQL_NOTICE_ALL - Get all stored notices - PGSQL_NOTICE_CLEAR - Remove all stored notices - It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls. - It returned FALSE for empty notice previously. -- pg_fetch_all() accepts 2nd optional result type parameter like - pg_fetch_row(). -- pg_select() accepts 4th optional result type parameter like pg_fetch_row(). -- parse_url() is more restrictive now and supports RFC3986. -- unpack() accepts an additional optional $offset argument. '@' format code - (that specifes an absolute position) is applyed to input data after - the $offset argument. -- strpos(), stripos(), substr_count(), grapheme_strpos(), grapheme_stripos(), - grapheme_extract(), iconv_strpos(), mb_strimwidth(), mb_ereg_search_setpos(), - mb_strpos() and mb_stripos() now accept negative string offsets. -- substr_count() and mb_strimwidth() additionally also accept negative length. -- file_get_contents() accepts a negative seek offset if the stream is seekable. -- tempnam() throws a notice when failing back to the system temp dir. -- getopt() has an extra by-ref parameter : optind -- mb_ereg() and mb_ereg_replace() reject illegal byte sequences. -- FILTER_FLAG_EMAIL_UNICODE can be used with filter_var() for email validation - according to RFC 6531. -- output_reset_rewrite_vars() no longer reset session URL rewrite vars. -- the lasinsertid() in pdo_pgsql extension triggers an error, when no nextval() - were called in in the current session. +- Standard: + . password_hash() can generate Argon2i hashes when the algorithm is set to PASSWORD_ARGON2I. + When using PASSWORD_ARGON2I, the following cost factors may be set: 'memory_cost', 'time_cost', + and 'threads'. These cost factors will default to 'PASSWORD_ARGON2_DEFAULT_MEMORY_COST', + 'PASSWORD_ARGON2_DEFAULT_TIME_COST', and 'PASSWORD_ARGON2_DEFAULT_THREADS' respectively if not set. + . password_verify() can verify Argon2i hashes. + . password_get_info() and password_needs_rehash() can accept Argon2i hashes. + . mail()/mb_send_mail() accept array $extra_header. Array paramter is checked against RFC 2822. + Array format is + $extra_headers = [ + 'Header-Name' => 'Header value', + 'Multiple' => ['One header', 'Another header'], + 'Multiline' = "FirstLine\r\n SecondLine", + ]; + +- XML: + . utf8_encode() and utf8_decode() have been moved to the Standard extension + as string functions. ======================================== 6. New Functions ======================================== -- Core: - . Added sapi_windows_cp_set(), sapi_windows_cp_get(), sapi_windows_cp_is_utf8(), - sapi_windows_cp_conv() for codepage handling. - -- cURL: - . Added curl_multi_errno() and curl_share_errno() to return the last error - number of curl_multi and curl_share resources. - . Added curl_share_strerror() to convert error code to error message text - describing the error. -- pcntl: - . Added pcntl_signal_get_handler() that returns the current signal handler - for a particular signal. +- GD: + . Added imagesetclip() and imagegetclip(). + . Added imageopenpolygon(). + . Added imageresolution(). -- Session: - . Added session_gc() that performs session data garbage collection. - https://wiki.php.net/rfc/session-gc - . Added session_create_id() for creating custom session ID. - https://wiki.php.net/rfc/session-create-id +- Mbstring: + . Added mb_chr() and mb_ord(). + . Added mb_scurb() that scrub broken multibyte strings. -- Standard: - . Added is_iterable() that determines if a value will be accepted by the new - iterable pseudo-type. +- Sockets: + . Added socket_addrinfo_lookup(), socket_addrinfo_connect(), + socket_addrinfo_bind() and socket_addrinfo_explain(). ======================================== 7. New Classes and Interfaces @@ -273,201 +97,53 @@ PHP 7.1 UPGRADE NOTES 9. Other Changes to Extensions ======================================== -- Date: - . Invalid serialization data for a DateTime or DatePeriod object will now - throw an instance of Error from __wakeup() or __set_state() instead of - resulting in a fatal error. - . Timezone initialization failure from serialized data will now throw an - instance of Error from __wakeup() or __set_state() instead of resulting in - a fatal error. - -- DBA: - . Data modification functions (e.g.: dba_insert()) now throw an instance of - Error instead of triggering a catchable fatal error if the key does not - contain exactly two elements. - -- DOM: - . Invalid schema or RelaxNG validation contexts will throw an instance of - Error instead of resulting in a fatal error. - . Attempting to register a node class that does not extend the appropriate - base class will now throw an instance of Error instead of resulting in a - fatal error. - . Attempting to read an invalid or write to a readonly property will throw - an instance of Error instead of resulting in a fatal error. +- EXIF: + . Added extended exif tag support for the following formats: + Samsung, DJI, Panasonic, Sony, Pentax, Minolta & Sigma/Foveon. - GD: - . Changed the default of the ini setting gd.jpeg_ignore_warning to 1. - -- IMAP: - . An email address longer than 16385 bytes will throw an instance of Error - instead of resulting in a fatal error. - -- Intl: - . Failure to call the parent constructor in a class extending Collator - before invoking the parent methods will throw an instance of Error - instead of resulting in a recoverable fatal error. - . Cloning a Transliterator object may will now throw an instance of Error - instead of resulting in a fatal error if cloning the internal - transliterator fails. - -- LDAP: - . Providing an unknown modification type to ldap_batch_modify() will now - throw an instance of Error instead of resulting in a fatal error. - -- Mbstring: - . mb_ereg() and mb_eregi() will now throw an instance of ParseError if an - invalid PHP expression is provided and the 'e' option is used. - -- Mcrypt: - . mcrypt_encrypt() and mcrypt_decrypt() will throw an instance of Error - instead of resulting in a fatal error if mcrypt cannot be initialized. - -- Mysqli: - . Attempting to read an invalid or write to a readonly property will throw - an instance of Error instead of resulting in a fatal error. - -- Reflection: - . Failure to retrieve a reflection object or retrieve an object property - will now throw an instance of Error instead of resulting in a fatal error. + . Removed --enable-gd-native-ttf configuration option which was unused as + of PHP 5.5.0 anyway. + . imagegd() stores truecolor images as real truecolor images. Formerly, they + have been converted to palette. + . imageantialias() is now also available if compiled with a system libgd. -- Session: - . Custom session handlers that do not return strings for session IDs will - now throw an instance of Error instead of resulting in a fatal error - when a function is called that must generate a session ID. - . Only CSPRNG is used to generate session ID. - -- SimpleXML: - . Creating an unnamed or duplicate attribute will throw an instance of Error - instead of resulting in a fatal error. - -- SPL: - . Attempting to clone an SplDirectory object will throw an instance of Error - instead of resulting in a fatal error. - . Calling ArrayIterator::append() when iterating over an object will throw an - instance of Error instead of resulting in a fatal error. - -- SQLite3: - . Upgraded bundled SQLite lib to 3.13.0 - -- Standard: - . assert() will throw a ParseError when evaluating a string given as the first - argument if the PHP code is invalid instead of resulting in a catchable - fatal error. - . Calling forward_static_call() outside of a class scope will now throw an - instance of Error instead of resulting in a fatal error. - -- Tidy: - . Creating a tidyNode manually will now throw an instance of Error instead of - resulting in a fatal error. - -- WDDX: - . A circular reference when serializing will now throw an instance of Error - instead of resulting in a fatal error. - -- XML-RPC: - . A circular reference when serializing will now throw an instance of Error - instead of resulting in a fatal error. - -- Zip: - . ZipArchive::addGlob() will throw an instance of Error instead of resulting - in a fatal error if glob support is not available. +- Mbstring + . mb_check_encoding() accepts array parameter. Both key and value + ecodings are checked recursively. + . mb_convert_encoding() accepts array parameter. Only value encodings + are converted recursively. ======================================== 10. New Global Constants ======================================== - Core: - . PHP_FD_SETSIZE + . PHP_FLOAT_DIG + . PHP_FLOAT_EPSILON + . PHP_FLOAT_MIN + . PHP_FLOAT_MAX -- JSON: - . JSON_UNESCAPED_LINE_TERMINATORS - -- Pgsql: - PGSQL_NOTICE_LAST - PGSQL_NOTICE_ALL - PGSQL_NOTICE_CLEAR +- GD: + . IMG_EFFECT_MULTIPLY - Standard: - . IMAGETYPE_WEBP + . PASSWORD_ARGON2_DEFAULT_MEMORY_COST + . PASSWORD_ARGON2_DEFAULT_TIME_COST + . PASSWORD_ARGON2_DEFAULT_THREADS + . PASSWORD_ARGON2I ======================================== 11. Changes to INI File Handling ======================================== -- serialize_precision - . If the value is set to -1, then the dtoa mode 0 is used. The value -1 - is now used by default. - -- precision - . If the value is set to -1, then the dtoa mode 0 is used. No changes - in default value which is still 14. +- sql.safe_mode + . This INI directive have been removed. ======================================== 12. Windows Support ======================================== -- Core: - . Support for long and UTF-8 path; - - If an application is UTF-8 conform, no further action is required. For - applications depending on paths in non UTF-8 encodings for I/O, an explicit - INI directive has to be set. The encoding INI settings check relies on the - order in the core: - - internal_encoding - - default_charset - - zend.multibyte - - Several functions for codepage handling were itroduced: - - sapi_windows_cp_set() to set the default codepage - - sapi_windows_cp_get() to retrieve the current codepage - - sapi_windows_cp_is_utf8() - - sapi_windows_cp_conv() to convert between codepages, using iconv() - compatible signature - These functions are thread safe. - - The console output codepage is adjusted depending on the encoding used in - PHP. Depending on the concrete system OEM codepage, the visible output - might or might be not correct. For example, in the default cmd.exe and on - a system with the OEM codepage 437, outputs in codepages 1251, 1252, 1253 - and some others can be shown correctly when using UTF-8. On the same system, - chars in codepage like 20932 probably won't be shown correctly. This refers - to the particular system rules for codepage, font compatibility and the - particular console program used. PHP automatically sets the console codepage - according to the encoding rules from php.ini. Using alternative consoles - instead of cmd.exe directly might bring better experience in some cases. - Nevertheless be aware, runtime codepage switch after the request start - might bring unexpected side effects on CLI. The preferrable way is php.ini. - - As a result of UTF-8 support in the streams, PHP scripts are not limited - to ASCII or ANSI filenames anymore. This is supported out of the box on - CLI. For other SAPI, the documentation for the corresponding server - is useful. - - Long paths support is transparent. Paths longer than 260 bytes get - automatically prefixed with \\?\. The max path length is limited to - 2048 bytes. Be aware, that the path segment limit (basename length) still - persists. - - The recommended way to handle file paths, I/O and other related topics is - by utilizing UTF-8. - - . Support for ftok() - -- FCGI - . PHP_FCGI_CHILDREN is respected. If this environment variable is defined, - the first php-fcgi.exe process will exec the specified number of children. - Those will share the same TCP socket. - -- readline: - . The readline extension is supported through the WinEditLine library - (http://mingweditline.sourceforge.net/). Thereby, the interactive CLI - shell is supported as well (php.exe -a). - - It is well known, but nevertheless is worth mentioning again, that - the readline extension is not thread safe and will never be. Thus, - the usage of it with any true thread safe SAPI (like Apache mod_winnt) is - strongely discouraged. - ======================================== 13. Other Changes ======================================== diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 710c131297..71ade7becc 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -1,10 +1,7 @@ PHP 7.1 INTERNALS UPGRADE NOTES -0. Wiki Examples 1. Internal API changes - e. Codepage handling on Windows - f. Path handling on Windows - g. SAPI logging + a. 2. Build system changes a. Unix build system changes @@ -12,68 +9,11 @@ PHP 7.1 INTERNALS UPGRADE NOTES 3. Module changes -================ -0. Wiki Examples -================ - -The wiki contains multiple examples and further explanations of the internal -changes. See: https://wiki.php.net/phpng-upgrading - - ======================== 1. Internal API changes ======================== - e. Codepage handling on Windows - - A set of new APIs was introduced, which allows to handle codepage - conversions. The corresponding prototypes and macros are contained - in win32/codepage.h. - - Functions with php_win32_cp_* signatures provide handling for various - codepage aspects. Primarily they are in use at various places in the - I/O utils code and directly in the core where necessary, providing - conversions to/from UTF-16. Arbitrary conversions between codepages - are possible as well, whereby UTF-16 will be always an intermediate - state in this case. - - For input length arguments, the macro PHP_WIN32_CP_IGNORE_LEN can be - passed, then the API will calculate the length. For output length - arguments, the macro PHP_WIN32_CP_IGNORE_LEN_P can be passed, then - the API won't set the output length. - - The mapping between encodings and codepages is provided by the predefined - array of data contained in win32/cp_enc_map.c. To change the data, - a generator win32/cp_enc_map_gen.c needs to be edited and run. - - f. Path handling on Windows - - A set of new APIs was introduced, which allows to handle UTF-8 paths. The - corresponding prototypes and macros are contained in win32/ioutil.h. - - Functions with php_win32_ioutil_* signatures provide POSIX I/O analogues. - These functions are integrated in various places across the code base to - support Unicode filenames. While accepting char * arguments, internally - the conversion to wchar_t * happens. Internally almost no ANSI APIs are - used, but directly their wide equivalents. The string conversion rules - correspond to those already present in the core and depend on the current - encoding settings. Doing so allows to move away from the ANSI Windows API - with its dependency on the system OEM/ANSI codepage. - - Thanks to the wide API usage, the long paths are now supported as well. The - PHP_WIN32_IOUTIL_MAXPATHLEN macro is defined to 2048 bytes and will override - the MAXPATHLEN in files where the header is included. - - The most optimal use case for scripts is utilizing UTF-8 for any I/O - related functions. UTF-8 filenames are supported on any system disregarding - the system OEM/ANSI codepage. - - g. SAPI logging - The log_message callback in the SAPI struct was extended with the severity - argument. This allows SAPI modules to implement mapping between PHP and - corresponding server error levels. A reference mapping implementation - can be found in apache2handler. - + a. ======================== 2. Build system changes @@ -82,8 +22,10 @@ changes. See: https://wiki.php.net/phpng-upgrading a. Unix build system changes b. Windows build system changes - Static analysis with clang and Cppcheck is supported by passing "clang" or - "cppcheck" keyword to the --with-analyzer configure option. + + * nice() now have a Windows alternative that is implemented in win32/nice.c, using + SetPriorityClass(). See the implementation for more in-depth details. This also + defines HAVE_NICE. ======================== 3. Module changes diff --git a/Zend/RFCs/001.txt b/Zend/RFCs/001.txt deleted file mode 100644 index bf1d847b97..0000000000 --- a/Zend/RFCs/001.txt +++ /dev/null @@ -1,136 +0,0 @@ -Revamped object model using object handles -=========================================== - -Background ----------- - -In the Zend Engine 1.0 (and its predecessor the PHP 3 scripting -engine) the object model's design is that instantiated objects are -language values. This means that when programmers are performing -operations, such variable assignment and passing parameters to -functions, objects are handled very similarly to the way other -primitive types are handled such as integers and strings. -Semantically this means that the whole object is being copied. The -approach Java takes is different where one refers to objects by handle -and not by value (one can think of a handle as an objects' ID). - -Need ----- - -Unfortunately, the approach taken up to now has severely limited the -Zend Engine's object oriented model, both feature and simplicity -wise. One of the main problems with the former approach is that object -instantiation and duplication is very hard to control, a problem which -can not only lead to inefficient development but also often to strange -run-time behavior. Changing the object model to a handle oriented -model will allow the addressing of many needs such as destructors, -de-referencing method return values, tight control of object -duplication and more. - -Overview --------- - -The proposed object model is very much influenced by the Java -model. In general, when you create a new object you will be getting a -handle to the object instead of the object itself. When this handle is -sent to functions, assigned and copied it is only the handle which is -copied/sent/assigned. The object itself is never copied nor -duplicated. This results in all handles of this object to always point -at the same object making it a very consistent solution and saving -unnecessary duplication and confusing behavior. - -Functionality -------------- - -After this change the basic use of objects will be almost identical to -previous versions of the scripting engine. However, you won't bump -into awkward and confusing copying & destructing of objects. In order -to create and use a new object instance you will do the following: -$object = new MyClass(); $object->method(); - -The previous code will assign $object the handle of a new instance of -the class MyClass and call one of its methods. - - -Consider the following code: - -1 class MyClass -2 { -3 function setMember($value) -4 { -5 $this->member = $value; -6 } -7 -8 function getMember() -9 { -10 return $this->member; -11 } -12 } -13 -14 function foo($obj) -15 { -16 $obj->setMember("foo"); -17 } -18 -19 $object = new MyClass(); -20 $object->setMember("bar"); -21 foo($object); -22 print $object->getMember(); - -Without the new Java-like handles, at line 20 the objects' data member -member is set to the string value of "bar". Because of the internal -representation of objects in the Zend Engine 1.0, the object is marked -as a reference, and when it is sent by value to the function foo, it -is duplicated (!). Therefore, the call to foo() on line 21 will -result in the $obj->setMember("foo") call being called on a duplicate -of $object. Line 22 will then result in "bar" being printed. - -This is how the scripting engine has worked until today. Most -developers are probably unaware of the fact that they aren't always -talking to the same object but often duplicates; others may have -realized this can usually be solved by always passing objects by -reference (unless a replica is actually desired, which is uncommon). - -The new object model will allow for a much more intuitive -implementation of the code. On line 21, the object's handle (ID) is -passed to foo() by value. Inside foo(), the object is fetched -according to this handle and, therefore, the setMember() method is -called on the originally instantiated object and not a copy. Line 22 -will therefore result in "foo" being printed. This approach gives -developers tighter control of when objects are created and duplicated. -An additional not-as-important benefit is that the object handle will -be passed to foo() by value, which most probably will also save -unnecessary duplication of the value containing the ID itself and thus -additionally improving run-time performance. - -This was just a simple description of why the new object model solves -awkward behavior and makes object handling much easier, intuitive and -efficient. The importance of this change goes far beyond what is -mentioned in this section as you will see in further sections which -describe new features with a majority of them being based on this -change. - -Compatibility Notes --------------------- - -Many PHP programmers aren't even aware of the copying quirks of the -current object model and, therefore, there is a relatively good chance -that the amount of PHP applications that will work out of the box or -after a very small amount of modifications would be high. - -To simplify migration, version 2.0 will support an optional -'auto-clone' feature, which will perform a cloning of the object -whenever it would have been copied in version 1.0. Optionally, it -will also be possible to request that the engine will emit an E_NOTICE -message whenever such an automatic clone occurs, in order to allow -developers to gradually migrate to the version 2.0-style behavior -(without automatic clones). - -Dependencies ------------- - -The new object model is not dependent on other features. Many of the -other Zend Engine 2.0 features, such as the $foo->bar()->barbara() -syntax, destructors and others completely rely on this new object -model. - diff --git a/Zend/RFCs/002.txt b/Zend/RFCs/002.txt deleted file mode 100644 index 7d7cb885d8..0000000000 --- a/Zend/RFCs/002.txt +++ /dev/null @@ -1,169 +0,0 @@ -Title: Zend 2.0 Namespaces -Version: $Id$ -Status: declined -Maintainer: Stig S. Bakken <ssb@php.net> -Created: 2001-09-08 -Modified: 2001-09-08 - - -1. Background/Need -================== - -PHP and Zend 1.0 have come to a point where a lot of reusable code is -being written; from simple functions and classes to entire application -frameworks. It is becoming increasingly difficult to avoid symbol -name collisions with the current scoping methods. - -The symbol scopes available in Zend 1.0 are the global scope, the -class scope and the function scope. All scopes but classes may -contain variables, only the class and global scopes may contain -functions, while only the global scope may contain constants and -classes. This means that all of Zend 1.0's scoping methods are -inherently limited for solving symbol name collision problems. - - -2. Overview -=========== - -Namespaces in Zend 2.0 provide a way to manage the symbol collision -problem by making it possible to define multiple symbol tables able to -contain all types of symbols. Zend will get the notion of a current -namespace, defaulting to the current global one. The current name -space may be changed on a file-by-file basis. Symbols in other name -spaces than the current one may be referenced using a new namespace -operator. It will be possible to "import" symbols from one namespace -into another. - - -3. Functionality -================ - -3.1. Namespace Syntax -===================== - -The namespace operator ":" is used to refer to symbols in other -namespaces than the current one: - -Class: Namespace:class -Function: Namespace:function -Static method: Namespace:class::method -Variable: $Namespace:variable -Constant: Namespace:CONSTANT -Class variable: $Namespace:class::variable - -To refer to symbols in the global namespace, symbols are prefixed with -only the namespace operator: - -Class: :class -Function: :function -Static method: :class::method -Variable: $:variable -Constant: :CONSTANT -Class variable: $:class::variable - -Note: $:variable will effectively be just another syntax for -$GLOBALS['variable']. - -A namespace may have a name containing a ":", it is always the last -":" character in the symbol qualifier that is the actual namespace -operator: - -Class: Name:Space:class -Function: Name:Space:function -Static method: Name:Space:class::method -Variable: $Name:Space:variable -Constant: Name:Space:CONSTANT -Class variable: $Name:Space:class::variable - -(Here, the ":" between "Name" and "Space" is part of the name, it is -the one after "Space" that is the namespace operator.) - - -3.2. Defining Namespaces -======================== - -Individual files may define a namespace that will apply to the entire -file. If no "namespace" operator occurs in the file, it will be in -the global namespace: - - 1 namespace HTML; - 2 - 3 class Form { - 4 function Form() { - 5 // constructor - 6 } - 7 // ... - 8 } - -Or with the "nested" name syntax: - - 1 namespace HTML:Form; - 2 - 3 class Image { - 4 var $src; - 5 function Image($src) { - 6 $this->src = $src; - 7 } - 8 // ... - 9 } - -Code executed within the "HTML" namespace may refer to the Form class -as just "Form". Code executed from within other namespaces has to -refer to it as "HTML:Form". The "namespace" statement must occur -before any other statements in the file. - -# [ssb 2001-09-08]: -# Should it be possible to "add" symbols to a namespace by including a -# second file with the same namespace statement? - - -3.3. Importing Symbols -====================== - -It is possible to import symbols from another namespace into the -current one with the "import" statement: - - import * from HTML; // all symbols - - import Form from HTML; // single symbols - - import Form,Table from HTML; // multiple symbols - -There is a potential for name clashes between symols of different -types that have the same qualifier syntax. These are resolved in this -order: class, function, constant. - -Optionally, the symbol type may be explicitly given to import (as -"class", "function", "variable" or "constant"): - - import class Form from HTML; - -And finally, you may import all symbols of a given type: - - import constant * from HTML:Table; - -The namespace with its symbols must already be defined before using -"import". - - -4. Compatibility Notes -====================== - -Old code that does not take advantage of namespaces will run without -modifications. - - -5. Dependencies -=============== - -The class variable syntax depends on this class variables being -implemented in the new ZE2 object model. - - -6. Acknowledgements -=================== - -Andi Gutmans <andi@zend.com> and Zeev Suraski <zeev@zend.com> for -initial ZE2 namespaces proposal - -Dean Hall <php@apt7.com> for the initial symbol qualification syntax diff --git a/Zend/RFCs/003.txt b/Zend/RFCs/003.txt deleted file mode 100644 index ac042183d4..0000000000 --- a/Zend/RFCs/003.txt +++ /dev/null @@ -1,72 +0,0 @@ -Title: Loose type requirements for functions -Version: $Id$ -Status: draft -Maintainer: Brian Moon <brianm@dealnews.com> -Created: 2001-09-17 -Modified: 2001-09-17 - - -1. Background/Need -================== - -Many internal functions of PHP will reject parameters because of their -type (the array and variable function come to mind). For userland -this is not an easy task as there is no uniform way to do it. An -addition to the engine for requiring loose types would allow -developers to know that the data passed to their functions are of the -correct type and reduce the need for duplicating the same code in -every function to check for the type of data. - - -2. Overview -=========== - -Loose typing mostly means evaluating the contents of the variable and -not the type of the variable itself. The requirements for this would -and should work much like several of the is_* functions do now. - -The typing of parameters would be optional and those not typed would -simply continue to be treated as they are now. - -3. Functionality -================ - -3.1. Allowed Types -================== - -Only loose types should be needed to ensure the data is usable by the -function. Duplicating the functionallity of is_scalar, is_resource, -is_array and is_object should give developers all the information they -need to use a variable correctly. - -3.2. Syntax -=========== - -The current function syntax should be expanded to allow typing of -variables inline in a C style. - -function foo ($var){ -} - -could be changed to require an array such as: - -function foo (array $var){ -} - -3.3. Errors -=========== - -Mis-matches in type should be reported as fatal errors and should halt -the execution of a script as that function cannot be run and code -following could not reliably run. - - -4. Compatibility Notes -====================== - -Old code that does not take advantage of this will run without -modifications. - - - - diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 9d3b46a755..a1c1d3b07b 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -466,3 +466,140 @@ else HAVE_GCC_GLOBAL_REGS=no fi AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS) + +dnl +dnl Check if atof() accepts NAN +dnl +AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[ +AC_TRY_RUN([ +#include <math.h> +#include <stdlib.h> + +#ifdef HAVE_ISNAN +#define zend_isnan(a) isnan(a) +#elif defined(HAVE_FPCLASS) +#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) +#else +#define zend_isnan(a) 0 +#endif + +int main(int argc, char** argv) +{ + return zend_isnan(atof("NAN")) ? 0 : 1; +} +],[ + ac_cv_atof_accept_nan=yes +],[ + ac_cv_atof_accept_nan=no +],[ + ac_cv_atof_accept_nan=no +])]) +if test "$ac_cv_atof_accept_nan" = "yes"; then + AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN]) +fi + +dnl +dnl Check if atof() accepts INF +dnl +AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[ +AC_TRY_RUN([ +#include <math.h> +#include <stdlib.h> + +#ifdef HAVE_ISINF +#define zend_isinf(a) isinf(a) +#elif defined(INFINITY) +/* Might not work, but is required by ISO C99 */ +#define zend_isinf(a) (((a)==INFINITY)?1:0) +#elif defined(HAVE_FPCLASS) +#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF)) +#else +#define zend_isinf(a) 0 +#endif + +int main(int argc, char** argv) +{ + return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1; +} +],[ + ac_cv_atof_accept_inf=yes +],[ + ac_cv_atof_accept_inf=no +],[ + ac_cv_atof_accept_inf=no +])]) +if test "$ac_cv_atof_accept_inf" = "yes"; then + AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF]) +fi + +dnl +dnl Check if HUGE_VAL == INF +dnl +AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[ +AC_TRY_RUN([ +#include <math.h> +#include <stdlib.h> + +#ifdef HAVE_ISINF +#define zend_isinf(a) isinf(a) +#elif defined(INFINITY) +/* Might not work, but is required by ISO C99 */ +#define zend_isinf(a) (((a)==INFINITY)?1:0) +#elif defined(HAVE_FPCLASS) +#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF)) +#else +#define zend_isinf(a) 0 +#endif + +int main(int argc, char** argv) +{ + return zend_isinf(HUGE_VAL) ? 0 : 1; +} +],[ + ac_cv_huge_val_inf=yes +],[ + ac_cv_huge_val_inf=no +],[ + ac_cv_huge_val_inf=yes +])]) +dnl This is the most probable fallback so we assume yes in case of cross compile. +if test "$ac_cv_huge_val_inf" = "yes"; then + AC_DEFINE([HAVE_HUGE_VAL_INF], 1, [whether HUGE_VAL == INF]) +fi + +dnl +dnl Check if HUGE_VAL + -HUGEVAL == NAN +dnl +AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[ +AC_TRY_RUN([ +#include <math.h> +#include <stdlib.h> + +#ifdef HAVE_ISNAN +#define zend_isnan(a) isnan(a) +#elif defined(HAVE_FPCLASS) +#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) +#else +#define zend_isnan(a) 0 +#endif + +int main(int argc, char** argv) +{ +#if defined(__sparc__) && !(__GNUC__ >= 3) + /* prevent bug #27830 */ + return 1; +#else + return zend_isnan(HUGE_VAL + -HUGE_VAL) ? 0 : 1; +#endif +} +],[ + ac_cv_huge_val_nan=yes +],[ + ac_cv_huge_val_nan=no +],[ + ac_cv_huge_val_nan=yes +])]) +dnl This is the most probable fallback so we assume yes in case of cross compile. +if test "$ac_cv_huge_val_nan" = "yes"; then + AC_DEFINE([HAVE_HUGE_VAL_NAN], 1, [whether HUGE_VAL + -HUGEVAL == NAN]) +fi diff --git a/Zend/tests/009.phpt b/Zend/tests/009.phpt index b44a6ba687..0dc9453576 100644 --- a/Zend/tests/009.phpt +++ b/Zend/tests/009.phpt @@ -7,6 +7,10 @@ class foo { function bar () { var_dump(get_class()); } + function testNull () + { + var_dump(get_class(null)); + } } class foo2 extends foo { @@ -27,6 +31,8 @@ var_dump(get_class("qwerty")); var_dump(get_class($f1)); var_dump(get_class($f2)); +$f1->testNull(); + echo "Done\n"; ?> --EXPECTF-- @@ -45,4 +51,7 @@ Warning: get_class() expects parameter 1 to be object, string given in %s on lin bool(false) string(3) "foo" string(4) "foo2" + +Warning: get_class() expects parameter 1 to be object, null given in %s on line %d +bool(false) Done diff --git a/Zend/tests/ast/zend-pow-assign.phpt b/Zend/tests/ast/zend-pow-assign.phpt new file mode 100644 index 0000000000..d978e77ce6 --- /dev/null +++ b/Zend/tests/ast/zend-pow-assign.phpt @@ -0,0 +1,11 @@ +--TEST-- +ZEND_POW_ASSIGN +--INI-- +zend.assertions=1 +--FILE-- +<?php + +assert_options(ASSERT_WARNING); +assert(false && ($a **= 2)); +--EXPECTF-- +Warning: assert(): assert(false && ($a **= 2)) failed in %s%ezend-pow-assign.php on line %d diff --git a/Zend/tests/use_function/conditional_function_declaration.phpt b/Zend/tests/use_function/conditional_function_declaration.phpt index ccfb96103a..02ac0803f0 100644 --- a/Zend/tests/use_function/conditional_function_declaration.phpt +++ b/Zend/tests/use_function/conditional_function_declaration.phpt @@ -1,5 +1,5 @@ --TEST-- -function that is conditionally defined at runtime should not cause compiler error +function that is conditionally defined is subject to symbol use checks --FILE-- <?php @@ -13,5 +13,5 @@ use function bar\foo; echo "Done"; ?> ---EXPECT-- -Done +--EXPECTF-- +Fatal error: Cannot use function bar\foo as foo because the name is already in use in %s on line %d diff --git a/Zend/tests/use_late_binding_conflict.phpt b/Zend/tests/use_late_binding_conflict.phpt new file mode 100644 index 0000000000..c8514d0b1a --- /dev/null +++ b/Zend/tests/use_late_binding_conflict.phpt @@ -0,0 +1,13 @@ +--TEST-- +Use conflicts are detected for late-bound classes +--FILE-- +<?php + +/* Reverse declaration order disables early-binding */ +class B extends A {} +class A {} +use Foo\B; + +?> +--EXPECTF-- +Fatal error: Cannot use Foo\B as B because the name is already in use in %s on line %d diff --git a/Zend/tests/use_no_eval_conflict.phpt b/Zend/tests/use_no_eval_conflict.phpt new file mode 100644 index 0000000000..cf9014b77d --- /dev/null +++ b/Zend/tests/use_no_eval_conflict.phpt @@ -0,0 +1,13 @@ +--TEST-- +Use conflicts should not occur across eval()s +--FILE-- +<?php + +/* It is important that these two eval()s occur on the same line, + * as this forces them to have the same filename. */ +eval("class A {}"); eval("use Foo\A;"); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 0e04d86dff..dba945129c 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1342,7 +1342,7 @@ simple_list: case ZEND_ASSIGN_BW_OR: BINARY_OP(" |= ", 90, 91, 90); case ZEND_ASSIGN_BW_AND: BINARY_OP(" &= ", 90, 91, 90); case ZEND_ASSIGN_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90); - case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90); + case ZEND_ASSIGN_POW: BINARY_OP(" **= ", 90, 91, 90); EMPTY_SWITCH_DEFAULT_CASE(); } break; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 0fb0036b7f..d99ebb292e 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1001,7 +1001,7 @@ ZEND_FUNCTION(get_class) { zval *obj = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o!", &obj) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o", &obj) == FAILURE) { RETURN_FALSE; } diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index eb726484f5..33e9c647ea 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -34,9 +34,6 @@ #define ZEND_CLOSURE_PROPERTY_ERROR() \ zend_throw_error(NULL, "Closure object cannot have properties") -/* reuse bit to mark "fake" closures (it wasn't used for functions before) */ -#define ZEND_ACC_FAKE_CLOSURE ZEND_ACC_INTERFACE - typedef struct _zend_closure { zend_object std; zend_function func; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f53365fd58..d56e670d9b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -301,12 +301,14 @@ void zend_file_context_begin(zend_file_context *prev_context) /* {{{ */ FC(in_namespace) = 0; FC(has_bracketed_namespaces) = 0; FC(declarables).ticks = 0; + zend_hash_init(&FC(seen_symbols), 8, NULL, NULL, 0); } /* }}} */ void zend_file_context_end(zend_file_context *prev_context) /* {{{ */ { zend_end_namespace(); + zend_hash_destroy(&FC(seen_symbols)); CG(file_context) = *prev_context; } /* }}} */ @@ -318,12 +320,27 @@ void zend_init_compiler_data_structures(void) /* {{{ */ CG(active_class_entry) = NULL; CG(in_compilation) = 0; CG(start_lineno) = 0; - zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0); CG(encoding_declared) = 0; } /* }}} */ +static void zend_register_seen_symbol(zend_string *name, uint32_t kind) { + zval *zv = zend_hash_find(&FC(seen_symbols), name); + if (zv) { + Z_LVAL_P(zv) |= kind; + } else { + zval tmp; + ZVAL_LONG(&tmp, kind); + zend_hash_add_new(&FC(seen_symbols), name, &tmp); + } +} + +static zend_bool zend_have_seen_symbol(zend_string *name, uint32_t kind) { + zval *zv = zend_hash_find(&FC(seen_symbols), name); + return zv && (Z_LVAL_P(zv) & kind) != 0; +} + ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */ { @@ -349,7 +366,6 @@ void shutdown_compiler(void) /* {{{ */ zend_stack_destroy(&CG(loop_var_stack)); zend_stack_destroy(&CG(delayed_oplines_stack)); zend_hash_destroy(&CG(filenames_table)); - zend_hash_destroy(&CG(const_filenames)); zend_arena_destroy(CG(arena)); } /* }}} */ @@ -5515,6 +5531,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as key = zend_build_runtime_definition_key(lcname, decl->lex_pos); zend_hash_update_ptr(CG(function_table), key, op_array); + zend_register_seen_symbol(lcname, ZEND_SYMBOL_FUNCTION); if (op_array->fn_flags & ZEND_ACC_CLOSURE) { opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL); @@ -5916,6 +5933,8 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ "because the name is already in use", ZSTR_VAL(name)); } } + + zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS); } else { name = zend_generate_anon_class_name(decl->lex_pos); lcname = zend_string_tolower(name); @@ -6083,19 +6102,19 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */ { switch (type) { - case T_CLASS: + case ZEND_SYMBOL_CLASS: if (!FC(imports)) { FC(imports) = emalloc(sizeof(HashTable)); zend_hash_init(FC(imports), 8, NULL, str_dtor, 0); } return FC(imports); - case T_FUNCTION: + case ZEND_SYMBOL_FUNCTION: if (!FC(imports_function)) { FC(imports_function) = emalloc(sizeof(HashTable)); zend_hash_init(FC(imports_function), 8, NULL, str_dtor, 0); } return FC(imports_function); - case T_CONST: + case ZEND_SYMBOL_CONST: if (!FC(imports_const)) { FC(imports_const) = emalloc(sizeof(HashTable)); zend_hash_init(FC(imports_const), 8, NULL, str_dtor, 0); @@ -6111,11 +6130,11 @@ static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */ static char *zend_get_use_type_str(uint32_t type) /* {{{ */ { switch (type) { - case T_CLASS: + case ZEND_SYMBOL_CLASS: return ""; - case T_FUNCTION: + case ZEND_SYMBOL_FUNCTION: return " function"; - case T_CONST: + case ZEND_SYMBOL_CONST: return " const"; EMPTY_SWITCH_DEFAULT_CASE() } @@ -6135,41 +6154,6 @@ static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend } /* }}} */ -static void zend_check_use_conflict( - uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *lookup_name) { - switch (type) { - case T_CLASS: - { - zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lookup_name); - if (ce && ce->type == ZEND_USER_CLASS - && ce->info.user.filename == CG(compiled_filename) - ) { - zend_check_already_in_use(type, old_name, new_name, lookup_name); - } - break; - } - case T_FUNCTION: - { - zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name); - if (fn && fn->type == ZEND_USER_FUNCTION - && fn->op_array.filename == CG(compiled_filename) - ) { - zend_check_already_in_use(type, old_name, new_name, lookup_name); - } - break; - } - case T_CONST: - { - zend_string *filename = zend_hash_find_ptr(&CG(const_filenames), lookup_name); - if (filename && filename == CG(compiled_filename)) { - zend_check_already_in_use(type, old_name, new_name, lookup_name); - } - break; - } - EMPTY_SWITCH_DEFAULT_CASE() - } -} - void zend_compile_use(zend_ast *ast) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); @@ -6177,7 +6161,7 @@ void zend_compile_use(zend_ast *ast) /* {{{ */ zend_string *current_ns = FC(current_namespace); uint32_t type = ast->attr; HashTable *current_import = zend_get_import_ht(type); - zend_bool case_sensitive = type == T_CONST; + zend_bool case_sensitive = type == ZEND_SYMBOL_CONST; for (i = 0; i < list->children; ++i) { zend_ast *use_ast = list->child[i]; @@ -6215,7 +6199,7 @@ void zend_compile_use(zend_ast *ast) /* {{{ */ lookup_name = zend_string_tolower(new_name); } - if (type == T_CLASS && zend_is_reserved_class_name(new_name)) { + if (type == ZEND_SYMBOL_CLASS && zend_is_reserved_class_name(new_name)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' " "is a special class name", ZSTR_VAL(old_name), ZSTR_VAL(new_name), ZSTR_VAL(new_name)); } @@ -6226,11 +6210,15 @@ void zend_compile_use(zend_ast *ast) /* {{{ */ ZSTR_VAL(ns_name)[ZSTR_LEN(current_ns)] = '\\'; memcpy(ZSTR_VAL(ns_name) + ZSTR_LEN(current_ns) + 1, ZSTR_VAL(lookup_name), ZSTR_LEN(lookup_name)); - zend_check_use_conflict(type, old_name, new_name, ns_name); + if (zend_have_seen_symbol(ns_name, type)) { + zend_check_already_in_use(type, old_name, new_name, ns_name); + } zend_string_free(ns_name); } else { - zend_check_use_conflict(type, old_name, new_name, lookup_name); + if (zend_have_seen_symbol(lookup_name, type)) { + zend_check_already_in_use(type, old_name, new_name, lookup_name); + } } zend_string_addref(old_name); @@ -6303,7 +6291,7 @@ void zend_compile_const_decl(zend_ast *ast) /* {{{ */ zend_emit_op(NULL, ZEND_DECLARE_CONST, &name_node, &value_node); - zend_hash_add_ptr(&CG(const_filenames), name, CG(compiled_filename)); + zend_register_seen_symbol(name, ZEND_SYMBOL_CONST); } } /* }}}*/ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1f0773d9a7..a736ecc668 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -121,6 +121,8 @@ typedef struct _zend_file_context { HashTable *imports; HashTable *imports_function; HashTable *imports_const; + + HashTable seen_symbols; } zend_file_context; typedef union _zend_parser_stack_elem { @@ -253,6 +255,7 @@ typedef struct _zend_oparray_context { #define ZEND_ACC_CLOSURE 0x100000 +#define ZEND_ACC_FAKE_CLOSURE 0x40 #define ZEND_ACC_GENERATOR 0x800000 #define ZEND_ACC_NO_RT_ARENA 0x80000 @@ -473,6 +476,7 @@ struct _zend_execute_data { #define ZEND_CALL_ALLOCATED (1 << 7) #define ZEND_CALL_GENERATOR (1 << 8) #define ZEND_CALL_DYNAMIC (1 << 9) +#define ZEND_CALL_FAKE_CLOSURE (1 << 10) #define ZEND_CALL_INFO_SHIFT 16 @@ -962,6 +966,11 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, #define ZEND_ARRAY_NOT_PACKED (1<<1) #define ZEND_ARRAY_SIZE_SHIFT 2 +/* For "use" AST nodes and the seen symbol table */ +#define ZEND_SYMBOL_CLASS (1<<0) +#define ZEND_SYMBOL_FUNCTION (1<<1) +#define ZEND_SYMBOL_CONST (1<<2) + /* Pseudo-opcodes that are used only temporarily during compilation */ #define ZEND_GOTO 253 #define ZEND_BRK 254 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bbd64f2ea7..1bc67fb3ca 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -584,7 +584,7 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v zval_dtor_func(garbage); return; } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); + gc_check_possible_root(garbage); } } ZVAL_REF(variable_ptr, ref); @@ -1294,7 +1294,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zend_long offset; offset = zend_check_string_offset(dim, BP_VAR_W); - if (offset < (zend_long)(-Z_STRLEN_P(str))) { + if (offset < -(zend_long)Z_STRLEN_P(str)) { /* Error on negative offset */ zend_error(E_WARNING, "Illegal string offset: " ZEND_LONG_FMT, offset); if (result) { @@ -2063,12 +2063,12 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec zval *end = cv + EX(func)->op_array.last_var; while (EXPECTED(cv != end)) { if (Z_REFCOUNTED_P(cv)) { - if (!Z_DELREF_P(cv)) { - zend_refcounted *r = Z_COUNTED_P(cv); + zend_refcounted *r = Z_COUNTED_P(cv); + if (!--GC_REFCOUNT(r)) { ZVAL_NULL(cv); zval_dtor_func(r); } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(cv); + gc_check_possible_root(r); } } cv++; @@ -2659,6 +2659,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval * ZEND_ASSERT(GC_TYPE((zend_object*)fbc->common.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)fbc->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; + if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 82c6a4a415..4d68fea800 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -101,8 +101,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval return variable_ptr; } else { /* we need to split */ /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ - if ((Z_COLLECTABLE_P(variable_ptr)) && - UNEXPECTED(!GC_INFO(garbage))) { + if (UNEXPECTED(GC_MAY_LEAK(garbage))) { gc_possible_root(garbage); } } @@ -216,12 +215,12 @@ static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_in do { p--; if (Z_REFCOUNTED_P(p)) { - if (!Z_DELREF_P(p)) { - zend_refcounted *r = Z_COUNTED_P(p); + zend_refcounted *r = Z_COUNTED_P(p); + if (!--GC_REFCOUNT(r)) { ZVAL_NULL(p); zval_dtor_func(r); } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(p); + gc_check_possible_root(r); } } } while (p != end); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fc4a39acb6..3438bcbf1e 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -815,9 +815,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { + uint32_t call_info; + ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->op_array.prototype)++; - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE); + call_info = ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } + ZEND_ADD_CALL_FLAG(call, call_info); } if (func->type == ZEND_USER_FUNCTION) { diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 862c18ad75..c69c641fd5 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -46,7 +46,7 @@ You can use the following macro to check the extension API version for compatibi /* The first number is the engine version and the rest is the date (YYYYMMDD). * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 320160303 +#define ZEND_EXTENSION_API_NO 320160731 typedef struct _zend_extension_version_info { int zend_extension_api_no; diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index eb8e500b03..be6b8c44fd 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -119,9 +119,6 @@ ZEND_API void gc_reset(void); ZEND_API int zend_gc_collect_cycles(void); END_EXTERN_C() -#define GC_ZVAL_CHECK_POSSIBLE_ROOT(z) \ - gc_check_possible_root((z)) - #define GC_REMOVE_FROM_BUFFER(p) do { \ zend_refcounted *_p = (zend_refcounted*)(p); \ if (GC_ADDRESS(GC_INFO(_p))) { \ @@ -129,11 +126,23 @@ END_EXTERN_C() } \ } while (0) -static zend_always_inline void gc_check_possible_root(zval *z) +#define GC_MAY_LEAK(ref) \ + ((GC_TYPE_INFO(ref) & \ + (GC_INFO_MASK | (GC_COLLECTABLE << GC_FLAGS_SHIFT))) == \ + (GC_COLLECTABLE << GC_FLAGS_SHIFT)) + +static zend_always_inline void gc_check_possible_root(zend_refcounted *ref) { - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - gc_possible_root(Z_COUNTED_P(z)); + if (GC_TYPE(ref) == IS_REFERENCE) { + zval *zv = &((zend_reference*)ref)->val; + + if (!Z_REFCOUNTED_P(zv)) { + return; + } + ref = Z_COUNTED_P(zv); + } + if (UNEXPECTED(GC_MAY_LEAK(ref))) { + gc_possible_root(ref); } } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index fbbf503c41..7662e263b1 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -105,8 +105,6 @@ struct _zend_compiler_globals { uint32_t compiler_options; /* set of ZEND_COMPILE_* constants */ - HashTable const_filenames; - zend_oparray_context context; zend_file_context file_context; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index fdbdcac5a0..c3cae2a831 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -171,7 +171,7 @@ static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) { GC_REFCOUNT(ht) = 1; - GC_TYPE_INFO(ht) = IS_ARRAY; + GC_TYPE_INFO(ht) = IS_ARRAY | (persistent ? 0 : (GC_COLLECTABLE << GC_FLAGS_SHIFT)); ht->u.flags = (persistent ? HASH_FLAG_PERSISTENT : 0) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS; ht->nTableSize = zend_hash_check_size(nSize); ht->nTableMask = HT_MIN_MASK; @@ -728,9 +728,6 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, ht->pDestructor(&p->val); } ZVAL_COPY_VALUE(&p->val, pData); - if ((zend_long)h >= (zend_long)ht->nNextFreeElement) { - ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX; - } return &p->val; } else { /* we have to keep the order :( */ goto convert_to_hash; @@ -1763,7 +1760,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) ALLOC_HASHTABLE(target); GC_REFCOUNT(target) = 1; - GC_TYPE_INFO(target) = IS_ARRAY; + GC_TYPE_INFO(target) = IS_ARRAY | (GC_COLLECTABLE << GC_FLAGS_SHIFT); target->nTableSize = source->nTableSize; target->pDestructor = source->pDestructor; diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 2dadb39b17..db53a266fb 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -191,16 +191,6 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter) } /* }}} */ -/* {{{ zend_user_it_get_current_key_default */ -#if 0 -static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key) -{ - *int_key = _iter->index; - return HASH_KEY_IS_LONG; -} -#endif -/* }}} */ - /* {{{ zend_user_it_get_current_key */ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key) { @@ -394,15 +384,6 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry /* {{{ zend_implement_arrayaccess */ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type) { -#if 0 - /* get ht from ce */ - if (ht->read_dimension != zend_std_read_dimension - || ht->write_dimension != zend_std_write_dimension - || ht->has_dimension != zend_std_has_dimension - || ht->unset_dimension != zend_std_unset_dimension) { - return FAILURE; - } -#endif return SUCCESS; } /* }}}*/ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 3c7117930e..31be044aa9 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -327,14 +327,14 @@ top_statement: { $$ = zend_ast_create(ZEND_AST_NAMESPACE, NULL, $4); } | T_USE mixed_group_use_declaration ';' { $$ = $2; } | T_USE use_type group_use_declaration ';' { $$ = $3; $$->attr = $2; } - | T_USE use_declarations ';' { $$ = $2; $$->attr = T_CLASS; } + | T_USE use_declarations ';' { $$ = $2; $$->attr = ZEND_SYMBOL_CLASS; } | T_USE use_type use_declarations ';' { $$ = $3; $$->attr = $2; } | T_CONST const_list ';' { $$ = $2; } ; use_type: - T_FUNCTION { $$ = T_FUNCTION; } - | T_CONST { $$ = T_CONST; } + T_FUNCTION { $$ = ZEND_SYMBOL_FUNCTION; } + | T_CONST { $$ = ZEND_SYMBOL_CONST; } ; group_use_declaration: @@ -373,7 +373,7 @@ use_declarations: ; inline_use_declaration: - unprefixed_use_declaration { $$ = $1; $$->attr = T_CLASS; } + unprefixed_use_declaration { $$ = $1; $$->attr = ZEND_SYMBOL_CLASS; } | use_type unprefixed_use_declaration { $$ = $2; $$->attr = $1; } ; diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h index 8a93990466..e7c2470a0f 100644 --- a/Zend/zend_multiply.h +++ b/Zend/zend_multiply.h @@ -19,10 +19,32 @@ /* $Id$ */ +#include "zend_portability.h" + #ifndef ZEND_MULTIPLY_H #define ZEND_MULTIPLY_H -#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) +#if PHP_HAVE_BUILTIN_SMULL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + +#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ + long __tmpvar; \ + if (((usedval) = __builtin_smull_overflow((a), (b), &__tmpvar))) { \ + (dval) = (double) (a) * (double) (b); \ + } \ + else (lval) = __tmpvar; \ +} while (0) + +#elif PHP_HAVE_BUILTIN_SMULLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + +#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ + long long __tmpvar; \ + if (((usedval) = __builtin_smulll_overflow((a), (b), &__tmpvar))) { \ + (dval) = (double) (a) * (double) (b); \ + } \ + else (lval) = __tmpvar; \ +} while (0) + +#elif (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ zend_long __tmpvar; \ diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 1e358996ed..07b586b6f8 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -32,7 +32,7 @@ ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce) zval *p, *end; GC_REFCOUNT(object) = 1; - GC_TYPE_INFO(object) = IS_OBJECT; + GC_TYPE_INFO(object) = IS_OBJECT | (GC_COLLECTABLE << GC_FLAGS_SHIFT); object->ce = ce; object->properties = NULL; zend_objects_store_put(object); diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index dbdb02f984..7dfad70fbc 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -76,7 +76,7 @@ static zend_always_inline void zend_object_release(zend_object *obj) { if (--GC_REFCOUNT(obj) == 0) { zend_objects_store_del(obj); - } else if (UNEXPECTED(!GC_INFO(obj))) { + } else if (UNEXPECTED(GC_MAY_LEAK((zend_refcounted*)obj))) { gc_possible_root((zend_refcounted*)obj); } } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 4159e43e53..9a90250934 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -411,19 +411,6 @@ try_again: ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */ { - if (Z_TYPE_P(op) == IS_OBJECT) { - if (Z_OBJ_HT_P(op)->cast_object) { - zval org; - - ZVAL_COPY_VALUE(&org, op); - if (Z_OBJ_HT_P(op)->cast_object(&org, op, IS_NULL) == SUCCESS) { - zval_dtor(&org); - return; - } - ZVAL_COPY_VALUE(op, &org); - } - } - zval_ptr_dtor(op); ZVAL_NULL(op); } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index a404b79c1c..7fc11cc144 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -35,13 +35,10 @@ #include <ieeefp.h> #endif +#include "zend_portability.h" #include "zend_strtod.h" #include "zend_multiply.h" -#if 0&&HAVE_BCMATH -#include "ext/bcmath/libbcmath/src/bcmath.h" -#endif - #define LONG_SIGN_MASK (((zend_long)1) << (8*sizeof(zend_long)-1)) BEGIN_EXTERN_C() @@ -444,7 +441,23 @@ ZEND_API void zend_update_current_locale(void); static zend_always_inline void fast_long_increment_function(zval *op1) { -#if defined(__GNUC__) && defined(__i386__) +#if PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), 1, &lresult))) { + /* switch to double */ + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0); + } else { + Z_LVAL_P(op1) = lresult; + } +#elif PHP_HAVE_BUILTIN_SADDLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_saddll_overflow(Z_LVAL_P(op1), 1, &llresult))) { + /* switch to double */ + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0); + } else { + Z_LVAL_P(op1) = llresult; + } +#elif defined(__GNUC__) && defined(__i386__) __asm__( "incl (%0)\n\t" "jno 0f\n\t" @@ -482,7 +495,23 @@ static zend_always_inline void fast_long_increment_function(zval *op1) static zend_always_inline void fast_long_decrement_function(zval *op1) { -#if defined(__GNUC__) && defined(__i386__) +#if PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), 1, &lresult))) { + /* switch to double */ + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0); + } else { + Z_LVAL_P(op1) = lresult; + } +#elif PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_ssubll_overflow(Z_LVAL_P(op1), 1, &llresult))) { + /* switch to double */ + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0); + } else { + Z_LVAL_P(op1) = llresult; + } +#elif defined(__GNUC__) && defined(__i386__) __asm__( "decl (%0)\n\t" "jno 0f\n\t" @@ -520,7 +549,21 @@ static zend_always_inline void fast_long_decrement_function(zval *op1) static zend_always_inline void fast_long_add_function(zval *result, zval *op1, zval *op2) { -#if defined(__GNUC__) && defined(__i386__) \ +#if PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, lresult); + } +#elif PHP_HAVE_BUILTIN_SADDLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_saddll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, llresult); + } +#elif defined(__GNUC__) && defined(__i386__) \ && !(4 == __GNUC__ && 8 == __GNUC_MINOR__) \ && !(4 == __GNUC__ && 9 == __GNUC_MINOR__ && (defined(__PIC__) || defined(__PIE__))) /* Position-independent builds fail with gcc-4.9.x */ @@ -609,7 +652,21 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, zval *op2) { -#if defined(__GNUC__) && defined(__i386__) && \ +#if PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, lresult); + } +#elif PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_ssubll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, llresult); + } +#elif defined(__GNUC__) && defined(__i386__) && \ !(4 == __GNUC__ && 8 == __GNUC_MINOR__) && \ !(4 == __GNUC__ && 9 == __GNUC_MINOR__ && (defined(__PIC__) || defined(__PIE__))) /* Position-independent builds fail with gcc-4.9.x */ diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 298dfb53fa..ff12d93269 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -53,6 +53,7 @@ #include <stdio.h> #include <assert.h> +#include <math.h> #ifdef HAVE_UNIX_H # include <unix.h> @@ -420,6 +421,51 @@ char *alloca(); #undef MAX #define MAX(a, b) (((a)>(b))?(a):(b)) #define MIN(a, b) (((a)<(b))?(a):(b)) + +/* 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 + * won't fail to compile on some machines and not others. + */ +static zend_always_inline double _zend_get_inf(void) /* {{{ */ +{ +#ifdef INFINITY + return INFINITY; +#elif HAVE_HUGE_VAL_INF + return HUGE_VAL; +#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) +# define _zend_DOUBLE_INFINITY_HIGH 0x7ff00000 + double val = 0.0; + ((uint32_t*)&val)[1] = _zend_DOUBLE_INFINITY_HIGH; + ((uint32_t*)&val)[0] = 0; + return val; +#elif HAVE_ATOF_ACCEPTS_INF + return atof("INF"); +#else + return 1.0/0.0; +#endif +} /* }}} */ +#define ZEND_INFINITY (_zend_get_inf()) + +static zend_always_inline double _zend_get_nan(void) /* {{{ */ +{ +#ifdef NAN + return NAN; +#elif HAVE_HUGE_VAL_NAN + return HUGE_VAL + -HUGE_VAL; +#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) +# define _zend_DOUBLE_QUIET_NAN_HIGH 0xfff80000 + double val = 0.0; + ((uint32_t*)&val)[1] = _zend_DOUBLE_QUIET_NAN_HIGH; + ((uint32_t*)&val)[0] = 0; + return val; +#elif HAVE_ATOF_ACCEPTS_NAN + return atof("NAN"); +#else + return 0.0/0.0; +#endif +} /* }}} */ +#define ZEND_NAN (_zend_get_nan()) + #define ZEND_STRL(str) (str), (sizeof(str)-1) #define ZEND_STRS(str) (str), (sizeof(str)) #define ZEND_NORMALIZE_BOOL(n) \ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 2a108877bf..9d4f6a7d4c 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -390,24 +390,33 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_GC_TYPE_INFO(zval) GC_TYPE_INFO(Z_COUNTED(zval)) #define Z_GC_TYPE_INFO_P(zval_p) Z_GC_TYPE_INFO(*(zval_p)) +#define GC_FLAGS_SHIFT 8 +#define GC_INFO_SHIFT 16 +#define GC_INFO_MASK 0xffff0000 + +/* zval.value->gc.u.v.flags */ +#define GC_COLLECTABLE (1<<7) + +#define GC_ARRAY (IS_ARRAY | (GC_COLLECTABLE << GC_FLAGS_SHIFT)) +#define GC_OBJECT (IS_OBJECT | (GC_COLLECTABLE << GC_FLAGS_SHIFT)) + /* zval.u1.v.type_flags */ #define IS_TYPE_CONSTANT (1<<0) #define IS_TYPE_IMMUTABLE (1<<1) #define IS_TYPE_REFCOUNTED (1<<2) -#define IS_TYPE_COLLECTABLE (1<<3) #define IS_TYPE_COPYABLE (1<<4) /* extended types */ #define IS_INTERNED_STRING_EX IS_STRING -#define IS_STRING_EX (IS_STRING | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_ARRAY_EX (IS_ARRAY | (( IS_TYPE_REFCOUNTED | IS_TYPE_COLLECTABLE | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_OBJECT_EX (IS_OBJECT | (( IS_TYPE_REFCOUNTED | IS_TYPE_COLLECTABLE ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_RESOURCE_EX (IS_RESOURCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_REFERENCE_EX (IS_REFERENCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) +#define IS_STRING_EX (IS_STRING | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_ARRAY_EX (IS_ARRAY | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_OBJECT_EX (IS_OBJECT | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) +#define IS_RESOURCE_EX (IS_RESOURCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) +#define IS_REFERENCE_EX (IS_REFERENCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_CONSTANT_EX (IS_CONSTANT | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_CONSTANT_EX (IS_CONSTANT | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) /* zval.u1.v.const_flags */ #define IS_CONSTANT_UNQUALIFIED 0x010 @@ -463,9 +472,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_REFCOUNTED(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0) #define Z_REFCOUNTED_P(zval_p) Z_REFCOUNTED(*(zval_p)) -#define Z_COLLECTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_COLLECTABLE) != 0) -#define Z_COLLECTABLE_P(zval_p) Z_COLLECTABLE(*(zval_p)) - #define Z_COPYABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_COPYABLE) != 0) #define Z_COPYABLE_P(zval_p) Z_COPYABLE(*(zval_p)) @@ -482,9 +488,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_OPT_REFCOUNTED(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) #define Z_OPT_REFCOUNTED_P(zval_p) Z_OPT_REFCOUNTED(*(zval_p)) -#define Z_OPT_COLLECTABLE(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0) -#define Z_OPT_COLLECTABLE_P(zval_p) Z_OPT_COLLECTABLE(*(zval_p)) - #define Z_OPT_COPYABLE(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT)) != 0) #define Z_OPT_COPYABLE_P(zval_p) Z_OPT_COPYABLE(*(zval_p)) diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index 0afe68760d..b0054eedd3 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -44,10 +44,11 @@ static zend_always_inline void _zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) { if (Z_REFCOUNTED_P(zval_ptr)) { - if (!Z_DELREF_P(zval_ptr)) { - _zval_dtor_func(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_RELAY_CC); + zend_refcounted *ref = Z_COUNTED_P(zval_ptr); + if (!--GC_REFCOUNT(ref)) { + _zval_dtor_func(ref ZEND_FILE_LINE_RELAY_CC); } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr); + gc_check_possible_root(ref); } } } diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index cc3f908e88..c623bf8d30 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -32,7 +32,6 @@ #include "zend.h" #include "zend_virtual_cwd.h" -#include "tsrm_strtok_r.h" #ifdef ZEND_WIN32 #include <io.h> @@ -85,63 +84,14 @@ cwd_state main_cwd_state; /* True global */ #include <direct.h> #endif -#ifdef ZEND_WIN32 -#include <tchar.h> -#define tsrm_strtok_r(a,b,c) _tcstok((a),(b)) -#define TOKENIZER_STRING "/\\" - -static int php_check_dots(const char *element, int n) -{ - while (n-- > 0) if (element[n] != '.') break; - - return (n != -1); -} - -#define IS_DIRECTORY_UP(element, len) \ - (len >= 2 && !php_check_dots(element, len)) - -#define IS_DIRECTORY_CURRENT(element, len) \ - (len == 1 && element[0] == '.') - -#elif defined(NETWARE) -/* NetWare has strtok() (in LibC) and allows both slashes in paths, like Windows -- - but rest of the stuff is like Unix */ -/* strtok() call in LibC is abending when used in a different address space -- hence using - PHP's version itself for now */ -/*#define tsrm_strtok_r(a,b,c) strtok((a),(b))*/ -#define TOKENIZER_STRING "/\\" - -#else -#define TOKENIZER_STRING "/" -#endif - -/* default macros */ - -#ifndef IS_DIRECTORY_UP -#define IS_DIRECTORY_UP(element, len) \ - (len == 2 && element[0] == '.' && element[1] == '.') -#endif - -#ifndef IS_DIRECTORY_CURRENT -#define IS_DIRECTORY_CURRENT(element, len) \ - (len == 1 && element[0] == '.') -#endif - -/* define this to check semantics */ -#define IS_DIR_OK(s) (1) - -#ifndef IS_DIR_OK -#define IS_DIR_OK(state) (php_is_dir_ok(state) == 0) -#endif - - #define CWD_STATE_COPY(d, s) \ (d)->cwd_length = (s)->cwd_length; \ (d)->cwd = (char *) emalloc((s)->cwd_length+1); \ memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1); #define CWD_STATE_FREE(s) \ - efree((s)->cwd); + efree((s)->cwd); \ + (s)->cwd_length = 0; #ifdef ZEND_WIN32 # define CWD_STATE_FREE_ERR(state) do { \ @@ -299,8 +249,8 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{ WIN32_FILE_ATTRIBUTE_DATA data; LARGE_INTEGER t; const size_t path_len = strlen(path); - wchar_t *pathw = php_win32_ioutil_any_to_w(path); ALLOCA_FLAG(use_heap_large) + wchar_t *pathw = php_win32_ioutil_any_to_w(path); if (!pathw) { return -1; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 78342a0636..71e2332532 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3523,12 +3523,12 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ - if (OP2_TYPE & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ @@ -3664,7 +3664,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) ZEND_ASSERT(!Z_ISREF_P(ret)); #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -3765,7 +3765,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -3862,7 +3862,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); if (!RETURN_VALUE_USED(opline)) { @@ -5371,20 +5371,6 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) switch (opline->extended_value) { case IS_NULL: - /* This code is taken from convert_to_null. However, it does not seems very useful, - * because a conversion to null always results in the same value. This could only - * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */ -#if 0 - if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { - ZVAL_DEREF(expr); - } - if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) { - if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) { - break; - } - } -#endif - ZVAL_NULL(result); break; case _IS_BOOL: @@ -5535,18 +5521,11 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET) if (Z_REFCOUNTED_P(var)) { zend_refcounted *garbage = Z_COUNTED_P(var); + ZVAL_UNDEF(var); if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); zval_dtor_func(garbage); } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } + gc_check_possible_root(garbage); } } else { ZVAL_UNDEF(var); @@ -7763,18 +7742,19 @@ ZEND_VM_C_LABEL(check_indirect): variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { - uint32_t refcnt = Z_DELREF_P(variable_ptr); + zend_refcounted *ref = Z_COUNTED_P(variable_ptr); + uint32_t refcnt = --GC_REFCOUNT(ref); if (EXPECTED(variable_ptr != value)) { if (refcnt == 0) { SAVE_OPLINE(); - zval_dtor_func(Z_COUNTED_P(variable_ptr)); + zval_dtor_func(ref); if (UNEXPECTED(EG(exception))) { ZVAL_NULL(variable_ptr); HANDLE_EXCEPTION(); } } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); + gc_check_possible_root(ref); } } } @@ -7837,14 +7817,7 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE) SAVE_OPLINE(); value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(value); - - if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || - EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { - result = 1; - } - } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { + if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); if (EXPECTED(type_name != NULL)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a8a0466b5a..4e5c0f9816 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -635,7 +635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA ZEND_ASSERT(!Z_ISREF_P(ret)); #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -682,7 +682,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND ZEND_ASSERT(!Z_ISREF_P(ret)); #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -805,7 +805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -884,7 +884,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); @@ -981,7 +981,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); if (!0) { @@ -1108,7 +1108,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND } #endif - EG(current_execute_data) = call->prev_execute_data; + EG(current_execute_data) = execute_data; zend_vm_stack_free_args(call); if (!1) { @@ -3362,20 +3362,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O switch (opline->extended_value) { case IS_NULL: - /* This code is taken from convert_to_null. However, it does not seems very useful, - * because a conversion to null always results in the same value. This could only - * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */ -#if 0 - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - ZVAL_DEREF(expr); - } - if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) { - if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) { - break; - } - } -#endif - ZVAL_NULL(result); break; case _IS_BOOL: @@ -4089,14 +4075,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER( SAVE_OPLINE(); value = EX_CONSTANT(opline->op1); if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(value); - - if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || - EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { - result = 1; - } - } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { + if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); if (EXPECTED(type_name != NULL)) { @@ -5653,12 +5632,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ - if (IS_CONST & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ @@ -7806,18 +7785,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA if (Z_REFCOUNTED_P(var)) { zend_refcounted *garbage = Z_COUNTED_P(var); + ZVAL_UNDEF(var); if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); zval_dtor_func(garbage); } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } + gc_check_possible_root(garbage); } } else { ZVAL_UNDEF(var); @@ -9568,12 +9540,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ - if (IS_CV & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ @@ -11547,12 +11519,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV } if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) { - ZVAL_DEREF(function_name); - } ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->common.prototype)++; call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; GC_REFCOUNT(object)++; /* For $this pointer */ @@ -12762,20 +12734,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC switch (opline->extended_value) { case IS_NULL: - /* This code is taken from convert_to_null. However, it does not seems very useful, - * because a conversion to null always results in the same value. This could only - * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */ -#if 0 - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(expr); - } - if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) { - if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) { - break; - } - } -#endif - ZVAL_NULL(result); break; case _IS_BOOL: @@ -13367,14 +13325,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(value); - - if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || - EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { - result = 1; - } - } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { + if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); if (EXPECTED(type_name != NULL)) { @@ -16342,20 +16293,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC switch (opline->extended_value) { case IS_NULL: - /* This code is taken from convert_to_null. However, it does not seems very useful, - * because a conversion to null always results in the same value. This could only - * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */ -#if 0 - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - ZVAL_DEREF(expr); - } - if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) { - if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) { - break; - } - } -#endif - ZVAL_NULL(result); break; case _IS_BOOL: @@ -17314,14 +17251,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE SAVE_OPLINE(); value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(value); - - if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || - EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { - result = 1; - } - } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { + if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); if (EXPECTED(type_name != NULL)) { @@ -35379,20 +35309,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO switch (opline->extended_value) { case IS_NULL: - /* This code is taken from convert_to_null. However, it does not seems very useful, - * because a conversion to null always results in the same value. This could only - * be relevant if a cast_object handler for IS_NULL has some kind of side-effect. */ -#if 0 - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - ZVAL_DEREF(expr); - } - if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->cast_object) { - if (Z_OBJ_HT_P(expr)->cast_object(expr, result, IS_NULL) == SUCCESS) { - break; - } - } -#endif - ZVAL_NULL(result); break; case _IS_BOOL: @@ -36106,14 +36022,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN SAVE_OPLINE(); value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(value); - - if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || - EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { - result = 1; - } - } else if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { + if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); if (EXPECTED(type_name != NULL)) { @@ -40600,18 +40509,19 @@ check_indirect: variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { - uint32_t refcnt = Z_DELREF_P(variable_ptr); + zend_refcounted *ref = Z_COUNTED_P(variable_ptr); + uint32_t refcnt = --GC_REFCOUNT(ref); if (EXPECTED(variable_ptr != value)) { if (refcnt == 0) { SAVE_OPLINE(); - zval_dtor_func(Z_COUNTED_P(variable_ptr)); + zval_dtor_func(ref); if (UNEXPECTED(EG(exception))) { ZVAL_NULL(variable_ptr); HANDLE_EXCEPTION(); } } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr); + gc_check_possible_root(ref); } } } @@ -42804,18 +42714,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL if (Z_REFCOUNTED_P(var)) { zend_refcounted *garbage = Z_COUNTED_P(var); + ZVAL_UNDEF(var); if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); zval_dtor_func(garbage); } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } + gc_check_possible_root(garbage); } } else { ZVAL_UNDEF(var); @@ -53993,18 +53896,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H if (Z_REFCOUNTED_P(var)) { zend_refcounted *garbage = Z_COUNTED_P(var); + ZVAL_UNDEF(var); if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); zval_dtor_func(garbage); } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } + gc_check_possible_root(garbage); } } else { ZVAL_UNDEF(var); diff --git a/acinclude.m4 b/acinclude.m4 index e6d84e5b83..3eb0f1e914 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -3111,3 +3111,123 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CTZLL], [ AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_CTZLL], [$have_builtin_ctzll], [Whether the compiler supports __builtin_ctzll]) ]) + +dnl PHP_CHECK_BUILTIN_SMULL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SMULL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_smull_overflow]) + + AC_TRY_LINK(, [ + long tmpvar; + return __builtin_smull_overflow(3, 7, &tmpvar); + ], [ + have_builtin_smull_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_smull_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SMULL_OVERFLOW], + [$have_builtin_smull_overflow], [Whether the compiler supports __builtin_smull_overflow]) + +]) + +dnl PHP_CHECK_BUILTIN_SMULLL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SMULLL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_smulll_overflow]) + + AC_TRY_LINK(, [ + long long tmpvar; + return __builtin_smulll_overflow(3, 7, &tmpvar); + ], [ + have_builtin_smulll_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_smulll_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SMULLL_OVERFLOW], + [$have_builtin_smulll_overflow], [Whether the compiler supports __builtin_smulll_overflow]) + +]) + +dnl PHP_CHECK_BUILTIN_SADDL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SADDL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_saddl_overflow]) + + AC_TRY_LINK(, [ + long tmpvar; + return __builtin_saddl_overflow(3, 7, &tmpvar); + ], [ + have_builtin_saddl_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_saddl_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SADDL_OVERFLOW], + [$have_builtin_saddl_overflow], [Whether the compiler supports __builtin_saddl_overflow]) + +]) + +dnl PHP_CHECK_BUILTIN_SADDLL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SADDLL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_saddll_overflow]) + + AC_TRY_LINK(, [ + long long tmpvar; + return __builtin_saddll_overflow(3, 7, &tmpvar); + ], [ + have_builtin_saddll_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_saddll_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SADDLL_OVERFLOW], + [$have_builtin_saddll_overflow], [Whether the compiler supports __builtin_saddll_overflow]) + +]) + +dnl PHP_CHECK_BUILTIN_SSUBL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SSUBL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_ssubl_overflow]) + + AC_TRY_LINK(, [ + long tmpvar; + return __builtin_ssubl_overflow(3, 7, &tmpvar); + ], [ + have_builtin_ssubl_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_ssubl_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SSUBL_OVERFLOW], + [$have_builtin_ssubl_overflow], [Whether the compiler supports __builtin_ssubl_overflow]) + +]) + +dnl PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW +AC_DEFUN([PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW], [ + AC_MSG_CHECKING([for __builtin_ssubll_overflow]) + + AC_TRY_LINK(, [ + long long tmpvar; + return __builtin_ssubll_overflow(3, 7, &tmpvar); + ], [ + have_builtin_ssubll_overflow=1 + AC_MSG_RESULT([yes]) + ], [ + have_builtin_ssubll_overflow=0 + AC_MSG_RESULT([no]) + ]) + + AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW], + [$have_builtin_ssubll_overflow], [Whether the compiler supports __builtin_ssubll_overflow]) + +]) diff --git a/configure.in b/configure.in index a35f413dad..de68932ca1 100644 --- a/configure.in +++ b/configure.in @@ -118,7 +118,7 @@ int zend_sprintf(char *buffer, const char *format, ...); ]) PHP_MAJOR_VERSION=7 -PHP_MINOR_VERSION=1 +PHP_MINOR_VERSION=2 PHP_RELEASE_VERSION=0 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" @@ -583,6 +583,18 @@ dnl Check __builtin_ctzl PHP_CHECK_BUILTIN_CTZL dnl Check __builtin_ctzll PHP_CHECK_BUILTIN_CTZLL +dnl Check __builtin_smull_overflow +PHP_CHECK_BUILTIN_SMULL_OVERFLOW +dnl Check __builtin_smulll_overflow +PHP_CHECK_BUILTIN_SMULLL_OVERFLOW +dnl Check __builtin_saddl_overflow +PHP_CHECK_BUILTIN_SADDL_OVERFLOW +dnl Check __builtin_saddll_overflow +PHP_CHECK_BUILTIN_SADDLL_OVERFLOW +dnl Check __builtin_ssubl_overflow +PHP_CHECK_BUILTIN_SSUBL_OVERFLOW +dnl Check __builtin_ssubll_overflow +PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW dnl Check for members of the stat structure AC_STRUCT_ST_BLKSIZE diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index 2211549fe8..6a21dd363e 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -307,7 +307,7 @@ static php_stream_filter_ops php_bz2_compress_ops = { /* {{{ bzip2.* common factory */ -static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_stream_filter_ops *fops = NULL; php_bz2_filter_data *data; diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c index ba8a7de108..10a5ae55e7 100644 --- a/ext/curl/curl_file.c +++ b/ext/curl/curl_file.c @@ -70,19 +70,19 @@ PHP_FUNCTION(curl_file_create) } /* }}} */ -static void curlfile_get_property(char *name, INTERNAL_FUNCTION_PARAMETERS) +static void curlfile_get_property(char *name, size_t name_len, INTERNAL_FUNCTION_PARAMETERS) { zval *res, rv; if (zend_parse_parameters_none() == FAILURE) { return; } - res = zend_read_property(curl_CURLFile_class, getThis(), name, strlen(name), 1, &rv); + res = zend_read_property(curl_CURLFile_class, getThis(), name, name_len, 1, &rv); ZVAL_DEREF(res); ZVAL_COPY(return_value, res); } -static void curlfile_set_property(char *name, INTERNAL_FUNCTION_PARAMETERS) +static void curlfile_set_property(char *name, size_t name_len, INTERNAL_FUNCTION_PARAMETERS) { char *arg = NULL; size_t arg_len; @@ -90,14 +90,14 @@ static void curlfile_set_property(char *name, INTERNAL_FUNCTION_PARAMETERS) if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { return; } - zend_update_property_string(curl_CURLFile_class, getThis(), name, strlen(name), arg); + zend_update_property_string(curl_CURLFile_class, getThis(), name, name_len, arg); } /* {{{ proto string CURLFile::getFilename() Get file name */ ZEND_METHOD(CURLFile, getFilename) { - curlfile_get_property("name", INTERNAL_FUNCTION_PARAM_PASSTHRU); + curlfile_get_property("name", sizeof("name")-1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -105,7 +105,7 @@ ZEND_METHOD(CURLFile, getFilename) Get MIME type */ ZEND_METHOD(CURLFile, getMimeType) { - curlfile_get_property("mime", INTERNAL_FUNCTION_PARAM_PASSTHRU); + curlfile_get_property("mime", sizeof("mime")-1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -113,7 +113,7 @@ ZEND_METHOD(CURLFile, getMimeType) Get file name for POST */ ZEND_METHOD(CURLFile, getPostFilename) { - curlfile_get_property("postname", INTERNAL_FUNCTION_PARAM_PASSTHRU); + curlfile_get_property("postname", sizeof("postname")-1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -121,7 +121,7 @@ ZEND_METHOD(CURLFile, getPostFilename) Set MIME type */ ZEND_METHOD(CURLFile, setMimeType) { - curlfile_set_property("mime", INTERNAL_FUNCTION_PARAM_PASSTHRU); + curlfile_set_property("mime", sizeof("mime")-1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -129,7 +129,7 @@ ZEND_METHOD(CURLFile, setMimeType) Set file name for POST */ ZEND_METHOD(CURLFile, setPostFilename) { - curlfile_set_property("postname", INTERNAL_FUNCTION_PARAM_PASSTHRU); + curlfile_set_property("postname", sizeof("postname")-1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ diff --git a/ext/dba/config.w32 b/ext/dba/config.w32 index 4abba8dbf4..d521e6ad62 100644 --- a/ext/dba/config.w32 +++ b/ext/dba/config.w32 @@ -2,17 +2,34 @@ // vim:ft=javascript ARG_WITH("dba", "DBA support", "no"); +ARG_WITH("qdbm", "DBA: QDBM support", "no"); +ARG_WITH("db", "DBA: Berkeley DB support", "no"); if (PHP_DBA != "no") { - if (CHECK_LIB("libdb31s.lib;libdb61.lib", "dba", PHP_DBA) && - CHECK_HEADER_ADD_INCLUDE("db.h", "CFLAGS_DBA")) { - EXTENSION("dba", "dba.c dba_cdb.c dba_db1.c dba_db2.c dba_db3.c dba_dbm.c dba_flatfile.c dba_gdbm.c dba_ndbm.c dba_inifile.c"); - ADD_SOURCES("ext/dba/libcdb", "cdb.c cdb_make.c uint32.c", "dba"); - ADD_SOURCES("ext/dba/libflatfile", "flatfile.c", "dba"); - ADD_SOURCES("ext/dba/libinifile", "inifile.c", "dba"); - AC_DEFINE('HAVE_DBA', 1, 'DBA support'); - ADD_FLAG("CFLAGS_DBA", "/D DBA_DB1=0 /D DB1_VERSION=\"\\\"Berkeley DB 1.85 emulation in DB3\\\"\" /D DB1_INCLUDE_FILE=\"\\\"db_185.h\\\"\" /D DBA_DB3=1 /D DB3_INCLUDE_FILE=\"\\\"db.h\\\"\" /D DBA_FLATFILE=1 /D DBA_CDB=1 /D DBA_CDB_MAKE=1 /D DBA_CDB_BUILTIN=1 /D DBA_INIFILE=1"); - } else { - WARNING("dba not enabled; libraries and headers not found"); + EXTENSION("dba", "dba.c dba_cdb.c dba_db1.c dba_db2.c dba_db3.c dba_dbm.c dba_flatfile.c dba_gdbm.c dba_ndbm.c dba_inifile.c"); + ADD_SOURCES("ext/dba/libcdb", "cdb.c cdb_make.c uint32.c", "dba"); + ADD_SOURCES("ext/dba/libflatfile", "flatfile.c", "dba"); + ADD_SOURCES("ext/dba/libinifile", "inifile.c", "dba"); + AC_DEFINE('HAVE_DBA', 1, 'DBA support'); + ADD_FLAG("CFLAGS_DBA", "/D DBA_FLATFILE=1 /D DBA_CDB=1 /D DBA_CDB_MAKE=1 /D DBA_CDB_BUILTIN=1 /D DBA_INIFILE=1"); + + if (PHP_DB != "no") { + if (CHECK_LIB("libdb31s.lib;libdb61.lib", "dba", PHP_DBA) && + CHECK_HEADER_ADD_INCLUDE("db.h", "CFLAGS_DBA")) { + ADD_FLAG("CFLAGS_DBA", "/D DBA_DB1=0 /D DB1_VERSION=\"\\\"Berkeley DB 1.85 emulation in DB3\\\"\" /D DB1_INCLUDE_FILE=\"\\\"db_185.h\\\"\" /D DBA_DB3=1 /D DB3_INCLUDE_FILE=\"\\\"db.h\\\"\""); + } else { + WARNING("dba: db handlers not enabled; libraries and headers not found"); + } + } + + if (PHP_QDBM != "no") { + if (CHECK_LIB("qdbm_a.lib;qdbm.lib", "dba", PHP_DBA) && + CHECK_HEADER_ADD_INCLUDE("depot.h", "CFLAGS_DBA", PHP_DBA + ";" + PHP_PHP_BUILD + "\\include\\qdbm")) { + ADD_SOURCES("ext/dba", "dba_qdbm.c", "dba"); + AC_DEFINE("QDBM_INCLUDE_FILE", "<depot.h>", "", false); + AC_DEFINE("DBA_QDBM", 1, ""); + } else { + WARNING("dba: qdbm handlers not enabled; libraries and headers not found"); + } } } diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 9879d81c1c..ef7622c893 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -299,13 +299,13 @@ static int dom_write_na(dom_object *obj, zval *newval) /* }}} */ /* {{{ dom_register_prop_handler */ -static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_read_t read_func, dom_write_t write_func) +static void dom_register_prop_handler(HashTable *prop_handler, char *name, size_t name_len, dom_read_t read_func, dom_write_t write_func) { dom_prop_handler hnd; hnd.read_func = read_func ? read_func : dom_read_na; hnd.write_func = write_func ? write_func : dom_write_na; - zend_hash_str_add_mem(prop_handler, name, strlen(name), &hnd, sizeof(dom_prop_handler)); + zend_hash_str_add_mem(prop_handler, name, name_len, &hnd, sizeof(dom_prop_handler)); } /* }}} */ @@ -622,19 +622,19 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMStringList", NULL, php_dom_domstringlist_class_functions, dom_domstringlist_class_entry); zend_hash_init(&dom_domstringlist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", dom_domstringlist_length_read, NULL); + dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", sizeof("length")-1, dom_domstringlist_length_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_domstringlist_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMNameList", NULL, php_dom_namelist_class_functions, dom_namelist_class_entry); zend_hash_init(&dom_namelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_namelist_prop_handlers, "length", dom_namelist_length_read, NULL); + dom_register_prop_handler(&dom_namelist_prop_handlers, "length", sizeof("length")-1, dom_namelist_length_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_namelist_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMImplementationList", NULL, php_dom_domimplementationlist_class_functions, dom_domimplementationlist_class_entry); zend_hash_init(&dom_domimplementationlist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", dom_domimplementationlist_length_read, NULL); + dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", sizeof("length")-1, dom_domimplementationlist_length_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_domimplementationlist_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMImplementationSource", NULL, php_dom_domimplementationsource_class_functions, dom_domimplementationsource_class_entry); @@ -643,35 +643,35 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMNode", NULL, php_dom_node_class_functions, dom_node_class_entry); zend_hash_init(&dom_node_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write); - dom_register_prop_handler(&dom_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "childNodes", dom_node_child_nodes_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "firstChild", dom_node_first_child_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "lastChild", dom_node_last_child_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "previousSibling", dom_node_previous_sibling_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "nextSibling", dom_node_next_sibling_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "attributes", dom_node_attributes_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "prefix", dom_node_prefix_read, dom_node_prefix_write); - dom_register_prop_handler(&dom_node_prop_handlers, "localName", dom_node_local_name_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL); - dom_register_prop_handler(&dom_node_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", sizeof("nodeName")-1, dom_node_node_name_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", sizeof("nodeValue")-1, dom_node_node_value_read, dom_node_node_value_write); + dom_register_prop_handler(&dom_node_prop_handlers, "nodeType", sizeof("nodeType")-1, dom_node_node_type_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "parentNode", sizeof("parentNode")-1, dom_node_parent_node_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "childNodes", sizeof("childNodes")-1, dom_node_child_nodes_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "firstChild", sizeof("firstChild")-1, dom_node_first_child_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "lastChild", sizeof("lastChild")-1, dom_node_last_child_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "previousSibling", sizeof("previousSibling")-1, dom_node_previous_sibling_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "nextSibling", sizeof("nextSibling")-1, dom_node_next_sibling_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "attributes", sizeof("attributes")-1, dom_node_attributes_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "ownerDocument", sizeof("ownerDocument")-1, dom_node_owner_document_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "namespaceURI", sizeof("namespaceURI")-1, dom_node_namespace_uri_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "prefix", sizeof("prefix")-1, dom_node_prefix_read, dom_node_prefix_write); + dom_register_prop_handler(&dom_node_prop_handlers, "localName", sizeof("localName")-1, dom_node_local_name_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "baseURI", sizeof("baseURI")-1, dom_node_base_uri_read, NULL); + dom_register_prop_handler(&dom_node_prop_handlers, "textContent", sizeof("textContent")-1, dom_node_text_content_read, dom_node_text_content_write); zend_hash_add_ptr(&classes, ce.name, &dom_node_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMNameSpaceNode", NULL, NULL, dom_namespace_node_class_entry); zend_hash_init(&dom_namespace_node_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeValue", dom_node_node_value_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "prefix", dom_node_prefix_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "localName", dom_node_local_name_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL); - dom_register_prop_handler(&dom_namespace_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeName", sizeof("nodeName")-1, dom_node_node_name_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeValue", sizeof("nodeValue")-1, dom_node_node_value_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeType", sizeof("nodeType")-1, dom_node_node_type_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "prefix", sizeof("prefix")-1, dom_node_prefix_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "localName", sizeof("localName")-1, dom_node_local_name_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "namespaceURI", sizeof("namespaceURI")-1, dom_node_namespace_uri_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "ownerDocument", sizeof("ownerDocument")-1, dom_node_owner_document_read, NULL); + dom_register_prop_handler(&dom_namespace_node_prop_handlers, "parentNode", sizeof("parentNode")-1, dom_node_parent_node_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_namespace_node_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMDocumentFragment", dom_node_class_entry, php_dom_documentfragment_class_functions, dom_documentfragment_class_entry); @@ -679,25 +679,25 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMDocument", dom_node_class_entry, php_dom_document_class_functions, dom_document_class_entry); zend_hash_init(&dom_document_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "implementation", dom_document_implementation_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", dom_document_encoding_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "encoding", dom_document_encoding_read, dom_document_encoding_write); - dom_register_prop_handler(&dom_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "standalone", dom_document_standalone_read, dom_document_standalone_write); - dom_register_prop_handler(&dom_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write); - dom_register_prop_handler(&dom_document_prop_handlers, "version", dom_document_version_read, dom_document_version_write); - dom_register_prop_handler(&dom_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write); - dom_register_prop_handler(&dom_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write); - dom_register_prop_handler(&dom_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write); - dom_register_prop_handler(&dom_document_prop_handlers, "config", dom_document_config_read, NULL); - dom_register_prop_handler(&dom_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write); - dom_register_prop_handler(&dom_document_prop_handlers, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write); - dom_register_prop_handler(&dom_document_prop_handlers, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write); - dom_register_prop_handler(&dom_document_prop_handlers, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write); - dom_register_prop_handler(&dom_document_prop_handlers, "recover", dom_document_recover_read, dom_document_recover_write); - dom_register_prop_handler(&dom_document_prop_handlers, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write); + dom_register_prop_handler(&dom_document_prop_handlers, "doctype", sizeof("doctype")-1, dom_document_doctype_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "implementation", sizeof("implementation")-1, dom_document_implementation_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "documentElement", sizeof("documentElement")-1, dom_document_document_element_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", sizeof("actualEncoding")-1, dom_document_encoding_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "encoding", sizeof("encoding")-1, dom_document_encoding_read, dom_document_encoding_write); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlEncoding", sizeof("xmlEncoding")-1, dom_document_encoding_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "standalone", sizeof("standalone")-1, dom_document_standalone_read, dom_document_standalone_write); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlStandalone", sizeof("xmlStandalone")-1, dom_document_standalone_read, dom_document_standalone_write); + dom_register_prop_handler(&dom_document_prop_handlers, "version", sizeof("version")-1, dom_document_version_read, dom_document_version_write); + dom_register_prop_handler(&dom_document_prop_handlers, "xmlVersion", sizeof("xmlVersion")-1, dom_document_version_read, dom_document_version_write); + dom_register_prop_handler(&dom_document_prop_handlers, "strictErrorChecking", sizeof("strictErrorChecking")-1, dom_document_strict_error_checking_read, dom_document_strict_error_checking_write); + dom_register_prop_handler(&dom_document_prop_handlers, "documentURI", sizeof("documentURI")-1, dom_document_document_uri_read, dom_document_document_uri_write); + dom_register_prop_handler(&dom_document_prop_handlers, "config", sizeof("config")-1, dom_document_config_read, NULL); + dom_register_prop_handler(&dom_document_prop_handlers, "formatOutput", sizeof("formatOutput")-1, dom_document_format_output_read, dom_document_format_output_write); + dom_register_prop_handler(&dom_document_prop_handlers, "validateOnParse", sizeof("validateOnParse")-1, dom_document_validate_on_parse_read, dom_document_validate_on_parse_write); + dom_register_prop_handler(&dom_document_prop_handlers, "resolveExternals", sizeof("resolveExternals")-1, dom_document_resolve_externals_read, dom_document_resolve_externals_write); + dom_register_prop_handler(&dom_document_prop_handlers, "preserveWhiteSpace", sizeof("preserveWhitespace")-1, dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write); + dom_register_prop_handler(&dom_document_prop_handlers, "recover", sizeof("recover")-1, dom_document_recover_read, dom_document_recover_write); + dom_register_prop_handler(&dom_document_prop_handlers, "substituteEntities", sizeof("substituteEntities")-1, dom_document_substitue_entities_read, dom_document_substitue_entities_write); zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_document_prop_handlers); @@ -709,7 +709,7 @@ PHP_MINIT_FUNCTION(dom) zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable); zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL); + dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", sizeof("length")-1, dom_nodelist_length_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_nodelist_prop_handlers); INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", php_dom_namednodemap_class_functions); @@ -719,40 +719,40 @@ PHP_MINIT_FUNCTION(dom) zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable); zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL); + dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_namednodemap_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMCharacterData", dom_node_class_entry, php_dom_characterdata_class_functions, dom_characterdata_class_entry); zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write); - dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL); + dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", sizeof("data")-1, dom_characterdata_data_read, dom_characterdata_data_write); + dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", sizeof("length")-1, dom_characterdata_length_read, NULL); zend_hash_merge(&dom_characterdata_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_characterdata_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMAttr", dom_node_class_entry, php_dom_attr_class_functions, dom_attr_class_entry); zend_hash_init(&dom_attr_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL); - dom_register_prop_handler(&dom_attr_prop_handlers, "specified", dom_attr_specified_read, NULL); - dom_register_prop_handler(&dom_attr_prop_handlers, "value", dom_attr_value_read, dom_attr_value_write); - dom_register_prop_handler(&dom_attr_prop_handlers, "ownerElement", dom_attr_owner_element_read, NULL); - dom_register_prop_handler(&dom_attr_prop_handlers, "schemaTypeInfo", dom_attr_schema_type_info_read, NULL); + dom_register_prop_handler(&dom_attr_prop_handlers, "name", sizeof("name")-1, dom_attr_name_read, NULL); + dom_register_prop_handler(&dom_attr_prop_handlers, "specified", sizeof("specified")-1, dom_attr_specified_read, NULL); + dom_register_prop_handler(&dom_attr_prop_handlers, "value", sizeof("value")-1, dom_attr_value_read, dom_attr_value_write); + dom_register_prop_handler(&dom_attr_prop_handlers, "ownerElement", sizeof("ownerElement")-1, dom_attr_owner_element_read, NULL); + dom_register_prop_handler(&dom_attr_prop_handlers, "schemaTypeInfo", sizeof("schemaTypeInfo")-1, dom_attr_schema_type_info_read, NULL); zend_hash_merge(&dom_attr_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_attr_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMElement", dom_node_class_entry, php_dom_element_class_functions, dom_element_class_entry); zend_hash_init(&dom_element_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL); - dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", dom_element_schema_type_info_read, NULL); + dom_register_prop_handler(&dom_element_prop_handlers, "tagName", sizeof("tagName")-1, dom_element_tag_name_read, NULL); + dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", sizeof("schemaTypeInfo")-1, dom_element_schema_type_info_read, NULL); zend_hash_merge(&dom_element_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_element_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMText", dom_characterdata_class_entry, php_dom_text_class_functions, dom_text_class_entry); zend_hash_init(&dom_text_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL); + dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", sizeof("wholeText")-1, dom_text_whole_text_read, NULL); zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_text_prop_handlers); @@ -762,31 +762,31 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMTypeinfo", NULL, php_dom_typeinfo_class_functions, dom_typeinfo_class_entry); zend_hash_init(&dom_typeinfo_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", dom_typeinfo_type_name_read, NULL); - dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", dom_typeinfo_type_namespace_read, NULL); + dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", sizeof("typeName")-1, dom_typeinfo_type_name_read, NULL); + dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", sizeof("typeNamespace")-1, dom_typeinfo_type_namespace_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_typeinfo_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMUserDataHandler", NULL, php_dom_userdatahandler_class_functions, dom_userdatahandler_class_entry); REGISTER_DOM_CLASS(ce, "DOMDomError", NULL, php_dom_domerror_class_functions, dom_domerror_class_entry); zend_hash_init(&dom_domerror_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", dom_domerror_severity_read, NULL); - dom_register_prop_handler(&dom_domerror_prop_handlers, "message", dom_domerror_message_read, NULL); - dom_register_prop_handler(&dom_domerror_prop_handlers, "type", dom_domerror_type_read, NULL); - dom_register_prop_handler(&dom_domerror_prop_handlers, "relatedException", dom_domerror_related_exception_read, NULL); - dom_register_prop_handler(&dom_domerror_prop_handlers, "related_data", dom_domerror_related_data_read, NULL); - dom_register_prop_handler(&dom_domerror_prop_handlers, "location", dom_domerror_location_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", sizeof("severity")-1, dom_domerror_severity_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "message", sizeof("message")-1, dom_domerror_message_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "type", sizeof("type")-1, dom_domerror_type_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "relatedException", sizeof("relatedException")-1, dom_domerror_related_exception_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "related_data", sizeof("related_data")-1, dom_domerror_related_data_read, NULL); + dom_register_prop_handler(&dom_domerror_prop_handlers, "location", sizeof("location")-1, dom_domerror_location_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_domerror_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMErrorHandler", NULL, php_dom_domerrorhandler_class_functions, dom_domerrorhandler_class_entry); REGISTER_DOM_CLASS(ce, "DOMLocator", NULL, php_dom_domlocator_class_functions, dom_domlocator_class_entry); zend_hash_init(&dom_domlocator_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", dom_domlocator_line_number_read, NULL); - dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", dom_domlocator_column_number_read, NULL); - dom_register_prop_handler(&dom_domlocator_prop_handlers, "offset", dom_domlocator_offset_read, NULL); - dom_register_prop_handler(&dom_domlocator_prop_handlers, "relatedNode", dom_domlocator_related_node_read, NULL); - dom_register_prop_handler(&dom_domlocator_prop_handlers, "uri", dom_domlocator_uri_read, NULL); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", sizeof("lineNumber")-1, dom_domlocator_line_number_read, NULL); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", sizeof("columnNumber")-1, dom_domlocator_column_number_read, NULL); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "offset", sizeof("offset")-1, dom_domlocator_offset_read, NULL); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "relatedNode", sizeof("relatedNode")-1, dom_domlocator_related_node_read, NULL); + dom_register_prop_handler(&dom_domlocator_prop_handlers, "uri", sizeof("uri")-1, dom_domlocator_uri_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_domlocator_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMConfiguration", NULL, php_dom_domconfiguration_class_functions, dom_domconfiguration_class_entry); @@ -796,32 +796,32 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMDocumentType", dom_node_class_entry, php_dom_documenttype_class_functions, dom_documenttype_class_entry); zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "notations", dom_documenttype_notations_read, NULL); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "publicId", dom_documenttype_public_id_read, NULL); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "systemId", dom_documenttype_system_id_read, NULL); - dom_register_prop_handler(&dom_documenttype_prop_handlers, "internalSubset", dom_documenttype_internal_subset_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", sizeof("name")-1, dom_documenttype_name_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", sizeof("entities")-1, dom_documenttype_entities_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "notations", sizeof("notations")-1, dom_documenttype_notations_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "publicId", sizeof("publicId")-1, dom_documenttype_public_id_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "systemId", sizeof("systemId")-1, dom_documenttype_system_id_read, NULL); + dom_register_prop_handler(&dom_documenttype_prop_handlers, "internalSubset", sizeof("internalSubset")-1, dom_documenttype_internal_subset_read, NULL); zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_documenttype_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMNotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry); zend_hash_init(&dom_notation_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL); - dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL); + dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", sizeof("publicId")-1, dom_notation_public_id_read, NULL); + dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", sizeof("systemId")-1, dom_notation_system_id_read, NULL); zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_notation_prop_handlers); REGISTER_DOM_CLASS(ce, "DOMEntity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry); zend_hash_init(&dom_entity_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL); - dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL); - dom_register_prop_handler(&dom_entity_prop_handlers, "notationName", dom_entity_notation_name_read, NULL); - dom_register_prop_handler(&dom_entity_prop_handlers, "actualEncoding", dom_entity_actual_encoding_read, dom_entity_actual_encoding_write); - dom_register_prop_handler(&dom_entity_prop_handlers, "encoding", dom_entity_encoding_read, dom_entity_encoding_write); - dom_register_prop_handler(&dom_entity_prop_handlers, "version", dom_entity_version_read, dom_entity_version_write); + dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", sizeof("publicId")-1, dom_entity_public_id_read, NULL); + dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", sizeof("systemId")-1, dom_entity_system_id_read, NULL); + dom_register_prop_handler(&dom_entity_prop_handlers, "notationName", sizeof("notationName")-1, dom_entity_notation_name_read, NULL); + dom_register_prop_handler(&dom_entity_prop_handlers, "actualEncoding", sizeof("actualEncoding")-1, dom_entity_actual_encoding_read, dom_entity_actual_encoding_write); + dom_register_prop_handler(&dom_entity_prop_handlers, "encoding", sizeof("encoding")-1, dom_entity_encoding_read, dom_entity_encoding_write); + dom_register_prop_handler(&dom_entity_prop_handlers, "version", sizeof("version")-1, dom_entity_version_read, dom_entity_version_write); zend_hash_merge(&dom_entity_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_entity_prop_handlers); @@ -831,8 +831,8 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMProcessingInstruction", dom_node_class_entry, php_dom_processinginstruction_class_functions, dom_processinginstruction_class_entry); zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL); - dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write); + dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", sizeof("target")-1, dom_processinginstruction_target_read, NULL); + dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", sizeof("data")-1, dom_processinginstruction_data_read, dom_processinginstruction_data_write); zend_hash_merge(&dom_processinginstruction_prop_handlers, &dom_node_prop_handlers, dom_copy_prop_handler, 0); zend_hash_add_ptr(&classes, ce.name, &dom_processinginstruction_prop_handlers); @@ -848,7 +848,7 @@ PHP_MINIT_FUNCTION(dom) dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL); zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); - dom_register_prop_handler(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL); + dom_register_prop_handler(&dom_xpath_prop_handlers, "document", sizeof("document")-1, dom_xpath_document_read, NULL); zend_hash_add_ptr(&classes, ce.name, &dom_xpath_prop_handlers); #endif diff --git a/ext/exif/config.w32 b/ext/exif/config.w32 index 595e71bda0..ad000c4251 100644 --- a/ext/exif/config.w32 +++ b/ext/exif/config.w32 @@ -1,14 +1,14 @@ // $Id$ // vim:ft=javascript -ARG_ENABLE("exif", "exif", "no"); +ARG_ENABLE('exif', 'Exchangeable image information (EXIF) Support', 'no'); -if (PHP_EXIF == "yes") { - if (ADD_EXTENSION_DEP('exif', 'mbstring')) { - EXTENSION("exif", "exif.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - AC_DEFINE('HAVE_EXIF', 1, 'Have exif'); - } else { - WARNING("exif support can't be enabled, libxml is not enabled") - PHP_EXIF = "no" +if(PHP_EXIF != 'no') +{ + if(ADD_EXTENSION_DEP('exif', 'mbstring')) + { + AC_DEFINE('HAVE_EXIF', 1, 'Have EXIF Support'); + + EXTENSION('exif', 'exif.c', null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); } -} +}
\ No newline at end of file diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 1c2db35f36..c882a12c7c 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -89,7 +89,7 @@ typedef unsigned char uchar; #define EFREE_IF(ptr) if (ptr) efree(ptr) -#define MAX_IFD_NESTING_LEVEL 100 +#define MAX_IFD_NESTING_LEVEL 150 /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_exif_tagname, 0) @@ -136,7 +136,16 @@ PHP_MINFO_FUNCTION(exif) php_info_print_table_row(2, "EXIF Support", "enabled"); php_info_print_table_row(2, "EXIF Version", PHP_EXIF_VERSION); php_info_print_table_row(2, "Supported EXIF Version", "0220"); - php_info_print_table_row(2, "Supported filetypes", "JPEG,TIFF"); + php_info_print_table_row(2, "Supported filetypes", "JPEG, TIFF"); + + if (zend_hash_str_exists(&module_registry, "mbstring", sizeof("mbstring")-1)) { + php_info_print_table_row(2, "Multibyte decoding support using mbstring", "enabled"); + } else { + php_info_print_table_row(2, "Multibyte decoding support using mbstring", "disabled"); + } + + php_info_print_table_row(2, "Extended EXIF tag formats", "Canon, Casio, Fujifilm, Nikon, Olympus, Samsung, Panasonic, DJI, Sony, Pentax, Minolta, Sigma, Foveon"); + php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } @@ -171,7 +180,7 @@ ZEND_INI_MH(OnUpdateEncode) php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value)); return FAILURE; } - efree(return_list); + pefree((void *) return_list, 0); } return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } @@ -186,7 +195,7 @@ ZEND_INI_MH(OnUpdateDecode) php_error_docref(NULL, E_WARNING, "Illegal encoding ignored: '%s'", ZSTR_VAL(new_value)); return FAILURE; } - efree(return_list); + pefree((void *) return_list, 0); } return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } @@ -218,7 +227,7 @@ static PHP_GINIT_FUNCTION(exif) /* }}} */ /* {{{ PHP_MINIT_FUNCTION(exif) - Get the size of an image as 4-element array */ + */ PHP_MINIT_FUNCTION(exif) { REGISTER_INI_ENTRIES(); @@ -955,6 +964,360 @@ static tag_info_array tag_table_VND_OLYMPUS = { TAG_TABLE_END }; +static tag_info_array tag_table_VND_SAMSUNG = { + { 0x0001, "Version"}, + { 0x0021, "PictureWizard"}, + { 0x0030, "LocalLocationName"}, + { 0x0031, "LocationName"}, + { 0x0035, "Preview"}, + { 0x0043, "CameraTemperature"}, + { 0xa001, "FirmwareName"}, + { 0xa003, "LensType"}, + { 0xa004, "LensFirmware"}, + { 0xa010, "SensorAreas"}, + { 0xa011, "ColorSpace"}, + { 0xa012, "SmartRange"}, + { 0xa013, "ExposureBiasValue"}, + { 0xa014, "ISO"}, + { 0xa018, "ExposureTime"}, + { 0xa019, "FNumber"}, + { 0xa01a, "FocalLengthIn35mmFormat"}, + { 0xa020, "EncryptionKey"}, + { 0xa021, "WB_RGGBLevelsUncorrected"}, + { 0xa022, "WB_RGGBLevelsAuto"}, + { 0xa023, "WB_RGGBLevelsIlluminator1"}, + { 0xa024, "WB_RGGBLevelsIlluminator2"}, + { 0xa028, "WB_RGGBLevelsBlack"}, + { 0xa030, "ColorMatrix"}, + { 0xa031, "ColorMatrixSRGB"}, + { 0xa032, "ColorMatrixAdobeRGB"}, + { 0xa040, "ToneCurve1"}, + { 0xa041, "ToneCurve2"}, + { 0xa042, "ToneCurve3"}, + { 0xa043, "ToneCurve4"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_PANASONIC = { + { 0x0001, "Quality"}, + { 0x0002, "FirmwareVersion"}, + { 0x0003, "WhiteBalance"}, + { 0x0004, "0x0004"}, + { 0x0007, "FocusMode"}, + { 0x000f, "AFMode"}, + { 0x001a, "ImageStabilization"}, + { 0x001c, "Macro"}, + { 0x001f, "ShootingMode"}, + { 0x0020, "Audio"}, + { 0x0021, "DataDump"}, + { 0x0022, "0x0022"}, + { 0x0023, "WhiteBalanceBias"}, + { 0x0024, "FlashBias"}, + { 0x0025, "InternalSerialNumber"}, + { 0x0026, "ExifVersion"}, + { 0x0027, "0x0027"}, + { 0x0028, "ColorEffect"}, + { 0x0029, "TimeSincePowerOn"}, + { 0x002a, "BurstMode"}, + { 0x002b, "SequenceNumber"}, + { 0x002c, "Contrast"}, + { 0x002d, "NoiseReduction"}, + { 0x002e, "SelfTimer"}, + { 0x002f, "0x002f"}, + { 0x0030, "Rotation"}, + { 0x0031, "AFAssistLamp"}, + { 0x0032, "ColorMode"}, + { 0x0033, "BabyAge1"}, + { 0x0034, "OpticalZoomMode"}, + { 0x0035, "ConversionLens"}, + { 0x0036, "TravelDay"}, + { 0x0039, "Contrast"}, + { 0x003a, "WorldTimeLocation"}, + { 0x003b, "TextStamp1"}, + { 0x003c, "ProgramISO"}, + { 0x003d, "AdvancedSceneType"}, + { 0x003e, "TextStamp2"}, + { 0x003f, "FacesDetected"}, + { 0x0040, "Saturation"}, + { 0x0041, "Sharpness"}, + { 0x0042, "FilmMode"}, + { 0x0044, "ColorTempKelvin"}, + { 0x0045, "BracketSettings"}, + { 0x0046, "WBAdjustAB"}, + { 0x0047, "WBAdjustGM"}, + { 0x0048, "FlashCurtain"}, + { 0x0049, "LongShutterNoiseReduction"}, + { 0x004b, "ImageWidth"}, + { 0x004c, "ImageHeight"}, + { 0x004d, "AFPointPosition"}, + { 0x004e, "FaceDetInfo"}, + { 0x0051, "LensType"}, + { 0x0052, "LensSerialNumber"}, + { 0x0053, "AccessoryType"}, + { 0x0054, "AccessorySerialNumber"}, + { 0x0059, "Transform1"}, + { 0x005d, "IntelligentExposure"}, + { 0x0060, "LensFirmwareVersion"}, + { 0x0061, "FaceRecInfo"}, + { 0x0062, "FlashWarning"}, + { 0x0065, "Title"}, + { 0x0066, "BabyName"}, + { 0x0067, "Location"}, + { 0x0069, "Country"}, + { 0x006b, "State"}, + { 0x006d, "City"}, + { 0x006f, "Landmark"}, + { 0x0070, "IntelligentResolution"}, + { 0x0077, "BurstSheed"}, + { 0x0079, "IntelligentDRange"}, + { 0x007c, "ClearRetouch"}, + { 0x0080, "City2"}, + { 0x0086, "ManometerPressure"}, + { 0x0089, "PhotoStyle"}, + { 0x008a, "ShadingCompensation"}, + { 0x008c, "AccelerometerZ"}, + { 0x008d, "AccelerometerX"}, + { 0x008e, "AccelerometerY"}, + { 0x008f, "CameraOrientation"}, + { 0x0090, "RollAngle"}, + { 0x0091, "PitchAngle"}, + { 0x0093, "SweepPanoramaDirection"}, + { 0x0094, "PanoramaFieldOfView"}, + { 0x0096, "TimerRecording"}, + { 0x009d, "InternalNDFilter"}, + { 0x009e, "HDR"}, + { 0x009f, "ShutterType"}, + { 0x00a3, "ClearRetouchValue"}, + { 0x00ab, "TouchAE"}, + { 0x0e00, "PrintIM"}, + { 0x4449, "0x4449"}, + { 0x8000, "MakerNoteVersion"}, + { 0x8001, "SceneMode"}, + { 0x8004, "WBRedLevel"}, + { 0x8005, "WBGreenLevel"}, + { 0x8006, "WBBlueLevel"}, + { 0x8007, "FlashFired"}, + { 0x8008, "TextStamp3"}, + { 0x8009, "TextStamp4"}, + { 0x8010, "BabyAge2"}, + { 0x8012, "Transform2"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_DJI = { + { 0x0001, "Make"}, + { 0x0003, "SpeedX"}, + { 0x0004, "SpeedY"}, + { 0x0005, "SpeedZ"}, + { 0x0006, "Pitch"}, + { 0x0007, "Yaw"}, + { 0x0008, "Roll"}, + { 0x0009, "CameraPitch"}, + { 0x000a, "CameraYaw"}, + { 0x000b, "CameraRoll"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_SONY = { + { 0x0102, "Quality"}, + { 0x0104, "FlashExposureComp"}, + { 0x0105, "Teleconverter"}, + { 0x0112, "WhiteBalanceFineTune"}, + { 0x0114, "CameraSettings"}, + { 0x0115, "WhiteBalance"}, + { 0x0116, "0x0116"}, + { 0x0e00, "PrintIM"}, + { 0x1000, "MultiBurstMode"}, + { 0x1001, "MultiBurstImageWidth"}, + { 0x1002, "MultiBurstImageHeight"}, + { 0x1003, "Panorama"}, + { 0x2000, "0x2000"}, + { 0x2001, "PreviewImage"}, + { 0x2002, "0x2002"}, + { 0x2003, "0x2003"}, + { 0x2004, "Contrast"}, + { 0x2005, "Saturation"}, + { 0x2006, "0x2006"}, + { 0x2007, "0x2007"}, + { 0x2008, "0x2008"}, + { 0x2009, "0x2009"}, + { 0x200a, "AutoHDR"}, + { 0x3000, "ShotInfo"}, + { 0xb000, "FileFormat"}, + { 0xb001, "SonyModelID"}, + { 0xb020, "ColorReproduction"}, + { 0xb021, "ColorTemperature"}, + { 0xb022, "ColorCompensationFilter"}, + { 0xb023, "SceneMode"}, + { 0xb024, "ZoneMatching"}, + { 0xb025, "DynamicRangeOptimizer"}, + { 0xb026, "ImageStabilization"}, + { 0xb027, "LensID"}, + { 0xb028, "MinoltaMakerNote"}, + { 0xb029, "ColorMode"}, + { 0xb02b, "FullImageSize"}, + { 0xb02c, "PreviewImageSize"}, + { 0xb040, "Macro"}, + { 0xb041, "ExposureMode"}, + { 0xb042, "FocusMode"}, + { 0xb043, "AFMode"}, + { 0xb044, "AFIlluminator"}, + { 0xb047, "JPEGQuality"}, + { 0xb048, "FlashLevel"}, + { 0xb049, "ReleaseMode"}, + { 0xb04a, "SequenceNumber"}, + { 0xb04b, "AntiBlur"}, + { 0xb04e, "LongExposureNoiseReduction"}, + { 0xb04f, "DynamicRangeOptimizer"}, + { 0xb052, "IntelligentAuto"}, + { 0xb054, "WhiteBalance2"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_PENTAX = { + { 0x0000, "Version"}, + { 0x0001, "Mode"}, + { 0x0002, "PreviewResolution"}, + { 0x0003, "PreviewLength"}, + { 0x0004, "PreviewOffset"}, + { 0x0005, "ModelID"}, + { 0x0006, "Date"}, + { 0x0007, "Time"}, + { 0x0008, "Quality"}, + { 0x0009, "Size"}, + { 0x000c, "Flash"}, + { 0x000d, "Focus"}, + { 0x000e, "AFPoint"}, + { 0x000f, "AFPointInFocus"}, + { 0x0012, "ExposureTime"}, + { 0x0013, "FNumber"}, + { 0x0014, "ISO"}, + { 0x0016, "ExposureCompensation"}, + { 0x0017, "MeteringMode"}, + { 0x0018, "AutoBracketing"}, + { 0x0019, "WhiteBalance"}, + { 0x001a, "WhiteBalanceMode"}, + { 0x001b, "BlueBalance"}, + { 0x001c, "RedBalance"}, + { 0x001d, "FocalLength"}, + { 0x001e, "DigitalZoom"}, + { 0x001f, "Saturation"}, + { 0x0020, "Contrast"}, + { 0x0021, "Sharpness"}, + { 0x0022, "Location"}, + { 0x0023, "Hometown"}, + { 0x0024, "Destination"}, + { 0x0025, "HometownDST"}, + { 0x0026, "DestinationDST"}, + { 0x0027, "DSPFirmwareVersion"}, + { 0x0028, "CPUFirmwareVersion"}, + { 0x0029, "FrameNumber"}, + { 0x002d, "EffectiveLV"}, + { 0x0032, "ImageProcessing"}, + { 0x0033, "PictureMode"}, + { 0x0034, "DriveMode"}, + { 0x0037, "ColorSpace"}, + { 0x0038, "ImageAreaOffset"}, + { 0x0039, "RawImageSize"}, + { 0x003e, "PreviewImageBorders"}, + { 0x003f, "LensType"}, + { 0x0040, "SensitivityAdjust"}, + { 0x0041, "DigitalFilter"}, + { 0x0047, "Temperature"}, + { 0x0048, "AELock"}, + { 0x0049, "NoiseReduction"}, + { 0x004d, "FlashExposureCompensation"}, + { 0x004f, "ImageTone"}, + { 0x0050, "ColorTemperature"}, + { 0x005c, "ShakeReduction"}, + { 0x005d, "ShutterCount"}, + { 0x0069, "DynamicRangeExpansion"}, + { 0x0071, "HighISONoiseReduction"}, + { 0x0072, "AFAdjustment"}, + { 0x0200, "BlackPoint"}, + { 0x0201, "WhitePoint"}, + { 0x0205, "ShotInfo"}, + { 0x0206, "AEInfo"}, + { 0x0207, "LensInfo"}, + { 0x0208, "FlashInfo"}, + { 0x0209, "AEMeteringSegments"}, + { 0x020a, "FlashADump"}, + { 0x020b, "FlashBDump"}, + { 0x020d, "WB_RGGBLevelsDaylight"}, + { 0x020e, "WB_RGGBLevelsShade"}, + { 0x020f, "WB_RGGBLevelsCloudy"}, + { 0x0210, "WB_RGGBLevelsTungsten"}, + { 0x0211, "WB_RGGBLevelsFluorescentD"}, + { 0x0212, "WB_RGGBLevelsFluorescentN"}, + { 0x0213, "WB_RGGBLevelsFluorescentW"}, + { 0x0214, "WB_RGGBLevelsFlash"}, + { 0x0215, "CameraInfo"}, + { 0x0216, "BatteryInfo"}, + { 0x021f, "AFInfo"}, + { 0x0222, "ColorInfo"}, + { 0x0229, "SerialNumber"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_MINOLTA = { + { 0x0000, "Version"}, + { 0x0001, "CameraSettingsStdOld"}, + { 0x0003, "CameraSettingsStdNew"}, + { 0x0004, "CameraSettings7D"}, + { 0x0018, "ImageStabilizationData"}, + { 0x0020, "WBInfoA100"}, + { 0x0040, "CompressedImageSize"}, + { 0x0081, "Thumbnail"}, + { 0x0088, "ThumbnailOffset"}, + { 0x0089, "ThumbnailLength"}, + { 0x0100, "SceneMode"}, + { 0x0101, "ColorMode"}, + { 0x0102, "Quality"}, + { 0x0103, "0x0103"}, + { 0x0104, "FlashExposureComp"}, + { 0x0105, "Teleconverter"}, + { 0x0107, "ImageStabilization"}, + { 0x0109, "RawAndJpgRecording"}, + { 0x010a, "ZoneMatching"}, + { 0x010b, "ColorTemperature"}, + { 0x010c, "LensID"}, + { 0x0111, "ColorCompensationFilter"}, + { 0x0112, "WhiteBalanceFineTune"}, + { 0x0113, "ImageStabilizationA100"}, + { 0x0114, "CameraSettings5D"}, + { 0x0115, "WhiteBalance"}, + { 0x0e00, "PrintIM"}, + { 0x0f00, "CameraSettingsZ1"}, + TAG_TABLE_END +}; + +static tag_info_array tag_table_VND_SIGMA = { + { 0x0002, "SerialNumber"}, + { 0x0003, "DriveMode"}, + { 0x0004, "ResolutionMode"}, + { 0x0005, "AutofocusMode"}, + { 0x0006, "FocusSetting"}, + { 0x0007, "WhiteBalance"}, + { 0x0008, "ExposureMode"}, + { 0x0009, "MeteringMode"}, + { 0x000a, "LensRange"}, + { 0x000b, "ColorSpace"}, + { 0x000c, "Exposure"}, + { 0x000d, "Contrast"}, + { 0x000e, "Shadow"}, + { 0x000f, "Highlight"}, + { 0x0010, "Saturation"}, + { 0x0011, "Sharpness"}, + { 0x0012, "FillLight"}, + { 0x0014, "ColorAdjustment"}, + { 0x0015, "AdjustmentMode"}, + { 0x0016, "Quality"}, + { 0x0017, "Firmware"}, + { 0x0018, "Software"}, + { 0x0019, "AutoBracket"}, + TAG_TABLE_END +}; + typedef enum mn_byte_order_t { MN_ORDER_INTEL = 0, MN_ORDER_MOTOROLA = 1, @@ -978,14 +1341,22 @@ typedef struct { mn_offset_mode_t offset_mode; } maker_note_type; +/* Remember to update PHP_MINFO if updated */ static const maker_note_type maker_note_array[] = { { tag_table_VND_CANON, "Canon", NULL, NULL, 0, 0, MN_ORDER_INTEL, MN_OFFSET_GUESS}, -/* { tag_table_VND_CANON, "Canon", NULL, NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL},*/ { tag_table_VND_CASIO, "CASIO", NULL, NULL, 0, 0, MN_ORDER_MOTOROLA, MN_OFFSET_NORMAL}, { tag_table_VND_FUJI, "FUJIFILM", NULL, "FUJIFILM\x0C\x00\x00\x00", 12, 12, MN_ORDER_INTEL, MN_OFFSET_MAKER}, { tag_table_VND_NIKON, "NIKON", NULL, "Nikon\x00\x01\x00", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, { tag_table_VND_NIKON_990, "NIKON", NULL, NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, { tag_table_VND_OLYMPUS, "OLYMPUS OPTICAL CO.,LTD", NULL, "OLYMP\x00\x01\x00", 8, 8, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_SAMSUNG, "SAMSUNG", NULL, NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_PANASONIC, "Panasonic", NULL, "Panasonic\x00\x00\x00", 12, 12, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_DJI, "DJI", NULL, NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_SONY, "SONY", NULL, "SONY DSC \x00\x00\x00", 12, 12, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_PENTAX, "PENTAX", NULL, "AOC\x00", 6, 6, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_MINOLTA, "Minolta, KONICA MINOLTA", NULL, NULL, 0, 0, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_SIGMA, "SIGMA, FOVEON", NULL, "SIGMA\x00\x00\x00", 10, 10, MN_ORDER_NORMAL, MN_OFFSET_NORMAL}, + { tag_table_VND_SIGMA, "SIGMA, FOVEON", NULL, "FOVEON\x00\x00\x00", 10, 10, MN_ORDER_NORMAL, MN_OFFSET_NORMAL} }; /* }}} */ @@ -1270,6 +1641,20 @@ static double exif_convert_any_format(void *value, int format, int motorola_inte } /* }}} */ +/* {{{ exif_rewrite_tag_format_to_unsigned + * Rewrite format tag so that it specifies an unsigned type for a tag */ +static int exif_rewrite_tag_format_to_unsigned(int format) +{ + switch(format) { + case TAG_FMT_SBYTE: return TAG_FMT_BYTE; + case TAG_FMT_SRATIONAL: return TAG_FMT_URATIONAL; + case TAG_FMT_SSHORT: return TAG_FMT_USHORT; + case TAG_FMT_SLONG: return TAG_FMT_ULONG; + } + return format; +} +/* }}} */ + /* {{{ exif_convert_any_to_int * Evaluate number, be it int, rational, or float from directory. */ static size_t exif_convert_any_to_int(void *value, int format, int motorola_intel) @@ -1704,7 +2089,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c case TAG_FMT_UNDEFINED: if (value) { if (tag == TAG_MAKER_NOTE) { - length = MIN(length, strlen(value)); + length = MIN(length, (int) strlen(value)); } /* do not recompute length here */ @@ -2715,7 +3100,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu int NumDirEntries, old_motorola_intel, offset_diff; const maker_note_type *maker_note; char *dir_start; - + for (i=0; i<=sizeof(maker_note_array)/sizeof(maker_note_type); i++) { if (i==sizeof(maker_note_array)/sizeof(maker_note_type)) { #ifdef EXIF_DEBUG @@ -2736,7 +3121,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu continue; break; } - + if (maker_note->offset >= value_len) { /* Do not go past the value end */ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset); @@ -2844,7 +3229,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha /*return TRUE;*/ } - if (components < 0) { + if (components <= 0) { exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal components(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table), components); return FALSE; } @@ -2933,18 +3318,18 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha switch(tag) { case TAG_IMAGEWIDTH: case TAG_COMP_IMAGE_WIDTH: - ImageInfo->Thumbnail.width = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->Thumbnail.width = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); break; case TAG_IMAGEHEIGHT: case TAG_COMP_IMAGE_HEIGHT: - ImageInfo->Thumbnail.height = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->Thumbnail.height = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); break; case TAG_STRIP_OFFSETS: case TAG_JPEG_INTERCHANGE_FORMAT: /* accept both formats */ - ImageInfo->Thumbnail.offset = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->Thumbnail.offset = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); break; case TAG_STRIP_BYTE_COUNTS: @@ -2954,13 +3339,13 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha /* motorola is easier to read */ ImageInfo->Thumbnail.filetype = IMAGE_FILETYPE_TIFF_MM; } - ImageInfo->Thumbnail.size = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->Thumbnail.size = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); break; case TAG_JPEG_INTERCHANGE_FORMAT_LEN: if (ImageInfo->Thumbnail.filetype == IMAGE_FILETYPE_UNKNOWN) { ImageInfo->Thumbnail.filetype = IMAGE_FILETYPE_JPEG; - ImageInfo->Thumbnail.size = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->Thumbnail.size = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); } break; } @@ -3032,7 +3417,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha break; case TAG_COMP_IMAGE_WIDTH: - ImageInfo->ExifImageWidth = exif_convert_any_to_int(value_ptr, format, ImageInfo->motorola_intel); + ImageInfo->ExifImageWidth = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel); break; case TAG_FOCALPLANE_X_RES: @@ -3725,6 +4110,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse if (fgot < ImageInfo->Thumbnail.size) { EXIF_ERRLOG_THUMBEOF(ImageInfo) efree(ImageInfo->Thumbnail.data); + ImageInfo->Thumbnail.data = NULL; } else { exif_thumbnail_build(ImageInfo); @@ -4204,7 +4590,7 @@ PHP_FUNCTION(exif_imagetype) php_stream * stream; int itype = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &imagefile, &imagefile_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &imagefile, &imagefile_len) == FAILURE) { return; } diff --git a/ext/exif/tests/bug68547.jpg b/ext/exif/tests/bug68547.jpg Binary files differnew file mode 100644 index 0000000000..2a328b76a8 --- /dev/null +++ b/ext/exif/tests/bug68547.jpg diff --git a/ext/exif/tests/bug68547.phpt b/ext/exif/tests/bug68547.phpt new file mode 100644 index 0000000000..894c76806d --- /dev/null +++ b/ext/exif/tests/bug68547.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #68547 (Exif Header component value check error) +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +exif_read_data(__DIR__ . DIRECTORY_SEPARATOR . 'bug68547.jpg'); +?> +===DONE=== +--EXPECTF-- +Warning: exif_read_data(bug68547.jpg): Process tag(x9C9E=Keywords ): Illegal components(%d) in %sbug68547.php on line %d +===DONE===
\ No newline at end of file diff --git a/ext/exif/tests/bug68799.phpt b/ext/exif/tests/bug68799.phpt index f50a41b402..a24664109d 100644 --- a/ext/exif/tests/bug68799.phpt +++ b/ext/exif/tests/bug68799.phpt @@ -39,6 +39,7 @@ print_r(exif_read_data(__DIR__.'/bug68799.jpg')); ?> --EXPECTF-- +Warning: exif_read_data(bug68799.jpg): Process tag(x9C9D=Author ): Illegal components(%d) in %s on line %d Array ( [FileName] => bug68799.jpg @@ -46,7 +47,7 @@ Array [FileSize] => 735 [FileType] => 2 [MimeType] => image/jpeg - [SectionsFound] => ANY_TAG, IFD0, WINXP + [SectionsFound] => ANY_TAG, IFD0 [COMPUTED] => Array ( [html] => width="1" height="1" @@ -59,5 +60,4 @@ Array [XResolution] => 96/1 [YResolution] => 96/1 [ResolutionUnit] => 2 - [Author] => ) diff --git a/ext/exif/tests/bug71534.phpt b/ext/exif/tests/bug71534.phpt new file mode 100644 index 0000000000..1f5fc9db04 --- /dev/null +++ b/ext/exif/tests/bug71534.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #71534 (Type confusion in exif_read_data() leading to heap overflow in debug mode) +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +// This is kinda bad, I know! But, this generates about 200+ warnings due to its +// broken TIFF format +var_dump(@exif_read_data(__DIR__ . DIRECTORY_SEPARATOR . 'bug71534.tiff') === false); +?> +--EXPECT-- +bool(true) diff --git a/ext/exif/tests/bug71534.tiff b/ext/exif/tests/bug71534.tiff Binary files differnew file mode 100644 index 0000000000..1a224d54c9 --- /dev/null +++ b/ext/exif/tests/bug71534.tiff diff --git a/ext/exif/tests/bug72094.phpt b/ext/exif/tests/bug72094.phpt index 611faf9152..486c3732a1 100644 --- a/ext/exif/tests/bug72094.phpt +++ b/ext/exif/tests/bug72094.phpt @@ -23,7 +23,7 @@ Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal Warning: exif_read_data(bug72094_1.jpg): Process tag(x8298=Copyright ): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_1.jpg): Illegal IFD offset in %s%ebug72094.php on line %d +Warning: exif_read_data(bug72094_1.jpg): Illegal IFD offset in %sbug72094.php on line %d Warning: exif_read_data(bug72094_1.jpg): File structure corrupted in %s%ebug72094.php on line %d @@ -47,7 +47,7 @@ Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s%ebug72094.php on line %d -Warning: exif_read_data(bug72094_3.jpg): Illegal IFD size in %s%ebug72094.php on line %d +Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal components(%d) in %s%ebug72094.php on line %d Warning: exif_read_data(bug72094_3.jpg): File structure corrupted in %s%ebug72094.php on line %d diff --git a/ext/exif/tests/bug72735/bug72682.phpt b/ext/exif/tests/bug72735/bug72682.phpt new file mode 100644 index 0000000000..b3f17791a3 --- /dev/null +++ b/ext/exif/tests/bug72735/bug72682.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72735 MakerNote regression +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +foreach (['nokia.jpg', 'samsung.jpg', 'panasonic.jpg'] as $picture) { + echo $picture . ': '; + + $info = exif_read_data(__DIR__ . DIRECTORY_SEPARATOR . $picture); + var_dump($info['MakerNote']); +} +?> +--EXPECTF-- +nokia.jpg: string(5) "Nikon" +samsung.jpg: NULL +panasonic.jpg: string(9) "Panasonic" diff --git a/ext/exif/tests/bug72735/bug72735.phpt b/ext/exif/tests/bug72735/bug72735.phpt new file mode 100644 index 0000000000..38d9ed2199 --- /dev/null +++ b/ext/exif/tests/bug72735/bug72735.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #72735 (Samsung picture thumb not read (zero size)) +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +foreach (['nokia.jpg', 'samsung.jpg', 'panasonic.jpg'] as $picture) { + echo $picture . ': '; + + $len = strlen(exif_thumbnail(__DIR__ . DIRECTORY_SEPARATOR . $picture)); + + if (!$len) { + echo 'Error, no length returned', PHP_EOL; + + continue; + } + + echo 'int(' . $len . ')', PHP_EOL; +} +?> +--EXPECTF-- +nokia.jpg: int(5899) +samsung.jpg: int(5778) +panasonic.jpg: int(651) diff --git a/ext/exif/tests/bug72735/nokia.jpg b/ext/exif/tests/bug72735/nokia.jpg Binary files differnew file mode 100644 index 0000000000..f402d765a6 --- /dev/null +++ b/ext/exif/tests/bug72735/nokia.jpg diff --git a/ext/exif/tests/bug72735/panasonic.jpg b/ext/exif/tests/bug72735/panasonic.jpg Binary files differnew file mode 100644 index 0000000000..35713e63a1 --- /dev/null +++ b/ext/exif/tests/bug72735/panasonic.jpg diff --git a/ext/exif/tests/bug72735/samsung.jpg b/ext/exif/tests/bug72735/samsung.jpg Binary files differnew file mode 100644 index 0000000000..1ec51eaf0c --- /dev/null +++ b/ext/exif/tests/bug72735/samsung.jpg diff --git a/ext/exif/tests/exif_imagetype_variation1.phpt b/ext/exif/tests/exif_imagetype_variation1.phpt index 767ed5fecb..d33217c5f8 100644 --- a/ext/exif/tests/exif_imagetype_variation1.phpt +++ b/ext/exif/tests/exif_imagetype_variation1.phpt @@ -142,23 +142,23 @@ Warning: exif_imagetype(0.5): failed to open stream: No such file or directory i bool(false) -- Iteration 10 -- -Warning: exif_imagetype() expects parameter 1 to be string, array given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, array given in %s on line %d NULL -- Iteration 11 -- -Warning: exif_imagetype() expects parameter 1 to be string, array given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, array given in %s on line %d NULL -- Iteration 12 -- -Warning: exif_imagetype() expects parameter 1 to be string, array given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, array given in %s on line %d NULL -- Iteration 13 -- -Warning: exif_imagetype() expects parameter 1 to be string, array given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, array given in %s on line %d NULL -- Iteration 14 -- -Warning: exif_imagetype() expects parameter 1 to be string, array given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, array given in %s on line %d NULL -- Iteration 15 -- @@ -198,7 +198,7 @@ Warning: exif_imagetype(obj'ct): failed to open stream: No such file or director bool(false) -- Iteration 24 -- -Warning: exif_imagetype() expects parameter 1 to be string, resource given in %s on line %d +Warning: exif_imagetype() expects parameter 1 to be a valid path, resource given in %s on line %d NULL -- Iteration 25 -- diff --git a/ext/exif/tests/exif_tagname_variation1-64bit.phpt b/ext/exif/tests/exif_tagname_variation1-64bit.phpt new file mode 100644 index 0000000000..22298af2ae --- /dev/null +++ b/ext/exif/tests/exif_tagname_variation1-64bit.phpt @@ -0,0 +1,183 @@ +--TEST-- +Test exif_tagname() function : usage variations - different types for index argument +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available'; +if (PHP_INT_SIZE != 8) die('skip 64-bit only'); +?> +--FILE-- +<?php + +/* Prototype : string exif_tagname ( string $index ) + * Description: Get the header name for an index + * Source code: ext/exif/exif.c +*/ + +echo "*** Testing exif_tagname() : different types for index argument ***\n"; +// initialize all required variables + +// get an unset variable +$unset_var = 'string_val'; +unset($unset_var); + +// declaring a class +class sample { + public function __toString() { + return "obj'ct"; + } +} + +// Defining resource +$file_handle = fopen(__FILE__, 'r'); + +// array with different values +$values = array ( + + // integer values + 0, + 1, + 12345, + -2345, + + // float values + 10.5, + -10.5, + 10.1234567e10, + 10.7654321E-10, + .5, + + // array values + array(), + array(0), + array(1), + array(1, 2), + array('color' => 'red', 'item' => 'pen'), + + // boolean values + true, + false, + TRUE, + FALSE, + + // empty string + "", + '', + + // undefined variable + $undefined_var, + + // unset variable + $unset_var, + + // objects + new sample(), + + // resource + $file_handle, + + NULL, + null +); + + +// loop through each element of the array and check the working of exif_tagname() +// when $index argument is supplied with different values + +echo "\n--- Testing exif_tagname() by supplying different values for 'index' argument ---\n"; +$counter = 1; +foreach($values as $index) { + echo "-- Iteration $counter --\n"; + var_dump( exif_tagname($index) ); + $counter ++; +} + +// closing the file +fclose($file_handle); + +echo "Done\n"; +?> + +?> +===Done=== +--EXPECTF-- +*** Testing exif_tagname() : different types for index argument *** + +Notice: Undefined variable: undefined_var in %s on line %d + +Notice: Undefined variable: unset_var in %s on line %d + +--- Testing exif_tagname() by supplying different values for 'index' argument --- +-- Iteration 1 -- +bool(false) +-- Iteration 2 -- +bool(false) +-- Iteration 3 -- +bool(false) +-- Iteration 4 -- +bool(false) +-- Iteration 5 -- +bool(false) +-- Iteration 6 -- +bool(false) +-- Iteration 7 -- +bool(false) +-- Iteration 8 -- +bool(false) +-- Iteration 9 -- +bool(false) +-- Iteration 10 -- + +Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d +NULL +-- Iteration 11 -- + +Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d +NULL +-- Iteration 12 -- + +Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d +NULL +-- Iteration 13 -- + +Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d +NULL +-- Iteration 14 -- + +Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d +NULL +-- Iteration 15 -- +bool(false) +-- Iteration 16 -- +bool(false) +-- Iteration 17 -- +bool(false) +-- Iteration 18 -- +bool(false) +-- Iteration 19 -- + +Warning: exif_tagname() expects parameter 1 to be integer, string given in %s on line %d +NULL +-- Iteration 20 -- + +Warning: exif_tagname() expects parameter 1 to be integer, string given in %s on line %d +NULL +-- Iteration 21 -- +bool(false) +-- Iteration 22 -- +bool(false) +-- Iteration 23 -- + +Warning: exif_tagname() expects parameter 1 to be integer, object given in %s on line %d +NULL +-- Iteration 24 -- + +Warning: exif_tagname() expects parameter 1 to be integer, resource given in %s on line %d +NULL +-- Iteration 25 -- +bool(false) +-- Iteration 26 -- +bool(false) +Done + +?> +===Done=== + diff --git a/ext/exif/tests/exif_tagname_variation1.phpt b/ext/exif/tests/exif_tagname_variation1.phpt index 22298af2ae..44d2568f49 100644 --- a/ext/exif/tests/exif_tagname_variation1.phpt +++ b/ext/exif/tests/exif_tagname_variation1.phpt @@ -2,7 +2,7 @@ Test exif_tagname() function : usage variations - different types for index argument --SKIPIF-- <?php if (!extension_loaded('exif')) print 'skip exif extension not available'; -if (PHP_INT_SIZE != 8) die('skip 64-bit only'); +if (PHP_INT_SIZE != 4) die('skip 32-bit only'); ?> --FILE-- <?php @@ -41,8 +41,6 @@ $values = array ( // float values 10.5, -10.5, - 10.1234567e10, - 10.7654321E-10, .5, // array values @@ -121,60 +119,56 @@ bool(false) -- Iteration 7 -- bool(false) -- Iteration 8 -- -bool(false) --- Iteration 9 -- -bool(false) --- Iteration 10 -- Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d NULL --- Iteration 11 -- +-- Iteration 9 -- Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d NULL --- Iteration 12 -- +-- Iteration 10 -- Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d NULL --- Iteration 13 -- +-- Iteration 11 -- Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d NULL --- Iteration 14 -- +-- Iteration 12 -- Warning: exif_tagname() expects parameter 1 to be integer, array given in %s on line %d NULL +-- Iteration 13 -- +bool(false) +-- Iteration 14 -- +bool(false) -- Iteration 15 -- bool(false) -- Iteration 16 -- bool(false) -- Iteration 17 -- -bool(false) --- Iteration 18 -- -bool(false) --- Iteration 19 -- Warning: exif_tagname() expects parameter 1 to be integer, string given in %s on line %d NULL --- Iteration 20 -- +-- Iteration 18 -- Warning: exif_tagname() expects parameter 1 to be integer, string given in %s on line %d NULL --- Iteration 21 -- +-- Iteration 19 -- bool(false) --- Iteration 22 -- +-- Iteration 20 -- bool(false) --- Iteration 23 -- +-- Iteration 21 -- Warning: exif_tagname() expects parameter 1 to be integer, object given in %s on line %d NULL --- Iteration 24 -- +-- Iteration 22 -- Warning: exif_tagname() expects parameter 1 to be integer, resource given in %s on line %d NULL --- Iteration 25 -- +-- Iteration 23 -- bool(false) --- Iteration 26 -- +-- Iteration 24 -- bool(false) Done diff --git a/ext/exif/tests/redhat-bug1362571.jpg b/ext/exif/tests/redhat-bug1362571.jpg Binary files differnew file mode 100644 index 0000000000..35713e63a1 --- /dev/null +++ b/ext/exif/tests/redhat-bug1362571.jpg diff --git a/ext/exif/tests/redhat-bug1362571.phpt b/ext/exif/tests/redhat-bug1362571.phpt new file mode 100644 index 0000000000..ec69e38c91 --- /dev/null +++ b/ext/exif/tests/redhat-bug1362571.phpt @@ -0,0 +1,10 @@ +--TEST-- +Redhat bug #1362571 (PHP not returning full results for exif_read_data function) +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +var_dump(strlen(exif_thumbnail(__DIR__ . DIRECTORY_SEPARATOR . 'redhat-bug1362571.jpg')) > 0); +?> +--EXPECT-- +bool(true) diff --git a/ext/exif/tests/sony.jpg b/ext/exif/tests/sony.jpg Binary files differnew file mode 100644 index 0000000000..865157032c --- /dev/null +++ b/ext/exif/tests/sony.jpg diff --git a/ext/exif/tests/sony.phpt b/ext/exif/tests/sony.phpt new file mode 100644 index 0000000000..683d58d4ac --- /dev/null +++ b/ext/exif/tests/sony.phpt @@ -0,0 +1,23 @@ +--TEST-- +Sony test +--SKIPIF-- +<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?> +--FILE-- +<?php +$data = exif_read_data(__DIR__ . DIRECTORY_SEPARATOR . 'sony.jpg'); + +if (!$data) { + exit('Error: Unable to parse EXIF data'); +} + +// Perhaps we should just test for SonyModelID since it seems to be +// the most specific tag name that should be found in any Sony generated +// picture +foreach (['SonyModelID', 'Panorama', 'AntiBlur'] as $sony_tag) { + printf('%s was %sfound' . PHP_EOL, $sony_tag, (!isset($data[$sony_tag]) ? 'NOT ' : '')); +} +?> +--EXPECT-- +SonyModelID was found +Panorama was found +AntiBlur was found diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 1864d258be..449142841b 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -35,9 +35,6 @@ PHP_ARG_WITH(xpm-dir, for the location of libXpm, PHP_ARG_WITH(freetype-dir, for FreeType 2, [ --with-freetype-dir[=DIR] GD: Set the path to FreeType 2 install prefix], no, no) -PHP_ARG_ENABLE(gd-native-ttf, whether to enable truetype string function in GD, -[ --enable-gd-native-ttf GD: Enable TrueType string function], no, no) - PHP_ARG_ENABLE(gd-jis-conv, whether to enable JIS-mapped Japanese font support in GD, [ --enable-gd-jis-conv GD: Enable JIS-mapped Japanese font support], no, no) @@ -206,7 +203,6 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ PHP_EVAL_INCLINE($FREETYPE2_CFLAGS) PHP_EVAL_LIBLINE($FREETYPE2_LIBS, GD_SHARED_LIBADD) - AC_DEFINE(USE_GD_IMGSTRTTF, 1, [ ]) AC_DEFINE(HAVE_LIBFREETYPE,1,[ ]) AC_DEFINE(ENABLE_GD_TTF,1,[ ]) else @@ -214,12 +210,6 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ fi ]) -AC_DEFUN([PHP_GD_TTSTR],[ - if test "$PHP_GD_NATIVE_TTF" = "yes"; then - AC_DEFINE(USE_GD_IMGSTRTTF, 1, [ ]) - fi -]) - AC_DEFUN([PHP_GD_JISX0208],[ if test "$PHP_GD_JIS_CONV" = "yes"; then USE_GD_JIS_CONV=1 @@ -265,8 +255,8 @@ if test "$PHP_GD" = "yes"; then libgd/gd_png.c libgd/gd_jpeg.c libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c \ libgd/gdfontmb.c libgd/gdfontl.c libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c \ libgd/gdcache.c libgd/gdkanji.c libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c \ - libgd/gd_topal.c libgd/gd_gif_in.c libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c \ - libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c \ + libgd/gd_topal.c libgd/gd_gif_in.c libgd/gd_xbm.c libgd/gd_gif_out.c libgd/gd_security.c \ + libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_rotate.c libgd/gd_color_match.c \ libgd/gd_transform.c libgd/gd_crop.c libgd/gd_interpolation.c libgd/gd_matrix.c" dnl check for fabsf and floorf which are available since C99 diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 71cbe9c4ae..0248a035e2 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -35,12 +35,12 @@ if (PHP_GD != "no") { CHECK_LIB("Gdi32.lib", "gd", PHP_GD); EXTENSION("gd", "gd.c", null, "-Iext/gd/libgd", "php_gd2.dll"); - ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd_arc_f_buggy.c gd.c \ + ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd.c \ gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \ gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \ gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \ - gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c gd_transform.c \ - gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c gd_webp.c \ + gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \ + gd_filter.c gd_pixelate.c gd_rotate.c gd_color_match.c gd_webp.c \ gd_crop.c gd_interpolation.c gd_matrix.c", "gd"); AC_DEFINE('HAVE_LIBGD', 1, 'GD support'); ADD_FLAG("CFLAGS_GD", " \ @@ -71,7 +71,6 @@ if (PHP_GD != "no") { /D HAVE_LIBPNG \ /D HAVE_XPM \ /D HAVE_COLORCLOSESTHWB \ -/D USE_GD_IMGSTRTTF \ /D USE_GD_IOCTX \ /D MSWIN32 \ "); diff --git a/ext/gd/gd.c b/ext/gd/gd.c index b0942a4e28..b957d75586 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -63,9 +63,7 @@ static int le_gd, le_gd_font; #include <gd.h> -#ifndef HAVE_GD_BUNDLED -# include <gd_errors.h> -#endif +#include <gd_errors.h> #include <gdfontt.h> /* 1 Tiny font */ #include <gdfonts.h> /* 2 Small font */ #include <gdfontmb.h> /* 3 Medium bold font */ @@ -578,6 +576,13 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagepolygon, 0) ZEND_ARG_INFO(0, col) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_imageopenpolygon, 0) + ZEND_ARG_INFO(0, im) + ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */ + ZEND_ARG_INFO(0, num_pos) + ZEND_ARG_INFO(0, col) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_imagefilledpolygon, 0) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */ @@ -685,6 +690,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagesy, 0) ZEND_ARG_INFO(0, im) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_imagesetclip, 0) + ZEND_ARG_INFO(0, im) + ZEND_ARG_INFO(0, x1) + ZEND_ARG_INFO(0, y1) + ZEND_ARG_INFO(0, x2) + ZEND_ARG_INFO(0, y2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_imagegetclip, 0) + ZEND_ARG_INFO(0, im) +ZEND_END_ARG_INFO() + #ifdef ENABLE_GD_TTF #if HAVE_LIBFREETYPE ZEND_BEGIN_ARG_INFO_EX(arginfo_imageftbbox, 0, 0, 4) @@ -774,12 +791,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_imageflip, 0) ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() -#ifdef HAVE_GD_BUNDLED ZEND_BEGIN_ARG_INFO(arginfo_imageantialias, 0) ZEND_ARG_INFO(0, im) ZEND_ARG_INFO(0, on) ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_INFO(arginfo_imagecrop, 0) ZEND_ARG_INFO(0, im) @@ -821,6 +836,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagesetinterpolation, 0) ZEND_ARG_INFO(0, method) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_imageresolution, 0, 0, 1) + ZEND_ARG_INFO(0, im) + ZEND_ARG_INFO(0, res_x) + ZEND_ARG_INFO(0, res_y) +ZEND_END_ARG_INFO() + /* }}} */ /* {{{ gd_functions[] @@ -872,9 +893,7 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagerotate, arginfo_imagerotate) PHP_FE(imageflip, arginfo_imageflip) -#ifdef HAVE_GD_BUNDLED PHP_FE(imageantialias, arginfo_imageantialias) -#endif PHP_FE(imagecrop, arginfo_imagecrop) PHP_FE(imagecropauto, arginfo_imagecropauto) PHP_FE(imagescale, arginfo_imagescale) @@ -930,12 +949,15 @@ const zend_function_entry gd_functions[] = { PHP_FE(imageline, arginfo_imageline) PHP_FE(imageloadfont, arginfo_imageloadfont) PHP_FE(imagepolygon, arginfo_imagepolygon) + PHP_FE(imageopenpolygon, arginfo_imageopenpolygon) PHP_FE(imagerectangle, arginfo_imagerectangle) PHP_FE(imagesetpixel, arginfo_imagesetpixel) PHP_FE(imagestring, arginfo_imagestring) PHP_FE(imagestringup, arginfo_imagestringup) PHP_FE(imagesx, arginfo_imagesx) PHP_FE(imagesy, arginfo_imagesy) + PHP_FE(imagesetclip, arginfo_imagesetclip) + PHP_FE(imagegetclip, arginfo_imagegetclip) PHP_FE(imagedashedline, arginfo_imagedashedline) #ifdef ENABLE_GD_TTF @@ -965,6 +987,8 @@ const zend_function_entry gd_functions[] = { PHP_FE(imagefilter, arginfo_imagefilter) PHP_FE(imageconvolution, arginfo_imageconvolution) + PHP_FE(imageresolution, arginfo_imageresolution) + PHP_FE_END }; /* }}} */ @@ -1018,15 +1042,16 @@ static void php_free_gd_font(zend_resource *rsrc) } /* }}} */ -#ifndef HAVE_GD_BUNDLED /* {{{ php_gd_error_method */ void php_gd_error_method(int type, const char *format, va_list args) { switch (type) { +#ifndef PHP_WIN32 case GD_DEBUG: case GD_INFO: +#endif case GD_NOTICE: type = E_NOTICE; break; @@ -1039,7 +1064,6 @@ void php_gd_error_method(int type, const char *format, va_list args) php_verror(NULL, "", type, format, args TSRMLS_CC); } /* }}} */ -#endif /* {{{ PHP_MINIT_FUNCTION */ @@ -1051,9 +1075,8 @@ PHP_MINIT_FUNCTION(gd) #if HAVE_GD_BUNDLED && HAVE_LIBFREETYPE gdFontCacheMutexSetup(); #endif -#ifndef HAVE_GD_BUNDLED gdSetErrorMethod(php_gd_error_method); -#endif + REGISTER_INI_ENTRIES(); REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT); @@ -1088,6 +1111,9 @@ PHP_MINIT_FUNCTION(gd) REGISTER_LONG_CONSTANT("IMG_EFFECT_ALPHABLEND", gdEffectAlphaBlend, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT); +#ifdef gdEffectMultiply + REGISTER_LONG_CONSTANT("IMG_EFFECT_MULTIPLY", gdEffectMultiply, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("IMG_CROP_DEFAULT", GD_CROP_DEFAULT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_CROP_TRANSPARENT", GD_CROP_TRANSPARENT, CONST_CS | CONST_PERSISTENT); @@ -1541,9 +1567,12 @@ PHP_FUNCTION(imagetruecolortopalette) php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX); RETURN_FALSE; } - gdImageTrueColorToPalette(im, dither, (int)ncolors); - - RETURN_TRUE; + if (gdImageTrueColorToPalette(im, dither, (int)ncolors)) { + RETURN_TRUE; + } else { + php_error_docref(NULL, E_WARNING, "Couldn't convert to palette"); + RETURN_FALSE; + } } /* }}} */ @@ -1891,10 +1920,7 @@ PHP_FUNCTION(imagegrabwindow) HDC memDC; HBITMAP memBM; HBITMAP hOld; - HINSTANCE handle; zend_long lwindow_handle; - typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT); - tPrintWindow pPrintWindow = 0; gdImagePtr im = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &lwindow_handle, &client_area) == FAILURE) { @@ -1926,21 +1952,7 @@ PHP_FUNCTION(imagegrabwindow) memBM = CreateCompatibleBitmap(hdc, Width, Height); hOld = (HBITMAP) SelectObject (memDC, memBM); - - handle = LoadLibrary("User32.dll"); - if ( handle == 0 ) { - goto clean; - } - pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow"); - - if ( pPrintWindow ) { - pPrintWindow(window, memDC, (UINT) client_area); - } else { - php_error_docref(NULL, E_WARNING, "Windows API too old"); - goto clean; - } - - FreeLibrary(handle); + PrintWindow(window, memDC, (UINT) client_area); im = gdImageCreateTrueColor(Width, Height); if (im) { @@ -1953,7 +1965,6 @@ PHP_FUNCTION(imagegrabwindow) } } -clean: SelectObject(memDC,hOld); DeleteObject(memBM); DeleteDC(memDC); @@ -2583,9 +2594,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char (*func_p)(im, i, fp); break; case PHP_GDIMG_TYPE_GD: - if (im->trueColor){ - gdImageTrueColorToPalette(im,1,256); - } (*func_p)(im, fp); break; case PHP_GDIMG_TYPE_GD2: @@ -2637,9 +2645,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char (*func_p)(im, q, tmp); break; case PHP_GDIMG_TYPE_GD: - if (im->trueColor) { - gdImageTrueColorToPalette(im,1,256); - } (*func_p)(im, tmp); break; case PHP_GDIMG_TYPE_GD2: @@ -2823,9 +2828,11 @@ PHP_FUNCTION(imagecolorat) zend_long x, y; gdImagePtr im; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rll", &IM, &x, &y) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_RESOURCE(IM) + Z_PARAM_LONG(x) + Z_PARAM_LONG(y) + ZEND_PARSE_PARAMETERS_END(); if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) { RETURN_FALSE; @@ -3033,7 +3040,7 @@ PHP_FUNCTION(imagegammacorrect) zval *IM; gdImagePtr im; int i; - double input, output; + double input, output, gamma; if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) { return; @@ -3044,6 +3051,8 @@ PHP_FUNCTION(imagegammacorrect) RETURN_FALSE; } + gamma = input / output; + if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) { RETURN_FALSE; } @@ -3056,9 +3065,9 @@ PHP_FUNCTION(imagegammacorrect) c = gdImageGetPixel(im, x, y); gdImageSetPixel(im, x, y, gdTrueColorAlpha( - (int) ((pow((pow((gdTrueColorGetRed(c) / 255.0), input)), 1.0 / output) * 255) + .5), - (int) ((pow((pow((gdTrueColorGetGreen(c) / 255.0), input)), 1.0 / output) * 255) + .5), - (int) ((pow((pow((gdTrueColorGetBlue(c) / 255.0), input)), 1.0 / output) * 255) + .5), + (int) ((pow((gdTrueColorGetRed(c) / 255.0), gamma) * 255) + .5), + (int) ((pow((gdTrueColorGetGreen(c) / 255.0), gamma) * 255) + .5), + (int) ((pow((gdTrueColorGetBlue(c) / 255.0), gamma) * 255) + .5), gdTrueColorGetAlpha(c) ) ); @@ -3068,9 +3077,9 @@ PHP_FUNCTION(imagegammacorrect) } for (i = 0; i < gdImageColorsTotal(im); i++) { - im->red[i] = (int)((pow((pow((im->red[i] / 255.0), input)), 1.0 / output) * 255) + .5); - im->green[i] = (int)((pow((pow((im->green[i] / 255.0), input)), 1.0 / output) * 255) + .5); - im->blue[i] = (int)((pow((pow((im->blue[i] / 255.0), input)), 1.0 / output) * 255) + .5); + im->red[i] = (int)((pow((im->red[i] / 255.0), gamma) * 255) + .5); + im->green[i] = (int)((pow((im->green[i] / 255.0), gamma) * 255) + .5); + im->blue[i] = (int)((pow((im->blue[i] / 255.0), gamma) * 255) + .5); } RETURN_TRUE; @@ -3085,9 +3094,12 @@ PHP_FUNCTION(imagesetpixel) zend_long x, y, col; gdImagePtr im; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &x, &y, &col) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_RESOURCE(IM) + Z_PARAM_LONG(x) + Z_PARAM_LONG(y) + Z_PARAM_LONG(col) + ZEND_PARSE_PARAMETERS_END(); if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) { RETURN_FALSE; @@ -3114,14 +3126,11 @@ PHP_FUNCTION(imageline) RETURN_FALSE; } -#ifdef HAVE_GD_BUNDLED - if (im->antialias) { - gdImageAALine(im, x1, y1, x2, y2, col); - } else -#endif - { - gdImageLine(im, x1, y1, x2, y2, col); + if (im->AA) { + gdImageSetAntiAliased(im, col); + col = gdAntiAliased; } + gdImageLine(im, x1, y1, x2, y2, col); RETURN_TRUE; } /* }}} */ @@ -3353,6 +3362,7 @@ PHP_FUNCTION(imageinterlace) /* }}} */ /* {{{ php_imagepolygon + arg = -1 open polygon arg = 0 normal polygon arg = 1 filled polygon */ /* im, points, num_points, col */ @@ -3401,10 +3411,20 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled) } } - if (filled) { - gdImageFilledPolygon(im, points, npoints, col); - } else { - gdImagePolygon(im, points, npoints, col); + if (im->AA) { + gdImageSetAntiAliased(im, col); + col = gdAntiAliased; + } + switch (filled) { + case -1: + gdImageOpenPolygon(im, points, npoints, col); + break; + case 0: + gdImagePolygon(im, points, npoints, col); + break; + case 1: + gdImageFilledPolygon(im, points, npoints, col); + break; } efree(points); @@ -3420,6 +3440,14 @@ PHP_FUNCTION(imagepolygon) } /* }}} */ +/* {{{ proto bool imageopenpolygon(resource im, array point, int num_points, int col) + Draw a polygon */ +PHP_FUNCTION(imageopenpolygon) +{ + php_imagepolygon(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1); +} +/* }}} */ + /* {{{ proto bool imagefilledpolygon(resource im, array point, int num_points, int col) Draw a filled polygon */ PHP_FUNCTION(imagefilledpolygon) @@ -3809,6 +3837,53 @@ PHP_FUNCTION(imagesy) } /* }}} */ +/* {{{ proto bool imagesetclip(resource im, int x1, int y1, int x2, int y2) + Set the clipping rectangle. */ +PHP_FUNCTION(imagesetclip) +{ + zval *im_zval; + gdImagePtr im; + zend_long x1, y1, x2, y2; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &im_zval, &x1, &y1, &x2, &y2) == FAILURE) { + return; + } + + if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(im_zval), "Image", le_gd)) == NULL) { + RETURN_FALSE; + } + + gdImageSetClip(im, x1, y1, x2, y2); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto array imagegetclip(resource im) + Get the clipping rectangle. */ +PHP_FUNCTION(imagegetclip) +{ + zval *im_zval; + gdImagePtr im; + int x1, y1, x2, y2; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &im_zval) == FAILURE) { + return; + } + + if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(im_zval), "Image", le_gd)) == NULL) { + RETURN_FALSE; + } + + gdImageGetClip(im, &x1, &y1, &x2, &y2); + + array_init(return_value); + add_next_index_long(return_value, x1); + add_next_index_long(return_value, y1); + add_next_index_long(return_value, x2); + add_next_index_long(return_value, y2); +} +/* }}} */ + #ifdef ENABLE_GD_TTF #define TTFTEXT_DRAW 0 #define TTFTEXT_BBOX 1 @@ -3995,7 +4070,10 @@ static void _php_image_bw_convert(gdImagePtr im_org, gdIOCtx *out, int threshold } if (im_org->trueColor) { - gdImageTrueColorToPalette(im_org, 1, 256); + if (!gdImageTrueColorToPalette(im_org, 1, 256)) { + php_error_docref(NULL, E_WARNING, "Unable to convert to palette"); + return; + } } for (y = 0; y < dest_height; y++) { @@ -4076,15 +4154,6 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type ) } switch (image_type) { - case PHP_GDIMG_TYPE_GIF: - im_org = gdImageCreateFromGif(org); - if (im_org == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid GIF file", fn_dest); - fclose(org); - fclose(dest); - RETURN_FALSE; - } - break; #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: @@ -4557,7 +4626,6 @@ PHP_FUNCTION(imageflip) } /* }}} */ -#ifdef HAVE_GD_BUNDLED /* {{{ proto bool imageantialias(resource im, bool on) Should antialiased functions used or not*/ PHP_FUNCTION(imageantialias) @@ -4573,11 +4641,10 @@ PHP_FUNCTION(imageantialias) if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) { RETURN_FALSE; } - gdImageAntialias(im, alias); + gdImageSetAntiAliased(im, 0); RETURN_TRUE; } /* }}} */ -#endif /* {{{ proto void imagecrop(resource im, array rect) Crop an image using the given coordinates and size, x, y, width and height. */ @@ -5007,6 +5074,37 @@ PHP_FUNCTION(imagesetinterpolation) } /* }}} */ +/* {{{ proto array imageresolution(resource im [, res_x, [res_y]]) + Get or set the resolution of the image in DPI. */ +PHP_FUNCTION(imageresolution) +{ + zval *IM; + gdImagePtr im; + zend_long res_x = GD_RESOLUTION, res_y = GD_RESOLUTION; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ll", &IM, &res_x, &res_y) == FAILURE) { + return; + } + + if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) { + RETURN_FALSE; + } + + switch (ZEND_NUM_ARGS()) { + case 3: + gdImageSetResolution(im, res_x, res_y); + RETURN_TRUE; + case 2: + gdImageSetResolution(im, res_x, res_x); + RETURN_TRUE; + default: + array_init(return_value); + add_next_index_long(return_value, gdImageResolutionX(im)); + add_next_index_long(return_value, gdImageResolutionY(im)); + } +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 99cbdde776..7f0a112b50 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -4,6 +4,7 @@ #include <stdlib.h> #include "gd.h" #include "gdhelpers.h" +#include "gd_errors.h" #include "php.h" @@ -91,33 +92,82 @@ static const unsigned char gd_toascii[256] = extern int gdCosT[]; extern int gdSinT[]; -static void gdImageBrushApply(gdImagePtr im, int x, int y); -static void gdImageTileApply(gdImagePtr im, int x, int y); -static void gdImageAntiAliasedApply(gdImagePtr im, int x, int y); -static int gdLayerOverlay(int dst, int src); -static int gdAlphaOverlayColor(int src, int dst, int max); -int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); +/** + * Group: Error Handling + */ + +void gd_stderr_error(int priority, const char *format, va_list args) +{ + switch (priority) { + case GD_ERROR: + fputs("GD Error: ", stderr); + break; + case GD_WARNING: + fputs("GD Warning: ", stderr); + break; + case GD_NOTICE: + fputs("GD Notice: ", stderr); + break; +#ifndef PHP_WIN32 + case GD_INFO: + fputs("GD Info: ", stderr); + break; + case GD_DEBUG: + fputs("GD Debug: ", stderr); + break; +#endif + } + vfprintf(stderr, format, args); + fflush(stderr); +} -void php_gd_error_ex(int type, const char *format, ...) +static gdErrorMethod gd_error_method = gd_stderr_error; + +static void _gd_error_ex(int priority, const char *format, va_list args) { - va_list args; + if (gd_error_method) { + gd_error_method(priority, format, args); + } +} +void gd_error(const char *format, ...) +{ + va_list args; va_start(args, format); - php_verror(NULL, "", type, format, args); + _gd_error_ex(GD_WARNING, format, args); va_end(args); } - -void php_gd_error(const char *format, ...) +void gd_error_ex(int priority, const char *format, ...) { va_list args; - va_start(args, format); - php_verror(NULL, "", E_WARNING, format, args); + _gd_error_ex(priority, format, args); va_end(args); } +/* + Function: gdSetErrorMethod +*/ +void gdSetErrorMethod(gdErrorMethod error_method) +{ + gd_error_method = error_method; +} + +/* + Function: gdClearErrorMethod +*/ +void gdClearErrorMethod(void) +{ + gd_error_method = gd_stderr_error; +} + +static void gdImageBrushApply(gdImagePtr im, int x, int y); +static void gdImageTileApply(gdImagePtr im, int x, int y); +static int gdAlphaOverlayColor(int src, int dst, int max); +int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); + gdImagePtr gdImageCreate (int sx, int sy) { int i; @@ -126,12 +176,10 @@ gdImagePtr gdImageCreate (int sx, int sy) if (overflow2(sx, sy)) { return NULL; } - if (overflow2(sizeof(unsigned char *), sy)) { return NULL; } - - if (overflow2(sizeof(unsigned char *), sx)) { + if (overflow2(sizeof(unsigned char), sx)) { return NULL; } @@ -139,7 +187,6 @@ gdImagePtr gdImageCreate (int sx, int sy) /* Row-major ever since gd 1.3 */ im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); - im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0; @@ -148,7 +195,6 @@ gdImagePtr gdImageCreate (int sx, int sy) for (i = 0; i < sy; i++) { /* Row-major ever since gd 1.3 */ im->pixels[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); - im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); } im->sx = sx; im->sy = sy; @@ -157,7 +203,6 @@ gdImagePtr gdImageCreate (int sx, int sy) im->interlace = 0; im->thick = 1; im->AA = 0; - im->AA_polygon = 0; for (i = 0; i < gdMaxColors; i++) { im->open[i] = 1; im->red[i] = 0; @@ -170,6 +215,8 @@ gdImagePtr gdImageCreate (int sx, int sy) im->cy1 = 0; im->cx2 = im->sx - 1; im->cy2 = im->sy - 1; + im->res_x = GD_RESOLUTION; + im->res_y = GD_RESOLUTION; im->interpolation = NULL; im->interpolation_id = GD_BILINEAR_FIXED; return im; @@ -183,19 +230,16 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy) if (overflow2(sx, sy)) { return NULL; } - - if (overflow2(sizeof(unsigned char *), sy)) { + if (overflow2(sizeof(int *), sy)) { return NULL; } - - if (overflow2(sizeof(int *), sx)) { + if (overflow2(sizeof(int), sx)) { return NULL; } im = (gdImage *) gdMalloc(sizeof(gdImage)); memset(im, 0, sizeof(gdImage)); im->tpixels = (int **) gdMalloc(sizeof(int *) * sy); - im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0; @@ -203,7 +247,6 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy) im->style = 0; for (i = 0; i < sy; i++) { im->tpixels[i] = (int *) gdCalloc(sx, sizeof(int)); - im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char)); } im->sx = sx; im->sy = sy; @@ -220,11 +263,12 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy) im->alphaBlendingFlag = 1; im->thick = 1; im->AA = 0; - im->AA_polygon = 0; im->cx1 = 0; im->cy1 = 0; im->cx2 = im->sx - 1; im->cy2 = im->sy - 1; + im->res_x = GD_RESOLUTION; + im->res_y = GD_RESOLUTION; im->interpolation = NULL; im->interpolation_id = GD_BILINEAR_FIXED; return im; @@ -245,12 +289,6 @@ void gdImageDestroy (gdImagePtr im) } gdFree(im->tpixels); } - if (im->AA_opacity) { - for (i = 0; i < im->sy; i++) { - gdFree(im->AA_opacity[i]); - } - gdFree(im->AA_opacity); - } if (im->polyInts) { gdFree(im->polyInts); } @@ -756,7 +794,9 @@ void gdImageSetPixel (gdImagePtr im, int x, int y, int color) gdImageTileApply(im, x, y); break; case gdAntiAliased: - gdImageAntiAliasedApply(im, x, y); + /* This shouldn't happen (2.0.26) because we just call + gdImageAALine now, but do something sane. */ + gdImageSetPixel(im, x, y, im->AA_color); break; default: if (gdImageBoundsSafe(im, x, y)) { @@ -767,14 +807,15 @@ void gdImageSetPixel (gdImagePtr im, int x, int y, int color) im->tpixels[y][x] = color; break; case gdEffectAlphaBlend: - im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); - break; case gdEffectNormal: im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color); break; case gdEffectOverlay : im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color); break; + case gdEffectMultiply : + im->tpixels[y][x] = gdLayerMultiply(im->tpixels[y][x], color); + break; } } else { im->pixels[y][x] = color; @@ -937,68 +978,6 @@ static int gdImageTileGet (gdImagePtr im, int x, int y) } -static void gdImageAntiAliasedApply (gdImagePtr im, int px, int py) -{ - float p_dist, p_alpha; - unsigned char opacity; - - /* - * Find the perpendicular distance from point C (px, py) to the line - * segment AB that is being drawn. (Adapted from an algorithm from the - * comp.graphics.algorithms FAQ.) - */ - - int LAC_2, LBC_2; - - int Ax_Cx = im->AAL_x1 - px; - int Ay_Cy = im->AAL_y1 - py; - - int Bx_Cx = im->AAL_x2 - px; - int By_Cy = im->AAL_y2 - py; - - /* 2.0.13: bounds check! AA_opacity is just as capable of - * overflowing as the main pixel array. Arne Jorgensen. - * 2.0.14: typo fixed. 2.0.15: moved down below declarations - * to satisfy non-C++ compilers. - */ - if (!gdImageBoundsSafe(im, px, py)) { - return; - } - - /* Get the squares of the lengths of the segemnts AC and BC. */ - LAC_2 = (Ax_Cx * Ax_Cx) + (Ay_Cy * Ay_Cy); - LBC_2 = (Bx_Cx * Bx_Cx) + (By_Cy * By_Cy); - - if (((im->AAL_LAB_2 + LAC_2) >= LBC_2) && ((im->AAL_LAB_2 + LBC_2) >= LAC_2)) { - /* The two angles are acute. The point lies inside the portion of the - * plane spanned by the line segment. - */ - p_dist = fabs ((float) ((Ay_Cy * im->AAL_Bx_Ax) - (Ax_Cx * im->AAL_By_Ay)) / im->AAL_LAB); - } else { - /* The point is past an end of the line segment. It's length from the - * segment is the shorter of the lengths from the endpoints, but call - * the distance -1, so as not to compute the alpha nor draw the pixel. - */ - p_dist = -1; - } - - if ((p_dist >= 0) && (p_dist <= (float) (im->thick))) { - p_alpha = pow (1.0 - (p_dist / 1.5), 2); - - if (p_alpha > 0) { - if (p_alpha >= 1) { - opacity = 255; - } else { - opacity = (unsigned char) (p_alpha * 255.0); - } - if (!im->AA_polygon || (im->AA_opacity[py][px] < opacity)) { - im->AA_opacity[py][px] = opacity; - } - } - } -} - - int gdImageGetPixel (gdImagePtr im, int x, int y) { if (gdImageBoundsSafe(im, x, y)) { @@ -1014,46 +993,7 @@ int gdImageGetPixel (gdImagePtr im, int x, int y) void gdImageAABlend (gdImagePtr im) { - float p_alpha, old_alpha; - int color = im->AA_color, color_red, color_green, color_blue; - int old_color, old_red, old_green, old_blue; - int p_color, p_red, p_green, p_blue; - int px, py; - - color_red = gdImageRed(im, color); - color_green = gdImageGreen(im, color); - color_blue = gdImageBlue(im, color); - - /* Impose the anti-aliased drawing on the image. */ - for (py = 0; py < im->sy; py++) { - for (px = 0; px < im->sx; px++) { - if (im->AA_opacity[py][px] != 0) { - old_color = gdImageGetPixel(im, px, py); - - if ((old_color != color) && ((old_color != im->AA_dont_blend) || (im->AA_opacity[py][px] == 255))) { - /* Only blend with different colors that aren't the dont_blend color. */ - p_alpha = (float) (im->AA_opacity[py][px]) / 255.0; - old_alpha = 1.0 - p_alpha; - - if (p_alpha >= 1.0) { - p_color = color; - } else { - old_red = gdImageRed(im, old_color); - old_green = gdImageGreen(im, old_color); - old_blue = gdImageBlue(im, old_color); - - p_red = (int) (((float) color_red * p_alpha) + ((float) old_red * old_alpha)); - p_green = (int) (((float) color_green * p_alpha) + ((float) old_green * old_alpha)); - p_blue = (int) (((float) color_blue * p_alpha) + ((float) old_blue * old_alpha)); - p_color = gdImageColorResolve(im, p_red, p_green, p_blue); - } - gdImageSetPixel(im, px, py, p_color); - } - } - } - /* Clear the AA_opacity array behind us. */ - memset(im->AA_opacity[py], 0, im->sx); - } + (void)im; } static void _gdImageFilledHRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color); @@ -1783,6 +1723,100 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e } } +/** + * Integer Ellipse functions (gdImageEllipse and gdImageFilledEllipse) + * Function added by Pierre-Alain Joye 02/08/2003 (paj@pearfr.org) + * See the ellipse function simplification for the equation + * as well as the midpoint algorithm. + */ + +void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) +{ + int x=0,mx1=0,mx2=0,my1=0,my2=0; + long aq,bq,dx,dy,r,rx,ry,a,b; + + a=w>>1; + b=h>>1; + gdImageSetPixel(im,mx+a, my, c); + gdImageSetPixel(im,mx-a, my, c); + mx1 = mx-a;my1 = my; + mx2 = mx+a;my2 = my; + + aq = a * a; + bq = b * b; + dx = aq << 1; + dy = bq << 1; + r = a * bq; + rx = r << 1; + ry = 0; + x = a; + while (x > 0){ + if (r > 0) { + my1++;my2--; + ry +=dx; + r -=ry; + } + if (r <= 0){ + x--; + mx1++;mx2--; + rx -=dy; + r +=rx; + } + gdImageSetPixel(im,mx1, my1, c); + gdImageSetPixel(im,mx1, my2, c); + gdImageSetPixel(im,mx2, my1, c); + gdImageSetPixel(im,mx2, my2, c); + } +} + +void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) +{ + int x=0,mx1=0,mx2=0,my1=0,my2=0; + long aq,bq,dx,dy,r,rx,ry,a,b; + int i; + int old_y2; + + a=w>>1; + b=h>>1; + + for (x = mx-a; x <= mx+a; x++) { + gdImageSetPixel(im, x, my, c); + } + + mx1 = mx-a;my1 = my; + mx2 = mx+a;my2 = my; + + aq = a * a; + bq = b * b; + dx = aq << 1; + dy = bq << 1; + r = a * bq; + rx = r << 1; + ry = 0; + x = a; + old_y2=-2; + while (x > 0){ + if (r > 0) { + my1++;my2--; + ry +=dx; + r -=ry; + } + if (r <= 0){ + x--; + mx1++;mx2--; + rx -=dy; + r +=rx; + } + if(old_y2!=my2){ + for(i=mx1;i<=mx2;i++){ + gdImageSetPixel(im,i,my1,c); + gdImageSetPixel(im,i,my2,c); + } + } + old_y2 = my2; + } +} + void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color) { int lastBorder; @@ -2067,7 +2101,6 @@ skip: for(x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++); void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) { - int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2, y2v = y2; int thick = im->thick; int t; @@ -2088,7 +2121,6 @@ void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) x2 = t; } - x1h = x1; x1v = x1; y1h = y1; y1v = y1; x2h = x2; x2v = x2; y2h = y2; y2v = y2; if (thick > 1) { int cx, cy, x1ul, y1ul, x2lr, y2lr; int half = thick >> 1; @@ -2136,12 +2168,10 @@ void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color) if (x1 == x2 || y1 == y2) { gdImageLine(im, x1, y1, x2, y2, color); } else { - y1v = y1h + 1; - y2v = y2h - 1; - gdImageLine(im, x1h, y1h, x2h, y1h, color); - gdImageLine(im, x1h, y2h, x2h, y2h, color); - gdImageLine(im, x1v, y1v, x1v, y2v, color); - gdImageLine(im, x2v, y1v, x2v, y2v, color); + gdImageLine(im, x1, y1, x2, y1, color); + gdImageLine(im, x1, y2, x2, y2, color); + gdImageLine(im, x1, y1 + 1, x1, y2 - 1, color); + gdImageLine(im, x2, y1 + 1, x2, y2 - 1, color); } } } @@ -2628,41 +2658,32 @@ void gdImageCopyResampled (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c) { + if (n <= 0) { + return; + } + + + gdImageLine (im, p->x, p->y, p[n - 1].x, p[n - 1].y, c); + gdImageOpenPolygon (im, p, n, c); +} + +void gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c) +{ int i; int lx, ly; - typedef void (*image_line)(gdImagePtr im, int x1, int y1, int x2, int y2, int color); - image_line draw_line; if (n <= 0) { return; } - /* Let it be known that we are drawing a polygon so that the opacity - * mask doesn't get cleared after each line. - */ - if (c == gdAntiAliased) { - im->AA_polygon = 1; - } - - if ( im->antialias) { - draw_line = gdImageAALine; - } else { - draw_line = gdImageLine; - } lx = p->x; ly = p->y; - draw_line(im, lx, ly, p[n - 1].x, p[n - 1].y, c); for (i = 1; i < n; i++) { p++; - draw_line(im, lx, ly, p->x, p->y, c); + gdImageLine(im, lx, ly, p->x, p->y, c); lx = p->x; ly = p->y; } - - if (c == gdAntiAliased) { - im->AA_polygon = 0; - gdImageAABlend(im); - } } int gdCompareInt (const void *a, const void *b); @@ -2805,6 +2826,9 @@ void gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels) if (im->style) { gdFree(im->style); } + if (overflow2(sizeof (int), noOfPixels)) { + return; + } im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(int) * noOfPixels); im->styleLength = noOfPixels; @@ -2934,29 +2958,6 @@ int gdImageCompare (gdImagePtr im1, gdImagePtr im2) return cmpStatus; } -int -gdAlphaBlendOld (int dst, int src) -{ - /* 2.0.12: TBB: alpha in the destination should be a - * component of the result. Thanks to Frank Warmerdam for - * pointing out the issue. - */ - return ((((gdTrueColorGetAlpha (src) * - gdTrueColorGetAlpha (dst)) / gdAlphaMax) << 24) + - ((((gdAlphaTransparent - gdTrueColorGetAlpha (src)) * - gdTrueColorGetRed (src) / gdAlphaMax) + - (gdTrueColorGetAlpha (src) * - gdTrueColorGetRed (dst)) / gdAlphaMax) << 16) + - ((((gdAlphaTransparent - gdTrueColorGetAlpha (src)) * - gdTrueColorGetGreen (src) / gdAlphaMax) + - (gdTrueColorGetAlpha (src) * - gdTrueColorGetGreen (dst)) / gdAlphaMax) << 8) + - (((gdAlphaTransparent - gdTrueColorGetAlpha (src)) * - gdTrueColorGetBlue (src) / gdAlphaMax) + - (gdTrueColorGetAlpha (src) * - gdTrueColorGetBlue (dst)) / gdAlphaMax)); -} - int gdAlphaBlend (int dst, int src) { int src_alpha = gdTrueColorGetAlpha(src); int dst_alpha, alpha, red, green, blue; @@ -3007,19 +3008,12 @@ void gdImageAlphaBlending (gdImagePtr im, int alphaBlendingArg) im->alphaBlendingFlag = alphaBlendingArg; } -void gdImageAntialias (gdImagePtr im, int antialias) -{ - if (im->trueColor){ - im->antialias = antialias; - } -} - void gdImageSaveAlpha (gdImagePtr im, int saveAlphaArg) { im->saveAlphaFlag = saveAlphaArg; } -static int gdLayerOverlay (int dst, int src) +int gdLayerOverlay (int dst, int src) { int a1, a2; a1 = gdAlphaMax - gdTrueColorGetAlpha(dst); @@ -3052,6 +3046,28 @@ static int gdAlphaOverlayColor (int src, int dst, int max ) } } +int gdLayerMultiply (int dst, int src) +{ + int a1, a2, r1, r2, g1, g2, b1, b2; + a1 = gdAlphaMax - gdTrueColorGetAlpha(src); + a2 = gdAlphaMax - gdTrueColorGetAlpha(dst); + + r1 = gdRedMax - (a1 * (gdRedMax - gdTrueColorGetRed(src))) / gdAlphaMax; + r2 = gdRedMax - (a2 * (gdRedMax - gdTrueColorGetRed(dst))) / gdAlphaMax; + g1 = gdGreenMax - (a1 * (gdGreenMax - gdTrueColorGetGreen(src))) / gdAlphaMax; + g2 = gdGreenMax - (a2 * (gdGreenMax - gdTrueColorGetGreen(dst))) / gdAlphaMax; + b1 = gdBlueMax - (a1 * (gdBlueMax - gdTrueColorGetBlue(src))) / gdAlphaMax; + b2 = gdBlueMax - (a2 * (gdBlueMax - gdTrueColorGetBlue(dst))) / gdAlphaMax ; + + a1 = gdAlphaMax - a1; + a2 = gdAlphaMax - a2; + return ( ((a1*a2/gdAlphaMax) << 24) + + ((r1*r2/gdRedMax) << 16) + + ((g1*g2/gdGreenMax) << 8) + + ((b1*b2/gdBlueMax)) + ); +} + void gdImageSetClip (gdImagePtr im, int x1, int y1, int x2, int y2) { if (x1 < 0) { @@ -3092,6 +3108,12 @@ void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P) *y2P = im->cy2; } +void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y) +{ + if (res_x > 0) im->res_x = res_x; + if (res_y > 0) im->res_y = res_y; +} + /* convert a palette image to true color */ int gdImagePaletteToTrueColor(gdImagePtr src) { diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 2eb4fd8e1c..613a7016b9 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -46,10 +46,6 @@ extern "C" { #include <stdio.h> #include "gd_io.h" -void php_gd_error_ex(int type, const char *format, ...); - -void php_gd_error(const char *format, ...); - /* The maximum number of palette entries in palette-based images. In the wonderful new world of gd 2.0, you can of course have @@ -92,6 +88,7 @@ void php_gd_error(const char *format, ...); #define gdEffectAlphaBlend 1 #define gdEffectNormal 2 #define gdEffectOverlay 3 +#define gdEffectMultiply 4 #define GD_TRUE 1 #define GD_FALSE 0 @@ -104,6 +101,8 @@ void php_gd_error(const char *format, ...); The resulting color is opaque. */ int gdAlphaBlend(int dest, int src); +int gdLayerOverlay(int dst, int src); +int gdLayerMultiply(int dest, int src); /** * Group: Transform @@ -222,37 +221,24 @@ typedef struct gdImageStruct { To do that, build your image as a truecolor image, then quantize down to 8 bits. */ int alphaBlendingFlag; - /* Should antialias functions be used */ - int antialias; /* Should the alpha channel of the image be saved? This affects PNG at the moment; other future formats may also have that capability. JPEG doesn't. */ int saveAlphaFlag; - - /* 2.0.12: anti-aliased globals */ + /* 2.0.12: anti-aliased globals. 2.0.26: just a few vestiges after + switching to the fast, memory-cheap implementation from PHP-gd. */ int AA; int AA_color; int AA_dont_blend; - unsigned char **AA_opacity; - int AA_polygon; - /* Stored and pre-computed variables for determining the perpendicular - * distance from a point to the anti-aliased line being drawn: - */ - int AAL_x1; - int AAL_y1; - int AAL_x2; - int AAL_y2; - int AAL_Bx_Ax; - int AAL_By_Ay; - int AAL_LAB_2; - float AAL_LAB; /* 2.0.12: simple clipping rectangle. These values must be checked for safety when set; please use gdImageSetClip */ int cx1; int cy1; int cx2; int cy2; + unsigned int res_x; + unsigned int res_y; gdInterpolationMethod interpolation_id; interpolation_method interpolation; } gdImage; @@ -299,6 +285,10 @@ typedef struct { /* Text functions take these. */ typedef gdFont *gdFontPtr; +typedef void(*gdErrorMethod)(int, const char *, va_list); + +void gdSetErrorMethod(gdErrorMethod); +void gdClearErrorMethod(void); /** * Group: Types @@ -433,6 +423,7 @@ void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color); void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2); void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P); +void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y); void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color); void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color); @@ -502,6 +493,7 @@ typedef struct { } gdPoint, *gdPointPtr; void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c); +void gdImageOpenPolygon(gdImagePtr im, gdPointPtr p, int n, int c); void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c); /* These functions still work with truecolor images, @@ -563,7 +555,7 @@ void gdImageColorDeallocate(gdImagePtr im, int color); gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted); -void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted); +int gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted); int gdImagePaletteToTrueColor(gdImagePtr src); /* An attempt at getting the results of gdImageTrueColorToPalette @@ -746,6 +738,8 @@ int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode); of image is also your responsibility. */ #define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)] #define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)] +#define gdImageResolutionX(im) (im)->res_x +#define gdImageResolutionY(im) (im)->res_y /* I/O Support routines. */ diff --git a/ext/gd/libgd/gd_arc.c b/ext/gd/libgd/gd_arc.c deleted file mode 100644 index 1c74871388..0000000000 --- a/ext/gd/libgd/gd_arc.c +++ /dev/null @@ -1,104 +0,0 @@ -#if HAVE_GD_BUNDLED -# include "gd.h" -#else -# include <gd.h> -#endif - -#include "gd_intern.h" - - -/** - * Integer Ellipse functions (gdImageEllipse and gdImageFilledEllipse) - * Function added by Pierre-Alain Joye 02/08/2003 (paj@pearfr.org) - * See the ellipse function simplification for the equation - * as well as the midpoint algorithm. - */ - -void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) -{ - int x=0,mx1=0,mx2=0,my1=0,my2=0; - long aq,bq,dx,dy,r,rx,ry,a,b; - - a=w>>1; - b=h>>1; - gdImageSetPixel(im,mx+a, my, c); - gdImageSetPixel(im,mx-a, my, c); - mx1 = mx-a;my1 = my; - mx2 = mx+a;my2 = my; - - aq = a * a; - bq = b * b; - dx = aq << 1; - dy = bq << 1; - r = a * bq; - rx = r << 1; - ry = 0; - x = a; - while (x > 0){ - if (r > 0) { - my1++;my2--; - ry +=dx; - r -=ry; - } - if (r <= 0){ - x--; - mx1++;mx2--; - rx -=dy; - r +=rx; - } - gdImageSetPixel(im,mx1, my1, c); - gdImageSetPixel(im,mx1, my2, c); - gdImageSetPixel(im,mx2, my1, c); - gdImageSetPixel(im,mx2, my2, c); - } -} - -void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) -{ - int x=0,mx1=0,mx2=0,my1=0,my2=0; - long aq,bq,dx,dy,r,rx,ry,a,b; - int i; - int old_y2; - - a=w>>1; - b=h>>1; - - for (x = mx-a; x <= mx+a; x++) { - gdImageSetPixel(im, x, my, c); - } - - mx1 = mx-a;my1 = my; - mx2 = mx+a;my2 = my; - - aq = a * a; - bq = b * b; - dx = aq << 1; - dy = bq << 1; - r = a * bq; - rx = r << 1; - ry = 0; - x = a; - old_y2=-2; - while (x > 0){ - if (r > 0) { - my1++;my2--; - ry +=dx; - r -=ry; - } - if (r <= 0){ - x--; - mx1++;mx2--; - rx -=dy; - r +=rx; - } - if(old_y2!=my2){ - for(i=mx1;i<=mx2;i++){ - gdImageSetPixel(im,i,my1,c); - gdImageSetPixel(im,i,my2,c); - } - } - old_y2 = my2; - } -} - - diff --git a/ext/gd/libgd/gd_arc_f_buggy.c b/ext/gd/libgd/gd_arc_f_buggy.c deleted file mode 100644 index ffab551230..0000000000 --- a/ext/gd/libgd/gd_arc_f_buggy.c +++ /dev/null @@ -1,741 +0,0 @@ -/* This is potentially great stuff, but fails against the test - program at the end. This would probably be much more - efficient than the implementation currently in gd.c if the - errors in the output were corrected. TBB */ - -#if 0 - -#include "gd.h" -#include <math.h> - -/* Courtesy of F J Franklin. */ - -static gdPoint gdArcClosest (int width, int height, int angle); - -void -gdImageFilledEllipse (gdImagePtr im, int cx, int cy, int width, int height, int color) -{ - gdImageFilledArc (im, cx, cy, width, height, 0, 360, color, gdChord); -} - -void -gdImageFilledArc (gdImagePtr im, int cx, int cy, int width, int height, int s, int e, int color, int style) -{ - gdPoint pt[7]; - gdPoint axis_pt[4]; - - int angle; - - int have_s = 0; - int have_e = 0; - - int flip_x = 0; - int flip_y = 0; - - int conquer = 0; - - int i; - - int a; - int b; - - int x; - int y; - - long s_sin = 0; - long s_cos = 0; - long e_sin = 0; - long e_cos = 0; - - long w; /* a * 2 */ - long h; /* b * 2 */ - - long x2; /* x * 2 */ - long y2; /* y * 2 */ - long lx2; /* x * 2 (line) */ - long ly2; /* y * 2 (line) */ - - long ws; /* (a * 2)^2 */ - long hs; /* (b * 2)^2 */ - - long whs; /* (a * 2)^2 * (b * 2)^2 */ - - long g; /* decision variable */ - long lg; /* decision variable (line) */ - - width = (width & 1) ? (width + 1) : (width); - height = (height & 1) ? (height + 1) : (height); - - a = width / 2; - b = height / 2; - - axis_pt[0].x = a; - axis_pt[0].y = 0; - axis_pt[1].x = 0; - axis_pt[1].y = b; - axis_pt[2].x = -a; - axis_pt[2].y = 0; - axis_pt[3].x = 0; - axis_pt[3].y = -b; - - if (s == e) - return; - - if ((e - s) >= 360) - { - s = 0; - e = 0; - } - - while (s < 0) - s += 360; - while (s >= 360) - s -= 360; - while (e < 0) - e += 360; - while (e >= 360) - e -= 360; - - if (e <= s) - e += 360; - - /* I'm assuming a chord-rule at the moment. Need to add origin to get a - * pie-rule, but will need to set chord-rule before recursion... - */ - - for (i = 0; i < 4; i++) - { - if ((s < (i + 1) * 90) && (e > (i + 1) * 90)) - { - gdImageFilledArc (im, cx, cy, width, height, s, (i + 1) * 90, color, gdChord); - pt[0] = gdArcClosest (width, height, s); - pt[0].x += cx; - pt[0].y += cy; - pt[1].x = cx + axis_pt[(i + 1) & 3].x; - pt[1].y = cy + axis_pt[(i + 1) & 3].y; - if (e <= (i + 2) * 90) - { - gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, e, color, gdChord); - pt[2] = gdArcClosest (width, height, e); - pt[2].x += cx; - pt[2].y += cy; - if (style == gdChord) - { - gdImageFilledPolygon (im, pt, 3, color); - gdImagePolygon (im, pt, 3, color); - } - else if (style == gdPie) - { - pt[3].x = cx; - pt[3].y = cy; - gdImageFilledPolygon (im, pt, 4, color); - gdImagePolygon (im, pt, 4, color); - } - } - else - { - gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, (i + 2) * 90, color, gdChord); - pt[2].x = cx + axis_pt[(i + 2) & 3].x; - pt[2].y = cy + axis_pt[(i + 2) & 3].y; - if (e <= (i + 3) * 90) - { - gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, e, color, gdChord); - pt[3] = gdArcClosest (width, height, e); - pt[3].x += cx; - pt[3].y += cy; - if (style == gdChord) - { - gdImageFilledPolygon (im, pt, 4, color); - gdImagePolygon (im, pt, 4, color); - } - else if (style == gdPie) - { - pt[4].x = cx; - pt[4].y = cy; - gdImageFilledPolygon (im, pt, 5, color); - gdImagePolygon (im, pt, 5, color); - } - } - else - { - gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, (i + 3) * 90, color, gdChord); - pt[3].x = cx + axis_pt[(i + 3) & 3].x; - pt[3].y = cy + axis_pt[(i + 3) & 3].y; - if (e <= (i + 4) * 90) - { - gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, e, color, gdChord); - pt[4] = gdArcClosest (width, height, e); - pt[4].x += cx; - pt[4].y += cy; - if (style == gdChord) - { - gdImageFilledPolygon (im, pt, 5, color); - gdImagePolygon (im, pt, 5, color); - } - else if (style == gdPie) - { - pt[5].x = cx; - pt[5].y = cy; - gdImageFilledPolygon (im, pt, 6, color); - gdImagePolygon (im, pt, 6, color); - } - } - else - { - gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, (i + 4) * 90, color, gdChord); - pt[4].x = cx + axis_pt[(i + 4) & 3].x; - pt[4].y = cy + axis_pt[(i + 4) & 3].y; - - gdImageFilledArc (im, cx, cy, width, height, (i + 4) * 90, e, color, gdChord); - pt[5] = gdArcClosest (width, height, e); - pt[5].x += cx; - pt[5].y += cy; - if (style == gdChord) - { - gdImageFilledPolygon (im, pt, 6, color); - gdImagePolygon (im, pt, 6, color); - } - else if (style == gdPie) - { - pt[6].x = cx; - pt[6].y = cy; - gdImageFilledPolygon (im, pt, 7, color); - gdImagePolygon (im, pt, 7, color); - } - } - } - } - return; - } - } - - /* At this point we have only arcs that lies within a quadrant - - * map this to first quadrant... - */ - - if ((s >= 90) && (e <= 180)) - { - angle = s; - s = 180 - e; - e = 180 - angle; - flip_x = 1; - } - if ((s >= 180) && (e <= 270)) - { - s = s - 180; - e = e - 180; - flip_x = 1; - flip_y = 1; - } - if ((s >= 270) && (e <= 360)) - { - angle = s; - s = 360 - e; - e = 360 - angle; - flip_y = 1; - } - - if (s == 0) - { - s_sin = 0; - s_cos = (long) ((double) 32768); - } - else - { - s_sin = (long) ((double) 32768 * sin ((double) s * M_PI / (double) 180)); - s_cos = (long) ((double) 32768 * cos ((double) s * M_PI / (double) 180)); - } - if (e == 0) - { - e_sin = (long) ((double) 32768); - e_cos = 0; - } - else - { - e_sin = (long) ((double) 32768 * sin ((double) e * M_PI / (double) 180)); - e_cos = (long) ((double) 32768 * cos ((double) e * M_PI / (double) 180)); - } - - w = (long) width; - h = (long) height; - - ws = w * w; - hs = h * h; - - whs = 1; - while ((ws > 32768) || (hs > 32768)) - { - ws = (ws + 1) / 2; /* Unfortunate limitations on integers makes */ - hs = (hs + 1) / 2; /* drawing large ellipses problematic... */ - whs *= 2; - } - while ((ws * hs) > (0x04000000L / whs)) - { - ws = (ws + 1) / 2; - hs = (hs + 1) / 2; - whs *= 2; - } - whs *= ws * hs; - - pt[0].x = w / 2; - pt[0].y = 0; - - pt[2].x = 0; - pt[2].y = h / 2; - - have_s = 0; - have_e = 0; - - if (s == 0) - have_s = 1; - if (e == 90) - have_e = 1; - - x2 = w; - y2 = 0; /* Starting point is exactly on ellipse */ - - g = x2 - 1; - g = g * g * hs + 4 * ws - whs; - - while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ - { - y2 += 2; - g += ws * 4 * (y2 + 1); - - if (g > 0) /* Need to drop */ - { - x2 -= 2; - g -= hs * 4 * x2; - } - - if ((have_s == 0) && ((s_sin * x2) <= (y2 * s_cos))) - { - pt[0].x = (int) (x2 / 2); - pt[0].y = (int) (y2 / 2); - have_s = 1; - } - - if ((have_e == 0) && ((e_sin * x2) <= (y2 * e_cos))) - { - pt[2].x = (int) (x2 / 2); - pt[2].y = (int) (y2 / 2); - have_e = 1; - } - } - pt[1].x = (int) (x2 / 2); - pt[1].y = (int) (y2 / 2); - - x2 = 0; - y2 = h; /* Starting point is exactly on ellipse */ - - g = y2 - 1; - g = g * g * ws + 4 * hs - whs; - - while ((x2 * hs) < (y2 * ws)) - { - x2 += 2; - g += hs * 4 * (x2 + 1); - - if (g > 0) /* Need to drop */ - { - y2 -= 2; - g -= ws * 4 * y2; - } - - if ((have_s == 0) && ((s_sin * x2) >= (y2 * s_cos))) - { - pt[0].x = (int) (x2 / 2); - pt[0].y = (int) (y2 / 2); - have_s = 1; - } - - if ((have_e == 0) && ((e_sin * x2) >= (y2 * e_cos))) - { - pt[2].x = (int) (x2 / 2); - pt[2].y = (int) (y2 / 2); - have_e = 1; - } - } - - if ((have_s == 0) || (have_e == 0)) - return; /* Bizarre case */ - - if (style == gdPie) - { - pt[3] = pt[0]; - pt[4] = pt[1]; - pt[5] = pt[2]; - - pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x); - pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y); - pt[1].x = cx; - pt[1].y = cy; - pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); - pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); - gdImageFilledPolygon (im, pt, 3, color); - gdImagePolygon (im, pt, 3, color); - - pt[0] = pt[3]; - pt[1] = pt[4]; - pt[2] = pt[5]; - } - - if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))) - { /* the points are on different parts of the curve... - * this is too tricky to try to handle, so divide and conquer: - */ - pt[3] = pt[0]; - pt[4] = pt[1]; - pt[5] = pt[2]; - - pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x); - pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y); - pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x); - pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y); - pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); - pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); - gdImageFilledPolygon (im, pt, 3, color); - gdImagePolygon (im, pt, 3, color); - - pt[0] = pt[3]; - pt[2] = pt[4]; - - conquer = 1; - } - - if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws)))) - { /* This is the best bit... */ - /* steep line + ellipse */ - /* go up & left from pt[0] to pt[2] */ - - x2 = w; - y2 = 0; /* Starting point is exactly on ellipse */ - - g = x2 - 1; - g = g * g * hs + 4 * ws - whs; - - while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ - { - if ((s_sin * x2) <= (y2 * s_cos)) - break; - - y2 += 2; - g += ws * 4 * (y2 + 1); - - if (g > 0) /* Need to drop */ - { - x2 -= 2; - g -= hs * 4 * x2; - } - } - - lx2 = x2; - ly2 = y2; - - lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); - lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg; - - while (y2 < (2 * pt[2].y)) - { - y2 += 2; - g += ws * 4 * (y2 + 1); - - if (g > 0) /* Need to drop */ - { - x2 -= 2; - g -= hs * 4 * x2; - } - - ly2 += 2; - lg -= 2 * (pt[0].x - pt[2].x); - - if (lg < 0) /* Need to drop */ - { - lx2 -= 2; - lg -= 2 * (pt[0].y - pt[2].y); - } - - y = (int) (y2 / 2); - for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++) - { - gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), - ((flip_y) ? (cy - y) : (cy + y)), color); - } - } - } - if (conquer) - { - pt[0] = pt[4]; - pt[2] = pt[5]; - } - if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))) - { /* This is the best bit... */ - /* gradual line + ellipse */ - /* go down & right from pt[2] to pt[0] */ - - x2 = 0; - y2 = h; /* Starting point is exactly on ellipse */ - - g = y2 - 1; - g = g * g * ws + 4 * hs - whs; - - while ((x2 * hs) < (y2 * ws)) - { - x2 += 2; - g += hs * 4 * (x2 + 1); - - if (g > 0) /* Need to drop */ - { - y2 -= 2; - g -= ws * 4 * y2; - } - - if ((e_sin * x2) >= (y2 * e_cos)) - break; - } - - lx2 = x2; - ly2 = y2; - - lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); - lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg; - - while (x2 < (2 * pt[0].x)) - { - x2 += 2; - g += hs * 4 * (x2 + 1); - - if (g > 0) /* Need to drop */ - { - y2 -= 2; - g -= ws * 4 * y2; - } - - lx2 += 2; - lg += 2 * (pt[0].y - pt[2].y); - - if (lg < 0) /* Need to drop */ - { - ly2 -= 2; - lg += 2 * (pt[0].x - pt[2].x); - } - - x = (int) (x2 / 2); - for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++) - { - gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), - ((flip_y) ? (cy - y) : (cy + y)), color); - } - } - } -} - -static gdPoint -gdArcClosest (int width, int height, int angle) -{ - gdPoint pt; - - int flip_x = 0; - int flip_y = 0; - - long a_sin = 0; - long a_cos = 0; - - long w; /* a * 2 */ - long h; /* b * 2 */ - - long x2; /* x * 2 */ - long y2; /* y * 2 */ - - long ws; /* (a * 2)^2 */ - long hs; /* (b * 2)^2 */ - - long whs; /* (a * 2)^2 * (b * 2)^2 */ - - long g; /* decision variable */ - - w = (long) ((width & 1) ? (width + 1) : (width)); - h = (long) ((height & 1) ? (height + 1) : (height)); - - while (angle < 0) - angle += 360; - while (angle >= 360) - angle -= 360; - - if (angle == 0) - { - pt.x = w / 2; - pt.y = 0; - return (pt); - } - if (angle == 90) - { - pt.x = 0; - pt.y = h / 2; - return (pt); - } - if (angle == 180) - { - pt.x = -w / 2; - pt.y = 0; - return (pt); - } - if (angle == 270) - { - pt.x = 0; - pt.y = -h / 2; - return (pt); - } - - pt.x = 0; - pt.y = 0; - - if ((angle > 90) && (angle < 180)) - { - angle = 180 - angle; - flip_x = 1; - } - if ((angle > 180) && (angle < 270)) - { - angle = angle - 180; - flip_x = 1; - flip_y = 1; - } - if ((angle > 270) && (angle < 360)) - { - angle = 360 - angle; - flip_y = 1; - } - - a_sin = (long) ((double) 32768 * sin ((double) angle * M_PI / (double) 180)); - a_cos = (long) ((double) 32768 * cos ((double) angle * M_PI / (double) 180)); - - ws = w * w; - hs = h * h; - - whs = 1; - while ((ws > 32768) || (hs > 32768)) - { - ws = (ws + 1) / 2; /* Unfortunate limitations on integers makes */ - hs = (hs + 1) / 2; /* drawing large ellipses problematic... */ - whs *= 2; - } - while ((ws * hs) > (0x04000000L / whs)) - { - ws = (ws + 1) / 2; - hs = (hs + 1) / 2; - whs *= 2; - } - whs *= ws * hs; - - if ((a_cos * hs) > (a_sin * ws)) - { - x2 = w; - y2 = 0; /* Starting point is exactly on ellipse */ - - g = x2 - 1; - g = g * g * hs + 4 * ws - whs; - - while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ - { - y2 += 2; - g += ws * 4 * (y2 + 1); - - if (g > 0) /* Need to drop */ - { - x2 -= 2; - g -= hs * 4 * x2; - } - - if ((a_sin * x2) <= (y2 * a_cos)) - { - pt.x = (int) (x2 / 2); - pt.y = (int) (y2 / 2); - break; - } - } - } - else - { - x2 = 0; - y2 = h; /* Starting point is exactly on ellipse */ - - g = y2 - 1; - g = g * g * ws + 4 * hs - whs; - - while ((x2 * hs) < (y2 * ws)) - { - x2 += 2; - g += hs * 4 * (x2 + 1); - - if (g > 0) /* Need to drop */ - { - y2 -= 2; - g -= ws * 4 * y2; - } - - if ((a_sin * x2) >= (y2 * a_cos)) - { - pt.x = (int) (x2 / 2); - pt.y = (int) (y2 / 2); - break; - } - } - } - - if (flip_x) - pt.x = -pt.x; - if (flip_y) - pt.y = -pt.y; - - return (pt); -} - -#include "gd.h" -#include <string.h> -#include <math.h> - -#define WIDTH 500 -#define HEIGHT 300 - -int -main (int argc, char *argv[]) -{ - gdImagePtr im = gdImageCreate (WIDTH, HEIGHT); - int white = gdImageColorResolve (im, 0xFF, 0xFF, 0xFF), black = gdImageColorResolve (im, 0, 0, 0), - red = gdImageColorResolve (im, 0xFF, 0xA0, 0xA0); - FILE *out; - - /* filled arc - circle */ - gdImageFilledArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, red, gdPie); - gdImageArc (im, WIDTH / 5, HEIGHT / 4, 200, 200, 45, 90, black); - - /* filled arc - ellipse */ - gdImageFilledArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, red, gdPie); - gdImageArc (im, WIDTH / 2, HEIGHT / 4, 200, 150, 45, 90, black); - - - /* reference lines */ - gdImageLine (im, 0, HEIGHT / 4, WIDTH, HEIGHT / 4, black); - gdImageLine (im, WIDTH / 5, 0, WIDTH / 5, HEIGHT, black); - gdImageLine (im, WIDTH / 2, 0, WIDTH / 2, HEIGHT, black); - gdImageLine (im, WIDTH / 2, HEIGHT / 4, WIDTH / 2 + 300, HEIGHT / 4 + 300, black); - gdImageLine (im, WIDTH / 5, HEIGHT / 4, WIDTH / 5 + 300, HEIGHT / 4 + 300, black); - - /* TBB: Write img to test/arctest.png */ - out = fopen ("test/arctest.png", "wb"); - if (!out) - { - php_gd_error("Can't create test/arctest.png"); - exit (1); - } - gdImagePng (im, out); - fclose (out); - php_gd_error("Test image written to test/arctest.png"); - /* Destroy it */ - gdImageDestroy (im); - - return 0; -} - -#endif diff --git a/ext/gd/libgd/gd_color.c b/ext/gd/libgd/gd_color_match.c index a4e56b1c40..a4e56b1c40 100644 --- a/ext/gd/libgd/gd_color.c +++ b/ext/gd/libgd/gd_color_match.c diff --git a/ext/gd/libgd/gd_errors.h b/ext/gd/libgd/gd_errors.h new file mode 100644 index 0000000000..8a28bf6051 --- /dev/null +++ b/ext/gd/libgd/gd_errors.h @@ -0,0 +1,30 @@ +#ifndef GD_ERRORS_H +#define GD_ERRORS_H + +#ifndef _WIN32 +# include <syslog.h> +#else +# include "win32/syslog.h" +#endif + +/* +LOG_EMERG system is unusable +LOG_ALERT action must be taken immediately +LOG_CRIT critical conditions +LOG_ERR error conditions +LOG_WARNING warning conditions +LOG_NOTICE normal, but significant, condition +LOG_INFO informational message +LOG_DEBUG debug-level message +*/ + +#define GD_ERROR LOG_ERR +#define GD_WARNING LOG_WARNING +#define GD_NOTICE LOG_NOTICE +#define GD_INFO LOG_INFO +#define GD_DEBUG LOG_DEBUG + +void gd_error(const char *format, ...); +void gd_error_ex(int priority, const char *format, ...); + +#endif diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index d06f328425..1808e723c3 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -16,6 +16,7 @@ #include <string.h> #include <stdlib.h> #include "gd.h" +#include "gd_errors.h" #include "gdhelpers.h" #include <zlib.h> @@ -60,7 +61,7 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in int sidx; int nc; - GD2_DBG(php_gd_error("Reading gd2 header info")); + GD2_DBG(gd_error("Reading gd2 header info")); for (i = 0; i < 4; i++) { ch = gdGetC(in); @@ -71,11 +72,11 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in } id[4] = 0; - GD2_DBG(php_gd_error("Got file code: %s", id)); + GD2_DBG(gd_error("Got file code: %s", id)); /* Equiv. of 'magick'. */ if (strcmp(id, GD2_ID) != 0) { - GD2_DBG(php_gd_error("Not a valid gd2 file")); + GD2_DBG(gd_error("Not a valid gd2 file")); goto fail1; } @@ -83,32 +84,32 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in if (gdGetWord(vers, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("Version: %d", *vers)); + GD2_DBG(gd_error("Version: %d", *vers)); if ((*vers != 1) && (*vers != 2)) { - GD2_DBG(php_gd_error("Bad version: %d", *vers)); + GD2_DBG(gd_error("Bad version: %d", *vers)); goto fail1; } /* Image Size */ if (!gdGetWord(sx, in)) { - GD2_DBG(php_gd_error("Could not get x-size")); + GD2_DBG(gd_error("Could not get x-size")); goto fail1; } if (!gdGetWord(sy, in)) { - GD2_DBG(php_gd_error("Could not get y-size")); + GD2_DBG(gd_error("Could not get y-size")); goto fail1; } - GD2_DBG(php_gd_error("Image is %dx%d", *sx, *sy)); + GD2_DBG(gd_error("Image is %dx%d", *sx, *sy)); /* Chunk Size (pixels, not bytes!) */ if (gdGetWord(cs, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("ChunkSize: %d", *cs)); + GD2_DBG(gd_error("ChunkSize: %d", *cs)); if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX)) { - GD2_DBG(php_gd_error("Bad chunk size: %d", *cs)); + GD2_DBG(gd_error("Bad chunk size: %d", *cs)); goto fail1; } @@ -116,10 +117,10 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in if (gdGetWord(fmt, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("Format: %d", *fmt)); + GD2_DBG(gd_error("Format: %d", *fmt)); if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED) && (*fmt != GD2_FMT_TRUECOLOR_RAW) && (*fmt != GD2_FMT_TRUECOLOR_COMPRESSED)) { - GD2_DBG(php_gd_error("Bad data format: %d", *fmt)); + GD2_DBG(gd_error("Bad data format: %d", *fmt)); goto fail1; } @@ -127,17 +128,17 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in if (gdGetWord(ncx, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("%d Chunks Wide", *ncx)); + GD2_DBG(gd_error("%d Chunks Wide", *ncx)); /* # of chunks high */ if (gdGetWord(ncy, in) != 1) { goto fail1; } - GD2_DBG(php_gd_error("%d Chunks vertically", *ncy)); + GD2_DBG(gd_error("%d Chunks vertically", *ncy)); if (gd2_compressed(*fmt)) { nc = (*ncx) * (*ncy); - GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); + GD2_DBG(gd_error("Reading %d chunk index entries", nc)); if (overflow2(sizeof(t_chunk_info), nc)) { goto fail1; } @@ -167,7 +168,7 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in *chunkIdx = cidx; } - GD2_DBG(php_gd_error("gd2 header complete")); + GD2_DBG(gd_error("gd2 header complete")); return 1; @@ -180,7 +181,7 @@ static gdImagePtr _gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy, int *cs, gdImagePtr im; if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1) { - GD2_DBG(php_gd_error("Bad GD2 header")); + GD2_DBG(gd_error("Bad GD2 header")); goto fail1; } @@ -190,15 +191,15 @@ static gdImagePtr _gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy, int *cs, im = gdImageCreate(*sx, *sy); } if (im == NULL) { - GD2_DBG(php_gd_error("Could not create gdImage")); + GD2_DBG(gd_error("Could not create gdImage")); goto fail2; } if (!_gdGetColors(in, im, (*vers) == 2)) { - GD2_DBG(php_gd_error("Could not read color palette")); + GD2_DBG(gd_error("Could not read color palette")); goto fail3; } - GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal)); + GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); return im; @@ -215,24 +216,24 @@ static int _gd2ReadChunk (int offset, char *compBuf, int compSize, char *chunkBu int zerr; if (gdTell(in) != offset) { - GD2_DBG(php_gd_error("Positioning in file to %d", offset)); + GD2_DBG(gd_error("Positioning in file to %d", offset)); gdSeek(in, offset); } else { - GD2_DBG(php_gd_error("Already Positioned in file to %d", offset)); + GD2_DBG(gd_error("Already Positioned in file to %d", offset)); } /* Read and uncompress an entire chunk. */ - GD2_DBG(php_gd_error("Reading file")); + GD2_DBG(gd_error("Reading file")); if (gdGetBuf(compBuf, compSize, in) != compSize) { return FALSE; } - GD2_DBG(php_gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen)); + GD2_DBG(gd_error("Got %d bytes. Uncompressing into buffer of %d bytes", compSize, (int)*chunkLen)); zerr = uncompress((unsigned char *) chunkBuf, chunkLen, (unsigned char *) compBuf, compSize); if (zerr != Z_OK) { - GD2_DBG(php_gd_error("Error %d from uncompress", zerr)); + GD2_DBG(gd_error("Error %d from uncompress", zerr)); return FALSE; } - GD2_DBG(php_gd_error("Got chunk")); + GD2_DBG(gd_error("Got chunk")); return TRUE; } @@ -304,7 +305,7 @@ gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in) chunkBuf = gdCalloc(chunkMax, 1); compBuf = gdCalloc(compMax, 1); - GD2_DBG(php_gd_error("Largest compressed chunk is %d bytes", compMax)); + GD2_DBG(gd_error("Largest compressed chunk is %d bytes", compMax)); } /* Read the data... */ @@ -316,13 +317,13 @@ gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in) yhi = im->sy; } - GD2_DBG(php_gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, yhi)); + GD2_DBG(gd_error("Processing Chunk %d (%d, %d), y from %d to %d", chunkNum, cx, cy, ylo, yhi)); if (gd2_compressed(fmt)) { chunkLen = chunkMax; if (!_gd2ReadChunk(chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *) chunkBuf, &chunkLen, in)) { - GD2_DBG(php_gd_error("Error reading comproessed chunk")); + GD2_DBG(gd_error("Error reading comproessed chunk")); goto fail2; } @@ -369,7 +370,7 @@ gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in) } } - GD2_DBG(php_gd_error("Freeing memory")); + GD2_DBG(gd_error("Freeing memory")); if (chunkBuf) { gdFree(chunkBuf); @@ -381,7 +382,7 @@ gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in) gdFree(chunkIdx); } - GD2_DBG(php_gd_error("Done")); + GD2_DBG(gd_error("Done")); return im; @@ -455,7 +456,7 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, goto fail1; } - GD2_DBG(php_gd_error("File size is %dx%d", fsx, fsy)); + GD2_DBG(gd_error("File size is %dx%d", fsx, fsy)); /* This is the difference - make a file based on size of chunks. */ if (gd2_truecolor(fmt)) { @@ -470,7 +471,7 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, if (!_gdGetColors(in, im, vers == 2)) { goto fail2; } - GD2_DBG(php_gd_error("Image palette completed: %d colours", im->colorsTotal)); + GD2_DBG(gd_error("Image palette completed: %d colours", im->colorsTotal)); /* Process the header info */ nc = ncx * ncy; @@ -519,7 +520,7 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, /* Remember file position of image data. */ dstart = gdTell(in); - GD2_DBG(php_gd_error("Data starts at %d", dstart)); + GD2_DBG(gd_error("Data starts at %d", dstart)); /* Loop through the chunks. */ for (cy = scy; (cy <= ecy); cy++) { @@ -537,10 +538,10 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, xhi = fsx; } - GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi)); + GD2_DBG(gd_error("Processing Chunk (%d, %d), from %d to %d", cx, cy, ylo, yhi)); if (!gd2_compressed(fmt)) { - GD2_DBG(php_gd_error("Using raw format data")); + GD2_DBG(gd_error("Using raw format data")); if (im->trueColor) { dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart; } else { @@ -549,23 +550,23 @@ gdImagePtr gdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, /* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */ if (!gdSeek(in, dpos)) { - php_gd_error_ex(E_WARNING, "Error from seek: %d", errno); + gd_error_ex(E_WARNING, "Error from seek: %d", errno); goto fail2; } - GD2_DBG(php_gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart)); + GD2_DBG(gd_error("Reading (%d, %d) from position %d", cx, cy, dpos - dstart)); } else { chunkNum = cx + cy * ncx; chunkLen = chunkMax; if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, (char *)chunkBuf, &chunkLen, in)) { - php_gd_error("Error reading comproessed chunk"); + gd_error("Error reading comproessed chunk"); goto fail2; } chunkPos = 0; - GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum)); + GD2_DBG(gd_error("Reading (%d, %d) from chunk %d", cx, cy, chunkNum)); } - GD2_DBG(php_gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi)); + GD2_DBG(gd_error(" into (%d, %d) - (%d, %d)", xlo, ylo, xhi, yhi)); for (y = ylo; (y < yhi); y++) { for (x = xlo; x < xhi; x++) { @@ -718,7 +719,7 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) */ idxPos = gdTell(out); idxSize = ncx * ncy * sizeof(t_chunk_info); - GD2_DBG(php_gd_error("Index size is %d", idxSize)); + GD2_DBG(gd_error("Index size is %d", idxSize)); gdSeek(out, idxPos + idxSize); chunkIdx = safe_emalloc(idxSize, sizeof(t_chunk_info), 0); @@ -727,8 +728,8 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) _gdPutColors (im, out); - GD2_DBG(php_gd_error("Size: %dx%d", im->sx, im->sy)); - GD2_DBG(php_gd_error("Chunks: %dx%d", ncx, ncy)); + GD2_DBG(gd_error("Size: %dx%d", im->sx, im->sy)); + GD2_DBG(gd_error("Chunks: %dx%d", ncx, ncy)); for (cy = 0; (cy < ncy); cy++) { for (cx = 0; (cx < ncx); cx++) { @@ -738,10 +739,10 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) yhi = im->sy; } - GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi)); + GD2_DBG(gd_error("Processing Chunk (%dx%d), y from %d to %d", cx, cy, ylo, yhi)); chunkLen = 0; for (y = ylo; (y < yhi); y++) { - GD2_DBG(php_gd_error("y=%d: ",y)); + GD2_DBG(gd_error("y=%d: ",y)); xlo = cx * cs; xhi = xlo + cs; if (xhi > im->sx) { @@ -750,7 +751,7 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) if (gd2_compressed(fmt)) { for (x = xlo; x < xhi; x++) { - GD2_DBG(php_gd_error("%d...",x)); + GD2_DBG(gd_error("%d...",x)); if (im->trueColor) { int p = im->tpixels[y][x]; chunkData[chunkLen++] = gdTrueColorGetAlpha(p); @@ -763,7 +764,7 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) } } else { for (x = xlo; x < xhi; x++) { - GD2_DBG(php_gd_error("%d, ",x)); + GD2_DBG(gd_error("%d, ",x)); if (im->trueColor) { gdPutInt(im->tpixels[y][x], out); @@ -772,21 +773,21 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) } } } - GD2_DBG(php_gd_error("y=%d done.",y)); + GD2_DBG(gd_error("y=%d done.",y)); } if (gd2_compressed(fmt)) { compLen = compMax; if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) { - php_gd_error("Error from compressing"); + gd_error("Error from compressing"); } else { chunkIdx[chunkNum].offset = gdTell(out); chunkIdx[chunkNum++].size = compLen; - GD2_DBG(php_gd_error("Chunk %d size %d offset %d", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); + GD2_DBG(gd_error("Chunk %d size %d offset %d", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); if (gdPutBuf (compData, compLen, out) <= 0) { /* Any alternate suggestions for handling this? */ - php_gd_error_ex(E_WARNING, "Error %d on write", errno); + gd_error_ex(E_WARNING, "Error %d on write", errno); } } } @@ -795,19 +796,19 @@ static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) if (gd2_compressed(fmt)) { /* Save the position, write the index, restore position (paranoia). */ - GD2_DBG(php_gd_error("Seeking %d to write index", idxPos)); + GD2_DBG(gd_error("Seeking %d to write index", idxPos)); posSave = gdTell(out); gdSeek(out, idxPos); - GD2_DBG(php_gd_error("Writing index")); + GD2_DBG(gd_error("Writing index")); for (x = 0; x < chunkNum; x++) { - GD2_DBG(php_gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset)); + GD2_DBG(gd_error("Chunk %d size %d offset %d", x, chunkIdx[x].size, chunkIdx[x].offset)); gdPutInt(chunkIdx[x].offset, out); gdPutInt(chunkIdx[x].size, out); } gdSeek(out, posSave); } fail: - GD2_DBG(php_gd_error("Freeing memory")); + GD2_DBG(gd_error("Freeing memory")); if (chunkData) { gdFree(chunkData); } @@ -817,7 +818,7 @@ fail: if (chunkIdx) { gdFree(chunkIdx); } - GD2_DBG(php_gd_error("Done")); + GD2_DBG(gd_error("Done")); } void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt) diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c index 74b7493331..0111a3ee78 100644 --- a/ext/gd/libgd/gd_gif_in.c +++ b/ext/gd/libgd/gd_gif_in.c @@ -3,6 +3,7 @@ #include <string.h> #include <stdlib.h> #include "gd.h" +#include "gd_errors.h" #include "php.h" @@ -361,7 +362,7 @@ GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP) } else { tmp = estrdup(""); } - php_gd_error_ex(E_NOTICE, "[GetDataBlock returning %d: %s]", rv, tmp); + gd_error_ex(GD_NOTICE, "[GetDataBlock returning %d: %s]", rv, tmp); efree(tmp); } return(rv); diff --git a/ext/gd/libgd/gd_io.c b/ext/gd/libgd/gd_io.c index ab807149f7..f10008649b 100644 --- a/ext/gd/libgd/gd_io.c +++ b/ext/gd/libgd/gd_io.c @@ -52,20 +52,20 @@ void gdPutC (const unsigned char c, gdIOCtx * ctx) void gdPutWord (int w, gdIOCtx * ctx) { - IO_DBG (php_gd_error("Putting word...")); + IO_DBG (gd_error("Putting word...")); (ctx->putC) (ctx, (unsigned char) (w >> 8)); (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (php_gd_error("put.")); + IO_DBG (gd_error("put.")); } void gdPutInt (int w, gdIOCtx * ctx) { - IO_DBG (php_gd_error("Putting int...")); + IO_DBG (gd_error("Putting int...")); (ctx->putC) (ctx, (unsigned char) (w >> 24)); (ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF)); (ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF)); (ctx->putC) (ctx, (unsigned char) (w & 0xFF)); - IO_DBG (php_gd_error("put.")); + IO_DBG (gd_error("put.")); } int gdGetC (gdIOCtx * ctx) @@ -121,9 +121,9 @@ int gdGetInt (int *result, gdIOCtx * ctx) int gdPutBuf (const void *buf, int size, gdIOCtx * ctx) { - IO_DBG (php_gd_error("Putting buf...")); + IO_DBG (gd_error("Putting buf...")); return (ctx->putBuf) (ctx, buf, size); - IO_DBG (php_gd_error("put.")); + IO_DBG (gd_error("put.")); } int gdGetBuf (void *buf, int size, gdIOCtx * ctx) @@ -133,14 +133,14 @@ int gdGetBuf (void *buf, int size, gdIOCtx * ctx) int gdSeek (gdIOCtx * ctx, const int pos) { - IO_DBG (php_gd_error("Seeking...")); + IO_DBG (gd_error("Seeking...")); return ((ctx->seek) (ctx, pos)); - IO_DBG (php_gd_error("Done.")); + IO_DBG (gd_error("Done.")); } long gdTell (gdIOCtx * ctx) { - IO_DBG (php_gd_error("Telling...")); + IO_DBG (gd_error("Telling...")); return ((ctx->tell) (ctx)); - IO_DBG (php_gd_error ("told.")); + IO_DBG (gd_error ("told.")); } diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index f239ef8acd..23d161631d 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -28,6 +28,7 @@ #include <string.h> #include "gd.h" +#include "gd_errors.h" /* TBB: move this up so include files are not brought in */ /* JCE: arrange HAVE_LIBJPEG so that it can be set in gd.h */ #ifdef HAVE_LIBJPEG @@ -66,14 +67,14 @@ static long php_jpeg_emit_message(j_common_ptr jpeg_info, int level) * unless strace_level >= 3 */ if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) { - php_gd_error_ex(ignore_warning ? E_NOTICE : E_WARNING, "gd-jpeg, libjpeg: recoverable error: %s\n", message); + gd_error_ex(ignore_warning ? GD_NOTICE : GD_WARNING, "gd-jpeg, libjpeg: recoverable error: %s\n", message); } jpeg_info->err->num_warnings++; } else { /* strace msg, Show it if trace_level >= level. */ if (jpeg_info->err->trace_level >= level) { - php_gd_error_ex(E_NOTICE, "gd-jpeg, libjpeg: strace message: %s\n", message); + gd_error_ex(GD_NOTICE, "gd-jpeg, libjpeg: strace message: %s\n", message); } } return 1; @@ -86,7 +87,7 @@ static void fatal_jpeg_error (j_common_ptr cinfo) { jmpbuf_wrapper *jmpbufw; - php_gd_error("gd-jpeg: JPEG library reports unrecoverable error: "); + gd_error("gd-jpeg: JPEG library reports unrecoverable error: "); (*cinfo->err->output_message) (cinfo); jmpbufw = (jmpbuf_wrapper *) cinfo->client_data; @@ -94,9 +95,9 @@ static void fatal_jpeg_error (j_common_ptr cinfo) if (jmpbufw != 0) { longjmp (jmpbufw->jmpbuf, 1); - php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating"); + gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating"); } else { - php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating"); + gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating"); } exit (99); @@ -195,6 +196,11 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults (&cinfo); + + cinfo.density_unit = 1; + cinfo.X_density = im->res_x; + cinfo.Y_density = im->res_y; + if (quality >= 0) { jpeg_set_quality (&cinfo, quality, TRUE); } @@ -221,7 +227,7 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) if (im->trueColor) { #if BITS_IN_JSAMPLE == 12 - php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry"); + gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry"); goto error; #endif /* BITS_IN_JSAMPLE == 12 */ @@ -236,7 +242,7 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); if (nlines != 1) { - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); + gd_error_ex(GD_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); } } } else { @@ -263,7 +269,7 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); if (nlines != 1) { - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); + gd_error_ex(GD_WARNING, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1", nlines); } } } @@ -364,23 +370,35 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) retval = jpeg_read_header (&cinfo, TRUE); if (retval != JPEG_HEADER_OK) { - php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); + gd_error_ex(GD_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); } if (cinfo.image_height > INT_MAX) { - php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image height (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_height, INT_MAX); + gd_error_ex(GD_WARNING, "gd-jpeg: warning: JPEG image height (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_height, INT_MAX); } if (cinfo.image_width > INT_MAX) { - php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX); + gd_error_ex(GD_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX); } im = gdImageCreateTrueColor ((int) cinfo.image_width, (int) cinfo.image_height); if (im == 0) { - php_gd_error("gd-jpeg error: cannot allocate gdImage struct"); + gd_error("gd-jpeg error: cannot allocate gdImage struct"); goto error; } + /* check if the resolution is specified */ + switch (cinfo.density_unit) { + case 1: + im->res_x = cinfo.X_density; + im->res_y = cinfo.Y_density; + break; + case 2: + im->res_x = DPCM2DPI(cinfo.X_density); + im->res_y = DPCM2DPI(cinfo.Y_density); + break; + } + /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for * thumbnails but there's no support for fussy adjustment of the * assumed properties of inks and paper. */ @@ -391,7 +409,7 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) } if (jpeg_start_decompress (&cinfo) != TRUE) { - php_gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source"); + gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source"); } /* REMOVED by TBB 2/12/01. This field of the structure is @@ -409,14 +427,14 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) if (cinfo.out_color_space == JCS_RGB) { if (cinfo.output_components != 3) { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3 for RGB)", cinfo.output_components); + gd_error_ex(GD_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3 for RGB)", cinfo.output_components); goto error; } channels = 3; } else if (cinfo.out_color_space == JCS_CMYK) { jpeg_saved_marker_ptr marker; if (cinfo.output_components != 4) { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 4 for CMYK)", cinfo.output_components); + gd_error_ex(GD_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 4 for CMYK)", cinfo.output_components); goto error; } channels = 4; @@ -429,12 +447,12 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) marker = marker->next; } } else { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: unexpected colorspace."); + gd_error_ex(GD_WARNING, "gd-jpeg: error: unexpected colorspace."); goto error; } #if BITS_IN_JSAMPLE == 12 - php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry."); + gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry."); goto error; #endif /* BITS_IN_JSAMPLE == 12 */ @@ -448,7 +466,7 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); if (nrows != 1) { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); + gd_error_ex(GD_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); goto error; } for (j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { @@ -461,7 +479,7 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); if (nrows != 1) { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); + gd_error_ex(GD_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); goto error; } for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { @@ -471,7 +489,7 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) } if (jpeg_finish_decompress (&cinfo) != TRUE) { - php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); + gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); } if (!ignore_warning) { if (cinfo.err->num_warnings > 0) { diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c index a012cc63b8..f628d876ef 100644 --- a/ext/gd/libgd/gd_png.c +++ b/ext/gd/libgd/gd_png.c @@ -3,6 +3,7 @@ #include <string.h> #include <stdlib.h> #include "gd.h" +#include "gd_errors.h" /* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */ #ifdef HAVE_LIBPNG @@ -61,11 +62,11 @@ static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) * been defined. */ - php_gd_error_ex(E_WARNING, "gd-png: fatal libpng error: %s", msg); + gd_error_ex(GD_WARNING, "gd-png: fatal libpng error: %s", msg); jmpbuf_ptr = png_get_error_ptr (png_ptr); if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ - php_gd_error_ex(E_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating."); + gd_error_ex(GD_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating."); } longjmp (jmpbuf_ptr->jmpbuf, 1); @@ -120,8 +121,8 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) #endif png_structp png_ptr; png_infop info_ptr; - png_uint_32 width, height, rowbytes, w, h; - int bit_depth, color_type, interlace_type; + png_uint_32 width, height, rowbytes, w, h, res_x, res_y; + int bit_depth, color_type, interlace_type, unit_type; int num_palette, num_trans; png_colorp palette; png_color_16p trans_gray_rgb; @@ -156,13 +157,13 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif if (png_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng main struct"); + gd_error("gd-png error: cannot allocate libpng main struct"); return NULL; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng info struct"); + gd_error("gd-png error: cannot allocate libpng info struct"); png_destroy_read_struct (&png_ptr, NULL, NULL); return NULL; @@ -178,7 +179,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) */ #ifdef PNG_SETJMP_SUPPORTED if (setjmp(jbw.jmpbuf)) { - php_gd_error("gd-png error: setjmp returns error condition"); + gd_error("gd-png error: setjmp returns error condition"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; @@ -198,7 +199,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) im = gdImageCreate((int) width, (int) height); } if (im == NULL) { - php_gd_error("gd-png error: cannot allocate gdImage struct"); + gd_error("gd-png error: cannot allocate gdImage struct"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; @@ -215,7 +216,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) */ #ifdef PNG_SETJMP_SUPPORTED if (setjmp(jbw.jmpbuf)) { - php_gd_error("gd-png error: setjmp returns error condition"); + gd_error("gd-png error: setjmp returns error condition"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); gdFree(image_data); gdFree(row_pointers); @@ -226,11 +227,25 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) } #endif +#ifdef PNG_pHYs_SUPPORTED + /* check if the resolution is specified */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) { + if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) { + switch (unit_type) { + case PNG_RESOLUTION_METER: + im->res_x = DPM2DPI(res_x); + im->res_y = DPM2DPI(res_y); + break; + } + } + } +#endif + switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); #ifdef DEBUG - php_gd_error("gd-png color_type is palette, colors: %d", num_palette); + gd_error("gd-png color_type is palette, colors: %d", num_palette); #endif /* DEBUG */ if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { /* gd 2.0: we support this rather thoroughly now. Grab the @@ -253,7 +268,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) case PNG_COLOR_TYPE_GRAY: /* create a fake palette and check for single-shade transparency */ if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) { - php_gd_error("gd-png error: cannot allocate gray palette"); + gd_error("gd-png error: cannot allocate gray palette"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; @@ -402,7 +417,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile) if (!im->trueColor) { for (i = num_palette; i < gdMaxColors; ++i) { if (!open[i]) { - php_gd_error("gd-png warning: image data references out-of-range color index (%d)", i); + gd_error("gd-png warning: image data references out-of-range color index (%d)", i); } } } @@ -484,13 +499,13 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif if (png_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng main struct"); + gd_error("gd-png error: cannot allocate libpng main struct"); return; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { - php_gd_error("gd-png error: cannot allocate libpng info struct"); + gd_error("gd-png error: cannot allocate libpng info struct"); png_destroy_write_struct (&png_ptr, (png_infopp) NULL); return; @@ -498,7 +513,7 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte #ifdef PNG_SETJMP_SUPPORTED if (setjmp(jbw.jmpbuf)) { - php_gd_error("gd-png error: setjmp returns error condition"); + gd_error("gd-png error: setjmp returns error condition"); png_destroy_write_struct (&png_ptr, &info_ptr); return; @@ -518,7 +533,7 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte /* 2.0.12: this is finally a parameter */ if (level != -1 && (level < 0 || level > 9)) { - php_gd_error("gd-png error: compression level must be 0 through 9"); + gd_error("gd-png error: compression level must be 0 through 9"); return; } png_set_compression_level(png_ptr, level); @@ -526,6 +541,12 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter); } +#ifdef PNG_pHYs_SUPPORTED + /* 2.1.0: specify the resolution */ + png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y), + PNG_RESOLUTION_METER); +#endif + /* can set this to a smaller value without compromising compression if all * image data is 16K or less; will save some decoder memory [min == 8] */ @@ -550,7 +571,7 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte } } if (colors == 0) { - php_gd_error("gd-png error: no colors in palette"); + gd_error("gd-png error: no colors in palette"); goto bail; } if (colors < im->colorsTotal) { diff --git a/ext/gd/libgd/gd_rotate.c b/ext/gd/libgd/gd_rotate.c index e94809ae77..010cc27a40 100644 --- a/ext/gd/libgd/gd_rotate.c +++ b/ext/gd/libgd/gd_rotate.c @@ -346,9 +346,7 @@ gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent) gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent) { - typedef int (*FuncPtr)(gdImagePtr, int, int); gdImagePtr dst1,dst2,dst3; - FuncPtr f; double dRadAngle, dSinE, dTan, dShear; double dOffset; /* Variable skew offset */ int u, iShear, newx, newy; @@ -363,22 +361,12 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int igno newy = src->sy; /* 1st shear */ - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } - dst1 = gdImageCreateTrueColor(newx, newy); /******* Perform 1st shear (horizontal) ******/ if (dst1 == NULL) { return NULL; } -#ifdef HAVE_GD_BUNDLED - dst1->alphaBlendingFlag = gdEffectReplace; -#else gdImageAlphaBlending(dst1, 0); -#endif if (dAngle == 0.0) { /* Returns copy of src */ gdImageCopy (dst1, src,0,0,0,0,src->sx,src->sy); @@ -396,10 +384,6 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int igno } } - dRadAngle = dAngle * ROTATE_DEG2RAD; /* Angle in radians */ - dSinE = sin (dRadAngle); - dTan = tan (dRadAngle / 2.0); - for (u = 0; u < dst1->sy; u++) { if (dTan >= 0.0) { dShear = ((double)(u + 0.5)) * dTan; @@ -433,22 +417,13 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int igno newy = (int) ((double) src->sx * fabs( dSinE ) + (double) src->sy * cos (dRadAngle))+1; - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } dst2 = gdImageCreateTrueColor(newx, newy); if (dst2 == NULL) { gdImageDestroy(dst1); return NULL; } -#ifdef HAVE_GD_BUNDLED - dst2->alphaBlendingFlag = gdEffectReplace; -#else gdImageAlphaBlending(dst2, 0); -#endif if (ignoretransparent) { dst2->transparent = dst1->transparent; @@ -465,22 +440,13 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int igno newx = (int) ((double)src->sy * fabs (dSinE) + (double)src->sx * cos (dRadAngle)) + 1; newy = dst2->sy; - if (src->trueColor) { - f = gdImageGetTrueColorPixel; - } else { - f = gdImageGetPixel; - } dst3 = gdImageCreateTrueColor(newx, newy); if (dst3 == NULL) { gdImageDestroy(dst2); return NULL; } -#ifdef HAVE_GD_BUNDLED - dst3->alphaBlendingFlag = gdEffectReplace; -#else gdImageAlphaBlending(dst3, 0); -#endif if (ignoretransparent) { dst3->transparent = dst2->transparent; diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c index 897c302539..3813707ade 100644 --- a/ext/gd/libgd/gd_security.c +++ b/ext/gd/libgd/gd_security.c @@ -16,15 +16,16 @@ #include <stdlib.h> #include <limits.h> #include "gd.h" +#include "gd_errors.h" int overflow2(int a, int b) { if(a <= 0 || b <= 0) { - php_gd_error("gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n"); + gd_error("gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n"); return 1; } if(a > INT_MAX / b) { - php_gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); + gd_error("gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n"); return 1; } return 0; diff --git a/ext/gd/libgd/gd_ss.c b/ext/gd/libgd/gd_ss.c index 08edea3eca..048ac0a700 100644 --- a/ext/gd/libgd/gd_ss.c +++ b/ext/gd/libgd/gd_ss.c @@ -38,11 +38,11 @@ gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) #else /* no HAVE_LIBPNG */ void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) { - php_gd_error("PNG support is not available"); + gd_error("PNG support is not available"); } gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource) { - php_gd_error("PNG support is not available"); + gd_error("PNG support is not available"); return NULL; } #endif /* HAVE_LIBPNG */ diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c index 896c3cb948..a92a7acb17 100644 --- a/ext/gd/libgd/gd_topal.c +++ b/ext/gd/libgd/gd_topal.c @@ -28,26 +28,12 @@ * fundamental assumptions even hold with an irregularly spaced color map. */ -#ifdef ORIGINAL_LIB_JPEG - -#define JPEG_INTERNALS - -#include "jinclude.h" -#include "jpeglib.h" - -#else - /* * THOMAS BOUTELL & BAREND GEHRELS, february 2003 * adapted the code to work within gd rather than within libjpeg. * If it is not working, it's not Thomas G. Lane's fault. */ -/* - SETTING THIS ONE CAUSES STRIPED IMAGE - to be done: solve this - #define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS - */ #include <string.h> #include "gd.h" @@ -130,8 +116,6 @@ #define input_buf (oim->tpixels) #define output_buf (nim->pixels) -#endif - #ifdef QUANT_2PASS_SUPPORTED @@ -303,15 +287,6 @@ typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ typedef struct { -#ifdef ORIGINAL_LIB_JPEG - struct jpeg_color_quantizer pub; /* public fields */ - - /* Space for the eventually created colormap is stashed here */ - JSAMPARRAY sv_colormap; /* colormap allocated at init time */ - int desired; /* desired # of colors = size of colormap */ - boolean needs_zeroed; /* TRUE if next pass must zero histogram */ -#endif - /* Variables for accumulating image statistics */ hist3d histogram; /* pointer to the histogram */ @@ -321,9 +296,7 @@ typedef struct boolean on_odd_row; /* flag to remember which row we are on */ int *error_limiter; /* table for clamping the applied error */ -#ifndef ORIGINAL_LIB_JPEG int *error_limiter_storage; /* gdMalloc'd storage for the above */ -#endif } my_cquantizer; @@ -340,37 +313,21 @@ typedef my_cquantizer *my_cquantize_ptr; */ METHODDEF (void) -#ifndef ORIGINAL_LIB_JPEG prescan_quantize (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) { -#else -prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; -#endif register JSAMPROW ptr; register histptr histp; register hist3d histogram = cquantize->histogram; int row; JDIMENSION col; -#ifdef ORIGINAL_LIB_JPEG - JDIMENSION width = cinfo->output_width; -#else int width = oim->sx; int num_rows = oim->sy; -#endif for (row = 0; row < num_rows; row++) { ptr = input_buf[row]; for (col = width; col > 0; col--) { -#ifdef ORIGINAL_LIB_JPEG - int r = GETJSAMPLE (ptr[0]) >> C0_SHIFT; - int g = GETJSAMPLE (ptr[1]) >> C1_SHIFT; - int b = GETJSAMPLE (ptr[2]) >> C2_SHIFT; -#else int r = gdTrueColorGetRed (*ptr) >> C0_SHIFT; int g = gdTrueColorGetGreen (*ptr) >> C1_SHIFT; int b = gdTrueColorGetBlue (*ptr) >> C2_SHIFT; @@ -381,17 +338,12 @@ prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, ptr++; continue; } -#endif /* get pixel value and index into the histogram */ histp = &histogram[r][g][b]; /* increment, check for overflow and undo increment if so. */ if (++(*histp) == 0) (*histp)--; -#ifdef ORIGINAL_LIB_JPEG - ptr += 3; -#else ptr++; -#endif } } } @@ -463,16 +415,8 @@ LOCAL (boxptr) find_biggest_volume (boxptr boxlist, int numboxes) LOCAL (void) -#ifndef ORIGINAL_LIB_JPEG update_box (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp) { -#else - update_box (j_decompress_ptr cinfo, boxptr boxp) -/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ -/* and recompute its volume and population */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; -#endif hist3d histogram = cquantize->histogram; histptr histp; int c0, c1, c2; @@ -596,13 +540,8 @@ have_c2max: LOCAL (int) -#ifdef ORIGINAL_LIB_JPEG -median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, - int desired_colors) -#else median_cut (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxlist, int numboxes, int desired_colors) -#endif /* Repeatedly select and split the largest box until we have enough boxes */ { int n, lb; @@ -692,13 +631,8 @@ median_cut (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, break; } /* Update stats for boxes */ -#ifdef ORIGINAL_LIB_JPEG - update_box (cinfo, b1); - update_box (cinfo, b2); -#else update_box (oim, nim, cquantize, b1); update_box (oim, nim, cquantize, b2); -#endif numboxes++; } return numboxes; @@ -706,18 +640,12 @@ median_cut (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, LOCAL (void) -#ifndef ORIGINAL_LIB_JPEG compute_color (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp, int icolor) -{ -#else - compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) /* Compute representative color for a box, put it in colormap[icolor] */ { /* Current algorithm: mean weighted by pixels (not colors) */ /* Note it is important to get the rounding correct! */ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; -#endif hist3d histogram = cquantize->histogram; histptr histp; int c0, c1, c2; @@ -754,11 +682,6 @@ LOCAL (void) } } -#ifdef ORIGINAL_LIB_JPEG - cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total >> 1)) / total); - cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total >> 1)) / total); - cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total >> 1)) / total); -#else /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */ if (total) { @@ -773,16 +696,11 @@ LOCAL (void) nim->blue[icolor] = 255; } nim->open[icolor] = 0; -#endif } LOCAL (void) -#ifdef ORIGINAL_LIB_JPEG -select_colors (j_decompress_ptr cinfo, int desired_colors) -#else select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors) -#endif /* Master routine for color selection */ { boxptr boxlist; @@ -790,12 +708,7 @@ select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int d int i; /* Allocate workspace for box list */ -#ifdef ORIGINAL_LIB_JPEG - boxlist = (boxptr) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF (box)); -#else boxlist = (boxptr) safe_emalloc(desired_colors, sizeof (box), 1); -#endif /* Initialize one box containing whole space */ numboxes = 1; boxlist[0].c0min = 0; @@ -804,17 +717,6 @@ select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int d boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; boxlist[0].c2min = 0; boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; -#ifdef ORIGINAL_LIB_JPEG - /* Shrink it to actually-used volume and set its statistics */ - update_box (cinfo, &boxlist[0]); - /* Perform median-cut to produce final box list */ - numboxes = median_cut (cinfo, boxlist, numboxes, desired_colors); - /* Compute the representative color for each box, fill colormap */ - for (i = 0; i < numboxes; i++) - compute_color (cinfo, &boxlist[i], i); - cinfo->actual_number_of_colors = numboxes; - TRACEMS1 (cinfo, 1, JTRC_QUANT_SELECTED, numboxes); -#else /* Shrink it to actually-used volume and set its statistics */ update_box (oim, nim, cquantize, &boxlist[0]); /* Perform median-cut to produce final box list */ @@ -839,7 +741,6 @@ select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int d } gdFree (boxlist); -#endif } @@ -921,11 +822,7 @@ select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int d LOCAL (int) find_nearby_colors ( -#ifdef ORIGINAL_LIB_JPEG - j_decompress_ptr cinfo, -#else gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, -#endif int minc0, int minc1, int minc2, JSAMPLE colorlist[]) /* Locate the colormap entries close enough to an update box to be candidates * for the nearest entry to some cell(s) in the update box. The update box @@ -936,11 +833,7 @@ find_nearby_colors ( * the colors that need further consideration. */ { -#ifdef ORIGINAL_LIB_JPEG - int numcolors = cinfo->actual_number_of_colors; -#else int numcolors = nim->colorsTotal; -#endif int maxc0, maxc1, maxc2; int centerc0, centerc1, centerc2; int i, x, ncolors; @@ -973,11 +866,7 @@ find_nearby_colors ( for (i = 0; i < numcolors; i++) { /* We compute the squared-c0-distance term, then add in the other two. */ -#ifdef ORIGINAL_LIB_JPEG - x = GETJSAMPLE (cinfo->colormap[0][i]); -#else x = nim->red[i]; -#endif if (x < minc0) { tdist = (x - minc0) * C0_SCALE; @@ -1008,11 +897,7 @@ find_nearby_colors ( } } -#ifdef ORIGINAL_LIB_JPEG - x = GETJSAMPLE (cinfo->colormap[1][i]); -#else x = nim->green[i]; -#endif if (x < minc1) { tdist = (x - minc1) * C1_SCALE; @@ -1042,11 +927,7 @@ find_nearby_colors ( } } -#ifdef ORIGINAL_LIB_JPEG - x = GETJSAMPLE (cinfo->colormap[2][i]); -#else x = nim->blue[i]; -#endif if (x < minc2) { tdist = (x - minc2) * C2_SCALE; @@ -1096,11 +977,7 @@ find_nearby_colors ( LOCAL (void) find_best_colors ( -#ifdef ORIGINAL_LIB_JPEG - j_decompress_ptr cinfo, -#else gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, -#endif int minc0, int minc1, int minc2, int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) @@ -1141,18 +1018,10 @@ LOCAL (void) find_best_colors ( for (i = 0; i < numcolors; i++) { int r, g, b; -#ifdef ORIGINAL_LIB_JPEG - - icolor = GETJSAMPLE (colorlist[i]); - r = GETJSAMPLE (cinfo->colormap[0][icolor]); - g = GETJSAMPLE (cinfo->colormap[1][icolor]); - b = GETJSAMPLE (cinfo->colormap[2][icolor]); -#else icolor = colorlist[i]; r = nim->red[icolor]; g = nim->green[icolor]; b = nim->blue[icolor]; -#endif /* Compute (square of) distance from minc0/c1/c2 to this color */ inc0 = (minc0 - r) * C0_SCALE; @@ -1201,19 +1070,12 @@ LOCAL (void) find_best_colors ( LOCAL (void) fill_inverse_cmap ( -#ifdef ORIGINAL_LIB_JPEG - j_decompress_ptr cinfo, -#else gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, -#endif int c0, int c1, int c2) /* Fill the inverse-colormap entries in the update box that contains */ /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ /* we can fill as many others as we wish.) */ { -#ifdef ORIGINAL_LIB_JPEG - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; -#endif hist3d histogram = cquantize->histogram; int minc0, minc1, minc2; /* lower left corner of update box */ int ic0, ic1, ic2; @@ -1241,18 +1103,10 @@ fill_inverse_cmap ( /* Determine which colormap entries are close enough to be candidates * for the nearest entry to some cell in the update box. */ -#ifdef ORIGINAL_LIB_JPEG - numcolors = find_nearby_colors (cinfo, minc0, minc1, minc2, colorlist); - - /* Determine the actually nearest colors. */ - find_best_colors (cinfo, minc0, minc1, minc2, numcolors, colorlist, - bestcolor); -#else numcolors = find_nearby_colors (oim, nim, cquantize, minc0, minc1, minc2, colorlist); find_best_colors (oim, nim, cquantize, minc0, minc1, minc2, numcolors, colorlist, bestcolor); -#endif /* Save the best color numbers (plus 1) in the main cache array */ c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ @@ -1266,11 +1120,7 @@ fill_inverse_cmap ( cachep = &histogram[c0 + ic0][c1 + ic1][c2]; for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { -#ifdef ORIGINAL_LIB_JPEG - *cachep++ = (histcell) (GETJSAMPLE (*cptr++) + 1); -#else *cachep++ = (histcell) ((*cptr++) + 1); -#endif } } } @@ -1282,22 +1132,12 @@ fill_inverse_cmap ( */ METHODDEF (void) -#ifndef ORIGINAL_LIB_JPEG pass2_no_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) { register int *inptr; register unsigned char *outptr; int width = oim->sx; int num_rows = oim->sy; -#else -pass2_no_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register JSAMPROW inptr, outptr; - JDIMENSION width = cinfo->output_width; -#endif hist3d histogram = cquantize->histogram; register int c0, c1, c2; int row; @@ -1313,11 +1153,6 @@ pass2_no_dither (j_decompress_ptr cinfo, { /* get pixel value and index into the cache */ int r, g, b; -#ifdef ORIGINAL_LIB_JPEG - r = GETJSAMPLE (*inptr++); - g = GETJSAMPLE (*inptr++); - b = GETJSAMPLE (*inptr++); -#else r = gdTrueColorGetRed (*inptr); g = gdTrueColorGetGreen (*inptr); /* @@ -1336,7 +1171,6 @@ pass2_no_dither (j_decompress_ptr cinfo, continue; } inptr++; -#endif c0 = r >> C0_SHIFT; c1 = g >> C1_SHIFT; c2 = b >> C2_SHIFT; @@ -1344,34 +1178,17 @@ pass2_no_dither (j_decompress_ptr cinfo, /* If we have not seen this color before, find nearest colormap entry */ /* and update the cache */ if (*cachep == 0) -#ifdef ORIGINAL_LIB_JPEG - fill_inverse_cmap (cinfo, c0, c1, c2); -#else fill_inverse_cmap (oim, nim, cquantize, c0, c1, c2); -#endif /* Now emit the colormap index for this cell */ -#ifdef ORIGINAL_LIB_JPEG - *outptr++ = (JSAMPLE) (*cachep - 1); -#else *outptr++ = (*cachep - 1); -#endif } } } METHODDEF (void) -#ifndef ORIGINAL_LIB_JPEG pass2_fs_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) { -#else -pass2_fs_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs Floyd-Steinberg dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPROW inptr; /* => current input pixel */ -#endif hist3d histogram = cquantize->histogram; register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ @@ -1382,14 +1199,6 @@ pass2_fs_dither (j_decompress_ptr cinfo, int dir3; /* 3*dir, for advancing inptr & errorptr */ int row; JDIMENSION col; -#ifdef ORIGINAL_LIB_JPEG - JSAMPROW outptr; /* => current output pixel */ - JDIMENSION width = cinfo->output_width; - JSAMPLE *range_limit = cinfo->sample_range_limit; - JSAMPROW colormap0 = cinfo->colormap[0]; - JSAMPROW colormap1 = cinfo->colormap[1]; - JSAMPROW colormap2 = cinfo->colormap[2]; -#else int *inptr; /* => current input pixel */ unsigned char *outptr; /* => current output pixel */ int width = oim->sx; @@ -1397,7 +1206,6 @@ pass2_fs_dither (j_decompress_ptr cinfo, int *colormap0 = nim->red; int *colormap1 = nim->green; int *colormap2 = nim->blue; -#endif int *error_limit = cquantize->error_limiter; @@ -1413,9 +1221,6 @@ pass2_fs_dither (j_decompress_ptr cinfo, dir = -1; dir3 = -3; errorptr = cquantize->fserrors + (width + 1) * 3; /* => entry after last column */ -#ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS - cquantize->on_odd_row = FALSE; /* flip for next time */ -#endif } else { @@ -1423,9 +1228,6 @@ pass2_fs_dither (j_decompress_ptr cinfo, dir = 1; dir3 = 3; errorptr = cquantize->fserrors; /* => entry before first real column */ -#ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS - cquantize->on_odd_row = TRUE; /* flip for next time */ -#endif } /* Preset error values: no error propagated to first pixel from left */ cur0 = cur1 = cur2 = 0; @@ -1472,21 +1274,12 @@ pass2_fs_dither (j_decompress_ptr cinfo, * The maximum error is +- MAXJSAMPLE (or less with error limiting); * this sets the required size of the range_limit array. */ -#ifdef ORIGINAL_LIB_JPEG - cur0 += GETJSAMPLE (inptr[0]); - cur1 += GETJSAMPLE (inptr[1]); - cur2 += GETJSAMPLE (inptr[2]); - cur0 = GETJSAMPLE (range_limit[cur0]); - cur1 = GETJSAMPLE (range_limit[cur1]); - cur2 = GETJSAMPLE (range_limit[cur2]); -#else cur0 += gdTrueColorGetRed (*inptr); cur1 += gdTrueColorGetGreen (*inptr); cur2 += gdTrueColorGetBlue (*inptr); range_limit (cur0); range_limit (cur1); range_limit (cur2); -#endif /* Index into the cache with adjusted pixel value */ cachep = @@ -1494,13 +1287,8 @@ pass2_fs_dither (j_decompress_ptr cinfo, /* If we have not seen this color before, find nearest colormap */ /* entry and update the cache */ if (*cachep == 0) -#ifdef ORIGINAL_LIB_JPEG - fill_inverse_cmap (cinfo, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, - cur2 >> C2_SHIFT); -#else fill_inverse_cmap (oim, nim, cquantize, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT); -#endif /* Now emit the colormap index for this cell */ { register int pixcode = *cachep - 1; @@ -1548,11 +1336,7 @@ pass2_fs_dither (j_decompress_ptr cinfo, * to the next pixel on the current line, and all the errors for the * next line have been shifted over. We are therefore ready to move on. */ -#ifdef ORIGINAL_LIB_JPEG - inptr += dir3; /* Advance pixel pointers to next column */ -#else inptr += dir; /* Advance pixel pointers to next column */ -#endif outptr += dir; errorptr += dir3; /* advance errorptr to current column */ } @@ -1585,20 +1369,12 @@ pass2_fs_dither (j_decompress_ptr cinfo, */ LOCAL (void) -#ifdef ORIGINAL_LIB_JPEG -init_error_limit (j_decompress_ptr cinfo) -#else init_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) -#endif /* Allocate and fill in the error_limiter table */ { int *table; int in, out; -#ifdef ORIGINAL_LIB_JPEG - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - table = (int *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * SIZEOF (int)); -#else + cquantize->error_limiter_storage = (int *) safe_emalloc ((MAXJSAMPLE * 2 + 1), sizeof (int), 0); if (!cquantize->error_limiter_storage) @@ -1606,7 +1382,6 @@ init_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) return; } table = cquantize->error_limiter_storage; -#endif table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ cquantize->error_limiter = table; @@ -1639,108 +1414,6 @@ init_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize) * Finish up at the end of each pass. */ -#ifdef ORIGINAL_LIB_JPEG -METHODDEF (void) -finish_pass1 (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Select the representative colors and fill in cinfo->colormap */ - cinfo->colormap = cquantize->sv_colormap; - select_colors (cinfo, cquantize->desired); - /* Force next pass to zero the color index table */ - cquantize->needs_zeroed = TRUE; -} - - -METHODDEF (void) -finish_pass2 (j_decompress_ptr cinfo) -{ - /* no work */ -} - -/* - * Initialize for each processing pass. - */ - -METHODDEF (void) -start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - int i; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - if (is_pre_scan) - { - /* Set up method pointers */ - cquantize->pub.color_quantize = prescan_quantize; - cquantize->pub.finish_pass = finish_pass1; - cquantize->needs_zeroed = TRUE; /* Always zero histogram */ - } - else - { - /* Set up method pointers */ - if (cinfo->dither_mode == JDITHER_FS) - cquantize->pub.color_quantize = pass2_fs_dither; - else - cquantize->pub.color_quantize = pass2_no_dither; - cquantize->pub.finish_pass = finish_pass2; - - /* Make sure color count is acceptable */ - i = cinfo->actual_number_of_colors; - if (i < 1) - ERREXIT1 (cinfo, JERR_QUANT_FEW_COLORS, 1); - if (i > MAXNUMCOLORS) - ERREXIT1 (cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - - if (cinfo->dither_mode == JDITHER_FS) - { - size_t arraysize = (size_t) ((cinfo->output_width + 2) * - (3 * SIZEOF (FSERROR))); - /* Allocate Floyd-Steinberg workspace if we didn't already. */ - if (cquantize->fserrors == NULL) - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); - /* Initialize the propagated errors to zero. */ - jzero_far ((void FAR *) cquantize->fserrors, arraysize); - /* Make the error-limit table if we didn't already. */ - if (cquantize->error_limiter == NULL) - init_error_limit (cinfo); - cquantize->on_odd_row = FALSE; - } - - } - /* Zero the histogram or inverse color map, if necessary */ - if (cquantize->needs_zeroed) - { - for (i = 0; i < HIST_C0_ELEMS; i++) - { - jzero_far ((void FAR *) histogram[i], - HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell)); - } - cquantize->needs_zeroed = FALSE; - } -} - - -/* - * Switch to a new external colormap between output passes. - */ - -METHODDEF (void) -new_color_map_2_quant (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Reset the inverse color map */ - cquantize->needs_zeroed = TRUE; -} -#else static void zeroHistogram (hist3d histogram) { @@ -1752,37 +1425,45 @@ zeroHistogram (hist3d histogram) 0, HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof (histcell)); } } -#endif -static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP); +static int gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP); gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int dither, int colorsWanted) { gdImagePtr nim; - gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim); - return nim; + if (TRUE == gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim)) { + return nim; + } + return NULL; } -void gdImageTrueColorToPalette (gdImagePtr im, int dither, int colorsWanted) +int gdImageTrueColorToPalette (gdImagePtr im, int dither, int colorsWanted) { - gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0); + return gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0); +} + +static void free_truecolor_image_data(gdImagePtr oim) +{ + int i; + oim->trueColor = 0; + /* Junk the truecolor pixels */ + for (i = 0; i < oim->sy; i++) + { + gdFree (oim->tpixels[i]); + } + gdFree (oim->tpixels); + oim->tpixels = 0; } /* * Module initialization routine for 2-pass color quantization. */ -#ifdef ORIGINAL_LIB_JPEG -GLOBAL (void) -jinit_2pass_quantizer (j_decompress_ptr cinfo) -#else -static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP) -#endif +static int gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP) { my_cquantize_ptr cquantize = NULL; - int i; + int i, conversionSucceeded=0; -#ifndef ORIGINAL_LIB_JPEG /* Allocate the JPEG palette-storage */ size_t arraysize; int maxColors = gdMaxColors; @@ -1791,7 +1472,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color nim = gdImageCreate(oim->sx, oim->sy); *cimP = nim; if (!nim) { - return; + return FALSE; } } else { nim = oim; @@ -1803,7 +1484,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color gdImageCopy(nim, oim, 0, 0, 0, 0, oim->sx, oim->sy); *cimP = nim; } - return; + return TRUE; } /* If we have a transparent color (the alphaless mode of transparency), we @@ -1832,42 +1513,18 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color } } } -#endif -#ifdef ORIGINAL_LIB_JPEG - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF (my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; - cquantize->pub.start_pass = start_pass_2_quant; - cquantize->pub.new_color_map = new_color_map_2_quant; - /* Make sure jdmaster didn't give me a case I can't handle */ - if (cinfo->out_color_components != 3) - ERREXIT (cinfo, JERR_NOTIMPL); -#else cquantize = (my_cquantize_ptr) gdCalloc (sizeof (my_cquantizer), 1); if (!cquantize) { /* No can do */ goto outOfMemory; } -#endif cquantize->fserrors = NULL; /* flag optional arrays not allocated */ cquantize->error_limiter = NULL; /* Allocate the histogram/inverse colormap storage */ -#ifdef ORIGINAL_LIB_JPEG - cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF (hist2d)); - for (i = 0; i < HIST_C0_ELEMS; i++) - { - cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell)); - } - cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ -#else cquantize->histogram = (hist3d) safe_emalloc (HIST_C0_ELEMS, sizeof (hist2d), 0); for (i = 0; i < HIST_C0_ELEMS; i++) { @@ -1878,50 +1535,6 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color goto outOfMemory; } } -#endif - -#ifdef ORIGINAL_LIB_JPEG - /* Allocate storage for the completed colormap, if required. - * We do this now since it is FAR storage and may affect - * the memory manager's space calculations. - */ - if (cinfo->enable_2pass_quant) - { - /* Make sure color count is acceptable */ - int desired = cinfo->desired_number_of_colors; - /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ - if (desired < 8) - ERREXIT1 (cinfo, JERR_QUANT_FEW_COLORS, 8); - /* Make sure colormap indexes can be represented by JSAMPLEs */ - if (desired > MAXNUMCOLORS) - ERREXIT1 (cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) desired, - (JDIMENSION) 3); - cquantize->desired = desired; - } - else - cquantize->sv_colormap = NULL; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - /* Allocate Floyd-Steinberg workspace if necessary. - * This isn't really needed until pass 2, but again it is FAR storage. - * Although we will cope with a later change in dither_mode, - * we do not promise to honor max_memory_to_use if dither_mode changes. - */ - if (cinfo->dither_mode == JDITHER_FS) - { - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF (FSERROR)))); - /* Might as well create the error-limiting table too. */ - init_error_limit (cinfo); - } -#else cquantize->fserrors = (FSERRPTR) safe_emalloc (3, sizeof (FSERROR), 0); init_error_limit (oim, nim, cquantize); @@ -2004,19 +1617,16 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color } /* Success! Get rid of the truecolor image data. */ - if (!cimP) { - oim->trueColor = 0; - /* Junk the truecolor pixels */ - for (i = 0; i < oim->sy; i++) - { - gdFree (oim->tpixels[i]); - } - gdFree (oim->tpixels); - oim->tpixels = 0; - } - goto success; + conversionSucceeded = TRUE; + if (!cimP) + { + free_truecolor_image_data(oim); + } + + goto freeQuantizeData; /* Tediously free stuff. */ outOfMemory: + conversionSucceeded = FALSE; if (oim->trueColor) { if (!cimP) { @@ -2038,7 +1648,7 @@ outOfMemory: *cimP = 0; } } -success: +freeQuantizeData: for (i = 0; i < HIST_C0_ELEMS; i++) { if (cquantize->histogram[i]) @@ -2062,8 +1672,7 @@ success: { gdFree (cquantize); } - -#endif + return conversionSucceeded; } diff --git a/ext/gd/libgd/gd_wbmp.c b/ext/gd/libgd/gd_wbmp.c index b81eed80e7..7b946aad2f 100644 --- a/ext/gd/libgd/gd_wbmp.c +++ b/ext/gd/libgd/gd_wbmp.c @@ -53,6 +53,7 @@ #include <gd.h> #include <gdfonts.h> +#include <gd_errors.h> #include <stdio.h> #include <stdlib.h> #include <limits.h> @@ -98,7 +99,7 @@ void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out) /* create the WBMP */ if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL) { - php_gd_error("Could not create WBMP"); + gd_error("Could not create WBMP"); } /* fill up the WBMP structure */ @@ -114,7 +115,7 @@ void gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out) /* write the WBMP to a gd file descriptor */ if (writewbmp (wbmp, &gd_putout, out)) { - php_gd_error("Could not save WBMP"); + gd_error("Could not save WBMP"); } /* des submitted this bugfix: gdFree the memory. */ freewbmp(wbmp); diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/gd_xbm.c index b351814abb..be3cce73b4 100644 --- a/ext/gd/libgd/xbm.c +++ b/ext/gd/libgd/gd_xbm.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include "gd.h" #include "gdhelpers.h" +#include "gd_errors.h" #include "php.h" @@ -149,7 +150,7 @@ gdImagePtr gdImageCreateFromXbm(FILE * fd) } } - php_gd_error("EOF before image was complete"); + gd_error("EOF before image was complete"); gdImageDestroy(im); return 0; } diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 6de24f883c..d68703aa32 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -626,6 +626,7 @@ static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, { unsigned char *pixel = NULL; int *tpixel = NULL; + int opixel; int x, y, row, col, pc, pcr; tweencolor_t *tc_elem; @@ -683,7 +684,13 @@ static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, } } else { if (im->alphaBlendingFlag) { - *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF)); + opixel = *tpixel; + if (gdTrueColorGetAlpha(opixel) != gdAlphaTransparent) { + *tpixel = gdAlphaBlend (opixel, + (level << 24) + (fg & 0xFFFFFF)); + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } } else { *tpixel = (level << 24) + (fg & 0xFFFFFF); } diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index 768fde93b8..afb45f0e67 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -42,5 +42,10 @@ int overflow2(int a, int b); #define gdMutexUnlock(x) #endif +#define DPCM2DPI(dpcm) (unsigned int)((dpcm)*2.54 + 0.5) +#define DPM2DPI(dpm) (unsigned int)((dpm)*0.0254 + 0.5) +#define DPI2DPCM(dpi) (unsigned int)((dpi)/2.54 + 0.5) +#define DPI2DPM(dpi) (unsigned int)((dpi)/0.0254 + 0.5) + #endif /* GDHELPERS_H */ diff --git a/ext/gd/libgd/mathmake.c b/ext/gd/libgd/mathmake.c deleted file mode 100644 index 3950c4b09c..0000000000 --- a/ext/gd/libgd/mathmake.c +++ /dev/null @@ -1,52 +0,0 @@ -#include <stdio.h> -#include <math.h> - -#define scale 1024 - -int basis[91]; -int cost[360]; - -main (void) -{ - int i; - printf ("#define costScale %d\n", scale); - printf ("int cost[] = {\n "); - for (i = 0; (i <= 90); i++) - { - basis[i] = cos ((double) i * .0174532925) * scale; - } - for (i = 0; (i < 90); i++) - { - printf ("%d,\n ", cost[i] = basis[i]); - } - for (i = 90; (i < 180); i++) - { - printf ("%d,\n ", cost[i] = -basis[180 - i]); - } - for (i = 180; (i < 270); i++) - { - printf ("%d,\n ", cost[i] = -basis[i - 180]); - } - for (i = 270; (i < 359); i++) - { - printf ("%d,\n ", cost[i] = basis[360 - i]); - } - printf ("%d\n", cost[359] = basis[1]); - printf ("};\n"); - printf ("#define sintScale %d\n", scale); - printf ("int sint[] = {\n "); - for (i = 0; (i < 360); i++) - { - int val; - val = cost[(i + 270) % 360]; - if (i != 359) - { - printf ("%d,\n ", val); - } - else - { - printf ("%d\n", val); - } - } - printf ("};\n"); -} diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 19e7063d9c..746cdff7b0 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -123,9 +123,7 @@ PHP_FUNCTION(imagerotate); PHP_FUNCTION(imageflip); -#ifdef HAVE_GD_BUNDLED PHP_FUNCTION(imageantialias); -#endif PHP_FUNCTION(imagecrop); PHP_FUNCTION(imagecropauto); @@ -176,12 +174,15 @@ PHP_FUNCTION(imageinterlace); PHP_FUNCTION(imageline); PHP_FUNCTION(imageloadfont); PHP_FUNCTION(imagepolygon); +PHP_FUNCTION(imageopenpolygon); PHP_FUNCTION(imagerectangle); PHP_FUNCTION(imagesetpixel); PHP_FUNCTION(imagestring); PHP_FUNCTION(imagestringup); PHP_FUNCTION(imagesx); PHP_FUNCTION(imagesy); +PHP_FUNCTION(imagesetclip); +PHP_FUNCTION(imagegetclip); PHP_FUNCTION(imagedashedline); PHP_FUNCTION(imagettfbbox); PHP_FUNCTION(imagettftext); @@ -198,6 +199,8 @@ PHP_FUNCTION(imagexbm); PHP_FUNCTION(imagefilter); PHP_FUNCTION(imageconvolution); +PHP_FUNCTION(imageresolution); + PHP_GD_API int phpi_get_le_gd(void); #else diff --git a/ext/gd/tests/bug28147.phpt b/ext/gd/tests/bug28147.phpt index de5c9022ad..fc5f37c5a0 100644 --- a/ext/gd/tests/bug28147.phpt +++ b/ext/gd/tests/bug28147.phpt @@ -3,7 +3,6 @@ Bug #28147 (Crash with anti-aliased line) --SKIPIF-- <?php if (!extension_loaded('gd')) die("skip gd extension not available\n"); - if (!function_exists("imageantialias")) die("skip requires bundled GD library\n"); ?> --FILE-- <?php diff --git a/ext/gd/tests/bug42434.phpt b/ext/gd/tests/bug42434.phpt index bc0790ede4..cede1ac17f 100644 --- a/ext/gd/tests/bug42434.phpt +++ b/ext/gd/tests/bug42434.phpt @@ -5,7 +5,6 @@ Bug #42434 (ImageLine w/ antialias = 1px shorter) if (!extension_loaded('gd')) {
die('skip gd extension not available');
}
-if (!GD_BUNDLED) die("skip requires bundled GD library\n");
?>
--FILE--
<?php
diff --git a/ext/gd/tests/bug72604.phpt b/ext/gd/tests/bug72604.phpt index f9592c05b7..5cbaba7504 100644 --- a/ext/gd/tests/bug72604.phpt +++ b/ext/gd/tests/bug72604.phpt @@ -3,7 +3,6 @@ Bug #72604 (imagearc() ignores thickness for full arcs) --SKIPIF-- <?php if (!extension_loaded('gd')) die('skip requires ext/gd'); -if (!(imagetypes() & IMG_PNG)) die('skip requires PNG support'); ?> --FILE-- <?php diff --git a/ext/gd/tests/imageantialias_error1.phpt b/ext/gd/tests/imageantialias_error1.phpt index e9475e9571..53fe0cc66a 100644 --- a/ext/gd/tests/imageantialias_error1.phpt +++ b/ext/gd/tests/imageantialias_error1.phpt @@ -6,7 +6,6 @@ Guilherme Blanco <guilhermeblanco [at] hotmail [dot] com> --SKIPIF-- <?php if (!extension_loaded("gd")) die("skip GD not present"); -if (!GD_BUNDLED) die("skip requires bundled GD library\n"); ?> --FILE-- <?php diff --git a/ext/gd/tests/imageantialias_error2.phpt b/ext/gd/tests/imageantialias_error2.phpt index 64b0a60eba..8dad8bd115 100644 --- a/ext/gd/tests/imageantialias_error2.phpt +++ b/ext/gd/tests/imageantialias_error2.phpt @@ -6,7 +6,6 @@ Guilherme Blanco <guilhermeblanco [at] hotmail [dot] com> --SKIPIF-- <?php if (!extension_loaded("gd")) die("skip GD not present"); -if (!GD_BUNDLED) die("skip requires bundled GD library\n"); ?> --FILE-- <?php diff --git a/ext/gd/tests/imagecopyresampled_basic.phpt b/ext/gd/tests/imagecopyresampled_basic.phpt index fd96ab6928..edf7ba6548 100644 --- a/ext/gd/tests/imagecopyresampled_basic.phpt +++ b/ext/gd/tests/imagecopyresampled_basic.phpt @@ -3,7 +3,6 @@ imagecopyresampled() --SKIPIF-- <?php if (!function_exists('imagecopyresampled')) die('skip imagecopyresampled() not available'); - if (!(imagetype() & IMG_PNG)) die('skip PNG Support is not enabled'); ?> --FILE-- <?php diff --git a/ext/gd/tests/imagedashedline_basic.phpt b/ext/gd/tests/imagedashedline_basic.phpt index be65af66d0..35525f57bc 100644 --- a/ext/gd/tests/imagedashedline_basic.phpt +++ b/ext/gd/tests/imagedashedline_basic.phpt @@ -3,7 +3,6 @@ imagedashedline() --SKIPIF-- <?php if (!function_exists('imagedashedline')) die('skip imagedashedline() not available'); - if (!(imagetype() & IMG_PNG)) die('skip PNG Support is not enabled'); ?> --FILE-- <?php diff --git a/ext/gd/tests/imagefilledpolygon_basic.phpt b/ext/gd/tests/imagefilledpolygon_basic.phpt index ded52da07b..b957cce698 100644 --- a/ext/gd/tests/imagefilledpolygon_basic.phpt +++ b/ext/gd/tests/imagefilledpolygon_basic.phpt @@ -3,7 +3,6 @@ imagefilledpolygon() --SKIPIF-- <?php if (!function_exists('imagefilledpolygon')) die('skip imagefilledpolygon() not available'); - if (!(imagetype() & IMG_PNG)) die('skip PNG Support is not enabled'); ?> --FILE-- <?php diff --git a/ext/gd/tests/imagegammacorrect_variation2.phpt b/ext/gd/tests/imagegammacorrect_variation2.phpt new file mode 100644 index 0000000000..4a317b5d90 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_variation2.phpt @@ -0,0 +1,72 @@ +--TEST--
+Apply imagegammacorrect() to a step wedge
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+test_gamma_both(1, 2);
+test_gamma_both(1, 1);
+test_gamma_both(2, 1);
+
+function test_gamma_both($in, $out)
+{
+ test_gamma($in, $out, 'imagecreate');
+ test_gamma($in, $out, 'imagecreatetruecolor');
+}
+
+function test_gamma($in, $out, $constructor)
+{
+ $im = $constructor(640, 480);
+ for ($j = 0; $j < 4; $j++) {
+ for ($i = 0; $i < 32; $i++) {
+ draw_cell($im, $i, $j);
+ }
+ }
+
+ imagegammacorrect($im, $in, $out);
+
+ $filename = __DIR__ . DIRECTORY_SEPARATOR
+ . "imagegammacorrect_variation2_{$in}_{$out}.png";
+ $kind = $constructor === 'imagecreate' ? 'palette' : 'truecolor';
+ echo "$kind gamma ($in, $out): ";
+ test_image_equals_file($filename, $im);
+}
+
+function draw_cell($im, $x, $y)
+{
+ $x1 = 20 * $x;
+ $y1 = 120 * $y;
+ $x2 = $x1 + 19;
+ $y2 = $y1 + 119;
+ $color = cell_color($im, $x, $y);
+ imagefilledrectangle($im, $x1,$y1, $x2,$y2, $color);
+}
+
+function cell_color($im, $x, $y)
+{
+ $channel = 8 * $x + 4;
+ switch ($y) {
+ case 0:
+ return imagecolorallocate($im, $channel, $channel, $channel);
+ case 1:
+ return imagecolorallocate($im, $channel, 0, 0);
+ case 2:
+ return imagecolorallocate($im, 0, $channel, 0);
+ case 3:
+ return imagecolorallocate($im, 0, 0, $channel);
+ }
+}
+?>
+===DONE===
+--EXPECT--
+palette gamma (1, 2): The images are equal.
+truecolor gamma (1, 2): The images are equal.
+palette gamma (1, 1): The images are equal.
+truecolor gamma (1, 1): The images are equal.
+palette gamma (2, 1): The images are equal.
+truecolor gamma (2, 1): The images are equal.
+===DONE===
diff --git a/ext/gd/tests/imagegammacorrect_variation2_1_1.png b/ext/gd/tests/imagegammacorrect_variation2_1_1.png Binary files differnew file mode 100644 index 0000000000..517010b42f --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_variation2_1_1.png diff --git a/ext/gd/tests/imagegammacorrect_variation2_1_2.png b/ext/gd/tests/imagegammacorrect_variation2_1_2.png Binary files differnew file mode 100644 index 0000000000..9b9d7f04a6 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_variation2_1_2.png diff --git a/ext/gd/tests/imagegammacorrect_variation2_2_1.png b/ext/gd/tests/imagegammacorrect_variation2_2_1.png Binary files differnew file mode 100644 index 0000000000..f7384be913 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_variation2_2_1.png diff --git a/ext/gd/tests/imagegd_truecolor.phpt b/ext/gd/tests/imagegd_truecolor.phpt new file mode 100644 index 0000000000..1eedae484f --- /dev/null +++ b/ext/gd/tests/imagegd_truecolor.phpt @@ -0,0 +1,34 @@ +--TEST--
+imagegd() writes truecolor images without palette conversion
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(10, 10);
+$white = imagecolorallocate($im, 255, 255, 255);
+imagefilledrectangle($im, 0,0, 9,9, $white);
+$blue = imagecolorallocate($im, 0, 0, 255);
+imagefilledrectangle($im, 3,3, 6,6, $blue);
+
+ob_start();
+imagegd($im);
+$buffer = ob_get_clean();
+
+$header = unpack('nsignature/nwidth/nheight/Ctruecolor', $buffer);
+printf("signature: %d\n", $header['signature']);
+printf("truecolor: %d\n", $header['truecolor']);
+printf("size: %d\n", strlen($buffer));
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'imagegd_truecolor.png', $im);
+?>
+===DONE===
+--EXPECT--
+signature: 65534
+truecolor: 1
+size: 411
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/imagegd_truecolor.png b/ext/gd/tests/imagegd_truecolor.png Binary files differnew file mode 100644 index 0000000000..8c77c9f422 --- /dev/null +++ b/ext/gd/tests/imagegd_truecolor.png diff --git a/ext/gd/tests/imagegetclip_basic.phpt b/ext/gd/tests/imagegetclip_basic.phpt new file mode 100644 index 0000000000..f5f1893cf8 --- /dev/null +++ b/ext/gd/tests/imagegetclip_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +imagegetclip() - basic functionality +--SKIP-- +<?php +if (!extension_loaded('gd')) die('skip ext/gd required'); +?> +--FILE-- +<?php +$im = imagecreate(10, 10); +echo '=== original ===', PHP_EOL; +var_dump(imagegetclip($im)); +imagesetclip($im, 1,2, 3,4); +echo '=== after imagesetclip() ===', PHP_EOL; +var_dump(imagegetclip($im)); +?> +--EXPECT-- +=== original === +array(4) { + [0]=> + int(0) + [1]=> + int(0) + [2]=> + int(9) + [3]=> + int(9) +} +=== after imagesetclip() === +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} diff --git a/ext/gd/tests/imageopenpolygon.png b/ext/gd/tests/imageopenpolygon.png Binary files differnew file mode 100644 index 0000000000..33bcf32223 --- /dev/null +++ b/ext/gd/tests/imageopenpolygon.png diff --git a/ext/gd/tests/imageopenpolygon_basic.phpt b/ext/gd/tests/imageopenpolygon_basic.phpt new file mode 100644 index 0000000000..569cb305b6 --- /dev/null +++ b/ext/gd/tests/imageopenpolygon_basic.phpt @@ -0,0 +1,29 @@ +--TEST--
+imageopenpolygon(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(100, 100);
+$white = imagecolorallocate($im, 255, 255, 255);
+$black = imagecolorallocate($im, 0, 0, 0);
+$red = imagecolorallocate($im, 255, 0, 0);
+$green = imagecolorallocate($im, 0, 128, 0);
+$blue = imagecolorallocate($im, 0, 0, 255);
+imagefilledrectangle($im, 0,0, 99,99, $white);
+
+imageopenpolygon($im, [10,10, 49,89, 89,10], 3, $black);
+imageopenpolygon($im, [10,89, 35,10, 60,89, 85,10], 4, $red);
+imageopenpolygon($im, [10,49, 30,89, 50,10, 70,89, 90,10], 5, $green);
+imageopenpolygon($im, [10,50, 25,10, 40,89, 55,10, 80,89, 90,50], 6, $blue);
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'imageopenpolygon.png', $im);
+?>
+===DONE===
+--EXPECT--
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/imagepolygon_aa.phpt b/ext/gd/tests/imagepolygon_aa.phpt new file mode 100644 index 0000000000..e868f0c366 --- /dev/null +++ b/ext/gd/tests/imagepolygon_aa.phpt @@ -0,0 +1,24 @@ +--TEST--
+antialiased imagepolygon()
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
+
+$im = imagecreatetruecolor(100, 100);
+$white = imagecolorallocate($im, 255, 255, 255);
+$black = imagecolorallocate($im, 0, 0, 0);
+imagefilledrectangle($im, 0,0, 99,99, $white);
+imageantialias($im, true);
+
+imagepolygon($im, [10,10, 49,89, 89,49], 3, $black);
+
+test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'imagepolygon_aa.png', $im);
+?>
+===DONE===
+--EXPECT--
+The images are equal.
+===DONE===
diff --git a/ext/gd/tests/imagepolygon_aa.png b/ext/gd/tests/imagepolygon_aa.png Binary files differnew file mode 100644 index 0000000000..a10af43e37 --- /dev/null +++ b/ext/gd/tests/imagepolygon_aa.png diff --git a/ext/gd/tests/imageresolution_jpeg.phpt b/ext/gd/tests/imageresolution_jpeg.phpt new file mode 100644 index 0000000000..a659e2682a --- /dev/null +++ b/ext/gd/tests/imageresolution_jpeg.phpt @@ -0,0 +1,43 @@ +--TEST-- +Set and get image resolution of JPEG images +--SKIPIF-- +<?php +if (!extension_loaded('gd')) die('skip gd extension not available'); +if (!(imagetypes() & IMG_JPEG)) die('skip JPEG support not available'); +?> +--FILE-- +<?php +$filename = __DIR__ . DIRECTORY_SEPARATOR . 'imageresolution_jpeg.jpeg'; + +$exp = imagecreate(100, 100); +imagecolorallocate($exp, 255, 0, 0); + +imageresolution($exp, 71); +imagejpeg($exp, $filename); +$act = imagecreatefromjpeg($filename); +var_dump(imageresolution($act)); + +imageresolution($exp, 71, 299); +imagejpeg($exp, $filename); +$act = imagecreatefromjpeg($filename); +var_dump(imageresolution($act)); +?> +===DONE=== +--EXPECT-- +array(2) { + [0]=> + int(71) + [1]=> + int(71) +} +array(2) { + [0]=> + int(71) + [1]=> + int(299) +} +===DONE=== +--CLEAN-- +<?php +@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'imageresolution_jpeg.jpeg'); +?> diff --git a/ext/gd/tests/imageresolution_png.phpt b/ext/gd/tests/imageresolution_png.phpt new file mode 100644 index 0000000000..5bb835b4e8 --- /dev/null +++ b/ext/gd/tests/imageresolution_png.phpt @@ -0,0 +1,42 @@ +--TEST-- +Set and get image resolution of PNG images +--SKIPIF-- +<?php +if (!extension_loaded('gd')) die('skip gd extension not available'); +?> +--FILE-- +<?php +$filename = __DIR__ . DIRECTORY_SEPARATOR . 'imageresolution_png.png'; + +$exp = imagecreate(100, 100); +imagecolorallocate($exp, 255, 0, 0); + +imageresolution($exp, 71); +imagepng($exp, $filename); +$act = imagecreatefrompng($filename); +var_dump(imageresolution($act)); + +imageresolution($exp, 71, 299); +imagepng($exp, $filename); +$act = imagecreatefrompng($filename); +var_dump(imageresolution($act)); +?> +===DONE=== +--EXPECT-- +array(2) { + [0]=> + int(71) + [1]=> + int(71) +} +array(2) { + [0]=> + int(71) + [1]=> + int(299) +} +===DONE=== +--CLEAN-- +<?php +@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'imageresolution_png.png'); +?> diff --git a/ext/gd/tests/imagesetclip_basic.phpt b/ext/gd/tests/imagesetclip_basic.phpt new file mode 100644 index 0000000000..ced49c7eaf --- /dev/null +++ b/ext/gd/tests/imagesetclip_basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +imagesetclip() - basic functionality +--SKIP-- +<?php +if (!extension_loaded('gd')) die('skip ext/gd required'); +?> +--FILE-- +<?php +// draw a clipped diagonal line +$im = imagecreate(100, 100); +imagecolorallocate($im, 0, 0, 0); +$white = imagecolorallocate($im, 255, 255, 255); +imagesetclip($im, 10,10, 89,89); +imageline($im, 0,0, 99,99, $white); + +// save image for manual inspection +// imagepng($im, __FILE__ . '.png'); + +// verify that the clipping has been respected +imagesetclip($im, 0,0, 99,99); +var_dump(imagecolorat($im, 9,9) !== $white); +var_dump(imagecolorat($im, 90,90) !== $white); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 30693da5cb..ea3c6cf408 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1365,7 +1365,16 @@ ZEND_FUNCTION(gmp_fact) RETURN_FALSE; } } else { - if (zval_get_long(a_arg) < 0) { + /* Use convert_to_number first to detect getting non-integer */ + convert_scalar_to_number(a_arg); + if (Z_TYPE_P(a_arg) != IS_LONG) { + convert_to_long(a_arg); + if (Z_LVAL_P(a_arg) >= 0) { + /* Only warn if we'll make it past the non-negative check */ + php_error_docref(NULL, E_WARNING, "Number has to be an integer"); + } + } + if (Z_LVAL_P(a_arg) < 0) { php_error_docref(NULL, E_WARNING, "Number has to be greater than or equal to 0"); RETURN_FALSE; } diff --git a/ext/gmp/tests/gmp_fact.phpt b/ext/gmp/tests/gmp_fact.phpt index 6afccaf936..5cb8089b49 100644 --- a/ext/gmp/tests/gmp_fact.phpt +++ b/ext/gmp/tests/gmp_fact.phpt @@ -38,6 +38,8 @@ string(1) "0" Warning: gmp_fact(): Number has to be greater than or equal to 0 in %s on line %d string(1) "0" + +Warning: gmp_fact(): Number has to be an integer in %s on line %d string(1) "1" string(19) "2432902008176640000" string(65) "30414093201713378043612608166064768844377641568960512000000000000" @@ -53,9 +55,13 @@ NULL Warning: gmp_fact() expects exactly 1 parameter, 2 given in %s on line %d NULL + +Warning: gmp_fact(): Number has to be an integer in %s on line %d object(GMP)#%d (1) { ["num"]=> string(1) "1" } + +Warning: gmp_fact(): Number has to be an integer in %s on line %d string(1) "1" Done diff --git a/ext/gmp/tests/gmp_sqrtrem.phpt b/ext/gmp/tests/gmp_sqrtrem.phpt index 2fca463daa..d30bb2b295 100644 --- a/ext/gmp/tests/gmp_sqrtrem.phpt +++ b/ext/gmp/tests/gmp_sqrtrem.phpt @@ -6,8 +6,7 @@ gmp_sqrtrem() basic tests <?php $r = gmp_sqrtrem(-1); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); +var_dump($r); $r = gmp_sqrtrem("0"); var_dump(gmp_strval($r[0])); @@ -44,8 +43,7 @@ var_dump(gmp_strval($r[1])); $n = gmp_init(-1); $r = gmp_sqrtrem($n); -var_dump(gmp_strval($r[0])); -var_dump(gmp_strval($r[1])); +var_dump($r); $n = gmp_init(1000001); $r = gmp_sqrtrem($n); @@ -59,11 +57,6 @@ echo "Done\n"; ?> --EXPECTF-- Warning: gmp_sqrtrem(): Number has to be greater than or equal to 0 in %s on line %d - -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d -bool(false) - -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) string(1) "0" string(1) "0" @@ -83,11 +76,6 @@ string(4) "1000" string(1) "1" Warning: gmp_sqrtrem(): Number has to be greater than or equal to 0 in %s on line %d - -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d -bool(false) - -Warning: gmp_strval(): Unable to convert variable to GMP - wrong type in %s on line %d bool(false) string(4) "1000" string(1) "1" diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 8f18fa1c27..b03c1f9453 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -38,7 +38,7 @@ static inline unsigned char idx(unsigned char x, unsigned char y) { #ifdef WORDS_BIGENDIAN static inline uint64_t load64(const unsigned char* x) { - unsigned char i; + char i; uint64_t ret = 0; for (i = 7; i >= 0; --i) { ret <<= 8; @@ -47,14 +47,14 @@ static inline uint64_t load64(const unsigned char* x) { return ret; } static inline void store64(unsigned char* x, uint64_t val) { - unsigned char i; + char i; for (i = 0; i < 8; ++i) { x[i] = val & 0xFF; val >>= 8; } } static inline void xor64(unsigned char* x, uint64_t val) { - unsigned char i; + char i; for (i = 0; i < 8; ++i) { x[i] ^= val & 0xFF; val >>= 8; diff --git a/ext/hash/tests/hash_update_file.phpt b/ext/hash/tests/hash_update_file.phpt index 32ce962bd0..488be47411 100644 --- a/ext/hash/tests/hash_update_file.phpt +++ b/ext/hash/tests/hash_update_file.phpt @@ -1,21 +1,24 @@ --TEST-- -bool hash_update_file ( resource $hcontext , string $filename [, resource $scontext = NULL ] ); +hash_update_file() function - basic test --CREDITS-- marcosptf - <marcosptf@yahoo.com.br> - @phpsp - sao paulo - br --SKIPIF-- <?php -if (phpversion() < "5.3.0") { - die('SKIP php version so lower.'); -} -require_once(dirname(__FILE__) . '/skip_mhash.inc'); ?> +if (!extension_loaded('hash')) die('skip hash extension not available'); ?> --FILE-- <?php +$filePath = __DIR__ . DIRECTORY_SEPARATOR . 'hash_update_stream.txt'; +file_put_contents($filePath, 'The quick brown fox jumped over the lazy dog.'); + $ctx = hash_init('md5'); -$filePath = __DIR__ . DIRECTORY_SEPARATOR . 'sha1.phpt'; -fopen($filePath, "r"); var_dump(hash_update_file($ctx, $filePath)); -hash_final($ctx); +echo hash_final($ctx); ?> --EXPECT-- bool(true) +5c6ffbdd40d9556b73a21e63c3e0e904 +--CLEAN-- +<?php +unlink(__DIR__ . DIRECTORY_SEPARATOR . 'hash_update_stream.txt'); +?> diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index ab51dd046a..528e981eaa 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -2869,7 +2869,7 @@ static php_stream_filter_ops php_iconv_stream_filter_ops = { }; /* {{{ php_iconv_stream_filter_create */ -static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, int persistent) +static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, uint8_t persistent) { php_stream_filter *retval = NULL; php_iconv_stream_filter *inst; diff --git a/ext/interbase/ibase_query.c b/ext/interbase/ibase_query.c index 37e59dd3a7..8923a8c55d 100644 --- a/ext/interbase/ibase_query.c +++ b/ext/interbase/ibase_query.c @@ -1109,11 +1109,7 @@ PHP_FUNCTION(ibase_query) isc_db_handle db = 0; isc_tr_handle trans = 0; - if (PG(sql_safe_mode)) { - _php_ibase_module_error("CREATE DATABASE is not allowed in SQL safe mode" - ); - - } else if (((l = INI_INT("ibase.max_links")) != -1) && (IBG(num_links) >= l)) { + if (((l = INI_INT("ibase.max_links")) != -1) && (IBG(num_links) >= l)) { _php_ibase_module_error("CREATE DATABASE is not allowed: maximum link count " "(" ZEND_LONG_FMT ") reached", l); diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c index 531019b841..a4e51c27a6 100644 --- a/ext/interbase/interbase.c +++ b/ext/interbase/interbase.c @@ -902,7 +902,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* } /* restrict to the server/db in the .ini if in safe mode */ - if ((!len[DB] || PG(sql_safe_mode)) && (c = INI_STR("ibase.default_db"))) { + if (!len[DB] && (c = INI_STR("ibase.default_db"))) { args[DB] = c; len[DB] = strlen(c); } diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp index f1bf75ab0f..2357a03940 100644 --- a/ext/intl/common/common_date.cpp +++ b/ext/intl/common/common_date.cpp @@ -25,13 +25,7 @@ extern "C" { #include <ext/date/php_date.h> } -#ifndef INFINITY -#define INFINITY (DBL_MAX+DBL_MAX) -#endif - -#ifndef NAN -#define NAN (INFINITY-INFINITY) -#endif +#include "zend_portability.h" /* {{{ timezone_convert_datetimezone * The timezone in DateTime and DateTimeZone is not unified. */ @@ -118,7 +112,7 @@ U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz, } if (millis) { - *millis = NAN; + *millis = ZEND_NAN; } if (tz) { *tz = NULL; @@ -173,13 +167,13 @@ U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz, U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func) { - double rv = NAN; + double rv = ZEND_NAN; zend_long lv; int type; char *message; if (err && U_FAILURE(err->code)) { - return NAN; + return ZEND_NAN; } switch (Z_TYPE_P(z)) { diff --git a/ext/json/config.m4 b/ext/json/config.m4 index fb87a93992..1411e83faa 100644 --- a/ext/json/config.m4 +++ b/ext/json/config.m4 @@ -15,7 +15,7 @@ PHP_NEW_EXTENSION(json, json_parser.tab.c \ json_scanner.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) - PHP_INSTALL_HEADERS([ext/json], [php_json.h]) + PHP_INSTALL_HEADERS([ext/json], [php_json.h php_json_parser.h php_json_scanner.h]) PHP_ADD_MAKEFILE_FRAGMENT() PHP_SUBST(JSON_SHARED_LIBADD) fi diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index f5ae57c719..d6d7cfc432 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -430,6 +430,21 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_check_encoding, 0, 0, 0) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_scrub, 0, 0, 1) + ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(0, encoding) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ord, 0, 0, 1) + ZEND_ARG_INFO(0, str) + ZEND_ARG_INFO(0, encoding) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_chr, 0, 0, 1) + ZEND_ARG_INFO(0, cp) + ZEND_ARG_INFO(0, encoding) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_regex_encoding, 0, 0, 0) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() @@ -555,6 +570,9 @@ const zend_function_entry mbstring_functions[] = { PHP_FE(mb_send_mail, arginfo_mb_send_mail) PHP_FE(mb_get_info, arginfo_mb_get_info) PHP_FE(mb_check_encoding, arginfo_mb_check_encoding) + PHP_FE(mb_ord, arginfo_mb_ord) + PHP_FE(mb_chr, arginfo_mb_chr) + PHP_FE(mb_scrub, arginfo_mb_scrub) #if HAVE_MBREGEX PHP_MBREGEX_FUNCTION_ENTRIES #endif @@ -3137,8 +3155,33 @@ PHP_FUNCTION(mb_strimwidth) } /* }}} */ + +/* See mbfl_no_encoding definition for list of unsupported encodings */ +static inline zend_bool php_mb_is_unsupported_no_encoding(enum mbfl_no_encoding no_enc) +{ + return ((no_enc >= mbfl_no_encoding_invalid && no_enc <= mbfl_no_encoding_qprint) + || (no_enc >= mbfl_no_encoding_utf7 && no_enc <= mbfl_no_encoding_utf7imap) + || (no_enc >= mbfl_no_encoding_jis && no_enc <= mbfl_no_encoding_2022jpms) + || (no_enc >= mbfl_no_encoding_cp50220 && no_enc <= mbfl_no_encoding_cp50222)); +} + + +/* See mbfl_no_encoding definition for list of unicode encodings */ +static inline zend_bool php_mb_is_no_encoding_unicode(enum mbfl_no_encoding no_enc) +{ + return (no_enc >= mbfl_no_encoding_ucs4 && no_enc <= mbfl_no_encoding_utf8_sb); +} + + +/* See mbfl_no_encoding definition for list of UTF-8 encodings */ +static inline zend_bool php_mb_is_no_encoding_utf8(enum mbfl_no_encoding no_enc) +{ + return (no_enc >= mbfl_no_encoding_utf8 && no_enc <= mbfl_no_encoding_utf8_sb); +} + + /* {{{ MBSTRING_API char *php_mb_convert_encoding() */ -MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len) +MBSTRING_API char *php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len) { mbfl_string string, result, *ret; const mbfl_encoding *from_encoding, *to_encoding; @@ -3207,7 +3250,28 @@ MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, co return NULL; } mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode)); - mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar)); + + if (string.no_encoding == MBSTRG(current_internal_encoding)->no_encoding) { + mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar)); + } else if (php_mb_is_no_encoding_unicode(string.no_encoding) && php_mb_is_no_encoding_unicode(MBSTRG(current_internal_encoding)->no_encoding)) { + + if (php_mb_is_no_encoding_utf8(string.no_encoding)) { + + if (MBSTRG(current_filter_illegal_substchar) > 0xd7ff && + 0xe000 > MBSTRG(current_filter_illegal_substchar) + ) { + mbfl_buffer_converter_illegal_substchar(convd, 0x3f); + } else { + mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar)); + } + + } else { + mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar)); + } + + } else { + mbfl_buffer_converter_illegal_substchar(convd, 0x3f); + } /* do it */ ret = mbfl_buffer_converter_feed_result(convd, &string, &result); @@ -3224,12 +3288,83 @@ MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, co } /* }}} */ +MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, const char *_to_encoding, const char *_from_encodings) +{ + HashTable *output, *chash; + zend_long idx; + zend_string *key, *key_tmp; + zval *entry, entry_tmp; + size_t ckey_len, cval_len; + char *ckey, *cval; + + if (!input) { + return NULL; + } + + if (input->u.v.nApplyCount++ > 1) { + input->u.v.nApplyCount--; + php_error_docref(NULL, E_WARNING, "Cannot convert recursively referenced values"); + return NULL; + } + output = (HashTable *)emalloc(sizeof(HashTable)); + zend_hash_init(output, zend_hash_num_elements(input), NULL, ZVAL_PTR_DTOR, 0); + ZEND_HASH_FOREACH_KEY_VAL(input, idx, key, entry) { + /* convert key */ + if (key) { + ckey = php_mb_convert_encoding(ZSTR_VAL(key), ZSTR_LEN(key), _to_encoding, _from_encodings, &ckey_len); + key_tmp = zend_string_init(ckey, ckey_len, 0); + } + /* convert value */ + ZEND_ASSERT(entry); + switch(Z_TYPE_P(entry)) { + case IS_STRING: + cval = php_mb_convert_encoding(Z_STRVAL_P(entry), Z_STRLEN_P(entry), _to_encoding, _from_encodings, &cval_len); + ZVAL_STRINGL(&entry_tmp, cval, cval_len); + efree(cval); + break; + case IS_NULL: + case IS_TRUE: + case IS_FALSE: + case IS_LONG: + case IS_DOUBLE: + ZVAL_COPY(&entry_tmp, entry); + break; + case IS_ARRAY: + chash = php_mb_convert_encoding_recursive(HASH_OF(entry), _to_encoding, _from_encodings); + if (!chash) { + chash = (HashTable *)emalloc(sizeof(HashTable)); + zend_hash_init(chash, 0, NULL, ZVAL_PTR_DTOR, 0); + } + ZVAL_ARR(&entry_tmp, chash); + break; + case IS_OBJECT: + default: + if (key) { + efree(key_tmp); + } + php_error_docref(NULL, E_WARNING, "Object is not supported"); + continue; + } + if (key) { + zend_hash_add(output, key_tmp, &entry_tmp); + } else { + zend_hash_index_add(output, idx, &entry_tmp); + } + } ZEND_HASH_FOREACH_END(); + input->u.v.nApplyCount--; + + return output; +} +/* }}} */ + + /* {{{ proto string mb_convert_encoding(string str, string to-encoding [, mixed from-encoding]) Returns converted string in desired encoding */ PHP_FUNCTION(mb_convert_encoding) { - char *arg_str, *arg_new; - size_t str_len, new_len; + zval *input; + char *arg_new; + size_t new_len; zval *arg_old = NULL; size_t size, l, n; char *_from_encodings = NULL, *ret, *s_free = NULL; @@ -3237,10 +3372,14 @@ PHP_FUNCTION(mb_convert_encoding) zval *hash_entry; HashTable *target_hash; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|z", &arg_str, &str_len, &arg_new, &new_len, &arg_old) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs|z", &input, &arg_new, &new_len, &arg_old) == FAILURE) { return; } + if (Z_TYPE_P(input) != IS_STRING && Z_TYPE_P(input) != IS_ARRAY) { + convert_to_string(input); + } + if (arg_old) { switch (Z_TYPE_P(arg_old)) { case IS_ARRAY: @@ -3275,19 +3414,26 @@ PHP_FUNCTION(mb_convert_encoding) } } - /* new encoding */ - ret = php_mb_convert_encoding(arg_str, str_len, arg_new, _from_encodings, &size); - if (ret != NULL) { - // TODO: avoid reallocation ??? - RETVAL_STRINGL(ret, size); /* the string is already strdup()'ed */ - efree(ret); + if (Z_TYPE_P(input) == IS_STRING) { + /* new encoding */ + ret = php_mb_convert_encoding(Z_STRVAL_P(input), Z_STRLEN_P(input), arg_new, _from_encodings, &size); + if (ret != NULL) { + // TODO: avoid reallocation ??? + RETVAL_STRINGL(ret, size); /* the string is already strdup()'ed */ + efree(ret); + } else { + RETVAL_FALSE; + } + if (s_free) { + efree(s_free); + } } else { - RETVAL_FALSE; + HashTable *tmp; + tmp = php_mb_convert_encoding_recursive(HASH_OF(input), arg_new, _from_encodings); + RETURN_ARR(tmp); } - if ( s_free) { - efree(s_free); - } + return; } /* }}} */ @@ -4257,11 +4403,11 @@ PHP_FUNCTION(mb_send_mail) size_t to_len; char *message = NULL; size_t message_len; - char *headers = NULL; - size_t headers_len; char *subject = NULL; - zend_string *extra_cmd = NULL; size_t subject_len; + zval *headers = NULL; + zend_string *extra_cmd = NULL; + zend_string *str_headers=NULL, *tmp_headers; int i; char *to_r = NULL; char *force_extra_parameters = INI_STR("mail.force_extra_parameters"); @@ -4301,7 +4447,7 @@ PHP_FUNCTION(mb_send_mail) body_enc = lang->mail_body_encoding; } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|sS", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &headers_len, &extra_cmd) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|zS", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &extra_cmd) == FAILURE) { return; } @@ -4310,7 +4456,20 @@ PHP_FUNCTION(mb_send_mail) MAIL_ASCIIZ_CHECK_MBSTRING(subject, subject_len); MAIL_ASCIIZ_CHECK_MBSTRING(message, message_len); if (headers) { - MAIL_ASCIIZ_CHECK_MBSTRING(headers, headers_len); + switch(Z_TYPE_P(headers)) { + case IS_STRING: + tmp_headers = zend_string_init(Z_STRVAL_P(headers), Z_STRLEN_P(headers), 0); + MAIL_ASCIIZ_CHECK_MBSTRING(ZSTR_VAL(tmp_headers), ZSTR_LEN(tmp_headers)); + str_headers = php_trim(tmp_headers, NULL, 0, 2); + zend_string_release(tmp_headers); + break; + case IS_ARRAY: + str_headers = php_mail_build_headers(headers); + break; + default: + php_error_docref(NULL, E_WARNING, "headers parameter must be string or array"); + RETURN_FALSE; + } } if (extra_cmd) { MAIL_ASCIIZ_CHECK_MBSTRING(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd)); @@ -4318,8 +4477,8 @@ PHP_FUNCTION(mb_send_mail) zend_hash_init(&ht_headers, 0, NULL, ZVAL_PTR_DTOR, 0); - if (headers != NULL) { - _php_mbstr_parse_mail_headers(&ht_headers, headers, headers_len); + if (str_headers != NULL) { + _php_mbstr_parse_mail_headers(&ht_headers, ZSTR_VAL(str_headers), ZSTR_LEN(str_headers)); } if ((s = zend_hash_str_find(&ht_headers, "CONTENT-TYPE", sizeof("CONTENT-TYPE") - 1))) { @@ -4462,10 +4621,11 @@ PHP_FUNCTION(mb_send_mail) #define PHP_MBSTR_MAIL_MIME_HEADER2 "Content-Type: text/plain" #define PHP_MBSTR_MAIL_MIME_HEADER3 "; charset=" #define PHP_MBSTR_MAIL_MIME_HEADER4 "Content-Transfer-Encoding: " - if (headers != NULL) { - p = headers; - n = headers_len; + if (str_headers != NULL) { + p = ZSTR_VAL(str_headers); + n = ZSTR_LEN(str_headers); mbfl_memory_device_strncat(&device, p, n); + zend_string_release(str_headers); if (n > 0 && p[n - 1] != '\n') { mbfl_memory_device_strncat(&device, "\n", 1); } @@ -4498,7 +4658,7 @@ PHP_FUNCTION(mb_send_mail) mbfl_memory_device_unput(&device); mbfl_memory_device_output('\0', &device); - headers = (char *)device.buffer; + str_headers = zend_string_init((char *)device.buffer, strlen((char *)device.buffer), 0); if (force_extra_parameters) { extra_cmd = php_escape_shell_cmd(force_extra_parameters); @@ -4506,7 +4666,7 @@ PHP_FUNCTION(mb_send_mail) extra_cmd = php_escape_shell_cmd(ZSTR_VAL(extra_cmd)); } - if (!err && php_mail(to_r, subject, message, headers, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) { + if (!err && php_mail(to_r, subject, message, ZSTR_VAL(str_headers), extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) { RETVAL_TRUE; } else { RETVAL_FALSE; @@ -4527,6 +4687,9 @@ PHP_FUNCTION(mb_send_mail) } mbfl_memory_device_clear(&device); zend_hash_destroy(&ht_headers); + if (str_headers) { + zend_string_release(str_headers); + } } #undef SKIP_LONG_HEADER_SEP_MBSTRING @@ -4715,13 +4878,51 @@ PHP_FUNCTION(mb_get_info) } /* }}} */ -MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const char *enc) + +static inline mbfl_buffer_converter *php_mb_init_convd(const mbfl_encoding *encoding) { - const mbfl_encoding *encoding = MBSTRG(current_internal_encoding); mbfl_buffer_converter *convd; + + convd = mbfl_buffer_converter_new2(encoding, encoding, 0); + if (convd == NULL) { + return NULL; + } + mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE); + mbfl_buffer_converter_illegal_substchar(convd, 0); + return convd; +} + + +static inline int php_mb_check_encoding_impl(mbfl_buffer_converter *convd, const char *input, size_t length, const mbfl_encoding *encoding) { mbfl_string string, result, *ret = NULL; long illegalchars = 0; + /* initialize string */ + mbfl_string_init_set(&string, mbfl_no_language_neutral, encoding->no_encoding); + mbfl_string_init(&result); + + string.val = (unsigned char *) input; + string.len = length; + + ret = mbfl_buffer_converter_feed_result(convd, &string, &result); + illegalchars = mbfl_buffer_illegalchars(convd); + + if (ret != NULL) { + if (illegalchars == 0 && string.len == result.len && memcmp(string.val, result.val, string.len) == 0) { + mbfl_string_clear(&result); + return 1; + } + mbfl_string_clear(&result); + } + return 0; +} + + +MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const char *enc) +{ + const mbfl_encoding *encoding = MBSTRG(current_internal_encoding); + mbfl_buffer_converter *convd; + if (input == NULL) { return MBSTRG(illegalchars) == 0; } @@ -4734,60 +4935,454 @@ MBSTRING_API int php_mb_check_encoding(const char *input, size_t length, const c } } - convd = mbfl_buffer_converter_new2(encoding, encoding, 0); - + convd = php_mb_init_convd(encoding); if (convd == NULL) { php_error_docref(NULL, E_WARNING, "Unable to create converter"); return 0; } - mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE); - mbfl_buffer_converter_illegal_substchar(convd, 0); + if (php_mb_check_encoding_impl(convd, input, length, encoding)) { + mbfl_buffer_converter_delete(convd); + return 1; + } + mbfl_buffer_converter_delete(convd); + return 0; +} - /* initialize string */ - mbfl_string_init_set(&string, mbfl_no_language_neutral, encoding->no_encoding); - mbfl_string_init(&result); - string.val = (unsigned char *) input; - string.len = length; +MBSTRING_API int php_mb_check_encoding_recursive(HashTable *vars, const zend_string *enc) +{ + const mbfl_encoding *encoding = MBSTRG(current_internal_encoding); + mbfl_buffer_converter *convd; + zend_long idx; + zend_string *key; + zval *entry; + int valid = 1; - ret = mbfl_buffer_converter_feed_result(convd, &string, &result); - illegalchars = mbfl_buffer_illegalchars(convd); - mbfl_buffer_converter_delete(convd); + (void)(idx); - if (ret != NULL) { - if (illegalchars == 0 && string.len == result.len && memcmp(string.val, result.val, string.len) == 0) { - mbfl_string_clear(&result); - return 1; + if (enc != NULL) { + encoding = mbfl_name2encoding(ZSTR_VAL(enc)); + if (!encoding || encoding == &mbfl_encoding_pass) { + php_error_docref(NULL, E_WARNING, "Invalid encoding \"%s\"", ZSTR_VAL(enc)); + return 0; } + } - mbfl_string_clear(&result); + convd = php_mb_init_convd(encoding); + if (convd == NULL) { + php_error_docref(NULL, E_WARNING, "Unable to create converter"); + return 0; } - return 0; + if (vars->u.v.nApplyCount++ > 1) { + vars->u.v.nApplyCount--; + mbfl_buffer_converter_delete(convd); + php_error_docref(NULL, E_WARNING, "Cannot not handle circular references"); + return 0; + } + ZEND_HASH_FOREACH_KEY_VAL(vars, idx, key, entry) { + ZVAL_DEREF(entry); + if (key) { + if (!php_mb_check_encoding_impl(convd, ZSTR_VAL(key), ZSTR_LEN(key), encoding)) { + valid = 0; + break; + } + } + switch (Z_TYPE_P(entry)) { + case IS_STRING: + if (!php_mb_check_encoding_impl(convd, Z_STRVAL_P(entry), Z_STRLEN_P(entry), encoding)) { + valid = 0; + break; + } + break; + case IS_ARRAY: + if (!php_mb_check_encoding_recursive(HASH_OF(entry), enc)) { + valid = 0; + break; + } + break; + case IS_LONG: + case IS_DOUBLE: + case IS_NULL: + case IS_TRUE: + case IS_FALSE: + break; + default: + /* Other types are error. */ + valid = 0; + break; + } + } ZEND_HASH_FOREACH_END(); + vars->u.v.nApplyCount--; + mbfl_buffer_converter_delete(convd); + return valid; } -/* {{{ proto bool mb_check_encoding([string var[, string encoding]]) + +/* {{{ proto bool mb_check_encoding([mixed var[, string encoding]]) Check if the string is valid for the specified encoding */ PHP_FUNCTION(mb_check_encoding) { - char *var = NULL; - size_t var_len; - char *enc = NULL; - size_t enc_len; + zval *input = NULL; + zend_string *enc = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ss", &var, &var_len, &enc, &enc_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zS", &input, &enc) == FAILURE) { return; - } + } - RETVAL_FALSE; + /* FIXME: Actually check all inputs, except $_FILES file content. */ + if (input == NULL) { + if (MBSTRG(illegalchars) == 0) { + RETURN_TRUE; + } + RETURN_FALSE; + } - if (php_mb_check_encoding(var, var_len, enc)) { - RETVAL_TRUE; + switch(Z_TYPE_P(input)) { + case IS_LONG: + case IS_DOUBLE: + case IS_NULL: + case IS_TRUE: + case IS_FALSE: + RETURN_TRUE; + break; + case IS_STRING: + if (!php_mb_check_encoding(Z_STRVAL_P(input), Z_STRLEN_P(input), enc ? ZSTR_VAL(enc): NULL)) { + RETURN_FALSE; + } + break; + case IS_ARRAY: + if (!php_mb_check_encoding_recursive(HASH_OF(input), enc)) { + RETURN_FALSE; + } + break; + default: + php_error_docref(NULL, E_WARNING, "Input is something other than scalar or array"); + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + + +static inline zend_long php_mb_ord(const char* str, size_t str_len, const char* enc) +{ + enum mbfl_no_encoding no_enc; + char* ret; + size_t ret_len; + const mbfl_encoding *encoding; + unsigned char char_len; + zend_long cp; + + if (enc == NULL) { + no_enc = MBSTRG(current_internal_encoding)->no_encoding; + } else { + no_enc = mbfl_name2no_encoding(enc); + + if (no_enc == mbfl_no_encoding_invalid) { + php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", enc); + return -1; + } + } + + if (php_mb_is_no_encoding_unicode(no_enc)) { + + ret = php_mb_convert_encoding(str, str_len, "UCS-4BE", enc, &ret_len); + + if (ret == NULL) { + return -1; + } + + cp = (unsigned char) ret[0] << 24 | \ + (unsigned char) ret[1] << 16 | \ + (unsigned char) ret[2] << 8 | \ + (unsigned char) ret[3]; + + efree(ret); + + return cp; + + } else if (php_mb_is_unsupported_no_encoding(no_enc)) { + php_error_docref(NULL, E_WARNING, "Unsupported encoding \"%s\"", enc); + return -1; + } + + ret = php_mb_convert_encoding(str, str_len, enc, enc, &ret_len); + + if (ret == NULL) { + return -1; + } + + encoding = mbfl_no2encoding(no_enc); + char_len = php_mb_mbchar_bytes_ex(ret, encoding); + + if (char_len == 1) { + cp = (unsigned char) ret[0]; + } else if (char_len == 2) { + cp = ((unsigned char) ret[0] << 8) | \ + (unsigned char) ret[1]; + } else if (char_len == 3) { + cp = ((unsigned char) ret[0] << 16) | \ + ((unsigned char) ret[1] << 8) | \ + (unsigned char) ret[2]; + } else { + cp = ((unsigned char) ret[0] << 24) | \ + ((unsigned char) ret[1] << 16) | \ + ((unsigned char) ret[2] << 8) | \ + (unsigned char) ret[3]; } + + efree(ret); + + return cp; +} + + +/* {{{ proto bool mb_ord([string str[, string encoding]]) */ +PHP_FUNCTION(mb_ord) +{ + char* str; + size_t str_len; + char* enc = NULL; + size_t enc_len; + zend_long cp; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(str, str_len) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(enc, enc_len) + ZEND_PARSE_PARAMETERS_END(); + + cp = php_mb_ord(str, str_len, enc); + + if (0 > cp) { + RETURN_FALSE; + } + + RETURN_LONG(cp); } /* }}} */ + +static inline char* php_mb_chr(zend_long cp, const char* enc, size_t *output_len) +{ + enum mbfl_no_encoding no_enc; + char* buf; + size_t buf_len; + char* ret; + size_t ret_len; + + if (enc == NULL) { + no_enc = MBSTRG(current_internal_encoding)->no_encoding; + } else { + no_enc = mbfl_name2no_encoding(enc); + if (no_enc == mbfl_no_encoding_invalid) { + php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", enc); + return NULL; + } + } + + if (php_mb_is_no_encoding_utf8(no_enc)) { + + if (0 > cp || cp > 0x10ffff || (cp > 0xd7ff && 0xe000 > cp)) { + if (php_mb_is_no_encoding_utf8(MBSTRG(current_internal_encoding)->no_encoding)) { + cp = MBSTRG(current_filter_illegal_substchar); + } else if (php_mb_is_no_encoding_unicode(MBSTRG(current_internal_encoding)->no_encoding)) { + if (0xd800 > MBSTRG(current_filter_illegal_substchar) || MBSTRG(current_filter_illegal_substchar) > 0xdfff) { + cp = MBSTRG(current_filter_illegal_substchar); + } else { + cp = 0x3f; + } + } else { + cp = 0x3f; + } + } + + if (cp < 0x80) { + ret_len = 1; + ret = (char *) safe_emalloc(ret_len, 1, 1); + ret[0] = cp; + ret[1] = 0; + } else if (cp < 0x800) { + ret_len = 2; + ret = (char *) safe_emalloc(ret_len, 1, 1); + ret[0] = 0xc0 | (cp >> 6); + ret[1] = 0x80 | (cp & 0x3f); + ret[2] = 0; + } else if (cp < 0x10000) { + ret_len = 3; + ret = (char *) safe_emalloc(ret_len, 1, 1); + ret[0] = 0xe0 | (cp >> 12); + ret[1] = 0x80 | ((cp >> 6) & 0x3f); + ret[2] = 0x80 | (cp & 0x3f); + ret[3] = 0; + } else { + ret_len = 4; + ret = (char *) safe_emalloc(ret_len, 1, 1); + ret[0] = 0xf0 | (cp >> 18); + ret[1] = 0x80 | ((cp >> 12) & 0x3f); + ret[2] = 0x80 | ((cp >> 6) & 0x3f); + ret[3] = 0x80 | (cp & 0x3f); + ret[4] = 0; + } + + if (output_len) { + *output_len = ret_len; + } + + return ret; + + } else if (php_mb_is_no_encoding_unicode(no_enc)) { + + if (0 > cp || 0x10ffff < cp) { + + if (php_mb_is_no_encoding_unicode(MBSTRG(current_internal_encoding)->no_encoding)) { + cp = MBSTRG(current_filter_illegal_substchar); + } else { + cp = 0x3f; + } + + } + + buf_len = 4; + buf = (char *) safe_emalloc(buf_len, 1, 1); + buf[0] = (cp >> 24) & 0xff; + buf[1] = (cp >> 16) & 0xff; + buf[2] = (cp >> 8) & 0xff; + buf[3] = cp & 0xff; + buf[4] = 0; + + ret = php_mb_convert_encoding(buf, buf_len, enc, "UCS-4BE", &ret_len); + efree(buf); + + if (output_len) { + *output_len = ret_len; + } + + return ret; + + } else if (php_mb_is_unsupported_no_encoding(no_enc)) { + php_error_docref(NULL, E_WARNING, "Unsupported encoding \"%s\"", enc); + return NULL; + } + + if (0 > cp || cp > 0x100000000) { + if (no_enc == MBSTRG(current_internal_encoding)->no_encoding) { + cp = MBSTRG(current_filter_illegal_substchar); + } else { + cp = 0x3f; + } + } + + if (cp < 0x100) { + buf_len = 1; + buf = (char *) safe_emalloc(buf_len, 1, 1); + buf[0] = cp; + buf[1] = 0; + } else if (cp < 0x10000) { + buf_len = 2; + buf = (char *) safe_emalloc(buf_len, 1, 1); + buf[0] = cp >> 8; + buf[1] = cp & 0xff; + buf[2] = 0; + } else if (cp < 0x1000000) { + buf_len = 3; + buf = (char *) safe_emalloc(buf_len, 1, 1); + buf[0] = cp >> 16; + buf[1] = (cp >> 8) & 0xff; + buf[2] = cp & 0xff; + buf[3] = 0; + } else { + buf_len = 4; + buf = (char *) safe_emalloc(buf_len, 1, 1); + buf[0] = cp >> 24; + buf[1] = (cp >> 16) & 0xff; + buf[2] = (cp >> 8) & 0xff; + buf[3] = cp & 0xff; + buf[4] = 0; + } + + ret = php_mb_convert_encoding(buf, buf_len, enc, enc, &ret_len); + efree(buf); + + if (output_len) { + *output_len = ret_len; + } + + return ret; +} + + +/* {{{ proto bool mb_ord([int cp[, string encoding]]) */ +PHP_FUNCTION(mb_chr) +{ + zend_long cp; + char* enc = NULL; + size_t enc_len; + char* ret; + size_t ret_len; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_LONG(cp) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(enc, enc_len) + ZEND_PARSE_PARAMETERS_END(); + + ret = php_mb_chr(cp, enc, &ret_len); + + if (ret == NULL) { + RETURN_FALSE; + } + + RETVAL_STRING(ret); + efree(ret); +} +/* }}} */ + + +static inline char* php_mb_scrub(const char* str, size_t str_len, const char* enc) +{ + size_t ret_len; + + return php_mb_convert_encoding(str, str_len, enc, enc, &ret_len); +} + + +/* {{{ proto bool mb_scrub([string str[, string encoding]]) */ +PHP_FUNCTION(mb_scrub) +{ + char* str; + size_t str_len; + char *enc = NULL; + size_t enc_len; + char *ret; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(str, str_len) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(enc, enc_len) + ZEND_PARSE_PARAMETERS_END(); + + if (enc == NULL) { + enc = (char *) MBSTRG(current_internal_encoding)->name; + } else if (!mbfl_is_support_encoding(enc)) { + php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", enc); + RETURN_FALSE; + } + + ret = php_mb_scrub(str, str_len, enc); + + if (ret == NULL) { + RETURN_FALSE; + } + + RETVAL_STRING(ret); + efree(ret); +} +/* }}} */ + + /* {{{ php_mb_populate_current_detect_order_list */ static void php_mb_populate_current_detect_order_list(void) { diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 1283598cfb..9021a3a454 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -130,6 +130,10 @@ PHP_FUNCTION(mb_decode_numericentity); PHP_FUNCTION(mb_send_mail); PHP_FUNCTION(mb_get_info); PHP_FUNCTION(mb_check_encoding); +PHP_FUNCTION(mb_ord); +PHP_FUNCTION(mb_chr); +PHP_FUNCTION(mb_scrub); + MBSTRING_API char *php_mb_safe_strrchr_ex(const char *s, unsigned int c, size_t nbytes, const mbfl_encoding *enc); diff --git a/ext/mbstring/tests/bug69086.phpt b/ext/mbstring/tests/bug69086.phpt new file mode 100644 index 0000000000..0540bcba78 --- /dev/null +++ b/ext/mbstring/tests/bug69086.phpt @@ -0,0 +1,17 @@ +--TEST-- +Request #69086 (enhancement for mb_convert_encoding) +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +mb_substitute_character(0xfffd); +var_dump("?" === mb_convert_encoding("\x80", "Shift_JIS", "EUC-JP")); +mb_internal_encoding("UCS-4BE"); +var_dump("\x00\x00\xff\xfd" === mb_convert_encoding("\x80", "UCS-4BE", "UTF-8")); +mb_substitute_character(0xd800); +var_dump("\x00\x00\x00\x3f" === mb_convert_encoding("\x80", "UCS-4BE", "UTF-8")); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true)
\ No newline at end of file diff --git a/ext/mbstring/tests/ini_encoding2.phpt b/ext/mbstring/tests/ini_encoding2.phpt new file mode 100644 index 0000000000..f0f62dab07 --- /dev/null +++ b/ext/mbstring/tests/ini_encoding2.phpt @@ -0,0 +1,74 @@ +--TEST-- +Encoding INI test +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--INI-- +error_reporting=E_ALL & ~E_DEPRECATED +default_charset= +internal_encoding=EUC-JP +input_encoding= +output_encoding= +mbstring.internal_encoding= +mbstring.http_input= +mbstring.http_output= +--FILE-- +<?php +echo "Getting INI\n"; +var_dump(ini_get('default_charset')); +var_dump(ini_get('internal_encoding')); +var_dump(ini_get('input_encoding')); +var_dump(ini_get('output_encoding')); + +var_dump(ini_get('mbstring.internal_encoding')); +var_dump(mb_internal_encoding()); +var_dump(ini_get('mbstring.http_input')); +var_dump(ini_get('mbstring.http_output')); + +echo "Setting INI\n"; +var_dump(ini_set('default_charset', 'UTF-8')); +var_dump(ini_set('internal_encoding', 'UTF-8')); +var_dump(ini_set('input_encoding', 'UTF-8')); +var_dump(ini_set('output_encoding', 'UTF-8')); +var_dump(ini_set('mbstring.internal_encoding', 'UTF-8')); +var_dump(ini_set('mbstring.http_input', 'UTF-8')); +var_dump(ini_set('mbstring.http_output', 'UTF-8')); + +echo "Getting INI\n"; +var_dump(ini_get('default_charset')); +var_dump(ini_get('internal_encoding')); +var_dump(ini_get('input_encoding')); +var_dump(ini_get('output_encoding')); + +var_dump(ini_get('mbstring.internal_encoding')); +var_dump(mb_internal_encoding()); +var_dump(ini_get('mbstring.http_input')); +var_dump(ini_get('mbstring.http_output')); + + +--EXPECT-- +Getting INI +string(0) "" +string(6) "EUC-JP" +string(0) "" +string(0) "" +string(0) "" +string(5) "UTF-8" +string(0) "" +string(0) "" +Setting INI +string(0) "" +string(6) "EUC-JP" +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" +Getting INI +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" diff --git a/ext/mbstring/tests/mb_check_encoding.phpt b/ext/mbstring/tests/mb_check_encoding.phpt new file mode 100644 index 0000000000..dded51a3f6 --- /dev/null +++ b/ext/mbstring/tests/mb_check_encoding.phpt @@ -0,0 +1,24 @@ +--TEST-- +mb_check_encoding() +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +ini_set('default_charset', 'UTF-8'); +// Valid +$str = "Japanese UTF-8 text. 日本語ã®UTF-8テã‚スト"; +$arr = [1234, 12.34, TRUE, FALSE, NULL, $str, 'key'=>$str, $str=>'val']; +var_dump(mb_check_encoding($str), mb_check_encoding($arr)); + +// Invalid +$str = "Japanese UTF-8 text. 日本語\xFE\x01\x02ã®UTF-8テã‚スト"; +$arr1 = [1234, 12.34, TRUE, FALSE, NULL, 'key'=>$str, $str=>'val']; +$arr2 = [1234, 12.34, TRUE, FALSE, NULL, $str=>'val']; +var_dump(mb_check_encoding($str), mb_check_encoding($arr1), mb_check_encoding($arr2)); +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) diff --git a/ext/mbstring/tests/mb_check_encoding_array.phpt b/ext/mbstring/tests/mb_check_encoding_array.phpt new file mode 100644 index 0000000000..91ee93a7bf --- /dev/null +++ b/ext/mbstring/tests/mb_check_encoding_array.phpt @@ -0,0 +1,31 @@ +--TEST-- +mb_check_encoding() - Circular references +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +ini_set('default_charset', 'UTF-8'); +// Valid - Detects recursion +$str = "Japanese UTF-8 text. 日本語ã®UTF-8テã‚スト"; +$arr = [1234, 12.34, TRUE, FALSE, NULL, $str, 'key'=>$str, $str=>'val']; +$tmp = &$arr; +$arr[] = $tmp; +var_dump(mb_check_encoding($str), mb_check_encoding($arr)); + +// Invalid - Return false due to short circuit check +$str = "Japanese UTF-8 text. 日本語\xFE\x01\x02ã®UTF-8テã‚スト"; +$arr1 = [1234, 12.34, TRUE, FALSE, NULL, 'key'=>$str, $str=>'val']; +$tmp = &$arr1; +$arr1[] = $tmp; +$arr2 = [1234, 12.34, TRUE, FALSE, NULL, $str=>'val']; +$tmp = &$arr2; +$arr2[] = $tmp; +var_dump(mb_check_encoding($str), mb_check_encoding($arr1), mb_check_encoding($arr2)); +?> +--EXPECTF-- +Warning: mb_check_encoding(): Cannot not handle circular references in %s on line %d +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/mbstring/tests/mb_chr.phpt b/ext/mbstring/tests/mb_chr.phpt new file mode 100644 index 0000000000..095ce90ae5 --- /dev/null +++ b/ext/mbstring/tests/mb_chr.phpt @@ -0,0 +1,59 @@ +--TEST-- +mb_chr() +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump( + "\u{20bb7}" === mb_chr(0x20bb7), + "\x8f\xa1\xef" === mb_chr(0x8fa1ef, "EUC-JP-2004"), + "?" === mb_chr(0xd800) +); + +mb_internal_encoding("UCS-4BE"); +mb_substitute_character(0xfffd); +var_dump( + "\u{fffd}" === mb_chr(0xd800, "UTF-8") +); +mb_substitute_character(0xd800); +var_dump( + "?" === mb_chr(0xd800, "UTF-8") +); + +mb_internal_encoding("EUC-JP"); +mb_substitute_character(0xa4a2); +var_dump( + "?" === mb_chr(0xd800, "UTF-8") +); + +// Invalid +var_dump( + mb_chr(0xd800, "typo"), + mb_chr(0xd800, "pass"), + mb_chr(0xd800, "jis"), + mb_chr(0xd800, "cp50222"), + mb_chr(0xd800, "utf-7") +); +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: mb_chr(): Unknown encoding "typo" in %s on line 26 + +Warning: mb_chr(): Unsupported encoding "pass" in %s on line 27 + +Warning: mb_chr(): Unsupported encoding "jis" in %s on line 28 + +Warning: mb_chr(): Unsupported encoding "cp50222" in %s on line 29 + +Warning: mb_chr(): Unsupported encoding "utf-7" in %s on line 30 +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/mbstring/tests/mb_chr_ord.phpt b/ext/mbstring/tests/mb_chr_ord.phpt new file mode 100644 index 0000000000..613f2e7f42 --- /dev/null +++ b/ext/mbstring/tests/mb_chr_ord.phpt @@ -0,0 +1,2062 @@ +--TEST-- +mb_chr() and mb_ord() +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +ini_set('internal_encoding', 'utf-8'); +for($ch = 1; $ch < 80000; $ch++) { + if ($ch !== mb_ord(mb_chr($ch))) echo "ERROR($ch)\n"; +} +echo 'OK'; +--EXPECTF-- +ERROR(55296) +ERROR(55297) +ERROR(55298) +ERROR(55299) +ERROR(55300) +ERROR(55301) +ERROR(55302) +ERROR(55303) +ERROR(55304) +ERROR(55305) +ERROR(55306) +ERROR(55307) +ERROR(55308) +ERROR(55309) +ERROR(55310) +ERROR(55311) +ERROR(55312) +ERROR(55313) +ERROR(55314) +ERROR(55315) +ERROR(55316) +ERROR(55317) +ERROR(55318) +ERROR(55319) +ERROR(55320) +ERROR(55321) +ERROR(55322) +ERROR(55323) +ERROR(55324) +ERROR(55325) +ERROR(55326) +ERROR(55327) +ERROR(55328) +ERROR(55329) +ERROR(55330) +ERROR(55331) +ERROR(55332) +ERROR(55333) +ERROR(55334) +ERROR(55335) +ERROR(55336) +ERROR(55337) +ERROR(55338) +ERROR(55339) +ERROR(55340) +ERROR(55341) +ERROR(55342) +ERROR(55343) +ERROR(55344) +ERROR(55345) +ERROR(55346) +ERROR(55347) +ERROR(55348) +ERROR(55349) +ERROR(55350) +ERROR(55351) +ERROR(55352) +ERROR(55353) +ERROR(55354) +ERROR(55355) +ERROR(55356) +ERROR(55357) +ERROR(55358) +ERROR(55359) +ERROR(55360) +ERROR(55361) +ERROR(55362) +ERROR(55363) +ERROR(55364) +ERROR(55365) +ERROR(55366) +ERROR(55367) +ERROR(55368) +ERROR(55369) +ERROR(55370) +ERROR(55371) +ERROR(55372) +ERROR(55373) +ERROR(55374) +ERROR(55375) +ERROR(55376) +ERROR(55377) +ERROR(55378) +ERROR(55379) +ERROR(55380) +ERROR(55381) +ERROR(55382) +ERROR(55383) +ERROR(55384) +ERROR(55385) +ERROR(55386) +ERROR(55387) +ERROR(55388) +ERROR(55389) +ERROR(55390) +ERROR(55391) +ERROR(55392) +ERROR(55393) +ERROR(55394) +ERROR(55395) +ERROR(55396) +ERROR(55397) +ERROR(55398) +ERROR(55399) +ERROR(55400) +ERROR(55401) +ERROR(55402) +ERROR(55403) +ERROR(55404) +ERROR(55405) +ERROR(55406) +ERROR(55407) +ERROR(55408) +ERROR(55409) +ERROR(55410) +ERROR(55411) +ERROR(55412) +ERROR(55413) +ERROR(55414) +ERROR(55415) +ERROR(55416) +ERROR(55417) +ERROR(55418) +ERROR(55419) +ERROR(55420) +ERROR(55421) +ERROR(55422) +ERROR(55423) +ERROR(55424) +ERROR(55425) +ERROR(55426) +ERROR(55427) +ERROR(55428) +ERROR(55429) +ERROR(55430) +ERROR(55431) +ERROR(55432) +ERROR(55433) +ERROR(55434) +ERROR(55435) +ERROR(55436) +ERROR(55437) +ERROR(55438) +ERROR(55439) +ERROR(55440) +ERROR(55441) +ERROR(55442) +ERROR(55443) +ERROR(55444) +ERROR(55445) +ERROR(55446) +ERROR(55447) +ERROR(55448) +ERROR(55449) +ERROR(55450) +ERROR(55451) +ERROR(55452) +ERROR(55453) +ERROR(55454) +ERROR(55455) +ERROR(55456) +ERROR(55457) +ERROR(55458) +ERROR(55459) +ERROR(55460) +ERROR(55461) +ERROR(55462) +ERROR(55463) +ERROR(55464) +ERROR(55465) +ERROR(55466) +ERROR(55467) +ERROR(55468) +ERROR(55469) +ERROR(55470) +ERROR(55471) +ERROR(55472) +ERROR(55473) +ERROR(55474) +ERROR(55475) +ERROR(55476) +ERROR(55477) +ERROR(55478) +ERROR(55479) +ERROR(55480) +ERROR(55481) +ERROR(55482) +ERROR(55483) +ERROR(55484) +ERROR(55485) +ERROR(55486) +ERROR(55487) +ERROR(55488) +ERROR(55489) +ERROR(55490) +ERROR(55491) +ERROR(55492) +ERROR(55493) +ERROR(55494) +ERROR(55495) +ERROR(55496) +ERROR(55497) +ERROR(55498) +ERROR(55499) +ERROR(55500) +ERROR(55501) +ERROR(55502) +ERROR(55503) +ERROR(55504) +ERROR(55505) +ERROR(55506) +ERROR(55507) +ERROR(55508) +ERROR(55509) +ERROR(55510) +ERROR(55511) +ERROR(55512) +ERROR(55513) +ERROR(55514) +ERROR(55515) +ERROR(55516) +ERROR(55517) +ERROR(55518) +ERROR(55519) +ERROR(55520) +ERROR(55521) +ERROR(55522) +ERROR(55523) +ERROR(55524) +ERROR(55525) +ERROR(55526) +ERROR(55527) +ERROR(55528) +ERROR(55529) +ERROR(55530) +ERROR(55531) +ERROR(55532) +ERROR(55533) +ERROR(55534) +ERROR(55535) +ERROR(55536) +ERROR(55537) +ERROR(55538) +ERROR(55539) +ERROR(55540) +ERROR(55541) +ERROR(55542) +ERROR(55543) +ERROR(55544) +ERROR(55545) +ERROR(55546) +ERROR(55547) +ERROR(55548) +ERROR(55549) +ERROR(55550) +ERROR(55551) +ERROR(55552) +ERROR(55553) +ERROR(55554) +ERROR(55555) +ERROR(55556) +ERROR(55557) +ERROR(55558) +ERROR(55559) +ERROR(55560) +ERROR(55561) +ERROR(55562) +ERROR(55563) +ERROR(55564) +ERROR(55565) +ERROR(55566) +ERROR(55567) +ERROR(55568) +ERROR(55569) +ERROR(55570) +ERROR(55571) +ERROR(55572) +ERROR(55573) +ERROR(55574) +ERROR(55575) +ERROR(55576) +ERROR(55577) +ERROR(55578) +ERROR(55579) +ERROR(55580) +ERROR(55581) +ERROR(55582) +ERROR(55583) +ERROR(55584) +ERROR(55585) +ERROR(55586) +ERROR(55587) +ERROR(55588) +ERROR(55589) +ERROR(55590) +ERROR(55591) +ERROR(55592) +ERROR(55593) +ERROR(55594) +ERROR(55595) +ERROR(55596) +ERROR(55597) +ERROR(55598) +ERROR(55599) +ERROR(55600) +ERROR(55601) +ERROR(55602) +ERROR(55603) +ERROR(55604) +ERROR(55605) +ERROR(55606) +ERROR(55607) +ERROR(55608) +ERROR(55609) +ERROR(55610) +ERROR(55611) +ERROR(55612) +ERROR(55613) +ERROR(55614) +ERROR(55615) +ERROR(55616) +ERROR(55617) +ERROR(55618) +ERROR(55619) +ERROR(55620) +ERROR(55621) +ERROR(55622) +ERROR(55623) +ERROR(55624) +ERROR(55625) +ERROR(55626) +ERROR(55627) +ERROR(55628) +ERROR(55629) +ERROR(55630) +ERROR(55631) +ERROR(55632) +ERROR(55633) +ERROR(55634) +ERROR(55635) +ERROR(55636) +ERROR(55637) +ERROR(55638) +ERROR(55639) +ERROR(55640) +ERROR(55641) +ERROR(55642) +ERROR(55643) +ERROR(55644) +ERROR(55645) +ERROR(55646) +ERROR(55647) +ERROR(55648) +ERROR(55649) +ERROR(55650) +ERROR(55651) +ERROR(55652) +ERROR(55653) +ERROR(55654) +ERROR(55655) +ERROR(55656) +ERROR(55657) +ERROR(55658) +ERROR(55659) +ERROR(55660) +ERROR(55661) +ERROR(55662) +ERROR(55663) +ERROR(55664) +ERROR(55665) +ERROR(55666) +ERROR(55667) +ERROR(55668) +ERROR(55669) +ERROR(55670) +ERROR(55671) +ERROR(55672) +ERROR(55673) +ERROR(55674) +ERROR(55675) +ERROR(55676) +ERROR(55677) +ERROR(55678) +ERROR(55679) +ERROR(55680) +ERROR(55681) +ERROR(55682) +ERROR(55683) +ERROR(55684) +ERROR(55685) +ERROR(55686) +ERROR(55687) +ERROR(55688) +ERROR(55689) +ERROR(55690) +ERROR(55691) +ERROR(55692) +ERROR(55693) +ERROR(55694) +ERROR(55695) +ERROR(55696) +ERROR(55697) +ERROR(55698) +ERROR(55699) +ERROR(55700) +ERROR(55701) +ERROR(55702) +ERROR(55703) +ERROR(55704) +ERROR(55705) +ERROR(55706) +ERROR(55707) +ERROR(55708) +ERROR(55709) +ERROR(55710) +ERROR(55711) +ERROR(55712) +ERROR(55713) +ERROR(55714) +ERROR(55715) +ERROR(55716) +ERROR(55717) +ERROR(55718) +ERROR(55719) +ERROR(55720) +ERROR(55721) +ERROR(55722) +ERROR(55723) +ERROR(55724) +ERROR(55725) +ERROR(55726) +ERROR(55727) +ERROR(55728) +ERROR(55729) +ERROR(55730) +ERROR(55731) +ERROR(55732) +ERROR(55733) +ERROR(55734) +ERROR(55735) +ERROR(55736) +ERROR(55737) +ERROR(55738) +ERROR(55739) +ERROR(55740) +ERROR(55741) +ERROR(55742) +ERROR(55743) +ERROR(55744) +ERROR(55745) +ERROR(55746) +ERROR(55747) +ERROR(55748) +ERROR(55749) +ERROR(55750) +ERROR(55751) +ERROR(55752) +ERROR(55753) +ERROR(55754) +ERROR(55755) +ERROR(55756) +ERROR(55757) +ERROR(55758) +ERROR(55759) +ERROR(55760) +ERROR(55761) +ERROR(55762) +ERROR(55763) +ERROR(55764) +ERROR(55765) +ERROR(55766) +ERROR(55767) +ERROR(55768) +ERROR(55769) +ERROR(55770) +ERROR(55771) +ERROR(55772) +ERROR(55773) +ERROR(55774) +ERROR(55775) +ERROR(55776) +ERROR(55777) +ERROR(55778) +ERROR(55779) +ERROR(55780) +ERROR(55781) +ERROR(55782) +ERROR(55783) +ERROR(55784) +ERROR(55785) +ERROR(55786) +ERROR(55787) +ERROR(55788) +ERROR(55789) +ERROR(55790) +ERROR(55791) +ERROR(55792) +ERROR(55793) +ERROR(55794) +ERROR(55795) +ERROR(55796) +ERROR(55797) +ERROR(55798) +ERROR(55799) +ERROR(55800) +ERROR(55801) +ERROR(55802) +ERROR(55803) +ERROR(55804) +ERROR(55805) +ERROR(55806) +ERROR(55807) +ERROR(55808) +ERROR(55809) +ERROR(55810) +ERROR(55811) +ERROR(55812) +ERROR(55813) +ERROR(55814) +ERROR(55815) +ERROR(55816) +ERROR(55817) +ERROR(55818) +ERROR(55819) +ERROR(55820) +ERROR(55821) +ERROR(55822) +ERROR(55823) +ERROR(55824) +ERROR(55825) +ERROR(55826) +ERROR(55827) +ERROR(55828) +ERROR(55829) +ERROR(55830) +ERROR(55831) +ERROR(55832) +ERROR(55833) +ERROR(55834) +ERROR(55835) +ERROR(55836) +ERROR(55837) +ERROR(55838) +ERROR(55839) +ERROR(55840) +ERROR(55841) +ERROR(55842) +ERROR(55843) +ERROR(55844) +ERROR(55845) +ERROR(55846) +ERROR(55847) +ERROR(55848) +ERROR(55849) +ERROR(55850) +ERROR(55851) +ERROR(55852) +ERROR(55853) +ERROR(55854) +ERROR(55855) +ERROR(55856) +ERROR(55857) +ERROR(55858) +ERROR(55859) +ERROR(55860) +ERROR(55861) +ERROR(55862) +ERROR(55863) +ERROR(55864) +ERROR(55865) +ERROR(55866) +ERROR(55867) +ERROR(55868) +ERROR(55869) +ERROR(55870) +ERROR(55871) +ERROR(55872) +ERROR(55873) +ERROR(55874) +ERROR(55875) +ERROR(55876) +ERROR(55877) +ERROR(55878) +ERROR(55879) +ERROR(55880) +ERROR(55881) +ERROR(55882) +ERROR(55883) +ERROR(55884) +ERROR(55885) +ERROR(55886) +ERROR(55887) +ERROR(55888) +ERROR(55889) +ERROR(55890) +ERROR(55891) +ERROR(55892) +ERROR(55893) +ERROR(55894) +ERROR(55895) +ERROR(55896) +ERROR(55897) +ERROR(55898) +ERROR(55899) +ERROR(55900) +ERROR(55901) +ERROR(55902) +ERROR(55903) +ERROR(55904) +ERROR(55905) +ERROR(55906) +ERROR(55907) +ERROR(55908) +ERROR(55909) +ERROR(55910) +ERROR(55911) +ERROR(55912) +ERROR(55913) +ERROR(55914) +ERROR(55915) +ERROR(55916) +ERROR(55917) +ERROR(55918) +ERROR(55919) +ERROR(55920) +ERROR(55921) +ERROR(55922) +ERROR(55923) +ERROR(55924) +ERROR(55925) +ERROR(55926) +ERROR(55927) +ERROR(55928) +ERROR(55929) +ERROR(55930) +ERROR(55931) +ERROR(55932) +ERROR(55933) +ERROR(55934) +ERROR(55935) +ERROR(55936) +ERROR(55937) +ERROR(55938) +ERROR(55939) +ERROR(55940) +ERROR(55941) +ERROR(55942) +ERROR(55943) +ERROR(55944) +ERROR(55945) +ERROR(55946) +ERROR(55947) +ERROR(55948) +ERROR(55949) +ERROR(55950) +ERROR(55951) +ERROR(55952) +ERROR(55953) +ERROR(55954) +ERROR(55955) +ERROR(55956) +ERROR(55957) +ERROR(55958) +ERROR(55959) +ERROR(55960) +ERROR(55961) +ERROR(55962) +ERROR(55963) +ERROR(55964) +ERROR(55965) +ERROR(55966) +ERROR(55967) +ERROR(55968) +ERROR(55969) +ERROR(55970) +ERROR(55971) +ERROR(55972) +ERROR(55973) +ERROR(55974) +ERROR(55975) +ERROR(55976) +ERROR(55977) +ERROR(55978) +ERROR(55979) +ERROR(55980) +ERROR(55981) +ERROR(55982) +ERROR(55983) +ERROR(55984) +ERROR(55985) +ERROR(55986) +ERROR(55987) +ERROR(55988) +ERROR(55989) +ERROR(55990) +ERROR(55991) +ERROR(55992) +ERROR(55993) +ERROR(55994) +ERROR(55995) +ERROR(55996) +ERROR(55997) +ERROR(55998) +ERROR(55999) +ERROR(56000) +ERROR(56001) +ERROR(56002) +ERROR(56003) +ERROR(56004) +ERROR(56005) +ERROR(56006) +ERROR(56007) +ERROR(56008) +ERROR(56009) +ERROR(56010) +ERROR(56011) +ERROR(56012) +ERROR(56013) +ERROR(56014) +ERROR(56015) +ERROR(56016) +ERROR(56017) +ERROR(56018) +ERROR(56019) +ERROR(56020) +ERROR(56021) +ERROR(56022) +ERROR(56023) +ERROR(56024) +ERROR(56025) +ERROR(56026) +ERROR(56027) +ERROR(56028) +ERROR(56029) +ERROR(56030) +ERROR(56031) +ERROR(56032) +ERROR(56033) +ERROR(56034) +ERROR(56035) +ERROR(56036) +ERROR(56037) +ERROR(56038) +ERROR(56039) +ERROR(56040) +ERROR(56041) +ERROR(56042) +ERROR(56043) +ERROR(56044) +ERROR(56045) +ERROR(56046) +ERROR(56047) +ERROR(56048) +ERROR(56049) +ERROR(56050) +ERROR(56051) +ERROR(56052) +ERROR(56053) +ERROR(56054) +ERROR(56055) +ERROR(56056) +ERROR(56057) +ERROR(56058) +ERROR(56059) +ERROR(56060) +ERROR(56061) +ERROR(56062) +ERROR(56063) +ERROR(56064) +ERROR(56065) +ERROR(56066) +ERROR(56067) +ERROR(56068) +ERROR(56069) +ERROR(56070) +ERROR(56071) +ERROR(56072) +ERROR(56073) +ERROR(56074) +ERROR(56075) +ERROR(56076) +ERROR(56077) +ERROR(56078) +ERROR(56079) +ERROR(56080) +ERROR(56081) +ERROR(56082) +ERROR(56083) +ERROR(56084) +ERROR(56085) +ERROR(56086) +ERROR(56087) +ERROR(56088) +ERROR(56089) +ERROR(56090) +ERROR(56091) +ERROR(56092) +ERROR(56093) +ERROR(56094) +ERROR(56095) +ERROR(56096) +ERROR(56097) +ERROR(56098) +ERROR(56099) +ERROR(56100) +ERROR(56101) +ERROR(56102) +ERROR(56103) +ERROR(56104) +ERROR(56105) +ERROR(56106) +ERROR(56107) +ERROR(56108) +ERROR(56109) +ERROR(56110) +ERROR(56111) +ERROR(56112) +ERROR(56113) +ERROR(56114) +ERROR(56115) +ERROR(56116) +ERROR(56117) +ERROR(56118) +ERROR(56119) +ERROR(56120) +ERROR(56121) +ERROR(56122) +ERROR(56123) +ERROR(56124) +ERROR(56125) +ERROR(56126) +ERROR(56127) +ERROR(56128) +ERROR(56129) +ERROR(56130) +ERROR(56131) +ERROR(56132) +ERROR(56133) +ERROR(56134) +ERROR(56135) +ERROR(56136) +ERROR(56137) +ERROR(56138) +ERROR(56139) +ERROR(56140) +ERROR(56141) +ERROR(56142) +ERROR(56143) +ERROR(56144) +ERROR(56145) +ERROR(56146) +ERROR(56147) +ERROR(56148) +ERROR(56149) +ERROR(56150) +ERROR(56151) +ERROR(56152) +ERROR(56153) +ERROR(56154) +ERROR(56155) +ERROR(56156) +ERROR(56157) +ERROR(56158) +ERROR(56159) +ERROR(56160) +ERROR(56161) +ERROR(56162) +ERROR(56163) +ERROR(56164) +ERROR(56165) +ERROR(56166) +ERROR(56167) +ERROR(56168) +ERROR(56169) +ERROR(56170) +ERROR(56171) +ERROR(56172) +ERROR(56173) +ERROR(56174) +ERROR(56175) +ERROR(56176) +ERROR(56177) +ERROR(56178) +ERROR(56179) +ERROR(56180) +ERROR(56181) +ERROR(56182) +ERROR(56183) +ERROR(56184) +ERROR(56185) +ERROR(56186) +ERROR(56187) +ERROR(56188) +ERROR(56189) +ERROR(56190) +ERROR(56191) +ERROR(56192) +ERROR(56193) +ERROR(56194) +ERROR(56195) +ERROR(56196) +ERROR(56197) +ERROR(56198) +ERROR(56199) +ERROR(56200) +ERROR(56201) +ERROR(56202) +ERROR(56203) +ERROR(56204) +ERROR(56205) +ERROR(56206) +ERROR(56207) +ERROR(56208) +ERROR(56209) +ERROR(56210) +ERROR(56211) +ERROR(56212) +ERROR(56213) +ERROR(56214) +ERROR(56215) +ERROR(56216) +ERROR(56217) +ERROR(56218) +ERROR(56219) +ERROR(56220) +ERROR(56221) +ERROR(56222) +ERROR(56223) +ERROR(56224) +ERROR(56225) +ERROR(56226) +ERROR(56227) +ERROR(56228) +ERROR(56229) +ERROR(56230) +ERROR(56231) +ERROR(56232) +ERROR(56233) +ERROR(56234) +ERROR(56235) +ERROR(56236) +ERROR(56237) +ERROR(56238) +ERROR(56239) +ERROR(56240) +ERROR(56241) +ERROR(56242) +ERROR(56243) +ERROR(56244) +ERROR(56245) +ERROR(56246) +ERROR(56247) +ERROR(56248) +ERROR(56249) +ERROR(56250) +ERROR(56251) +ERROR(56252) +ERROR(56253) +ERROR(56254) +ERROR(56255) +ERROR(56256) +ERROR(56257) +ERROR(56258) +ERROR(56259) +ERROR(56260) +ERROR(56261) +ERROR(56262) +ERROR(56263) +ERROR(56264) +ERROR(56265) +ERROR(56266) +ERROR(56267) +ERROR(56268) +ERROR(56269) +ERROR(56270) +ERROR(56271) +ERROR(56272) +ERROR(56273) +ERROR(56274) +ERROR(56275) +ERROR(56276) +ERROR(56277) +ERROR(56278) +ERROR(56279) +ERROR(56280) +ERROR(56281) +ERROR(56282) +ERROR(56283) +ERROR(56284) +ERROR(56285) +ERROR(56286) +ERROR(56287) +ERROR(56288) +ERROR(56289) +ERROR(56290) +ERROR(56291) +ERROR(56292) +ERROR(56293) +ERROR(56294) +ERROR(56295) +ERROR(56296) +ERROR(56297) +ERROR(56298) +ERROR(56299) +ERROR(56300) +ERROR(56301) +ERROR(56302) +ERROR(56303) +ERROR(56304) +ERROR(56305) +ERROR(56306) +ERROR(56307) +ERROR(56308) +ERROR(56309) +ERROR(56310) +ERROR(56311) +ERROR(56312) +ERROR(56313) +ERROR(56314) +ERROR(56315) +ERROR(56316) +ERROR(56317) +ERROR(56318) +ERROR(56319) +ERROR(56320) +ERROR(56321) +ERROR(56322) +ERROR(56323) +ERROR(56324) +ERROR(56325) +ERROR(56326) +ERROR(56327) +ERROR(56328) +ERROR(56329) +ERROR(56330) +ERROR(56331) +ERROR(56332) +ERROR(56333) +ERROR(56334) +ERROR(56335) +ERROR(56336) +ERROR(56337) +ERROR(56338) +ERROR(56339) +ERROR(56340) +ERROR(56341) +ERROR(56342) +ERROR(56343) +ERROR(56344) +ERROR(56345) +ERROR(56346) +ERROR(56347) +ERROR(56348) +ERROR(56349) +ERROR(56350) +ERROR(56351) +ERROR(56352) +ERROR(56353) +ERROR(56354) +ERROR(56355) +ERROR(56356) +ERROR(56357) +ERROR(56358) +ERROR(56359) +ERROR(56360) +ERROR(56361) +ERROR(56362) +ERROR(56363) +ERROR(56364) +ERROR(56365) +ERROR(56366) +ERROR(56367) +ERROR(56368) +ERROR(56369) +ERROR(56370) +ERROR(56371) +ERROR(56372) +ERROR(56373) +ERROR(56374) +ERROR(56375) +ERROR(56376) +ERROR(56377) +ERROR(56378) +ERROR(56379) +ERROR(56380) +ERROR(56381) +ERROR(56382) +ERROR(56383) +ERROR(56384) +ERROR(56385) +ERROR(56386) +ERROR(56387) +ERROR(56388) +ERROR(56389) +ERROR(56390) +ERROR(56391) +ERROR(56392) +ERROR(56393) +ERROR(56394) +ERROR(56395) +ERROR(56396) +ERROR(56397) +ERROR(56398) +ERROR(56399) +ERROR(56400) +ERROR(56401) +ERROR(56402) +ERROR(56403) +ERROR(56404) +ERROR(56405) +ERROR(56406) +ERROR(56407) +ERROR(56408) +ERROR(56409) +ERROR(56410) +ERROR(56411) +ERROR(56412) +ERROR(56413) +ERROR(56414) +ERROR(56415) +ERROR(56416) +ERROR(56417) +ERROR(56418) +ERROR(56419) +ERROR(56420) +ERROR(56421) +ERROR(56422) +ERROR(56423) +ERROR(56424) +ERROR(56425) +ERROR(56426) +ERROR(56427) +ERROR(56428) +ERROR(56429) +ERROR(56430) +ERROR(56431) +ERROR(56432) +ERROR(56433) +ERROR(56434) +ERROR(56435) +ERROR(56436) +ERROR(56437) +ERROR(56438) +ERROR(56439) +ERROR(56440) +ERROR(56441) +ERROR(56442) +ERROR(56443) +ERROR(56444) +ERROR(56445) +ERROR(56446) +ERROR(56447) +ERROR(56448) +ERROR(56449) +ERROR(56450) +ERROR(56451) +ERROR(56452) +ERROR(56453) +ERROR(56454) +ERROR(56455) +ERROR(56456) +ERROR(56457) +ERROR(56458) +ERROR(56459) +ERROR(56460) +ERROR(56461) +ERROR(56462) +ERROR(56463) +ERROR(56464) +ERROR(56465) +ERROR(56466) +ERROR(56467) +ERROR(56468) +ERROR(56469) +ERROR(56470) +ERROR(56471) +ERROR(56472) +ERROR(56473) +ERROR(56474) +ERROR(56475) +ERROR(56476) +ERROR(56477) +ERROR(56478) +ERROR(56479) +ERROR(56480) +ERROR(56481) +ERROR(56482) +ERROR(56483) +ERROR(56484) +ERROR(56485) +ERROR(56486) +ERROR(56487) +ERROR(56488) +ERROR(56489) +ERROR(56490) +ERROR(56491) +ERROR(56492) +ERROR(56493) +ERROR(56494) +ERROR(56495) +ERROR(56496) +ERROR(56497) +ERROR(56498) +ERROR(56499) +ERROR(56500) +ERROR(56501) +ERROR(56502) +ERROR(56503) +ERROR(56504) +ERROR(56505) +ERROR(56506) +ERROR(56507) +ERROR(56508) +ERROR(56509) +ERROR(56510) +ERROR(56511) +ERROR(56512) +ERROR(56513) +ERROR(56514) +ERROR(56515) +ERROR(56516) +ERROR(56517) +ERROR(56518) +ERROR(56519) +ERROR(56520) +ERROR(56521) +ERROR(56522) +ERROR(56523) +ERROR(56524) +ERROR(56525) +ERROR(56526) +ERROR(56527) +ERROR(56528) +ERROR(56529) +ERROR(56530) +ERROR(56531) +ERROR(56532) +ERROR(56533) +ERROR(56534) +ERROR(56535) +ERROR(56536) +ERROR(56537) +ERROR(56538) +ERROR(56539) +ERROR(56540) +ERROR(56541) +ERROR(56542) +ERROR(56543) +ERROR(56544) +ERROR(56545) +ERROR(56546) +ERROR(56547) +ERROR(56548) +ERROR(56549) +ERROR(56550) +ERROR(56551) +ERROR(56552) +ERROR(56553) +ERROR(56554) +ERROR(56555) +ERROR(56556) +ERROR(56557) +ERROR(56558) +ERROR(56559) +ERROR(56560) +ERROR(56561) +ERROR(56562) +ERROR(56563) +ERROR(56564) +ERROR(56565) +ERROR(56566) +ERROR(56567) +ERROR(56568) +ERROR(56569) +ERROR(56570) +ERROR(56571) +ERROR(56572) +ERROR(56573) +ERROR(56574) +ERROR(56575) +ERROR(56576) +ERROR(56577) +ERROR(56578) +ERROR(56579) +ERROR(56580) +ERROR(56581) +ERROR(56582) +ERROR(56583) +ERROR(56584) +ERROR(56585) +ERROR(56586) +ERROR(56587) +ERROR(56588) +ERROR(56589) +ERROR(56590) +ERROR(56591) +ERROR(56592) +ERROR(56593) +ERROR(56594) +ERROR(56595) +ERROR(56596) +ERROR(56597) +ERROR(56598) +ERROR(56599) +ERROR(56600) +ERROR(56601) +ERROR(56602) +ERROR(56603) +ERROR(56604) +ERROR(56605) +ERROR(56606) +ERROR(56607) +ERROR(56608) +ERROR(56609) +ERROR(56610) +ERROR(56611) +ERROR(56612) +ERROR(56613) +ERROR(56614) +ERROR(56615) +ERROR(56616) +ERROR(56617) +ERROR(56618) +ERROR(56619) +ERROR(56620) +ERROR(56621) +ERROR(56622) +ERROR(56623) +ERROR(56624) +ERROR(56625) +ERROR(56626) +ERROR(56627) +ERROR(56628) +ERROR(56629) +ERROR(56630) +ERROR(56631) +ERROR(56632) +ERROR(56633) +ERROR(56634) +ERROR(56635) +ERROR(56636) +ERROR(56637) +ERROR(56638) +ERROR(56639) +ERROR(56640) +ERROR(56641) +ERROR(56642) +ERROR(56643) +ERROR(56644) +ERROR(56645) +ERROR(56646) +ERROR(56647) +ERROR(56648) +ERROR(56649) +ERROR(56650) +ERROR(56651) +ERROR(56652) +ERROR(56653) +ERROR(56654) +ERROR(56655) +ERROR(56656) +ERROR(56657) +ERROR(56658) +ERROR(56659) +ERROR(56660) +ERROR(56661) +ERROR(56662) +ERROR(56663) +ERROR(56664) +ERROR(56665) +ERROR(56666) +ERROR(56667) +ERROR(56668) +ERROR(56669) +ERROR(56670) +ERROR(56671) +ERROR(56672) +ERROR(56673) +ERROR(56674) +ERROR(56675) +ERROR(56676) +ERROR(56677) +ERROR(56678) +ERROR(56679) +ERROR(56680) +ERROR(56681) +ERROR(56682) +ERROR(56683) +ERROR(56684) +ERROR(56685) +ERROR(56686) +ERROR(56687) +ERROR(56688) +ERROR(56689) +ERROR(56690) +ERROR(56691) +ERROR(56692) +ERROR(56693) +ERROR(56694) +ERROR(56695) +ERROR(56696) +ERROR(56697) +ERROR(56698) +ERROR(56699) +ERROR(56700) +ERROR(56701) +ERROR(56702) +ERROR(56703) +ERROR(56704) +ERROR(56705) +ERROR(56706) +ERROR(56707) +ERROR(56708) +ERROR(56709) +ERROR(56710) +ERROR(56711) +ERROR(56712) +ERROR(56713) +ERROR(56714) +ERROR(56715) +ERROR(56716) +ERROR(56717) +ERROR(56718) +ERROR(56719) +ERROR(56720) +ERROR(56721) +ERROR(56722) +ERROR(56723) +ERROR(56724) +ERROR(56725) +ERROR(56726) +ERROR(56727) +ERROR(56728) +ERROR(56729) +ERROR(56730) +ERROR(56731) +ERROR(56732) +ERROR(56733) +ERROR(56734) +ERROR(56735) +ERROR(56736) +ERROR(56737) +ERROR(56738) +ERROR(56739) +ERROR(56740) +ERROR(56741) +ERROR(56742) +ERROR(56743) +ERROR(56744) +ERROR(56745) +ERROR(56746) +ERROR(56747) +ERROR(56748) +ERROR(56749) +ERROR(56750) +ERROR(56751) +ERROR(56752) +ERROR(56753) +ERROR(56754) +ERROR(56755) +ERROR(56756) +ERROR(56757) +ERROR(56758) +ERROR(56759) +ERROR(56760) +ERROR(56761) +ERROR(56762) +ERROR(56763) +ERROR(56764) +ERROR(56765) +ERROR(56766) +ERROR(56767) +ERROR(56768) +ERROR(56769) +ERROR(56770) +ERROR(56771) +ERROR(56772) +ERROR(56773) +ERROR(56774) +ERROR(56775) +ERROR(56776) +ERROR(56777) +ERROR(56778) +ERROR(56779) +ERROR(56780) +ERROR(56781) +ERROR(56782) +ERROR(56783) +ERROR(56784) +ERROR(56785) +ERROR(56786) +ERROR(56787) +ERROR(56788) +ERROR(56789) +ERROR(56790) +ERROR(56791) +ERROR(56792) +ERROR(56793) +ERROR(56794) +ERROR(56795) +ERROR(56796) +ERROR(56797) +ERROR(56798) +ERROR(56799) +ERROR(56800) +ERROR(56801) +ERROR(56802) +ERROR(56803) +ERROR(56804) +ERROR(56805) +ERROR(56806) +ERROR(56807) +ERROR(56808) +ERROR(56809) +ERROR(56810) +ERROR(56811) +ERROR(56812) +ERROR(56813) +ERROR(56814) +ERROR(56815) +ERROR(56816) +ERROR(56817) +ERROR(56818) +ERROR(56819) +ERROR(56820) +ERROR(56821) +ERROR(56822) +ERROR(56823) +ERROR(56824) +ERROR(56825) +ERROR(56826) +ERROR(56827) +ERROR(56828) +ERROR(56829) +ERROR(56830) +ERROR(56831) +ERROR(56832) +ERROR(56833) +ERROR(56834) +ERROR(56835) +ERROR(56836) +ERROR(56837) +ERROR(56838) +ERROR(56839) +ERROR(56840) +ERROR(56841) +ERROR(56842) +ERROR(56843) +ERROR(56844) +ERROR(56845) +ERROR(56846) +ERROR(56847) +ERROR(56848) +ERROR(56849) +ERROR(56850) +ERROR(56851) +ERROR(56852) +ERROR(56853) +ERROR(56854) +ERROR(56855) +ERROR(56856) +ERROR(56857) +ERROR(56858) +ERROR(56859) +ERROR(56860) +ERROR(56861) +ERROR(56862) +ERROR(56863) +ERROR(56864) +ERROR(56865) +ERROR(56866) +ERROR(56867) +ERROR(56868) +ERROR(56869) +ERROR(56870) +ERROR(56871) +ERROR(56872) +ERROR(56873) +ERROR(56874) +ERROR(56875) +ERROR(56876) +ERROR(56877) +ERROR(56878) +ERROR(56879) +ERROR(56880) +ERROR(56881) +ERROR(56882) +ERROR(56883) +ERROR(56884) +ERROR(56885) +ERROR(56886) +ERROR(56887) +ERROR(56888) +ERROR(56889) +ERROR(56890) +ERROR(56891) +ERROR(56892) +ERROR(56893) +ERROR(56894) +ERROR(56895) +ERROR(56896) +ERROR(56897) +ERROR(56898) +ERROR(56899) +ERROR(56900) +ERROR(56901) +ERROR(56902) +ERROR(56903) +ERROR(56904) +ERROR(56905) +ERROR(56906) +ERROR(56907) +ERROR(56908) +ERROR(56909) +ERROR(56910) +ERROR(56911) +ERROR(56912) +ERROR(56913) +ERROR(56914) +ERROR(56915) +ERROR(56916) +ERROR(56917) +ERROR(56918) +ERROR(56919) +ERROR(56920) +ERROR(56921) +ERROR(56922) +ERROR(56923) +ERROR(56924) +ERROR(56925) +ERROR(56926) +ERROR(56927) +ERROR(56928) +ERROR(56929) +ERROR(56930) +ERROR(56931) +ERROR(56932) +ERROR(56933) +ERROR(56934) +ERROR(56935) +ERROR(56936) +ERROR(56937) +ERROR(56938) +ERROR(56939) +ERROR(56940) +ERROR(56941) +ERROR(56942) +ERROR(56943) +ERROR(56944) +ERROR(56945) +ERROR(56946) +ERROR(56947) +ERROR(56948) +ERROR(56949) +ERROR(56950) +ERROR(56951) +ERROR(56952) +ERROR(56953) +ERROR(56954) +ERROR(56955) +ERROR(56956) +ERROR(56957) +ERROR(56958) +ERROR(56959) +ERROR(56960) +ERROR(56961) +ERROR(56962) +ERROR(56963) +ERROR(56964) +ERROR(56965) +ERROR(56966) +ERROR(56967) +ERROR(56968) +ERROR(56969) +ERROR(56970) +ERROR(56971) +ERROR(56972) +ERROR(56973) +ERROR(56974) +ERROR(56975) +ERROR(56976) +ERROR(56977) +ERROR(56978) +ERROR(56979) +ERROR(56980) +ERROR(56981) +ERROR(56982) +ERROR(56983) +ERROR(56984) +ERROR(56985) +ERROR(56986) +ERROR(56987) +ERROR(56988) +ERROR(56989) +ERROR(56990) +ERROR(56991) +ERROR(56992) +ERROR(56993) +ERROR(56994) +ERROR(56995) +ERROR(56996) +ERROR(56997) +ERROR(56998) +ERROR(56999) +ERROR(57000) +ERROR(57001) +ERROR(57002) +ERROR(57003) +ERROR(57004) +ERROR(57005) +ERROR(57006) +ERROR(57007) +ERROR(57008) +ERROR(57009) +ERROR(57010) +ERROR(57011) +ERROR(57012) +ERROR(57013) +ERROR(57014) +ERROR(57015) +ERROR(57016) +ERROR(57017) +ERROR(57018) +ERROR(57019) +ERROR(57020) +ERROR(57021) +ERROR(57022) +ERROR(57023) +ERROR(57024) +ERROR(57025) +ERROR(57026) +ERROR(57027) +ERROR(57028) +ERROR(57029) +ERROR(57030) +ERROR(57031) +ERROR(57032) +ERROR(57033) +ERROR(57034) +ERROR(57035) +ERROR(57036) +ERROR(57037) +ERROR(57038) +ERROR(57039) +ERROR(57040) +ERROR(57041) +ERROR(57042) +ERROR(57043) +ERROR(57044) +ERROR(57045) +ERROR(57046) +ERROR(57047) +ERROR(57048) +ERROR(57049) +ERROR(57050) +ERROR(57051) +ERROR(57052) +ERROR(57053) +ERROR(57054) +ERROR(57055) +ERROR(57056) +ERROR(57057) +ERROR(57058) +ERROR(57059) +ERROR(57060) +ERROR(57061) +ERROR(57062) +ERROR(57063) +ERROR(57064) +ERROR(57065) +ERROR(57066) +ERROR(57067) +ERROR(57068) +ERROR(57069) +ERROR(57070) +ERROR(57071) +ERROR(57072) +ERROR(57073) +ERROR(57074) +ERROR(57075) +ERROR(57076) +ERROR(57077) +ERROR(57078) +ERROR(57079) +ERROR(57080) +ERROR(57081) +ERROR(57082) +ERROR(57083) +ERROR(57084) +ERROR(57085) +ERROR(57086) +ERROR(57087) +ERROR(57088) +ERROR(57089) +ERROR(57090) +ERROR(57091) +ERROR(57092) +ERROR(57093) +ERROR(57094) +ERROR(57095) +ERROR(57096) +ERROR(57097) +ERROR(57098) +ERROR(57099) +ERROR(57100) +ERROR(57101) +ERROR(57102) +ERROR(57103) +ERROR(57104) +ERROR(57105) +ERROR(57106) +ERROR(57107) +ERROR(57108) +ERROR(57109) +ERROR(57110) +ERROR(57111) +ERROR(57112) +ERROR(57113) +ERROR(57114) +ERROR(57115) +ERROR(57116) +ERROR(57117) +ERROR(57118) +ERROR(57119) +ERROR(57120) +ERROR(57121) +ERROR(57122) +ERROR(57123) +ERROR(57124) +ERROR(57125) +ERROR(57126) +ERROR(57127) +ERROR(57128) +ERROR(57129) +ERROR(57130) +ERROR(57131) +ERROR(57132) +ERROR(57133) +ERROR(57134) +ERROR(57135) +ERROR(57136) +ERROR(57137) +ERROR(57138) +ERROR(57139) +ERROR(57140) +ERROR(57141) +ERROR(57142) +ERROR(57143) +ERROR(57144) +ERROR(57145) +ERROR(57146) +ERROR(57147) +ERROR(57148) +ERROR(57149) +ERROR(57150) +ERROR(57151) +ERROR(57152) +ERROR(57153) +ERROR(57154) +ERROR(57155) +ERROR(57156) +ERROR(57157) +ERROR(57158) +ERROR(57159) +ERROR(57160) +ERROR(57161) +ERROR(57162) +ERROR(57163) +ERROR(57164) +ERROR(57165) +ERROR(57166) +ERROR(57167) +ERROR(57168) +ERROR(57169) +ERROR(57170) +ERROR(57171) +ERROR(57172) +ERROR(57173) +ERROR(57174) +ERROR(57175) +ERROR(57176) +ERROR(57177) +ERROR(57178) +ERROR(57179) +ERROR(57180) +ERROR(57181) +ERROR(57182) +ERROR(57183) +ERROR(57184) +ERROR(57185) +ERROR(57186) +ERROR(57187) +ERROR(57188) +ERROR(57189) +ERROR(57190) +ERROR(57191) +ERROR(57192) +ERROR(57193) +ERROR(57194) +ERROR(57195) +ERROR(57196) +ERROR(57197) +ERROR(57198) +ERROR(57199) +ERROR(57200) +ERROR(57201) +ERROR(57202) +ERROR(57203) +ERROR(57204) +ERROR(57205) +ERROR(57206) +ERROR(57207) +ERROR(57208) +ERROR(57209) +ERROR(57210) +ERROR(57211) +ERROR(57212) +ERROR(57213) +ERROR(57214) +ERROR(57215) +ERROR(57216) +ERROR(57217) +ERROR(57218) +ERROR(57219) +ERROR(57220) +ERROR(57221) +ERROR(57222) +ERROR(57223) +ERROR(57224) +ERROR(57225) +ERROR(57226) +ERROR(57227) +ERROR(57228) +ERROR(57229) +ERROR(57230) +ERROR(57231) +ERROR(57232) +ERROR(57233) +ERROR(57234) +ERROR(57235) +ERROR(57236) +ERROR(57237) +ERROR(57238) +ERROR(57239) +ERROR(57240) +ERROR(57241) +ERROR(57242) +ERROR(57243) +ERROR(57244) +ERROR(57245) +ERROR(57246) +ERROR(57247) +ERROR(57248) +ERROR(57249) +ERROR(57250) +ERROR(57251) +ERROR(57252) +ERROR(57253) +ERROR(57254) +ERROR(57255) +ERROR(57256) +ERROR(57257) +ERROR(57258) +ERROR(57259) +ERROR(57260) +ERROR(57261) +ERROR(57262) +ERROR(57263) +ERROR(57264) +ERROR(57265) +ERROR(57266) +ERROR(57267) +ERROR(57268) +ERROR(57269) +ERROR(57270) +ERROR(57271) +ERROR(57272) +ERROR(57273) +ERROR(57274) +ERROR(57275) +ERROR(57276) +ERROR(57277) +ERROR(57278) +ERROR(57279) +ERROR(57280) +ERROR(57281) +ERROR(57282) +ERROR(57283) +ERROR(57284) +ERROR(57285) +ERROR(57286) +ERROR(57287) +ERROR(57288) +ERROR(57289) +ERROR(57290) +ERROR(57291) +ERROR(57292) +ERROR(57293) +ERROR(57294) +ERROR(57295) +ERROR(57296) +ERROR(57297) +ERROR(57298) +ERROR(57299) +ERROR(57300) +ERROR(57301) +ERROR(57302) +ERROR(57303) +ERROR(57304) +ERROR(57305) +ERROR(57306) +ERROR(57307) +ERROR(57308) +ERROR(57309) +ERROR(57310) +ERROR(57311) +ERROR(57312) +ERROR(57313) +ERROR(57314) +ERROR(57315) +ERROR(57316) +ERROR(57317) +ERROR(57318) +ERROR(57319) +ERROR(57320) +ERROR(57321) +ERROR(57322) +ERROR(57323) +ERROR(57324) +ERROR(57325) +ERROR(57326) +ERROR(57327) +ERROR(57328) +ERROR(57329) +ERROR(57330) +ERROR(57331) +ERROR(57332) +ERROR(57333) +ERROR(57334) +ERROR(57335) +ERROR(57336) +ERROR(57337) +ERROR(57338) +ERROR(57339) +ERROR(57340) +ERROR(57341) +ERROR(57342) +ERROR(57343) +OK + diff --git a/ext/mbstring/tests/mb_convert_encoding_array.phpt b/ext/mbstring/tests/mb_convert_encoding_array.phpt new file mode 100644 index 0000000000..5bb78df028 --- /dev/null +++ b/ext/mbstring/tests/mb_convert_encoding_array.phpt @@ -0,0 +1,187 @@ +--TEST-- +Test mb_convert_encoding() function : array functionality +--SKIPIF-- +<?php +extension_loaded('mbstring') or die('skip'); +function_exists('mb_convert_encoding') or die("skip mb_convert_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string mb_convert_encoding(string $str, string $to_encoding [, mixed $from_encoding]) + * Description: Returns converted string in desired encoding + * Source code: ext/mbstring/mbstring.c + */ + +/* + * Test basic functionality of mb_convert_encoding() + */ + +echo "*** Testing mb_convert_encoding() : array functionality ***\n"; + +//All strings are the same when displayed in their respective encodings +$sjis_string[] = base64_decode('k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); +$sjis_string[] = base64_decode('k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); +$jis_string[] = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg=='); +$jis_string[] = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg=='); +$euc_jp_string[] = base64_decode('xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow=='); +$euc_jp_string[] = base64_decode('xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow=='); +$utf8_string[] = base64_decode('5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); +$utf8_string[] = base64_decode('5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); + + +function base64_encode_array($input) { + foreach ($input as $var) { + $ret[] = base64_encode($var); + } + return $ret; +} + +echo "\n-- Convert to JIS --\n"; +echo "JIS encoded string in base64:\n"; +var_dump(base64_encode_array($jis_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'JIS', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'JIS', 'EUC-JP'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'JIS', 'UTF-8'))); + +echo "\n-- Convert to EUC-JP --\n"; +echo "EUC-JP encoded string in base64:\n"; +var_dump(base64_encode_array($euc_jp_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'EUC-JP', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'EUC-JP', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'EUC-JP', 'UTF-8'))); + +echo "\n-- Convert to SJIS --\n"; +echo "SJIS encoded string in base64:\n"; +var_dump(base64_encode_array($sjis_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'SJIS', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'SJIS', 'EUC-JP'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'SJIS', 'UTF-8'))); + +echo "\n-- Convert to UTF-8 --\n"; +echo "UTF-8 encoded string in base64:\n"; +var_dump(base64_encode_array($utf8_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'UTF-8', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'UTF-8', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'UTF-8', 'EUC-JP'))); + +echo "Done"; +?> +--EXPECTF-- +*** Testing mb_convert_encoding() : array functionality *** + +-- Convert to JIS -- +JIS encoded string in base64: +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} +Converted Strings: +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} + +-- Convert to EUC-JP -- +EUC-JP encoded string in base64: +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} +Converted Strings: +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} + +-- Convert to SJIS -- +SJIS encoded string in base64: +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} +Converted Strings: +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} + +-- Convert to UTF-8 -- +UTF-8 encoded string in base64: +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +Converted Strings: +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +Done diff --git a/ext/mbstring/tests/mb_convert_encoding_array2.phpt b/ext/mbstring/tests/mb_convert_encoding_array2.phpt new file mode 100644 index 0000000000..29991f2165 --- /dev/null +++ b/ext/mbstring/tests/mb_convert_encoding_array2.phpt @@ -0,0 +1,223 @@ +--TEST-- +Test mb_convert_encoding() function : Circular references +--SKIPIF-- +<?php +extension_loaded('mbstring') or die('skip'); +function_exists('mb_convert_encoding') or die("skip mb_convert_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string mb_convert_encoding(string $str, string $to_encoding [, mixed $from_encoding]) + * Description: Returns converted string in desired encoding + * Source code: ext/mbstring/mbstring.c + */ + +/* + * Test basic functionality of mb_convert_encoding() + */ + +echo "*** Testing mb_convert_encoding() : Circular references ***\n"; + +//All strings are the same when displayed in their respective encodings +$sjis_string[] = base64_decode('k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); +$sjis_string[] = base64_decode('k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); +$tmp = &$sjis_string; +$sjis_string[] = $tmp; + +$jis_string[] = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg=='); +$jis_string[] = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg=='); +$tmp = &$jis_string; +$jis_string[] = $tmp; + +$euc_jp_string[] = base64_decode('xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow=='); +$euc_jp_string[] = base64_decode('xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow=='); +$tmp = &$euc_jp_string; +$euc_jp_string[] = $tmp; + +$utf8_string[] = base64_decode('5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); +$utf8_string[] = base64_decode('5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII='); +$tmp = &$utf8_string; +$utf8_string[] = $tmp; + + +function base64_encode_array($input) { + foreach ($input as $var) { + if (is_scalar($var)) + $ret[] = base64_encode($var); + } + return $ret; +} + +echo "\n-- Convert to JIS --\n"; +echo "JIS encoded string in base64:\n"; +var_dump(base64_encode_array($jis_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'JIS', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'JIS', 'EUC-JP'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'JIS', 'UTF-8'))); + +echo "\n-- Convert to EUC-JP --\n"; +echo "EUC-JP encoded string in base64:\n"; +var_dump(base64_encode_array($euc_jp_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'EUC-JP', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'EUC-JP', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'EUC-JP', 'UTF-8'))); + +echo "\n-- Convert to SJIS --\n"; +echo "SJIS encoded string in base64:\n"; +var_dump(base64_encode_array($sjis_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'SJIS', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'SJIS', 'EUC-JP'))); +var_dump(base64_encode_array(mb_convert_encoding($utf8_string, 'SJIS', 'UTF-8'))); + +echo "\n-- Convert to UTF-8 --\n"; +echo "UTF-8 encoded string in base64:\n"; +var_dump(base64_encode_array($utf8_string)); +echo "Converted Strings:\n"; +var_dump(base64_encode_array(mb_convert_encoding($sjis_string, 'UTF-8', 'SJIS'))); +var_dump(base64_encode_array(mb_convert_encoding($jis_string, 'UTF-8', 'JIS'))); +var_dump(base64_encode_array(mb_convert_encoding($euc_jp_string, 'UTF-8', 'EUC-JP'))); + +echo "Done"; +?> +--EXPECTF-- +*** Testing mb_convert_encoding() : Circular references *** + +-- Convert to JIS -- +JIS encoded string in base64: +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} +Converted Strings: + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" + [1]=> + string(68) "GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg==" +} + +-- Convert to EUC-JP -- +EUC-JP encoded string in base64: +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} +Converted Strings: + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" + [1]=> + string(52) "xvzL3LjspcalraW5pcikx6S5oaMwMTIzNKO1o7ajt6O4o7mhow==" +} + +-- Convert to SJIS -- +SJIS encoded string in base64: +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} +Converted Strings: + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" + [1]=> + string(52) "k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg==" +} + +-- Convert to UTF-8 -- +UTF-8 encoded string in base64: +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +Converted Strings: + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} + +Warning: mb_convert_encoding(): Cannot convert recursively referenced values in %s on line %d +array(2) { + [0]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" + [1]=> + string(72) "5pel5pys6Kqe44OG44Kt44K544OI44Gn44GZ44CCMDEyMzTvvJXvvJbvvJfvvJjvvJnjgII=" +} +Done diff --git a/ext/mbstring/tests/mb_internal_encoding_basic2.phpt b/ext/mbstring/tests/mb_internal_encoding_basic2.phpt new file mode 100644 index 0000000000..eb8fea2b9b --- /dev/null +++ b/ext/mbstring/tests/mb_internal_encoding_basic2.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test mb_internal_encoding() function : basic functionality +--INI-- +default_charset="" +input_encoding="ISO-8859-1" +output_encoding="ISO-8859-1" +internal_encoding="ISO-8859-1" +--SKIPIF-- +<?php +extension_loaded('mbstring') or die('skip'); +function_exists('mb_internal_encoding') or die("skip mb_internal_encoding() is not available in this build"); +?> +--FILE-- +<?php +/* Prototype : string mb_internal_encoding([string $encoding]) + * Description: Sets the current internal encoding or Returns + * the current internal encoding as a string + * Source code: ext/mbstring/mbstring.c + */ + +/* + * Test basic functionality of mb_internal_encoding + */ + +echo "*** Testing mb_internal_encoding() : basic functionality ***\n"; + +var_dump(ini_get('default_charset')); +var_dump(ini_get('input_encoding')); +var_dump(ini_get('output_encoding')); +var_dump(ini_get('internal_encoding')); +var_dump(ini_get('mbstring.http_input')); +var_dump(ini_get('mbstring.http_output')); +var_dump(ini_get('mbstring.internal_encoding')); + +var_dump(mb_internal_encoding()); //default internal encoding +var_dump(mb_internal_encoding('UTF-8')); //change internal encoding to UTF-8 +var_dump(mb_internal_encoding()); //check internal encoding is now set to UTF-8 + +echo "Done"; +?> +--EXPECTF-- +*** Testing mb_internal_encoding() : basic functionality *** +string(0) "" +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +string(0) "" +string(0) "" +string(0) "" +string(5) "UTF-8" +bool(true) +string(5) "UTF-8" +Done diff --git a/ext/mbstring/tests/mb_ord.phpt b/ext/mbstring/tests/mb_ord.phpt new file mode 100644 index 0000000000..e3f5343fd8 --- /dev/null +++ b/ext/mbstring/tests/mb_ord.phpt @@ -0,0 +1,40 @@ +--TEST-- +mb_ord() +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump( + 0x20bb7 === mb_ord("\u{20bb7}"), + 0x3f === mb_ord("\u{d800}"), + 0x8fa1ef === mb_ord("\x8f\xa1\xef", "EUC-JP-2004") +); + +// Invalid +var_dump( + mb_ord("\u{d800}", "typo"), + mb_ord("\u{d800}", "pass"), + mb_ord("\u{d800}", "jis"), + mb_ord("\u{d800}", "cp50222"), + mb_ord("\u{d800}", "utf-7") +); +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) + +Warning: mb_ord(): Unknown encoding "typo" %s 10 + +Warning: mb_ord(): Unsupported encoding "pass" %s 11 + +Warning: mb_ord(): Unsupported encoding "jis" %s 12 + +Warning: mb_ord(): Unsupported encoding "cp50222" %s 13 + +Warning: mb_ord(): Unsupported encoding "utf-7" %s 14 +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/mbstring/tests/mb_scrub.phpt b/ext/mbstring/tests/mb_scrub.phpt new file mode 100644 index 0000000000..131e13d536 --- /dev/null +++ b/ext/mbstring/tests/mb_scrub.phpt @@ -0,0 +1,14 @@ +--TEST-- +mb_scrub() +--SKIPIF-- +<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?> +--FILE-- +<?php +var_dump( + "?" === mb_scrub("\x80"), + "?" === mb_scrub("\x80", 'UTF-8') +); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/mcrypt/mcrypt_filter.c b/ext/mcrypt/mcrypt_filter.c index fc5aefbbe4..23ed098373 100644 --- a/ext/mcrypt/mcrypt_filter.c +++ b/ext/mcrypt/mcrypt_filter.c @@ -149,7 +149,7 @@ static php_stream_filter_ops php_mcrypt_filter_ops = { /* {{{ php_mcrypt_filter_create * Instantiate mcrypt filter */ -static php_stream_filter *php_mcrypt_filter_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *php_mcrypt_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { int encrypt = 1, iv_len, key_len, keyl, result; const char *cipher = filtername + sizeof("mcrypt.") - 1; diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 1e3cdad28f..412f9acf79 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -691,6 +691,9 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT); +#if MYSQL_VERSION_ID > 40101 || defined(MYSQLI_USE_MYSQLND) + REGISTER_LONG_CONSTANT("MYSQLI_OPT_READ_TIMEOUT", MYSQL_OPT_READ_TIMEOUT, CONST_CS | CONST_PERSISTENT); +#endif #if defined(MYSQLI_USE_MYSQLND) REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 7b403dff08..fb522130d6 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1712,14 +1712,14 @@ static int mysqli_options_get_option_zval_type(int option) #ifdef MYSQL_OPT_PROTOCOL case MYSQL_OPT_PROTOCOL: #endif /* MySQL 4.1.0 */ -#ifdef MYSQL_OPT_READ_TIMEOUT +#if MYSQL_VERSION_ID > 40101 || defined(MYSQLI_USE_MYSQLND) case MYSQL_OPT_READ_TIMEOUT: case MYSQL_OPT_WRITE_TIMEOUT: case MYSQL_OPT_GUESS_CONNECTION: case MYSQL_OPT_USE_EMBEDDED_CONNECTION: case MYSQL_OPT_USE_REMOTE_CONNECTION: case MYSQL_SECURE_AUTH: -#endif /* MySQL 4.1.1 */ +#endif #ifdef MYSQL_OPT_RECONNECT case MYSQL_OPT_RECONNECT: #endif /* MySQL 5.0.13 */ diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index cc5fa9f1c4..e1bbe21e96 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -20,6 +20,7 @@ require_once('skipifconnectfailure.inc'); 'MYSQLI_READ_DEFAULT_FILE' => true, 'MYSQLI_OPT_CONNECT_TIMEOUT' => true, 'MYSQLI_OPT_LOCAL_INFILE' => true, + 'MYSQLI_OPT_READ_TIMEOUT' => true, 'MYSQLI_INIT_COMMAND' => true, 'MYSQLI_CLIENT_SSL' => true, "MYSQLI_CLIENT_COMPRESS" => true, diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 10addf0f10..4b5087a3df 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1676,10 +1676,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c goto end; } switch (option) { -#ifdef WHEN_SUPPORTED_BY_MYSQLI case MYSQL_OPT_READ_TIMEOUT: case MYSQL_OPT_WRITE_TIMEOUT: -#endif case MYSQLND_OPT_SSL_KEY: case MYSQLND_OPT_SSL_CERT: case MYSQLND_OPT_SSL_CA: diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 111a4898d0..5437409088 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -818,13 +818,13 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys break; } case MYSQL_OPT_READ_TIMEOUT: + DBG_INF("MYSQL_OPT_READ_TIMEOUT"); net->data->options.timeout_read = *(unsigned int*) value; break; -#ifdef WHEN_SUPPORTED_BY_MYSQLI case MYSQL_OPT_WRITE_TIMEOUT: + DBG_INF("MYSQL_OPT_WRITE_TIMEOUT"); net->data->options.timeout_write = *(unsigned int*) value; break; -#endif case MYSQL_OPT_COMPRESS: net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION; break; diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index 87e5009183..42e06a6f8d 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -228,7 +228,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("mysqlnd.trace_alloc", NULL, PHP_INI_SYSTEM, OnUpdateString, trace_alloc_settings, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size", MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR, PHP_INI_ALL, OnUpdateNetCmdBufferSize, net_cmd_buffer_size, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.net_read_buffer_size", "32768",PHP_INI_ALL, OnUpdateLong, net_read_buffer_size, zend_mysqlnd_globals, mysqlnd_globals) - STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout", "31536000", PHP_INI_SYSTEM, OnUpdateLong, net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals) + STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout", "86400",PHP_INI_ALL, OnUpdateLong, net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.log_mask", "0", PHP_INI_ALL, OnUpdateLong, log_mask, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000", PHP_INI_ALL, OnUpdateLong, mempool_default_size, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, PHP_INI_PERDIR, OnUpdateString, sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index e36c533d37..100862cb1f 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -284,7 +284,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array #if 0 /* pre-evaluate functions: constant(x) - defined(x) function_exists(x) extension_loaded(x) BAD: interacts badly with Accelerator @@ -301,16 +300,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array zval *arg = &OPLINE_OP1_LITERAL(sv); char *fname = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].function_name; int flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len; - if(flen == sizeof("defined")-1 && zend_binary_strcasecmp(fname, flen, "defined", sizeof("defined")-1) == 0) { - zval c; - if(zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, 0 ELS_CC) != 0) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - LITERAL_BOOL(opline->op1, 1); - ZEND_OP1_TYPE(opline) = IS_CONST; - } - } else if((flen == sizeof("function_exists")-1 && zend_binary_strcasecmp(fname, flen, "function_exists", sizeof("function_exists")-1) == 0) || + if((flen == sizeof("function_exists")-1 && zend_binary_strcasecmp(fname, flen, "function_exists", sizeof("function_exists")-1) == 0) || (flen == sizeof("is_callable")-1 && zend_binary_strcasecmp(fname, flen, "is_callable", sizeof("is_callable")-1) == 0) ) { zend_function *function; diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index e8399ccc90..ea9c5c1323 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -436,7 +436,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } /* pre-evaluate constant functions: - defined(x) constant(x) function_exists(x) is_callable(x) @@ -518,24 +517,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) MAKE_NOP(opline); break; } - } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("defined")-1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), - "defined", sizeof("defined")-1) && - !zend_optimizer_is_disabled_func("defined", sizeof("defined") - 1)) { - zval t; - - if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(send1_opline)), &t, 0)) { - - ZVAL_TRUE(&t); - if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t)) { - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - MAKE_NOP(opline); - break; - } - } } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("constant")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "constant", sizeof("constant")-1) && @@ -552,21 +533,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } } - } else if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN) == 0 && - Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("strlen") - 1 && - !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), "strlen", sizeof("strlen") - 1) && - !zend_optimizer_is_disabled_func("strlen", sizeof("strlen") - 1)) { - zval t; - - ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(send1_opline))); - if (zend_optimizer_replace_by_const(op_array, opline + 1, IS_VAR, ZEND_RESULT(opline).var, &t)) { - literal_dtor(&ZEND_OP2_LITERAL(init_opline)); - MAKE_NOP(init_opline); - literal_dtor(&ZEND_OP1_LITERAL(send1_opline)); - MAKE_NOP(send1_opline); - MAKE_NOP(opline); - break; - } /* dirname(IS_CONST/IS_STRING) -> IS_CONST/IS_STRING */ } else if (Z_STRLEN(ZEND_OP2_LITERAL(init_opline)) == sizeof("dirname")-1 && !memcmp(Z_STRVAL(ZEND_OP2_LITERAL(init_opline)), diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index d9e3d5ee4f..480b1c5c18 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -37,6 +37,9 @@ typedef struct _func_info_t { info_func_t info_func; } func_info_t; +/* MSVC defines its own IN macro, undefine it here */ +#undef IN + #define F0(name, info) \ {name, sizeof(name)-1, (FUNC_MAY_WARN | (info)), NULL} #define F1(name, info) \ diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 0635cc5119..20a00906dd 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -274,7 +274,7 @@ zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d) { zend_ulong m, temp; - m = 1L << (sizeof(zend_ulong) * 8 - 1); + m = Z_UL(1) << (sizeof(zend_ulong) * 8 - 1); while (m != 0) { if (~a & c & m) { temp = (a | m) & -m; @@ -298,7 +298,7 @@ zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d) { zend_ulong m, temp; - m = 1L << (sizeof(zend_ulong) * 8 - 1); + m = Z_UL(1) << (sizeof(zend_ulong) * 8 - 1); while (m != 0) { if (b & d & m) { temp = (b - m) | (m - 1); @@ -321,7 +321,7 @@ zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d) { zend_ulong m, temp; - m = 1L << (sizeof(zend_ulong) * 8 - 1); + m = Z_UL(1) << (sizeof(zend_ulong) * 8 - 1); while (m != 0) { if (~a & ~c & m) { temp = (a | m) & -m; @@ -344,7 +344,7 @@ zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d) { zend_ulong m, temp; - m = 1L << (sizeof(zend_ulong) * 8 - 1); + m = Z_UL(1) << (sizeof(zend_ulong) * 8 - 1); while (m != 0) { if (b & ~d & m) { temp = (b | ~m) | (m - 1); diff --git a/ext/opcache/Optimizer/zend_inference.h b/ext/opcache/Optimizer/zend_inference.h index 4febc99cea..bd15cae3eb 100644 --- a/ext/opcache/Optimizer/zend_inference.h +++ b/ext/opcache/Optimizer/zend_inference.h @@ -163,14 +163,15 @@ static zend_always_inline uint32_t _const_op_type(const zval *zv) { } else if (Z_TYPE_P(zv) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(zv); uint32_t tmp = MAY_BE_ARRAY; + zend_string *str; + zval *val; if (Z_REFCOUNTED_P(zv)) { tmp |= MAY_BE_RC1 | MAY_BE_RCN; } else { tmp |= MAY_BE_RCN; } - zend_string *str; - zval *val; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, str, val) { if (str) { tmp |= MAY_BE_ARRAY_KEY_STRING; diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index a0a2df92de..5b98d62492 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -450,9 +450,8 @@ static void place_essa_pis( if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) { pi_type_mask(pi, mask_for_type_check(type)); } - if (type != IS_OBJECT && type != IS_RESOURCE) { - /* is_object() and is_resource() may return false, even though the value is - * an object/resource. */ + if (type != IS_RESOURCE) { + /* is_resource() may return false for closed resources */ if ((pi = add_pi(arena, op_array, dfg, ssa, j, bf, var))) { pi_not_type_mask(pi, mask_for_type_check(type)); } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 24a3d21ca2..e022b40950 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -133,7 +133,7 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement void *old_data = HT_GET_DATA_ADDR(ht); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ - ZCG(mem) = (void*)((char*)data + HT_USED_SIZE(ht)); + ZCG(mem) = (void*)((char*)data + ZEND_ALIGNED_SIZE(HT_USED_SIZE(ht))); memcpy(data, old_data, HT_USED_SIZE(ht)); efree(old_data); HT_SET_DATA_ADDR(ht, data); @@ -214,7 +214,7 @@ static void zend_hash_persist_immutable(HashTable *ht) void *data = ZCG(mem); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ - ZCG(mem) = (void*)((char*)data + HT_USED_SIZE(ht)); + ZCG(mem) = (void*)((char*)data + ZEND_ALIGNED_SIZE(HT_USED_SIZE(ht))); memcpy(data, HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht)); HT_SET_DATA_ADDR(ht, data); } diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index ab58f47d0f..88d3d357b1 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -64,7 +64,6 @@ #define timezone _timezone /* timezone is called _timezone in LibC */ #endif -#define DEFAULT_KEY_LENGTH 512 #define MIN_KEY_LENGTH 384 #define OPENSSL_ALGO_SHA1 1 @@ -3867,11 +3866,12 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req #ifdef HAVE_EVP_PKEY_EC case OPENSSL_KEYTYPE_EC: { + EC_KEY *eckey; if (req->curve_name == NID_undef) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing configuration value: 'curve_name' not set"); return NULL; } - EC_KEY *eckey = EC_KEY_new_by_curve_name(req->curve_name); + eckey = EC_KEY_new_by_curve_name(req->curve_name); if (eckey) { EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_generate_key(eckey) && diff --git a/ext/openssl/openssl.mak b/ext/openssl/openssl.mak deleted file mode 100644 index 9bc053b662..0000000000 --- a/ext/openssl/openssl.mak +++ /dev/null @@ -1,185 +0,0 @@ -# Temporarily here -- later may go into some batch file -# which will set this as an environment variable -PROJECT_ROOT = ..\.. - -# Module details -MODULE_NAME = php_ossl -MODULE_DESC = "PHP 7 - OpenSSL Extension" -VMAJ = 1 -VMIN = 0 -VREV = 0 - -#include the common settings -include $(PROJECT_ROOT)/netware/common.mif - -# OpenSSL directory -OSSL_DIR = P:/APPS/script/sw/OpenSSL - -# Build type defaults to 'release' -ifndef BUILD -BUILD = release -endif - -# Extensions of all input and output files -.SUFFIXES: -.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d - -# Source files -C_SRC = openssl.c \ - xp_ssl.c \ - start.c \ - -CPP_SRC_NODIR = $(notdir $(CPP_SRC)) -C_SRC_NODIR = $(notdir $(C_SRC)) -SRC_DIR = $(dir $(CPP_SRC) $(C_SRC)) - -# Library files -LIBRARY = $(OSSL_DIR)/lib/RSAglue.lib \ - $(OSSL_DIR)/lib/crypto.lib \ - $(OSSL_DIR)/lib/ssl.lib - -# Destination directories and files -OBJ_DIR = $(BUILD) -FINAL_DIR = $(BUILD) -MAP_FILE = $(FINAL_DIR)\$(MODULE_NAME).map -OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.obj) $(C_SRC_NODIR:.c=.obj)) -DEPDS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.d) $(C_SRC_NODIR:.c=.d)) - -# Binary file -ifndef BINARY - BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm -endif - -# Compile flags -C_FLAGS += -c -maxerrors 25 -msgstyle gcc -C_FLAGS += -wchar_t on -bool on -processor Pentium -C_FLAGS += -nostdinc -nosyspath -C_FLAGS += -relax_pointers # To remove type-casting errors -C_FLAGS += -DNETWARE -DZTS -C_FLAGS += -DUSE_OLD_FUNCTIONS -DCOMPILE_DL_OPENSSL=1 - -C_FLAGS += -I. -I$(PROJECT_ROOT) -I$(PROJECT_ROOT)/main -C_FLAGS += -I$(PROJECT_ROOT)/ext/standard -I$(PROJECT_ROOT)/netware -C_FLAGS += -I$(PROJECT_ROOT)/zend -I$(PROJECT_ROOT)/tsrm -C_FLAGS += -I- -I$(SDK_DIR)/include -I$(MWCIncludes) -C_FLAGS += -I$(OSSL_DIR)/include - -ifndef STACK_SIZE -STACK_SIZE=8192 -endif - -# Extra stuff based on debug / release builds -ifeq '$(BUILD)' 'debug' - SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym - C_FLAGS += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -sym internal -DDEBUGGING -DDKFBPON - C_FLAGS += -exc cw -DZEND_DEBUG=1 - LD_FLAGS += -sym on -sym codeview4 -osym $(SYM_FILE) - export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib -else - C_FLAGS += -opt all -inline on -inline smart -inline auto -sym off - C_FLAGS += -opt intrinsics -opt level=4 -DZEND_DEBUG=0 - LD_FLAGS += -sym off - export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib -endif - - -# Dependencies -MODULE = LibC \ - phplib -IMPORT = @$(SDK_DIR)/imports/libc.imp \ - @$(SDK_DIR)/imports/ws2nlm.imp \ - @$(SDK_DIR)/imports/netware.imp \ - @$(MPK_DIR)/import/mpkOrg.imp \ - @$(PROJECT_ROOT)/netware/phplib.imp -EXPORT = ($(MODULE_NAME)) get_module -API = OutputToScreen - -# Virtual paths -vpath %.cpp . -vpath %.c . ..\..\netware -vpath %.obj $(OBJ_DIR) - - -all: prebuild project - -.PHONY: all - -prebuild: - @if not exist $(OBJ_DIR) md $(OBJ_DIR) - -project: $(BINARY) - @echo Build complete. - -$(OBJ_DIR)/%.d: %.cpp - @echo Building Dependencies for $(<F) - @$(CC) -M $< $(C_FLAGS) -o $@ - -$(OBJ_DIR)/%.d: %.c - @echo Building Dependencies for $(<F) - @$(CC) -M $< $(C_FLAGS) -o $@ - -$(OBJ_DIR)/%.obj: %.cpp - @echo Compiling $?... - @$(CC) $< $(C_FLAGS) -o $@ - -$(OBJ_DIR)/%.obj: %.c - @echo Compiling $?... - @$(CC) $< $(C_FLAGS) -o $@ - - -$(BINARY): $(OBJECTS) - @echo Import $(IMPORT) > $(basename $@).def -ifdef API - @echo Import $(API) >> $(basename $@).def -endif - @echo Module $(MODULE) >> $(basename $@).def -ifdef EXPORT - @echo Export $(EXPORT) >> $(basename $@).def -endif - @echo AutoUnload >> $(basename $@).def -ifeq '$(BUILD)' 'debug' - @echo Debug >> $(basename $@).def -endif - @echo Flag_On 0x00000008 >> $(basename $@).def - @echo Start _LibCPrelude >> $(basename $@).def - @echo Exit _LibCPostlude >> $(basename $@).def - -# Two functions imported to build the openssl extension - @echo Import GetProcessSwitchCount >> $(basename $@).def - @echo Import RunningProcess >> $(basename $@).def - - $(MPKTOOL) $(XDCFLAGS) $(basename $@).xdc - @echo xdcdata $(basename $@).xdc >> $(basename $@).def - - @echo Linking $@... - @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link - - @echo $(LIBRARY) $(OBJECTS) >> $(basename $@).link - - @$(LINK) @$(basename $@).link - - -.PHONY: clean -clean: cleanobj cleanbin - -.PHONY: cleand -cleand: - @echo Deleting all dependency files... - -@del "$(OBJ_DIR)\*.d" - -.PHONY: cleanobj -cleanobj: - @echo Deleting all object files... - -@del "$(OBJ_DIR)\*.obj" - -.PHONY: cleanbin -cleanbin: - @echo Deleting binary files... - -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm" - @echo Deleting MAP, DEF files, etc.... - -@del "$(FINAL_DIR)\$(MODULE_NAME).map" - -@del "$(FINAL_DIR)\$(MODULE_NAME).def" - -@del "$(FINAL_DIR)\$(MODULE_NAME).link" -ifeq '$(BUILD)' 'debug' - -@del $(FINAL_DIR)\$(MODULE_NAME).sym -endif diff --git a/ext/openssl/tests/openssl_decrypt_ccm.phpt b/ext/openssl/tests/openssl_decrypt_ccm.phpt index 2107fea1fb..2bf93629f0 100644 --- a/ext/openssl/tests/openssl_decrypt_ccm.phpt +++ b/ext/openssl/tests/openssl_decrypt_ccm.phpt @@ -22,13 +22,13 @@ foreach ($tests as $idx => $test) { // no IV var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - NULL, $test['tag'], $test['aad'])); + NULL, $test['tag'], $test['aad'])); // failed because no AAD var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - $test['iv'], $test['tag'])); + $test['iv'], $test['tag'])); // failed because wrong tag var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - $test['iv'], str_repeat('x', 10), $test['aad'])); + $test['iv'], str_repeat('x', 10), $test['aad'])); ?> --EXPECTF-- diff --git a/ext/openssl/tests/openssl_decrypt_gcm.phpt b/ext/openssl/tests/openssl_decrypt_gcm.phpt index d8c464346a..4637f6b316 100644 --- a/ext/openssl/tests/openssl_decrypt_gcm.phpt +++ b/ext/openssl/tests/openssl_decrypt_gcm.phpt @@ -22,13 +22,13 @@ foreach ($tests as $idx => $test) { // no IV var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - NULL, $test['tag'], $test['aad'])); + NULL, $test['tag'], $test['aad'])); // failed because no AAD var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - $test['iv'], $test['tag'])); + $test['iv'], $test['tag'])); // failed because wrong tag var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, - $test['iv'], str_repeat('x', 16), $test['aad'])); + $test['iv'], str_repeat('x', 16), $test['aad'])); ?> --EXPECTF-- diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c index 573d5865a0..f34d36999f 100644 --- a/ext/pdo/pdo_sql_parser.c +++ b/ext/pdo/pdo_sql_parser.c @@ -554,40 +554,54 @@ safe: } plc->freeq = 1; } else { - zval tmp_param; - ZVAL_DUP(&tmp_param, parameter); - switch (Z_TYPE(tmp_param)) { - case IS_NULL: - plc->quoted = "NULL"; - plc->qlen = sizeof("NULL")-1; + enum pdo_param_type param_type = param->param_type; + zend_string *buf = NULL; + + /* assume all types are nullable */ + if (Z_TYPE_P(parameter) == IS_NULL) { + param_type = PDO_PARAM_NULL; + } + + switch (param_type) { + case PDO_PARAM_BOOL: + plc->quoted = zend_is_true(parameter) ? "1" : "0"; + plc->qlen = sizeof("1")-1; plc->freeq = 0; break; - case IS_FALSE: - case IS_TRUE: - convert_to_long(&tmp_param); - /* fall through */ - case IS_LONG: - case IS_DOUBLE: - convert_to_string(&tmp_param); - plc->qlen = Z_STRLEN(tmp_param); - plc->quoted = estrdup(Z_STRVAL(tmp_param)); + case PDO_PARAM_INT: + buf = zend_long_to_str(zval_get_long(parameter)); + + plc->qlen = ZSTR_LEN(buf); + plc->quoted = estrdup(ZSTR_VAL(buf)); plc->freeq = 1; break; + case PDO_PARAM_NULL: + plc->quoted = "NULL"; + plc->qlen = sizeof("NULL")-1; + plc->freeq = 0; + break; + default: - convert_to_string(&tmp_param); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), - Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, - param->param_type)) { + buf = zval_get_string(parameter); + if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), + ZSTR_LEN(buf), &plc->quoted, &plc->qlen, + param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); + if (buf) { + zend_string_release(buf); + } goto clean_up; } plc->freeq = 1; } - zval_dtor(&tmp_param); + + if (buf) { + zend_string_release(buf); + } } } else { zval *parameter; @@ -717,132 +731,6 @@ clean_up: return ret; } -#if 0 -int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, - int *outquery_len) -{ - Scanner s; - char *ptr; - int t; - int bindno = 0; - int newbuffer_len; - int padding; - HashTable *params = stmt->bound_params; - struct pdo_bound_param_data *param; - /* allocate buffer for query with expanded binds, ptr is our writing pointer */ - newbuffer_len = inquery_len; - - /* calculate the possible padding factor due to quoting */ - if(stmt->dbh->max_escaped_char_length) { - padding = stmt->dbh->max_escaped_char_length; - } else { - padding = 3; - } - if(params) { - ZEND_HASH_FOREACH_PTR(params, param) { - if(param->parameter) { - convert_to_string(param->parameter); - /* accommodate a string that needs to be fully quoted - bind placeholders are at least 2 characters, so - the accommodate their own "'s - */ - newbuffer_len += padding * Z_STRLEN_P(param->parameter); - } - } ZEND_HASH_FOREACH_END(); - } - *outquery = (char *) emalloc(newbuffer_len + 1); - *outquery_len = 0; - - ptr = *outquery; - s.cur = inquery; - while((t = scan(&s)) != PDO_PARSER_EOI) { - if(t == PDO_PARSER_TEXT) { - memcpy(ptr, s.tok, s.cur - s.tok); - ptr += (s.cur - s.tok); - *outquery_len += (s.cur - s.tok); - } - else if(t == PDO_PARSER_BIND) { - if(!params) { - /* error */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - /* lookup bind first via hash and then index */ - /* stupid keys need to be null-terminated, even though we know their length */ - if((NULL != (param = zend_hash_str_find_ptr(params, s.tok, s.cur-s.tok)) - || - NULL != (params = zend_hash_index_find_ptr(params, bindno))) - { - char *quotedstr; - int quotedstrlen; - /* restore the in-string key, doesn't need null-termination here */ - /* currently everything is a string here */ - - /* quote the bind value if necessary */ - if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), "edstr, "edstrlen)) - { - memcpy(ptr, quotedstr, quotedstrlen); - ptr += quotedstrlen; - *outquery_len += quotedstrlen; - efree(quotedstr); - } else { - memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); - ptr += Z_STRLEN_P(param->parameter); - *outquery_len += (Z_STRLEN_P(param->parameter)); - } - } - else { - /* error and cleanup */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - bindno++; - } - else if(t == PDO_PARSER_BIND_POS) { - if(!params) { - /* error */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - /* lookup bind by index */ - if(NULL != (params = zend_hash_index_find_ptr(params, bindno))) - { - char *quotedstr; - int quotedstrlen; - /* currently everything is a string here */ - - /* quote the bind value if necessary */ - if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), "edstr, "edstrlen)) - { - memcpy(ptr, quotedstr, quotedstrlen); - ptr += quotedstrlen; - *outquery_len += quotedstrlen; - efree(quotedstr); - } else { - memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); - ptr += Z_STRLEN_P(param->parameter); - *outquery_len += (Z_STRLEN_P(param->parameter)); - } - } - else { - /* error and cleanup */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - bindno++; - } - } - *ptr = '\0'; - return 0; -} -#endif - /* * Local variables: * tab-width: 4 diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 20b9976850..16fc29f0f1 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -240,40 +240,54 @@ safe: } plc->freeq = 1; } else { - zval tmp_param; - ZVAL_DUP(&tmp_param, parameter); - switch (Z_TYPE(tmp_param)) { - case IS_NULL: - plc->quoted = "NULL"; - plc->qlen = sizeof("NULL")-1; + enum pdo_param_type param_type = param->param_type; + zend_string *buf = NULL; + + /* assume all types are nullable */ + if (Z_TYPE_P(parameter) == IS_NULL) { + param_type = PDO_PARAM_NULL; + } + + switch (param_type) { + case PDO_PARAM_BOOL: + plc->quoted = zend_is_true(parameter) ? "1" : "0"; + plc->qlen = sizeof("1")-1; plc->freeq = 0; break; - case IS_FALSE: - case IS_TRUE: - convert_to_long(&tmp_param); - /* fall through */ - case IS_LONG: - case IS_DOUBLE: - convert_to_string(&tmp_param); - plc->qlen = Z_STRLEN(tmp_param); - plc->quoted = estrdup(Z_STRVAL(tmp_param)); + case PDO_PARAM_INT: + buf = zend_long_to_str(zval_get_long(parameter)); + + plc->qlen = ZSTR_LEN(buf); + plc->quoted = estrdup(ZSTR_VAL(buf)); plc->freeq = 1; break; + case PDO_PARAM_NULL: + plc->quoted = "NULL"; + plc->qlen = sizeof("NULL")-1; + plc->freeq = 0; + break; + default: - convert_to_string(&tmp_param); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), - Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, - param->param_type)) { + buf = zval_get_string(parameter); + if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), + ZSTR_LEN(buf), &plc->quoted, &plc->qlen, + param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); + if (buf) { + zend_string_release(buf); + } goto clean_up; } plc->freeq = 1; } - zval_dtor(&tmp_param); + + if (buf) { + zend_string_release(buf); + } } } else { zval *parameter; @@ -403,132 +417,6 @@ clean_up: return ret; } -#if 0 -int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery, - int *outquery_len) -{ - Scanner s; - char *ptr; - int t; - int bindno = 0; - int newbuffer_len; - int padding; - HashTable *params = stmt->bound_params; - struct pdo_bound_param_data *param; - /* allocate buffer for query with expanded binds, ptr is our writing pointer */ - newbuffer_len = inquery_len; - - /* calculate the possible padding factor due to quoting */ - if(stmt->dbh->max_escaped_char_length) { - padding = stmt->dbh->max_escaped_char_length; - } else { - padding = 3; - } - if(params) { - ZEND_HASH_FOREACH_PTR(params, param) { - if(param->parameter) { - convert_to_string(param->parameter); - /* accommodate a string that needs to be fully quoted - bind placeholders are at least 2 characters, so - the accommodate their own "'s - */ - newbuffer_len += padding * Z_STRLEN_P(param->parameter); - } - } ZEND_HASH_FOREACH_END(); - } - *outquery = (char *) emalloc(newbuffer_len + 1); - *outquery_len = 0; - - ptr = *outquery; - s.cur = inquery; - while((t = scan(&s)) != PDO_PARSER_EOI) { - if(t == PDO_PARSER_TEXT) { - memcpy(ptr, s.tok, s.cur - s.tok); - ptr += (s.cur - s.tok); - *outquery_len += (s.cur - s.tok); - } - else if(t == PDO_PARSER_BIND) { - if(!params) { - /* error */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - /* lookup bind first via hash and then index */ - /* stupid keys need to be null-terminated, even though we know their length */ - if((NULL != (param = zend_hash_str_find_ptr(params, s.tok, s.cur-s.tok)) - || - NULL != (params = zend_hash_index_find_ptr(params, bindno))) - { - char *quotedstr; - int quotedstrlen; - /* restore the in-string key, doesn't need null-termination here */ - /* currently everything is a string here */ - - /* quote the bind value if necessary */ - if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), "edstr, "edstrlen)) - { - memcpy(ptr, quotedstr, quotedstrlen); - ptr += quotedstrlen; - *outquery_len += quotedstrlen; - efree(quotedstr); - } else { - memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); - ptr += Z_STRLEN_P(param->parameter); - *outquery_len += (Z_STRLEN_P(param->parameter)); - } - } - else { - /* error and cleanup */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - bindno++; - } - else if(t == PDO_PARSER_BIND_POS) { - if(!params) { - /* error */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - /* lookup bind by index */ - if(NULL != (params = zend_hash_index_find_ptr(params, bindno))) - { - char *quotedstr; - int quotedstrlen; - /* currently everything is a string here */ - - /* quote the bind value if necessary */ - if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), "edstr, "edstrlen)) - { - memcpy(ptr, quotedstr, quotedstrlen); - ptr += quotedstrlen; - *outquery_len += quotedstrlen; - efree(quotedstr); - } else { - memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter)); - ptr += Z_STRLEN_P(param->parameter); - *outquery_len += (Z_STRLEN_P(param->parameter)); - } - } - else { - /* error and cleanup */ - efree(*outquery); - *outquery = NULL; - return (int) (s.cur - inquery); - } - bindno++; - } - } - *ptr = '\0'; - return 0; -} -#endif - /* * Local variables: * tab-width: 4 diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index f4420dcbdd..7f3acc7395 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -46,7 +46,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64); # define FALSE 0 #endif -#define PDO_DRIVER_API 20150127 +#define PDO_DRIVER_API 20161020 enum pdo_param_type { PDO_PARAM_NULL, @@ -529,9 +529,6 @@ struct pdo_column_data { size_t maxlen; zend_ulong precision; enum pdo_param_type param_type; - - /* don't touch this unless your name is dbdo */ - void *dbdo_data; }; /* describes a bound parameter */ diff --git a/ext/pdo/tests/bug_65946.phpt b/ext/pdo/tests/bug_65946.phpt index c636db5204..76a4e8db89 100644 --- a/ext/pdo/tests/bug_65946.phpt +++ b/ext/pdo/tests/bug_65946.phpt @@ -18,9 +18,7 @@ $db->exec('CREATE TABLE test(id int)'); $db->exec('INSERT INTO test VALUES(1)'); switch ($db->getAttribute(PDO::ATTR_DRIVER_NAME)) { case 'dblib': - // if :limit is used, the value will be quoted as '1', which is invalid syntax - // this is a bug, to be addressed separately from adding these tests to pdo_dblib - $sql = 'SELECT TOP 1 * FROM test'; + $sql = 'SELECT TOP :limit * FROM test'; break; case 'firebird': $sql = 'SELECT FIRST :limit * FROM test'; diff --git a/ext/pdo/tests/bug_73234.phpt b/ext/pdo/tests/bug_73234.phpt new file mode 100644 index 0000000000..43b484e9b2 --- /dev/null +++ b/ext/pdo/tests/bug_73234.phpt @@ -0,0 +1,43 @@ +--TEST-- +PDO Common: Bug #73234 (Emulated statements let value dictate parameter type) +--SKIPIF-- +<?php +if (!extension_loaded('pdo')) die('skip'); +$dir = getenv('REDIR_TEST_DIR'); +if (false == $dir) die('skip no driver'); +require_once $dir . 'pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/'); +require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; + +$db = PDOTest::factory(); +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +$db->exec('CREATE TABLE test(id INT NULL)'); + +$stmt = $db->prepare('INSERT INTO test VALUES(:value)'); + +$stmt->bindValue(':value', 0, PDO::PARAM_NULL); +$stmt->execute(); + +$stmt->bindValue(':value', null, PDO::PARAM_NULL); +$stmt->execute(); + +$stmt = $db->query('SELECT * FROM test'); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +?> +--EXPECT-- +array(2) { + [0]=> + array(1) { + ["id"]=> + NULL + } + [1]=> + array(1) { + ["id"]=> + NULL + } +} diff --git a/ext/pdo/tests/pdo_024.phpt b/ext/pdo/tests/pdo_024.phpt index 571ea73286..a70e924d49 100644 --- a/ext/pdo/tests/pdo_024.phpt +++ b/ext/pdo/tests/pdo_024.phpt @@ -19,7 +19,7 @@ $db->exec('create table test (id int, name varchar(10) null)'); $stmt = $db->prepare('insert into test (id, name) values(0, :name)'); $name = NULL; $before_bind = $name; -$stmt->bindParam(':name', $name); +$stmt->bindParam(':name', $name, PDO::PARAM_NULL); if ($name !== $before_bind) { echo "bind: fail\n"; } else { diff --git a/ext/pdo/tests/pdo_drivers_basic.phpt b/ext/pdo/tests/pdo_drivers_basic.phpt new file mode 100644 index 0000000000..c57c52e31e --- /dev/null +++ b/ext/pdo/tests/pdo_drivers_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test normal operation of PDO::getAvailableDrivers / pdo_drivers +--CREDITS-- +Amo Chohan <amo.chohan@gmail.com> +--SKIPIF-- +<?php +if (!extension_loaded('pdo')) die('skip'); +--FILE-- +<?php +var_dump(is_array(PDO::getAvailableDrivers())); +var_dump(is_array(pdo_drivers())); +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/pdo/tests/pdo_drivers_error.phpt b/ext/pdo/tests/pdo_drivers_error.phpt new file mode 100644 index 0000000000..5a371f02bc --- /dev/null +++ b/ext/pdo/tests/pdo_drivers_error.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test that PDO::getAvailableDrivers / pdo_drivers does not accept any parameters +--CREDITS-- +Amo Chohan <amo.chohan@gmail.com> +--SKIPIF-- +<?php +if (!extension_loaded('pdo')) die('skip'); +--FILE-- +<?php +PDO::getAvailableDrivers('fail'); +pdo_drivers('fail'); +--EXPECTF-- +Warning: PDO::getAvailableDrivers() expects exactly 0 parameters, 1 given in %s on line %d + +Warning: pdo_drivers() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/pdo/tests/pecl_bug_5217.phpt b/ext/pdo/tests/pecl_bug_5217.phpt index 34de925e41..7fe2bf4af7 100644 --- a/ext/pdo/tests/pecl_bug_5217.phpt +++ b/ext/pdo/tests/pecl_bug_5217.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO Common: PECL Bug #5217 (serialize/unserialze safety) +PDO Common: PECL Bug #5217 (serialize/unserialize safety) --SKIPIF-- <?php # vim:ft=php if (!extension_loaded('pdo')) die('skip'); diff --git a/ext/pdo_dblib/CREDITS b/ext/pdo_dblib/CREDITS index 91a8057be3..35388e6c02 100644 --- a/ext/pdo_dblib/CREDITS +++ b/ext/pdo_dblib/CREDITS @@ -1,2 +1,2 @@ DB-LIB (MS SQL, Sybase) -Wez Furlong, Frank M. Kromann +Wez Furlong, Frank M. Kromann, Adam Baratz diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index a230db2984..18e9ab65c1 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -167,7 +167,6 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; - RETCODE ret; dbsetuserdata(H->link, (BYTE*) &S->err); @@ -181,7 +180,7 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt) return 0; } - ret = pdo_dblib_stmt_next_rowset_no_cancel(stmt); + pdo_dblib_stmt_next_rowset_no_cancel(stmt); stmt->row_count = DBCOUNT(H->link); stmt->column_count = dbnumcols(H->link); @@ -269,7 +268,9 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, data_len = dbdatlen(H->link, colno+1); if (data_len != 0 || data != NULL) { - if (stmt->dbh->stringify) { + /* force stringify if DBBIGINT won't fit in zend_long */ + /* this should only be an issue for 32-bit machines */ + if (stmt->dbh->stringify || (coltype == SQLINT8 && sizeof(zend_long) < sizeof(DBBIGINT))) { switch (coltype) { case SQLDECIMAL: case SQLNUMERIC: @@ -278,6 +279,7 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, case SQLMONEYN: case SQLFLT4: case SQLFLT8: + case SQLINT8: case SQLINT4: case SQLINT2: case SQLINT1: @@ -352,22 +354,28 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, break; } + case SQLINT8: { + zv = emalloc(sizeof(zval)); + ZVAL_LONG(zv, *(DBBIGINT *) data); + + break; + } case SQLINT4: { zv = emalloc(sizeof(zval)); - ZVAL_LONG(zv, (long) ((int) *(DBINT *) data)); + ZVAL_LONG(zv, *(DBINT *) data); break; } case SQLINT2: { zv = emalloc(sizeof(zval)); - ZVAL_LONG(zv, (long) ((int) *(DBSMALLINT *) data)); + ZVAL_LONG(zv, *(DBSMALLINT *) data); break; } case SQLINT1: case SQLBIT: { zv = emalloc(sizeof(zval)); - ZVAL_LONG(zv, (long) ((int) *(DBTINYINT *) data)); + ZVAL_LONG(zv, *(DBTINYINT *) data); break; } @@ -385,11 +393,7 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, break; } -#ifdef SQLUNIQUE case SQLUNIQUE: { -#else - case 36: { /* FreeTDS hack */ -#endif if (H->stringify_uniqueidentifier) { // 36-char hex string representation tmp_data_len = 36; tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1); diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index 01c538eed7..0b2c3a5dd0 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -53,6 +53,7 @@ # define SQLINT1 SYBINT1 # define SQLINT2 SYBINT2 # define SQLINT4 SYBINT4 +# define SQLINT8 SYBINT8 # define SQLINTN SYBINTN # define SQLBIT SYBBIT # define SQLFLT4 SYBREAL diff --git a/ext/pdo_dblib/tests/bug_73396.phpt b/ext/pdo_dblib/tests/bug_73396.phpt new file mode 100644 index 0000000000..909e1194c0 --- /dev/null +++ b/ext/pdo_dblib/tests/bug_73396.phpt @@ -0,0 +1,20 @@ +--TEST-- +PDO_DBLIB: bigint columns are returned as strings +--SKIPIF-- +<?php +if (!extension_loaded('pdo_dblib')) die('skip not loaded'); +require dirname(__FILE__) . '/config.inc'; +?> +--FILE-- +<?php +require dirname(__FILE__) . '/config.inc'; + +// on 64-bit machines, these columns should come back as ints +// on 32-bit machines, they will come back as strings because zend_long isn't big enough +$expected = PHP_INT_SIZE == 8 ? 1 : '1'; + +$stmt = $db->query('SELECT CAST(1 AS bigint)'); +var_dump($stmt->fetchColumn() === $expected); +?> +--EXPECT-- +bool(true) diff --git a/ext/pdo_mysql/tests/mysql_pdo_test.inc b/ext/pdo_mysql/tests/mysql_pdo_test.inc index 7a97bb4630..4e953ed7e1 100644 --- a/ext/pdo_mysql/tests/mysql_pdo_test.inc +++ b/ext/pdo_mysql/tests/mysql_pdo_test.inc @@ -55,7 +55,7 @@ class MySQLPDOTest extends PDOTest { strpos(PDO_MYSQL_TEST_DSN, ':') + 1, strlen(PDO_MYSQL_TEST_DSN)); - // no real parser - any excotic setting can fool us + // no real parser - any exotic setting can fool us $parts = explode(';', $dsn); foreach ($parts as $k => $v) { $tmp = explode('=', $v); diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 1aa3855af0..32f583bd76 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1510,20 +1510,6 @@ err: } /* }}} */ -#if 0 -/* {{{ php_pgsql_get_default_link - */ -static int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS) -{ - if (PGG(default_link)==-1) { /* no link opened yet, implicitly open one */ - ht = 0; - php_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); - } - return PGG(default_link); -} -/* }}} */ -#endif - /* {{{ proto resource pg_connect(string connection_string[, int connect_type] | [string host, string port [, string options [, string tty,]]] string database) Open a PostgreSQL connection */ PHP_FUNCTION(pg_connect) diff --git a/ext/session/tests/save_handler.inc b/ext/session/tests/save_handler.inc index 79ebaaabb0..301a2d65c5 100644 --- a/ext/session/tests/save_handler.inc +++ b/ext/session/tests/save_handler.inc @@ -1,31 +1,77 @@ <?php DEFINE("SESSION_FILE_PREFIX" ,"session_test_"); + +/* + * == General Return Value Rule == + * + * Returning FALSE indicates FATAL error. + * Exceptions are: gc(), validate_sid() + * + * == Session Data Lock == + * + * Session data lock is mandatory. Lock must be exclusive. i.e. Block read also. + * + * == Collision Detection == + * + * Collision detection is mandatory to reject attacker initialized session ID. + * Coolision detection is absolute requirement for secure session. + */ + + +/* Open session data database */ function open($save_path, $session_name) { + // string $save_path - Directory path, connection strings, etc. Default: session.save_path + // string $session_name - Session ID cookie name. Default: session.name + global $session_save_path, $name; $session_save_path = $save_path; $name = $session_name; echo "Open [${session_save_path},${session_name}]\n"; + + // MUST return bool. Return TRUE for success. return true; } +/* Close session data database */ function close() { + // void parameter + // NOTE: This function should unlock session data, if write() does not unlock it. + global $session_save_path, $name; echo "Close [${session_save_path},${name}]\n"; + + // MUST return bool. Return TRUE for success. return true; } +/* Read session data */ function read($id) { + // string $id - Session ID string + // NOTE: All production session save handler MUST implement "exclusive" lock. + // e.g. Use "serializable transaction isolation level" with RDBMS. + // read() would be the best place for locking for most save handlers. + global $session_save_path, $name, $session_id; $session_id = $id; echo "Read [${session_save_path},${id}]\n"; $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; // read MUST create file. Otherwise, strict mode will not work touch($session_file); + + // MUST return STRING for successful read(). + // Return FALSE only when there is error. i.e. Do not return FALSE + // for non-existing session data for the $id. return (string) @file_get_contents($session_file); } +/* Write session data */ function write($id, $session_data) { + // string $id - Session ID string + // string $session_data - Session data string serialized by session serializer. + // NOTE: This function may unlock session data locked by read(). If write() is + // is not suitable place your handler to unlock. Unlock data at close(). + global $session_save_path, $name, $session_id; $session_id = $id; echo "Write [${session_save_path},${id},${session_data}]\n"; @@ -35,18 +81,30 @@ function write($id, $session_data) { fclose($fp); return $return === FALSE ? FALSE : TRUE; } + + // MUST return bool. Return TRUE for success. return false; } +/* Remove specified session */ function destroy($id) { + // string $id - Session ID string + global $session_save_path, $name; echo "Destroy [${session_save_path},${id}]\n"; $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; unlink($session_file); + + // MUST return bool. Return TRUE for success. + // Return FALSE only when there is error. i.e. Do not return FALSE + // for non-existing session data for the $id. return true; } +/* Perform garbage collection */ function gc($maxlifetime) { + // long $maxlifetime - GC TTL in seconds. Default: session.gc_maxlifetime + global $session_save_path, $name; $directory = opendir($session_save_path."/"); $length = strlen(SESSION_FILE_PREFIX); @@ -59,35 +117,67 @@ function gc($maxlifetime) { } } closedir($directory); - return true; + + // SHOULD return long (number of deleted sessions). + // Returning TRUE works also, but it will not report correct number of deleted sessions. + // Return negative value for error. FALSE does not work because it's the same as 0. + return 1; } +/* Create new secure session ID */ function create_sid() { + // void parameter + // NOTE: Defining create_sid() is mandatory because validate_sid() is mandatory for + // security reasons for production save handler. + // PHP 7.1 has session_create_id() for secure session ID generation. Older PHPs + // must generate secure session ID by yourself. + // e.g. hash('sha2', random_bytes(64)) or use /dev/urandom + $id = ('PHPT-'.time()); echo "CreateID [${id}]\n"; + + // MUST return session ID string. + // Return FALSE for error. return $id; } +/* Check session ID collision */ function validate_sid($id) { + // string $id - Session ID string + global $session_save_path, $name; echo "ValidateID [${session_save_path},${id}]\n"; $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; $ret = file_exists($session_file); + + // MUST return bool. Return TRUE for collision. + // NOTE: This handler is mandatory for session security. + // All save handlers MUST implement this handler. + // Check session ID collision, return TRUE when it collides. + // Otherwise, return FALSE. return $ret; } +/* Update session data access time stamp WITHOUT writing $session_data */ function update($id, $session_data) { + // string $id - Session ID string + // string $session_data - Session data serialized by session serializer + // NOTE: This handler is optional. If your session database cannot + // support time stamp updating, you must not define this. + global $session_save_path, $name; echo "Update [${session_save_path},${id}]\n"; $session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id; $ret = touch($session_file); + + // MUST return bool. Return TRUE for success. return $ret; } function feature() { /* NOT IMPLEMENTED YET */ - /* TYPES: gc, create_sid, use_strict_mode, minizie_lock, lazy_write + /* TYPES: gc, create_sid, use_strict_mode, minimzie_lock, lazy_write /* VALUES: 0=unknown, 1=supported, 2=partially supported, 3=unsupported */ return array('gc'=>0, 'create_sid'=>1, diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 7870377687..47b8826374 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -36,8 +36,6 @@ #include "zend_interfaces.h" #include "sxe.h" -#define SXE_ELEMENT_BY_NAME 0 - zend_class_entry *sxe_class_entry = NULL; PHP_SXE_API zend_class_entry *sxe_get_element_class_entry() /* {{{ */ @@ -347,20 +345,10 @@ long_dim: _node_as_zval(sxe, node, rv, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix); } } else { -#if SXE_ELEMENT_BY_NAME - int newtype; - - GET_NODE(sxe, node); - node = sxe_get_element_by_name(sxe, node, &name, &newtype); - if (node) { - _node_as_zval(sxe, node, rv, newtype, name, sxe->iter.nsprefix, sxe->iter.isprefix); - } -#else /* In BP_VAR_IS mode only return a proper node if it actually exists. */ if (type != BP_VAR_IS || sxe_find_element_by_name(sxe, node->children, (xmlChar *) name)) { _node_as_zval(sxe, node, rv, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix, sxe->iter.isprefix); } -#endif } } } diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index ce5cdaf313..37f3453c01 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -74,8 +74,10 @@ struct sockaddr_un { PHP_SOCKETS_API int php_sockets_le_socket(void); PHP_SOCKETS_API php_socket *php_create_socket(void); PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc); +PHP_SOCKETS_API void php_destroy_sockaddr(zend_resource *rsrc); #define php_sockets_le_socket_name "Socket" +#define php_sockets_le_addrinfo_name "AddressInfo" #define PHP_SOCKET_ERROR(socket, msg, errn) \ do { \ diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index c23f984720..432551a920 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -97,6 +97,9 @@ ZEND_DECLARE_MODULE_GLOBALS(sockets) static int le_socket; #define le_socket_name php_sockets_le_socket_name +static int le_addrinfo; +#define le_addrinfo_name php_sockets_le_addrinfo_name + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_select, 0, 0, 4) ZEND_ARG_INFO(1, read_fds) @@ -271,6 +274,25 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_cmsg_space, 0, 0, 2) ZEND_ARG_INFO(0, level) ZEND_ARG_INFO(0, type) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_lookup, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, service) + ZEND_ARG_INFO(0, hints) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_connect, 0, 0, 1) + ZEND_ARG_INFO(0, addr) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_bind, 0, 0, 1) + ZEND_ARG_INFO(0, addr) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_addrinfo_explain, 0, 0, 1) + ZEND_ARG_INFO(0, addr) +ZEND_END_ARG_INFO() + /* }}} */ static PHP_GINIT_FUNCTION(sockets); @@ -310,6 +332,10 @@ PHP_FUNCTION(socket_last_error); PHP_FUNCTION(socket_clear_error); PHP_FUNCTION(socket_import_stream); PHP_FUNCTION(socket_export_stream); +PHP_FUNCTION(socket_addrinfo_lookup); +PHP_FUNCTION(socket_addrinfo_connect); +PHP_FUNCTION(socket_addrinfo_bind); +PHP_FUNCTION(socket_addrinfo_explain); /* {{{ sockets_functions[] */ @@ -348,6 +374,10 @@ const zend_function_entry sockets_functions[] = { PHP_FE(socket_sendmsg, arginfo_socket_sendmsg) PHP_FE(socket_recvmsg, arginfo_socket_recvmsg) PHP_FE(socket_cmsg_space, arginfo_socket_cmsg_space) + PHP_FE(socket_addrinfo_lookup, arginfo_socket_addrinfo_lookup) + PHP_FE(socket_addrinfo_connect, arginfo_socket_addrinfo_connect) + PHP_FE(socket_addrinfo_bind, arginfo_socket_addrinfo_bind) + PHP_FE(socket_addrinfo_explain, arginfo_socket_addrinfo_explain) /* for downwards compatibility */ PHP_FALIAS(socket_getopt, socket_get_option, arginfo_socket_get_option) @@ -422,6 +452,17 @@ PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc) /* {{{ */ } /* }}} */ +PHP_SOCKETS_API void php_destroy_addrinfo(zend_resource *rsrc) /* {{{ */ +{ + struct addrinfo *addr = rsrc->ptr; + efree(addr->ai_addr); + if (addr->ai_canonname != NULL) { + efree(addr->ai_canonname); + } + efree(addr); +} +/* }}} */ + static int php_open_listen_sock(php_socket **php_sock, int port, int backlog) /* {{{ */ { struct sockaddr_in la; @@ -625,6 +666,7 @@ static PHP_MINIT_FUNCTION(sockets) ZEND_TSRMLS_CACHE_UPDATE(); #endif le_socket = zend_register_list_destructors_ex(php_destroy_socket, NULL, le_socket_name, module_number); + le_addrinfo = zend_register_list_destructors_ex(php_destroy_addrinfo, NULL, le_addrinfo_name, module_number); REGISTER_LONG_CONSTANT("AF_UNIX", AF_UNIX, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("AF_INET", AF_INET, CONST_CS | CONST_PERSISTENT); @@ -744,6 +786,20 @@ static PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS, CONST_CS | CONST_PERSISTENT); #endif + REGISTER_LONG_CONSTANT("AI_PASSIVE", AI_PASSIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_CANONNAME", AI_CANONNAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_NUMERICHOST", AI_NUMERICHOST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_V4MAPPED", AI_V4MAPPED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_ALL", AI_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_ADDRCONFIG", AI_ADDRCONFIG, CONST_CS | CONST_PERSISTENT); +#ifdef __USE_GNU + REGISTER_LONG_CONSTANT("AI_IDN", AI_IDN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_CANONIDN", AI_CANONIDN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_IDN_ALLOW_UNASSIGNED", AI_IDN_ALLOW_UNASSIGNED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AI_IDN_USE_STD3_ASCII_RULES", AI_IDN_USE_STD3_ASCII_RULES, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("AI_NUMERICSERV", AI_NUMERICSERV, CONST_CS | CONST_PERSISTENT); + php_socket_sendrecvmsg_init(INIT_FUNC_ARGS_PASSTHRU); return SUCCESS; @@ -2456,6 +2512,254 @@ PHP_FUNCTION(socket_export_stream) } /* }}} */ +/* {{{ proto resource addrinfo socket_addrinfo_lookup(string hostname[, mixed service, array hints]) + Gets array with contents of getaddrinfo about the given hostname. */ +PHP_FUNCTION(socket_addrinfo_lookup) +{ + char *service = NULL; + size_t service_len; + zend_string *hostname, *key; + zval *hint, *zhints = NULL; + + struct addrinfo hints, *result, *rp, *res; + + memset(&hints, 0, sizeof(hints)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|sa", &hostname, &service, &service_len, &zhints) == FAILURE) { + RETURN_NULL(); + } + + if (zhints) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zhints), key, hint) { + if (key) { + if (zend_string_equals_literal(key, "ai_flags")) { + hints.ai_flags = zval_get_long(hint); + } else if (zend_string_equals_literal(key, "ai_socktype")) { + hints.ai_socktype = zval_get_long(hint); + } else if (zend_string_equals_literal(key, "ai_protocol")) { + hints.ai_protocol = zval_get_long(hint); + } else if (zend_string_equals_literal(key, "ai_family")) { + hints.ai_family = zval_get_long(hint); + } else { + php_error_docref(NULL, E_NOTICE, "Unknown hint %s", ZSTR_VAL(key)); + } + } + } ZEND_HASH_FOREACH_END(); + } + + if (getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result) != 0) { + RETURN_FALSE; + } + + array_init(return_value); + + for (rp = result; rp != NULL; rp = rp->ai_next) { + if (rp->ai_family != AF_UNSPEC) { + res = emalloc(sizeof(struct addrinfo)); + memcpy(res, rp, sizeof(struct addrinfo)); + + res->ai_addr = emalloc(rp->ai_addrlen); + memcpy(res->ai_addr, rp->ai_addr, rp->ai_addrlen); + + if (rp->ai_canonname != NULL) { + res->ai_canonname = estrdup(rp->ai_canonname); + } + + add_next_index_resource(return_value, zend_register_resource(res, le_addrinfo)); + } + } + + freeaddrinfo(result); +} +/* }}} */ + +/* {{{ proto resource socket_addrinfo_bind(resource addrinfo) + Creates and binds to a socket from a given addrinfo resource */ +PHP_FUNCTION(socket_addrinfo_bind) +{ + zval *arg1; + int retval; + struct addrinfo *ai; + php_socket *php_sock; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { + return; + } + + if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { + RETURN_FALSE; + } + + php_sock = php_create_socket(); + php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + php_sock->type = ai->ai_family; + + if (IS_INVALID_SOCKET(php_sock)) { + SOCKETS_G(last_error) = errno; + php_error_docref(NULL, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno)); + efree(php_sock); + RETURN_FALSE; + } + + php_sock->error = 0; + php_sock->blocking = 1; + + switch(php_sock->type) { + case AF_UNIX: + { + // AF_UNIX sockets via getaddrino are not implemented due to security problems + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + case AF_INET: +#if HAVE_IPV6 + case AF_INET6: +#endif + { + retval = bind(php_sock->bsd_socket, ai->ai_addr, ai->ai_addrlen); + break; + } + default: + php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type); + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + if (retval != 0) { + PHP_SOCKET_ERROR(php_sock, "unable to bind address", errno); + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + RETURN_RES(zend_register_resource(php_sock, le_socket)); +} +/* }}} */ + +/* {{{ proto resource socket_addrinfo_connect(resource addrinfo) + Creates and connects to a socket from a given addrinfo resource */ +PHP_FUNCTION(socket_addrinfo_connect) +{ + zval *arg1; + int retval; + struct addrinfo *ai; + php_socket *php_sock; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { + return; + } + + if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { + RETURN_FALSE; + } + + php_sock = php_create_socket(); + php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + php_sock->type = ai->ai_family; + + if (IS_INVALID_SOCKET(php_sock)) { + SOCKETS_G(last_error) = errno; + php_error_docref(NULL, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno)); + efree(php_sock); + RETURN_FALSE; + } + + php_sock->error = 0; + php_sock->blocking = 1; + + switch(php_sock->type) { + case AF_UNIX: + { + // AF_UNIX sockets via getaddrino are not implemented due to security problems + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + case AF_INET: +#if HAVE_IPV6 + case AF_INET6: +#endif + { + retval = connect(php_sock->bsd_socket, ai->ai_addr, ai->ai_addrlen); + break; + } + default: + php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type); + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + if (retval != 0) { + PHP_SOCKET_ERROR(php_sock, "unable to connect address", errno); + close(php_sock->bsd_socket); + efree(php_sock); + RETURN_FALSE; + } + + RETURN_RES(zend_register_resource(php_sock, le_socket)); +} +/* }}} */ + +/* {{{ proto resource socket_addrinfo_explain(resource addrinfo) + Creates and connects to a socket from a given addrinfo resource */ +PHP_FUNCTION(socket_addrinfo_explain) +{ + zval *arg1, sockaddr; + struct addrinfo *ai; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) { + return; + } + + if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) { + RETURN_FALSE; + } + + array_init(return_value); + + add_assoc_long(return_value, "ai_flags", ai->ai_flags); + add_assoc_long(return_value, "ai_family", ai->ai_family); + add_assoc_long(return_value, "ai_socktype", ai->ai_socktype); + add_assoc_long(return_value, "ai_protocol", ai->ai_protocol); + if (ai->ai_canonname != NULL) { + add_assoc_string(return_value, "ai_canonname", ai->ai_canonname); + } + + array_init(&sockaddr); + switch(ai->ai_family) { + case AF_INET: + { + struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; + char addr[INET_ADDRSTRLEN]; + + add_assoc_long(&sockaddr, "sin_port", ntohs((unsigned short) sa->sin_port)); + inet_ntop(ai->ai_family, &sa->sin_addr, addr, sizeof(addr)); + add_assoc_string(&sockaddr, "sin_addr", addr); + break; + } +#if HAVE_IPV6 + case AF_INET6: + { + struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; + char addr[INET6_ADDRSTRLEN]; + + add_assoc_long(&sockaddr, "sin6_port", ntohs((unsigned short) sa->sin6_port)); + inet_ntop(ai->ai_family, &sa->sin6_addr, addr, sizeof(addr)); + add_assoc_string(&sockaddr, "sin6_addr", addr); + break; + } +#endif + } + + add_assoc_zval(return_value, "ai_addr", &sockaddr); +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/sockets/tests/socket_addrinfo_bind.phpt b/ext/sockets/tests/socket_addrinfo_bind.phpt new file mode 100644 index 0000000000..eb15afee25 --- /dev/null +++ b/ext/sockets/tests/socket_addrinfo_bind.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test socket_addrinfo_bind() +--SKIPIF-- +<?php +if (!extension_loaded('sockets')) { + die('SKIP The sockets extension is not loaded.'); +} +--FILE-- +<?php +$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, +)); +var_dump(socket_addrinfo_bind($addrinfo[0])); +echo "Done"; +--EXPECTF-- +resource(%d) of type (Socket) +Done diff --git a/ext/sockets/tests/socket_addrinfo_connect.phpt b/ext/sockets/tests/socket_addrinfo_connect.phpt new file mode 100644 index 0000000000..009d54839b --- /dev/null +++ b/ext/sockets/tests/socket_addrinfo_connect.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test socket_addrinfo_connect() +--SKIPIF-- +<?php +if (!extension_loaded('sockets')) { + die('SKIP The sockets extension is not loaded.'); +} +--FILE-- +<?php +$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, +)); +var_dump(socket_addrinfo_connect($addrinfo[0])); +echo "Done"; +--EXPECTF-- +resource(%d) of type (Socket) +Done diff --git a/ext/sockets/tests/socket_addrinfo_explain.phpt b/ext/sockets/tests/socket_addrinfo_explain.phpt new file mode 100644 index 0000000000..aa891039dd --- /dev/null +++ b/ext/sockets/tests/socket_addrinfo_explain.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test socket_addrinfo_explain() +--SKIPIF-- +<?php +if (!extension_loaded('sockets')) { + die('SKIP The sockets extension is not loaded.'); +} +--FILE-- +<?php +$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, +)); +var_dump(socket_addrinfo_explain($addrinfo[0])); +echo "Done"; +--EXPECT-- +array(5) { + ["ai_flags"]=> + int(0) + ["ai_family"]=> + int(2) + ["ai_socktype"]=> + int(2) + ["ai_protocol"]=> + int(17) + ["ai_addr"]=> + array(2) { + ["sin_port"]=> + int(2000) + ["sin_addr"]=> + string(9) "127.0.0.1" + } +} +Done diff --git a/ext/sockets/tests/socket_addrinfo_lookup.phpt b/ext/sockets/tests/socket_addrinfo_lookup.phpt new file mode 100644 index 0000000000..5ecd945f71 --- /dev/null +++ b/ext/sockets/tests/socket_addrinfo_lookup.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test socket_addrinfo_lookup() +--SKIPIF-- +<?php +if (!extension_loaded('sockets')) { + die('SKIP The sockets extension is not loaded.'); +} +--FILE-- +<?php +$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array( + 'ai_family' => AF_INET, + 'ai_socktype' => SOCK_DGRAM, + 'invalid' => null, +)); +var_dump($addrinfo[0]); +echo "Done"; +--EXPECTF-- +Notice: socket_addrinfo_lookup(): Unknown hint invalid in %ssocket_addrinfo_lookup.php on line %d +resource(%d) of type (AddressInfo) +Done diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index b936cfe45b..890945c687 100644 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -24,12 +24,6 @@ #define PHP_SPL_VERSION PHP_VERSION -#if 0 -#define SPL_DEBUG(x) x -#else -#define SPL_DEBUG(x) -#endif - extern zend_module_entry spl_module_entry; #define phpext_spl_ptr &spl_module_entry diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 9eaf714b96..07949a9d5e 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -251,7 +251,7 @@ PHP_METHOD(sqlite3, lastInsertRowID) return; } - RETURN_LONG(sqlite3_last_insert_rowid(db_obj->db)); + RETURN_LONG((zend_long) sqlite3_last_insert_rowid(db_obj->db)); } /* }}} */ @@ -306,7 +306,9 @@ PHP_METHOD(sqlite3, busyTimeout) php_sqlite3_db_object *db_obj; zval *object = getThis(); zend_long ms; +#ifdef SQLITE_ENABLE_API_ARMOR int return_code; +#endif db_obj = Z_SQLITE3_DB_P(object); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) @@ -315,11 +317,15 @@ PHP_METHOD(sqlite3, busyTimeout) return; } +#ifdef SQLITE_ENABLE_API_ARMOR return_code = sqlite3_busy_timeout(db_obj->db, ms); if (return_code != SQLITE_OK) { php_sqlite3_error(db_obj, "Unable to set busy timeout: %d, %s", return_code, sqlite3_errmsg(db_obj->db)); RETURN_FALSE; } +#else + php_ignore_value(sqlite3_busy_timeout(db_obj->db, ms)); +#endif RETURN_TRUE; } @@ -577,7 +583,7 @@ static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column)); } else { #endif - ZVAL_LONG(data, val); + ZVAL_LONG(data, (zend_long) val); #if LONG_MAX <= 2147483647 } #endif @@ -1908,14 +1914,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_createcollation, 0, 0, 2) ZEND_ARG_INFO(0, callback) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(argingo_sqlite3_openblob, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_openblob, 0, 0, 3) ZEND_ARG_INFO(0, table) ZEND_ARG_INFO(0, column) ZEND_ARG_INFO(0, rowid) ZEND_ARG_INFO(0, dbname) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(argingo_sqlite3_enableexceptions, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_enableexceptions, 0, 0, 1) ZEND_ARG_INFO(0, enableExceptions) ZEND_END_ARG_INFO() @@ -1972,8 +1978,8 @@ static zend_function_entry php_sqlite3_class_methods[] = { PHP_ME(sqlite3, createFunction, arginfo_sqlite3_createfunction, ZEND_ACC_PUBLIC) PHP_ME(sqlite3, createAggregate, arginfo_sqlite3_createaggregate, ZEND_ACC_PUBLIC) PHP_ME(sqlite3, createCollation, arginfo_sqlite3_createcollation, ZEND_ACC_PUBLIC) - PHP_ME(sqlite3, openBlob, argingo_sqlite3_openblob, ZEND_ACC_PUBLIC) - PHP_ME(sqlite3, enableExceptions, argingo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC) + PHP_ME(sqlite3, openBlob, arginfo_sqlite3_openblob, ZEND_ACC_PUBLIC) + PHP_ME(sqlite3, enableExceptions, arginfo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC) /* Aliases */ PHP_MALIAS(sqlite3, __construct, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_FE_END diff --git a/ext/sqlite3/tests/bug45798.phpt b/ext/sqlite3/tests/bug45798.phpt index 1beacc4910..9637c1fc9b 100644 --- a/ext/sqlite3/tests/bug45798.phpt +++ b/ext/sqlite3/tests/bug45798.phpt @@ -1,11 +1,11 @@ --TEST-- Bug #45798 (sqlite3 doesn't notice if variable was bound) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); $db->exec('CREATE TABLE test (time INTEGER, id STRING)'); diff --git a/ext/sqlite3/tests/bug47159.phpt b/ext/sqlite3/tests/bug47159.phpt index f8ffa289f5..7d91e1a14e 100644 --- a/ext/sqlite3/tests/bug47159.phpt +++ b/ext/sqlite3/tests/bug47159.phpt @@ -1,11 +1,11 @@ --TEST-- Bug #45798 (sqlite3 doesn't track unexecuted statements) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); $stmt = $db->prepare("SELECT 1"); diff --git a/ext/sqlite3/tests/bug53463.phpt b/ext/sqlite3/tests/bug53463.phpt index dcfc13d5ba..3d907811c1 100644 --- a/ext/sqlite3/tests/bug53463.phpt +++ b/ext/sqlite3/tests/bug53463.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #53463 (sqlite3 columnName() segfaults on bad column_number) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_01_open-mb.phpt b/ext/sqlite3/tests/sqlite3_01_open-mb.phpt index ad9b147d9d..e77ba38a4b 100644 --- a/ext/sqlite3/tests/sqlite3_01_open-mb.phpt +++ b/ext/sqlite3/tests/sqlite3_01_open-mb.phpt @@ -1,13 +1,13 @@ --TEST-- SQLite3::open/close tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -$db_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ç§ã¯ã‚¬ãƒ©ã‚¹ã‚’食ã¹ã‚‰ã‚Œã¾ã™.db'; +$db_file = __DIR__ . DIRECTORY_SEPARATOR . 'ç§ã¯ã‚¬ãƒ©ã‚¹ã‚’食ã¹ã‚‰ã‚Œã¾ã™.db'; $db = new SQLite3($db_file); -//require_once(dirname(__FILE__) . '/new_db.inc'); +//require_once(__DIR__ . '/new_db.inc'); var_dump($db); var_dump($db->close()); diff --git a/ext/sqlite3/tests/sqlite3_01_open.phpt b/ext/sqlite3/tests/sqlite3_01_open.phpt index 11c482722b..f5cc452f0f 100644 --- a/ext/sqlite3/tests/sqlite3_01_open.phpt +++ b/ext/sqlite3/tests/sqlite3_01_open.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::open/close tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); var_dump($db); var_dump($db->close()); diff --git a/ext/sqlite3/tests/sqlite3_02_create.phpt b/ext/sqlite3/tests/sqlite3_02_create.phpt index 5a1aa719d3..913df09ad2 100644 --- a/ext/sqlite3/tests/sqlite3_02_create.phpt +++ b/ext/sqlite3/tests/sqlite3_02_create.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query CREATE tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); echo "Creating Table\n"; var_dump($db->exec('CREATE TABLE test (time INTEGER, id STRING)')); diff --git a/ext/sqlite3/tests/sqlite3_02_open.phpt b/ext/sqlite3/tests/sqlite3_02_open.phpt index b9b49530b3..87f4b91625 100644 --- a/ext/sqlite3/tests/sqlite3_02_open.phpt +++ b/ext/sqlite3/tests/sqlite3_02_open.phpt @@ -4,7 +4,7 @@ SQLite3::open test, testing for function parameters Felix De Vliegher # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_03_insert.phpt b/ext/sqlite3/tests/sqlite3_03_insert.phpt index 7a9fedabcf..1a0690a000 100644 --- a/ext/sqlite3/tests/sqlite3_03_insert.phpt +++ b/ext/sqlite3/tests/sqlite3_03_insert.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query INSERT tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_04_update.phpt b/ext/sqlite3/tests/sqlite3_04_update.phpt index 4a84fdd3f8..3ce7d9cf8b 100644 --- a/ext/sqlite3/tests/sqlite3_04_update.phpt +++ b/ext/sqlite3/tests/sqlite3_04_update.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query UPDATE tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_05_delete.phpt b/ext/sqlite3/tests/sqlite3_05_delete.phpt index b35e7c1378..9ce50c4789 100644 --- a/ext/sqlite3/tests/sqlite3_05_delete.phpt +++ b/ext/sqlite3/tests/sqlite3_05_delete.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query DELETE tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_06_prepared_stmt.phpt b/ext/sqlite3/tests/sqlite3_06_prepared_stmt.phpt index 403adbbf41..710813e8f5 100644 --- a/ext/sqlite3/tests/sqlite3_06_prepared_stmt.phpt +++ b/ext/sqlite3/tests/sqlite3_06_prepared_stmt.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::prepare Bound Variable test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_07_prepared_stmt.phpt b/ext/sqlite3/tests/sqlite3_07_prepared_stmt.phpt index 7a3d950f55..d9a2408123 100644 --- a/ext/sqlite3/tests/sqlite3_07_prepared_stmt.phpt +++ b/ext/sqlite3/tests/sqlite3_07_prepared_stmt.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::prepare Bound Value test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_08_udf.phpt b/ext/sqlite3/tests/sqlite3_08_udf.phpt index d6a326cfbd..061b8a02e0 100644 --- a/ext/sqlite3/tests/sqlite3_08_udf.phpt +++ b/ext/sqlite3/tests/sqlite3_08_udf.phpt @@ -1,7 +1,7 @@ --TEST-- SQLite3::createFunction --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php @@ -10,7 +10,7 @@ function my_udf_md5($foo) return md5($foo); } -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_09_blob_bound_param.phpt b/ext/sqlite3/tests/sqlite3_09_blob_bound_param.phpt index ccc6a8b07f..994503dd03 100644 --- a/ext/sqlite3/tests/sqlite3_09_blob_bound_param.phpt +++ b/ext/sqlite3/tests/sqlite3_09_blob_bound_param.phpt @@ -1,12 +1,12 @@ --TEST-- SQLite3::prepare Bound Variable Blob test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); -require_once(dirname(__FILE__) . '/stream_test.inc'); +require_once(__DIR__ . '/new_db.inc'); +require_once(__DIR__ . '/stream_test.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_10_bound_value_name.phpt b/ext/sqlite3/tests/sqlite3_10_bound_value_name.phpt index 35852ba117..712ad2e539 100644 --- a/ext/sqlite3/tests/sqlite3_10_bound_value_name.phpt +++ b/ext/sqlite3/tests/sqlite3_10_bound_value_name.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::prepare Bound Value test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_11_numrows.phpt b/ext/sqlite3/tests/sqlite3_11_numrows.phpt index 8e2d428419..44fb533974 100644 --- a/ext/sqlite3/tests/sqlite3_11_numrows.phpt +++ b/ext/sqlite3/tests/sqlite3_11_numrows.phpt @@ -1,7 +1,7 @@ --TEST-- SQLite3::prepare number of rows --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); +<?php require_once(__DIR__ . '/skipif.inc'); // Create an instance of the ReflectionMethod class try { $method = new ReflectionMethod('sqlite3result', 'numRows'); @@ -12,7 +12,7 @@ try { --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt b/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt index 2bfd0af9e7..eac5a59a8a 100644 --- a/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt +++ b/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query Unfinalized statement tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_13_skip_all_cleanup.phpt b/ext/sqlite3/tests/sqlite3_13_skip_all_cleanup.phpt index 573d87fe76..daeacc0832 100644 --- a/ext/sqlite3/tests/sqlite3_13_skip_all_cleanup.phpt +++ b/ext/sqlite3/tests/sqlite3_13_skip_all_cleanup.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query Skip all cleanup --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_14_querysingle.phpt b/ext/sqlite3/tests/sqlite3_14_querysingle.phpt index 8cfe089f27..0c8aefb14f 100644 --- a/ext/sqlite3/tests/sqlite3_14_querysingle.phpt +++ b/ext/sqlite3/tests/sqlite3_14_querysingle.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::querySingle tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_16_select_no_results.phpt b/ext/sqlite3/tests/sqlite3_16_select_no_results.phpt index de9fdefdbf..0f2330e596 100644 --- a/ext/sqlite3/tests/sqlite3_16_select_no_results.phpt +++ b/ext/sqlite3/tests/sqlite3_16_select_no_results.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::query SELECT with no results --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_17_version.phpt b/ext/sqlite3/tests/sqlite3_17_version.phpt index 4550057e94..117358ecc1 100644 --- a/ext/sqlite3/tests/sqlite3_17_version.phpt +++ b/ext/sqlite3/tests/sqlite3_17_version.phpt @@ -1,7 +1,7 @@ --TEST-- SQLite3::version() --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php print_r(SQLite3::version()); diff --git a/ext/sqlite3/tests/sqlite3_18_changes.phpt b/ext/sqlite3/tests/sqlite3_18_changes.phpt index 6802db3e0a..4de4a85e9d 100644 --- a/ext/sqlite3/tests/sqlite3_18_changes.phpt +++ b/ext/sqlite3/tests/sqlite3_18_changes.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::changes() tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_19_columninfo.phpt b/ext/sqlite3/tests/sqlite3_19_columninfo.phpt index 4451bdf716..7f243b78d5 100644 --- a/ext/sqlite3/tests/sqlite3_19_columninfo.phpt +++ b/ext/sqlite3/tests/sqlite3_19_columninfo.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3 columnType and columnName --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_20_error.phpt b/ext/sqlite3/tests/sqlite3_20_error.phpt index d98644ab2a..a9324c3999 100644 --- a/ext/sqlite3/tests/sqlite3_20_error.phpt +++ b/ext/sqlite3/tests/sqlite3_20_error.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3 error functions --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); echo "SELECTING from invalid table\n"; $result = $db->query("SELECT * FROM non_existent_table"); diff --git a/ext/sqlite3/tests/sqlite3_21_security.phpt b/ext/sqlite3/tests/sqlite3_21_security.phpt index a667a1234c..5221807cd5 100644 --- a/ext/sqlite3/tests/sqlite3_21_security.phpt +++ b/ext/sqlite3/tests/sqlite3_21_security.phpt @@ -1,14 +1,14 @@ --TEST-- SQLite3 open_basedir checks --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --INI-- open_basedir=. --FILE-- <?php chdir(__DIR__); -$directory = dirname(__FILE__) . '/'; +$directory = __DIR__ . '/'; $file = uniqid() . '.db'; echo "Within test directory\n"; diff --git a/ext/sqlite3/tests/sqlite3_22_loadextension.phpt b/ext/sqlite3/tests/sqlite3_22_loadextension.phpt index 091dcd4a59..52a533d542 100644 --- a/ext/sqlite3/tests/sqlite3_22_loadextension.phpt +++ b/ext/sqlite3/tests/sqlite3_22_loadextension.phpt @@ -2,7 +2,7 @@ SQLite3 load extension --SKIPIF-- <?php -require_once(dirname(__FILE__) . '/skipif.inc'); +require_once(__DIR__ . '/skipif.inc'); $r = new ReflectionClass("sqlite3"); if (!$r->hasMethod("loadExtension")) { die("skip - sqlite3 doesn't have loadExtension enabled"); @@ -14,9 +14,9 @@ sqlite3.extension_dir=. --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); -$directory = dirname(__FILE__); +$directory = __DIR__; touch($directory . '/myext.txt'); diff --git a/ext/sqlite3/tests/sqlite3_23_escape_string.phpt b/ext/sqlite3/tests/sqlite3_23_escape_string.phpt index 4091ff8ae0..6552c222a7 100644 --- a/ext/sqlite3/tests/sqlite3_23_escape_string.phpt +++ b/ext/sqlite3/tests/sqlite3_23_escape_string.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::escapeString --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_24_last_insert_rowid.phpt b/ext/sqlite3/tests/sqlite3_24_last_insert_rowid.phpt index 83d0a292f8..52752e52e7 100644 --- a/ext/sqlite3/tests/sqlite3_24_last_insert_rowid.phpt +++ b/ext/sqlite3/tests/sqlite3_24_last_insert_rowid.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::lastInsertRowID tests --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_25_create_aggregate.phpt b/ext/sqlite3/tests/sqlite3_25_create_aggregate.phpt index 6626ed687f..1eef6662c5 100644 --- a/ext/sqlite3/tests/sqlite3_25_create_aggregate.phpt +++ b/ext/sqlite3/tests/sqlite3_25_create_aggregate.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::createAggregate() test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); function sum_list_step($context, $rows, $string) { if (empty($context)) diff --git a/ext/sqlite3/tests/sqlite3_26_reset_prepared_stmt.phpt b/ext/sqlite3/tests/sqlite3_26_reset_prepared_stmt.phpt index eda1bd5f22..ffd05d3329 100644 --- a/ext/sqlite3/tests/sqlite3_26_reset_prepared_stmt.phpt +++ b/ext/sqlite3/tests/sqlite3_26_reset_prepared_stmt.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::reset prepared statement --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_27_reset_prepared_stmt_result.phpt b/ext/sqlite3/tests/sqlite3_27_reset_prepared_stmt_result.phpt index ea7e8bfba0..646cb473f3 100644 --- a/ext/sqlite3/tests/sqlite3_27_reset_prepared_stmt_result.phpt +++ b/ext/sqlite3/tests/sqlite3_27_reset_prepared_stmt_result.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::reset prepared statement results --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_28_clear_bindings.phpt b/ext/sqlite3/tests/sqlite3_28_clear_bindings.phpt index 77a69b3114..a17e1fb3f1 100644 --- a/ext/sqlite3/tests/sqlite3_28_clear_bindings.phpt +++ b/ext/sqlite3/tests/sqlite3_28_clear_bindings.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3_stmt::clear prepared statement results --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt index 9448b30ade..6ea000adcd 100644 --- a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt +++ b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3::createFunction - Basic test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); $func = 'strtoupper'; var_dump($db->createfunction($func, $func)); diff --git a/ext/sqlite3/tests/sqlite3_30_blobopen.phpt b/ext/sqlite3/tests/sqlite3_30_blobopen.phpt index ed51153784..1daa4b1ffb 100644 --- a/ext/sqlite3/tests/sqlite3_30_blobopen.phpt +++ b/ext/sqlite3/tests/sqlite3_30_blobopen.phpt @@ -1,12 +1,12 @@ --TEST-- SQLite3::blobOpen stream test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); -require_once(dirname(__FILE__) . '/stream_test.inc'); +require_once(__DIR__ . '/new_db.inc'); +require_once(__DIR__ . '/stream_test.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_31_changes.phpt b/ext/sqlite3/tests/sqlite3_31_changes.phpt index 1667b3484a..589a498f30 100644 --- a/ext/sqlite3/tests/sqlite3_31_changes.phpt +++ b/ext/sqlite3/tests/sqlite3_31_changes.phpt @@ -4,7 +4,7 @@ SQLite3::changes (parameters) tests Ward Hus #@PHP TESTFEST 2009 (BELGIUM) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_31_open.phpt b/ext/sqlite3/tests/sqlite3_31_open.phpt index b30266b7ee..47a08f25fa 100644 --- a/ext/sqlite3/tests/sqlite3_31_open.phpt +++ b/ext/sqlite3/tests/sqlite3_31_open.phpt @@ -4,7 +4,7 @@ SQLite3::re-initialize object tests Jelle Lampaert #Belgian Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_32_changes.phpt b/ext/sqlite3/tests/sqlite3_32_changes.phpt index 0aad451270..52666fd889 100644 --- a/ext/sqlite3/tests/sqlite3_32_changes.phpt +++ b/ext/sqlite3/tests/sqlite3_32_changes.phpt @@ -4,7 +4,7 @@ SQLite3::changes empty str tests Ward Hus #@ PHP TESTFEST 2009 (BELGIUM) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt b/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt index 8a05c57531..3c30bdb664 100644 --- a/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt +++ b/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt @@ -4,7 +4,7 @@ SQLite3::createAggregate Test that an error is thrown when no parameters are pre James Cauwelier # Belgium PHP TestFest --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_32_last_insert_rowid_param.phpt b/ext/sqlite3/tests/sqlite3_32_last_insert_rowid_param.phpt index c696ef9dfc..049a774c82 100644 --- a/ext/sqlite3/tests/sqlite3_32_last_insert_rowid_param.phpt +++ b/ext/sqlite3/tests/sqlite3_32_last_insert_rowid_param.phpt @@ -4,7 +4,7 @@ SQLite3::lastInsertRowID parameter test Jelle Lampaert #Belgian Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt index 7a1bb2831a..fe7c8fb75a 100644 --- a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt +++ b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt @@ -4,7 +4,7 @@ SQLite3::createAggregate() Test whether a supplied PHP function is valid when us James Cauwelier # Belgium PHP TestFest (2009) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt index b7b418c47c..716ec9dc36 100644 --- a/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt +++ b/ext/sqlite3/tests/sqlite3_33_load_extension_param.phpt @@ -6,7 +6,7 @@ Jelle Lampaert --INI-- sqlite3.extension_dir=/tmp --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_33_reset.phpt b/ext/sqlite3/tests/sqlite3_33_reset.phpt index 5f513fb681..531874ceb6 100644 --- a/ext/sqlite3/tests/sqlite3_33_reset.phpt +++ b/ext/sqlite3/tests/sqlite3_33_reset.phpt @@ -4,7 +4,7 @@ SQLite3:: reset Ward Hus & James Cauwelier #@ PHP TESTFEST 2009 (BELGIUM) --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_34_load_extension_ext_dir.phpt b/ext/sqlite3/tests/sqlite3_34_load_extension_ext_dir.phpt index 1d2721bd37..20ad370bc3 100644 --- a/ext/sqlite3/tests/sqlite3_34_load_extension_ext_dir.phpt +++ b/ext/sqlite3/tests/sqlite3_34_load_extension_ext_dir.phpt @@ -4,7 +4,7 @@ SQLite3::loadExtension with disabled extensions Jelle Lampaert #Belgian Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt index 0c542a1632..23392e5a51 100644 --- a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt +++ b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt @@ -1,7 +1,7 @@ --TEST-- SQLite3_stmt::readOnly check --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); +<?php require_once(__DIR__ . '/skipif.inc'); $version = SQLite3::version(); if ($version['versionNumber'] < 3007004) { die("skip"); @@ -10,7 +10,7 @@ if ($version['versionNumber'] < 3007004) { --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); define('TIMENOW', time()); echo "Creating Table\n"; diff --git a/ext/sqlite3/tests/sqlite3_36_create_collation.phpt b/ext/sqlite3/tests/sqlite3_36_create_collation.phpt index c4d88c69f7..90fbd9d37b 100644 --- a/ext/sqlite3/tests/sqlite3_36_create_collation.phpt +++ b/ext/sqlite3/tests/sqlite3_36_create_collation.phpt @@ -1,11 +1,11 @@ --TEST-- Test SQLite3::createCollation() by adding strnatcmp() as an SQL COLLATE sequence --SKIPIF-- -<?php require_once dirname(__FILE__) . '/skipif.inc'; ?> +<?php require_once __DIR__ . '/skipif.inc'; ?> --FILE-- <?php -require_once dirname(__FILE__) . '/new_db.inc'; +require_once __DIR__ . '/new_db.inc'; $db->createCollation('NAT', 'strnatcmp'); diff --git a/ext/sqlite3/tests/sqlite3_bind_bug68849.phpt b/ext/sqlite3/tests/sqlite3_bind_bug68849.phpt index 321f883a8e..d04e596b50 100644 --- a/ext/sqlite3/tests/sqlite3_bind_bug68849.phpt +++ b/ext/sqlite3/tests/sqlite3_bind_bug68849.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #68849 bindValue is not using the right data type --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_blob_bind_resource.phpt b/ext/sqlite3/tests/sqlite3_blob_bind_resource.phpt index 108956b87b..c35af945db 100644 --- a/ext/sqlite3/tests/sqlite3_blob_bind_resource.phpt +++ b/ext/sqlite3/tests/sqlite3_blob_bind_resource.phpt @@ -1,12 +1,12 @@ --TEST-- SQLite3::execute() with a resource bound for blob param --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); -require_once(dirname(__FILE__) . '/stream_test.inc'); +require_once(__DIR__ . '/new_db.inc'); +require_once(__DIR__ . '/stream_test.inc'); var_dump($db->exec('CREATE TABLE test (id STRING, data BLOB)')); $insert_stmt = $db->prepare("INSERT INTO test (id, data) VALUES (1, ?)"); diff --git a/ext/sqlite3/tests/sqlite3_close_error.phpt b/ext/sqlite3/tests/sqlite3_close_error.phpt index d242352872..dad8cb9937 100644 --- a/ext/sqlite3/tests/sqlite3_close_error.phpt +++ b/ext/sqlite3/tests/sqlite3_close_error.phpt @@ -4,7 +4,7 @@ SQLite3::close parameters Jachim Coudenys # TestFest 2009 Belgium --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_close_with_params.phpt b/ext/sqlite3/tests/sqlite3_close_with_params.phpt index 98e0483ea1..6e44dbf1a7 100644 --- a/ext/sqlite3/tests/sqlite3_close_with_params.phpt +++ b/ext/sqlite3/tests/sqlite3_close_with_params.phpt @@ -4,7 +4,7 @@ SQLite3::close test with parameters Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_enable_exceptions.phpt b/ext/sqlite3/tests/sqlite3_enable_exceptions.phpt index ebb59eb2b0..767f9d0065 100644 --- a/ext/sqlite3/tests/sqlite3_enable_exceptions.phpt +++ b/ext/sqlite3/tests/sqlite3_enable_exceptions.phpt @@ -4,7 +4,7 @@ SQLite3::enableExceptions test Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_exec_wrongparams.phpt b/ext/sqlite3/tests/sqlite3_exec_wrongparams.phpt index c94b521dce..c3af18865c 100644 --- a/ext/sqlite3/tests/sqlite3_exec_wrongparams.phpt +++ b/ext/sqlite3/tests/sqlite3_exec_wrongparams.phpt @@ -4,7 +4,7 @@ SQLite3::exec test, testing for wrong type parameters Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_lasterrorcode_with_params.phpt b/ext/sqlite3/tests/sqlite3_lasterrorcode_with_params.phpt index 243392b318..281adb49c0 100644 --- a/ext/sqlite3/tests/sqlite3_lasterrorcode_with_params.phpt +++ b/ext/sqlite3/tests/sqlite3_lasterrorcode_with_params.phpt @@ -4,7 +4,7 @@ SQLite3::lastErrorCode test with parameters Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_lasterrormsg_with_params.phpt b/ext/sqlite3/tests/sqlite3_lasterrormsg_with_params.phpt index c2fa35d954..1d4c6d3783 100644 --- a/ext/sqlite3/tests/sqlite3_lasterrormsg_with_params.phpt +++ b/ext/sqlite3/tests/sqlite3_lasterrormsg_with_params.phpt @@ -4,7 +4,7 @@ SQLite3::lastErrorMsg test with parameters Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_loadextension_with_wrong_param.phpt b/ext/sqlite3/tests/sqlite3_loadextension_with_wrong_param.phpt index 9811f86e6a..d3f90642c9 100644 --- a/ext/sqlite3/tests/sqlite3_loadextension_with_wrong_param.phpt +++ b/ext/sqlite3/tests/sqlite3_loadextension_with_wrong_param.phpt @@ -4,7 +4,7 @@ SQLite3::loadExtension test with wrong parameter type Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_open_empty_string.phpt b/ext/sqlite3/tests/sqlite3_open_empty_string.phpt index 940056bf0a..c1832694a7 100644 --- a/ext/sqlite3/tests/sqlite3_open_empty_string.phpt +++ b/ext/sqlite3/tests/sqlite3_open_empty_string.phpt @@ -4,7 +4,7 @@ SQLite3::open test with empty string argument via the constructor Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(''); diff --git a/ext/sqlite3/tests/sqlite3_openblob_wrongparams.phpt b/ext/sqlite3/tests/sqlite3_openblob_wrongparams.phpt index 439e397787..03242d935b 100644 --- a/ext/sqlite3/tests/sqlite3_openblob_wrongparams.phpt +++ b/ext/sqlite3/tests/sqlite3_openblob_wrongparams.phpt @@ -4,7 +4,7 @@ SQLite3::blobOpen test, testing stream with wrong parameter count Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php class SQLite3_Test_Stream diff --git a/ext/sqlite3/tests/sqlite3_prepare_001.phpt b/ext/sqlite3/tests/sqlite3_prepare_001.phpt index f9e5fadce7..baf0c83025 100644 --- a/ext/sqlite3/tests/sqlite3_prepare_001.phpt +++ b/ext/sqlite3/tests/sqlite3_prepare_001.phpt @@ -1,7 +1,7 @@ --TEST-- SQLite3 - memory leak on SQLite3Result and SQLite3Stmt --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_prepare_faultystmt.phpt b/ext/sqlite3/tests/sqlite3_prepare_faultystmt.phpt index 5cdf322a96..2793e5f746 100644 --- a/ext/sqlite3/tests/sqlite3_prepare_faultystmt.phpt +++ b/ext/sqlite3/tests/sqlite3_prepare_faultystmt.phpt @@ -4,7 +4,7 @@ SQLite3::prepare test, testing for faulty statement Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_prepare_with_empty_string.phpt b/ext/sqlite3/tests/sqlite3_prepare_with_empty_string.phpt index dea7d91226..391bc54dd3 100644 --- a/ext/sqlite3/tests/sqlite3_prepare_with_empty_string.phpt +++ b/ext/sqlite3/tests/sqlite3_prepare_with_empty_string.phpt @@ -4,7 +4,7 @@ SQLite3::prepare test with empty string argument Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_prepare_wrongparams.phpt b/ext/sqlite3/tests/sqlite3_prepare_wrongparams.phpt index b7eb564e19..3010e32447 100644 --- a/ext/sqlite3/tests/sqlite3_prepare_wrongparams.phpt +++ b/ext/sqlite3/tests/sqlite3_prepare_wrongparams.phpt @@ -4,7 +4,7 @@ SQLite3::prepare test, testing for wrong parameters Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_prepared_stmt_clear_with_params.phpt b/ext/sqlite3/tests/sqlite3_prepared_stmt_clear_with_params.phpt index d04fb66e56..779d254671 100644 --- a/ext/sqlite3/tests/sqlite3_prepared_stmt_clear_with_params.phpt +++ b/ext/sqlite3/tests/sqlite3_prepared_stmt_clear_with_params.phpt @@ -4,7 +4,7 @@ SQLite3Stmt::clear test with parameters Thijs Feryn <thijs@feryn.eu> #TestFest PHPBelgium 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_query_error.phpt b/ext/sqlite3/tests/sqlite3_query_error.phpt index ab7f700d92..f5d64fd837 100644 --- a/ext/sqlite3/tests/sqlite3_query_error.phpt +++ b/ext/sqlite3/tests/sqlite3_query_error.phpt @@ -4,7 +4,7 @@ SQLite3::query parameters Jachim Coudenys # TestFest 2009 Belgium --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3_querysingle_error.phpt b/ext/sqlite3/tests/sqlite3_querysingle_error.phpt index 85889c755a..9d19dbea7d 100644 --- a/ext/sqlite3/tests/sqlite3_querysingle_error.phpt +++ b/ext/sqlite3/tests/sqlite3_querysingle_error.phpt @@ -4,7 +4,7 @@ SQLite3::query parameters Jachim Coudenys # TestFest 2009 Belgium --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3_version_noparam.phpt b/ext/sqlite3/tests/sqlite3_version_noparam.phpt index 19d6ec5a33..2b8e77b05f 100644 --- a/ext/sqlite3/tests/sqlite3_version_noparam.phpt +++ b/ext/sqlite3/tests/sqlite3_version_noparam.phpt @@ -4,7 +4,7 @@ SQLite3::version test, testing for missing function parameters Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php diff --git a/ext/sqlite3/tests/sqlite3result_fetcharray_with_two_params_fails.phpt b/ext/sqlite3/tests/sqlite3result_fetcharray_with_two_params_fails.phpt index cb49b75539..657d19f961 100644 --- a/ext/sqlite3/tests/sqlite3result_fetcharray_with_two_params_fails.phpt +++ b/ext/sqlite3/tests/sqlite3result_fetcharray_with_two_params_fails.phpt @@ -4,7 +4,7 @@ SQLite3Result::fetchArray() test, testing two params causes a failure Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3result_numcolumns_error.phpt b/ext/sqlite3/tests/sqlite3result_numcolumns_error.phpt index 5f8306cb2d..52ab6efca8 100644 --- a/ext/sqlite3/tests/sqlite3result_numcolumns_error.phpt +++ b/ext/sqlite3/tests/sqlite3result_numcolumns_error.phpt @@ -4,7 +4,7 @@ SQLite3Result::numColumns parameters Jachim Coudenys # TestFest 2009 Belgium --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3result_reset_with_params_fails.phpt b/ext/sqlite3/tests/sqlite3result_reset_with_params_fails.phpt index b397ac6730..2c263baaa5 100644 --- a/ext/sqlite3/tests/sqlite3result_reset_with_params_fails.phpt +++ b/ext/sqlite3/tests/sqlite3result_reset_with_params_fails.phpt @@ -4,7 +4,7 @@ SQLite3Result::reset test, testing an exception is raised when calling reset wit Michelangelo van Dam # Belgian PHP Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/sqlite3/tests/sqlite3stmt_paramCount_basic.phpt b/ext/sqlite3/tests/sqlite3stmt_paramCount_basic.phpt index a4b29e3434..97ef1f7aba 100644 --- a/ext/sqlite3/tests/sqlite3stmt_paramCount_basic.phpt +++ b/ext/sqlite3/tests/sqlite3stmt_paramCount_basic.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3Stmt::paramCount basic test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); echo "Creating Table\n"; var_dump($db->exec('CREATE TABLE foobar (id INTEGER, name STRING, city STRING)')); diff --git a/ext/sqlite3/tests/sqlite3stmt_paramCount_error.phpt b/ext/sqlite3/tests/sqlite3stmt_paramCount_error.phpt index 2aac6c2108..64016db6da 100644 --- a/ext/sqlite3/tests/sqlite3stmt_paramCount_error.phpt +++ b/ext/sqlite3/tests/sqlite3stmt_paramCount_error.phpt @@ -1,11 +1,11 @@ --TEST-- SQLite3Stmt::paramCount error test --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php -require_once(dirname(__FILE__) . '/new_db.inc'); +require_once(__DIR__ . '/new_db.inc'); echo "Creating Table\n"; var_dump($db->exec('CREATE TABLE foobar (id INTEGER, name STRING, city STRING)')); diff --git a/ext/sqlite3/tests/sqlite3stmt_reset_params.phpt b/ext/sqlite3/tests/sqlite3stmt_reset_params.phpt index b0dfc20456..f2fa74ada1 100644 --- a/ext/sqlite3/tests/sqlite3stmt_reset_params.phpt +++ b/ext/sqlite3/tests/sqlite3stmt_reset_params.phpt @@ -4,7 +4,7 @@ SQLite3Stmt::reset with parameter test Jelle Lampaert #Belgian Testfest 2009 --SKIPIF-- -<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?> +<?php require_once(__DIR__ . '/skipif.inc'); ?> --FILE-- <?php $db = new SQLite3(':memory:'); diff --git a/ext/standard/array.c b/ext/standard/array.c index 69439a7877..f3a7f4de84 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1767,12 +1767,6 @@ PHP_FUNCTION(extract) } symbol_table = zend_rebuild_symbol_table(); -#if 0 - if (!symbol_table) { - php_error_docref(NULL, E_WARNING, "failed to build symbol table"); - return; - } -#endif /* The array might be stored in a local variable that will be overwritten. To avoid losing the * reference in that case we work on a copy. */ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 13e8a4e6eb..af66d1e0a6 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -49,6 +49,8 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #include "zend_language_scanner.h" #include <zend_language_parser.h> +#include "zend_portability.h" + #include <stdarg.h> #include <stdlib.h> #include <math.h> @@ -2465,6 +2467,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_substr_compare, 0, 0, 3) ZEND_ARG_INFO(0, length) ZEND_ARG_INFO(0, case_sensitivity) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_encode, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_decode, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ syslog.c */ #ifdef HAVE_SYSLOG_H @@ -2764,6 +2774,8 @@ const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(str_split, arginfo_str_split) PHP_FE(strpbrk, arginfo_strpbrk) PHP_FE(substr_compare, arginfo_substr_compare) + PHP_FE(utf8_encode, arginfo_utf8_encode) + PHP_FE(utf8_decode, arginfo_utf8_decode) #ifdef HAVE_STRCOLL PHP_FE(strcoll, arginfo_strcoll) @@ -3516,40 +3528,15 @@ static void basic_globals_dtor(php_basic_globals *basic_globals_p) /* {{{ */ } /* }}} */ -#define PHP_DOUBLE_INFINITY_HIGH 0x7ff00000 -#define PHP_DOUBLE_QUIET_NAN_HIGH 0xfff80000 - PHPAPI double php_get_nan(void) /* {{{ */ { -#if HAVE_HUGE_VAL_NAN - return HUGE_VAL + -HUGE_VAL; -#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) - double val = 0.0; - ((uint32_t*)&val)[1] = PHP_DOUBLE_QUIET_NAN_HIGH; - ((uint32_t*)&val)[0] = 0; - return val; -#elif HAVE_ATOF_ACCEPTS_NAN - return atof("NAN"); -#else - return 0.0/0.0; -#endif + return ZEND_NAN; } /* }}} */ PHPAPI double php_get_inf(void) /* {{{ */ { -#if HAVE_HUGE_VAL_INF - return HUGE_VAL; -#elif defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) - double val = 0.0; - ((uint32_t*)&val)[1] = PHP_DOUBLE_INFINITY_HIGH; - ((uint32_t*)&val)[0] = 0; - return val; -#elif HAVE_ATOF_ACCEPTS_INF - return atof("INF"); -#else - return 1.0/0.0; -#endif + return ZEND_INFINITY; } /* }}} */ @@ -3641,8 +3628,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ REGISTER_MATH_CONSTANT(M_SQRT2); REGISTER_MATH_CONSTANT(M_SQRT1_2); REGISTER_MATH_CONSTANT(M_SQRT3); - REGISTER_DOUBLE_CONSTANT("INF", php_get_inf(), CONST_CS | CONST_PERSISTENT); - REGISTER_DOUBLE_CONSTANT("NAN", php_get_nan(), CONST_CS | CONST_PERSISTENT); + REGISTER_DOUBLE_CONSTANT("INF", ZEND_INFINITY, CONST_CS | CONST_PERSISTENT); + REGISTER_DOUBLE_CONSTANT("NAN", ZEND_NAN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_UP", PHP_ROUND_HALF_UP, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_DOWN", PHP_ROUND_HALF_DOWN, CONST_CS | CONST_PERSISTENT); diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index c73dace754..3f2da2dc24 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -351,143 +351,6 @@ dnl PHP_CHECK_FUNC(res_search, resolv, bind, socket) dnl -dnl Check if atof() accepts NAN -dnl -AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[ -AC_TRY_RUN([ -#include <math.h> -#include <stdlib.h> - -#ifdef HAVE_ISNAN -#define zend_isnan(a) isnan(a) -#elif defined(HAVE_FPCLASS) -#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) -#else -#define zend_isnan(a) 0 -#endif - -int main(int argc, char** argv) -{ - return zend_isnan(atof("NAN")) ? 0 : 1; -} -],[ - ac_cv_atof_accept_nan=yes -],[ - ac_cv_atof_accept_nan=no -],[ - ac_cv_atof_accept_nan=no -])]) -if test "$ac_cv_atof_accept_nan" = "yes"; then - AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN]) -fi - -dnl -dnl Check if atof() accepts INF -dnl -AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[ -AC_TRY_RUN([ -#include <math.h> -#include <stdlib.h> - -#ifdef HAVE_ISINF -#define zend_isinf(a) isinf(a) -#elif defined(INFINITY) -/* Might not work, but is required by ISO C99 */ -#define zend_isinf(a) (((a)==INFINITY)?1:0) -#elif defined(HAVE_FPCLASS) -#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF)) -#else -#define zend_isinf(a) 0 -#endif - -int main(int argc, char** argv) -{ - return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1; -} -],[ - ac_cv_atof_accept_inf=yes -],[ - ac_cv_atof_accept_inf=no -],[ - ac_cv_atof_accept_inf=no -])]) -if test "$ac_cv_atof_accept_inf" = "yes"; then - AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF]) -fi - -dnl -dnl Check if HUGE_VAL == INF -dnl -AC_CACHE_CHECK(whether HUGE_VAL == INF, ac_cv_huge_val_inf,[ -AC_TRY_RUN([ -#include <math.h> -#include <stdlib.h> - -#ifdef HAVE_ISINF -#define zend_isinf(a) isinf(a) -#elif defined(INFINITY) -/* Might not work, but is required by ISO C99 */ -#define zend_isinf(a) (((a)==INFINITY)?1:0) -#elif defined(HAVE_FPCLASS) -#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF)) -#else -#define zend_isinf(a) 0 -#endif - -int main(int argc, char** argv) -{ - return zend_isinf(HUGE_VAL) ? 0 : 1; -} -],[ - ac_cv_huge_val_inf=yes -],[ - ac_cv_huge_val_inf=no -],[ - ac_cv_huge_val_inf=yes -])]) -dnl This is the most probable fallback so we assume yes in case of cross compile. -if test "$ac_cv_huge_val_inf" = "yes"; then - AC_DEFINE([HAVE_HUGE_VAL_INF], 1, [whether HUGE_VAL == INF]) -fi - -dnl -dnl Check if HUGE_VAL + -HUGEVAL == NAN -dnl -AC_CACHE_CHECK(whether HUGE_VAL + -HUGEVAL == NAN, ac_cv_huge_val_nan,[ -AC_TRY_RUN([ -#include <math.h> -#include <stdlib.h> - -#ifdef HAVE_ISNAN -#define zend_isnan(a) isnan(a) -#elif defined(HAVE_FPCLASS) -#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) -#else -#define zend_isnan(a) 0 -#endif - -int main(int argc, char** argv) -{ -#if defined(__sparc__) && !(__GNUC__ >= 3) - /* prevent bug #27830 */ - return 1; -#else - return zend_isnan(HUGE_VAL + -HUGE_VAL) ? 0 : 1; -#endif -} -],[ - ac_cv_huge_val_nan=yes -],[ - ac_cv_huge_val_nan=no -],[ - ac_cv_huge_val_nan=yes -])]) -dnl This is the most probable fallback so we assume yes in case of cross compile. -if test "$ac_cv_huge_val_nan" = "yes"; then - AC_DEFINE([HAVE_HUGE_VAL_NAN], 1, [whether HUGE_VAL + -HUGEVAL == NAN]) -fi - -dnl dnl Check for strptime() dnl AC_CACHE_CHECK(whether strptime() declaration fails, ac_cv_strptime_decl_fails,[ @@ -551,6 +414,38 @@ dnl AC_CHECK_DECLS([getrandom]) dnl +dnl Check for argon2 +dnl +PHP_ARG_WITH(password-argon2, for Argon2 support, +[ --with-password-argon2[=DIR] Include Argon2 support in password_*. DIR is the Argon2 shared library path]]) + +if test "$PHP_PASSWORD_ARGON2" != "no"; then + AC_MSG_CHECKING([for Argon2 library]) + for i in $PHP_PASSWORD_ARGON2 /usr /usr/local ; do + if test -r $i/include/argon2.h; then + ARGON2_DIR=$i; + AC_MSG_RESULT(found in $i) + break + fi + done + + if test -z "$ARGON2_DIR"; then + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([Please ensure the argon2 header and library are installed]) + fi + + PHP_ADD_LIBRARY_WITH_PATH(argon2, $ARGON2_DIR/$PHP_LIBDIR) + PHP_ADD_INCLUDE($ARGON2_DIR/include) + + AC_CHECK_LIB(argon2, argon2_hash, [ + LIBS="$LIBS -largon2" + AC_DEFINE(HAVE_ARGON2LIB, 1, [ Define to 1 if you have the <argon2.h> header file ]) + ], [ + AC_MSG_ERROR([Problem with libargon2.(a|so). Please verify that Argon2 header and libaries are installed]) + ]) +fi + +dnl dnl Setup extension sources dnl PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.c crypt.c \ diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index ee5c319aa7..8154e7936c 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -1,6 +1,17 @@ // vim:ft=javascript // $Id$ +ARG_WITH("password-argon2", "Argon2 support", "no"); + +if (PHP_PASSWORD_ARGON2 != "no") { + if (CHECK_LIB("argon2_a.lib;argon2.lib", null, PHP_PASSWORD_ARGON2) + && CHECK_HEADER_ADD_INCLUDE("argon2.h", "CFLAGS")) { + AC_DEFINE('HAVE_ARGON2LIB', 1); + } else { + WARNING("Argon2 not enabled; libaries and headers not found"); + } +} + ARG_WITH("config-file-scan-dir", "Dir to check for additional php ini files", ""); AC_DEFINE("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR); diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 222c993c65..de7e01ffea 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -63,15 +63,6 @@ int dir_globals_id; php_dir_globals dir_globals; #endif -#if 0 -typedef struct { - int id; - DIR *dir; -} php_dir; - -static int le_dirp; -#endif - static zend_class_entry *dir_class_entry_ptr; #define FETCH_DIRP() \ diff --git a/ext/standard/dl.c b/ext/standard/dl.c index eae7630fe5..8908fee5b6 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -79,12 +79,6 @@ PHPAPI PHP_FUNCTION(dl) #if defined(HAVE_LIBDL) -#ifdef ZTS -#define USING_ZTS 1 -#else -#define USING_ZTS 0 -#endif - /* {{{ php_load_extension */ PHPAPI int php_load_extension(char *filename, int type, int start_now) diff --git a/ext/standard/exec.c b/ext/standard/exec.c index bf9100b0d2..1a387da142 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -54,6 +54,10 @@ #include <limits.h> #endif +#ifdef PHP_WIN32 +# include "win32/nice.h" +#endif + static size_t cmd_max_len; /* {{{ PHP_MINIT_FUNCTION(exec) */ @@ -557,7 +561,11 @@ PHP_FUNCTION(proc_nice) errno = 0; php_ignore_value(nice(pri)); if (errno) { +#ifdef PHP_WIN32 + php_error_docref(NULL, E_WARNING, php_win_err()); +#else php_error_docref(NULL, E_WARNING, "Only a super user may attempt to increase the priority of a process"); +#endif RETURN_FALSE; } diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 70f0629c53..cf26cea340 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -67,7 +67,7 @@ static php_stream_filter_ops strfilter_rot13_ops = { "string.rot13" }; -static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent); } @@ -149,12 +149,12 @@ static php_stream_filter_ops strfilter_tolower_ops = { "string.tolower" }; -static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent); } -static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent); } @@ -172,8 +172,8 @@ static php_stream_filter_factory strfilter_tolower_factory = { typedef struct _php_strip_tags_filter { const char *allowed_tags; int allowed_tags_len; - int state; - int persistent; + uint8_t state; + uint8_t persistent; } php_strip_tags_filter; static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, const char *allowed_tags, size_t allowed_tags_len, int persistent) @@ -244,7 +244,7 @@ static php_stream_filter_ops strfilter_strip_tags_ops = { "string.strip_tags" }; -static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_strip_tags_filter *inst; smart_str tags_ss = {0}; @@ -1724,7 +1724,7 @@ static php_stream_filter_ops strfilter_convert_ops = { "convert.*" }; -static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_convert_filter *inst; php_stream_filter *retval = NULL; @@ -1778,7 +1778,7 @@ static php_stream_filter_factory strfilter_convert_factory = { typedef struct _php_consumed_filter_data { size_t consumed; zend_off_t offset; - int persistent; + uint8_t persistent; } php_consumed_filter_data; static php_stream_filter_status_t consumed_filter_filter( @@ -1827,7 +1827,7 @@ static php_stream_filter_ops consumed_filter_ops = { "consumed" }; -static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_stream_filter_ops *fops = NULL; php_consumed_filter_data *data; @@ -2035,7 +2035,7 @@ static php_stream_filter_ops chunked_filter_ops = { "dechunk" }; -static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_stream_filter_ops *fops = NULL; php_chunked_filter_data *data; diff --git a/ext/standard/info.c b/ext/standard/info.c index 982d4e461b..b62679528c 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -41,10 +41,7 @@ #include "php_string.h" #ifdef PHP_WIN32 -typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); -typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); # include "winver.h" - #endif #define SECTION(name) if (!sapi_module.phpinfo_as_text) { \ @@ -295,19 +292,12 @@ char* php_get_windows_name() { OSVERSIONINFOEX osvi = EG(windows_version_info); SYSTEM_INFO si; - PGNSI pGNSI; - PGPI pGPI; DWORD dwType; char *major = NULL, *sub = NULL, *retval; ZeroMemory(&si, sizeof(SYSTEM_INFO)); - pGNSI = (PGNSI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo"); - if(NULL != pGNSI) { - pGNSI(&si); - } else { - GetSystemInfo(&si); - } + GetNativeSystemInfo(&si); if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) { if (osvi.dwMajorVersion == 10) { @@ -380,8 +370,8 @@ char* php_get_windows_name() major = "Unknown Windows version"; } - pGPI = (PGPI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo"); - pGPI(6, 0, 0, 0, &dwType); + /* No return value check, as it can only fail if the input parameters are broken (which we manually supply) */ + GetProductInfo(6, 0, 0, 0, &dwType); switch (dwType) { case PRODUCT_ULTIMATE: diff --git a/ext/standard/mail.c b/ext/standard/mail.c index b27e12adc1..8d70e5a47b 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -27,6 +27,7 @@ #include "ext/standard/php_string.h" #include "ext/standard/basic_functions.h" #include "ext/date/php_date.h" +#include "zend_smart_str.h" #if HAVE_SYSEXITS_H #include <sysexits.h> @@ -96,20 +97,210 @@ PHP_FUNCTION(ezmlm_hash) } /* }}} */ + +static zend_bool php_mail_build_headers_check_field_value(zval *val) +{ + size_t len = 0; + zend_string *value = Z_STR_P(val); + + /* https://tools.ietf.org/html/rfc2822#section-2.2.1 */ + /* https://tools.ietf.org/html/rfc2822#section-2.2.3 */ + while (len < value->len) { + if (*(value->val+len) == '\r') { + if (value->len - len >= 3 + && *(value->val+len+1) == '\n' + && (*(value->val+len+2) == ' ' || *(value->val+len+2) == '\t')) { + len += 3; + continue; + } + return FAILURE; + } + if (*(value->val+len) == '\0') { + return FAILURE; + } + len++; + } + return SUCCESS; +} + + +static zend_bool php_mail_build_headers_check_field_name(zend_string *key) +{ + size_t len = 0; + + /* https://tools.ietf.org/html/rfc2822#section-2.2 */ + while (len < key->len) { + if (*(key->val+len) < 33 || *(key->val+len) > 126 || *(key->val+len) == ':') { + return FAILURE; + } + len++; + } + return SUCCESS; +} + + +static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *val); + +static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *val) +{ + switch(Z_TYPE_P(val)) { + case IS_STRING: + if (php_mail_build_headers_check_field_name(key) != SUCCESS) { + php_error_docref(NULL, E_WARNING, "Header field name (%s) contains invalid chars", ZSTR_VAL(key)); + return; + } + if (php_mail_build_headers_check_field_value(val) != SUCCESS) { + php_error_docref(NULL, E_WARNING, "Header field value (%s => %s) contains invalid chars or format", ZSTR_VAL(key), Z_STRVAL_P(val)); + return; + } + smart_str_append(s, key); + smart_str_appendl(s, ": ", 2); + smart_str_appends(s, Z_STRVAL_P(val)); + smart_str_appendl(s, "\r\n", 2); + break; + case IS_ARRAY: + php_mail_build_headers_elems(s, key, val); + break; + default: + php_error_docref(NULL, E_WARNING, "headers array elements must be string or array (%s)", ZSTR_VAL(key)); + } +} + + +static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *val) +{ + zend_ulong idx; + zend_string *tmp_key; + zval *tmp_val; + + (void)(idx); + ZEND_HASH_FOREACH_KEY_VAL(HASH_OF(val), idx, tmp_key, tmp_val) { + if (tmp_key) { + php_error_docref(NULL, E_WARNING, "Multiple header key must be numeric index (%s)", ZSTR_VAL(tmp_key)); + continue; + } + if (Z_TYPE_P(tmp_val) != IS_STRING) { + php_error_docref(NULL, E_WARNING, "Multiple header values must be string (%s)", ZSTR_VAL(key)); + continue; + } + php_mail_build_headers_elem(s, key, tmp_val); + } ZEND_HASH_FOREACH_END(); +} + + +PHPAPI zend_string *php_mail_build_headers(zval *headers) +{ + zend_ulong idx; + zend_string *key; + zval *val; + smart_str s = {0}; + + ZEND_ASSERT(Z_TYPE_P(headers) == IS_ARRAY); + + ZEND_HASH_FOREACH_KEY_VAL(HASH_OF(headers), idx, key, val) { + if (!key) { + php_error_docref(NULL, E_WARNING, "Found numeric header (" ZEND_LONG_FMT ")", idx); + continue; + } + /* https://tools.ietf.org/html/rfc2822#section-3.6 */ + switch(ZSTR_LEN(key)) { + case sizeof("orig-date")-1: + if (!strncasecmp("orig-date", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("orig-date", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("from")-1: + if (!strncasecmp("from", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("from", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("sender")-1: + if (!strncasecmp("sender", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("sender", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("reply-to")-1: + if (!strncasecmp("reply-to", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("reply-to", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("to")-1: /* "to", "cc" */ + if (!strncasecmp("to", ZSTR_VAL(key), ZSTR_LEN(key))) { + php_error_docref(NULL, E_WARNING, "Extra header cannot contain 'To' header"); + continue; + } + if (!strncasecmp("cc", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("cc", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("bcc")-1: + if (!strncasecmp("bcc", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("bcc", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("message-id")-1: /* "references" */ + if (!strncasecmp("message-id", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("message-id", s, key, val); + } else if (!strncasecmp("references", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("references", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("in-reply-to")-1: + if (!strncasecmp("in-reply-to", ZSTR_VAL(key), ZSTR_LEN(key))) { + PHP_MAIL_BUILD_HEADER_CHECK("in-reply-to", s, key, val); + } else { + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + break; + case sizeof("subject")-1: + if (!strncasecmp("subject", ZSTR_VAL(key), ZSTR_LEN(key))) { + php_error_docref(NULL, E_WARNING, "Extra header cannot contain 'Subject' header"); + continue; + } + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + break; + default: + PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); + } + } ZEND_HASH_FOREACH_END(); + + /* Remove the last \r\n */ + if (s.s) s.s->len -= 2; + smart_str_0(&s); + + return s.s; +} + + /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]]) Send an email message */ PHP_FUNCTION(mail) { char *to=NULL, *message=NULL; char *subject=NULL; - zend_string *extra_cmd=NULL, *headers=NULL, *headers_trimmed=NULL; + zend_string *extra_cmd=NULL, *str_headers=NULL, *tmp_headers; + zval *headers = NULL; size_t to_len, message_len; size_t subject_len, i; char *force_extra_parameters = INI_STR("mail.force_extra_parameters"); char *to_r, *subject_r; char *p, *e; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|SS", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &extra_cmd) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|zS", &to, &to_len, &subject, &subject_len, &message, &message_len, &headers, &extra_cmd) == FAILURE) { return; } @@ -118,8 +309,20 @@ PHP_FUNCTION(mail) MAIL_ASCIIZ_CHECK(subject, subject_len); MAIL_ASCIIZ_CHECK(message, message_len); if (headers) { - MAIL_ASCIIZ_CHECK(ZSTR_VAL(headers), ZSTR_LEN(headers)); - headers_trimmed = php_trim(headers, NULL, 0, 2); + switch(Z_TYPE_P(headers)) { + case IS_STRING: + tmp_headers = zend_string_init(Z_STRVAL_P(headers), Z_STRLEN_P(headers), 0); + MAIL_ASCIIZ_CHECK(ZSTR_VAL(tmp_headers), ZSTR_LEN(tmp_headers)); + str_headers = php_trim(tmp_headers, NULL, 0, 2); + zend_string_release(tmp_headers); + break; + case IS_ARRAY: + str_headers = php_mail_build_headers(headers); + break; + default: + php_error_docref(NULL, E_WARNING, "headers parameter must be string or array"); + RETURN_FALSE; + } } if (extra_cmd) { MAIL_ASCIIZ_CHECK(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd)); @@ -171,14 +374,14 @@ PHP_FUNCTION(mail) extra_cmd = php_escape_shell_cmd(ZSTR_VAL(extra_cmd)); } - if (php_mail(to_r, subject_r, message, headers_trimmed ? ZSTR_VAL(headers_trimmed) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) { + if (php_mail(to_r, subject_r, message, str_headers ? ZSTR_VAL(str_headers) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) { RETVAL_TRUE; } else { RETVAL_FALSE; } - if (headers_trimmed) { - zend_string_release(headers_trimmed); + if (str_headers) { + zend_string_release(str_headers); } if (extra_cmd) { diff --git a/ext/standard/math.c b/ext/standard/math.c index 83145a4dc9..7a3d9b6621 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -25,6 +25,7 @@ #include "php_math.h" #include "zend_multiply.h" #include "zend_exceptions.h" +#include "zend_portability.h" #include <math.h> #include <float.h> @@ -239,7 +240,7 @@ static double php_acosh(double x) if (x >= 1) { return log(x + sqrt(x * x - 1)); } else { - return (DBL_MAX+DBL_MAX)-(DBL_MAX+DBL_MAX); + return ZEND_NAN; } # else return(log(x + sqrt(x * x - 1))); @@ -707,7 +708,7 @@ PHP_FUNCTION(log) } if (base == 1.0) { - RETURN_DOUBLE(php_get_nan()); + RETURN_DOUBLE(ZEND_NAN); } if (base <= 0.0) { @@ -951,7 +952,7 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base) char buf[(sizeof(double) << 3) + 1]; /* Don't try to convert +/- infinity */ - if (fvalue == HUGE_VAL || fvalue == -HUGE_VAL) { + if (fvalue == ZEND_INFINITY || fvalue == -ZEND_INFINITY) { php_error_docref(NULL, E_WARNING, "Number too large"); return ZSTR_EMPTY_ALLOC(); } diff --git a/ext/standard/password.c b/ext/standard/password.c index d01ddb0563..d362e6f7f3 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara <ircmaxell@php.net> | + | Charles R. Portwood II <charlesportwoodii@erianna.com> | +----------------------------------------------------------------------+ */ @@ -30,6 +31,9 @@ #include "zend_interfaces.h" #include "info.h" #include "php_random.h" +#if HAVE_ARGON2LIB +#include "argon2.h" +#endif #if PHP_WIN32 #include "win32/winutil.h" @@ -39,8 +43,16 @@ PHP_MINIT_FUNCTION(password) /* {{{ */ { REGISTER_LONG_CONSTANT("PASSWORD_DEFAULT", PHP_PASSWORD_DEFAULT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PASSWORD_BCRYPT", PHP_PASSWORD_BCRYPT, CONST_CS | CONST_PERSISTENT); +#if HAVE_ARGON2LIB + REGISTER_LONG_CONSTANT("PASSWORD_ARGON2I", PHP_PASSWORD_ARGON2I, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("PASSWORD_BCRYPT_DEFAULT_COST", PHP_PASSWORD_BCRYPT_COST, CONST_CS | CONST_PERSISTENT); +#if HAVE_ARGON2LIB + REGISTER_LONG_CONSTANT("PASSWORD_ARGON2_DEFAULT_MEMORY_COST", PHP_PASSWORD_ARGON2_MEMORY_COST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PASSWORD_ARGON2_DEFAULT_TIME_COST", PHP_PASSWORD_ARGON2_TIME_COST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PASSWORD_ARGON2_DEFAULT_THREADS", PHP_PASSWORD_ARGON2_THREADS, CONST_CS | CONST_PERSISTENT); +#endif return SUCCESS; } @@ -51,6 +63,10 @@ static char* php_password_get_algo_name(const php_password_algo algo) switch (algo) { case PHP_PASSWORD_BCRYPT: return "bcrypt"; +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + return "argon2i"; +#endif case PHP_PASSWORD_UNKNOWN: default: return "unknown"; @@ -61,7 +77,12 @@ static php_password_algo php_password_determine_algo(const char *hash, const siz { if (len > 3 && hash[0] == '$' && hash[1] == '2' && hash[2] == 'y' && len == 60) { return PHP_PASSWORD_BCRYPT; + } +#if HAVE_ARGON2LIB + if (len >= sizeof("$argon2i$")-1 && !memcmp(hash, "$argon2i$", sizeof("$argon2i$")-1)) { + return PHP_PASSWORD_ARGON2I; } +#endif return PHP_PASSWORD_UNKNOWN; } @@ -143,6 +164,8 @@ static int php_password_make_salt(size_t length, char *ret) /* {{{ */ } /* }}} */ +/* {{{ proto array password_get_info(string $hash) +Retrieves information about a given hash */ PHP_FUNCTION(password_get_info) { php_password_algo algo; @@ -167,6 +190,21 @@ PHP_FUNCTION(password_get_info) add_assoc_long(&options, "cost", cost); } break; +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + { + zend_long v = 0; + zend_long memory_cost = PHP_PASSWORD_ARGON2_MEMORY_COST; + zend_long time_cost = PHP_PASSWORD_ARGON2_TIME_COST; + zend_long threads = PHP_PASSWORD_ARGON2_THREADS; + + sscanf(hash, "$%*[argon2i]$v=" ZEND_LONG_FMT "$m=" ZEND_LONG_FMT ",t=" ZEND_LONG_FMT ",p=" ZEND_LONG_FMT, &v, &memory_cost, &time_cost, &threads); + add_assoc_long(&options, "memory_cost", memory_cost); + add_assoc_long(&options, "time_cost", time_cost); + add_assoc_long(&options, "threads", threads); + } + break; +#endif case PHP_PASSWORD_UNKNOWN: default: break; @@ -178,7 +216,10 @@ PHP_FUNCTION(password_get_info) add_assoc_string(return_value, "algoName", algo_name); add_assoc_zval(return_value, "options", &options); } +/** }}} */ +/* {{{ proto boolean password_needs_rehash(string $hash, integer $algo[, array $options]) +Determines if a given hash requires re-hashing based upon parameters */ PHP_FUNCTION(password_needs_rehash) { zend_long new_algo = 0; @@ -213,14 +254,43 @@ PHP_FUNCTION(password_needs_rehash) } } break; +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + { + zend_long v = 0; + zend_long new_memory_cost = PHP_PASSWORD_ARGON2_MEMORY_COST, memory_cost = 0; + zend_long new_time_cost = PHP_PASSWORD_ARGON2_TIME_COST, time_cost = 0; + zend_long new_threads = PHP_PASSWORD_ARGON2_THREADS, threads = 0; + + if (options && (option_buffer = zend_hash_str_find(options, "memory_cost", sizeof("memory_cost")-1)) != NULL) { + new_memory_cost = zval_get_long(option_buffer); + } + + if (options && (option_buffer = zend_hash_str_find(options, "time_cost", sizeof("time_cost")-1)) != NULL) { + new_time_cost = zval_get_long(option_buffer); + } + + if (options && (option_buffer = zend_hash_str_find(options, "threads", sizeof("threads")-1)) != NULL) { + new_threads = zval_get_long(option_buffer); + } + + sscanf(hash, "$%*[argon2i]$v=" ZEND_LONG_FMT "$m=" ZEND_LONG_FMT ",t=" ZEND_LONG_FMT ",p=" ZEND_LONG_FMT, &v, &memory_cost, &time_cost, &threads); + + if (new_time_cost != time_cost || new_memory_cost != memory_cost || new_threads != threads) { + RETURN_TRUE; + } + } + break; +#endif case PHP_PASSWORD_UNKNOWN: default: break; } RETURN_FALSE; } +/* }}} */ -/* {{{ proto boolean password_make_salt(string password, string hash) +/* {{{ proto boolean password_verify(string password, string hash) Verify a hash created using crypt() or password_hash() */ PHP_FUNCTION(password_verify) { @@ -228,35 +298,62 @@ PHP_FUNCTION(password_verify) size_t i, password_len, hash_len; char *password, *hash; zend_string *ret; + php_password_algo algo; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &password, &password_len, &hash, &hash_len) == FAILURE) { RETURN_FALSE; } - if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len, 1)) == NULL) { - RETURN_FALSE; - } - if (ZSTR_LEN(ret) != hash_len || hash_len < 13) { - zend_string_free(ret); - RETURN_FALSE; - } + algo = php_password_determine_algo(hash, (size_t) hash_len); - /* We're using this method instead of == in order to provide - * resistance towards timing attacks. This is a constant time - * equality check that will always check every byte of both - * values. */ - for (i = 0; i < hash_len; i++) { - status |= (ZSTR_VAL(ret)[i] ^ hash[i]); - } + switch(algo) { +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + { + argon2_type type = Argon2_i; - zend_string_free(ret); + status = argon2_verify(hash, password, password_len, type); + + if (status == ARGON2_OK) { + RETURN_TRUE; + } - RETURN_BOOL(status == 0); + RETURN_FALSE; + } + break; +#endif + case PHP_PASSWORD_BCRYPT: + case PHP_PASSWORD_UNKNOWN: + default: + { + if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len, 1)) == NULL) { + RETURN_FALSE; + } + + if (ZSTR_LEN(ret) != hash_len || hash_len < 13) { + zend_string_free(ret); + RETURN_FALSE; + } + + /* We're using this method instead of == in order to provide + * resistance towards timing attacks. This is a constant time + * equality check that will always check every byte of both + * values. */ + for (i = 0; i < hash_len; i++) { + status |= (ZSTR_VAL(ret)[i] ^ hash[i]); + } + + zend_string_free(ret); + + RETURN_BOOL(status == 0); + } + } + RETURN_FALSE; } /* }}} */ -/* {{{ proto string password_hash(string password, int algo, array options = array()) +/* {{{ proto string password_hash(string password, int algo[, array options = array()]) Hash a password */ PHP_FUNCTION(password_hash) { @@ -267,7 +364,13 @@ PHP_FUNCTION(password_hash) size_t salt_len = 0, required_salt_len = 0, hash_format_len; HashTable *options = 0; zval *option_buffer; - zend_string *result; + +#if HAVE_ARGON2LIB + size_t time_cost = PHP_PASSWORD_ARGON2_TIME_COST; + size_t memory_cost = PHP_PASSWORD_ARGON2_MEMORY_COST; + size_t threads = PHP_PASSWORD_ARGON2_THREADS; + argon2_type type = Argon2_i; +#endif if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|H", &password, &password_len, &algo, &options) == FAILURE) { return; @@ -275,23 +378,57 @@ PHP_FUNCTION(password_hash) switch (algo) { case PHP_PASSWORD_BCRYPT: - { - zend_long cost = PHP_PASSWORD_BCRYPT_COST; + { + zend_long cost = PHP_PASSWORD_BCRYPT_COST; - if (options && (option_buffer = zend_hash_str_find(options, "cost", sizeof("cost")-1)) != NULL) { - cost = zval_get_long(option_buffer); - } + if (options && (option_buffer = zend_hash_str_find(options, "cost", sizeof("cost")-1)) != NULL) { + cost = zval_get_long(option_buffer); + } - if (cost < 4 || cost > 31) { - php_error_docref(NULL, E_WARNING, "Invalid bcrypt cost parameter specified: " ZEND_LONG_FMT, cost); - RETURN_NULL(); + if (cost < 4 || cost > 31) { + php_error_docref(NULL, E_WARNING, "Invalid bcrypt cost parameter specified: " ZEND_LONG_FMT, cost); + RETURN_NULL(); + } + + required_salt_len = 22; + sprintf(hash_format, "$2y$%02ld$", (long) cost); + hash_format_len = 7; } + break; +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + { + if (options && (option_buffer = zend_hash_str_find(options, "memory_cost", sizeof("memory_cost")-1)) != NULL) { + memory_cost = zval_get_long(option_buffer); + } - required_salt_len = 22; - sprintf(hash_format, "$2y$%02ld$", (long) cost); - hash_format_len = 7; - } - break; + if (memory_cost > ARGON2_MAX_MEMORY || memory_cost < ARGON2_MIN_MEMORY) { + php_error_docref(NULL, E_WARNING, "Memory cost is outside of allowed memory range", memory_cost); + RETURN_NULL(); + } + + if (options && (option_buffer = zend_hash_str_find(options, "time_cost", sizeof("time_cost")-1)) != NULL) { + time_cost = zval_get_long(option_buffer); + } + + if (time_cost > ARGON2_MAX_TIME || time_cost < ARGON2_MIN_TIME) { + php_error_docref(NULL, E_WARNING, "Time cost is outside of allowed time range", time_cost); + RETURN_NULL(); + } + + if (options && (option_buffer = zend_hash_str_find(options, "threads", sizeof("threads")-1)) != NULL) { + threads = zval_get_long(option_buffer); + } + + if (threads > ARGON2_MAX_LANES || threads == 0) { + php_error_docref(NULL, E_WARNING, "Invalid number of threads", threads); + RETURN_NULL(); + } + + required_salt_len = 16; + } + break; +#endif case PHP_PASSWORD_UNKNOWN: default: php_error_docref(NULL, E_WARNING, "Unknown password hashing algorithm: " ZEND_LONG_FMT, algo); @@ -356,30 +493,88 @@ PHP_FUNCTION(password_hash) salt_len = required_salt_len; } - salt[salt_len] = 0; + switch (algo) { + case PHP_PASSWORD_BCRYPT: + { + zend_string *result; + salt[salt_len] = 0; - hash = safe_emalloc(salt_len + hash_format_len, 1, 1); - sprintf(hash, "%s%s", hash_format, salt); - hash[hash_format_len + salt_len] = 0; + hash = safe_emalloc(salt_len + hash_format_len, 1, 1); + sprintf(hash, "%s%s", hash_format, salt); + hash[hash_format_len + salt_len] = 0; - efree(salt); + efree(salt); - /* This cast is safe, since both values are defined here in code and cannot overflow */ - hash_len = (int) (hash_format_len + salt_len); + /* This cast is safe, since both values are defined here in code and cannot overflow */ + hash_len = (int) (hash_format_len + salt_len); - if ((result = php_crypt(password, (int)password_len, hash, hash_len, 1)) == NULL) { - efree(hash); - RETURN_FALSE; - } + if ((result = php_crypt(password, (int)password_len, hash, hash_len, 1)) == NULL) { + efree(hash); + RETURN_FALSE; + } - efree(hash); + efree(hash); - if (ZSTR_LEN(result) < 13) { - zend_string_free(result); - RETURN_FALSE; - } + if (ZSTR_LEN(result) < 13) { + zend_string_free(result); + RETURN_FALSE; + } - RETURN_STR(result); + RETURN_STR(result); + } + break; +#if HAVE_ARGON2LIB + case PHP_PASSWORD_ARGON2I: + { + size_t out_len = 32; + size_t encoded_len; + int status = 0; + char *out; + zend_string *encoded; + + encoded_len = argon2_encodedlen( + time_cost, + memory_cost, + threads, + (uint32_t)salt_len, + out_len + ); + + out = emalloc(out_len + 1); + encoded = zend_string_alloc(encoded_len, 0); + + status = argon2_hash( + time_cost, + memory_cost, + threads, + password, + password_len, + salt, + salt_len, + out, + out_len, + ZSTR_VAL(encoded), + encoded_len, + type, + ARGON2_VERSION_NUMBER + ); + + efree(out); + efree(salt); + + if (status != ARGON2_OK) { + zend_string_free(encoded); + php_error_docref(NULL, E_WARNING, argon2_error_message(status)); + RETURN_FALSE; + } + + RETURN_STR(encoded); + } + break; +#endif + default: + RETURN_FALSE; + } } /* }}} */ diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 514b189681..6f7d703312 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -22,9 +22,39 @@ #define PHP_MAIL_H PHP_FUNCTION(mail); +PHP_FUNCTION(ezmlm_hash); + PHP_MINFO_FUNCTION(mail); -PHP_FUNCTION(ezmlm_hash); +PHPAPI zend_string *php_mail_build_headers(zval *headers); PHPAPI extern int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd); +#define PHP_MAIL_BUILD_HEADER_CHECK(target, s, key, val) \ +do { \ + if (Z_TYPE_P(val) == IS_STRING) { \ + php_mail_build_headers_elem(&s, key, val); \ + } else if (Z_TYPE_P(val) == IS_ARRAY) { \ + if (!strncasecmp(target, ZSTR_VAL(key), ZSTR_LEN(key))) { \ + php_error_docref(NULL, E_WARNING, "'%s' header must be at most one header. Array is passed for '%s'", target, target); \ + continue; \ + } \ + php_mail_build_headers_elems(&s, key, val); \ + } else { \ + php_error_docref(NULL, E_WARNING, "Extra header element '%s' cannot be other than string or array.", ZSTR_VAL(key)); \ + } \ +} while(0) + + +#define PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val) \ +do { \ + if (Z_TYPE_P(val) == IS_STRING) { \ + php_mail_build_headers_elem(&s, key, val); \ + } else if (Z_TYPE_P(val) == IS_ARRAY) { \ + php_mail_build_headers_elems(&s, key, val); \ + } else { \ + php_error_docref(NULL, E_WARNING, "Extra header element '%s' cannot be other than string or array.", ZSTR_VAL(key)); \ + } \ +} while(0) + + #endif /* PHP_MAIL_H */ diff --git a/ext/standard/php_password.h b/ext/standard/php_password.h index fdc72b0258..4bc2e5660f 100644 --- a/ext/standard/php_password.h +++ b/ext/standard/php_password.h @@ -13,6 +13,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara <ircmaxell@php.net> | + | Charles R. Portwood II <charlesportwoodii@erianna.com> | +----------------------------------------------------------------------+ */ @@ -28,13 +29,21 @@ PHP_FUNCTION(password_get_info); PHP_MINIT_FUNCTION(password); -#define PHP_PASSWORD_DEFAULT PHP_PASSWORD_BCRYPT - +#define PHP_PASSWORD_DEFAULT PHP_PASSWORD_BCRYPT #define PHP_PASSWORD_BCRYPT_COST 10 +#if HAVE_ARGON2LIB +#define PHP_PASSWORD_ARGON2_MEMORY_COST 1<<10 +#define PHP_PASSWORD_ARGON2_TIME_COST 2 +#define PHP_PASSWORD_ARGON2_THREADS 2 +#endif + typedef enum { - PHP_PASSWORD_UNKNOWN, - PHP_PASSWORD_BCRYPT + PHP_PASSWORD_UNKNOWN, + PHP_PASSWORD_BCRYPT, +#if HAVE_ARGON2LIB + PHP_PASSWORD_ARGON2I, +#endif } php_password_algo; #endif diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 51cf8c9962..6fc7587121 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -93,6 +93,8 @@ PHP_FUNCTION(str_word_count); PHP_FUNCTION(str_split); PHP_FUNCTION(strpbrk); PHP_FUNCTION(substr_compare); +PHP_FUNCTION(utf8_encode); +PHP_FUNCTION(utf8_decode); #ifdef HAVE_STRCOLL PHP_FUNCTION(strcoll); #endif @@ -133,8 +135,8 @@ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len); PHPAPI zend_string *php_str_to_str(char *haystack, size_t length, char *needle, size_t needle_len, char *str, size_t str_len); PHPAPI zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode); -PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *state, const char *allow, size_t allow_len); -PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces); +PHPAPI size_t php_strip_tags(char *rbuf, size_t len, uint8_t *state, const char *allow, size_t allow_len); +PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces); PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value); PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit); diff --git a/ext/standard/string.c b/ext/standard/string.c index c41d48ef17..4389e10702 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -64,6 +64,8 @@ /* For str_getcsv() support */ #include "ext/standard/file.h" +/* For php_next_utf8_char() */ +#include "ext/standard/html.h" #define STR_PAD_LEFT 0 #define STR_PAD_RIGHT 1 @@ -4599,7 +4601,7 @@ int php_tag_find(char *tag, size_t len, const char *set) { } /* }}} */ -PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len) /* {{{ */ +PHPAPI size_t php_strip_tags(char *rbuf, size_t len, uint8_t *stateptr, const char *allow, size_t allow_len) /* {{{ */ { return php_strip_tags_ex(rbuf, len, stateptr, allow, allow_len, 0); } @@ -4625,11 +4627,11 @@ PHPAPI size_t php_strip_tags(char *rbuf, size_t len, int *stateptr, const char * swm: Added ability to strip <?xml tags without assuming it PHP code. */ -PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces) +PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces) { char *tbuf, *buf, *p, *tp, *rp, c, lc; int br, depth=0, in_q = 0; - int state = 0; + uint8_t state = 0; size_t pos, i = 0; char *allow_free = NULL; const char *allow_actual; @@ -5653,6 +5655,98 @@ PHP_FUNCTION(substr_compare) } /* }}} */ +/* {{{ */ +static zend_string *php_utf8_encode(const char *s, size_t len) +{ + size_t pos = len; + zend_string *str; + unsigned char c; + + str = zend_string_safe_alloc(len, 2, 0, 0); + ZSTR_LEN(str) = 0; + while (pos > 0) { + /* The lower 256 codepoints of Unicode are identical to Latin-1, + * so we don't need to do any mapping here. */ + c = (unsigned char)(*s); + if (c < 0x80) { + ZSTR_VAL(str)[ZSTR_LEN(str)++] = (char) c; + /* We only account for the single-byte and two-byte cases because + * we're only dealing with the first 256 Unicode codepoints. */ + } else { + ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xc0 | (c >> 6)); + ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0x80 | (c & 0x3f)); + } + pos--; + s++; + } + ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0'; + str = zend_string_truncate(str, ZSTR_LEN(str), 0); + return str; +} +/* }}} */ + +/* {{{ */ +static zend_string *php_utf8_decode(const char *s, size_t len) +{ + size_t pos = 0; + unsigned int c; + zend_string *str; + + str = zend_string_alloc(len, 0); + ZSTR_LEN(str) = 0; + while (pos < len) { + int status = FAILURE; + c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status); + + /* The lower 256 codepoints of Unicode are identical to Latin-1, + * so we don't need to do any mapping here beyond replacing non-Latin-1 + * characters. */ + if (status == FAILURE || c > 0xFFU) { + c = '?'; + } + + ZSTR_VAL(str)[ZSTR_LEN(str)++] = c; + } + ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0'; + if (ZSTR_LEN(str) < len) { + str = zend_string_truncate(str, ZSTR_LEN(str), 0); + } + + return str; +} +/* }}} */ + + +/* {{{ proto string utf8_encode(string data) + Encodes an ISO-8859-1 string to UTF-8 */ +PHP_FUNCTION(utf8_encode) +{ + char *arg; + size_t arg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { + return; + } + + RETURN_STR(php_utf8_encode(arg, arg_len)); +} +/* }}} */ + +/* {{{ proto string utf8_decode(string data) + Converts a UTF-8 encoded string to ISO-8859-1 */ +PHP_FUNCTION(utf8_decode) +{ + char *arg; + size_t arg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { + return; + } + + RETURN_STR(php_utf8_decode(arg, arg_len)); +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/standard/strnatcmp.c b/ext/standard/strnatcmp.c index a272be8a29..ac8d2a2e91 100644 --- a/ext/standard/strnatcmp.c +++ b/ext/standard/strnatcmp.c @@ -30,16 +30,6 @@ #include "php.h" #include "php_string.h" -#if defined(__GNUC__) -# define UNUSED __attribute__((__unused__)) -#else -# define UNUSED -#endif - -#if 0 -static char const *version UNUSED = - "$Id$"; -#endif /* {{{ compare_right */ static int diff --git a/ext/standard/tests/class_object/get_class_variation_001.phpt b/ext/standard/tests/class_object/get_class_variation_001.phpt index d39da3a991..3987968e90 100644 --- a/ext/standard/tests/class_object/get_class_variation_001.phpt +++ b/ext/standard/tests/class_object/get_class_variation_001.phpt @@ -152,12 +152,12 @@ bool(false) Arg value: (type: NULL) -Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d +Warning: get_class() expects parameter 1 to be object, null given in %s on line %d bool(false) Arg value: (type: NULL) -Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d +Warning: get_class() expects parameter 1 to be object, null given in %s on line %d bool(false) Arg value: 1 (type: boolean) @@ -202,11 +202,11 @@ bool(false) Arg value: (type: NULL) -Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d +Warning: get_class() expects parameter 1 to be object, null given in %s on line %d bool(false) Arg value: (type: NULL) -Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d +Warning: get_class() expects parameter 1 to be object, null given in %s on line %d bool(false) Done diff --git a/ext/standard/tests/general_functions/proc_nice_basic-win.phpt b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt new file mode 100644 index 0000000000..232389fd90 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_basic-win.phpt @@ -0,0 +1,96 @@ +--TEST-- +proc_nice() basic behaviour +--SKIPIF-- +<?php +/* No function_exists() check, proc_nice() is always available on Windows */ + +if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + die('skip: Only for Windows'); +} + +if (PHP_SAPI != 'cli') { + die('skip: Only for CLI'); +} + +if (getenv('SKIP_SLOW_TESTS')) { + doe('skip: Slow test'); +} +?> +--FILE-- +<?php +function get_priority_from_wmic() { + static $bin, $pid; + + if (!$bin) { + $t = explode('\\', PHP_BINARY); + + $bin = end($t); + $pid = getmypid(); + } + + $t = ''; + $p = popen('wmic process where name="' . $bin . '"', 'r'); + + if (!$p) { + return false; + } + + while(!feof($p)) { + $t .= fread($p, 1024); + } + + pclose($p); + + $t = explode(PHP_EOL, $t); + + $f = false; + $m = [ + strpos($t[0], ' ProcessId' ), + strpos($t[0], ' Priority ') + ]; + + foreach ($t as $n => $l) { + if (!$n || empty($l)) { + continue; + } + + $d = []; + + foreach ($m as $c) { + $d[] = (int) substr($l, $c + 1, strpos($l, ' ', $c + 2) - ($c + 1)); + } + + if ($d[0] === $pid) { + return $d[1]; + } + } + + return false; +} + +$p = [ + /* '<verbose name>' => ['<wmic value>', '<proc_nice value>'] */ + + 'Idle' => [4, 10], + 'Below normal' => [6, 5], + 'Normal' => [8, 0], + 'Above normal' => [10, -5], + 'High priority' => [13, -10], + 'Real time' => [24, -16] + ]; + +foreach ($p as $test => $data) { + printf('Testing \'%s\' (%d): ', $test, $data[1]); + + proc_nice($data[1]); + + print (($wp = get_priority_from_wmic()) === $data[0] ? 'Passed' : 'Failed (' . $wp . ')') . PHP_EOL; +} +?> +--EXPECTF-- +Testing 'Idle' (10): Passed +Testing 'Below normal' (5): Passed +Testing 'Normal' (0): Passed +Testing 'Above normal' (-5): Passed +Testing 'High priority' (-10): Passed +Testing 'Real time' (-16): Passed diff --git a/ext/standard/tests/general_functions/proc_nice_basic.phpt b/ext/standard/tests/general_functions/proc_nice_basic.phpt index 83b5165679..12469bf4eb 100644 --- a/ext/standard/tests/general_functions/proc_nice_basic.phpt +++ b/ext/standard/tests/general_functions/proc_nice_basic.phpt @@ -8,6 +8,7 @@ Simone Gentili (sensorario@gmail.com) --SKIPIF-- <?php if(!function_exists('proc_nice')) die("skip. proc_nice not available "); +if(substr(strtoupper(PHP_OS), 0, 3) == 'WIN') die('skip. not for Windows'); ?> --FILE-- <?php diff --git a/ext/standard/tests/general_functions/type.phpt b/ext/standard/tests/general_functions/type.phpt index eb6f0672fe..df2dbaf461 100644 --- a/ext/standard/tests/general_functions/type.phpt +++ b/ext/standard/tests/general_functions/type.phpt @@ -63,7 +63,7 @@ string(6) "double" string(4) "NULL" string(7) "boolean" string(6) "string" -string(12) "unknown type" +string(17) "resource (closed)" string(8) "resource" string(6) "object" bool(true) diff --git a/ext/standard/tests/mail/mail_basic7.phpt b/ext/standard/tests/mail/mail_basic7.phpt new file mode 100644 index 0000000000..3b389d2c4e --- /dev/null +++ b/ext/standard/tests/mail/mail_basic7.phpt @@ -0,0 +1,218 @@ +--TEST-- +Test mail() function : array extra header basic functionality +--INI-- +sendmail_path=tee mailBasic.out >/dev/null +mail.add_x_header = Off +--SKIPIF-- +<?php +if(substr(PHP_OS, 0, 3) == "WIN") + die("skip Won't run on Windows"); +?> +--FILE-- +<?php +/* Prototype : int mail(string to, string subject, string message [, mixed additional_headers [, string additional_parameters]]) + * Description: Send an email message + * Source code: ext/standard/mail.c + * Alias to functions: + */ + +error_reporting(-1); + +echo "*** Testing mail() : basic functionality ***\n"; + +echo "\n\n************* TEST ******************\n"; +// Should pass +// Initialise all required variables +$to = 'user@example.com'; +$subject = 'Test Subject'; +$message = 'A Message'; +$additional_headers = array( + 'KHeaders' => 'aaaa', + 'bcc'=>'foo@bar', + 'foo'=> + array( + "bar\r\n hoge", + "bar\r\n\t fuga", + ), +); +$outFile = "mailBasic.out"; +@unlink($outFile); + +echo "-- All Mail Content Parameters --\n"; +// Calling mail() with all additional headers +var_dump( mail($to, $subject, $message, $additional_headers) ); +echo file_get_contents($outFile); +unlink($outFile); + + +echo "\n\n************* TEST ******************\n"; +// Should fail all +// Initialise all required variables +$to = 'user@example.com'; +$subject = 'Test Subject'; +$message = 'A Message'; +// Headers should not have array values +$additional_headers = array( + 'orig-date' => array('foo1'), + 'from' => array('foo2'), + 'sender' => array('foo3'), + 'reply-to' => array('foo4'), + 'to' => array('foo5'), + 'bcc' => array('foo6'), + 'message-id' => array('foo7'), + 'in-reply-to'=> array('foo8'), +); +$outFile = "mailBasic.out"; +@unlink($outFile); + +echo "-- All Mail Content Parameters --\n"; +// Calling mail() with all additional headers +var_dump( mail($to, $subject, $message, $additional_headers) ); +echo file_get_contents($outFile); +unlink($outFile); + + +echo "\n\n************* TEST ******************\n"; +// Should fail all +// Initialise all required variables +$to = 'user@example.com'; +$subject = 'Test Subject'; +$message = 'A Message'; +$additional_headers = array( + 'foo1' => array('foo1'=>'bar1'), + 'foo2' => array('foo2', array('foo3')), + 'foo3' => array(123), + 'foo4' => array(123.456), + 'foo5' => array(FALSE), + 'foo6' => array(NULL), + 'foo7' => array(new StdClass), +); +$outFile = "mailBasic.out"; +@unlink($outFile); + +echo "-- All Mail Content Parameters --\n"; +// Calling mail() with all additional headers +var_dump( mail($to, $subject, $message, $additional_headers) ); +echo file_get_contents($outFile); +unlink($outFile); + + +echo "\n\n************* TEST ******************\n"; +// Should fail most +// Initialise all required variables +$to = 'user@example.com'; +$subject = 'Test Subject'; +$message = 'A Message'; +$additional_headers = array( + '*:foo1' => array('bar1'), + 'foo2:::' => array('bar1'), + 'foo3()' => array('bar1'), + 'foo4@' => array('bar1'), + 'foo5|' => array('bar1'), + "\0foo6" => array('bar1'), + "foo7\0" => array('bar1'), + "foo8" => array(), + "foo9" => '%&$#!', + "foo10" => "abc\0\tdef", +); +$outFile = "mailBasic.out"; +@unlink($outFile); + +echo "-- All Mail Content Parameters --\n"; +// Calling mail() with all additional headers +var_dump( mail($to, $subject, $message, $additional_headers) ); +echo file_get_contents($outFile); +unlink($outFile); + +?> +===DONE=== +--EXPECTF-- +*** Testing mail() : basic functionality *** + + +************* TEST ****************** +-- All Mail Content Parameters -- +bool(true) +To: user@example.com +Subject: Test Subject +KHeaders: aaaa +bcc: foo@bar +foo: bar + hoge +foo: bar + fuga + +A Message + + +************* TEST ****************** +-- All Mail Content Parameters -- + +Warning: mail(): 'orig-date' header must be at most one header. Array is passed for 'orig-date' in %s on line 59 + +Warning: mail(): 'from' header must be at most one header. Array is passed for 'from' in %s on line 59 + +Warning: mail(): 'sender' header must be at most one header. Array is passed for 'sender' in %s on line 59 + +Warning: mail(): 'reply-to' header must be at most one header. Array is passed for 'reply-to' in %s on line 59 + +Warning: mail(): Extra header cannot contain 'To' header in %s on line 59 + +Warning: mail(): 'bcc' header must be at most one header. Array is passed for 'bcc' in %s on line 59 + +Warning: mail(): 'message-id' header must be at most one header. Array is passed for 'message-id' in %s on line 59 + +Warning: mail(): 'in-reply-to' header must be at most one header. Array is passed for 'in-reply-to' in %s on line 59 +bool(true) +To: user@example.com +Subject: Test Subject + +A Message + + +************* TEST ****************** +-- All Mail Content Parameters -- + +Warning: mail(): Multiple header key must be numeric index (foo1) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo2) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo3) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo4) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo5) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo6) in %s on line 84 + +Warning: mail(): Multiple header values must be string (foo7) in %s on line 84 +bool(true) +To: user@example.com +Subject: Test Subject +foo2: foo2 + +A Message + + +************* TEST ****************** +-- All Mail Content Parameters -- + +Warning: mail(): Header field name (*:foo1) contains invalid chars in %s on line 112 + +Warning: mail(): Header field name (foo2:::) contains invalid chars in %s on line 112 + +Warning: mail(): Header field name () contains invalid chars in %s on line 112 + +Warning: mail(): Header field name (foo7) contains invalid chars in %s on line 112 + +Warning: mail(): Header field value (foo10 => abc) contains invalid chars or format in %s on line 112 +bool(true) +To: user@example.com +Subject: Test Subject +foo3(): bar1 +foo4@: bar1 +foo5|: bar1 +foo9: %&$#! + +A Message +===DONE=== diff --git a/ext/standard/tests/network/dns_get_mx.phpt b/ext/standard/tests/network/dns_get_mx.phpt index c5bf361b12..f6bb7ec05e 100644 --- a/ext/standard/tests/network/dns_get_mx.phpt +++ b/ext/standard/tests/network/dns_get_mx.phpt @@ -14,7 +14,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { ?> --FILE-- <?php -$domains = array('yahoo.co.jp', 'yahoo.com', 'es.yahoo.com', 'fr.yahoo.com', 'it.yahoo.com'); +$domains = array('php.net', 'doc.php.net', 'wiki.php.net'); foreach ($domains as $domain) { if (getmxrr($domain, $hosts, $weights)) { echo "Hosts: " . count($hosts) . ", weights: " . count($weights) . "\n"; @@ -25,5 +25,3 @@ foreach ($domains as $domain) { Hosts: %i, weights: %i Hosts: %i, weights: %i Hosts: %i, weights: %i -Hosts: %i, weights: %i -Hosts: %i, weights: %i diff --git a/ext/standard/tests/password/password_get_info_argon2.phpt b/ext/standard/tests/password/password_get_info_argon2.phpt new file mode 100644 index 0000000000..80c6f93416 --- /dev/null +++ b/ext/standard/tests/password/password_get_info_argon2.phpt @@ -0,0 +1,29 @@ +--TEST--
+Test normal operation of password_get_info() with Argon2
+--SKIPIF--
+<?php
+if (!defined('PASSWORD_ARGON2I')) die('skip password_get_info not built with Argon2');
+?>
+--FILE--
+<?php
+
+var_dump(password_get_info('$argon2i$v=19$m=65536,t=3,p=1$SWhIcG5MT21Pc01PbWdVZw$WagZELICsz7jlqOR2YzoEVTWb2oOX1tYdnhZYXxptbU'));
+echo "OK!";
+?>
+--EXPECT--
+array(3) {
+ ["algo"]=>
+ int(2)
+ ["algoName"]=>
+ string(7) "argon2i"
+ ["options"]=>
+ array(3) {
+ ["memory_cost"]=>
+ int(65536)
+ ["time_cost"]=>
+ int(3)
+ ["threads"]=>
+ int(1)
+ }
+}
+OK!
\ No newline at end of file diff --git a/ext/standard/tests/password/password_hash_argon2.phpt b/ext/standard/tests/password/password_hash_argon2.phpt new file mode 100644 index 0000000000..7bd8cd700c --- /dev/null +++ b/ext/standard/tests/password/password_hash_argon2.phpt @@ -0,0 +1,18 @@ +--TEST--
+Test normal operation of password_hash() with argon2
+--SKIPIF--
+<?php
+if (!defined('PASSWORD_ARGON2I')) die('skip password_hash not built with Argon2');
+--FILE--
+<?php
+
+$password = "the password for testing 12345!";
+
+$hash = password_hash($password, PASSWORD_ARGON2I);
+var_dump(password_verify($password, $hash));
+
+echo "OK!";
+?>
+--EXPECT--
+bool(true)
+OK!
\ No newline at end of file diff --git a/ext/standard/tests/password/password_hash_error_argon2.phpt b/ext/standard/tests/password/password_hash_error_argon2.phpt new file mode 100644 index 0000000000..7e8722ec6f --- /dev/null +++ b/ext/standard/tests/password/password_hash_error_argon2.phpt @@ -0,0 +1,21 @@ +--TEST--
+Test error operation of password_hash() with argon2
+--SKIPIF--
+<?php
+if (!defined('PASSWORD_ARGON2I')) die('skip password_hash not built with Argon2');
+?>
+--FILE--
+<?php
+var_dump(password_hash('test', PASSWORD_ARGON2I, ['memory_cost' => 0]));
+var_dump(password_hash('test', PASSWORD_ARGON2I, ['time_cost' => 0]));
+var_dump(password_hash('test', PASSWORD_ARGON2I, ['threads' => 0]));
+?>
+--EXPECTF--
+Warning: password_hash(): Memory cost is outside of allowed memory range in %s on line %d
+NULL
+
+Warning: password_hash(): Time cost is outside of allowed time range in %s on line %d
+NULL
+
+Warning: password_hash(): Invalid number of threads in %s on line %d
+NULL
\ No newline at end of file diff --git a/ext/standard/tests/password/password_needs_rehash_argon2.phpt b/ext/standard/tests/password/password_needs_rehash_argon2.phpt new file mode 100644 index 0000000000..61fc0a5cae --- /dev/null +++ b/ext/standard/tests/password/password_needs_rehash_argon2.phpt @@ -0,0 +1,22 @@ +--TEST--
+Test normal operation of password_needs_rehash() with argon2
+--SKIPIF--
+<?php
+if (!defined('PASSWORD_ARGON2I')) die('skip password_needs_rehash not built with Argon2');
+?>
+--FILE--
+<?php
+
+$hash = password_hash('test', PASSWORD_ARGON2I);
+var_dump(password_needs_rehash($hash, PASSWORD_ARGON2I));
+var_dump(password_needs_rehash($hash, PASSWORD_ARGON2I, ['memory_cost' => 1<<17]));
+var_dump(password_needs_rehash($hash, PASSWORD_ARGON2I, ['time_cost' => 4]));
+var_dump(password_needs_rehash($hash, PASSWORD_ARGON2I, ['threads' => 4]));
+echo "OK!";
+?>
+--EXPECT--
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+OK!
diff --git a/ext/standard/tests/password/password_verify_argon2.phpt b/ext/standard/tests/password/password_verify_argon2.phpt new file mode 100644 index 0000000000..e3a35942f5 --- /dev/null +++ b/ext/standard/tests/password/password_verify_argon2.phpt @@ -0,0 +1,18 @@ +--TEST--
+Test normal operation of password_verify() with argon2
+--SKIPIF--
+<?php
+if (!defined('PASSWORD_ARGON2I')) die('skip password_verify not built with Argon2');
+?>
+--FILE--
+<?php
+
+var_dump(password_verify('test', '$argon2i$v=19$m=65536,t=3,p=1$OEVjWWs2Z3YvWlNZQ0ZmNw$JKin7ahjmh8JYvMyFcXri0Ss/Uvd3uYpD7MG6C/5Cy0'));
+
+var_dump(password_verify('argon2', '$argon2i$v=19$m=65536,t=3,p=1$OEVjWWs2Z3YvWlNZQ0ZmNw$JKin7ahjmh8JYvMyFcXri0Ss/Uvd3uYpD7MG6C/5Cy0'));
+echo "OK!";
+?>
+--EXPECT--
+bool(true)
+bool(false)
+OK!
\ No newline at end of file diff --git a/ext/standard/tests/serialize/serialization_objects_005.phpt b/ext/standard/tests/serialize/serialization_objects_005.phpt index 35b1593879..9800168ca2 100644 --- a/ext/standard/tests/serialize/serialization_objects_005.phpt +++ b/ext/standard/tests/serialize/serialization_objects_005.phpt @@ -88,7 +88,7 @@ object(__PHP_Incomplete_Class)#%d (2) { ["p"]=> int(1) } -bool(false) +bool(true) Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line 43 NULL @@ -117,4 +117,4 @@ Notice: main(): The script tried to execute a method or access a property of an Notice: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line 57 NULL -Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line 59
\ No newline at end of file +Fatal error: main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "C" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in %s on line 59 diff --git a/ext/xml/tests/bug43957.phpt b/ext/standard/tests/strings/bug43957.phpt index f11d15627b..0380787b73 100644 --- a/ext/xml/tests/bug43957.phpt +++ b/ext/standard/tests/strings/bug43957.phpt @@ -1,10 +1,5 @@ --TEST-- Bug #43957 (utf8_decode() bogus conversion on multibyte indicator near end of string) ---SKIPIF-- -<?php -require_once("skipif.inc"); -if (!extension_loaded('xml')) die ("skip xml extension not available"); -?> --FILE-- <?php echo utf8_decode('abc'.chr(0xe0)); diff --git a/ext/xml/tests/bug49687.phpt b/ext/standard/tests/strings/bug49687.phpt index 3ff19cee7e..99e8dc3ec6 100644 --- a/ext/xml/tests/bug49687.phpt +++ b/ext/standard/tests/strings/bug49687.phpt @@ -1,10 +1,5 @@ --TEST--
Bug #49687 Several utf8_decode deficiencies and vulnerabilities
---SKIPIF--
-<?php
-require_once("skipif.inc");
-if (!extension_loaded('xml')) die ("skip xml extension not available");
-?>
--FILE--
<?php
diff --git a/ext/xml/tests/xml006.phpt b/ext/standard/tests/strings/utf8.phpt index c714e85913..aea04fdecd 100644 --- a/ext/xml/tests/xml006.phpt +++ b/ext/standard/tests/strings/utf8.phpt @@ -1,7 +1,5 @@ --TEST-- UTF-8<->ISO Latin 1 encoding/decoding test ---SKIPIF-- -<?php include("skipif.inc"); ?> --FILE-- <?php printf("%s -> %s\n", urlencode("æ"), urlencode(utf8_encode("æ"))); diff --git a/ext/xml/tests/utf8_decode_error.phpt b/ext/standard/tests/strings/utf8_decode_error.phpt index 8735fd82f6..911cc15cfc 100644 --- a/ext/xml/tests/utf8_decode_error.phpt +++ b/ext/standard/tests/strings/utf8_decode_error.phpt @@ -1,16 +1,10 @@ --TEST-- Test utf8_decode() function : error conditions ---SKIPIF-- -<?php -if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; -} -?> --FILE-- <?php /* Prototype : proto string utf8_decode(string data) * Description: Converts a UTF-8 encoded string to ISO-8859-1 - * Source code: ext/xml/xml.c + * Source code: ext/standard/string.c * Alias to functions: */ diff --git a/ext/xml/tests/utf8_decode_variation1.phpt b/ext/standard/tests/strings/utf8_decode_variation1.phpt index 4b9679a895..f564b87da0 100644 --- a/ext/xml/tests/utf8_decode_variation1.phpt +++ b/ext/standard/tests/strings/utf8_decode_variation1.phpt @@ -1,16 +1,10 @@ --TEST-- Test utf8_decode() function : usage variations - different types for data ---SKIPIF-- -<?php -if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; -} -?> --FILE-- <?php /* Prototype : proto string utf8_decode(string data) * Description: Converts a UTF-8 encoded string to ISO-8859-1 - * Source code: ext/xml/xml.c + * Source code: ext/standard/string.c * Alias to functions: */ diff --git a/ext/xml/tests/utf8_encode_error.phpt b/ext/standard/tests/strings/utf8_encode_error.phpt index a82f98ff3b..e12f0978b6 100644 --- a/ext/xml/tests/utf8_encode_error.phpt +++ b/ext/standard/tests/strings/utf8_encode_error.phpt @@ -1,16 +1,10 @@ --TEST-- Test utf8_encode() function : error conditions ---SKIPIF-- -<?php -if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; -} -?> --FILE-- <?php /* Prototype : proto string utf8_encode(string data) * Description: Encodes an ISO-8859-1 string to UTF-8 - * Source code: ext/xml/xml.c + * Source code: ext/standard/string.c * Alias to functions: */ diff --git a/ext/xml/tests/utf8_encode_variation1.phpt b/ext/standard/tests/strings/utf8_encode_variation1.phpt index 04b956c422..fa4b79976e 100644 --- a/ext/xml/tests/utf8_encode_variation1.phpt +++ b/ext/standard/tests/strings/utf8_encode_variation1.phpt @@ -1,16 +1,10 @@ --TEST-- Test utf8_encode() function : usage variations - <type here specifics of this variation> ---SKIPIF-- -<?php -if (!extension_loaded("xml")) { - print "skip - XML extension not loaded"; -} -?> --FILE-- <?php /* Prototype : proto string utf8_encode(string data) * Description: Encodes an ISO-8859-1 string to UTF-8 - * Source code: ext/xml/xml.c + * Source code: ext/standard/string.c * Alias to functions: */ diff --git a/ext/standard/type.c b/ext/standard/type.c index 60884da94e..88a1501570 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -59,17 +59,6 @@ PHP_FUNCTION(gettype) case IS_OBJECT: RETVAL_STRING("object"); - /* - { - char *result; - int res_len; - - res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length; - spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name); - RETVAL_STRINGL(result, res_len); - efree(result); - } - */ break; case IS_RESOURCE: @@ -78,8 +67,10 @@ PHP_FUNCTION(gettype) if (type_name) { RETVAL_STRING("resource"); - break; + } else { + RETVAL_STRING("resource (closed)"); } + break; } default: @@ -207,13 +198,7 @@ static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (Z_TYPE_P(arg) == type) { - if (type == IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(arg); - if (ZSTR_LEN(ce->name) == sizeof(INCOMPLETE_CLASS) - 1 - && !memcmp(ZSTR_VAL(ce->name), INCOMPLETE_CLASS, sizeof(INCOMPLETE_CLASS) - 1)) { - RETURN_FALSE; - } - } else if (type == IS_RESOURCE) { + if (type == IS_RESOURCE) { const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg)); if (!type_name) { RETURN_FALSE; diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 5ca6e0bb1f..9342cb0e2a 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -261,7 +261,7 @@ static php_stream_filter_ops userfilter_ops = { }; static php_stream_filter *user_filter_factory_create(const char *filtername, - zval *filterparams, int persistent) + zval *filterparams, uint8_t persistent) { struct php_user_filter_data *fdat = NULL; php_stream_filter *filter; diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index f3b997a6ef..4cf41e6eeb 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.16 */ +/* Generated by re2c 0.15.3 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -23,6 +23,7 @@ #include "php.h" #include "ext/standard/php_var.h" #include "php_incomplete_class.h" +#include "zend_portability.h" struct php_unserialize_data { void *first; @@ -283,7 +284,7 @@ static inline int unserialize_allowed_class( #define YYMARKER marker -#line 291 "ext/standard/var_unserializer.re" +#line 292 "ext/standard/var_unserializer.re" @@ -589,7 +590,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER) start = cursor; -#line 593 "ext/standard/var_unserializer.c" +#line 594 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -630,506 +631,107 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER) yych = *YYCURSOR; switch (yych) { case 'C': - case 'O': goto yy4; + case 'O': goto yy13; case 'N': goto yy5; - case 'R': goto yy6; - case 'S': goto yy7; - case 'a': goto yy8; - case 'b': goto yy9; - case 'd': goto yy10; - case 'i': goto yy11; + case 'R': goto yy2; + case 'S': goto yy10; + case 'a': goto yy11; + case 'b': goto yy6; + case 'd': goto yy8; + case 'i': goto yy7; case 'o': goto yy12; - case 'r': goto yy13; - case 's': goto yy14; - case '}': goto yy15; - default: goto yy2; + case 'r': goto yy4; + case 's': goto yy9; + case '}': goto yy14; + default: goto yy16; } yy2: - ++YYCURSOR; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == ':') goto yy95; yy3: -#line 959 "ext/standard/var_unserializer.re" +#line 960 "ext/standard/var_unserializer.re" { return 0; } -#line 653 "ext/standard/var_unserializer.c" +#line 655 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy17; + if (yych == ':') goto yy89; goto yy3; yy5: yych = *++YYCURSOR; - if (yych == ';') goto yy19; + if (yych == ';') goto yy87; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy21; + if (yych == ':') goto yy83; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy22; + if (yych == ':') goto yy77; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy23; + if (yych == ':') goto yy53; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy24; + if (yych == ':') goto yy46; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy25; + if (yych == ':') goto yy39; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy26; + if (yych == ':') goto yy32; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy27; + if (yych == ':') goto yy25; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy28; + if (yych == ':') goto yy17; goto yy3; yy14: - yych = *(YYMARKER = ++YYCURSOR); - if (yych == ':') goto yy29; - goto yy3; -yy15: ++YYCURSOR; -#line 953 "ext/standard/var_unserializer.re" +#line 954 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 706 "ext/standard/var_unserializer.c" +#line 704 "ext/standard/var_unserializer.c" +yy16: + yych = *++YYCURSOR; + goto yy3; yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { - goto yy31; + goto yy20; } - if (yych == '+') goto yy30; + if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: - ++YYCURSOR; -#line 648 "ext/standard/var_unserializer.re" - { - *p = YYCURSOR; - ZVAL_NULL(rval); - return 1; -} -#line 724 "ext/standard/var_unserializer.c" -yy21: - yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy33; - goto yy18; - } else { - if (yych <= '-') goto yy33; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy34; - goto yy18; - } -yy22: - yych = *++YYCURSOR; - if (yych == '+') goto yy36; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy37; - goto yy18; -yy23: - yych = *++YYCURSOR; - if (yych == '+') goto yy39; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy40; - goto yy18; -yy24: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '1') goto yy42; - goto yy18; -yy25: - yych = *++YYCURSOR; - if (yych <= '/') { - if (yych <= ',') { - if (yych == '+') goto yy43; - goto yy18; - } else { - if (yych <= '-') goto yy44; - if (yych <= '.') goto yy45; - goto yy18; - } - } else { - if (yych <= 'I') { - if (yych <= '9') goto yy46; - if (yych <= 'H') goto yy18; - goto yy48; - } else { - if (yych == 'N') goto yy49; - goto yy18; - } - } -yy26: - yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy50; - goto yy18; - } else { - if (yych <= '-') goto yy50; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy51; - goto yy18; - } -yy27: - yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy53; - goto yy18; - } else { - if (yych <= '-') goto yy53; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy54; - goto yy18; - } -yy28: - yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy56; - goto yy18; - } else { - if (yych <= '-') goto yy56; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy57; - goto yy18; - } -yy29: - yych = *++YYCURSOR; - if (yych == '+') goto yy59; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy60; - goto yy18; -yy30: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { - goto yy31; + goto yy20; } goto yy18; -yy31: +yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { - goto yy31; + goto yy20; } if (yych <= '/') goto yy18; - if (yych <= ':') goto yy62; - goto yy18; -yy33: + if (yych >= ';') goto yy18; yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy34: + if (yych != '"') goto yy18; ++YYCURSOR; - if (YYLIMIT <= YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy34; - if (yych == ';') goto yy63; - goto yy18; -yy36: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy37: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy37; - if (yych <= ':') goto yy65; - goto yy18; -yy39: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy40: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy40; - if (yych <= ':') goto yy66; - goto yy18; -yy42: - yych = *++YYCURSOR; - if (yych == ';') goto yy67; - goto yy18; -yy43: - yych = *++YYCURSOR; - if (yych == '.') goto yy45; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy46; - goto yy18; -yy44: - yych = *++YYCURSOR; - if (yych <= '/') { - if (yych != '.') goto yy18; - } else { - if (yych <= '9') goto yy46; - if (yych == 'I') goto yy48; - goto yy18; - } -yy45: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy69; - goto yy18; -yy46: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); - yych = *YYCURSOR; - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy18; - goto yy69; - } else { - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy46; - goto yy18; - } - } else { - if (yych <= 'E') { - if (yych <= ';') goto yy71; - if (yych <= 'D') goto yy18; - goto yy73; - } else { - if (yych == 'e') goto yy73; - goto yy18; - } - } -yy48: - yych = *++YYCURSOR; - if (yych == 'N') goto yy74; - goto yy18; -yy49: - yych = *++YYCURSOR; - if (yych == 'A') goto yy75; - goto yy18; -yy50: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy51: - ++YYCURSOR; - if (YYLIMIT <= YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy51; - if (yych == ';') goto yy76; - goto yy18; -yy53: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy54: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy54; - if (yych <= ':') goto yy78; - goto yy18; -yy56: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy57: - ++YYCURSOR; - if (YYLIMIT <= YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy57; - if (yych == ';') goto yy79; - goto yy18; -yy59: - yych = *++YYCURSOR; - if (yych <= '/') goto yy18; - if (yych >= ':') goto yy18; -yy60: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); - yych = *YYCURSOR; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy60; - if (yych <= ':') goto yy81; - goto yy18; -yy62: - yych = *++YYCURSOR; - if (yych == '"') goto yy82; - goto yy18; -yy63: - ++YYCURSOR; -#line 597 "ext/standard/var_unserializer.re" - { - zend_long id; - - *p = YYCURSOR; - if (!var_hash) return 0; - - id = parse_iv(start + 2) - 1; - if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { - return 0; - } - - zval_ptr_dtor(rval); - if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { - ZVAL_UNDEF(rval); - return 1; - } - if (Z_ISREF_P(rval_ref)) { - ZVAL_COPY(rval, rval_ref); - } else { - ZVAL_NEW_REF(rval_ref, rval_ref); - ZVAL_COPY(rval, rval_ref); - } - - return 1; -} -#line 1000 "ext/standard/var_unserializer.c" -yy65: - yych = *++YYCURSOR; - if (yych == '"') goto yy84; - goto yy18; -yy66: - yych = *++YYCURSOR; - if (yych == '{') goto yy86; - goto yy18; -yy67: - ++YYCURSOR; -#line 654 "ext/standard/var_unserializer.re" - { - *p = YYCURSOR; - ZVAL_BOOL(rval, parse_iv(start + 2)); - return 1; -} -#line 1017 "ext/standard/var_unserializer.c" -yy69: - ++YYCURSOR; - if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); - yych = *YYCURSOR; - if (yych <= ';') { - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy69; - if (yych <= ':') goto yy18; - } else { - if (yych <= 'E') { - if (yych <= 'D') goto yy18; - goto yy73; - } else { - if (yych == 'e') goto yy73; - goto yy18; - } - } -yy71: - ++YYCURSOR; -#line 702 "ext/standard/var_unserializer.re" - { -#if SIZEOF_ZEND_LONG == 4 -use_double: -#endif - *p = YYCURSOR; - ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); - return 1; -} -#line 1046 "ext/standard/var_unserializer.c" -yy73: - yych = *++YYCURSOR; - if (yych <= ',') { - if (yych == '+') goto yy88; - goto yy18; - } else { - if (yych <= '-') goto yy88; - if (yych <= '/') goto yy18; - if (yych <= '9') goto yy89; - goto yy18; - } -yy74: - yych = *++YYCURSOR; - if (yych == 'F') goto yy91; - goto yy18; -yy75: - yych = *++YYCURSOR; - if (yych == 'N') goto yy91; - goto yy18; -yy76: - ++YYCURSOR; -#line 660 "ext/standard/var_unserializer.re" - { -#if SIZEOF_ZEND_LONG == 4 - int digits = YYCURSOR - start - 3; - - if (start[2] == '-' || start[2] == '+') { - digits--; - } - - /* Use double for large zend_long values that were serialized on a 64-bit system */ - if (digits >= MAX_LENGTH_OF_LONG - 1) { - if (digits == MAX_LENGTH_OF_LONG - 1) { - int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); - - if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { - goto use_double; - } - } else { - goto use_double; - } - } -#endif - *p = YYCURSOR; - ZVAL_LONG(rval, parse_iv(start + 2)); - return 1; -} -#line 1094 "ext/standard/var_unserializer.c" -yy78: - yych = *++YYCURSOR; - if (yych == '"') goto yy92; - goto yy18; -yy79: - ++YYCURSOR; -#line 623 "ext/standard/var_unserializer.re" - { - zend_long id; - - *p = YYCURSOR; - if (!var_hash) return 0; - - id = parse_iv(start + 2) - 1; - if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { - return 0; - } - - if (rval_ref == rval) { - return 0; - } - - if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { - ZVAL_UNDEF(rval); - return 1; - } - - ZVAL_COPY(rval, rval_ref); - - return 1; -} -#line 1126 "ext/standard/var_unserializer.c" -yy81: - yych = *++YYCURSOR; - if (yych == '"') goto yy94; - goto yy18; -yy82: - ++YYCURSOR; -#line 808 "ext/standard/var_unserializer.re" +#line 809 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; @@ -1274,10 +876,105 @@ yy82: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 1278 "ext/standard/var_unserializer.c" -yy84: +#line 880 "ext/standard/var_unserializer.c" +yy25: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy18; + } else { + if (yych <= '-') goto yy26; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy27; + goto yy18; + } +yy26: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy27: ++YYCURSOR; -#line 743 "ext/standard/var_unserializer.re" + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy27; + if (yych >= ';') goto yy18; + yych = *++YYCURSOR; + if (yych != '"') goto yy18; + ++YYCURSOR; +#line 802 "ext/standard/var_unserializer.re" + { + if (!var_hash) return 0; + + return object_common2(UNSERIALIZE_PASSTHRU, + object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); +} +#line 912 "ext/standard/var_unserializer.c" +yy32: + yych = *++YYCURSOR; + if (yych == '+') goto yy33; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy34; + goto yy18; +yy33: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy34: + ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy34; + if (yych >= ';') goto yy18; + yych = *++YYCURSOR; + if (yych != '{') goto yy18; + ++YYCURSOR; +#line 778 "ext/standard/var_unserializer.re" + { + zend_long elements = parse_iv(start + 2); + /* use iv() not uiv() in order to check data range */ + *p = YYCURSOR; + if (!var_hash) return 0; + + if (elements < 0) { + return 0; + } + + array_init_size(rval, elements); + if (elements) { + /* we can't convert from packed to hash during unserialization, because + reference to some zvals might be keept in var_hash (to support references) */ + zend_hash_real_init(Z_ARRVAL_P(rval), 0); + } + + if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) { + return 0; + } + + return finish_nested_data(UNSERIALIZE_PASSTHRU); +} +#line 957 "ext/standard/var_unserializer.c" +yy39: + yych = *++YYCURSOR; + if (yych == '+') goto yy40; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy41; + goto yy18; +yy40: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy41: + ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy41; + if (yych >= ';') goto yy18; + yych = *++YYCURSOR; + if (yych != '"') goto yy18; + ++YYCURSOR; +#line 744 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; @@ -1311,127 +1008,407 @@ yy84: ZVAL_STR(rval, str); return 1; } -#line 1315 "ext/standard/var_unserializer.c" -yy86: +#line 1012 "ext/standard/var_unserializer.c" +yy46: + yych = *++YYCURSOR; + if (yych == '+') goto yy47; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy48; + goto yy18; +yy47: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy48: ++YYCURSOR; -#line 777 "ext/standard/var_unserializer.re" + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy48; + if (yych >= ';') goto yy18; + yych = *++YYCURSOR; + if (yych != '"') goto yy18; + ++YYCURSOR; +#line 712 "ext/standard/var_unserializer.re" { - zend_long elements = parse_iv(start + 2); - /* use iv() not uiv() in order to check data range */ - *p = YYCURSOR; - if (!var_hash) return 0; + size_t len, maxlen; + char *str; - if (elements < 0) { + len = parse_uiv(start + 2); + maxlen = max - YYCURSOR; + if (maxlen < len) { + *p = start + 2; return 0; } - array_init_size(rval, elements); - if (elements) { - /* we can't convert from packed to hash during unserialization, because - reference to some zvals might be keept in var_hash (to support references) */ - zend_hash_real_init(Z_ARRVAL_P(rval), 0); + str = (char*)YYCURSOR; + + YYCURSOR += len; + + if (*(YYCURSOR) != '"') { + *p = YYCURSOR; + return 0; } - if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) { + if (*(YYCURSOR + 1) != ';') { + *p = YYCURSOR + 1; return 0; } - return finish_nested_data(UNSERIALIZE_PASSTHRU); + YYCURSOR += 2; + *p = YYCURSOR; + + ZVAL_STRINGL(rval, str, len); + return 1; } -#line 1342 "ext/standard/var_unserializer.c" -yy88: +#line 1065 "ext/standard/var_unserializer.c" +yy53: + yych = *++YYCURSOR; + if (yych <= '/') { + if (yych <= ',') { + if (yych == '+') goto yy57; + goto yy18; + } else { + if (yych <= '-') goto yy55; + if (yych <= '.') goto yy60; + goto yy18; + } + } else { + if (yych <= 'I') { + if (yych <= '9') goto yy58; + if (yych <= 'H') goto yy18; + goto yy56; + } else { + if (yych != 'N') goto yy18; + } + } + yych = *++YYCURSOR; + if (yych == 'A') goto yy76; + goto yy18; +yy55: + yych = *++YYCURSOR; + if (yych <= '/') { + if (yych == '.') goto yy60; + goto yy18; + } else { + if (yych <= '9') goto yy58; + if (yych != 'I') goto yy18; + } +yy56: + yych = *++YYCURSOR; + if (yych == 'N') goto yy72; + goto yy18; +yy57: + yych = *++YYCURSOR; + if (yych == '.') goto yy60; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy58: + ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + if (yych <= ':') { + if (yych <= '.') { + if (yych <= '-') goto yy18; + goto yy70; + } else { + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy58; + goto yy18; + } + } else { + if (yych <= 'E') { + if (yych <= ';') goto yy63; + if (yych <= 'D') goto yy18; + goto yy65; + } else { + if (yych == 'e') goto yy65; + goto yy18; + } + } +yy60: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy61: + ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + if (yych <= ';') { + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy61; + if (yych <= ':') goto yy18; + } else { + if (yych <= 'E') { + if (yych <= 'D') goto yy18; + goto yy65; + } else { + if (yych == 'e') goto yy65; + goto yy18; + } + } +yy63: + ++YYCURSOR; +#line 703 "ext/standard/var_unserializer.re" + { +#if SIZEOF_ZEND_LONG == 4 +use_double: +#endif + *p = YYCURSOR; + ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); + return 1; +} +#line 1162 "ext/standard/var_unserializer.c" +yy65: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy18; + } else { + if (yych <= '-') goto yy66; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy67; + goto yy18; + } +yy66: yych = *++YYCURSOR; if (yych <= ',') { - if (yych == '+') goto yy96; + if (yych == '+') goto yy69; goto yy18; } else { - if (yych <= '-') goto yy96; + if (yych <= '-') goto yy69; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; } -yy89: +yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; - if (yych <= '9') goto yy89; - if (yych == ';') goto yy71; + if (yych <= '9') goto yy67; + if (yych == ';') goto yy63; goto yy18; -yy91: +yy69: yych = *++YYCURSOR; - if (yych == ';') goto yy97; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy67; goto yy18; -yy92: +yy70: ++YYCURSOR; -#line 801 "ext/standard/var_unserializer.re" + if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; + if (yych <= ';') { + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy70; + if (yych <= ':') goto yy18; + goto yy63; + } else { + if (yych <= 'E') { + if (yych <= 'D') goto yy18; + goto yy65; + } else { + if (yych == 'e') goto yy65; + goto yy18; + } + } +yy72: + yych = *++YYCURSOR; + if (yych != 'F') goto yy18; +yy73: + yych = *++YYCURSOR; + if (yych != ';') goto yy18; + ++YYCURSOR; +#line 687 "ext/standard/var_unserializer.re" { - if (!var_hash) return 0; + *p = YYCURSOR; - return object_common2(UNSERIALIZE_PASSTHRU, - object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); + if (!strncmp((char*)start + 2, "NAN", 3)) { + ZVAL_DOUBLE(rval, ZEND_NAN); + } else if (!strncmp((char*)start + 2, "INF", 3)) { + ZVAL_DOUBLE(rval, ZEND_INFINITY); + } else if (!strncmp((char*)start + 2, "-INF", 4)) { + ZVAL_DOUBLE(rval, -ZEND_INFINITY); + } else { + ZVAL_NULL(rval); + } + + return 1; } -#line 1374 "ext/standard/var_unserializer.c" -yy94: +#line 1237 "ext/standard/var_unserializer.c" +yy76: + yych = *++YYCURSOR; + if (yych == 'N') goto yy73; + goto yy18; +yy77: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy18; + } else { + if (yych <= '-') goto yy78; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy79; + goto yy18; + } +yy78: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy79: ++YYCURSOR; -#line 711 "ext/standard/var_unserializer.re" + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy79; + if (yych != ';') goto yy18; + ++YYCURSOR; +#line 661 "ext/standard/var_unserializer.re" { - size_t len, maxlen; - char *str; +#if SIZEOF_ZEND_LONG == 4 + int digits = YYCURSOR - start - 3; - len = parse_uiv(start + 2); - maxlen = max - YYCURSOR; - if (maxlen < len) { - *p = start + 2; - return 0; + if (start[2] == '-' || start[2] == '+') { + digits--; } - str = (char*)YYCURSOR; + /* Use double for large zend_long values that were serialized on a 64-bit system */ + if (digits >= MAX_LENGTH_OF_LONG - 1) { + if (digits == MAX_LENGTH_OF_LONG - 1) { + int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); - YYCURSOR += len; + if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { + goto use_double; + } + } else { + goto use_double; + } + } +#endif + *p = YYCURSOR; + ZVAL_LONG(rval, parse_iv(start + 2)); + return 1; +} +#line 1290 "ext/standard/var_unserializer.c" +yy83: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= '2') goto yy18; + yych = *++YYCURSOR; + if (yych != ';') goto yy18; + ++YYCURSOR; +#line 655 "ext/standard/var_unserializer.re" + { + *p = YYCURSOR; + ZVAL_BOOL(rval, parse_iv(start + 2)); + return 1; +} +#line 1304 "ext/standard/var_unserializer.c" +yy87: + ++YYCURSOR; +#line 649 "ext/standard/var_unserializer.re" + { + *p = YYCURSOR; + ZVAL_NULL(rval); + return 1; +} +#line 1313 "ext/standard/var_unserializer.c" +yy89: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy18; + } else { + if (yych <= '-') goto yy90; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy91; + goto yy18; + } +yy90: + yych = *++YYCURSOR; + if (yych <= '/') goto yy18; + if (yych >= ':') goto yy18; +yy91: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy91; + if (yych != ';') goto yy18; + ++YYCURSOR; +#line 624 "ext/standard/var_unserializer.re" + { + zend_long id; - if (*(YYCURSOR) != '"') { - *p = YYCURSOR; + *p = YYCURSOR; + if (!var_hash) return 0; + + id = parse_iv(start + 2) - 1; + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { return 0; } - if (*(YYCURSOR + 1) != ';') { - *p = YYCURSOR + 1; + if (rval_ref == rval) { return 0; } - YYCURSOR += 2; - *p = YYCURSOR; + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { + ZVAL_UNDEF(rval); + return 1; + } + + ZVAL_COPY(rval, rval_ref); - ZVAL_STRINGL(rval, str, len); return 1; } -#line 1409 "ext/standard/var_unserializer.c" +#line 1361 "ext/standard/var_unserializer.c" +yy95: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy18; + } else { + if (yych <= '-') goto yy96; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy97; + goto yy18; + } yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; - if (yych <= '9') goto yy89; - goto yy18; + if (yych >= ':') goto yy18; yy97: ++YYCURSOR; -#line 686 "ext/standard/var_unserializer.re" + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy18; + if (yych <= '9') goto yy97; + if (yych != ';') goto yy18; + ++YYCURSOR; +#line 598 "ext/standard/var_unserializer.re" { - *p = YYCURSOR; + zend_long id; - if (!strncmp((char*)start + 2, "NAN", 3)) { - ZVAL_DOUBLE(rval, php_get_nan()); - } else if (!strncmp((char*)start + 2, "INF", 3)) { - ZVAL_DOUBLE(rval, php_get_inf()); - } else if (!strncmp((char*)start + 2, "-INF", 4)) { - ZVAL_DOUBLE(rval, -php_get_inf()); + *p = YYCURSOR; + if (!var_hash) return 0; + + id = parse_iv(start + 2) - 1; + if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) { + return 0; + } + + zval_ptr_dtor(rval); + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { + ZVAL_UNDEF(rval); + return 1; + } + if (Z_ISREF_P(rval_ref)) { + ZVAL_COPY(rval, rval_ref); } else { - ZVAL_NULL(rval); + ZVAL_NEW_REF(rval_ref, rval_ref); + ZVAL_COPY(rval, rval_ref); } return 1; } -#line 1433 "ext/standard/var_unserializer.c" +#line 1410 "ext/standard/var_unserializer.c" } -#line 961 "ext/standard/var_unserializer.re" +#line 962 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 6d53cb6249..4b6266cb1c 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -21,6 +21,7 @@ #include "php.h" #include "ext/standard/php_var.h" #include "php_incomplete_class.h" +#include "zend_portability.h" struct php_unserialize_data { void *first; @@ -687,11 +688,11 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER) *p = YYCURSOR; if (!strncmp((char*)start + 2, "NAN", 3)) { - ZVAL_DOUBLE(rval, php_get_nan()); + ZVAL_DOUBLE(rval, ZEND_NAN); } else if (!strncmp((char*)start + 2, "INF", 3)) { - ZVAL_DOUBLE(rval, php_get_inf()); + ZVAL_DOUBLE(rval, ZEND_INFINITY); } else if (!strncmp((char*)start + 2, "-INF", 4)) { - ZVAL_DOUBLE(rval, -php_get_inf()); + ZVAL_DOUBLE(rval, -ZEND_INFINITY); } else { ZVAL_NULL(rval); } diff --git a/ext/xml/xml.c b/ext/xml/xml.c index f0da47dc5b..f8d72523a0 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -212,14 +212,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_parser_get_option, 0, 0, 2) ZEND_ARG_INFO(0, option) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_encode, 0, 0, 1) - ZEND_ARG_INFO(0, data) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_utf8_decode, 0, 0, 1) - ZEND_ARG_INFO(0, data) -ZEND_END_ARG_INFO() - const zend_function_entry xml_functions[] = { PHP_FE(xml_parser_create, arginfo_xml_parser_create) PHP_FE(xml_parser_create_ns, arginfo_xml_parser_create_ns) @@ -243,8 +235,6 @@ const zend_function_entry xml_functions[] = { PHP_FE(xml_parser_free, arginfo_xml_parser_free) PHP_FE(xml_parser_set_option, arginfo_xml_parser_set_option) PHP_FE(xml_parser_get_option, arginfo_xml_parser_get_option) - PHP_FE(utf8_encode, arginfo_utf8_encode) - PHP_FE(utf8_decode, arginfo_utf8_decode) PHP_FE_END }; @@ -1667,46 +1657,6 @@ PHP_FUNCTION(xml_parser_get_option) } /* }}} */ -/* {{{ proto string utf8_encode(string data) - Encodes an ISO-8859-1 string to UTF-8 */ -PHP_FUNCTION(utf8_encode) -{ - char *arg; - size_t arg_len; - zend_string *encoded; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { - return; - } - - encoded = xml_utf8_encode(arg, arg_len, (XML_Char*)"ISO-8859-1"); - if (encoded == NULL) { - RETURN_FALSE; - } - RETURN_STR(encoded); -} -/* }}} */ - -/* {{{ proto string utf8_decode(string data) - Converts a UTF-8 encoded string to ISO-8859-1 */ -PHP_FUNCTION(utf8_decode) -{ - char *arg; - size_t arg_len; - zend_string *decoded; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { - return; - } - - decoded = xml_utf8_decode((XML_Char*)arg, arg_len, (XML_Char*)"ISO-8859-1"); - if (decoded == NULL) { - RETURN_FALSE; - } - RETURN_STR(decoded); -} -/* }}} */ - #endif /* diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index fa6cc32b51..a6d06d3e22 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -15,6 +15,7 @@ static const char rcsid[] = "#(@) $Id$"; /* ENCODE -- Encode binary file into base64. */ #include <stdlib.h> #include <ctype.h> +#include <php.h> #include "base64.h" @@ -23,7 +24,7 @@ static unsigned char dtable[512]; void buffer_new(struct buffer_st *b) { b->length = 512; - b->data = malloc(sizeof(char)*(b->length)); + b->data = emalloc(sizeof(char)*(b->length)); b->data[0] = 0; b->ptr = b->data; b->offset = 0; @@ -35,14 +36,14 @@ void buffer_add(struct buffer_st *b, char c) b->offset++; if (b->offset == b->length) { b->length += 512; - b->data = realloc(b->data, b->length); + b->data = erealloc(b->data, b->length); b->ptr = b->data + b->offset; } } void buffer_delete(struct buffer_st *b) { - free(b->data); + efree(b->data); b->length = 0; b->offset = 0; b->ptr = NULL; diff --git a/ext/xmlrpc/libxmlrpc/encodings.c b/ext/xmlrpc/libxmlrpc/encodings.c index 081e38e5de..5777152ea8 100644 --- a/ext/xmlrpc/libxmlrpc/encodings.c +++ b/ext/xmlrpc/libxmlrpc/encodings.c @@ -30,16 +30,7 @@ */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef PHP_WIN32 -#include <php_config.h> -#else -#include <config.w32.h> -#include <stdlib.h> -#endif +#include <php.h> static const char rcsid[] = "#(@) $Id$"; @@ -74,7 +65,7 @@ static char* convert(const char* src, int src_len, int *new_len, const char* fro ic = iconv_open(to_enc, from_enc); if(ic != (iconv_t)-1) { size_t st; - outbuf = (char*)malloc(outlen + 1); + outbuf = (char*)emalloc(outlen + 1); if(outbuf) { out_ptr = (char*)outbuf; @@ -85,14 +76,14 @@ static char* convert(const char* src, int src_len, int *new_len, const char* fro int diff = out_ptr - outbuf; outlen += inlenleft; outlenleft += inlenleft; - outbuf = (char*)realloc(outbuf, outlen + 1); + outbuf = (char*)erealloc(outbuf, outlen + 1); if(!outbuf) { break; } out_ptr = outbuf + diff; } else { - free(outbuf); + efree(outbuf); outbuf = 0; break; } diff --git a/ext/xmlrpc/libxmlrpc/queue.c b/ext/xmlrpc/libxmlrpc/queue.c index 6a0ba1df47..961b4ca873 100644 --- a/ext/xmlrpc/libxmlrpc/queue.c +++ b/ext/xmlrpc/libxmlrpc/queue.c @@ -97,13 +97,10 @@ static const char rcsid[] = "#(@) $Id$"; * ****************************************************************/ -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <stdlib.h> +#include <php.h> #include "queue.h" - static void QuickSort(void *list[], int low, int high, int (*Comp)(const void *, const void *)); static int Q_BSearch(queue *q, void *key, @@ -111,8 +108,8 @@ static int Q_BSearch(queue *q, void *key, /* The index: a pointer to pointers */ -static void **index; -static datanode **posn_index; +static void **queue_index; +static datanode **queue_posn_index; /*** @@ -289,7 +286,7 @@ int Q_PushHead(queue *q, void *d) node *n; datanode *p; - p = malloc(sizeof(datanode)); + p = emalloc(sizeof(datanode)); if(p == NULL) return False_; @@ -341,7 +338,7 @@ int Q_PushTail(queue *q, void *d) node *p; datanode *n; - n = malloc(sizeof(datanode)); + n = emalloc(sizeof(datanode)); if(n == NULL) return False_; @@ -397,7 +394,7 @@ void *Q_PopHead(queue *q) d = q->head->data; n = q->head->next; - free(q->head); + efree(q->head); q->size--; @@ -440,7 +437,7 @@ void *Q_PopTail(queue *q) d = q->tail->data; p = q->tail->prev; - free(q->tail); + efree(q->tail); q->size--; if(q->size == 0) @@ -539,7 +536,7 @@ void *Q_Iter_Del(queue *q, q_iter iter) p = ((node*)iter)->prev; d = ((node*)iter)->data; - free(iter); + efree(iter); if(p) { p->next = n; @@ -783,20 +780,20 @@ int Q_Sort(queue *q, int (*Comp)(const void *, const void *)) /* if already sorted free memory for tag array */ if(q->sorted) { - free(index); - free(posn_index); + efree(queue_index); + efree(queue_posn_index); q->sorted = False_; } /* Now allocate memory of array, array of pointers */ - index = malloc(q->size * sizeof(q->cursor->data)); - if(index == NULL) + queue_index = emalloc(q->size * sizeof(q->cursor->data)); + if(queue_index == NULL) return False_; - posn_index = malloc(q->size * sizeof(q->cursor)); - if(posn_index == NULL) { - free(index); + queue_posn_index = emalloc(q->size * sizeof(q->cursor)); + if(queue_posn_index == NULL) { + efree(queue_index); return False_; } @@ -804,21 +801,21 @@ int Q_Sort(queue *q, int (*Comp)(const void *, const void *)) d = Q_Head(q); for(i=0; i < q->size; i++) { - index[i] = d; - posn_index[i] = q->cursor; + queue_index[i] = d; + queue_posn_index[i] = q->cursor; d = Q_Next(q); } /* Now sort the index */ - QuickSort(index, 0, q->size - 1, Comp); + QuickSort(queue_index, 0, q->size - 1, Comp); /* Rearrange the actual queue into correct order */ dn = q->head; i = 0; while(dn != NULL) { - dn->data = index[i++]; + dn->data = queue_index[i++]; dn = dn->next; } @@ -860,7 +857,7 @@ static int Q_BSearch( queue *q, void *key, while(low <= hi) { mid = (low + hi) / 2; - val = Comp(key, index[ mid ]); + val = Comp(key, queue_index[ mid ]); if(val < 0) hi = mid - 1; @@ -912,9 +909,9 @@ void *Q_Seek(queue *q, void *data, int (*Comp)(const void *, const void *)) if(idx < 0) return NULL; - q->cursor = posn_index[idx]; + q->cursor = queue_posn_index[idx]; - return index[idx]; + return queue_index[idx]; } diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index c88754fb9a..98901845c1 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -30,6 +30,7 @@ */ +#include <php.h> static const char rcsid[] = "#(@) $Id$"; @@ -82,7 +83,7 @@ static const char rcsid[] = "#(@) $Id$"; #include <string.h> #include "simplestring.h" -#define my_free(thing) if(thing) {free(thing); thing = 0;} +#define my_free(thing) if(thing) {efree(thing); thing = 0;} /*----------------------** * Begin String Functions * @@ -111,7 +112,7 @@ void simplestring_init(simplestring* string) { /******/ static void simplestring_init_str(simplestring* string) { - string->str = (char*)malloc(SIMPLESTRING_INCR); + string->str = (char*)emalloc(SIMPLESTRING_INCR); if(string->str) { string->str[0] = 0; string->len = 0; @@ -218,7 +219,7 @@ void simplestring_addn(simplestring* target, const char* source, size_t add_len) /* some kind of overflow happened */ return; } - target->str = (char*)realloc(target->str, newsize); + target->str = (char*)erealloc(target->str, newsize); target->size = target->str ? newsize : 0; } diff --git a/ext/xmlrpc/libxmlrpc/xml_element.c b/ext/xmlrpc/libxmlrpc/xml_element.c index 6fc6bd3977..070680d4a7 100644 --- a/ext/xmlrpc/libxmlrpc/xml_element.c +++ b/ext/xmlrpc/libxmlrpc/xml_element.c @@ -119,9 +119,6 @@ static const char rcsid[] = "#(@) $Id$"; ******/ #include "ext/xml/expat_compat.h" -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -130,7 +127,7 @@ static const char rcsid[] = "#(@) $Id$"; #include "queue.h" #include "encodings.h" -#define my_free(thing) if(thing) {free(thing); thing = NULL;} +#define my_free(thing) if(thing) {efree(thing); thing = NULL;} #define XML_DECL_START "<?xml" #define XML_DECL_START_LEN sizeof(XML_DECL_START) - 1 @@ -207,7 +204,7 @@ void xml_elem_free_non_recurse(xml_element* root) { Q_Destroy(&root->children); Q_Destroy(&root->attrs); if(root->name) { - free((char *)root->name); + efree((char *)root->name); root->name = NULL; } simplestring_free(&root->text); @@ -263,7 +260,7 @@ void xml_elem_free(xml_element* root) { * SOURCE */ xml_element* xml_elem_new() { - xml_element* elem = calloc(1, sizeof(xml_element)); + xml_element* elem = ecalloc(1, sizeof(xml_element)); if(elem) { Q_Init(&elem->children); Q_Init(&elem->attrs); @@ -347,7 +344,7 @@ static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, X if(ToBeXmlEscaped) { - NewBuffer= malloc(iLength+1); + NewBuffer= emalloc(iLength+1); if(NewBuffer) { bufcopy=buf; while(*bufcopy) { @@ -602,15 +599,15 @@ static void _xmlrpc_startElement(void *userData, const char *name, const char ** c = mydata->current; mydata->current = xml_elem_new(); - mydata->current->name = (char*)strdup(name); + mydata->current->name = (char*)estrdup(name); mydata->current->parent = c; /* init attrs */ while(p && *p) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); + xml_element_attr* attr = emalloc(sizeof(xml_element_attr)); if(attr) { - attr->key = strdup(*p); - attr->val = strdup(*(p+1)); + attr->key = estrdup(*p); + attr->val = estrdup(*(p+1)); Q_PushTail(&mydata->current->attrs, attr); p += 2; @@ -646,7 +643,7 @@ static void _xmlrpc_charHandler(void *userData, if(add_text) { len = new_len; simplestring_addn(&mydata->current->text, add_text, len); - free(add_text); + efree(add_text); return; } } diff --git a/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c b/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c index 000df192fd..63cc52d6b7 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_dandarpc.c @@ -30,9 +30,6 @@ */ -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <string.h> #include <stdlib.h> #include "xml_to_dandarpc.h" @@ -180,21 +177,21 @@ xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xml_element* elem_val = xml_elem_new(); const char* pAttrType = NULL; - xml_element_attr* attr_type = bNoAddType ? NULL : malloc(sizeof(xml_element_attr)); + xml_element_attr* attr_type = bNoAddType ? NULL : emalloc(sizeof(xml_element_attr)); if(attr_type) { - attr_type->key = strdup(ATTR_TYPE); + attr_type->key = estrdup(ATTR_TYPE); attr_type->val = 0; Q_PushTail(&elem_val->attrs, attr_type); } - elem_val->name = (type == xmlrpc_vector) ? strdup(ATTR_VECTOR) : strdup(ATTR_SCALAR); + elem_val->name = (type == xmlrpc_vector) ? estrdup(ATTR_VECTOR) : estrdup(ATTR_SCALAR); if(id && *id) { - xml_element_attr* attr_id = malloc(sizeof(xml_element_attr)); + xml_element_attr* attr_id = emalloc(sizeof(xml_element_attr)); if(attr_id) { - attr_id->key = strdup(ATTR_ID); - attr_id->val = strdup(id); + attr_id->key = estrdup(ATTR_ID); + attr_id->val = estrdup(id); Q_PushTail(&elem_val->attrs, attr_id); } } @@ -265,7 +262,7 @@ xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE break; } if(pAttrType && attr_type && !bNoAddType) { - attr_type->val = strdup(pAttrType); + attr_type->val = estrdup(pAttrType); } root = elem_val; } @@ -282,9 +279,9 @@ xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { if(request) { XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); const char* pStr = NULL; - xml_element_attr* version = malloc(sizeof(xml_element_attr)); - version->key = strdup(ATTR_VERSION); - version->val = strdup(VAL_VERSION_0_9); + xml_element_attr* version = emalloc(sizeof(xml_element_attr)); + version->key = estrdup(ATTR_VERSION); + version->val = estrdup(VAL_VERSION_0_9); wrapper = xml_elem_new(); @@ -295,11 +292,11 @@ xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { pStr = ELEM_METHODCALL; } if(pStr) { - wrapper->name = strdup(pStr); + wrapper->name = estrdup(pStr); } root = xml_elem_new(); - root->name = strdup(ELEM_ROOT); + root->name = estrdup(ELEM_ROOT); Q_PushTail(&root->attrs, version); Q_PushTail(&root->children, wrapper); @@ -307,7 +304,7 @@ xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { if(pStr) { xml_element* method = xml_elem_new(); - method->name = strdup(ELEM_METHODNAME); + method->name = estrdup(ELEM_METHODNAME); simplestring_add(&method->text, pStr); Q_PushTail(&wrapper->children, method); } diff --git a/ext/xmlrpc/libxmlrpc/xml_to_soap.c b/ext/xmlrpc/libxmlrpc/xml_to_soap.c index e0604bae62..64a9a6eaa5 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_soap.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_soap.c @@ -23,9 +23,6 @@ static const char rcsid[] = "#(@) $Id:"; -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <string.h> #include <stdlib.h> #include "xml_to_soap.h" @@ -66,10 +63,10 @@ static inline int is_soap_type(const char* soap_type) { /* utility func to generate a new attribute. possibly should be in xml_element.c?? */ static xml_element_attr* new_attr(const char* key, const char* val) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); + xml_element_attr* attr = emalloc(sizeof(xml_element_attr)); if (attr) { - attr->key = key ? strdup(key) : NULL; - attr->val = val ? strdup(val) : NULL; + attr->key = key ? estrdup(key) : NULL; + attr->val = val ? estrdup(val) : NULL; } return attr; } @@ -87,7 +84,7 @@ struct array_info { static struct array_info* parse_array_type_info(const char* array_type) { struct array_info* ai = NULL; if (array_type) { - ai = (struct array_info*)calloc(1, sizeof(struct array_info)); + ai = (struct array_info*)ecalloc(1, sizeof(struct array_info)); if (ai) { char buf[128], *p; snprintf(buf, sizeof(buf), "%s", array_type); @@ -407,7 +404,7 @@ XMLRPC_VALUE xml_element_to_SOAP_REQUEST_worker(XMLRPC_REQUEST request, } /* cleanup */ if (ai) { - free(ai); + efree(ai); } } } @@ -563,7 +560,7 @@ xml_element* SOAP_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE nod } } } - elem_val->name = strdup(pName); + elem_val->name = estrdup(pName); /* cleanup */ if (bFreeNode) { @@ -585,7 +582,7 @@ xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) { /* safety first. */ if (root) { xml_element* body = xml_elem_new(); - root->name = strdup("SOAP-ENV:Envelope"); + root->name = estrdup("SOAP-ENV:Envelope"); /* silly namespace stuff */ Q_PushTail(&root->attrs, new_attr("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/")); @@ -620,7 +617,7 @@ xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) { /* if we are making a request, we want to use the methodname as is. */ if (rtype == xmlrpc_request_call) { if (methodname) { - rpc->name = strdup(methodname); + rpc->name = estrdup(methodname); } } /* if it's a response, we append "Response". Also, given xmlrpc-epi @@ -632,7 +629,7 @@ xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) { methodname ? methodname : "", "Response"); - rpc->name = strdup(buf); + rpc->name = estrdup(buf); } /* add serialized data to method call/response. @@ -660,7 +657,7 @@ xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) { } } } - body->name = strdup("SOAP-ENV:Body"); + body->name = estrdup("SOAP-ENV:Body"); Q_PushTail(&root->children, body); } } diff --git a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c index c557ee06d8..309f0dce3d 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c @@ -35,9 +35,6 @@ static const char rcsid[] = "#(@) $Id$"; #include "php.h" #include "main/snprintf.h" -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <string.h> #include <stdlib.h> #include "xml_to_xmlrpc.h" @@ -207,40 +204,40 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA if (next_el) { Q_PushTail(&elem_val->children, next_el); } - elem_val->name = strdup(bIsFault ? ELEM_FAULT : ELEM_PARAMS); + elem_val->name = estrdup(bIsFault ? ELEM_FAULT : ELEM_PARAMS); } else { switch (type) { case xmlrpc_empty: /* treat null value as empty string in xmlrpc. */ case xmlrpc_string: - elem_val->name = strdup(ELEM_STRING); + elem_val->name = estrdup(ELEM_STRING); simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); break; case xmlrpc_int: - elem_val->name = strdup(ELEM_INT); + elem_val->name = estrdup(ELEM_INT); snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_boolean: - elem_val->name = strdup(ELEM_BOOLEAN); + elem_val->name = estrdup(ELEM_BOOLEAN); snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); simplestring_add(&elem_val->text, buf); break; case xmlrpc_double: { - elem_val->name = strdup(ELEM_DOUBLE); + elem_val->name = estrdup(ELEM_DOUBLE); ap_php_snprintf(buf, BUF_SIZE, "%.*G", (int) EG(precision), XMLRPC_GetValueDouble(node)); simplestring_add(&elem_val->text, buf); } break; case xmlrpc_datetime: - elem_val->name = strdup(ELEM_DATETIME); + elem_val->name = estrdup(ELEM_DATETIME); simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); break; case xmlrpc_base64: { struct buffer_st buf; - elem_val->name = strdup(ELEM_BASE64); + elem_val->name = estrdup(ELEM_BASE64); base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); simplestring_addn(&elem_val->text, buf.data, buf.offset ); buffer_delete(&buf); @@ -256,7 +253,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA case xmlrpc_vector_array: { if(depth == 0) { - elem_val->name = strdup(ELEM_PARAMS); + elem_val->name = estrdup(ELEM_PARAMS); } else { /* Hi my name is Dave and I like to make things as confusing @@ -268,9 +265,9 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA * GRRRRRRRRR! */ xml_element* data = xml_elem_new(); - data->name = strdup(ELEM_DATA); + data->name = estrdup(ELEM_DATA); - elem_val->name = strdup(ELEM_ARRAY); + elem_val->name = estrdup(ELEM_ARRAY); Q_PushTail(&elem_val->children, data); root_vector_elem = data; } @@ -278,7 +275,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA break; case xmlrpc_vector_mixed: /* not officially supported */ case xmlrpc_vector_struct: - elem_val->name = strdup(ELEM_STRUCT); + elem_val->name = estrdup(ELEM_STRUCT); break; default: break; @@ -304,7 +301,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA if (depth == 1) { xml_element* value = xml_elem_new(); - value->name = strdup(ELEM_VALUE); + value->name = estrdup(ELEM_VALUE); /* yet another hack for the "fault" crap */ if (XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)) { @@ -312,7 +309,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA } else { xml_element* param = xml_elem_new(); - param->name = strdup(ELEM_PARAM); + param->name = estrdup(ELEM_PARAM); Q_PushTail(¶m->children, value); @@ -325,9 +322,9 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA xml_element* name = xml_elem_new(); xml_element* value = xml_elem_new(); - member->name = strdup(ELEM_MEMBER); - name->name = strdup(ELEM_NAME); - value->name = strdup(ELEM_VALUE); + member->name = estrdup(ELEM_MEMBER); + name->name = estrdup(ELEM_NAME); + value->name = estrdup(ELEM_VALUE); simplestring_add(&name->text, XMLRPC_GetValueID(node)); @@ -340,7 +337,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA else if (vtype == xmlrpc_vector_array) { xml_element* value = xml_elem_new(); - value->name = strdup(ELEM_VALUE); + value->name = estrdup(ELEM_VALUE); Q_PushTail(&value->children, elem_val); @@ -353,7 +350,7 @@ xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VA else { xml_element* value = xml_elem_new(); - value->name = strdup(ELEM_VALUE); + value->name = estrdup(ELEM_VALUE); Q_PushTail(&value->children, elem_val); @@ -384,7 +381,7 @@ xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { pStr = ELEM_METHODRESPONSE; } if (pStr) { - wrapper->name = strdup(pStr); + wrapper->name = estrdup(pStr); } if(request_type == xmlrpc_request_call) { @@ -392,7 +389,7 @@ xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { if (pStr) { xml_element* method = xml_elem_new(); - method->name = strdup(ELEM_METHODNAME); + method->name = estrdup(ELEM_METHODNAME); simplestring_add(&method->text, pStr); Q_PushTail(&wrapper->children, method); } @@ -404,7 +401,7 @@ xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { else { /* Despite the spec, the xml-rpc list folk want me to send an empty params element */ xml_element* params = xml_elem_new(); - params->name = strdup(ELEM_PARAMS); + params->name = estrdup(ELEM_PARAMS); Q_PushTail(&wrapper->children, params); } } diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c index 0836f27291..7a7d9c833c 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c @@ -145,9 +145,6 @@ static const char rcsid[] = "#(@) $Id$"; #include "ext/xml/expat_compat.h" #include "main/php_reentrancy.h" -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -308,7 +305,7 @@ static int date_to_ISO8601 (time_t value, char *buf, int length) { * SOURCE */ XMLRPC_REQUEST XMLRPC_RequestNew() { - XMLRPC_REQUEST xRequest = calloc(1, sizeof(STRUCT_XMLRPC_REQUEST)); + XMLRPC_REQUEST xRequest = ecalloc(1, sizeof(STRUCT_XMLRPC_REQUEST)); if(xRequest) { simplestring_init(&xRequest->methodName); } @@ -861,7 +858,7 @@ XMLRPC_REQUEST XMLRPC_REQUEST_FromXML (const char *in_buf, int len, * SOURCE */ XMLRPC_VALUE XMLRPC_CreateValueEmpty() { - XMLRPC_VALUE v = calloc(1, sizeof(STRUCT_XMLRPC_VALUE)); + XMLRPC_VALUE v = ecalloc(1, sizeof(STRUCT_XMLRPC_VALUE)); if(v) { #ifdef XMLRPC_DEBUG_REFCOUNT printf ("calloc'd 0x%x\n", v); @@ -1053,9 +1050,9 @@ int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type) { } } else { - value->v = calloc(1, sizeof(STRUCT_XMLRPC_VECTOR)); + value->v = ecalloc(1, sizeof(STRUCT_XMLRPC_VECTOR)); if(value->v) { - value->v->q = (queue*)malloc(sizeof(queue)); + value->v->q = (queue*)emalloc(sizeof(queue)); if(value->v->q) { Q_Init(value->v->q); value->v->type = type; @@ -2322,7 +2319,7 @@ XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy (XMLRPC_VALUE value) { * SOURCE */ XMLRPC_SERVER XMLRPC_ServerCreate() { - XMLRPC_SERVER server = calloc(1, sizeof(STRUCT_XMLRPC_SERVER)); + XMLRPC_SERVER server = ecalloc(1, sizeof(STRUCT_XMLRPC_SERVER)); if(server) { Q_Init(&server->methodlist); Q_Init(&server->docslist); @@ -2392,9 +2389,7 @@ void XMLRPC_ServerDestroy(XMLRPC_SERVER server) { dm = Q_Next(&server->docslist); } while( sm ) { - if(sm->name) { - my_free(sm->name); - } + my_free(sm->name); if(sm->desc) { XMLRPC_CleanupValue(sm->desc); } @@ -2439,10 +2434,10 @@ void XMLRPC_ServerDestroy(XMLRPC_SERVER server) { int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) { if(server && name && cb) { - server_method* sm = malloc(sizeof(server_method)); + server_method* sm = emalloc(sizeof(server_method)); if(sm) { - sm->name = strdup(name); + sm->name = estrdup(name); sm->method = cb; sm->desc = NULL; diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.h b/ext/xmlrpc/libxmlrpc/xmlrpc.h index 9b0d934129..12b6c7a8ee 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc.h +++ b/ext/xmlrpc/libxmlrpc/xmlrpc.h @@ -36,6 +36,7 @@ /* includes */ #include "xml_element.h" #include <time.h> /* for time_t */ +#include <php.h> #ifdef __cplusplus extern "C" { diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c b/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c index 6da21b974e..c554e73dc4 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c @@ -51,9 +51,6 @@ *******/ -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif #include "queue.h" #include "xmlrpc.h" #include "xmlrpc_private.h" @@ -578,7 +575,7 @@ int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_Intr int bSuccess = 0; if(server && cb) { - doc_method* dm = calloc(1, sizeof(doc_method)); + doc_method* dm = ecalloc(1, sizeof(doc_method)); if(dm) { dm->method = cb; diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc_private.h b/ext/xmlrpc/libxmlrpc/xmlrpc_private.h index fbe7104aac..e43f78ecfb 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc_private.h +++ b/ext/xmlrpc/libxmlrpc/xmlrpc_private.h @@ -166,7 +166,7 @@ const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype); /*---------------------------------------------------------------------------- * Macros */ -#define my_free(thing) if(thing) {free(thing); thing = 0;} +#define my_free(thing) if(thing) {efree(thing); thing = 0;} #ifdef __cplusplus diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc_win32.h b/ext/xmlrpc/libxmlrpc/xmlrpc_win32.h deleted file mode 100644 index 3e45052b0d..0000000000 --- a/ext/xmlrpc/libxmlrpc/xmlrpc_win32.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _XMLRPC_WIN32_H -#define _XMLRPC_WIN32_H -/* just some things needed to compile win32 */ -#include <windows.h> -#include <stdlib.h> -#ifndef inline -# define inline __inline -#endif -#if !defined(snprintf) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif -#ifndef strcasecmp -# define strcasecmp(s1, s2) stricmp(s1, s2) -#endif - -#endif diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 368f8954ea..782a1317ec 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -701,7 +701,7 @@ PHP_FUNCTION(xmlrpc_encode_request) outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0); if (outBuf) { RETVAL_STRING(outBuf); - free(outBuf); + efree(outBuf); } XMLRPC_RequestFree(xRequest, 1); } @@ -735,7 +735,7 @@ PHP_FUNCTION(xmlrpc_encode) if (xOut) { if (outBuf) { RETVAL_STRING(outBuf); - free(outBuf); + efree(outBuf); } /* cleanup */ XMLRPC_CleanupValue(xOut); @@ -1102,7 +1102,7 @@ PHP_FUNCTION(xmlrpc_server_call_method) outBuf = XMLRPC_REQUEST_ToXML(xResponse, &buf_len); if (outBuf) { RETVAL_STRINGL(outBuf, buf_len); - free(outBuf); + efree(outBuf); } /* cleanup after ourselves. what a sty! */ XMLRPC_RequestFree(xResponse, 0); diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index 4018e253ae..e48c5d60f3 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -286,7 +286,7 @@ static php_stream_filter_ops php_zlib_deflate_ops = { /* {{{ zlib.* common factory */ -static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *filterparams, int persistent) +static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_stream_filter_ops *fops = NULL; php_zlib_filter_data *data; diff --git a/main/main.c b/main/main.c index dd69734aea..3f20556518 100644 --- a/main/main.c +++ b/main/main.c @@ -546,7 +546,6 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("register_argc_argv", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, register_argc_argv, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("auto_globals_jit", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, auto_globals_jit, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("short_open_tag", DEFAULT_SHORT_OPEN_TAG, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, short_tags, zend_compiler_globals, compiler_globals) - STD_PHP_INI_BOOLEAN("sql.safe_mode", "0", PHP_INI_SYSTEM, OnUpdateBool, sql_safe_mode, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("track_errors", "0", PHP_INI_ALL, OnUpdateBool, track_errors, php_core_globals, core_globals) STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals) @@ -2137,6 +2136,11 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError()); return FAILURE; } + /* Check that we actually got the requested WSA version */ + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) { + php_printf("\nwinsock.dll unusable. Requested version: %d.%d, got %d.%d", LOBYTE(wVersionRequested), HIBYTE(wVersionRequested), LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); + return FAILURE; + } #endif le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0); @@ -2178,6 +2182,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MIN", ZEND_LONG_MIN, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("PHP_FD_SETSIZE", FD_SETSIZE, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_FLOAT_DIG", DBL_DIG, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_EPSILON", DBL_EPSILON, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MAX", DBL_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_DOUBLE_CONSTANT("PHP_FLOAT_MIN", DBL_MIN, CONST_PERSISTENT | CONST_CS); #ifdef PHP_WIN32 REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MAJOR", EG(windows_version_info).dwMajorVersion, CONST_PERSISTENT | CONST_CS); @@ -2387,11 +2395,6 @@ void php_module_shutdown(void) ts_free_worker_threads(); #endif -#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) - /*close winsock */ - WSACleanup(); -#endif - #ifdef PHP_WIN32 php_win32_free_rng_lock(); #endif @@ -2400,6 +2403,11 @@ void php_module_shutdown(void) zend_shutdown(); +#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) + /*close winsock */ + WSACleanup(); +#endif + /* Destroys filter & transport registries too */ php_shutdown_stream_wrappers(module_number); diff --git a/main/php.h b/main/php.h index 7f38d3026a..32ab59386f 100644 --- a/main/php.h +++ b/main/php.h @@ -26,7 +26,7 @@ #include <dmalloc.h> #endif -#define PHP_API_VERSION 20160303 +#define PHP_API_VERSION 20160731 #define PHP_HAVE_STREAMS #define YYDEBUG 0 #define PHP_DEFAULT_CHARSET "UTF-8" diff --git a/main/php_globals.h b/main/php_globals.h index e50ea2ebfb..91bd100f7e 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -58,7 +58,6 @@ struct _php_core_globals { zend_long output_buffering; - zend_bool sql_safe_mode; zend_bool enable_dl; char *output_handler; diff --git a/main/php_streams.h b/main/php_streams.h index 5da29a2f4f..2f65d6e97b 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -197,22 +197,26 @@ struct _php_stream { void *wrapperthis; /* convenience pointer for a instance of a wrapper */ zval wrapperdata; /* fgetwrapperdata retrieves this */ - int fgetss_state; /* for fgetss to handle multiline tags */ - int is_persistent; - char mode[16]; /* "rwb" etc. ala stdio */ - zend_resource *res; /* used for auto-cleanup */ - int in_free; /* to prevent recursion during free */ + uint8_t is_persistent:1; + uint8_t in_free:2; /* to prevent recursion during free */ + uint8_t eof:1; + uint8_t __exposed:1; /* non-zero if exposed as a zval somewhere */ + /* so we know how to clean it up correctly. This should be set to * PHP_STREAM_FCLOSE_XXX as appropriate */ - int fclose_stdiocast; + uint8_t fclose_stdiocast:2; + + uint8_t fgetss_state; /* for fgetss to handle multiline tags */ + + char mode[16]; /* "rwb" etc. ala stdio */ + + uint32_t flags; /* PHP_STREAM_FLAG_XXX */ + + zend_resource *res; /* used for auto-cleanup */ FILE *stdiocast; /* cache this, otherwise we might leak! */ - int __exposed; /* non-zero if exposed as a zval somewhere */ char *orig_path; zend_resource *ctx; - int flags; /* PHP_STREAM_FLAG_XXX */ - - int eof; /* buffer */ zend_off_t position; /* of underlying stream */ @@ -226,7 +230,7 @@ struct _php_stream { #if ZEND_DEBUG const char *open_filename; - uint open_lineno; + uint32_t open_lineno; #endif struct _php_stream *enclosing_stream; /* this is a private stream owned by enclosing_stream */ @@ -249,11 +253,11 @@ END_EXTERN_C() #define php_stream_get_resource_id(stream) ((php_stream *)(stream))->res->handle /* use this to tell the stream that it is OK if we don't explicitly close it */ -#define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } +#define php_stream_auto_cleanup(stream) { (stream)->__exposed = 1; } /* use this to assign the stream to a zval and tell the stream that is * has been exported to the engine; it will expect to be closed automatically * when the resources are auto-destructed */ -#define php_stream_to_zval(stream, zval) { ZVAL_RES(zval, (stream)->res); (stream)->__exposed++; } +#define php_stream_to_zval(stream, zval) { ZVAL_RES(zval, (stream)->res); (stream)->__exposed = 1; } #define php_stream_from_zval(xstr, pzval) do { \ if (((xstr) = (php_stream*)zend_fetch_resource2_ex((pzval), \ diff --git a/main/php_version.h b/main/php_version.h index 4714e5dc4b..405e54a710 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -1,8 +1,8 @@ /* automatically generated by configure */ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 7 -#define PHP_MINOR_VERSION 1 +#define PHP_MINOR_VERSION 2 #define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "7.1.0-dev" -#define PHP_VERSION_ID 70100 +#define PHP_VERSION "7.2.0-dev" +#define PHP_VERSION_ID 70200 diff --git a/main/streams/filter.c b/main/streams/filter.c index e97dea9f21..71b06aa7c8 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -68,7 +68,7 @@ PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern /* Buckets */ -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent) +PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent) { int is_persistent = php_stream_is_persistent(stream); php_stream_bucket *bucket; @@ -247,7 +247,7 @@ PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket) * match. If that fails, we try "convert.charset.*", then "convert.*" * This means that we don't need to clog up the hashtable with a zillion * charsets (for example) but still be able to provide them all as filters */ -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent) +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash); php_stream_filter_factory *factory = NULL; @@ -290,7 +290,7 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval return filter; } -PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC) +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, uint8_t persistent STREAMS_DC) { php_stream_filter *filter; diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index 27a6da9692..ff96fd88c9 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -48,8 +48,8 @@ struct _php_stream_bucket { char *buf; size_t buflen; /* if non-zero, buf should be pefreed when the bucket is destroyed */ - int own_buf; - int is_persistent; + uint8_t own_buf; + uint8_t is_persistent; /* destroy this struct when refcount falls to zero */ int refcount; @@ -67,7 +67,7 @@ typedef enum { /* Buckets API. */ BEGIN_EXTERN_C() -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent); +PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, uint8_t own_buf, uint8_t buf_persistent); PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length); PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket); #define php_stream_bucket_addref(bucket) (bucket)->refcount++ @@ -131,7 +131,7 @@ PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_strea PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish); PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor); PHPAPI void php_stream_filter_free(php_stream_filter *filter); -PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC); +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, uint8_t persistent STREAMS_DC); END_EXTERN_C() #define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC) #define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC) @@ -142,14 +142,14 @@ END_EXTERN_C() #define php_stream_is_filtered(stream) ((stream)->readfilters.head || (stream)->writefilters.head) typedef struct _php_stream_filter_factory { - php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, int persistent); + php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, uint8_t persistent); } php_stream_filter_factory; BEGIN_EXTERN_C() PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory); PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern); PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory); -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent); +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, uint8_t persistent); END_EXTERN_C() /* diff --git a/php.ini-development b/php.ini-development index 149b0a1688..fff094c919 100644 --- a/php.ini-development +++ b/php.ini-development @@ -870,15 +870,15 @@ default_socket_timeout = 60 ; ; For example, on Windows: ; -; extension=msql.dll +; extension=mysqli.dll ; ; ... or under UNIX: ; -; extension=msql.so +; extension=mysqli.so ; ; ... or with a path: ; -; extension=/path/to/extension/msql.so +; extension=/path/to/extension/mysqli.so ; ; If you only provide the name of the extension, PHP will look for it in its ; default extension directory. @@ -1057,10 +1057,6 @@ mail.add_x_header = On ; Log mail to syslog (Event Log on Windows). ;mail.log = syslog -[SQL] -; http://php.net/sql.safe-mode -sql.safe_mode = Off - [ODBC] ; http://php.net/odbc.default-db ;odbc.default_db = Not yet implemented diff --git a/php.ini-production b/php.ini-production index c90238f35b..1090321e04 100644 --- a/php.ini-production +++ b/php.ini-production @@ -870,15 +870,15 @@ default_socket_timeout = 60 ; ; For example, on Windows: ; -; extension=msql.dll +; extension=mysqli.dll ; ; ... or under UNIX: ; -; extension=msql.so +; extension=mysqli.so ; ; ... or with a path: ; -; extension=/path/to/extension/msql.so +; extension=/path/to/extension/mysqli.so ; ; If you only provide the name of the extension, PHP will look for it in its ; default extension directory. @@ -1057,10 +1057,6 @@ mail.add_x_header = On ; Log mail to syslog (Event Log on Windows). ;mail.log = syslog -[SQL] -; http://php.net/sql.safe-mode -sql.safe_mode = Off - [ODBC] ; http://php.net/odbc.default-db ;odbc.default_db = Not yet implemented diff --git a/run-tests.php b/run-tests.php index 41a061666b..20d148b0b0 100755 --- a/run-tests.php +++ b/run-tests.php @@ -229,7 +229,7 @@ $ini_overwrites = array( $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0'; -function write_information($show_html) +function write_information() { global $cwd, $php, $php_cgi, $phpdbg, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $leak_check, $valgrind_header, $no_file_cache; @@ -269,7 +269,7 @@ More .INIs : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n" @unlink($info_file); // load list of enabled extensions - save_text($info_file, '<?php echo str_replace("Zend OPcache", "opcache", join(",", get_loaded_extensions())); ?>'); + save_text($info_file, '<?php echo str_replace("Zend OPcache", "opcache", implode(",", get_loaded_extensions())); ?>'); $exts_to_test = explode(',',`$php $pass_options $info_params $no_file_cache "$info_file"`); // check for extensions that need special handling and regenerate $info_params_ex = array( @@ -311,7 +311,7 @@ define('TRAVIS_CI' , (bool) getenv('TRAVIS')); function save_or_mail_results() { global $sum_results, $just_save_results, $failed_test_summary, - $PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file, $compression; + $PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file; /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */ if (!getenv('NO_INTERACTION') && !TRAVIS_CI) { @@ -422,7 +422,7 @@ function save_or_mail_results() $failed_tests_data .= $sep . "PHPINFO" . $sep; $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null'); - if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status) && !TRAVIS_CI) { + if (($just_save_results || !mail_qa_team($failed_tests_data, $status)) && !TRAVIS_CI) { file_put_contents($output_file, $failed_tests_data); if (!$just_save_results) { @@ -450,13 +450,8 @@ $failed_tests_file= false; $pass_option_n = false; $pass_options = ''; -$compression = 0; $output_file = $CUR_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt'; -if ($compression && in_array("compress.zlib", stream_get_filters())) { - $output_file = 'compress.zlib://' . $output_file . '.gz'; -} - $just_save_results = false; $leak_check = false; $html_output = false; @@ -481,7 +476,7 @@ foreach($cfgtypes as $type) { if (getenv('TEST_PHP_ARGS')) { - if (!isset($argc) || !$argc || !isset($argv)) { + if (!isset($argc, $argv) || !$argc) { $argv = array(__FILE__); } @@ -789,7 +784,7 @@ HELP; if ($test_cnt) { putenv('NO_INTERACTION=1'); verify_config(); - write_information($html_output); + write_information(); usort($test_files, "test_sort"); $start_time = time(); @@ -837,7 +832,7 @@ HELP; } verify_config(); -write_information($html_output); +write_information(); // Compile a list of all test files (*.phpt). $test_files = array(); @@ -869,7 +864,7 @@ foreach ($user_tests as $dir) { function find_files($dir, $is_ext_dir = false, $ignore = false) { - global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped, $exts_tested; + global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped; $o = opendir($dir) or error("cannot open directory: $dir"); @@ -973,7 +968,7 @@ exit(0); // Send Email to QA Team // -function mail_qa_team($data, $compression, $status = false) +function mail_qa_team($data, $status = false) { $url_bits = parse_url(QA_SUBMISSION_PAGE); @@ -1125,13 +1120,13 @@ function system_with_timeout($commandline, $env = null, $stdin = null) $data .= "\nTermsig=" . ($stat["exitcode"] - 128) . "\n"; } - $code = proc_close($proc); + proc_close($proc); return $data; } function run_all_tests($test_files, $env, $redir_tested = null) { - global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx; + global $test_results, $failed_tests_file, $php, $test_idx; foreach($test_files as $name) { @@ -1182,12 +1177,11 @@ function show_file_block($file, $block, $section = null) // function run_test($php, $file, $env) { - global $log_format, $info_params, $ini_overwrites, $cwd, $PHP_FAILED_TESTS; + global $log_format, $ini_overwrites, $cwd, $PHP_FAILED_TESTS; global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx; global $leak_check, $temp_source, $temp_target, $cfg, $environment; global $no_clean; global $valgrind_version; - global $JUNIT; global $SHOW_ONLY_GROUPS; global $no_file_cache; $temp_filenames = null; @@ -1296,7 +1290,7 @@ TEST $file unset($section_text['FILEEOF']); } - foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { + foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { $key = $prefix . '_EXTERNAL'; if (@count($section_text[$key]) == 1) { @@ -1507,7 +1501,7 @@ TEST $file if (array_key_exists('EXTENSIONS', $section_text)) { $ext_dir=`$php -r 'echo ini_get("extension_dir");'`; $extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS'])); - $loaded = explode(",", `$php -n -r 'echo join(",", get_loaded_extensions());'`); + $loaded = explode(",", `$php -n -r 'echo implode(",", get_loaded_extensions());'`); foreach ($extensions as $req_ext) { if (!in_array($req_ext, $loaded)) { if ($req_ext == 'opcache') { @@ -1572,10 +1566,6 @@ TEST $file show_result('SKIP', $tested, $tested_file, '', $temp_filenames); } - if (isset($old_php)) { - $php = $old_php; - } - if (!$cfg['keep']['skip']) { @unlink($test_skipif); } @@ -1599,9 +1589,9 @@ TEST $file } } } - + if (!extension_loaded("zlib") - && ( array_key_exists("GZIP_POST", $section_text) + && ( array_key_exists("GZIP_POST", $section_text) || array_key_exists("DEFLATE_POST", $section_text)) ) { $message = "ext/zlib required"; @@ -1915,12 +1905,11 @@ COMMAND $cmd $output = preg_replace("/\r\n/", "\n", trim($out)); /* when using CGI, strip the headers from the output */ - $headers = ""; + $headers = array(); if (!empty($uses_cgi) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) { $output = trim($match[2]); $rh = preg_split("/[\n\r]+/", $match[1]); - $headers = array(); foreach ($rh as $line) { if (strpos($line, ':') !== false) { @@ -1945,26 +1934,23 @@ COMMAND $cmd } } - $org_headers = $headers; - $headers = array(); $output_headers = array(); foreach($want as $k => $v) { - if (isset($org_headers[$k])) { - $headers = $org_headers[$k]; - $output_headers[] = $k . ': ' . $org_headers[$k]; + if (isset($headers[$k])) { + $output_headers[] = $k . ': ' . $headers[$k]; } - if (!isset($org_headers[$k]) || $org_headers[$k] != $v) { + if (!isset($headers[$k]) || $headers[$k] != $v) { $failed_headers = true; } } ksort($wanted_headers); - $wanted_headers = join("\n", $wanted_headers); + $wanted_headers = implode("\n", $wanted_headers); ksort($output_headers); - $output_headers = join("\n", $output_headers); + $output_headers = implode("\n", $output_headers); } show_file_block('out', $output); @@ -2054,9 +2040,6 @@ COMMAND $cmd if (!$cfg['keep']['php']) { @unlink($test_file); } - if (isset($old_php)) { - $php = $old_php; - } if (!$leaked && !$failed_headers) { if (isset($section_text['XFAIL'] )) { @@ -2084,10 +2067,6 @@ COMMAND $cmd @unlink($test_file); } - if (isset($old_php)) { - $php = $old_php; - } - if (!$leaked && !$failed_headers) { if (isset($section_text['XFAIL'] )) { $warn = true; @@ -2187,10 +2166,6 @@ $output ); } - if (isset($old_php)) { - $php = $old_php; - } - $diff = empty($diff) ? '' : preg_replace('/\e/', '<esc>', $diff); junit_mark_test_as($restype, str_replace($cwd . '/', '', $tested_file), $tested, null, $info, $diff); @@ -2251,8 +2226,8 @@ function count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2, $cnt1, $cnt2, $ function generate_array_diff($ar1, $ar2, $is_reg, $w) { - $idx1 = 0; $ofs1 = 0; $cnt1 = @count($ar1); - $idx2 = 0; $ofs2 = 0; $cnt2 = @count($ar2); + $idx1 = 0; $cnt1 = @count($ar1); + $idx2 = 0; $cnt2 = @count($ar2); $diff = array(); $old1 = array(); $old2 = array(); @@ -2270,10 +2245,8 @@ function generate_array_diff($ar1, $ar2, $is_reg, $w) if ($c1 > $c2) { $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++]; - $last = 1; } else if ($c2 > 0) { $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; - $last = 2; } else { $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++]; $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; diff --git a/sapi/fpm/.gitignore b/sapi/fpm/.gitignore new file mode 100644 index 0000000000..3f8c0913a4 --- /dev/null +++ b/sapi/fpm/.gitignore @@ -0,0 +1,4 @@ +php-fpm.8 +php-fpm.service +status.html +www.conf diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 3c6101c0f7..ce4529d5d1 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -378,7 +378,7 @@ static PHP_FUNCTION(phpdbg_break_file) return; } - phpdbg_set_breakpoint_file(file, line); + phpdbg_set_breakpoint_file(file, 0, line); } /* }}} */ /* {{{ proto void phpdbg_break_method(string class, string method) */ diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index a690a77af8..da4c8f71bf 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -230,12 +230,7 @@ PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str) /* {{{ */ } } /* }}} */ -PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {{{ */ -{ - phpdbg_set_breakpoint_file_ex(path, 0, line_num); -} /* }}} */ - -PHPDBG_API void phpdbg_set_breakpoint_file_ex(const char *path, size_t path_len, long line_num) /* {{{ */ +PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, size_t path_len, long line_num) /* {{{ */ { php_stream_statbuf ssb; char realpath[MAXPATHLEN]; diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h index b44d5ec74e..7daafe48c1 100644 --- a/sapi/phpdbg/phpdbg_bp.h +++ b/sapi/phpdbg/phpdbg_bp.h @@ -125,8 +125,7 @@ PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uin PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file); /* }}} */ /* {{{ Breakpoint Creation API */ -PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, long lineno); -PHPDBG_API void phpdbg_set_breakpoint_file_ex(const char* filename, size_t path_len, long lineno); +PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, size_t path_len, long lineno); PHPDBG_API void phpdbg_set_breakpoint_symbol(const char* func_name, size_t func_name_len); PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name); PHPDBG_API void phpdbg_set_breakpoint_opcode(const char* opname, size_t opname_len); diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 35ee4332cd..36d947b57f 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1175,7 +1175,7 @@ PHPDBG_COMMAND(break) /* {{{ */ { if (!param) { if (PHPDBG_G(exec)) { - phpdbg_set_breakpoint_file_ex( + phpdbg_set_breakpoint_file( zend_get_executed_filename(), strlen(zend_get_executed_filename()), zend_get_executed_lineno()); @@ -1188,7 +1188,7 @@ PHPDBG_COMMAND(break) /* {{{ */ break; case NUMERIC_PARAM: if (PHPDBG_G(exec)) { - phpdbg_set_breakpoint_file_ex(phpdbg_current_file(), strlen(phpdbg_current_file()), param->num); + phpdbg_set_breakpoint_file(phpdbg_current_file(), strlen(phpdbg_current_file()), param->num); } else { phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!"); } @@ -1203,7 +1203,7 @@ PHPDBG_COMMAND(break) /* {{{ */ phpdbg_set_breakpoint_function_opline(param->str, param->num); break; case FILE_PARAM: - phpdbg_set_breakpoint_file(param->file.name, param->file.line); + phpdbg_set_breakpoint_file(param->file.name, 0, param->file.line); break; case NUMERIC_FILE_PARAM: phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line); diff --git a/win32/build/buildconf.js b/win32/build/buildconf.js index d7975d0139..b7e964e3e7 100644 --- a/win32/build/buildconf.js +++ b/win32/build/buildconf.js @@ -257,4 +257,4 @@ C.WriteBlankLines(1); C.Write(file_get_contents("win32/build/configure.tail"));
B.WriteLine("@echo off");
-B.WriteLine("cscript /nologo configure.js %*");
+B.WriteLine("cscript /nologo configure.js %*");
\ No newline at end of file diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 5c892899bb..682f1bd274 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -63,6 +63,9 @@ toolset_setup_common_cflags(); ARG_WITH('mp', 'Tell Visual Studio use up to [n,auto,disable] processes for compilation', 'auto'); var PHP_MP_DISABLED = true; if (VS_TOOLSET && PHP_MP != 'disable') { + if(PHP_DEBUG == 'yes') { + STDOUT.WriteLine('WARNING: Debug builds cannot be built using multi processing'); + } else { // no from disable-all if(PHP_MP == 'auto' || PHP_MP == 'no') { ADD_FLAG('CFLAGS', ' /MP '); @@ -75,6 +78,7 @@ if (VS_TOOLSET && PHP_MP != 'disable') { STDOUT.WriteLine('WARNING: Invalid argument for MP: ' + PHP_MP); } } + } } if (!PHP_MP_DISABLED) { @@ -151,7 +155,6 @@ ADD_SOURCES("main", "main.c snprintf.c spprintf.c getopt.c fopen_wrappers.c \ strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c network.c \ php_open_temporary_file.c output.c internal_functions.c php_sprintf.c"); ADD_FLAG("CFLAGS_BD_MAIN", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -ADD_SOURCES("win32", "inet.c fnmatch.c sockets.c"); AC_DEFINE('HAVE_STRNLEN', 1); @@ -161,7 +164,8 @@ ADD_FLAG("CFLAGS_BD_MAIN_STREAMS", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_SOURCES("win32", "dllmain.c glob.c readdir.c \ registry.c select.c sendmail.c time.c winutil.c wsyslog.c globals.c \ - getrusage.c ftok.c ioutil.c codepage.c"); + getrusage.c ftok.c ioutil.c codepage.c nice.c \ + inet.c fnmatch.c sockets.c"); ADD_FLAG("CFLAGS_BD_WIN32", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); @@ -294,3 +298,8 @@ toolset_setup_codegen_arch(); ARG_WITH("all-shared", "Force all the non obligatory extensions to be shared", "no"); +// Config profiles (--with-config-profile=<name>) will save a certain config to php-src/config.<name>.bat +// so that it can be executed like: cofig.<name> instead of a long list of parameters +// +// Note, nice as a name is disallowed and will generate a warning and skip saving +ARG_WITH('config-profile', 'Name of the configuration profile to save this to in php-src/config.name.bat', 'no');
\ No newline at end of file diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index 2a8297a144..e871088f15 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -175,3 +175,5 @@ #define HAVE_GETRUSAGE #define HAVE_FTOK 1 + +#define HAVE_NICE diff --git a/win32/build/confutils.js b/win32/build/confutils.js index a534b1eeb8..451954406f 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -103,7 +103,7 @@ var PHP_VERSION = 7; var PHP_MINOR_VERSION = 1; var PHP_RELEASE_VERSION = 0; var PHP_EXTRA_VERSION = ""; -var PHP_VERSION_STRING = "7.1.0"; +var PHP_VERSION_STRING = "7.2.0"; /* Get version numbers and DEFINE as a string */ function get_version_numbers() @@ -337,6 +337,7 @@ function conf_process_args() for (i = 0; i < args.length; i++) { arg = args(i); nice += ' "' + arg + '"'; + if (arg == "--help") { configure_help_mode = true; break; @@ -437,7 +438,7 @@ can be built that way. \ 'pcre-regex', 'fastcgi', 'force-cgi-redirect', 'path-info-check', 'zts', 'ipv6', 'memory-limit', 'zend-multibyte', 'fd-setsize', 'memory-manager', - 't1lib', 'pgi', 'pgo', 'all-shared' + 'pgi', 'pgo', 'all-shared', 'config-profile' ); var force; @@ -518,10 +519,31 @@ can be built that way. \ MFO = FSO.CreateTextFile("Makefile.objects", true); - STDOUT.WriteLine("Saving configure options to config.nice.bat"); - var nicefile = FSO.CreateTextFile("config.nice.bat", true); - nicefile.WriteLine(nice + " %*"); - nicefile.Close(); + var profile = false; + + if (PHP_CONFIG_PROFILE != 'no') { + if (PHP_CONFIG_PROFILE.toLowerCase() == 'nice') { + WARNING('Config profile name cannot be named \'nice\''); + } else { + var config_profile = FSO.CreateTextFile('config.' + PHP_CONFIG_PROFILE + '.bat', true); + + config_profile.WriteLine('@echo off'); + config_profile.WriteLine(nice + ' %*'); + config_profile.Close(); + + profile = true; + } + } + + // Only generate an updated config.nice.bat file if a profile was not used + if (!profile) { + STDOUT.WriteLine("Saving configure options to config.nice.bat"); + + var nicefile = FSO.CreateTextFile("config.nice.bat", true); + nicefile.WriteLine('@echo off'); + nicefile.WriteLine(nice + " %*"); + nicefile.Close(); + } AC_DEFINE('CONFIGURE_COMMAND', nice, "Configure line"); } @@ -929,7 +951,7 @@ function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env if (typeof(add_to_flag_only) != "undefined") { ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have); - } else { + } else if (!configure_hdr.Exists('HAVE_' + sym)) { AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); } diff --git a/win32/dllmain.c b/win32/dllmain.c index 37408f1e76..ab4f105528 100644 --- a/win32/dllmain.c +++ b/win32/dllmain.c @@ -40,11 +40,19 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID dummy) switch (reason) { case DLL_PROCESS_ATTACH: - ret = ret && php_win32_init_gettimeofday(); - if (!ret) { - fprintf(stderr, "gettimeofday() initialization failed"); - return ret; - } + /* + * We do not need to check the return value of php_win32_init_gettimeofday() + * because the symbol bare minimum symbol we need is always available on our + * lowest supported platform. + * + * On Windows 8 or greater, we use a more precise symbol to obtain the system + * time, which is dynamically. The fallback allows us to proper support + * Vista/7/Server 2003 R2/Server 2008/Server 2008 R2. + * + * Instead simply initialize the global in win32/time.c for gettimeofday() + * use later on + */ + php_win32_init_gettimeofday(); ret = ret && php_win32_ioutil_init(); if (!ret) { diff --git a/win32/ftok.c b/win32/ftok.c index 842da78192..4c35017060 100644 --- a/win32/ftok.c +++ b/win32/ftok.c @@ -22,7 +22,7 @@ #include <sys/stat.h> -PHPAPI key_t +PHP_WIN32_IPC_API key_t ftok(const char *pathname, int proj_id) { HANDLE fh; diff --git a/win32/getrusage.c b/win32/getrusage.c index d719bcde26..3267ac63ad 100644 --- a/win32/getrusage.c +++ b/win32/getrusage.c @@ -26,7 +26,7 @@ * and have been modified to work with PHP. */ -static void usage_to_timeval(FILETIME *ft, struct timeval *tv) +static zend_always_inline void usage_to_timeval(FILETIME *ft, struct timeval *tv) { ULARGE_INTEGER time; diff --git a/win32/ioutil.h b/win32/ioutil.h index 15c8f0e339..6699d78a14 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -466,7 +466,7 @@ __forceinline static char *php_win32_ioutil_getcwd(char *buf, int len) /* If buf was NULL, the result has to be freed outside here. */ buf = tmp_bufa; } else { - if (tmp_bufa_len + 1 > len) { + if (tmp_bufa_len + 1 > (size_t)len) { free(tmp_bufa); SET_ERRNO_FROM_WIN32_CODE(ERROR_INSUFFICIENT_BUFFER); return NULL; diff --git a/win32/ipc.h b/win32/ipc.h index cafcf4f85e..0d7cc47e8c 100644 --- a/win32/ipc.h +++ b/win32/ipc.h @@ -19,11 +19,15 @@ #ifndef PHP_WIN32_IPC_H #define PHP_WIN32_IPC_H 1 -#include "php.h" +#ifdef PHP_EXPORTS +# define PHP_WIN32_IPC_API __declspec(dllexport) +#else +# define PHP_WIN32_IPC_API __declspec(dllimport) +#endif typedef int key_t; -PHPAPI key_t ftok(const char *path, int id); +PHP_WIN32_IPC_API key_t ftok(const char *path, int id); #endif /* PHP_WIN32_IPC_H */ diff --git a/win32/nice.c b/win32/nice.c new file mode 100644 index 0000000000..db26cc1aa6 --- /dev/null +++ b/win32/nice.c @@ -0,0 +1,83 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#include <php.h> +#include "nice.h" + +/* + * Basic Windows implementation for the nice() function. + * + * This implementation uses SetPriorityClass() as a backend for defining + * a process priority. + * + * The following values of inc, defines the value sent to SetPriorityClass(): + * + * +-----------------------+-----------------------------+ + * | Expression | Priority type | + * +-----------------------+-----------------------------+ + * | priority < -14 | REALTIME_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -9 | HIGH_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority < -4 | ABOVE_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority > 4 | BELOW_NORMAL_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * | priority > 9 | IDLE_PRIORITY_CLASS | + * +-----------------------+-----------------------------+ + * + * If a value is between -4 and 4 (inclusive), then the priority will be set + * to NORMAL_PRIORITY_CLASS. + * + * These values tries to mimic that of the UNIX version of nice(). + * + * This is applied to the main process, not per thread, although this could + * be implemented using SetThreadPriority() at one point. + */ + +PHPAPI int nice(zend_long p) +{ + DWORD dwFlag = NORMAL_PRIORITY_CLASS; + + if (p < -14) { + dwFlag = REALTIME_PRIORITY_CLASS; + } else if (p < -9) { + dwFlag = HIGH_PRIORITY_CLASS; + } else if (p < -4) { + dwFlag = ABOVE_NORMAL_PRIORITY_CLASS; + } else if (p > 9) { + dwFlag = IDLE_PRIORITY_CLASS; + } else if (p > 4) { + dwFlag = BELOW_NORMAL_PRIORITY_CLASS; + } + + if (!SetPriorityClass(GetCurrentProcess(), dwFlag)) { + return -1; + } + + return 0; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/win32/nice.h b/win32/nice.h new file mode 100644 index 0000000000..037949f3bf --- /dev/null +++ b/win32/nice.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2016 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen <kalle@php.net> | + +----------------------------------------------------------------------+ + */ + +#ifndef HAVE_NICE_H +# define HAVE_NICE_H + +PHPAPI int nice(zend_long); + +#endif + diff --git a/win32/time.c b/win32/time.c index dfcc46a59b..a0ed1b344e 100644 --- a/win32/time.c +++ b/win32/time.c @@ -39,20 +39,21 @@ static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void) /* Max possible resolution <1us, win8/server2012 */ timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime"); - if(!timefunc) { - /* 100ns blocks since 01-Jan-1641 */ - timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime"); - } + /* Lower the refcount */ + FreeLibrary(hMod); + } + + if(!timefunc) { + /* 100ns blocks since 01-Jan-1641 */ + timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime; } return timefunc; } -BOOL php_win32_init_gettimeofday(void) +void php_win32_init_gettimeofday(void) { timefunc = get_time_func(); - - return (NULL != timefunc); } #endif diff --git a/win32/time.h b/win32/time.h index b46c1675ca..865e299aa9 100644 --- a/win32/time.h +++ b/win32/time.h @@ -55,7 +55,7 @@ PHPAPI int usleep(unsigned int useconds); #ifdef PHP_EXPORTS /* This symbols are needed only for the DllMain, but should not be exported or be available when used with PHP binaries. */ -BOOL php_win32_init_gettimeofday(void); +void php_win32_init_gettimeofday(void); #endif #endif |