1999-04-08 02:10:10 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Zend Engine |
|
|
|
|
+----------------------------------------------------------------------+
|
2018-01-02 12:57:58 +08:00
|
|
|
| Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
|
1999-04-08 02:10:10 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2001-12-11 23:16:21 +08:00
|
|
|
| This source file is subject to version 2.00 of the Zend license, |
|
1999-07-16 22:58:16 +08:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
2003-06-11 04:04:29 +08:00
|
|
|
| available through the world-wide-web at the following url: |
|
2001-12-11 23:16:21 +08:00
|
|
|
| http://www.zend.com/license/2_00.txt. |
|
1999-07-16 22:58:16 +08:00
|
|
|
| If you did not receive a copy of the Zend license and are unable to |
|
|
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
|
|
| license@zend.com so we can mail you a copy immediately. |
|
1999-04-08 02:10:10 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Authors: Andi Gutmans <andi@zend.com> |
|
|
|
|
| Zeev Suraski <zeev@zend.com> |
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
2003-02-01 09:49:15 +08:00
|
|
|
/* $Id$ */
|
1999-04-08 02:18:16 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
#include "zend.h"
|
|
|
|
#include "zend_extensions.h"
|
2001-02-27 02:18:34 +08:00
|
|
|
#include "zend_modules.h"
|
1999-04-08 02:10:10 +08:00
|
|
|
#include "zend_constants.h"
|
|
|
|
#include "zend_list.h"
|
1999-06-11 18:44:26 +08:00
|
|
|
#include "zend_API.h"
|
2004-02-12 18:38:14 +08:00
|
|
|
#include "zend_exceptions.h"
|
1999-09-20 20:24:39 +08:00
|
|
|
#include "zend_builtin_functions.h"
|
2000-12-27 23:43:15 +08:00
|
|
|
#include "zend_ini.h"
|
2008-04-17 18:21:38 +08:00
|
|
|
#include "zend_vm.h"
|
2010-04-24 21:32:30 +08:00
|
|
|
#include "zend_dtrace.h"
|
2013-10-17 16:40:43 +08:00
|
|
|
#include "zend_virtual_cwd.h"
|
2015-10-07 17:35:43 +08:00
|
|
|
#include "zend_smart_str.h"
|
2016-12-19 00:53:27 +08:00
|
|
|
#include "zend_smart_string.h"
|
2018-01-16 18:27:18 +08:00
|
|
|
#include "zend_cpuinfo.h"
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
2017-01-16 04:27:05 +08:00
|
|
|
ZEND_API int compiler_globals_id;
|
|
|
|
ZEND_API int executor_globals_id;
|
|
|
|
static HashTable *global_function_table = NULL;
|
|
|
|
static HashTable *global_class_table = NULL;
|
|
|
|
static HashTable *global_constants_table = NULL;
|
|
|
|
static HashTable *global_auto_globals_table = NULL;
|
|
|
|
static HashTable *global_persistent_list = NULL;
|
|
|
|
ZEND_TSRMLS_CACHE_DEFINE()
|
2007-11-03 03:40:39 +08:00
|
|
|
# define GLOBAL_FUNCTION_TABLE global_function_table
|
|
|
|
# define GLOBAL_CLASS_TABLE global_class_table
|
|
|
|
# define GLOBAL_CONSTANTS_TABLE global_constants_table
|
|
|
|
# define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
|
1999-04-21 11:49:09 +08:00
|
|
|
#else
|
2007-11-03 03:40:39 +08:00
|
|
|
# define GLOBAL_FUNCTION_TABLE CG(function_table)
|
|
|
|
# define GLOBAL_CLASS_TABLE CG(class_table)
|
|
|
|
# define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
|
|
|
|
# define GLOBAL_CONSTANTS_TABLE EG(zend_constants)
|
1999-04-21 11:49:09 +08:00
|
|
|
#endif
|
|
|
|
|
2017-01-16 04:27:05 +08:00
|
|
|
ZEND_API zend_utility_values zend_uv;
|
2017-01-21 00:50:09 +08:00
|
|
|
ZEND_API zend_bool zend_dtrace_enabled;
|
2017-01-16 04:27:05 +08:00
|
|
|
|
|
|
|
/* version information */
|
|
|
|
static char *zend_version_info;
|
|
|
|
static uint32_t zend_version_info_length;
|
2018-01-02 12:57:58 +08:00
|
|
|
#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2018 Zend Technologies\n"
|
2017-01-16 04:27:05 +08:00
|
|
|
#define PRINT_ZVAL_INDENT 4
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* true multithread-shared globals */
|
2002-03-12 18:08:47 +08:00
|
|
|
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
|
2014-08-26 01:24:55 +08:00
|
|
|
ZEND_API size_t (*zend_printf)(const char *format, ...);
|
2000-03-26 03:10:07 +08:00
|
|
|
ZEND_API zend_write_func_t zend_write;
|
2015-03-04 07:05:28 +08:00
|
|
|
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
|
|
|
|
ZEND_API void (*zend_ticks_function)(int ticks);
|
2016-06-23 20:01:23 +08:00
|
|
|
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
|
2016-11-26 22:18:42 +08:00
|
|
|
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args);
|
2016-12-19 00:53:27 +08:00
|
|
|
void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
|
|
|
|
void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API char *(*zend_getenv)(char *name, size_t name_len);
|
2017-07-27 05:10:07 +08:00
|
|
|
ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
|
2017-10-18 22:18:54 +08:00
|
|
|
ZEND_API int (*zend_post_startup_cb)(void) = NULL;
|
2000-06-19 00:02:32 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void (*zend_on_timeout)(int seconds);
|
2002-09-19 23:58:01 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
|
2014-09-02 00:57:33 +08:00
|
|
|
static zval *(*zend_get_configuration_directive_p)(zend_string *name);
|
1999-06-20 04:42:15 +08:00
|
|
|
|
2017-10-27 06:28:58 +08:00
|
|
|
#if ZEND_RC_DEBUG
|
|
|
|
ZEND_API zend_bool zend_rc_debug = 0;
|
|
|
|
#endif
|
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
|
2002-11-20 01:51:30 +08:00
|
|
|
{
|
|
|
|
if (!new_value) {
|
2008-02-24 01:06:22 +08:00
|
|
|
EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
|
2002-11-20 01:51:30 +08:00
|
|
|
} else {
|
2015-06-30 18:59:27 +08:00
|
|
|
EG(error_reporting) = atoi(ZSTR_VAL(new_value));
|
2002-11-20 01:51:30 +08:00
|
|
|
}
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2002-11-20 01:51:30 +08:00
|
|
|
|
2008-01-22 17:27:48 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
|
|
|
|
{
|
2018-02-26 17:49:58 +08:00
|
|
|
zend_bool val;
|
|
|
|
|
2018-03-05 16:51:58 +08:00
|
|
|
val = zend_ini_parse_bool(new_value);
|
2018-03-02 16:02:21 +08:00
|
|
|
gc_enable(val);
|
2018-02-26 17:49:58 +08:00
|
|
|
|
2008-01-22 17:27:48 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2018-02-26 17:49:58 +08:00
|
|
|
static ZEND_INI_DISP(zend_gc_enabled_displayer_cb) /* {{{ */
|
|
|
|
{
|
|
|
|
if (gc_enabled()) {
|
|
|
|
ZEND_PUTS("On");
|
|
|
|
} else {
|
|
|
|
ZEND_PUTS("Off");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
2010-12-20 00:36:37 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
|
|
|
|
{
|
2014-12-24 00:33:30 +08:00
|
|
|
if (!CG(multibyte)) {
|
2010-12-20 00:36:37 +08:00
|
|
|
return FAILURE;
|
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
if (!zend_multibyte_get_functions()) {
|
2010-12-20 00:36:37 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
2015-06-30 18:59:27 +08:00
|
|
|
return zend_multibyte_set_script_encoding_by_string(new_value ? ZSTR_VAL(new_value) : NULL, new_value ? ZSTR_LEN(new_value) : 0);
|
2010-12-20 00:36:37 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-03-02 17:25:40 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_long *p, val;
|
|
|
|
#ifndef ZTS
|
|
|
|
char *base = (char *) mh_arg2;
|
|
|
|
#else
|
|
|
|
char *base;
|
|
|
|
|
|
|
|
base = (char *) ts_resource(*((int *) mh_arg2));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
p = (zend_long *) (base+(size_t) mh_arg1);
|
|
|
|
|
2017-07-28 20:54:01 +08:00
|
|
|
val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
|
2015-03-02 17:25:40 +08:00
|
|
|
|
|
|
|
if (stage != ZEND_INI_STAGE_STARTUP &&
|
|
|
|
stage != ZEND_INI_STAGE_SHUTDOWN &&
|
|
|
|
*p != val &&
|
|
|
|
(*p < 0 || val < 0)) {
|
|
|
|
zend_error(E_WARNING, "zend.assertions may be completely enabled or disabled only in php.ini");
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = val;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
/* }}} */
|
2010-12-20 00:36:37 +08:00
|
|
|
|
2002-11-20 01:51:30 +08:00
|
|
|
ZEND_INI_BEGIN()
|
2004-02-25 18:57:10 +08:00
|
|
|
ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
|
2015-10-06 16:13:38 +08:00
|
|
|
STD_ZEND_INI_ENTRY("zend.assertions", "1", ZEND_INI_ALL, OnUpdateAssertions, assertions, zend_executor_globals, executor_globals)
|
2018-02-26 17:49:58 +08:00
|
|
|
ZEND_INI_ENTRY3_EX("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, NULL, NULL, NULL, zend_gc_enabled_displayer_cb)
|
2010-11-24 13:41:23 +08:00
|
|
|
STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals)
|
2010-12-20 00:36:37 +08:00
|
|
|
ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding)
|
|
|
|
STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
|
2011-06-22 22:23:21 +08:00
|
|
|
#ifdef ZEND_SIGNALS
|
|
|
|
STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
|
|
|
|
#endif
|
2002-11-20 01:51:30 +08:00
|
|
|
ZEND_INI_END()
|
|
|
|
|
2016-12-19 00:53:27 +08:00
|
|
|
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
|
|
|
|
{
|
|
|
|
smart_string buf = {0};
|
|
|
|
|
|
|
|
/* since there are places where (v)spprintf called without checking for null,
|
|
|
|
a bit of defensive coding here */
|
|
|
|
if (!pbuf) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
zend_printf_to_smart_string(&buf, format, ap);
|
|
|
|
|
|
|
|
if (max_len && buf.len > max_len) {
|
|
|
|
buf.len = max_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
smart_string_0(&buf);
|
|
|
|
|
|
|
|
if (buf.c) {
|
|
|
|
*pbuf = buf.c;
|
|
|
|
return buf.len;
|
|
|
|
} else {
|
|
|
|
*pbuf = estrndup("", 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2016-12-19 00:31:00 +08:00
|
|
|
ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list arg;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
len = zend_vspprintf(message, max_len, format, arg);
|
|
|
|
va_end(arg);
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2017-11-16 19:29:27 +08:00
|
|
|
ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list arg;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
len = zend_vspprintf(message, max_len, format, arg);
|
|
|
|
va_end(arg);
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2016-12-19 00:53:27 +08:00
|
|
|
ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
|
|
|
|
{
|
|
|
|
smart_str buf = {0};
|
|
|
|
|
|
|
|
zend_printf_to_smart_str(&buf, format, ap);
|
|
|
|
|
|
|
|
if (!buf.s) {
|
|
|
|
return ZSTR_EMPTY_ALLOC();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_len && ZSTR_LEN(buf.s) > max_len) {
|
|
|
|
ZSTR_LEN(buf.s) = max_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
smart_str_0(&buf);
|
|
|
|
return buf.s;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2016-12-19 00:31:00 +08:00
|
|
|
ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list arg;
|
|
|
|
zend_string *str;
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
str = zend_vstrpprintf(max_len, format, arg);
|
|
|
|
va_end(arg);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2017-11-16 19:29:27 +08:00
|
|
|
ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list arg;
|
|
|
|
zend_string *str;
|
|
|
|
|
|
|
|
va_start(arg, format);
|
|
|
|
str = zend_vstrpprintf(max_len, format, arg);
|
|
|
|
va_end(arg);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-10-07 17:35:43 +08:00
|
|
|
static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent);
|
|
|
|
|
|
|
|
static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval *tmp;
|
|
|
|
zend_string *string_key;
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_ulong num_key;
|
1999-04-08 02:10:10 +08:00
|
|
|
int i;
|
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appendc(buf, ' ');
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, "(\n");
|
1999-12-22 01:14:31 +08:00
|
|
|
indent += PRINT_ZVAL_INDENT;
|
2015-10-07 17:35:43 +08:00
|
|
|
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appendc(buf, ' ');
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appendc(buf, '[');
|
2014-04-18 23:18:11 +08:00
|
|
|
if (string_key) {
|
|
|
|
if (is_object) {
|
|
|
|
const char *prop_name, *class_name;
|
2014-09-16 06:23:58 +08:00
|
|
|
size_t prop_len;
|
|
|
|
int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
|
2014-04-18 23:18:11 +08:00
|
|
|
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appendl(buf, prop_name, prop_len);
|
2014-04-18 23:18:11 +08:00
|
|
|
if (class_name && mangled == SUCCESS) {
|
2015-10-07 17:35:43 +08:00
|
|
|
if (class_name[0] == '*') {
|
|
|
|
smart_str_appends(buf, ":protected");
|
2014-04-18 23:18:11 +08:00
|
|
|
} else {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, ":");
|
|
|
|
smart_str_appends(buf, class_name);
|
|
|
|
smart_str_appends(buf, ":private");
|
2003-06-09 02:53:58 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
}
|
2014-04-18 23:18:11 +08:00
|
|
|
} else {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_append(buf, string_key);
|
2014-04-18 23:18:11 +08:00
|
|
|
}
|
|
|
|
} else {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_append_long(buf, num_key);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, "] => ");
|
|
|
|
zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT);
|
|
|
|
smart_str_appends(buf, "\n");
|
2014-04-18 23:18:11 +08:00
|
|
|
} ZEND_HASH_FOREACH_END();
|
1999-12-22 01:14:31 +08:00
|
|
|
indent -= PRINT_ZVAL_INDENT;
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appendc(buf, ' ');
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, ")\n");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void print_flat_hash(HashTable *ht) /* {{{ */
|
2002-12-02 03:47:02 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval *tmp;
|
|
|
|
zend_string *string_key;
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_ulong num_key;
|
2007-11-03 03:40:39 +08:00
|
|
|
int i = 0;
|
|
|
|
|
2014-05-26 02:07:29 +08:00
|
|
|
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
|
2007-11-03 03:40:39 +08:00
|
|
|
if (i++ > 0) {
|
|
|
|
ZEND_PUTS(",");
|
|
|
|
}
|
|
|
|
ZEND_PUTS("[");
|
2014-04-18 23:18:11 +08:00
|
|
|
if (string_key) {
|
2015-06-30 18:59:27 +08:00
|
|
|
ZEND_WRITE(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
|
2014-04-18 23:18:11 +08:00
|
|
|
} else {
|
2014-08-26 02:22:49 +08:00
|
|
|
zend_printf(ZEND_ULONG_FMT, num_key);
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
|
|
|
ZEND_PUTS("] => ");
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_flat_zval_r(tmp);
|
2014-04-18 23:18:11 +08:00
|
|
|
} ZEND_HASH_FOREACH_END();
|
2002-12-02 03:47:02 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-03-07 13:48:28 +08:00
|
|
|
if (Z_TYPE_P(expr) == IS_STRING) {
|
2014-07-09 20:05:55 +08:00
|
|
|
return 0;
|
2014-09-23 12:56:59 +08:00
|
|
|
} else {
|
2017-11-16 22:09:01 +08:00
|
|
|
ZVAL_STR(expr_copy, zval_get_string_func(expr));
|
2014-09-23 12:56:59 +08:00
|
|
|
return 1;
|
1999-06-11 18:44:26 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-11 18:44:26 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
|
1999-06-11 18:44:26 +08:00
|
|
|
{
|
2017-11-16 22:09:32 +08:00
|
|
|
zend_string *tmp_str;
|
|
|
|
zend_string *str = zval_get_tmp_string(expr, &tmp_str);
|
2015-06-30 18:59:27 +08:00
|
|
|
size_t len = ZSTR_LEN(str);
|
1999-06-11 18:44:26 +08:00
|
|
|
|
2014-04-21 23:12:10 +08:00
|
|
|
if (len != 0) {
|
2015-10-07 17:35:43 +08:00
|
|
|
zend_write(ZSTR_VAL(str), len);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2014-04-21 23:12:10 +08:00
|
|
|
|
2017-11-16 22:09:32 +08:00
|
|
|
zend_tmp_string_release(tmp_str);
|
2014-04-21 23:12:10 +08:00
|
|
|
return len;
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
|
2002-12-02 03:47:02 +08:00
|
|
|
{
|
2007-11-03 03:40:39 +08:00
|
|
|
switch (Z_TYPE_P(expr)) {
|
|
|
|
case IS_ARRAY:
|
|
|
|
ZEND_PUTS("Array (");
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_REFCOUNTED_P(expr)) {
|
|
|
|
if (Z_IS_RECURSIVE_P(expr)) {
|
|
|
|
ZEND_PUTS(" *RECURSION*");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Z_PROTECT_RECURSION_P(expr);
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
print_flat_hash(Z_ARRVAL_P(expr));
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_PUTS(")");
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_REFCOUNTED_P(expr)) {
|
|
|
|
Z_UNPROTECT_RECURSION_P(expr);
|
2014-05-29 22:21:56 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
break;
|
|
|
|
case IS_OBJECT:
|
|
|
|
{
|
2003-01-12 21:45:50 +08:00
|
|
|
HashTable *properties = NULL;
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
|
2015-06-30 18:59:27 +08:00
|
|
|
zend_printf("%s Object (", ZSTR_VAL(class_name));
|
2018-05-28 21:27:12 +08:00
|
|
|
zend_string_release_ex(class_name, 0);
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_IS_RECURSIVE_P(expr)) {
|
2015-04-16 03:07:34 +08:00
|
|
|
ZEND_PUTS(" *RECURSION*");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-01-14 20:13:51 +08:00
|
|
|
if (Z_OBJ_HANDLER_P(expr, get_properties)) {
|
2003-01-12 21:45:50 +08:00
|
|
|
properties = Z_OBJPROP_P(expr);
|
|
|
|
}
|
2003-01-14 20:13:51 +08:00
|
|
|
if (properties) {
|
2017-10-06 06:34:50 +08:00
|
|
|
Z_PROTECT_RECURSION_P(expr);
|
2014-12-14 06:06:14 +08:00
|
|
|
print_flat_hash(properties);
|
2017-10-06 06:34:50 +08:00
|
|
|
Z_UNPROTECT_RECURSION_P(expr);
|
2003-01-12 21:45:50 +08:00
|
|
|
}
|
|
|
|
ZEND_PUTS(")");
|
|
|
|
break;
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
2016-07-12 05:28:14 +08:00
|
|
|
case IS_REFERENCE:
|
|
|
|
zend_print_flat_zval_r(Z_REFVAL_P(expr));
|
|
|
|
break;
|
2007-11-03 03:40:39 +08:00
|
|
|
default:
|
2018-07-04 05:50:57 +08:00
|
|
|
zend_print_zval(expr, 0);
|
2007-11-03 03:40:39 +08:00
|
|
|
break;
|
|
|
|
}
|
2002-12-02 03:47:02 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2015-10-07 17:35:43 +08:00
|
|
|
static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2007-11-03 03:40:39 +08:00
|
|
|
switch (Z_TYPE_P(expr)) {
|
1999-04-08 02:10:10 +08:00
|
|
|
case IS_ARRAY:
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, "Array\n");
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_REFCOUNTED_P(expr)) {
|
|
|
|
if (Z_IS_RECURSIVE_P(expr)) {
|
|
|
|
smart_str_appends(buf, " *RECURSION*");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Z_PROTECT_RECURSION_P(expr);
|
2000-11-03 07:17:55 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_REFCOUNTED_P(expr)) {
|
|
|
|
Z_UNPROTECT_RECURSION_P(expr);
|
2014-05-29 22:21:56 +08:00
|
|
|
}
|
1999-04-08 02:10:10 +08:00
|
|
|
break;
|
|
|
|
case IS_OBJECT:
|
2001-07-29 16:22:57 +08:00
|
|
|
{
|
2007-10-11 09:03:19 +08:00
|
|
|
HashTable *properties;
|
|
|
|
int is_temp;
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, ZSTR_VAL(class_name));
|
2018-05-28 21:27:12 +08:00
|
|
|
zend_string_release_ex(class_name, 0);
|
2014-10-10 01:15:07 +08:00
|
|
|
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, " Object\n");
|
2017-10-06 06:34:50 +08:00
|
|
|
if (Z_IS_RECURSIVE_P(expr)) {
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_appends(buf, " *RECURSION*");
|
2007-10-11 09:03:19 +08:00
|
|
|
return;
|
|
|
|
}
|
2015-04-16 03:07:34 +08:00
|
|
|
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-10-06 06:34:50 +08:00
|
|
|
Z_PROTECT_RECURSION_P(expr);
|
2015-10-07 17:35:43 +08:00
|
|
|
print_hash(buf, properties, indent, 1);
|
2017-10-06 06:34:50 +08:00
|
|
|
Z_UNPROTECT_RECURSION_P(expr);
|
2015-04-16 03:07:34 +08:00
|
|
|
|
2007-10-11 09:03:19 +08:00
|
|
|
if (is_temp) {
|
|
|
|
zend_hash_destroy(properties);
|
2014-04-25 15:54:10 +08:00
|
|
|
FREE_HASHTABLE(properties);
|
2001-07-29 16:22:57 +08:00
|
|
|
}
|
|
|
|
break;
|
2000-11-03 07:17:55 +08:00
|
|
|
}
|
2015-10-07 17:35:43 +08:00
|
|
|
case IS_LONG:
|
|
|
|
smart_str_append_long(buf, Z_LVAL_P(expr));
|
|
|
|
break;
|
2016-07-12 05:28:14 +08:00
|
|
|
case IS_REFERENCE:
|
|
|
|
zend_print_zval_r_to_buf(buf, Z_REFVAL_P(expr), indent);
|
|
|
|
break;
|
2017-11-16 22:09:32 +08:00
|
|
|
case IS_STRING:
|
|
|
|
smart_str_append(buf, Z_STR_P(expr));
|
|
|
|
break;
|
1999-04-08 02:10:10 +08:00
|
|
|
default:
|
2015-10-07 17:35:43 +08:00
|
|
|
{
|
2017-11-16 22:09:32 +08:00
|
|
|
zend_string *str = zval_get_string_func(expr);
|
2015-10-07 17:35:43 +08:00
|
|
|
smart_str_append(buf, str);
|
2018-05-28 21:27:12 +08:00
|
|
|
zend_string_release_ex(str, 0);
|
2015-10-07 17:35:43 +08:00
|
|
|
}
|
1999-04-08 02:10:10 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2015-10-07 17:35:43 +08:00
|
|
|
ZEND_API zend_string *zend_print_zval_r_to_str(zval *expr, int indent) /* {{{ */
|
|
|
|
{
|
|
|
|
smart_str buf = {0};
|
|
|
|
zend_print_zval_r_to_buf(&buf, expr, indent);
|
|
|
|
smart_str_0(&buf);
|
|
|
|
return buf.s;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_string *str = zend_print_zval_r_to_str(expr, indent);
|
|
|
|
zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
|
2018-05-28 21:27:12 +08:00
|
|
|
zend_string_release_ex(str, 0);
|
2015-10-07 17:35:43 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-03-04 07:05:28 +08:00
|
|
|
static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
1999-12-01 04:15:04 +08:00
|
|
|
if (opened_path) {
|
2015-03-04 07:05:28 +08:00
|
|
|
*opened_path = zend_string_init(filename, strlen(filename), 0);
|
1999-12-01 04:15:04 +08:00
|
|
|
}
|
2000-06-26 01:05:22 +08:00
|
|
|
return fopen(filename, "rb");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-01-12 22:37:46 +08:00
|
|
|
#ifdef ZTS
|
2014-09-10 05:14:19 +08:00
|
|
|
static zend_bool short_tags_default = 1;
|
2014-08-26 01:28:33 +08:00
|
|
|
static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
|
2007-01-12 22:37:46 +08:00
|
|
|
#else
|
2008-03-18 16:36:30 +08:00
|
|
|
# define short_tags_default 1
|
|
|
|
# define compiler_options_default ZEND_COMPILE_DEFAULT
|
2007-01-12 22:37:46 +08:00
|
|
|
#endif
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_set_default_compile_time_values(void) /* {{{ */
|
2000-06-16 03:18:57 +08:00
|
|
|
{
|
|
|
|
/* default compile-time values */
|
2007-01-12 22:37:46 +08:00
|
|
|
CG(short_tags) = short_tags_default;
|
2008-03-18 16:36:30 +08:00
|
|
|
CG(compiler_options) = compiler_options_default;
|
2000-06-16 03:18:57 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-06-16 03:18:57 +08:00
|
|
|
|
2015-04-06 04:45:58 +08:00
|
|
|
#ifdef ZEND_WIN32
|
2015-04-06 01:45:04 +08:00
|
|
|
static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
|
|
|
|
{
|
|
|
|
ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
|
|
|
|
osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
|
|
|
|
ZEND_ASSERT(0); /* Should not happen as sizeof is used. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* }}} */
|
2015-04-06 04:45:58 +08:00
|
|
|
#endif
|
2015-04-06 01:45:04 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_init_exception_op(void) /* {{{ */
|
2008-04-17 18:21:38 +08:00
|
|
|
{
|
|
|
|
memset(EG(exception_op), 0, sizeof(EG(exception_op)));
|
|
|
|
EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
|
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
|
|
|
|
EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
|
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
|
|
|
|
EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
|
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-04-11 04:01:00 +08:00
|
|
|
static void zend_init_call_trampoline_op(void) /* {{{ */
|
|
|
|
{
|
|
|
|
memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
|
|
|
|
EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
|
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-09-18 17:27:39 +08:00
|
|
|
static void auto_global_dtor(zval *zv) /* {{{ */
|
|
|
|
{
|
2015-12-21 19:09:24 +08:00
|
|
|
free(Z_PTR_P(zv));
|
2015-09-18 17:27:39 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
2015-09-18 17:27:39 +08:00
|
|
|
static void function_copy_ctor(zval *zv) /* {{{ */
|
2014-04-10 03:40:01 +08:00
|
|
|
{
|
|
|
|
zend_function *old_func = Z_FUNC_P(zv);
|
2018-03-06 19:59:30 +08:00
|
|
|
zend_function *func = pemalloc(sizeof(zend_internal_function), 1);
|
|
|
|
|
|
|
|
Z_FUNC_P(zv) = func;
|
|
|
|
memcpy(func, old_func, sizeof(zend_internal_function));
|
|
|
|
function_add_ref(func);
|
|
|
|
if ((old_func->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))
|
|
|
|
&& old_func->common.arg_info) {
|
|
|
|
uint32_t i;
|
|
|
|
uint32_t num_args = old_func->common.num_args + 1;
|
|
|
|
zend_arg_info *arg_info = old_func->common.arg_info - 1;
|
|
|
|
zend_arg_info *new_arg_info;
|
|
|
|
|
|
|
|
if (old_func->common.fn_flags & ZEND_ACC_VARIADIC) {
|
|
|
|
num_args++;
|
|
|
|
}
|
|
|
|
new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1);
|
|
|
|
memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args);
|
|
|
|
for (i = 0 ; i < num_args; i++) {
|
|
|
|
if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
|
|
|
|
zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
|
|
|
|
|
|
|
|
new_arg_info[i].type =
|
|
|
|
ZEND_TYPE_ENCODE_CLASS(
|
|
|
|
name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func->common.arg_info = new_arg_info + 1;
|
|
|
|
}
|
2014-04-10 03:40:01 +08:00
|
|
|
}
|
2015-09-18 17:27:39 +08:00
|
|
|
/* }}} */
|
2014-04-10 03:40:01 +08:00
|
|
|
|
2015-09-18 17:27:39 +08:00
|
|
|
static void auto_global_copy_ctor(zval *zv) /* {{{ */
|
2015-07-31 19:22:24 +08:00
|
|
|
{
|
|
|
|
zend_auto_global *old_ag = (zend_auto_global *) Z_PTR_P(zv);
|
|
|
|
zend_auto_global *new_ag = pemalloc(sizeof(zend_auto_global), 1);
|
|
|
|
|
2015-12-21 19:09:24 +08:00
|
|
|
new_ag->name = old_ag->name;
|
2015-07-31 19:22:24 +08:00
|
|
|
new_ag->auto_global_callback = old_ag->auto_global_callback;
|
|
|
|
new_ag->jit = old_ag->jit;
|
|
|
|
|
|
|
|
Z_PTR_P(zv) = new_ag;
|
|
|
|
}
|
2015-09-18 17:27:39 +08:00
|
|
|
/* }}} */
|
2015-07-31 19:22:24 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{{ */
|
1999-04-21 11:49:09 +08:00
|
|
|
{
|
2000-07-13 00:37:46 +08:00
|
|
|
compiler_globals->compiled_filename = NULL;
|
|
|
|
|
2003-06-02 20:13:11 +08:00
|
|
|
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
2014-04-10 03:40:01 +08:00
|
|
|
zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
2014-02-17 21:59:18 +08:00
|
|
|
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
|
1999-12-27 19:22:57 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_set_default_compile_time_values();
|
2001-07-15 22:08:58 +08:00
|
|
|
|
2001-08-09 01:18:16 +08:00
|
|
|
compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
|
2015-09-18 17:27:39 +08:00
|
|
|
zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0);
|
2015-07-31 19:22:24 +08:00
|
|
|
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
|
2005-12-01 19:48:17 +08:00
|
|
|
|
|
|
|
compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
|
|
|
|
if (compiler_globals->last_static_member) {
|
2014-09-14 03:57:58 +08:00
|
|
|
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval*));
|
2005-12-01 19:48:17 +08:00
|
|
|
} else {
|
2010-05-25 01:07:52 +08:00
|
|
|
compiler_globals->static_members_table = NULL;
|
2005-12-01 19:48:17 +08:00
|
|
|
}
|
2010-12-28 04:25:34 +08:00
|
|
|
compiler_globals->script_encoding_list = NULL;
|
1999-04-21 11:49:09 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{{ */
|
1999-04-21 11:49:09 +08:00
|
|
|
{
|
2001-12-13 04:45:38 +08:00
|
|
|
if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
|
1999-05-11 04:46:42 +08:00
|
|
|
zend_hash_destroy(compiler_globals->function_table);
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->function_table);
|
1999-05-11 04:46:42 +08:00
|
|
|
}
|
2001-12-13 04:45:38 +08:00
|
|
|
if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
|
1999-05-11 04:46:42 +08:00
|
|
|
zend_hash_destroy(compiler_globals->class_table);
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->class_table);
|
1999-05-11 04:46:42 +08:00
|
|
|
}
|
2003-12-12 18:50:23 +08:00
|
|
|
if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
|
2001-08-09 01:18:16 +08:00
|
|
|
zend_hash_destroy(compiler_globals->auto_globals);
|
|
|
|
free(compiler_globals->auto_globals);
|
|
|
|
}
|
2010-05-25 01:07:52 +08:00
|
|
|
if (compiler_globals->static_members_table) {
|
|
|
|
free(compiler_globals->static_members_table);
|
2005-12-01 19:48:17 +08:00
|
|
|
}
|
2010-12-20 00:36:37 +08:00
|
|
|
if (compiler_globals->script_encoding_list) {
|
2014-08-15 03:53:27 +08:00
|
|
|
pefree((char*)compiler_globals->script_encoding_list, 1);
|
2010-12-20 00:36:37 +08:00
|
|
|
}
|
2005-12-01 19:48:17 +08:00
|
|
|
compiler_globals->last_static_member = 0;
|
1999-04-21 11:49:09 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
|
1999-04-22 01:26:37 +08:00
|
|
|
{
|
2015-02-17 00:19:32 +08:00
|
|
|
ZEND_TSRMLS_CACHE_UPDATE();
|
2015-02-21 11:35:16 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_startup_constants();
|
2017-02-21 19:12:42 +08:00
|
|
|
zend_copy_constants(executor_globals->zend_constants, GLOBAL_CONSTANTS_TABLE);
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_init_rsrc_plist();
|
|
|
|
zend_init_exception_op();
|
2015-04-11 04:01:00 +08:00
|
|
|
zend_init_call_trampoline_op();
|
|
|
|
memset(&executor_globals->trampoline, 0, sizeof(zend_op_array));
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->lambda_count = 0;
|
|
|
|
ZVAL_UNDEF(&executor_globals->user_error_handler);
|
|
|
|
ZVAL_UNDEF(&executor_globals->user_exception_handler);
|
|
|
|
executor_globals->in_autoload = NULL;
|
|
|
|
executor_globals->current_execute_data = NULL;
|
|
|
|
executor_globals->current_module = NULL;
|
|
|
|
executor_globals->exit_status = 0;
|
2015-02-13 18:25:44 +08:00
|
|
|
#if XPFPA_HAVE_CW
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->saved_fpu_cw = 0;
|
2015-02-13 18:25:44 +08:00
|
|
|
#endif
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->saved_fpu_cw_ptr = NULL;
|
|
|
|
executor_globals->active = 0;
|
|
|
|
executor_globals->bailout = NULL;
|
|
|
|
executor_globals->error_handling = EH_NORMAL;
|
|
|
|
executor_globals->exception_class = NULL;
|
|
|
|
executor_globals->exception = NULL;
|
|
|
|
executor_globals->objects_store.object_buckets = NULL;
|
2015-04-05 02:28:58 +08:00
|
|
|
#ifdef ZEND_WIN32
|
2015-04-06 01:45:04 +08:00
|
|
|
zend_get_windows_version_info(&executor_globals->windows_version_info);
|
2015-04-05 02:28:58 +08:00
|
|
|
#endif
|
2017-02-10 01:40:33 +08:00
|
|
|
executor_globals->flags = EG_FLAGS_INITIAL;
|
1999-04-22 01:26:37 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
|
1999-04-22 01:26:37 +08:00
|
|
|
{
|
2014-12-16 17:15:02 +08:00
|
|
|
zend_ini_dtor(executor_globals->ini_directives);
|
2015-07-31 19:43:17 +08:00
|
|
|
|
2005-09-12 17:06:15 +08:00
|
|
|
if (&executor_globals->persistent_list != global_persistent_list) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&executor_globals->persistent_list);
|
2005-09-12 17:06:15 +08:00
|
|
|
}
|
|
|
|
if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
|
|
|
|
zend_hash_destroy(executor_globals->zend_constants);
|
|
|
|
free(executor_globals->zend_constants);
|
|
|
|
}
|
1999-04-22 01:26:37 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
|
2001-08-06 21:48:51 +08:00
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_copy_ini_directives() == SUCCESS) {
|
|
|
|
zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
|
2006-11-08 19:04:27 +08:00
|
|
|
}
|
2001-08-06 21:48:51 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2001-08-03 15:06:05 +08:00
|
|
|
#endif
|
|
|
|
|
2004-07-11 03:29:01 +08:00
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
/* FreeBSD and DragonFly floating point precision fix */
|
2000-06-12 01:45:19 +08:00
|
|
|
#include <floatingpoint.h>
|
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p) /* {{{ */
|
2008-03-17 05:06:55 +08:00
|
|
|
{
|
|
|
|
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p) /* {{{ */
|
2000-12-27 23:43:15 +08:00
|
|
|
{
|
2008-03-17 05:06:55 +08:00
|
|
|
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
2000-12-27 23:43:15 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-12-27 23:43:15 +08:00
|
|
|
|
2014-02-17 21:59:18 +08:00
|
|
|
static void module_destructor_zval(zval *zv) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
|
|
|
|
|
|
|
|
module_destructor(module);
|
|
|
|
free(module);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
|
2010-07-08 22:05:11 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval globals;
|
|
|
|
|
2018-01-19 22:47:26 +08:00
|
|
|
/* IS_ARRAY, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_ARR(&globals, &EG(symbol_table));
|
2018-01-19 22:47:26 +08:00
|
|
|
Z_TYPE_FLAGS_P(&globals) = 0;
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_NEW_REF(&globals, &globals);
|
2015-02-14 03:20:39 +08:00
|
|
|
zend_hash_update(&EG(symbol_table), name, &globals);
|
2010-07-08 22:05:11 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
int zend_startup(zend_utility_functions *utility_functions, char **extensions) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
1999-04-22 01:26:37 +08:00
|
|
|
#ifdef ZTS
|
1999-04-26 22:10:42 +08:00
|
|
|
zend_compiler_globals *compiler_globals;
|
1999-04-22 01:26:37 +08:00
|
|
|
zend_executor_globals *executor_globals;
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
|
|
|
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
|
2015-02-17 00:19:32 +08:00
|
|
|
ZEND_TSRMLS_CACHE_UPDATE();
|
2001-08-06 21:48:51 +08:00
|
|
|
#else
|
2008-03-17 05:06:55 +08:00
|
|
|
extern zend_ini_scanner_globals ini_scanner_globals;
|
|
|
|
extern zend_php_scanner_globals language_scanner_globals;
|
2001-08-06 21:48:51 +08:00
|
|
|
#endif
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2018-01-16 18:27:18 +08:00
|
|
|
zend_cpu_startup();
|
|
|
|
|
2017-08-14 06:44:19 +08:00
|
|
|
#ifdef ZEND_WIN32
|
|
|
|
php_win32_cp_set_by_id(65001);
|
|
|
|
#endif
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
start_memory_manager();
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2013-10-17 16:40:43 +08:00
|
|
|
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
|
|
|
|
|
2004-07-11 03:29:01 +08:00
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
/* FreeBSD and DragonFly floating point precision fix */
|
2000-12-23 05:11:34 +08:00
|
|
|
fpsetmask(0);
|
2000-06-12 01:45:19 +08:00
|
|
|
#endif
|
2000-09-26 02:10:45 +08:00
|
|
|
|
2006-12-06 17:52:51 +08:00
|
|
|
zend_startup_strtod();
|
2000-09-26 02:10:45 +08:00
|
|
|
zend_startup_extensions_mechanism();
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* Set up utility functions and values */
|
2000-04-19 23:08:06 +08:00
|
|
|
zend_error_cb = utility_functions->error_function;
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_printf = utility_functions->printf_function;
|
2000-03-26 03:10:07 +08:00
|
|
|
zend_write = (zend_write_func_t) utility_functions->write_function;
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_fopen = utility_functions->fopen_function;
|
|
|
|
if (!zend_fopen) {
|
|
|
|
zend_fopen = zend_fopen_wrapper;
|
|
|
|
}
|
2003-02-18 17:37:54 +08:00
|
|
|
zend_stream_open_function = utility_functions->stream_open_function;
|
2000-03-06 03:50:10 +08:00
|
|
|
zend_message_dispatcher_p = utility_functions->message_handler;
|
2001-01-08 02:39:11 +08:00
|
|
|
zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
|
2000-01-25 03:00:30 +08:00
|
|
|
zend_ticks_function = utility_functions->ticks_function;
|
2002-09-19 23:58:01 +08:00
|
|
|
zend_on_timeout = utility_functions->on_timeout;
|
2016-12-19 00:53:27 +08:00
|
|
|
zend_printf_to_smart_string = utility_functions->printf_to_smart_string_function;
|
|
|
|
zend_printf_to_smart_str = utility_functions->printf_to_smart_str_function;
|
2004-09-06 06:40:35 +08:00
|
|
|
zend_getenv = utility_functions->getenv_function;
|
2008-03-05 21:34:12 +08:00
|
|
|
zend_resolve_path = utility_functions->resolve_path_function;
|
1999-06-20 04:42:15 +08:00
|
|
|
|
2016-06-23 20:01:23 +08:00
|
|
|
zend_interrupt_function = NULL;
|
|
|
|
|
2016-11-18 17:52:46 +08:00
|
|
|
#if HAVE_DTRACE
|
|
|
|
/* build with dtrace support */
|
2016-11-18 18:19:30 +08:00
|
|
|
{
|
|
|
|
char *tmp = getenv("USE_ZEND_DTRACE");
|
|
|
|
|
|
|
|
if (tmp && zend_atoi(tmp, 0)) {
|
2017-01-21 00:45:15 +08:00
|
|
|
zend_dtrace_enabled = 1;
|
2016-11-18 18:19:30 +08:00
|
|
|
zend_compile_file = dtrace_compile_file;
|
|
|
|
zend_execute_ex = dtrace_execute_ex;
|
|
|
|
zend_execute_internal = dtrace_execute_internal;
|
|
|
|
} else {
|
|
|
|
zend_compile_file = compile_file;
|
|
|
|
zend_execute_ex = execute_ex;
|
|
|
|
zend_execute_internal = NULL;
|
|
|
|
}
|
|
|
|
}
|
2016-11-18 17:52:46 +08:00
|
|
|
#else
|
2000-08-10 03:22:35 +08:00
|
|
|
zend_compile_file = compile_file;
|
2012-11-30 17:39:23 +08:00
|
|
|
zend_execute_ex = execute_ex;
|
2003-01-12 00:12:44 +08:00
|
|
|
zend_execute_internal = NULL;
|
2017-08-02 10:49:10 +08:00
|
|
|
#endif /* HAVE_DTRACE */
|
2010-04-24 21:32:30 +08:00
|
|
|
zend_compile_string = compile_string;
|
2004-04-13 23:19:21 +08:00
|
|
|
zend_throw_exception_hook = NULL;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-03 04:18:18 +08:00
|
|
|
/* Set up the default garbage collection implementation. */
|
|
|
|
gc_collect_cycles = zend_gc_collect_cycles;
|
|
|
|
|
2018-02-19 21:42:02 +08:00
|
|
|
zend_vm_init();
|
2002-10-19 05:19:27 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* set up version */
|
|
|
|
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
|
2007-11-03 03:40:39 +08:00
|
|
|
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
|
|
|
|
|
|
|
|
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
|
|
|
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
2014-02-17 21:59:18 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);
|
2001-10-01 01:29:55 +08:00
|
|
|
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);
|
2000-04-15 21:02:22 +08:00
|
|
|
zend_init_rsrc_list_dtors();
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
|
|
|
|
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
|
|
|
|
ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
|
|
|
|
ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
|
1999-04-26 22:10:42 +08:00
|
|
|
compiler_globals = ts_resource(compiler_globals_id);
|
1999-04-22 01:26:37 +08:00
|
|
|
executor_globals = ts_resource(executor_globals_id);
|
2002-09-19 06:16:22 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_dtor(compiler_globals);
|
2004-02-12 06:58:03 +08:00
|
|
|
compiler_globals->in_compilation = 0;
|
2003-12-12 18:50:23 +08:00
|
|
|
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
|
2001-12-14 00:55:04 +08:00
|
|
|
*compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
|
|
|
|
*compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
|
2001-08-09 01:18:16 +08:00
|
|
|
compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
|
2002-09-19 06:16:22 +08:00
|
|
|
|
|
|
|
zend_hash_destroy(executor_globals->zend_constants);
|
|
|
|
*executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
|
1999-07-15 03:49:19 +08:00
|
|
|
#else
|
2014-12-14 06:06:14 +08:00
|
|
|
ini_scanner_globals_ctor(&ini_scanner_globals);
|
|
|
|
php_scanner_globals_ctor(&language_scanner_globals);
|
|
|
|
zend_set_default_compile_time_values();
|
2015-05-29 17:44:46 +08:00
|
|
|
#ifdef ZEND_WIN32
|
|
|
|
zend_get_windows_version_info(&EG(windows_version_info));
|
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
#endif
|
2015-02-21 11:35:16 +08:00
|
|
|
EG(error_reporting) = E_ALL & ~E_NOTICE;
|
2008-12-31 04:15:28 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_interned_strings_init();
|
|
|
|
zend_startup_builtin_functions();
|
|
|
|
zend_register_standard_constants();
|
2017-11-29 22:10:51 +08:00
|
|
|
zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
|
1999-04-21 11:49:09 +08:00
|
|
|
|
1999-05-09 20:24:21 +08:00
|
|
|
#ifndef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_init_rsrc_plist();
|
|
|
|
zend_init_exception_op();
|
2015-04-11 04:01:00 +08:00
|
|
|
zend_init_call_trampoline_op();
|
1999-05-09 20:24:21 +08:00
|
|
|
#endif
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_ini_startup();
|
2000-12-27 23:43:15 +08:00
|
|
|
|
Fixed the UTF-8 and long path support in the streams on Windows.
Since long the default PHP charset is UTF-8, however the Windows part is
out of step with this important point. The current implementation in PHP
doesn't technically permit to handle UTF-8 filepath and several other
things. Till now, only the ANSI compatible APIs are being used. Here is more
about it
https://msdn.microsoft.com/en-us/library/windows/desktop/dd317752%28v=vs.85%29.aspx
The patch fixes not only issues with multibyte filenames under
incompatible codepages, but indirectly also issues with some other multibyte
encodings like BIG5, Shift-JIS, etc. by providing a clean way to access
filenames in UTF-8. Below is a small list of issues from the bug tracker,
that are getting fixed:
https://bugs.php.net/63401
https://bugs.php.net/41199
https://bugs.php.net/50203
https://bugs.php.net/71509
https://bugs.php.net/64699
https://bugs.php.net/64506
https://bugs.php.net/30195
https://bugs.php.net/65358
https://bugs.php.net/61315
https://bugs.php.net/70943
https://bugs.php.net/70903
https://bugs.php.net/63593
https://bugs.php.net/54977
https://bugs.php.net/54028
https://bugs.php.net/43148
https://bugs.php.net/30730
https://bugs.php.net/33350
https://bugs.php.net/35300
https://bugs.php.net/46990
https://bugs.php.net/61309
https://bugs.php.net/69333
https://bugs.php.net/45517
https://bugs.php.net/70551
https://bugs.php.net/50197
https://bugs.php.net/72200
https://bugs.php.net/37672
Yet more related tickets can for sure be found - on bugs.php.net, Stackoverflow
and Github. Some of the bugs are pretty recent, some descend to early
2000th, but the user comments in there last even till today. Just for example,
bug #30195 was opened in 2004, the latest comment in there was made in 2014. It
is certain, that these bugs descend not only to pure PHP use cases, but get also
redirected from the popular PHP based projects. Given the modern systems (and
those supported by PHP) are always based on NTFS, there is no excuse to keep
these issues unresolved.
The internalization approach on Windows is in many ways different from
UNIX and Linux, while it supports and is based on Unicode. It depends on the
current system code page, APIs used and exact kind how the binary was compiled
The locale doesn't affect the way Unicode or ANSI API work. PHP in particular
is being compiled without _UNICODE defined and this is conditioned by the
way we handle strings. Here is more about it
https://msdn.microsoft.com/en-us/library/tsbaswba.aspx
However, with any system code page ANSI functions automatically convert
paths to UTF-16. Paths in some encodings incompatible with the
current system code page, won't work correctly with ANSI APIs. PHP
till now only uses the ANSI Windows APIs.
For example, on a system with the current code page 1252, the paths
in cp1252 are supported and transparently converted to UTF-16 by the
ANSI functions. Once one wants to handle a filepath encoded with cp932 on
that particular system, an ANSI or a POSIX compatible function used in
PHP will produce an erroneous result. When trying to convert that cp932 path
to UTF-8 and passing to the ANSI functions, an ANSI function would
likely interpret the UTF-8 string as some string in the current code page and
create a filepath that represents every single byte of the UTF-8 string.
These behaviors are not only broken but also disregard the documented
INI settings.
This patch solves the issies with the multibyte paths on Windows by
intelligently enforcing the usage of the Unicode aware APIs. For
functions expect Unicode (fe CreateFileW, FindFirstFileW, etc.), arguments
will be converted to UTF-16 wide chars. For functions returning Unicode
aware data (fe GetCurrentDirectoryW, etc.), resulting wide string is
converted back to char's depending on the current PHP charset settings,
either to the current ANSI codepage (this is the behavior prior to this patch)
or to UTF-8 (the default behavior).
In a particular case, users might have to explicitly set
internal_encoding or default_charset, if filenames in ANSI codepage are
necessary. Current tests show no regressions and witness that this will be an
exotic case, the current default UTF-8 encoding is compatible with any
supported system. The dependency libraries are long switching to Unicode APIs,
so some tests were also added for extensions not directly related to streams.
At large, the patch brings over 150 related tests into the core. Those target
and was run on various environments with European, Asian, etc. codepages.
General PHP frameworks was tested and showed no regressions.
The impact on the current C code base is low, the most places affected
are the Windows only places in the three files tsrm_win32.c, zend_virtual_cwd.c
and plain_wrapper.c. The actual implementation of the most of the wide
char supporting functionality is in win32/ioutil.* and win32/codepage.*,
several low level functionsare extended in place to avoid reimplementation for
now. No performance impact was sighted. As previously mentioned, the ANSI APIs
used prior the patch perform Unicode conversions internally. Using the
Unicode APIs directly while doing custom conversions just retains the status
quo. The ways to optimize it are open (fe. by implementing caching for the
strings converted to wide variants).
The long path implementation is user transparent. If a path exceeds the
length of _MAX_PATH, it'll be automatically prefixed with \\?\. The MAXPATHLEN
is set to 2048 bytes.
Appreciation to Pierre Joye, Matt Ficken, @algo13 and others for tips, ideas
and testing.
Thanks.
2016-06-20 15:32:19 +08:00
|
|
|
#ifdef ZEND_WIN32
|
|
|
|
/* Uses INI settings, so needs to be run after it. */
|
|
|
|
php_win32_cp_setup();
|
|
|
|
#endif
|
|
|
|
|
2000-12-27 23:43:15 +08:00
|
|
|
#ifdef ZTS
|
|
|
|
tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
|
2017-03-04 17:39:13 +08:00
|
|
|
tsrm_set_shutdown_handler(zend_interned_strings_dtor);
|
2000-12-27 23:43:15 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_register_standard_ini_entries(void) /* {{{ */
|
2002-11-20 01:51:30 +08:00
|
|
|
{
|
|
|
|
int module_number = 0;
|
|
|
|
|
|
|
|
REGISTER_INI_ENTRIES();
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2002-11-20 01:51:30 +08:00
|
|
|
|
2002-09-17 20:42:11 +08:00
|
|
|
/* Unlink the global (r/o) copies of the class, function and constant tables,
|
|
|
|
* and use a fresh r/w copy for the startup thread
|
|
|
|
*/
|
2017-10-18 22:18:54 +08:00
|
|
|
int zend_post_startup(void) /* {{{ */
|
2002-09-17 20:42:11 +08:00
|
|
|
{
|
2007-11-03 03:40:39 +08:00
|
|
|
#ifdef ZTS
|
2012-05-03 22:39:53 +08:00
|
|
|
zend_encoding **script_encoding_list;
|
|
|
|
|
2002-09-17 20:42:11 +08:00
|
|
|
zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
|
2002-09-19 06:16:22 +08:00
|
|
|
zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
|
2002-09-17 20:42:11 +08:00
|
|
|
|
2002-09-19 06:16:22 +08:00
|
|
|
*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
|
|
|
|
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
|
|
|
|
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
|
2007-01-12 22:37:46 +08:00
|
|
|
|
|
|
|
short_tags_default = CG(short_tags);
|
2008-03-18 16:36:30 +08:00
|
|
|
compiler_options_default = CG(compiler_options);
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(persistent_list));
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->function_table);
|
|
|
|
free(compiler_globals->class_table);
|
2012-05-03 22:39:53 +08:00
|
|
|
if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_ctor(compiler_globals);
|
2012-05-03 22:39:53 +08:00
|
|
|
compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
|
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_ctor(compiler_globals);
|
2012-05-03 22:39:53 +08:00
|
|
|
}
|
2003-12-12 18:50:23 +08:00
|
|
|
free(EG(zend_constants));
|
2013-10-17 16:40:43 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
executor_globals_ctor(executor_globals);
|
2005-09-12 17:06:15 +08:00
|
|
|
global_persistent_list = &EG(persistent_list);
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_copy_ini_directives();
|
2002-09-17 20:42:11 +08:00
|
|
|
#endif
|
2017-10-18 22:18:54 +08:00
|
|
|
|
|
|
|
if (zend_post_startup_cb) {
|
|
|
|
int (*cb)(void) = zend_post_startup_cb;
|
|
|
|
|
|
|
|
zend_post_startup_cb = NULL;
|
|
|
|
if (cb() != SUCCESS) {
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCESS;
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
2002-09-17 20:42:11 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_shutdown(void) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2018-02-19 21:42:02 +08:00
|
|
|
zend_vm_dtor();
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(persistent_list));
|
2010-07-06 19:40:17 +08:00
|
|
|
zend_destroy_modules();
|
2001-12-24 02:39:52 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_deactivate();
|
2014-09-02 06:08:02 +08:00
|
|
|
virtual_cwd_shutdown();
|
2013-10-17 16:40:43 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
|
2001-12-26 19:18:00 +08:00
|
|
|
zend_hash_destroy(GLOBAL_CLASS_TABLE);
|
2001-12-24 02:39:52 +08:00
|
|
|
|
2001-08-09 01:18:16 +08:00
|
|
|
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
|
|
|
|
free(GLOBAL_AUTO_GLOBALS_TABLE);
|
2005-01-10 00:18:39 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_shutdown_extensions();
|
1999-04-08 02:10:10 +08:00
|
|
|
free(zend_version_info);
|
2003-04-19 02:40:53 +08:00
|
|
|
|
2003-12-12 19:14:44 +08:00
|
|
|
free(GLOBAL_FUNCTION_TABLE);
|
|
|
|
free(GLOBAL_CLASS_TABLE);
|
2005-09-12 17:06:15 +08:00
|
|
|
|
2003-04-19 02:40:53 +08:00
|
|
|
zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
|
2003-12-12 16:25:58 +08:00
|
|
|
free(GLOBAL_CONSTANTS_TABLE);
|
2006-12-06 17:52:51 +08:00
|
|
|
zend_shutdown_strtod();
|
2007-11-03 03:40:39 +08:00
|
|
|
|
2005-09-12 17:06:15 +08:00
|
|
|
#ifdef ZTS
|
2003-12-12 18:50:23 +08:00
|
|
|
GLOBAL_FUNCTION_TABLE = NULL;
|
|
|
|
GLOBAL_CLASS_TABLE = NULL;
|
|
|
|
GLOBAL_AUTO_GLOBALS_TABLE = NULL;
|
2005-09-12 17:06:15 +08:00
|
|
|
GLOBAL_CONSTANTS_TABLE = NULL;
|
2003-04-19 17:04:15 +08:00
|
|
|
#endif
|
2004-03-15 04:11:13 +08:00
|
|
|
zend_destroy_rsrc_list_dtors();
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
|
1999-04-10 19:21:55 +08:00
|
|
|
{
|
|
|
|
zend_uv = *utility_values;
|
2016-11-26 22:18:42 +08:00
|
|
|
zend_uv.import_use_extension_length = (uint32_t)strlen(zend_uv.import_use_extension);
|
1999-04-10 19:21:55 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-10 19:21:55 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* this should be compatible with the standard zenderror */
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_COLD void zenderror(const char *error) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2017-09-24 14:53:27 +08:00
|
|
|
CG(parse_error) = 0;
|
|
|
|
|
2015-03-22 03:10:19 +08:00
|
|
|
if (EG(exception)) {
|
|
|
|
/* An exception was thrown in the lexer, don't throw another in the parser. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_parse_error, error, 0);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-05-15 23:47:24 +08:00
|
|
|
BEGIN_EXTERN_C()
|
2017-03-10 18:52:26 +08:00
|
|
|
ZEND_API ZEND_COLD void _zend_bailout(const char *filename, uint32_t lineno) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-10-15 15:37:55 +08:00
|
|
|
|
2006-05-19 14:09:15 +08:00
|
|
|
if (!EG(bailout)) {
|
2001-07-22 00:21:22 +08:00
|
|
|
zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
|
2001-07-21 22:25:27 +08:00
|
|
|
exit(-1);
|
|
|
|
}
|
2018-03-02 16:02:21 +08:00
|
|
|
gc_protect(1);
|
1999-05-12 05:39:48 +08:00
|
|
|
CG(unclean_shutdown) = 1;
|
2011-06-08 06:58:38 +08:00
|
|
|
CG(active_class_entry) = NULL;
|
2014-07-03 05:02:25 +08:00
|
|
|
CG(in_compilation) = 0;
|
2002-08-28 22:43:32 +08:00
|
|
|
EG(current_execute_data) = NULL;
|
2008-03-19 05:14:28 +08:00
|
|
|
LONGJMP(*EG(bailout), FAILURE);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-05-15 23:47:24 +08:00
|
|
|
END_EXTERN_C()
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-10-13 01:22:03 +08:00
|
|
|
ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
|
|
|
char *new_info;
|
2016-11-26 22:18:42 +08:00
|
|
|
uint32_t new_info_length;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2016-11-26 22:18:42 +08:00
|
|
|
new_info_length = (uint32_t)(sizeof(" with v, , by \n")
|
1999-04-08 02:10:10 +08:00
|
|
|
+ strlen(extension->name)
|
|
|
|
+ strlen(extension->version)
|
|
|
|
+ strlen(extension->copyright)
|
2014-10-22 15:25:53 +08:00
|
|
|
+ strlen(extension->author));
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
new_info = (char *) malloc(new_info_length + 1);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2011-08-08 11:08:59 +08:00
|
|
|
snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
|
2011-08-08 11:08:59 +08:00
|
|
|
strncat(zend_version_info, new_info, new_info_length);
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_version_info_length += new_info_length;
|
|
|
|
free(new_info);
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_API char *get_zend_version(void) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
|
|
|
return zend_version_info;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-06 04:00:00 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_activate(void) /* {{{ */
|
1999-06-06 04:00:00 +08:00
|
|
|
{
|
2013-11-02 20:32:31 +08:00
|
|
|
#ifdef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_activate();
|
2013-11-02 20:32:31 +08:00
|
|
|
#endif
|
2014-12-14 06:06:14 +08:00
|
|
|
gc_reset();
|
|
|
|
init_compiler();
|
|
|
|
init_executor();
|
|
|
|
startup_scanner();
|
1999-06-06 04:00:00 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-06 04:00:00 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_call_destructors(void) /* {{{ */
|
2004-07-25 15:14:49 +08:00
|
|
|
{
|
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_destructors();
|
2004-07-25 15:14:49 +08:00
|
|
|
} zend_end_try();
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2004-07-25 15:14:49 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_deactivate(void) /* {{{ */
|
1999-06-06 04:00:00 +08:00
|
|
|
{
|
2000-07-12 20:00:17 +08:00
|
|
|
/* we're no longer executing anything */
|
2014-07-03 03:29:53 +08:00
|
|
|
EG(current_execute_data) = NULL;
|
2000-04-24 20:47:07 +08:00
|
|
|
|
2001-07-21 22:25:27 +08:00
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_scanner();
|
2001-07-21 22:25:27 +08:00
|
|
|
} zend_end_try();
|
|
|
|
|
2001-07-20 22:20:34 +08:00
|
|
|
/* shutdown_executor() takes care of its own bailout handling */
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_executor();
|
2001-07-21 22:25:27 +08:00
|
|
|
|
2016-01-26 15:57:39 +08:00
|
|
|
zend_try {
|
|
|
|
zend_ini_deactivate();
|
|
|
|
} zend_end_try();
|
|
|
|
|
2001-07-21 22:25:27 +08:00
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_compiler();
|
2001-07-21 22:25:27 +08:00
|
|
|
} zend_end_try();
|
|
|
|
|
2015-02-22 00:19:06 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(regular_list));
|
|
|
|
|
2008-01-24 18:42:12 +08:00
|
|
|
#if GC_BENCH
|
2008-01-29 04:34:02 +08:00
|
|
|
fprintf(stderr, "GC Statistics\n");
|
|
|
|
fprintf(stderr, "-------------\n");
|
|
|
|
fprintf(stderr, "Runs: %d\n", GC_G(gc_runs));
|
|
|
|
fprintf(stderr, "Collected: %d\n", GC_G(collected));
|
|
|
|
fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
|
|
|
|
fprintf(stderr, "Root buffer peak: %d\n\n", GC_G(root_buf_peak));
|
|
|
|
fprintf(stderr, " Possible Remove from Marked\n");
|
|
|
|
fprintf(stderr, " Root Buffered buffer grey\n");
|
|
|
|
fprintf(stderr, " -------- -------- ----------- ------\n");
|
|
|
|
fprintf(stderr, "ZVAL %8d %8d %9d %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
|
2008-01-24 18:42:12 +08:00
|
|
|
#endif
|
1999-06-06 04:00:00 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-06 03:50:10 +08:00
|
|
|
|
2000-03-06 18:46:40 +08:00
|
|
|
BEGIN_EXTERN_C()
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_message_dispatcher(zend_long message, const void *data) /* {{{ */
|
2000-03-06 03:50:10 +08:00
|
|
|
{
|
|
|
|
if (zend_message_dispatcher_p) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_message_dispatcher_p(message, data);
|
2000-03-06 03:50:10 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-06 18:46:40 +08:00
|
|
|
END_EXTERN_C()
|
2000-03-06 03:50:10 +08:00
|
|
|
|
2014-09-02 00:57:33 +08:00
|
|
|
ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
|
2000-03-06 03:50:10 +08:00
|
|
|
{
|
2001-01-08 02:39:11 +08:00
|
|
|
if (zend_get_configuration_directive_p) {
|
2014-09-02 00:57:33 +08:00
|
|
|
return zend_get_configuration_directive_p(name);
|
2000-03-06 03:50:10 +08:00
|
|
|
} else {
|
2014-09-02 00:57:33 +08:00
|
|
|
return NULL;
|
2000-03-06 03:50:10 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2011-08-02 15:38:23 +08:00
|
|
|
#define SAVE_STACK(stack) do { \
|
|
|
|
if (CG(stack).top) { \
|
|
|
|
memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
|
|
|
|
CG(stack).top = CG(stack).max = 0; \
|
|
|
|
CG(stack).elements = NULL; \
|
|
|
|
} else { \
|
|
|
|
stack.top = 0; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define RESTORE_STACK(stack) do { \
|
|
|
|
if (stack.top) { \
|
|
|
|
zend_stack_destroy(&CG(stack)); \
|
|
|
|
memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */
|
2014-09-09 02:34:26 +08:00
|
|
|
#else
|
2015-08-19 19:40:56 +08:00
|
|
|
static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list args)
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2000-04-19 23:08:06 +08:00
|
|
|
{
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2000-04-19 23:08:06 +08:00
|
|
|
va_list args;
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2004-12-06 23:50:27 +08:00
|
|
|
va_list usr_copy;
|
2014-02-10 14:04:30 +08:00
|
|
|
zval params[5];
|
|
|
|
zval retval;
|
2011-09-13 21:29:35 +08:00
|
|
|
const char *error_filename;
|
2016-11-26 22:18:42 +08:00
|
|
|
uint32_t error_lineno = 0;
|
2014-02-10 14:04:30 +08:00
|
|
|
zval orig_user_error_handler;
|
2007-01-12 00:47:32 +08:00
|
|
|
zend_bool in_compilation;
|
|
|
|
zend_class_entry *saved_class_entry;
|
2015-07-10 08:31:52 +08:00
|
|
|
zend_stack loop_var_stack;
|
2014-08-15 23:10:06 +08:00
|
|
|
zend_stack delayed_oplines_stack;
|
2014-07-04 22:03:45 +08:00
|
|
|
zend_array *symbol_table;
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2012-09-06 15:26:40 +08:00
|
|
|
/* Report about uncaught exception in case of fatal errors */
|
|
|
|
if (EG(exception)) {
|
2014-07-03 03:29:53 +08:00
|
|
|
zend_execute_data *ex;
|
2014-08-28 06:44:06 +08:00
|
|
|
const zend_op *opline;
|
2014-07-03 03:29:53 +08:00
|
|
|
|
2012-09-06 15:26:40 +08:00
|
|
|
switch (type) {
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_ERROR:
|
|
|
|
case E_RECOVERABLE_ERROR:
|
|
|
|
case E_PARSE:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_USER_ERROR:
|
2014-07-03 03:29:53 +08:00
|
|
|
ex = EG(current_execute_data);
|
|
|
|
opline = NULL;
|
|
|
|
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
|
|
|
ex = ex->prev_execute_data;
|
|
|
|
}
|
2014-07-07 19:50:44 +08:00
|
|
|
if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
|
2014-07-03 03:29:53 +08:00
|
|
|
EG(opline_before_exception)) {
|
|
|
|
opline = EG(opline_before_exception);
|
2012-09-06 15:26:40 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_exception_error(EG(exception), E_WARNING);
|
2012-09-06 15:26:40 +08:00
|
|
|
EG(exception) = NULL;
|
2014-07-03 03:29:53 +08:00
|
|
|
if (opline) {
|
|
|
|
ex->opline = opline;
|
2012-09-06 15:26:40 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-28 03:38:11 +08:00
|
|
|
/* Obtain relevant filename and lineno */
|
|
|
|
switch (type) {
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_CORE_WARNING:
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
break;
|
|
|
|
case E_PARSE:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_COMPILE_WARNING:
|
|
|
|
case E_ERROR:
|
|
|
|
case E_NOTICE:
|
2003-11-18 17:25:04 +08:00
|
|
|
case E_STRICT:
|
2008-02-24 01:06:22 +08:00
|
|
|
case E_DEPRECATED:
|
2000-04-28 03:38:11 +08:00
|
|
|
case E_WARNING:
|
|
|
|
case E_USER_ERROR:
|
|
|
|
case E_USER_WARNING:
|
|
|
|
case E_USER_NOTICE:
|
2008-07-21 17:41:00 +08:00
|
|
|
case E_USER_DEPRECATED:
|
2006-05-10 22:04:18 +08:00
|
|
|
case E_RECOVERABLE_ERROR:
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_is_compiling()) {
|
2015-06-30 18:59:27 +08:00
|
|
|
error_filename = ZSTR_VAL(zend_get_compiled_filename());
|
2014-12-14 06:06:14 +08:00
|
|
|
error_lineno = zend_get_compiled_lineno();
|
|
|
|
} else if (zend_is_executing()) {
|
|
|
|
error_filename = zend_get_executed_filename();
|
2014-07-03 05:02:25 +08:00
|
|
|
if (error_filename[0] == '[') { /* [no active file] */
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
error_lineno = zend_get_executed_lineno();
|
2014-07-03 05:02:25 +08:00
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
} else {
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!error_filename) {
|
|
|
|
error_filename = "Unknown";
|
|
|
|
}
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2010-04-24 21:32:30 +08:00
|
|
|
#ifdef HAVE_DTRACE
|
2015-02-07 11:27:42 +08:00
|
|
|
if (DTRACE_ERROR_ENABLED()) {
|
2010-04-24 21:32:30 +08:00
|
|
|
char *dtrace_error_buffer;
|
2015-02-07 11:27:42 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_start(args, format);
|
2015-02-07 11:27:42 +08:00
|
|
|
#endif
|
2010-04-24 21:32:30 +08:00
|
|
|
zend_vspprintf(&dtrace_error_buffer, 0, format, args);
|
2013-08-14 11:42:39 +08:00
|
|
|
DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
|
2010-04-24 21:32:30 +08:00
|
|
|
efree(dtrace_error_buffer);
|
2015-02-07 11:27:42 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_end(args);
|
2015-02-07 11:27:42 +08:00
|
|
|
#endif
|
2010-04-24 21:32:30 +08:00
|
|
|
}
|
|
|
|
#endif /* HAVE_DTRACE */
|
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_start(args, format);
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2013-08-19 08:20:56 +08:00
|
|
|
|
2000-04-19 23:08:06 +08:00
|
|
|
/* if we don't have a user defined error handler */
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|
2008-03-09 05:54:03 +08:00
|
|
|
|| !(EG(user_error_handler_error_reporting) & type)
|
|
|
|
|| EG(error_handling) != EH_NORMAL) {
|
2000-04-28 03:38:11 +08:00
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
} else switch (type) {
|
2000-04-19 23:08:06 +08:00
|
|
|
case E_ERROR:
|
|
|
|
case E_PARSE:
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_CORE_WARNING:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_COMPILE_WARNING:
|
2000-04-28 03:38:11 +08:00
|
|
|
/* The error may not be safe to handle in user-space */
|
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Handle the error in user space */
|
2005-06-28 06:04:41 +08:00
|
|
|
va_copy(usr_copy, args);
|
2017-06-25 22:52:50 +08:00
|
|
|
ZVAL_STR(¶ms[1], zend_vstrpprintf(0, format, usr_copy));
|
2004-12-06 23:50:27 +08:00
|
|
|
va_end(usr_copy);
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_LONG(¶ms[0], type);
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2000-06-29 06:08:47 +08:00
|
|
|
if (error_filename) {
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_STRING(¶ms[2], error_filename);
|
|
|
|
} else {
|
|
|
|
ZVAL_NULL(¶ms[2]);
|
2000-06-29 06:08:47 +08:00
|
|
|
}
|
2003-01-12 20:39:06 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_LONG(¶ms[3], error_lineno);
|
2000-06-29 06:08:47 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
symbol_table = zend_rebuild_symbol_table();
|
2009-10-27 21:02:36 +08:00
|
|
|
|
|
|
|
/* during shutdown the symbol table table can be still null */
|
2014-07-04 22:03:45 +08:00
|
|
|
if (!symbol_table) {
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_NULL(¶ms[4]);
|
2009-10-27 21:02:36 +08:00
|
|
|
} else {
|
2015-02-14 03:20:39 +08:00
|
|
|
ZVAL_ARR(¶ms[4], zend_array_dup(symbol_table));
|
2009-10-27 21:02:36 +08:00
|
|
|
}
|
2000-06-29 23:07:59 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
|
|
|
|
ZVAL_UNDEF(&EG(user_error_handler));
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2007-01-12 00:47:32 +08:00
|
|
|
/* User error handler may include() additinal PHP files.
|
|
|
|
* If an error was generated during comilation PHP will compile
|
2007-10-11 09:03:19 +08:00
|
|
|
* such scripts recursivly, but some CG() variables may be
|
|
|
|
* inconsistent. */
|
2007-01-12 00:47:32 +08:00
|
|
|
|
2013-09-29 23:58:25 +08:00
|
|
|
in_compilation = CG(in_compilation);
|
2007-01-12 00:47:32 +08:00
|
|
|
if (in_compilation) {
|
|
|
|
saved_class_entry = CG(active_class_entry);
|
|
|
|
CG(active_class_entry) = NULL;
|
2015-07-10 08:31:52 +08:00
|
|
|
SAVE_STACK(loop_var_stack);
|
2014-08-15 23:10:06 +08:00
|
|
|
SAVE_STACK(delayed_oplines_stack);
|
2013-09-29 23:58:25 +08:00
|
|
|
CG(in_compilation) = 0;
|
2007-01-12 00:47:32 +08:00
|
|
|
}
|
|
|
|
|
2018-05-29 22:58:06 +08:00
|
|
|
if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params) == SUCCESS) {
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(retval) != IS_UNDEF) {
|
2014-04-30 22:32:42 +08:00
|
|
|
if (Z_TYPE(retval) == IS_FALSE) {
|
2004-05-29 01:28:33 +08:00
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
}
|
2002-11-25 04:15:56 +08:00
|
|
|
zval_ptr_dtor(&retval);
|
|
|
|
}
|
2006-03-28 06:07:38 +08:00
|
|
|
} else if (!EG(exception)) {
|
2000-04-28 03:38:11 +08:00
|
|
|
/* The user error handler failed, use built-in error handler */
|
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
}
|
2003-12-19 22:08:22 +08:00
|
|
|
|
2007-01-12 00:47:32 +08:00
|
|
|
if (in_compilation) {
|
|
|
|
CG(active_class_entry) = saved_class_entry;
|
2015-07-10 08:31:52 +08:00
|
|
|
RESTORE_STACK(loop_var_stack);
|
2014-08-15 23:10:06 +08:00
|
|
|
RESTORE_STACK(delayed_oplines_stack);
|
2013-09-29 23:58:25 +08:00
|
|
|
CG(in_compilation) = 1;
|
2007-01-12 00:47:32 +08:00
|
|
|
}
|
|
|
|
|
2014-02-25 17:35:39 +08:00
|
|
|
zval_ptr_dtor(¶ms[4]);
|
|
|
|
zval_ptr_dtor(¶ms[2]);
|
|
|
|
zval_ptr_dtor(¶ms[1]);
|
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
|
|
|
|
ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
|
2014-02-25 17:35:39 +08:00
|
|
|
} else {
|
2005-05-14 07:08:43 +08:00
|
|
|
zval_ptr_dtor(&orig_user_error_handler);
|
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
break;
|
2000-04-19 23:08:06 +08:00
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2000-04-28 03:38:11 +08:00
|
|
|
va_end(args);
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2001-05-07 03:30:31 +08:00
|
|
|
|
2002-10-08 05:20:23 +08:00
|
|
|
if (type == E_PARSE) {
|
2013-01-02 12:14:44 +08:00
|
|
|
/* eval() errors do not affect exit_status */
|
|
|
|
if (!(EG(current_execute_data) &&
|
2014-07-07 19:50:44 +08:00
|
|
|
EG(current_execute_data)->func &&
|
|
|
|
ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
|
2013-01-02 12:14:44 +08:00
|
|
|
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
|
|
|
|
EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
|
|
|
|
EG(exit_status) = 255;
|
|
|
|
}
|
2001-05-07 03:30:31 +08:00
|
|
|
}
|
2000-04-19 23:08:06 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2015-02-06 18:42:22 +08:00
|
|
|
#ifdef HAVE_NORETURN
|
|
|
|
# ifdef HAVE_NORETURN_ALIAS
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
|
2015-02-06 18:42:22 +08:00
|
|
|
# else
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */
|
2014-09-09 02:34:26 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_error_va_list(type, format, va);
|
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
|
2014-09-09 02:34:26 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_error_va_list(type, format, va);
|
|
|
|
va_end(va);
|
|
|
|
}
|
2014-09-20 13:51:58 +08:00
|
|
|
/* }}} */
|
2015-02-06 18:42:22 +08:00
|
|
|
# endif
|
2005-06-13 19:22:59 +08:00
|
|
|
#endif
|
2000-06-03 09:49:49 +08:00
|
|
|
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
|
2015-07-04 02:41:17 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
2017-12-31 12:35:25 +08:00
|
|
|
|
2015-07-08 00:37:33 +08:00
|
|
|
if (exception_ce) {
|
|
|
|
if (!instanceof_function(exception_ce, zend_ce_error)) {
|
|
|
|
zend_error(E_NOTICE, "Error exceptions must be derived from Error");
|
|
|
|
exception_ce = zend_ce_error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
exception_ce = zend_ce_error;
|
|
|
|
}
|
2015-07-04 05:04:33 +08:00
|
|
|
|
2015-07-04 02:41:17 +08:00
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
|
|
|
|
2015-07-08 00:37:33 +08:00
|
|
|
//TODO: we can't convert compile-time errors to exceptions yet???
|
2015-07-04 05:04:33 +08:00
|
|
|
if (EG(current_execute_data) && !CG(in_compilation)) {
|
2015-07-04 06:28:11 +08:00
|
|
|
zend_throw_exception(exception_ce, message, 0);
|
2015-07-04 05:04:33 +08:00
|
|
|
} else {
|
2015-11-12 14:51:19 +08:00
|
|
|
zend_error(E_ERROR, "%s", message);
|
2015-07-04 02:41:17 +08:00
|
|
|
}
|
2015-07-04 05:04:33 +08:00
|
|
|
|
2015-07-04 02:41:17 +08:00
|
|
|
efree(message);
|
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
|
2015-03-19 00:23:09 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_type_error, message, 0);
|
2015-03-19 00:23:09 +08:00
|
|
|
efree(message);
|
|
|
|
va_end(va);
|
|
|
|
} /* }}} */
|
|
|
|
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
|
2015-03-19 00:23:09 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
2015-04-03 00:52:32 +08:00
|
|
|
if (throw_exception) {
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_type_error, message, 0);
|
2015-03-19 00:23:09 +08:00
|
|
|
} else {
|
2015-11-12 14:35:34 +08:00
|
|
|
zend_error(E_WARNING, "%s", message);
|
2015-03-19 00:23:09 +08:00
|
|
|
}
|
|
|
|
efree(message);
|
|
|
|
|
|
|
|
va_end(va);
|
|
|
|
} /* }}} */
|
2016-08-31 03:09:26 +08:00
|
|
|
|
|
|
|
ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
|
|
|
if (throw_exception) {
|
|
|
|
zend_throw_exception(zend_ce_argument_count_error, message, 0);
|
|
|
|
} else {
|
|
|
|
zend_error(E_WARNING, "%s", message);
|
|
|
|
}
|
|
|
|
efree(message);
|
|
|
|
|
|
|
|
va_end(va);
|
|
|
|
} /* }}} */
|
2015-03-19 00:23:09 +08:00
|
|
|
|
2015-08-19 19:40:56 +08:00
|
|
|
ZEND_API ZEND_COLD void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
|
2000-06-03 09:49:49 +08:00
|
|
|
{
|
|
|
|
#if ZEND_DEBUG
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, format);
|
2000-06-03 15:34:20 +08:00
|
|
|
# ifdef ZEND_WIN32
|
2000-06-03 09:49:49 +08:00
|
|
|
{
|
|
|
|
char output_buf[1024];
|
|
|
|
|
|
|
|
vsnprintf(output_buf, 1024, format, args);
|
|
|
|
OutputDebugString(output_buf);
|
|
|
|
OutputDebugString("\n");
|
|
|
|
if (trigger_break && IsDebuggerPresent()) {
|
|
|
|
DebugBreak();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# else
|
|
|
|
vfprintf(stderr, format, args);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
# endif
|
|
|
|
va_end(args);
|
|
|
|
#endif
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-08-10 03:22:35 +08:00
|
|
|
|
2015-09-23 23:53:22 +08:00
|
|
|
ZEND_API void zend_try_exception_handler() /* {{{ */
|
|
|
|
{
|
|
|
|
if (EG(exception)) {
|
|
|
|
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
|
|
|
|
zval orig_user_exception_handler;
|
|
|
|
zval params[1], retval2;
|
|
|
|
zend_object *old_exception;
|
|
|
|
old_exception = EG(exception);
|
|
|
|
EG(exception) = NULL;
|
|
|
|
ZVAL_OBJ(¶ms[0], old_exception);
|
|
|
|
ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
|
|
|
|
|
2018-05-29 22:58:06 +08:00
|
|
|
if (call_user_function(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params) == SUCCESS) {
|
2015-09-23 23:53:22 +08:00
|
|
|
zval_ptr_dtor(&retval2);
|
|
|
|
if (EG(exception)) {
|
|
|
|
OBJ_RELEASE(EG(exception));
|
|
|
|
EG(exception) = NULL;
|
|
|
|
}
|
|
|
|
OBJ_RELEASE(old_exception);
|
|
|
|
} else {
|
|
|
|
EG(exception) = old_exception;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
|
2000-08-10 03:22:35 +08:00
|
|
|
{
|
|
|
|
va_list files;
|
|
|
|
int i;
|
|
|
|
zend_file_handle *file_handle;
|
2014-07-03 02:03:21 +08:00
|
|
|
zend_op_array *op_array;
|
2003-01-12 20:39:06 +08:00
|
|
|
|
2000-08-10 03:22:35 +08:00
|
|
|
va_start(files, file_count);
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < file_count; i++) {
|
2000-08-10 03:22:35 +08:00
|
|
|
file_handle = va_arg(files, zend_file_handle *);
|
|
|
|
if (!file_handle) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-01-03 17:22:58 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
op_array = zend_compile_file(file_handle, type);
|
2007-11-03 03:40:39 +08:00
|
|
|
if (file_handle->opened_path) {
|
2015-03-04 07:05:28 +08:00
|
|
|
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
|
2005-05-05 00:17:33 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_file_handle(file_handle);
|
2014-07-03 02:03:21 +08:00
|
|
|
if (op_array) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_execute(op_array, retval);
|
|
|
|
zend_exception_restore();
|
2015-09-23 23:53:22 +08:00
|
|
|
zend_try_exception_handler();
|
2001-12-09 04:58:20 +08:00
|
|
|
if (EG(exception)) {
|
2015-09-23 23:53:22 +08:00
|
|
|
zend_exception_error(EG(exception), E_ERROR);
|
2001-08-31 21:11:52 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
destroy_op_array(op_array);
|
2014-08-28 00:49:56 +08:00
|
|
|
efree_size(op_array, sizeof(zend_op_array));
|
2000-08-10 03:22:35 +08:00
|
|
|
} else if (type==ZEND_REQUIRE) {
|
|
|
|
va_end(files);
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
va_end(files);
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-08-10 03:22:35 +08:00
|
|
|
|
2000-09-13 03:47:25 +08:00
|
|
|
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
|
2000-09-13 03:47:25 +08:00
|
|
|
{
|
2011-09-13 21:29:35 +08:00
|
|
|
const char *cur_filename;
|
2000-09-13 03:47:25 +08:00
|
|
|
int cur_lineno;
|
|
|
|
char *compiled_string_description;
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_is_compiling()) {
|
2015-06-30 18:59:27 +08:00
|
|
|
cur_filename = ZSTR_VAL(zend_get_compiled_filename());
|
2014-12-14 06:06:14 +08:00
|
|
|
cur_lineno = zend_get_compiled_lineno();
|
|
|
|
} else if (zend_is_executing()) {
|
|
|
|
cur_filename = zend_get_executed_filename();
|
|
|
|
cur_lineno = zend_get_executed_lineno();
|
2000-09-13 03:47:25 +08:00
|
|
|
} else {
|
|
|
|
cur_filename = "Unknown";
|
|
|
|
cur_lineno = 0;
|
|
|
|
}
|
|
|
|
|
2007-02-24 10:17:47 +08:00
|
|
|
zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
|
2000-09-13 03:47:25 +08:00
|
|
|
return compiled_string_description;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-09-13 03:47:25 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
void free_estring(char **str_p) /* {{{ */
|
2001-01-15 18:52:06 +08:00
|
|
|
{
|
|
|
|
efree(*str_p);
|
|
|
|
}
|
2014-09-20 13:51:58 +08:00
|
|
|
/* }}} */
|
2014-02-17 21:59:18 +08:00
|
|
|
|
2002-08-16 18:12:17 +08:00
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* indent-tabs-mode: t
|
|
|
|
* End:
|
2017-07-05 00:12:45 +08:00
|
|
|
* vim600: sw=4 ts=4 fdm=marker
|
|
|
|
* vim<600: sw=4 ts=4
|
2002-08-16 18:12:17 +08:00
|
|
|
*/
|