]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.5' into PHP-5.6
authorBob Weinand <bobwei9@hotmail.com>
Sun, 13 Apr 2014 22:08:36 +0000 (00:08 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Sun, 13 Apr 2014 22:08:36 +0000 (00:08 +0200)
1  2 
NEWS
UPGRADING.INTERNALS
ext/phar/phar_object.c
ext/spl/spl_observer.c
ext/standard/array.c
ext/standard/php_array.h

diff --cc NEWS
index cd75dca28fd426e9b750cddb3173be49c0da9cc1,cb6c695854fc3c383c44223f821ed42a1851f8de..e4809ae403efc6bc9cda1e7a28be4ea0d5697707
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,21 -1,28 +1,23 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? 2014, PHP 5.5.12
 -- Core:
 -  . Fixed bug #61019 (Out of memory on command stream_get_contents). (Mike)
 -  . Fixed bug #64330 (stream_socket_server() creates wrong Abstract Namespace 
 -    UNIX sockets). (Mike)
 -  . Fixed bug #66182 (exit in stream filter produces segfault). (Mike)  
 -  . Fixed bug #66736 (fpassthru broken). (Mike)
 -  . Fixed bug #67043 (substr_compare broke by previous change) (Tjerk)
 -
 -- Embed:
 -  . Fixed bug #65715 (php5embed.lib isn't provided anymore). (Anatol).
 +?? ??? 2014, PHP 5.6.0 Beta 2
  
 -- Fileinfo:
 -  . Fixed bug #66987 (Memory corruption in fileinfo ext / bigendian).
 -    (Remi)
 +- Core:
 +  . Fixed bug #66015 (Unexpected array indexing in class's static property). (Bob)
 +  . Added (constant) string/array dereferencing to static scalar expressions
 +    to complete the set; now possible thanks to bug #66015 being fixed. (Bob)
 +  . Fixed bug #66568 (Update reflection information for unserialize() function).
 +    (Ferenc)
 +  . Fixed bug #66660 (Composer.phar install/update fails). (Ferenc)
++  . Fixed bug #67064  (Countable interface prevents using 2nd parameter
++    ($mode) of count() function). (Bob)
  
 -- mysqli:
 -  . Fixed problem in mysqli_commit()/mysqli_rollback() with second parameter
 -    (extra comma) and third parameters (lack of escaping). (Andrey)
 +- mysqlnd:
 +  . Added a new fetching mode to mysqlnd. (Andrey)
  
 -- SimpleXML:
 -  . Fixed bug #66084 (simplexml_load_string() mangles empty node name)
 -    (Anatol)
 +- PDO:
 +  . Fixed bug #66604 ('pdo/php_pdo_error.h' not copied to the include dir).
 +    (Matteo)
  
  - SQLite:
    . Fixed bug #66967 (Updated bundled libsqlite to 3.8.4.3). (Anatol)
index f3e7281ca18977e4f01bd903265075f8fd21c79d,bdc2a43ab9ce21038b54818a271b136576a314cb..1bc359bfd003be665585ea500aa8a5f00b1c8263
@@@ -22,166 -18,96 +22,173 @@@ UPGRADE NOTES - PHP X.
  1. Internal API changes
  ========================
  
 -      a. Executor changes
 -
 - * extensions can't override zend_execute() any more, they should override
 -   zend_execute_ex() instead. The EG(current_execute_data) is already
 -   initialized in zend_execute_ex(), so for compatibility extensions
 -   may need to use EG(current_execute_data)->prev_execute_data instead.
 - * removed EG(arg_types_stack), EX(fbc), EX(called_scope), EX(current_object)
 - * added op_array->nested_calls. It's calculated at compile time.
 - * added EX(call_slots). It is an array to store information about syntaticaly
 -   nested calls (e.g. foo(bar())). It's preallocated together with execute_data.
 - * added EX(call) - pointer to a current calling function. Actually an
 -   element of EX(call_slots)
 - * opcodes INIT_METHOD_CALL, ZEND_INIT_STATIC_METHOD_CALL,
 -   ZEND_INIT_FCALL_BY_NAME, ZEND_INIT_NS_FCALL_BY_NAME use result.num as
 -   an index in EX(call_slots)
 - * opcode ZEND_NEW uses extended_vallue as an index in EX(call_slots)
 - * opcoes ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME use op2.num as
 -   an index in EX(call_slots)
 - * added op_array->used_stack. It's calculated at compile time and the
 -   corresponding stack space is preallocated together with execute_data.
 -   ZEND_SEND* and ZEND_DO_FCALL* don't need to check for stack overflow
 -   anymore.
 - * Removed execute_data->Ts field. The VM temporary variables always allocated
 -   immediately before execute_data structure. Now they are accessed by offset
 -   from the execute_data base pointer (instead of execute_data->Ts). Compiler
 -   stores new offsets in op_array->opcodes[*].op?.num. You can use macros
 -   EX_TMP_VAR() and EX_TMP_VAR_NUM() to access temp_variable by offset or
 -   number. You can convert number to offset using EX_TMP_VAR_NUM(0, num) or
 -   offset to number (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)).
 - * Removed execute_data->CVs field. The VM compiled variables always allocated
 -   immediately after execute_data structure. Now they are accessed by offset
 -   from the execute_data base pointer (instead of execute_data->CVs). You can
 -   use macros EX_CV_NUM() to access compiled variables by number.
 -
 -      b. Streams pooling API
 -
 -The streams pooling API has been removed. The following functions no longer
 -exist:
 -
 -PHPAPI int php_stream_context_get_link(php_stream_context *context,
 -              const char *hostent, php_stream **stream);
 -PHPAPI int php_stream_context_set_link(php_stream_context *context,
 -              const char *hostent, php_stream *stream);
 -PHPAPI int php_stream_context_del_link(php_stream_context *context,
 -              php_stream *stream);
 -
 -      c. Lowercasing and locales
 -
 -The lowercasing functions in zend_operators.c were split into those that do 
 -lowercasing according to locale rules and those that do ASCII lowercasing.
 -ASCII:
 -
 -                zend_str_tolower_copy
 -                zend_str_tolower_dup
 -                zend_str_tolower
 -                zend_binary_strcasecmp
 -                zend_binary_strncasecmp
 -
 -Locale-based:
 -                zend_binary_strncasecmp_l
 -                zend_binary_strcasecmp_l
 -                zend_binary_zval_strcasecmp
 -                zend_binary_zval_strncasecmp
 -                string_compare_function_ex
 -                string_case_compare_function
 -
 -Internal engine lowercasing will be using ASCII-only rules. User-facing functions,
 -such as strcasecmp, will be using locale rules. 
 -
 -Two new functions - zend_binary_strncasecmp_l and zend_binary_strcasecmp_l - added as 
 -locale-based counterparts to zend_binary_strcasecmp and zend_binary_strncasecmp.
 -
 -      d. zend_qsort_r
 -
 -Added the function zend_qsort_r():
 -
 -typedef int  (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
 -void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
 -
 -The extra argument it has (relatively to zend_qsort()) is passed to the
 -comparison function.
 -
 -      e. get_current_key
 -
 -The signature of the get_current_key iteration handler has been changed to:
 -
 -void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
 -
 -The key should be written into the zval* using the ZVAL_* macros.
 +  a. Addition of do_operation and compare object handlers
 +
 +  Two new object handlers have been added:
 +
 +    do_operation:
 +    typedef int (*zend_object_do_operation_t)(
 +        zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC
 +    );
 +
 +    compare:
 +    typedef int (*zend_object_compare_zvals_t)(
 +        zval *result, zval *op1, zval *op2 TSRMLS_DC
 +    );
 +
 +  The first handler is used to overload arithmetic operations. The first
 +  argument specifies the opcode of the operator, result is the target zval,
 +  op1 the first operand and op2 the second operand. For unary operations
 +  op2 is NULL. If the handler returns FAILURE PHP falls back to the default
 +  behavior for the operation.
 +
 +  The second handler is used to perform comparison operations with
 +  non-objects. The value written into result must be an IS_LONG with value
 +  -1 (smaller), 0 (equal) or 1 (greater). The return value is a SUCCESS/FAILURE
 +  return code. The difference between this handler and compare_objects is
 +  that it will be triggered for comparisons with non-objects and objects of
 +  different types. It takes precedence over compare_objects.
 +
 +  Further docs in the RFC: https://wiki.php.net/rfc/operator_overloading_gmp
 +
 +  b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros
 +
 +  The return_value_ptr argument to internal functions is now always set.
 +  Previously it was only available for functions returning by-reference.
 +  return_value_ptr can now be used to return zvals without copying them.
 +  For this purpose two new macros are provided:
 +
 +      RETVAL_ZVAL_FAST(zv); /* analog to RETVAL_ZVAL(zv, 1, 0) */
 +      RETURN_ZVAL_FAST(zv); /* analog to RETURN_ZVAL(zv, 1, 0) */
 +
 +  The macros behave similarly to the non-FAST variants with copy=1 and
 +  dtor=0, but will try to return the zval without making a copy by utilizing
 +  return_value_ptr.
 +  
 +  c. POST data handling
 +  
 +  The sapi_request_info's members post_data, post_data_len and raw_post_data as 
 +  well as raw_post_data_len have been replaced with a temp PHP stream 
 +  request_body.
 +  
 +  The recommended way to access raw POST data is to open and use a php://input 
 +  stream wrapper.  It is safe to be used concurrently and more than once. 
 +
 +  d. Arginfo changes
 +
 +  The pass_rest_by_reference argument of the ZEND_BEGIN_ARG_INFO and
 +  ZEND_BEGIN_ARG_INFO_EX() is no longer used. The value passed to it is ignored.
 +
 +  Instead a variadic argument is created using ZEND_ARG_VARIADIC_INFO():
 +
 +      ZEND_ARG_VARIADIC_INFO(0, name) /* pass rest by value */
 +      ZEND_ARG_VARIADIC_INFO(1, name) /* pass rest by reference */
 +      ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, name)
 +          /* pass rest by prefer-ref */
 +
 +  ZEND_ARG_VARIADIC_INFO() should only be used for the last argument.
 +
 +  The following changes were applied to the zend_arg_info struct:
 +
 +       typedef struct _zend_arg_info {
 +           const char *class_name;
 +           zend_uint class_name_len;
 +           zend_uchar type_hint;
 +      +    zend_uchar pass_by_reference;
 +           zend_bool allow_null;
 +      -    zend_bool pass_by_reference;
 +      +    zend_bool is_variadic;
 +       } zend_arg_info;
 +
 +  The following changes were applied to the zend_internal_function_info struct:
 +
 +       typedef struct _zend_internal_function_info {
 +           zend_uint required_num_args;
 +           zend_uchar _type_hint;
 +           zend_bool return_reference;
 +      -    zend_bool pass_rest_by_reference;
 +      +    zend_bool _allow_null;
 +      +    zend_bool _is_variadic;
 +       } zend_internal_function_info;
 +
 +  The CHECK_ARG_SEND_TYPE(), ARG_MUST_BE_SENT_BY_REF(),
 +  ARG_SHOULD_BE_SENT_BY_REF() and ARG_MAY_BE_SENT_BY_REF() macros now assume
 +  that the argument passed to them is a zend_function* and that it is non-NULL.
 +
 +  e. tsrm_virtual_cwd.h moved to zend_virtual_cwd.h
 +
 +  Memory allocation is now managed by emalloc/efree instead of malloc/free.
 +
 +  f. empty strings are interned
 +
 +  String created using STR_EMPTY_ALLOC() are now interned.
 +  convert_to_string use STR_EMPTY_ALLOC() for zval when IS_NULL.
 +  str_efree() shoud be preferred as efree() on such strings can cause memory
 +  corruption.
 +
 +  g. Additional str_* APIs
 +
 +  In addition to the previously existing str_free() and str_efree() macros, the
 +  following macros have been introduced to simplify dealing with potentially
 +  interned strings:
 +
 +      str_efree_rel(str)         - efree_rel() if not interned
 +      str_erealloc(str, new_len) - erealloc() or emalloc+memcpy if interned
 +      str_estrndup(str, len)     - estrndup() if not interned
 +      str_strndup(str, len)      - zend_strndup() if not interned
 +      str_hash(str, len)         - INTERNED_HASH(str) if interned,
 +                                   zend_hash_func(str, len+1) otherwise
 +
 +  h. Addition of zend_hash_reindex
 +
 +  A zend_hash_reindex() function with the following prototype has been added:
 +
 +      void zend_hash_reindex(HashTable *ht, zend_bool only_integer_keys);
 +
 +  If only_integer_keys==0, this function will change all keys to be continuous,
 +  zero-based integers in hash order. If only_integer_keys==1 the same will be
 +  done only for keys that were already integers previously, while leaving
 +  string keys alone.
 +
 +  i. Addition of zend_hash_splice
 +
 +  A zend_hash_splice() macro with the following prototype has been added:
 +
 +      void zend_hash_splice(
 +          HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor,
 +          uint offset, uint length,
 +          void **list, uint list_count, HashTable *removed
 +      );
 +
 +  This function performs an in-place splice operation on a hashtable:
 +
 +  The elements between offset and offset+length are removed and the elements in
 +  list[list_count] are inserted in their place. The removed elements can be
 +  optionally collected into a hashtable.
 +
 +  This operation reindexes the hashtable, i.e. integer keys will be zero-based
 +  and sequential, while string keys stay intact. The same applies to the
 +  elements inserted into the removed HT.
 +
 +  As a side-effect of this addition the signature of the php_splice() function
 +  changed:
 +
 +      void php_splice(
 +          HashTable *ht, zend_uint offset, zend_uint length,
 +          zval ***list, zend_uint list_count, HashTable *removed TSRMLS_DC
 +      )
 +  
 +  This function now directly forwards to zend_hash_splice(), resets the
 +  IAP of ht (for compatibility with the previous implementation) and resets
 +  CVs if the passed hashtable is the global symbol table.
 +
++  j. An additional parameter is sent to Countable::count()
++
++  That parameter denotes the $mode passed to count; it shouldn't affect any
++  userland code, but any zend_parse_parameters() used with no arguments should
++  fail. Extensions which implement Countable internally, need to accept one
++  optional long as parameter.
  ========================
  2. Build system changes
  ========================
index 99907f86ddcc3addb9b91db38fee07f02f4d3831,7857fa71c890ed61914f4866c8ca4d4fc7962629..407edda0fbf17ec69470a115063fde89ee5ae6d1
@@@ -1934,10 -1934,10 +1934,12 @@@ PHP_METHOD(Phar, buildFromIterator
   */
  PHP_METHOD(Phar, count)
  {
++      /* mode can be ignored, maximum depth is 1 */
++      long mode;
        PHAR_ARCHIVE_OBJECT();
        
--      if (zend_parse_parameters_none() == FAILURE) {
--              return;
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) {
++              RETURN_FALSE;
        }
  
        RETURN_LONG(zend_hash_num_elements(&phar_obj->arc.archive->manifest));
index 1a706f76429ea135553ac1b3e23e6fc146ff18d4,1a706f76429ea135553ac1b3e23e6fc146ff18d4..91830ab000da50d4a549a4bc0f304df7daa12647
@@@ -26,6 -26,6 +26,7 @@@
  #include "php.h"
  #include "php_ini.h"
  #include "ext/standard/info.h"
++#include "ext/standard/php_array.h"
  #include "ext/standard/php_var.h"
  #include "ext/standard/php_smart_str.h"
  #include "zend_interfaces.h"
@@@ -621,11 -621,11 +622,27 @@@ SPL_METHOD(SplObjectStorage, contains
  SPL_METHOD(SplObjectStorage, count)
  {
        spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
--      
--      if (zend_parse_parameters_none() == FAILURE) {
++      long mode = COUNT_NORMAL;
++
++      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) {
                return;
        }
--      
++
++      if (mode == COUNT_RECURSIVE) {
++              long ret = zend_hash_num_elements(&intern->storage);
++              HashPosition position;
++              zval *element;
++
++              for (zend_hash_internal_pointer_reset_ex(&intern->storage, &position);
++                   zend_hash_get_current_data_ex(&intern->storage, (void**) &element, &position) == SUCCESS;
++                   zend_hash_move_forward_ex(&intern->storage, &position)) {
++                      ret += php_count_recursive(element, mode TSRMLS_CC);
++              }
++
++              RETURN_LONG(ret);
++              return;
++      }
++
        RETURN_LONG(zend_hash_num_elements(&intern->storage));
  } /* }}} */
  
index 34057e34c80caaf58fa18074f02eaf06b1dad66d,1a29afa6dc20fd7eb622bd185b8d5ca42b17644d..4f983310353d024aec523c4ce7880d9d81867fdf
@@@ -64,9 -64,9 +64,6 @@@
  #define CASE_LOWER                            0
  #define CASE_UPPER                            1
  
--#define COUNT_NORMAL                  0
--#define COUNT_RECURSIVE                       1
--
  #define DIFF_NORMAL                   1
  #define DIFF_KEY                      2
  #define DIFF_ASSOC                    6
@@@ -274,7 -271,7 +271,7 @@@ PHP_FUNCTION(ksort
  }
  /* }}} */
  
--static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
++PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
  {
        long cnt = 0;
        zval **element;
@@@ -336,15 -333,12 +333,17 @@@ PHP_FUNCTION(count
  #ifdef HAVE_SPL
                        /* if not and the object implements Countable we call its count() method */
                        if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
 -                              zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
 +                              zval *mode_zv;
 +                              MAKE_STD_ZVAL(mode_zv);
-                               Z_LVAL_P(mode_zv) = mode;
++                              ZVAL_LONG(mode_zv, mode);
 +                              zend_call_method_with_1_params(&array, NULL, NULL, "count", &retval, mode_zv);
                                if (retval) {
                                        convert_to_long_ex(&retval);
                                        RETVAL_LONG(Z_LVAL_P(retval));
                                        zval_ptr_dtor(&retval);
                                }
++                              zval_dtor(mode_zv);
++                              efree(mode_zv);
                                return;
                        }
  #endif
index deddeb48716a6dc5608f69c530c9216c8d42a9a6,e2af3310d03c0b6037d07ed5f58f2700abcf4647..1b30e347871036229de9555e6a6a7b382d782c84
@@@ -107,6 -107,6 +107,7 @@@ PHPAPI void php_splice(HashTable *ht, z
  PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);
  PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC);
  PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
++PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC);
  
  #define PHP_SORT_REGULAR            0
  #define PHP_SORT_NUMERIC            1
  #define PHP_SORT_NATURAL            6
  #define PHP_SORT_FLAG_CASE          8
  
++#define COUNT_NORMAL      0
++#define COUNT_RECURSIVE   1
++
 +#define ARRAY_FILTER_USE_BOTH 1
 +#define ARRAY_FILTER_USE_KEY  2
 +
  ZEND_BEGIN_MODULE_GLOBALS(array) 
        int *multisort_flags[2];
        int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC);