Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Patch import

  • Loading branch information...
commit 790d551ac9ef8e204b44f4030291536137b0be25 1 parent 7301447
@infusion authored
Showing with 4,908 additions and 2,220 deletions.
  1. +1 −7 Makefile.global
  2. +4 −14 Zend/zend.c
  3. +0 −57 Zend/zend_API.c
  4. +0 −4 Zend/zend_API.h
  5. +0 −9 Zend/zend_builtin_functions.c
  6. +37 −1 Zend/zend_compile.c
  7. +10 −2 Zend/zend_compile.h
  8. +0 −19 Zend/zend_constants.c
  9. +13 −9 Zend/zend_execute.c
  10. +1 −0  Zend/zend_execute.h
  11. +0 −3  Zend/zend_globals.h
  12. +3 −0  Zend/zend_iterators.c
  13. +2 −1  Zend/zend_iterators.h
  14. +24 −17 Zend/zend_language_parser.h
  15. +20 −2 Zend/zend_language_parser.y
  16. +68 −95 Zend/zend_language_scanner.l
  17. +27 −0 Zend/zend_strtod.c
  18. +1 −0  Zend/zend_strtod.h
  19. +117 −4 Zend/zend_vm_def.h
  20. +499 −40 Zend/zend_vm_execute.h
  21. +1 −0  Zend/zend_vm_opcodes.h
  22. +1 −1  configure.in
  23. +1 −7 ext/bz2/bz2.c
  24. +1 −1  ext/calendar/cal_unix.c
  25. +0 −12 ext/com_dotnet/com_persist.c
  26. +11 −11 ext/curl/interface.c
  27. +4 −4 ext/curl/streams.c
  28. +152 −11 ext/date/php_date.c
  29. +2 −0  ext/date/php_date.h
  30. +1 −13 ext/dba/dba.c
  31. +0 −1  ext/dba/libflatfile/flatfile.c
  32. +0 −1  ext/dba/libinifile/inifile.c
  33. +0 −4 ext/enchant/enchant.c
  34. +4 −16 ext/exif/exif.c
  35. +0 −4 ext/fileinfo/fileinfo.c
  36. +1 −5 ext/filter/filter.c
  37. +0 −1  ext/filter/php_filter.h
  38. +0 −15 ext/filter/sanitizing_filters.c
  39. +1 −1  ext/ftp/ftp.c
  40. +1 −3 ext/gd/php_gd.h
  41. +2 −5 ext/imap/php_imap.c
  42. +2 −9 ext/interbase/ibase_query.c
  43. +1 −1  ext/interbase/interbase.c
  44. +35 −2 ext/json/json.c
  45. +2 −0  ext/json/php_json.h
  46. +0 −13 ext/mbstring/mb_gpc.c
  47. +0 −1  ext/mbstring/mb_gpc.h
  48. +0 −6 ext/mbstring/mbstring.c
  49. +0 −5 ext/mssql/php_mssql.c
  50. +3 −20 ext/mysql/php_mysql.c
  51. +2 −52 ext/mysqli/mysqli.c
  52. +45 −4 ext/mysqli/mysqli_api.c
  53. +4 −0 ext/mysqli/mysqli_fe.c
  54. +3 −0  ext/mysqli/mysqli_fe.h
  55. +29 −1 ext/mysqli/mysqli_nonapi.c
  56. +73 −0 ext/mysqli/mysqli_prop.c
  57. +20 −0 ext/mysqlnd/mysqlnd.c
  58. +2 −0  ext/mysqlnd/mysqlnd.h
  59. +2 −0  ext/mysqlnd/mysqlnd_libmysql_compat.h
  60. +11 −0 ext/mysqlnd/mysqlnd_ps.c
  61. +4 −0 ext/mysqlnd/mysqlnd_structs.h
  62. +5 −9 ext/oci8/oci8.c
  63. +0 −10 ext/oci8/oci8_interface.c
  64. +1 −1  ext/oci8/oci8_lob.c
  65. +1 −8 ext/odbc/php_odbc.c
  66. +0 −3  ext/openssl/openssl.c
  67. +1 −6 ext/pdo_mysql/mysql_driver.c
  68. +2 −7 ext/pdo_sqlite/sqlite_driver.c
  69. +2 −14 ext/pgsql/pgsql.c
  70. +0 −7 ext/phar/func_interceptors.c
  71. +3 −17 ext/phar/phar.c
  72. +1 −27 ext/phar/phar_object.c
  73. +1 −1  ext/phar/tar.c
  74. +1 −13 ext/phar/util.c
  75. +2 −2 ext/phar/zip.c
  76. +3 −6 ext/posix/posix.c
  77. +0 −13 ext/pspell/pspell.c
  78. +1 −5 ext/reflection/php_reflection.c
  79. +2 −11 ext/session/mod_files.c
  80. +4 −94 ext/session/session.c
  81. +2 −2 ext/soap/php_sdl.c
  82. +1 −11 ext/spl/spl_directory.c
  83. +1 −6 ext/sqlite/pdo_sqlite2.c
  84. +2 −2 ext/sqlite/sess_sqlite.c
  85. +4 −13 ext/sqlite/sqlite.c
  86. +0 −18 ext/sqlite3/sqlite3.c
  87. +2 −2 ext/standard/array.c
  88. +87 −116 ext/standard/basic_functions.c
  89. +0 −3  ext/standard/basic_functions.h
  90. +1 −1  ext/standard/config.m4
  91. +4 −7 ext/standard/dir.c
  92. +0 −3  ext/standard/dl.c
  93. +2 −39 ext/standard/exec.c
  94. +38 −95 ext/standard/file.c
  95. +1 −0  ext/standard/file.h
  96. +1 −49 ext/standard/filestat.c
  97. +1 −1  ext/standard/ftok.c
  98. +1 −1  ext/standard/ftp_fopen_wrapper.c
  99. +1 −2  ext/standard/head.c
  100. +7 −7 ext/standard/html.c
  101. +0 −4 ext/standard/iptc.c
  102. +0 −21 ext/standard/link.c
  103. +0 −1  ext/standard/link_win32.c
  104. +0 −6 ext/standard/mail.c
  105. +180 −1 ext/standard/math.c
  106. +1 −1  ext/standard/microtime.c
  107. +0 −1  ext/standard/pack.c
  108. +1 −1  ext/standard/php_array.h
  109. +1 −2  ext/standard/php_ext_syslog.h
  110. +7 −1 ext/standard/php_math.h
  111. +2 −2 ext/standard/php_rand.h
  112. +11 −9 ext/standard/php_smart_str.h
  113. +9 −2 ext/standard/php_string.h
  114. +0 −79 ext/standard/proc_open.c
  115. +2,307 −0 ext/standard/session.c
  116. +1 −9 ext/standard/streamsfuncs.c
  117. +563 −72 ext/standard/string.c
  118. +2 −87 ext/standard/syslog.c
  119. +1 −3 ext/sybase_ct/php_sybase_ct.c
  120. +1 −2  ext/tidy/tidy.c
  121. +0 −5 ext/zip/php_zip.h
  122. +1 −7 ext/zlib/zlib.c
  123. +1 −62 main/SAPI.c
  124. +1 −1  main/SAPI.h
  125. +0 −83 main/fopen_wrappers.c
  126. +1 −3 main/fopen_wrappers.h
  127. +327 −152 main/main.c
  128. +4 −15 main/php_globals.h
  129. +0 −4 main/php_ini.c
  130. +14 −66 main/php_variables.c
  131. +0 −17 main/rfc1867.c
  132. +0 −172 main/safe_mode.c
  133. +0 −13 main/safe_mode.h
  134. +0 −63 main/streams/plain_wrapper.c
  135. +1 −4 sapi/apache/mod_php5.c
  136. +3 −10 sapi/apache/php_apache.c
  137. +1 −4 sapi/apache2filter/sapi_apache2.c
  138. +1 −4 sapi/apache2handler/sapi_apache2.c
  139. +0 −3  sapi/apache_hooks/mod_php5.c
  140. +3 −4 sapi/apache_hooks/php_apache.c
  141. +1 −4 sapi/apache_hooks/sapi_apache.c
  142. +12 −5 sapi/cgi/cgi_main.c
  143. +1 −10 sapi/cli/php_cli_readline.c
  144. +12 −5 sapi/fpm/fpm/fpm_main.c
  145. +0 −14 sapi/fpm/fpm/fpm_php.c
  146. +1 −35 sapi/litespeed/lsapi_main.c
  147. +2 −5 sapi/nsapi/nsapi.c
View
8 Makefile.global
@@ -79,20 +79,14 @@ PHP_TEST_SHARED_EXTENSIONS = ` \
. $$i; $(top_srcdir)/build/shtool echo -n -- " -d $(ZEND_EXT_TYPE)=$(top_builddir)/modules/$$dlname"; \
done; \
fi`
-PHP_DEPRECATED_DIRECTIVES_REGEX = '^(define_syslog_variables|register_(globals|long_arrays)?|safe_mode|magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
test: all
-@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
- if test "$$INI_FILE"; then \
- $(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
- else \
- echo > $(top_builddir)/tmp-php.ini; \
- fi; \
+ echo > $(top_builddir)/tmp-php.ini; \
INI_SCANNED_PATH=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \
if test "$$INI_SCANNED_PATH"; then \
INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \
- $(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \
fi; \
TEST_PHP_EXECUTABLE=$(PHP_EXECUTABLE) \
TEST_PHP_SRCDIR=$(top_srcdir) \
View
18 Zend/zend.c
@@ -221,11 +221,11 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
break;
case IS_BOOL:
if (Z_LVAL_P(expr)) {
- Z_STRLEN_P(expr_copy) = 1;
- Z_STRVAL_P(expr_copy) = estrndup("1", 1);
+ Z_STRLEN_P(expr_copy) = 4;
+ Z_STRVAL_P(expr_copy) = estrndup("true", 4);
} else {
- Z_STRLEN_P(expr_copy) = 0;
- Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
+ Z_STRLEN_P(expr_copy) = 5;
+ Z_STRVAL_P(expr_copy) = estrndup("false", 5);
}
break;
case IS_RESOURCE:
@@ -439,13 +439,9 @@ static FILE *zend_fopen_wrapper(const char *filename, char **opened_path TSRMLS_
/* }}} */
#ifdef ZTS
-static zend_bool asp_tags_default = 0;
-static zend_bool short_tags_default = 1;
static zend_bool ct_pass_ref_default = 1;
static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
#else
-# define asp_tags_default 0
-# define short_tags_default 1
# define ct_pass_ref_default 1
# define compiler_options_default ZEND_COMPILE_DEFAULT
#endif
@@ -453,9 +449,6 @@ static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
static void zend_set_default_compile_time_values(TSRMLS_D) /* {{{ */
{
/* default compile-time values */
- CG(asp_tags) = asp_tags_default;
- CG(short_tags) = short_tags_default;
- CG(allow_call_time_pass_reference) = ct_pass_ref_default;
CG(compiler_options) = compiler_options_default;
}
/* }}} */
@@ -733,9 +726,6 @@ void zend_post_startup(TSRMLS_D) /* {{{ */
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
- asp_tags_default = CG(asp_tags);
- short_tags_default = CG(short_tags);
- ct_pass_ref_default = CG(allow_call_time_pass_reference);
compiler_options_default = CG(compiler_options);
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
View
57 Zend/zend_API.c
@@ -2278,63 +2278,6 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt
}
/* }}} */
-/* Disabled functions support */
-
-/* {{{ proto void display_disabled_function(void)
-Dummy function which displays an error when a disabled function is called. */
-ZEND_API ZEND_FUNCTION(display_disabled_function)
-{
- zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name(TSRMLS_C));
-}
-/* }}} */
-
-static zend_function_entry disabled_function[] = {
- ZEND_FE(display_disabled_function, NULL)
- { NULL, NULL, NULL }
-};
-
-ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC) /* {{{ */
-{
- if (zend_hash_del(CG(function_table), function_name, function_name_length+1)==FAILURE) {
- return FAILURE;
- }
- disabled_function[0].fname = function_name;
- return zend_register_functions(NULL, disabled_function, CG(function_table), MODULE_PERSISTENT TSRMLS_CC);
-}
-/* }}} */
-
-static zend_object_value display_disabled_class(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
-{
- zend_object_value retval;
- zend_object *intern;
- retval = zend_objects_new(&intern, class_type TSRMLS_CC);
- ALLOC_HASHTABLE(intern->properties);
- zend_hash_init(intern->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name);
- return retval;
-}
-/* }}} */
-
-static const zend_function_entry disabled_class_new[] = {
- { NULL, NULL, NULL }
-};
-
-ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC) /* {{{ */
-{
- zend_class_entry disabled_class;
-
- zend_str_tolower(class_name, class_name_length);
- if (zend_hash_del(CG(class_table), class_name, class_name_length+1)==FAILURE) {
- return FAILURE;
- }
- INIT_OVERLOADED_CLASS_ENTRY_EX(disabled_class, class_name, class_name_length, disabled_class_new, NULL, NULL, NULL, NULL, NULL);
- disabled_class.create_object = display_disabled_class;
- disabled_class.name_length = class_name_length;
- zend_register_internal_class(&disabled_class TSRMLS_CC);
- return SUCCESS;
-}
-/* }}} */
-
static int zend_is_callable_check_class(const char *name, int name_len, zend_fcall_info_cache *fcc, int *strict_class, char **error TSRMLS_DC) /* {{{ */
{
int ret = 0;
View
4 Zend/zend_API.h
@@ -265,8 +265,6 @@ ZEND_API int zend_register_class_alias_ex(const char *name, int name_len, zend_c
#define zend_register_ns_class_alias(ns, name, ce) \
zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce TSRMLS_DC)
-ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC);
-ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC);
ZEND_API void zend_wrong_param_count(TSRMLS_D);
@@ -496,8 +494,6 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
#define add_method(arg, key, method) add_assoc_function((arg), (key), (method))
-ZEND_API ZEND_FUNCTION(display_disabled_function);
-ZEND_API ZEND_FUNCTION(display_disabled_class);
END_EXTERN_C()
#if ZEND_DEBUG
View
9 Zend/zend_builtin_functions.c
@@ -1290,15 +1290,6 @@ ZEND_FUNCTION(function_exists)
efree(lcname);
- /*
- * A bit of a hack, but not a bad one: we see if the handler of the function
- * is actually one that displays "function is disabled" message.
- */
- if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
- func->internal_function.handler == zif_display_disabled_function) {
- retval = 0;
- }
-
RETURN_BOOL(retval);
}
/* }}} */
View
38 Zend/zend_compile.c
@@ -2079,7 +2079,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
function_ptr = *function_ptr_ptr;
- if (original_op == ZEND_SEND_REF && !CG(allow_call_time_pass_reference)) {
+ if (original_op == ZEND_SEND_REF) {
if (function_ptr &&
function_ptr->common.function_name &&
function_ptr->common.type == ZEND_USER_FUNCTION &&
@@ -4431,6 +4431,42 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
}
/* }}} */
+void zend_do_sizeof(int type, znode *result, znode *arg TSRMLS_DC) {
+
+ if (arg->op_type == IS_CONST) {
+
+ if (type == ZEND_STRLEN) {
+ result->op_type = IS_CONST;
+ Z_TYPE(result->u.constant) = IS_LONG;
+ Z_LVAL(result->u.constant) = Z_STRLEN(arg->u.constant);
+ } else {
+ zend_error(E_COMPILE_ERROR, "count() expects an array, constant given");
+ }
+
+ } else {
+
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+ opline->result.op_type = IS_TMP_VAR;
+ opline->result.u.var = get_temporary_variable(CG(active_op_array));
+ opline->op1 = *arg;
+
+ opline->opcode = ZEND_SIZEOF;
+ opline->extended_value|= type;
+ SET_UNUSED(opline->op2);
+ *result = opline->result;
+ }
+}
+/* }}} */
+
+void zend_do_ifset(znode *result, znode *variable TSRMLS_DC) {
+
+
+ fprintf(stderr, "IFSET: %i\n", variable->op_type);
+
+}
+/* }}} */
+
void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC) /* {{{ */
{
int last_op_number = get_next_op_number(CG(active_op_array));
View
12 Zend/zend_compile.h
@@ -504,6 +504,9 @@ void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC
void zend_do_unset(const znode *variable TSRMLS_DC);
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
+void zend_do_ifset(znode *result, znode *variable TSRMLS_DC);
+
+void zend_do_sizeof(int type, znode *result, znode *variable TSRMLS_DC);
void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC);
@@ -681,8 +684,13 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_ISSET (1<<0)
#define ZEND_ISEMPTY (1<<1)
-#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY)
-#define ZEND_QUICK_SET (1<<2)
+#define ZEND_EXISTS (1<<2)
+#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY | ZEND_EXISTS)
+#define ZEND_QUICK_SET (1<<3)
+
+
+#define ZEND_STRLEN (1<<0)
+#define ZEND_COUNT (1<<1)
#define ZEND_CT (1<<0)
#define ZEND_RT (1<<1)
View
19 Zend/zend_constants.c
@@ -118,27 +118,8 @@ void zend_register_standard_constants(TSRMLS_D)
/* true/false constants */
{
zend_constant c;
-
- c.flags = CONST_PERSISTENT | CONST_CT_SUBST;
c.module_number = 0;
- c.name = zend_strndup(ZEND_STRL("TRUE"));
- c.name_len = sizeof("TRUE");
- c.value.value.lval = 1;
- c.value.type = IS_BOOL;
- zend_register_constant(&c TSRMLS_CC);
-
- c.name = zend_strndup(ZEND_STRL("FALSE"));
- c.name_len = sizeof("FALSE");
- c.value.value.lval = 0;
- c.value.type = IS_BOOL;
- zend_register_constant(&c TSRMLS_CC);
-
- c.name = zend_strndup(ZEND_STRL("NULL"));
- c.name_len = sizeof("NULL");
- c.value.type = IS_NULL;
- zend_register_constant(&c TSRMLS_CC);
-
c.flags = CONST_PERSISTENT;
c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE"));
View
22 Zend/zend_execute.c
@@ -607,18 +607,20 @@ static inline int zend_assign_to_string_offset(const temp_variable *T, const zva
{
if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
- if (((int)T->str_offset.offset < 0)) {
+ int off = T->str_offset.offset;
+
+ if (off < 0 && (off+= Z_STRLEN_P(T->str_offset.str)) < 0) {
zend_error(E_WARNING, "Illegal string offset: %d", T->str_offset.offset);
return 0;
}
- if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
- Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
+ if (off >= Z_STRLEN_P(T->str_offset.str)) {
+ Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), off+1+1);
memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
' ',
- T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
- Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
- Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
+ off - Z_STRLEN_P(T->str_offset.str));
+ Z_STRVAL_P(T->str_offset.str)[off+1] = 0;
+ Z_STRLEN_P(T->str_offset.str) = off+1;
}
if (Z_TYPE_P(value) != IS_STRING) {
@@ -628,10 +630,10 @@ static inline int zend_assign_to_string_offset(const temp_variable *T, const zva
zval_copy_ctor(&tmp);
}
convert_to_string(&tmp);
- Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0];
+ Z_STRVAL_P(T->str_offset.str)[off] = Z_STRVAL(tmp)[0];
STR_FREE(Z_STRVAL(tmp));
} else {
- Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0];
+ Z_STRVAL_P(T->str_offset.str)[off] = Z_STRVAL_P(value)[0];
if (value_type == IS_TMP_VAR) {
/* we can safely free final_value here
* because separation is done only
@@ -1067,7 +1069,9 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
dim = &tmp;
}
if (result) {
- if ((Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) && type != BP_VAR_IS) {
+ if (Z_LVAL_P(dim) < 0 && type != BP_VAR_IS && (Z_LVAL_P(dim)+= Z_STRLEN_P(container)) < 0) {
+ zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim)-= Z_STRLEN_P(container));
+ } else if (Z_STRLEN_P(container) <= Z_LVAL_P(dim) < 0 && type != BP_VAR_IS) {
zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
}
result->str_offset.str = container;
View
1  Zend/zend_execute.h
@@ -46,6 +46,7 @@ typedef union _temp_variable {
zval *ptr;
zend_bool fcall_returned_reference;
HashPointer fe_pos;
+ long pos;
} fe;
zend_class_entry *class_entry;
} temp_variable;
View
3  Zend/zend_globals.h
@@ -102,9 +102,6 @@ struct _zend_compiler_globals {
HashTable *auto_globals;
zend_bool in_compilation;
- zend_bool short_tags;
- zend_bool asp_tags;
- zend_bool allow_call_time_pass_reference;
zend_declarables declarables;
View
3  Zend/zend_iterators.c
@@ -87,6 +87,9 @@ ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
}
return ZEND_ITER_INVALID;
+ case IS_STRING:
+ return ZEND_ITER_STRING;
+
case IS_ARRAY:
if (HASH_OF(array_ptr)) {
return ZEND_ITER_PLAIN_ARRAY;
View
3  Zend/zend_iterators.h
@@ -71,7 +71,8 @@ enum zend_object_iterator_kind {
ZEND_ITER_INVALID,
ZEND_ITER_PLAIN_ARRAY,
ZEND_ITER_PLAIN_OBJECT,
- ZEND_ITER_OBJECT
+ ZEND_ITER_OBJECT,
+ ZEND_ITER_STRING
};
BEGIN_EXTERN_C()
View
41 Zend/zend_language_parser.h
@@ -1,24 +1,23 @@
-/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* A Bison parser, made by GNU Bison 2.4.1. */
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
+
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -29,10 +28,11 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
-
+
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@@ -161,7 +161,11 @@
T_NAMESPACE = 377,
T_NS_C = 378,
T_DIR = 379,
- T_NS_SEPARATOR = 380
+ T_NS_SEPARATOR = 380,
+ T_STRLEN = 381,
+ T_COUNT = 382,
+ T_IFSET = 383,
+ T_EXISTS = 384
};
#endif
/* Tokens. */
@@ -288,16 +292,19 @@
#define T_NS_C 378
#define T_DIR 379
#define T_NS_SEPARATOR 380
-
-
+#define T_STRLEN 381
+#define T_COUNT 382
+#define T_IFSET 383
+#define T_EXISTS 384
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
#endif
+
View
22 Zend/zend_language_parser.y
@@ -119,6 +119,10 @@
%token T_UNSET
%token T_ISSET
%token T_EMPTY
+%token T_STRLEN
+%token T_COUNT
+%token T_IFSET
+%token T_EXISTS
%token T_HALT_COMPILER
%token T_CLASS
%token T_INTERFACE
@@ -645,6 +649,7 @@ expr_without_variable:
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
| scalar { $$ = $1; }
| T_ARRAY '(' array_pair_list ')' { $$ = $3; }
+ | '[' array_pair_list ']' { $$ = $2; }
| '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
| function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type TSRMLS_CC); }
@@ -981,7 +986,11 @@ encaps_var_offset:
internal_functions_in_yacc:
T_ISSET '(' isset_variables ')' { $$ = $3; }
- | T_EMPTY '(' variable ')' { zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 TSRMLS_CC); }
+ | T_IFSET '(' ifset_variables ')' { $$ = $3; }
+ | T_EXISTS '(' exists_variables ')' { $$ = $3; }
+ | T_EMPTY '(' variable ')'{ zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 TSRMLS_CC); }
+ | T_STRLEN '(' expr ')' { zend_do_sizeof(ZEND_STRLEN, &$$, &$3 TSRMLS_CC); }
+ | T_COUNT '(' expr ')' { zend_do_sizeof(ZEND_COUNT, &$$, &$3 TSRMLS_CC); }
| T_INCLUDE expr { zend_do_include_or_eval(ZEND_INCLUDE, &$$, &$2 TSRMLS_CC); }
| T_INCLUDE_ONCE expr { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 TSRMLS_CC); }
| T_EVAL '(' expr ')' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); }
@@ -990,10 +999,19 @@ internal_functions_in_yacc:
;
isset_variables:
- variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); }
+ variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); }
| isset_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } variable { znode tmp; zend_do_isset_or_isempty(ZEND_ISSET, &tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2 TSRMLS_CC); }
;
+ifset_variables:
+ ifset_variables ',' expr { zend_do_add_array_element(&$$, &$3, NULL, 0 TSRMLS_CC); }
+ | expr { zend_do_init_array(&$$, &$1, NULL, 0 TSRMLS_CC); }
+
+exists_variables:
+ variable { zend_do_isset_or_isempty(ZEND_EXISTS, &$$, &$1 TSRMLS_CC); }
+ | exists_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } variable { znode tmp; zend_do_isset_or_isempty(ZEND_EXISTS, &tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2 TSRMLS_CC); }
+;
+
class_constant:
class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT, 0 TSRMLS_CC); }
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT, 0 TSRMLS_CC); }
View
163 Zend/zend_language_scanner.l
@@ -859,6 +859,7 @@ LNUM [0-9]+
DNUM ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM})
HNUM "0x"[0-9a-fA-F]+
+BNUM "0b"[01]+
LABEL [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
WHITESPACE [ \n\r\t]+
TABS_AND_SPACES [ \t]*
@@ -922,6 +923,22 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_WHILE;
}
+<ST_IN_SCRIPTING>"count" {
+ return T_COUNT;
+}
+
+<ST_IN_SCRIPTING>"strlen" {
+ return T_STRLEN;
+}
+
+<ST_IN_SCRIPTING>"xifset" {
+ return T_IFSET;
+}
+
+<ST_IN_SCRIPTING>"exists" {
+ return T_EXISTS;
+}
+
<ST_IN_SCRIPTING>"endwhile" {
return T_ENDWHILE;
}
@@ -1369,6 +1386,47 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
}
+<ST_IN_SCRIPTING>{BNUM} {
+ char *hex = yytext + 2; /* Skip "0x" */
+ int len = yyleng - 2;
+
+ /* Skip any leading 0s */
+ while (*hex == '0') {
+ hex++;
+ len--;
+ }
+
+ if (len < SIZEOF_LONG * 2 * 4) {
+ zendlval->value.lval = strtol(hex, NULL, 2);
+ zendlval->type = IS_LONG;
+ return T_LNUMBER;
+ } else {
+ zendlval->value.dval = zend_bin_strtod(hex, NULL);
+ zendlval->type = IS_DOUBLE;
+ return T_DNUMBER;
+ }
+}
+
+<ST_IN_SCRIPTING>"false" {
+
+ zendlval->value.lval = 0;
+ zendlval->type = IS_BOOL;
+ return T_LNUMBER;
+}
+
+<ST_IN_SCRIPTING>"true" {
+
+ zendlval->value.lval = 1;
+ zendlval->type = IS_BOOL;
+ return T_LNUMBER;
+}
+
+<ST_IN_SCRIPTING>"null" {
+
+ zendlval->type = IS_NULL;
+ return T_LNUMBER;
+}
+
<ST_VAR_OFFSET>[0]|([1-9][0-9]*) { /* Offset could be treated as a long */
if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
zendlval->value.lval = strtol(yytext, NULL, 10);
@@ -1381,7 +1439,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_NUM_STRING;
}
-<ST_VAR_OFFSET>{LNUM}|{HNUM} { /* Offset must be treated as a string */
+<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */
zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
zendlval->value.str.len = yyleng;
zendlval->type = IS_STRING;
@@ -1502,85 +1560,25 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_NS_C;
}
-<INITIAL>"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"'php'"){WHITESPACE}*">" {
- YYCTYPE *bracket = zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
-
- if (bracket != SCNG(yy_text)) {
- /* Handle previously scanned HTML, as possible <script> tags found are assumed to not be PHP's */
- YYCURSOR = bracket;
- goto inline_html;
- }
- HANDLE_NEWLINES(yytext, yyleng);
- zendlval->value.str.val = yytext; /* no copying - intentional */
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
+<INITIAL>"<?php=" {
+ zendlval->value.str.val = yytext; /* no copying - intentional */
+ zendlval->value.str.len = yyleng;
+ zendlval->type = IS_STRING;
+ BEGIN(ST_IN_SCRIPTING);
+ return T_OPEN_TAG_WITH_ECHO;
}
-<INITIAL>"<%=" {
- if (CG(asp_tags)) {
- zendlval->value.str.val = yytext; /* no copying - intentional */
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG_WITH_ECHO;
- } else {
- goto inline_char_handler;
- }
-}
-
-
-<INITIAL>"<?=" {
- if (CG(short_tags)) {
- zendlval->value.str.val = yytext; /* no copying - intentional */
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG_WITH_ECHO;
- } else {
- goto inline_char_handler;
- }
-}
-
-
-<INITIAL>"<%" {
- if (CG(asp_tags)) {
- zendlval->value.str.val = yytext; /* no copying - intentional */
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
- } else {
- goto inline_char_handler;
- }
-}
-
-
-<INITIAL>"<?php"([ \t]|{NEWLINE}) {
+<INITIAL>"<?php" {
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
zendlval->type = IS_STRING;
- HANDLE_NEWLINE(yytext[yyleng-1]);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
}
-<INITIAL>"<?" {
- if (CG(short_tags)) {
- zendlval->value.str.val = yytext; /* no copying - intentional */
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- BEGIN(ST_IN_SCRIPTING);
- return T_OPEN_TAG;
- } else {
- goto inline_char_handler;
- }
-}
-
<INITIAL>{ANY_CHAR} {
if (YYCURSOR > YYLIMIT) {
return 0;
@@ -1596,12 +1594,7 @@ inline_char_handler:
if (YYCURSOR < YYLIMIT) {
switch (*YYCURSOR) {
case '?':
- if (CG(short_tags) || !strncasecmp(YYCURSOR + 1, "php", 3)) { /* Assume [ \t\n\r] follows "php" */
- break;
- }
- continue;
- case '%':
- if (CG(asp_tags)) {
+ if (!strncasecmp(YYCURSOR + 1, "php", 3)) { /* Assume [ \t\n\r] follows "php" */
break;
}
continue;
@@ -1709,11 +1702,6 @@ inline_html:
case '\n':
CG(zend_lineno)++;
break;
- case '%':
- if (!CG(asp_tags)) {
- continue;
- }
- /* fall through */
case '?':
if (*YYCURSOR == '>') {
YYCURSOR--;
@@ -1766,7 +1754,7 @@ inline_html:
return T_COMMENT;
}
-<ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {
+<ST_IN_SCRIPTING>("?>"){NEWLINE}? {
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
zendlval->type = IS_STRING;
@@ -1774,21 +1762,6 @@ inline_html:
return T_CLOSE_TAG; /* implicit ';' at php-end tag */
}
-
-<ST_IN_SCRIPTING>"%>"{NEWLINE}? {
- if (CG(asp_tags)) {
- BEGIN(INITIAL);
- zendlval->value.str.len = yyleng;
- zendlval->type = IS_STRING;
- zendlval->value.str.val = yytext; /* no copying - intentional */
- return T_CLOSE_TAG; /* implicit ';' at php-end tag */
- } else {
- yyless(1);
- return yytext[0];
- }
-}
-
-
<ST_IN_SCRIPTING>b?['] {
register char *s, *t;
char *end;
View
27 Zend/zend_strtod.c
@@ -2615,6 +2615,33 @@ ZEND_API double zend_hex_strtod(const char *str, char **endptr)
return value;
}
+ZEND_API double zend_bin_strtod(const char *str, char **endptr)
+{
+ const char *s = str;
+ char c;
+ int any = 0;
+ double value = 0;
+
+ if (*s == '0' && (s[1] == 'b' || s[1] == 'B')) {
+ s += 2;
+ }
+
+ while ((c = *s++)) {
+ if (!(c >= '0' && c <= '1')) {
+ break;
+ }
+
+ any = 1;
+ value = value * 2 + c - '0';
+ }
+
+ if (endptr != NULL) {
+ *endptr = (char *)(any ? s - 1 : str);
+ }
+
+ return value;
+}
+
ZEND_API double zend_oct_strtod(const char *str, char **endptr)
{
const char *s = str;
View
1  Zend/zend_strtod.h
@@ -29,6 +29,7 @@ ZEND_API void zend_freedtoa(char *s);
ZEND_API char * zend_dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve);
ZEND_API double zend_strtod(const char *s00, char **se);
ZEND_API double zend_hex_strtod(const char *str, char **endptr);
+ZEND_API double zend_bin_strtod(const char *str, char **endptr);
ZEND_API double zend_oct_strtod(const char *str, char **endptr);
ZEND_API int zend_startup_strtod(void);
ZEND_API int zend_shutdown_strtod(void);
View
121 Zend/zend_vm_def.h
@@ -922,6 +922,74 @@ ZEND_VM_HANDLER(41, ZEND_PRINT, CONST|TMP|VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ECHO);
}
+ZEND_VM_HANDLER(154, ZEND_SIZEOF, CONST|TMP|VAR|CV, ANY)
+{
+ zend_op *opline = EX(opline);
+ zend_free_op free_op1;
+ zval z_copy, x_copy;
+ zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);
+
+ int use_copy;
+
+ Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
+
+
+ if (opline->extended_value & ZEND_STRLEN) {
+
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+
+ zend_make_printable_zval(&z_copy, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(z_copy);
+ }
+ zval_dtor(&z_copy);
+
+ } else if (Z_TYPE_P(z) == IS_ARRAY) {
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, array given");
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ } else {
+ zend_make_printable_zval(z, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN_P(z);
+ }
+ }
+
+ } else {
+
+ switch (Z_TYPE_P(z)) {
+ case IS_NULL:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ break;
+ case IS_ARRAY:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = zend_hash_num_elements(Z_ARRVAL_P(z));
+ break;
+ case IS_OBJECT: {
+
+ /* first, we check if the handler is defined */
+ if (Z_OBJ_HT_P(z)->count_elements) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ if (SUCCESS == Z_OBJ_HT(*z)->count_elements(z, &Z_LVAL(EX_T(opline->result.u.var).tmp_var) TSRMLS_CC)) {
+ break;
+ }
+ }
+ }
+ default:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ break;
+ }
+
+ }
+
+ FREE_OP1();
+ ZEND_VM_NEXT_OPCODE();
+}
+
ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type)
{
zend_op *opline = EX(opline);
@@ -3639,7 +3707,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC);
if (EG(exception)) {
- Z_DELREF_P(array_ptr);
+ Z_DELREF_P(array_ptr);
zval_ptr_dtor(&array_ptr);
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
FREE_OP1_VAR_PTR();
@@ -3661,6 +3729,17 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
iter->index = -1; /* will be set to 0 before using next handler */
+
+ } else if (IS_STRING == Z_TYPE_P(array_ptr)) {
+
+ is_empty = (0 == Z_STRLEN_P(array_ptr));
+ EX_T(opline->result.u.var).fe.pos = 0;
+
+ if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
+ zend_error(E_WARNING, "Ref-Variables are not allowed with string arguments for foreach()");
+ is_empty = 1;
+ }
+
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
@@ -3713,6 +3792,8 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
int key_type = 0;
zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
+ char c[] = {0, 0};
+
switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
default:
case ZEND_ITER_INVALID:
@@ -3760,6 +3841,27 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
break;
+ case ZEND_ITER_STRING:
+
+ if (EX_T(opline->op1.u.var).fe.pos == Z_STRLEN_P(array)) {
+ /* reached end of iteration */
+ ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
+ }
+
+ *c = Z_STRVAL_P(array)[EX_T(opline->op1.u.var).fe.pos];
+
+ EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+ ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+ INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+ ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, c, 1, 1);
+
+ key_type = HASH_KEY_IS_LONG;
+ int_key = EX_T(opline->op1.u.var).fe.pos;
+
+ EX_T(opline->op1.u.var).fe.pos++;
+
+ goto assign_key;
+
case ZEND_ITER_OBJECT:
/* !iter happens from exception */
if (iter && ++iter->index > 0) {
@@ -3818,6 +3920,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
PZVAL_LOCK(*value);
}
+assign_key:
if (use_key) {
zend_op *op_data = opline+1;
zval *key = &EX_T(op_data->result.u.var).tmp_var;
@@ -3894,6 +3997,9 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
+ case ZEND_EXISTS:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -3956,11 +4062,13 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -4011,14 +4119,18 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -4033,6 +4145,7 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
View
539 Zend/zend_vm_execute.h
@@ -1317,6 +1317,73 @@ static int ZEND_FASTCALL ZEND_PRINT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
return ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_SIZEOF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_op *opline = EX(opline);
+
+ zval z_copy, x_copy;
+ zval *z = &opline->op1.u.constant;
+
+ int use_copy;
+
+ Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
+
+
+ if (opline->extended_value & ZEND_STRLEN) {
+
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+
+ zend_make_printable_zval(&z_copy, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(z_copy);
+ }
+ zval_dtor(&z_copy);
+
+ } else if (Z_TYPE_P(z) == IS_ARRAY) {
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, array given");
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ } else {
+ zend_make_printable_zval(z, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN_P(z);
+ }
+ }
+
+ } else {
+
+ switch (Z_TYPE_P(z)) {
+ case IS_NULL:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ break;
+ case IS_ARRAY:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = zend_hash_num_elements(Z_ARRVAL_P(z));
+ break;
+ case IS_OBJECT: {
+
+ /* first, we check if the handler is defined */
+ if (Z_OBJ_HT_P(z)->count_elements) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ if (SUCCESS == Z_OBJ_HT(*z)->count_elements(z, &Z_LVAL(EX_T(opline->result.u.var).tmp_var) TSRMLS_CC)) {
+ break;
+ }
+ }
+ }
+ default:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ break;
+ }
+
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@@ -2172,7 +2239,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC);
if (EG(exception)) {
- Z_DELREF_P(array_ptr);
+ Z_DELREF_P(array_ptr);
zval_ptr_dtor(&array_ptr);
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
@@ -2194,6 +2261,17 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
ZEND_VM_NEXT_OPCODE();
}
iter->index = -1; /* will be set to 0 before using next handler */
+
+ } else if (IS_STRING == Z_TYPE_P(array_ptr)) {
+
+ is_empty = (0 == Z_STRLEN_P(array_ptr));
+ EX_T(opline->result.u.var).fe.pos = 0;
+
+ if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
+ zend_error(E_WARNING, "Ref-Variables are not allowed with string arguments for foreach()");
+ is_empty = 1;
+ }
+
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
@@ -2283,6 +2361,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
+ case ZEND_EXISTS:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -4600,6 +4681,74 @@ static int ZEND_FASTCALL ZEND_PRINT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
return ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_SIZEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_op *opline = EX(opline);
+ zend_free_op free_op1;
+ zval z_copy, x_copy;
+ zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+ int use_copy;
+
+ Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
+
+
+ if (opline->extended_value & ZEND_STRLEN) {
+
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+
+ zend_make_printable_zval(&z_copy, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(z_copy);
+ }
+ zval_dtor(&z_copy);
+
+ } else if (Z_TYPE_P(z) == IS_ARRAY) {
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, array given");
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ } else {
+ zend_make_printable_zval(z, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN_P(z);
+ }
+ }
+
+ } else {
+
+ switch (Z_TYPE_P(z)) {
+ case IS_NULL:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ break;
+ case IS_ARRAY:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = zend_hash_num_elements(Z_ARRVAL_P(z));
+ break;
+ case IS_OBJECT: {
+
+ /* first, we check if the handler is defined */
+ if (Z_OBJ_HT_P(z)->count_elements) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ if (SUCCESS == Z_OBJ_HT(*z)->count_elements(z, &Z_LVAL(EX_T(opline->result.u.var).tmp_var) TSRMLS_CC)) {
+ break;
+ }
+ }
+ }
+ default:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ break;
+ }
+
+ }
+
+ zval_dtor(free_op1.var);
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@@ -5446,7 +5595,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC);
if (EG(exception)) {
- Z_DELREF_P(array_ptr);
+ Z_DELREF_P(array_ptr);
zval_ptr_dtor(&array_ptr);
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
@@ -5468,6 +5617,17 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_NEXT_OPCODE();
}
iter->index = -1; /* will be set to 0 before using next handler */
+
+ } else if (IS_STRING == Z_TYPE_P(array_ptr)) {
+
+ is_empty = (0 == Z_STRLEN_P(array_ptr));
+ EX_T(opline->result.u.var).fe.pos = 0;
+
+ if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
+ zend_error(E_WARNING, "Ref-Variables are not allowed with string arguments for foreach()");
+ is_empty = 1;
+ }
+
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
@@ -5557,6 +5717,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HA
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
+ case ZEND_EXISTS:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -7848,6 +8011,74 @@ static int ZEND_FASTCALL ZEND_PRINT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
return ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_SIZEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_op *opline = EX(opline);
+ zend_free_op free_op1;
+ zval z_copy, x_copy;
+ zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+ int use_copy;
+
+ Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
+
+
+ if (opline->extended_value & ZEND_STRLEN) {
+
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+
+ zend_make_printable_zval(&z_copy, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(z_copy);
+ }
+ zval_dtor(&z_copy);
+
+ } else if (Z_TYPE_P(z) == IS_ARRAY) {
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, array given");
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ } else {
+ zend_make_printable_zval(z, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN_P(z);
+ }
+ }
+
+ } else {
+
+ switch (Z_TYPE_P(z)) {
+ case IS_NULL:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ break;
+ case IS_ARRAY:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = zend_hash_num_elements(Z_ARRVAL_P(z));
+ break;
+ case IS_OBJECT: {
+
+ /* first, we check if the handler is defined */
+ if (Z_OBJ_HT_P(z)->count_elements) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ if (SUCCESS == Z_OBJ_HT(*z)->count_elements(z, &Z_LVAL(EX_T(opline->result.u.var).tmp_var) TSRMLS_CC)) {
+ break;
+ }
+ }
+ }
+ default:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ break;
+ }
+
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@@ -8815,7 +9046,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC);
if (EG(exception)) {
- Z_DELREF_P(array_ptr);
+ Z_DELREF_P(array_ptr);
zval_ptr_dtor(&array_ptr);
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -8837,6 +9068,17 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_NEXT_OPCODE();
}
iter->index = -1; /* will be set to 0 before using next handler */
+
+ } else if (IS_STRING == Z_TYPE_P(array_ptr)) {
+
+ is_empty = (0 == Z_STRLEN_P(array_ptr));
+ EX_T(opline->result.u.var).fe.pos = 0;
+
+ if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
+ zend_error(E_WARNING, "Ref-Variables are not allowed with string arguments for foreach()");
+ is_empty = 1;
+ }
+
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
@@ -8889,6 +9131,8 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
int key_type = 0;
zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
+ char c[] = {0, 0};
+
switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
default:
case ZEND_ITER_INVALID:
@@ -8936,6 +9180,27 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.u.var).fe.fe_pos);
break;
+ case ZEND_ITER_STRING:
+
+ if (EX_T(opline->op1.u.var).fe.pos == Z_STRLEN_P(array)) {
+ /* reached end of iteration */
+ ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.u.opline_num);
+ }
+
+ *c = Z_STRVAL_P(array)[EX_T(opline->op1.u.var).fe.pos];
+
+ EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+ ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+ INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+ ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, c, 1, 1);
+
+ key_type = HASH_KEY_IS_LONG;
+ int_key = EX_T(opline->op1.u.var).fe.pos;
+
+ EX_T(opline->op1.u.var).fe.pos++;
+
+ goto assign_key;
+
case ZEND_ITER_OBJECT:
/* !iter happens from exception */
if (iter && ++iter->index > 0) {
@@ -8994,6 +9259,7 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(*value);
}
+assign_key:
if (use_key) {
zend_op *op_data = opline+1;
zval *key = &EX_T(op_data->result.u.var).tmp_var;
@@ -9070,6 +9336,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HA
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
+ case ZEND_EXISTS:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -10862,11 +11131,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -10917,14 +11188,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -10939,6 +11214,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -12611,11 +12887,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -12666,14 +12944,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -12688,6 +12970,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -14411,11 +14694,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -14466,14 +14751,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -14488,6 +14777,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -16797,11 +17087,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -16852,14 +17144,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -16874,6 +17170,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -17987,11 +18284,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -18042,14 +18341,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -18064,6 +18367,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -19044,11 +19348,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -19099,14 +19405,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -19121,6 +19431,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -20101,11 +20412,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -20156,14 +20469,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -20178,6 +20495,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -21417,11 +21735,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -21472,14 +21792,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -21494,6 +21818,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -21720,6 +22045,73 @@ static int ZEND_FASTCALL ZEND_PRINT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
return ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_SIZEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_op *opline = EX(opline);
+
+ zval z_copy, x_copy;
+ zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
+
+ int use_copy;
+
+ Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;
+
+
+ if (opline->extended_value & ZEND_STRLEN) {
+
+ if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
+
+ zend_make_printable_zval(&z_copy, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(z_copy);
+ }
+ zval_dtor(&z_copy);
+
+ } else if (Z_TYPE_P(z) == IS_ARRAY) {
+ zend_error(E_WARNING, "strlen() expects parameter 1 to be string, array given");
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ } else {
+ zend_make_printable_zval(z, &x_copy, &use_copy);
+ if (use_copy) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN(x_copy);
+ zval_dtor(&x_copy);
+ } else {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = Z_STRLEN_P(z);
+ }
+ }
+
+ } else {
+
+ switch (Z_TYPE_P(z)) {
+ case IS_NULL:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
+ break;
+ case IS_ARRAY:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = zend_hash_num_elements(Z_ARRVAL_P(z));
+ break;
+ case IS_OBJECT: {
+
+ /* first, we check if the handler is defined */
+ if (Z_OBJ_HT_P(z)->count_elements) {
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ if (SUCCESS == Z_OBJ_HT(*z)->count_elements(z, &Z_LVAL(EX_T(opline->result.u.var).tmp_var) TSRMLS_CC)) {
+ break;
+ }
+ }
+ }
+ default:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 1;
+ break;
+ }
+
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@@ -22677,7 +23069,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC);
if (EG(exception)) {
- Z_DELREF_P(array_ptr);
+ Z_DELREF_P(array_ptr);
zval_ptr_dtor(&array_ptr);
if (opline->extended_value & ZEND_FE_RESET_VARIABLE) {
@@ -22699,6 +23091,17 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
ZEND_VM_NEXT_OPCODE();
}
iter->index = -1; /* will be set to 0 before using next handler */
+
+ } else if (IS_STRING == Z_TYPE_P(array_ptr)) {
+
+ is_empty = (0 == Z_STRLEN_P(array_ptr));
+ EX_T(opline->result.u.var).fe.pos = 0;
+
+ if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
+ zend_error(E_WARNING, "Ref-Variables are not allowed with string arguments for foreach()");
+ is_empty = 1;
+ }
+
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
@@ -22788,6 +23191,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HAN
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value & ZEND_ISSET_ISEMPTY_MASK) {
+ case ZEND_EXISTS:
+ Z_LVAL(EX_T(opline->result.u.var).tmp_var) = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = 0;
@@ -24415,11 +24821,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -24470,14 +24878,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -24492,6 +24904,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -26055,11 +26468,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
-
break;
}
switch (opline->extended_value) {
+ case ZEND_EXISTS:
+ result = isset;
+ break;
case ZEND_ISSET:
if (isset && Z_TYPE_PP(value) == IS_NULL) {
result = 0;
@@ -26110,14 +26525,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
offset = &tmp;
}
if (Z_TYPE_P(offset) == IS_LONG) {
+
+ int off = offset->value.lval < 0 ? -1 - offset->value.lval : offset->value.lval;
+
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (off >= 0 && off < Z_STRLEN_PP(container)) {
result = 1;
}
break;
case ZEND_ISEMPTY:
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (off >= 0 && off < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
result = 1;
}
break;
@@ -26132,6 +26551,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
switch (opline->extended_value) {
+ case ZEND_EXISTS:
case ZEND_ISSET:
Z_LVAL(EX_T(opline->result.u.var).tmp_var) = result;
break;
@@ -27745,11 +28165,13 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");