summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPGRADING.INTERNALS15
-rw-r--r--Zend/zend.c16
-rw-r--r--Zend/zend.h12
-rw-r--r--Zend/zend_compile.c9
-rw-r--r--Zend/zend_dtrace.c4
-rw-r--r--Zend/zend_execute.c12
-rw-r--r--Zend/zend_execute_API.c2
-rw-r--r--Zend/zend_globals.h2
-rw-r--r--Zend/zend_ini_parser.y1
-rw-r--r--Zend/zend_ini_scanner.l7
-rw-r--r--Zend/zend_language_scanner.l21
-rw-r--r--Zend/zend_llist.c2
-rw-r--r--Zend/zend_stream.c59
-rw-r--r--Zend/zend_stream.h18
-rw-r--r--ext/opcache/ZendAccelerator.c209
-rw-r--r--ext/opcache/ZendAccelerator.h8
-rw-r--r--ext/opcache/zend_accelerator_hash.c26
-rw-r--r--ext/opcache/zend_accelerator_hash.h10
-rw-r--r--ext/opcache/zend_accelerator_module.c32
-rw-r--r--ext/opcache/zend_persist.c6
-rw-r--r--ext/opcache/zend_persist.h4
-rw-r--r--ext/opcache/zend_persist_calc.c6
-rw-r--r--ext/phar/phar.c35
-rw-r--r--ext/phar/phar_internal.h4
-rw-r--r--ext/phar/phar_object.c5
-rw-r--r--ext/phar/util.c6
-rw-r--r--ext/readline/readline_cli.c2
-rw-r--r--ext/spl/php_spl.c22
-rwxr-xr-xext/standard/basic_functions.c22
-rw-r--r--ext/standard/browscap.c7
-rw-r--r--ext/standard/streamsfuncs.c7
-rw-r--r--main/fopen_wrappers.c50
-rw-r--r--main/main.c45
-rw-r--r--main/php_ini.c15
-rw-r--r--main/php_main.h2
-rw-r--r--main/php_streams.h3
-rw-r--r--main/streams/streams.c10
-rw-r--r--sapi/apache2handler/sapi_apache2.c2
-rw-r--r--sapi/cgi/cgi_main.c45
-rw-r--r--sapi/cli/php_cli.c31
-rw-r--r--sapi/cli/php_cli_server.c5
-rw-r--r--sapi/fuzzer/fuzzer-sapi.c2
-rw-r--r--sapi/litespeed/lsapi_main.c22
-rw-r--r--sapi/phpdbg/phpdbg_list.c17
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c5
45 files changed, 441 insertions, 404 deletions
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 2c5d1a944d..d22c88fcf3 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -2,6 +2,7 @@ PHP 8.1 INTERNALS UPGRADE NOTES
1. Internal API changes
a. Removed Zend APIs
+ b. Zend Stream API
2. Build system changes
@@ -16,6 +17,20 @@ PHP 8.1 INTERNALS UPGRADE NOTES
spl_ce_Stringable, spl_ce_Traversable alias class entries have been removed in favor of zend_ce_aggregate,
zend_ce_arrayaccess, zend_ce_countable, zend_ce_iterator, zend_ce_serializable, zend_ce_stringable,
zend_ce_traversable.
+ b. Zend Stream API has been changed to use "zend_string*" instead of "char*"
+ - zend_file_handle.filename now is zend_string*
+ - zend_file_handle.free_filename is removed. Now zend_file_handle.filename is always released.
+ - added zend_file_handle.primary_script flag. SAPIs should set it for main executed script.
+ - added zend_file_handle.in_list flag, which is set when a file_handle is added into CG(open_files)
+ - added zend_stream_init_filename_ex() function, that takes filename as zend_string*
+ - the "filename" parameter of functons zend_stream_open(), php_stream_open_for_zend_ex() and
+ callback zend_stream_open_function() has been removed (it's now passed as a "filename" field of the
+ file_handle parameter)
+ - in zend_fopen() and zend_resolve_path() callbacks filename now passed as zend_string*
+ - file_handles should be destroyed by zend_destroy_file_handle() function (usually in the same function
+ the same function where they were created by zend_stream_init_*()). Previously there were two different
+ destructors zend_destroy_file_handle() and zend_file_handle_dtor().
+ - zend_ini_scanner_globals.filename now is zend_string*
========================
2. Build system changes
diff --git a/Zend/zend.c b/Zend/zend.c
index 9e5c7e2328..822160508a 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -73,15 +73,15 @@ static uint32_t zend_version_info_length;
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
ZEND_API size_t (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write;
-ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
-ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
+ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
+ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
ZEND_API void (*zend_ticks_function)(int ticks);
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
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);
ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
-ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
+ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = NULL;
@@ -515,12 +515,12 @@ ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
}
/* }}} */
-static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
+static FILE *zend_fopen_wrapper(zend_string *filename, zend_string **opened_path) /* {{{ */
{
if (opened_path) {
- *opened_path = zend_string_init(filename, strlen(filename), 0);
+ *opened_path = zend_string_copy(filename);
}
- return fopen(filename, "rb");
+ return fopen(ZSTR_VAL(filename), "rb");
}
/* }}} */
@@ -1674,9 +1674,6 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count
}
if (ret == FAILURE) {
- /* If a failure occurred in one of the earlier files,
- * only destroy the following file handles. */
- zend_file_handle_dtor(file_handle);
continue;
}
@@ -1684,7 +1681,6 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count
if (file_handle->opened_path) {
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
}
- zend_destroy_file_handle(file_handle);
if (op_array) {
zend_execute(op_array, retval);
zend_exception_restore();
diff --git a/Zend/zend.h b/Zend/zend.h
index 44f3baac46..e09884941c 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -215,16 +215,16 @@ typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
size_t (*write_function)(const char *str, size_t str_length);
- FILE *(*fopen_function)(const char *filename, zend_string **opened_path);
+ FILE *(*fopen_function)(zend_string *filename, zend_string **opened_path);
void (*message_handler)(zend_long message, const void *data);
zval *(*get_configuration_directive)(zend_string *name);
void (*ticks_function)(int ticks);
void (*on_timeout)(int seconds);
- zend_result (*stream_open_function)(const char *filename, zend_file_handle *handle);
+ zend_result (*stream_open_function)(zend_file_handle *handle);
void (*printf_to_smart_string_function)(smart_string *buf, const char *format, va_list ap);
void (*printf_to_smart_str_function)(smart_str *buf, const char *format, va_list ap);
char *(*getenv_function)(const char *name, size_t name_len);
- zend_string *(*resolve_path_function)(const char *filename, size_t filename_len);
+ zend_string *(*resolve_path_function)(zend_string *filename);
} zend_utility_functions;
typedef struct _zend_utility_values {
@@ -303,16 +303,16 @@ END_EXTERN_C()
BEGIN_EXTERN_C()
extern ZEND_API size_t (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
extern ZEND_API zend_write_func_t zend_write;
-extern ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
+extern ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
extern ZEND_API void (*zend_ticks_function)(int ticks);
extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
extern ZEND_API void (*zend_on_timeout)(int seconds);
-extern ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
+extern ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
extern void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
extern ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
-extern ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
+extern ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
/* These two callbacks are especially for opcache */
extern ZEND_API zend_result (*zend_post_startup_cb)(void);
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index deff0dbe57..d6b3075357 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -398,13 +398,6 @@ static bool zend_have_seen_symbol(zend_string *name, uint32_t kind) {
return zv && (Z_LVAL_P(zv) & kind) != 0;
}
-ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
-{
-
- zend_file_handle_dtor(fh);
-}
-/* }}} */
-
void init_compiler(void) /* {{{ */
{
CG(arena) = zend_arena_create(64 * 1024);
@@ -412,7 +405,7 @@ void init_compiler(void) /* {{{ */
memset(&CG(context), 0, sizeof(CG(context)));
zend_init_compiler_data_structures();
zend_init_rsrc_list();
- zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
+ zend_stream_init();
CG(unclean_shutdown) = 0;
CG(delayed_variance_obligations) = NULL;
diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c
index 935421121e..cce810c177 100644
--- a/Zend/zend_dtrace.c
+++ b/Zend/zend_dtrace.c
@@ -44,9 +44,9 @@ static inline const char *dtrace_get_executed_filename(void)
ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type)
{
zend_op_array *res;
- DTRACE_COMPILE_FILE_ENTRY(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
+ DTRACE_COMPILE_FILE_ENTRY(ZSTR_VAL(file_handle->opened_path), ZSTR_VAL(file_handle->filename));
res = compile_file(file_handle, type);
- DTRACE_COMPILE_FILE_RETURN(ZSTR_VAL(file_handle->opened_path), (char *)file_handle->filename);
+ DTRACE_COMPILE_FILE_RETURN(ZSTR_VAL(file_handle->opened_path), ZSTR_VAL(file_handle->filename));
return res;
}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index ce2901d52c..9f69041257 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -4222,10 +4222,12 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
zend_file_handle file_handle;
zend_string *resolved_path;
- resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
+ resolved_path = zend_resolve_path(Z_STR_P(inc_filename));
if (EXPECTED(resolved_path)) {
if (zend_hash_exists(&EG(included_files), resolved_path)) {
- goto already_compiled;
+ new_op_array = ZEND_FAKE_OP_ARRAY;
+ zend_string_release_ex(resolved_path, 0);
+ break;
}
} else if (UNEXPECTED(EG(exception))) {
break;
@@ -4239,7 +4241,8 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
resolved_path = zend_string_copy(Z_STR_P(inc_filename));
}
- if (SUCCESS == zend_stream_open(ZSTR_VAL(resolved_path), &file_handle)) {
+ zend_stream_init_filename_ex(&file_handle, resolved_path);
+ if (SUCCESS == zend_stream_open(&file_handle)) {
if (!file_handle.opened_path) {
file_handle.opened_path = zend_string_copy(resolved_path);
@@ -4254,8 +4257,6 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
}
return op_array;
} else {
- zend_file_handle_dtor(&file_handle);
-already_compiled:
new_op_array = ZEND_FAKE_OP_ARRAY;
}
} else if (!EG(exception)) {
@@ -4264,6 +4265,7 @@ already_compiled:
ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN,
Z_STRVAL_P(inc_filename));
}
+ zend_destroy_file_handle(&file_handle);
zend_string_release_ex(resolved_path, 0);
}
break;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 4e8c1d5a1f..f61a865ddc 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -264,7 +264,7 @@ void shutdown_executor(void) /* {{{ */
#endif
zend_try {
- zend_llist_destroy(&CG(open_files));
+ zend_stream_shutdown();
} zend_end_try();
EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index e9b24fc0e3..6ea35f3f36 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -270,7 +270,7 @@ struct _zend_ini_scanner_globals {
int yy_state;
zend_stack state_stack;
- char *filename;
+ zend_string *filename;
int lineno;
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
index 6d9dd09e34..7eb3753520 100644
--- a/Zend/zend_ini_parser.y
+++ b/Zend/zend_ini_parser.y
@@ -227,7 +227,6 @@ ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_e
CG(ini_parser_unbuffered_errors) = unbuffered_errors;
retval = ini_parse();
- zend_file_handle_dtor(fh);
shutdown_ini_scanner();
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index 1d689f3748..b75387714d 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -231,7 +231,7 @@ static zend_result init_ini_scanner(int scanner_mode, zend_file_handle *fh)
SCNG(yy_in) = fh;
if (fh != NULL) {
- ini_filename = zend_strndup(fh->filename, strlen(fh->filename));
+ ini_filename = zend_string_copy(fh->filename);
} else {
ini_filename = NULL;
}
@@ -248,7 +248,7 @@ void shutdown_ini_scanner(void)
{
zend_stack_destroy(&SCNG(state_stack));
if (ini_filename) {
- free(ini_filename);
+ zend_string_release(ini_filename);
}
}
/* }}} */
@@ -263,7 +263,7 @@ ZEND_COLD int zend_ini_scanner_get_lineno(void)
/* {{{ zend_ini_scanner_get_filename() */
ZEND_COLD char *zend_ini_scanner_get_filename(void)
{
- return ini_filename ? ini_filename : "Unknown";
+ return ini_filename ? ZSTR_VAL(ini_filename) : "Unknown";
}
/* }}} */
@@ -278,7 +278,6 @@ zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mo
}
if (init_ini_scanner(scanner_mode, fh) == FAILURE) {
- zend_file_handle_dtor(fh);
return FAILURE;
}
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index c639fa3209..02714b4e1f 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -297,16 +297,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state)
RESET_DOC_COMMENT();
}
-ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
-{
- zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
- /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
- file_handle->opened_path = NULL;
- if (file_handle->free_filename) {
- file_handle->filename = NULL;
- }
-}
-
ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident)
{
unsigned char *end = ident;
@@ -542,11 +532,13 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
if (zend_stream_fixup(file_handle, &buf, &size) == FAILURE) {
/* Still add it to open_files to make destroy_file_handle work */
zend_llist_add_element(&CG(open_files), file_handle);
+ file_handle->in_list = 1;
return FAILURE;
}
ZEND_ASSERT(!EG(exception) && "stream_fixup() should have failed");
zend_llist_add_element(&CG(open_files), file_handle);
+ file_handle->in_list = 1;
/* Reset the scanner for scanning the new file */
SCNG(yy_in) = file_handle;
@@ -584,7 +576,7 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
if (file_handle->opened_path) {
compiled_filename = zend_string_copy(file_handle->opened_path);
} else {
- compiled_filename = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
+ compiled_filename = zend_string_copy(file_handle->filename);
}
zend_set_compiled_filename(compiled_filename);
@@ -655,9 +647,9 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
if (open_file_for_scanning(file_handle)==FAILURE) {
if (!EG(exception)) {
if (type==ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
} else {
@@ -715,7 +707,7 @@ zend_op_array *compile_filename(int type, zval *filename)
ZVAL_STR(&tmp, zval_get_string(filename));
filename = &tmp;
}
- zend_stream_init_filename(&file_handle, Z_STRVAL_P(filename));
+ zend_stream_init_filename_ex(&file_handle, Z_STR_P(filename));
retval = zend_compile_file(&file_handle, type);
if (retval && file_handle.handle.stream.handle) {
@@ -837,6 +829,7 @@ zend_result highlight_file(const char *filename, zend_syntax_highlighter_ini *sy
zend_save_lexical_state(&original_lex_state);
if (open_file_for_scanning(&file_handle)==FAILURE) {
zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename);
+ zend_destroy_file_handle(&file_handle);
zend_restore_lexical_state(&original_lex_state);
return FAILURE;
}
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
index 78a3310438..8c42b2494e 100644
--- a/Zend/zend_llist.c
+++ b/Zend/zend_llist.c
@@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
current = next;
}
+ l->head = NULL;
+ l->tail = NULL;
l->count = 0;
}
diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c
index 1dfc5b1bc1..aadc62558e 100644
--- a/Zend/zend_stream.c
+++ b/Zend/zend_stream.c
@@ -64,25 +64,36 @@ ZEND_API void zend_stream_init_fp(zend_file_handle *handle, FILE *fp, const char
memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_FP;
handle->handle.fp = fp;
- handle->filename = filename;
+ handle->filename = filename ? zend_string_init(filename, strlen(filename), 0) : NULL;
}
ZEND_API void zend_stream_init_filename(zend_file_handle *handle, const char *filename) {
memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_FILENAME;
- handle->filename = filename;
+ handle->filename = filename ? zend_string_init(filename, strlen(filename), 0) : NULL;
}
-ZEND_API zend_result zend_stream_open(const char *filename, zend_file_handle *handle) /* {{{ */
+ZEND_API void zend_stream_init_filename_ex(zend_file_handle *handle, zend_string *filename) {
+ memset(handle, 0, sizeof(zend_file_handle));
+ handle->type = ZEND_HANDLE_FILENAME;
+ handle->filename = zend_string_copy(filename);
+}
+
+ZEND_API zend_result zend_stream_open(zend_file_handle *handle) /* {{{ */
{
zend_string *opened_path;
+
+ ZEND_ASSERT(handle->type == ZEND_HANDLE_FILENAME);
if (zend_stream_open_function) {
- return zend_stream_open_function(filename, handle);
+ return zend_stream_open_function(handle);
}
- zend_stream_init_fp(handle, zend_fopen(filename, &opened_path), filename);
- handle->opened_path = opened_path;
- return handle->handle.fp ? SUCCESS : FAILURE;
+ handle->handle.fp = zend_fopen(handle->filename, &opened_path);
+ if (!handle->handle.fp) {
+ return FAILURE;
+ }
+ handle->type = ZEND_HANDLE_FP;
+ return SUCCESS;
} /* }}} */
static int zend_stream_getc(zend_file_handle *file_handle) /* {{{ */
@@ -124,7 +135,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf
}
if (file_handle->type == ZEND_HANDLE_FILENAME) {
- if (zend_stream_open(file_handle->filename, file_handle) == FAILURE) {
+ if (zend_stream_open(file_handle) == FAILURE) {
return FAILURE;
}
}
@@ -199,7 +210,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf
return SUCCESS;
} /* }}} */
-ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */
+static void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */
{
switch (fh->type) {
case ZEND_HANDLE_FP:
@@ -225,22 +236,22 @@ ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */
efree(fh->buf);
fh->buf = NULL;
}
- if (fh->free_filename && fh->filename) {
- efree((char*)fh->filename);
+ if (fh->filename) {
+ zend_string_release(fh->filename);
fh->filename = NULL;
}
}
/* }}} */
/* return int to be compatible with Zend linked list API */
-ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) /* {{{ */
+static int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) /* {{{ */
{
if (fh1->type != fh2->type) {
return 0;
}
switch (fh1->type) {
case ZEND_HANDLE_FILENAME:
- return strcmp(fh1->filename, fh2->filename) == 0;
+ return zend_string_equals(fh1->filename, fh2->filename);
case ZEND_HANDLE_FP:
return fh1->handle.fp == fh2->handle.fp;
case ZEND_HANDLE_STREAM:
@@ -250,3 +261,25 @@ ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *
}
return 0;
} /* }}} */
+
+ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle) /* {{{ */
+{
+ if (file_handle->in_list) {
+ zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
+ /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
+ file_handle->opened_path = NULL;
+ file_handle->filename = NULL;
+ } else {
+ zend_file_handle_dtor(file_handle);
+ }
+} /* }}} */
+
+void zend_stream_init(void) /* {{{ */
+{
+ zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_file_handle_dtor, 0);
+} /* }}} */
+
+void zend_stream_shutdown(void) /* {{{ */
+{
+ zend_llist_destroy(&CG(open_files));
+} /* }}} */
diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h
index e97a796730..047719e175 100644
--- a/Zend/zend_stream.h
+++ b/Zend/zend_stream.h
@@ -53,12 +53,11 @@ typedef struct _zend_file_handle {
FILE *fp;
zend_stream stream;
} handle;
- const char *filename;
+ zend_string *filename;
zend_string *opened_path;
- zend_stream_type type;
- /* free_filename is used by wincache */
- /* TODO: Clean up filename vs opened_path mess */
- bool free_filename;
+ zend_uchar type; /* packed zend_stream_type */
+ bool primary_script;
+ bool in_list; /* added into CG(open_file) */
char *buf;
size_t len;
} zend_file_handle;
@@ -66,10 +65,13 @@ typedef struct _zend_file_handle {
BEGIN_EXTERN_C()
ZEND_API void zend_stream_init_fp(zend_file_handle *handle, FILE *fp, const char *filename);
ZEND_API void zend_stream_init_filename(zend_file_handle *handle, const char *filename);
-ZEND_API zend_result zend_stream_open(const char *filename, zend_file_handle *handle);
+ZEND_API void zend_stream_init_filename_ex(zend_file_handle *handle, zend_string *filename);
+ZEND_API zend_result zend_stream_open(zend_file_handle *handle);
ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len);
-ZEND_API void zend_file_handle_dtor(zend_file_handle *fh);
-ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
+ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle);
+
+void zend_stream_init(void);
+void zend_stream_shutdown(void);
END_EXTERN_C()
#ifdef ZEND_WIN32
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index d2349b90bd..5ef84b2a2a 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -120,8 +120,8 @@ bool fallback_process = 0; /* process uses file cache fallback */
static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type);
static zend_class_entry* (*accelerator_orig_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces);
static zend_class_entry* (*accelerator_orig_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies);
-static zend_result (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle );
-static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len);
+static zend_result (*accelerator_orig_zend_stream_open_function)(zend_file_handle *handle );
+static zend_string *(*accelerator_orig_zend_resolve_path)(zend_string *filename);
static void (*accelerator_orig_zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
static zif_handler orig_chdir = NULL;
static ZEND_INI_MH((*orig_include_path_on_modify)) = NULL;
@@ -952,7 +952,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_
if (sapi_module.get_stat &&
!EG(current_execute_data) &&
- file_handle->filename == SG(request_info).path_translated) {
+ file_handle->primary_script) {
zend_stat_t *tmpbuf = sapi_module.get_stat();
@@ -974,7 +974,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_
switch (file_handle->type) {
case ZEND_HANDLE_FP:
if (zend_fstat(fileno(file_handle->handle.fp), &statbuf) == -1) {
- if (zend_get_stream_timestamp(file_handle->filename, &statbuf) != SUCCESS) {
+ if (zend_get_stream_timestamp(ZSTR_VAL(file_handle->filename), &statbuf) != SUCCESS) {
return 0;
}
}
@@ -993,7 +993,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_
}
}
- if (zend_get_stream_timestamp(file_handle->filename, &statbuf) != SUCCESS) {
+ if (zend_get_stream_timestamp(ZSTR_VAL(file_handle->filename), &statbuf) != SUCCESS) {
return 0;
}
break;
@@ -1039,6 +1039,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri
{
zend_file_handle ps_handle;
zend_string *full_path_ptr = NULL;
+ int ret;
/** check that the persistent script is indeed the same file we cached
* (if part of the path is a symlink than it possible that the user will change it)
@@ -1050,7 +1051,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri
return FAILURE;
}
} else {
- full_path_ptr = accelerator_orig_zend_resolve_path(file_handle->filename, strlen(file_handle->filename));
+ full_path_ptr = accelerator_orig_zend_resolve_path(file_handle->filename);
if (full_path_ptr &&
persistent_script->script.filename != full_path_ptr &&
!zend_string_equal_content(persistent_script->script.filename, full_path_ptr)) {
@@ -1080,14 +1081,15 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri
file_handle->opened_path = NULL;
}
- zend_stream_init_filename(&ps_handle, ZSTR_VAL(persistent_script->script.filename));
+ zend_stream_init_filename_ex(&ps_handle, persistent_script->script.filename);
ps_handle.opened_path = persistent_script->script.filename;
- if (zend_get_file_handle_timestamp(&ps_handle, NULL) == persistent_script->timestamp) {
- return SUCCESS;
- }
+ ret = zend_get_file_handle_timestamp(&ps_handle, NULL) == persistent_script->timestamp
+ ? SUCCESS : FAILURE;
- return FAILURE;
+ zend_destroy_file_handle(&ps_handle);
+
+ return ret;
}
int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle)
@@ -1119,23 +1121,25 @@ int validate_timestamp_and_record_ex(zend_persistent_script *persistent_script,
/* Instead of resolving full real path name each time we need to identify file,
* we create a key that consist from requested file name, current working
* directory, current include_path, etc */
-char *accel_make_persistent_key(const char *path, size_t path_length, int *key_len)
+zend_string *accel_make_persistent_key(zend_string *str)
{
+ const char *path = ZSTR_VAL(str);
+ size_t path_length = ZSTR_LEN(str);
+ char *key;
int key_length;
+ ZSTR_LEN(&ZCG(key)) = 0;
+
/* CWD and include_path don't matter for absolute file names and streams */
if (IS_ABSOLUTE_PATH(path, path_length)) {
/* pass */
- ZCG(key_len) = 0;
} else if (UNEXPECTED(is_stream_path(path))) {
if (!is_cacheable_stream_path(path)) {
return NULL;
}
/* pass */
- ZCG(key_len) = 0;
} else if (UNEXPECTED(!ZCG(accel_directives).use_cwd)) {
/* pass */
- ZCG(key_len) = 0;
} else {
const char *include_path = NULL, *cwd = NULL;
int include_path_len = 0, cwd_len = 0;
@@ -1233,7 +1237,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l
}
/* Calculate key length */
- if (UNEXPECTED((size_t)(cwd_len + path_length + include_path_len + 2) >= sizeof(ZCG(key)))) {
+ if (UNEXPECTED((size_t)(cwd_len + path_length + include_path_len + 2) >= sizeof(ZCG(_key)))) {
return NULL;
}
@@ -1242,16 +1246,17 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l
* since in itself, it may include colons (which we use to separate
* different components of the key)
*/
- memcpy(ZCG(key), path, path_length);
- ZCG(key)[path_length] = ':';
+ key = ZSTR_VAL(&ZCG(key));
+ memcpy(key, path, path_length);
+ key[path_length] = ':';
key_length = path_length + 1;
- memcpy(ZCG(key) + key_length, cwd, cwd_len);
+ memcpy(key + key_length, cwd, cwd_len);
key_length += cwd_len;
if (include_path_len) {
- ZCG(key)[key_length] = ':';
+ key[key_length] = ':';
key_length += 1;
- memcpy(ZCG(key) + key_length, include_path, include_path_len);
+ memcpy(key + key_length, include_path, include_path_len);
key_length += include_path_len;
}
@@ -1265,25 +1270,27 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l
parent_script_len = ZSTR_LEN(parent_script);
while ((--parent_script_len > 0) && !IS_SLASH(ZSTR_VAL(parent_script)[parent_script_len]));
- if (UNEXPECTED((size_t)(key_length + parent_script_len + 1) >= sizeof(ZCG(key)))) {
+ if (UNEXPECTED((size_t)(key_length + parent_script_len + 1) >= sizeof(ZCG(_key)))) {
return NULL;
}
- ZCG(key)[key_length] = ':';
+ key[key_length] = ':';
key_length += 1;
- memcpy(ZCG(key) + key_length, ZSTR_VAL(parent_script), parent_script_len);
+ memcpy(key + key_length, ZSTR_VAL(parent_script), parent_script_len);
key_length += parent_script_len;
}
- ZCG(key)[key_length] = '\0';
- *key_len = ZCG(key_len) = key_length;
- return ZCG(key);
+ key[key_length] = '\0';
+ GC_SET_REFCOUNT(&ZCG(key), 1);
+ GC_TYPE_INFO(&ZCG(key)) = GC_STRING;
+ ZSTR_H(&ZCG(key)) = 0;
+ ZSTR_LEN(&ZCG(key)) = key_length;
+ return &ZCG(key);
}
/* not use_cwd */
- *key_len = path_length;
- return (char*)path;
+ return str;
}
-int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
+int zend_accel_invalidate(zend_string *filename, bool force)
{
zend_string *realpath;
zend_persistent_script *persistent_script;
@@ -1292,7 +1299,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
return FAILURE;
}
- realpath = accelerator_orig_zend_resolve_path(filename, filename_len);
+ realpath = accelerator_orig_zend_resolve_path(filename);
if (!realpath) {
return FAILURE;
@@ -1305,7 +1312,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
persistent_script = zend_accel_hash_find(&ZCSG(hash), realpath);
if (persistent_script && !persistent_script->corrupted) {
zend_file_handle file_handle;
- zend_stream_init_filename(&file_handle, ZSTR_VAL(realpath));
+ zend_stream_init_filename_ex(&file_handle, realpath);
file_handle.opened_path = realpath;
if (force ||
@@ -1328,6 +1335,9 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
}
+
+ file_handle.opened_path = NULL;
+ zend_destroy_file_handle(&file_handle);
}
accelerator_shm_read_unlock();
@@ -1337,18 +1347,18 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
}
/* Adds another key for existing cached script */
-static void zend_accel_add_key(const char *key, unsigned int key_length, zend_accel_hash_entry *bucket)
+static void zend_accel_add_key(zend_string *key, zend_accel_hash_entry *bucket)
{
- if (!zend_accel_hash_str_find(&ZCSG(hash), key, key_length)) {
+ if (!zend_accel_hash_find(&ZCSG(hash), key)) {
if (zend_accel_hash_is_full(&ZCSG(hash))) {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1;
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH);
} else {
- char *new_key = zend_shared_alloc(key_length + 1);
+ char *new_key = zend_shared_alloc(ZSTR_LEN(key) + 1);
if (new_key) {
- memcpy(new_key, key, key_length + 1);
- if (zend_accel_hash_update(&ZCSG(hash), new_key, key_length, 1, bucket)) {
+ memcpy(new_key, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
+ if (zend_accel_hash_update(&ZCSG(hash), new_key, ZSTR_LEN(key), 1, bucket)) {
zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", new_key);
}
} else {
@@ -1372,7 +1382,7 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script
zend_shared_alloc_init_xlat_table();
/* Calculate the required memory size */
- memory_used = zend_accel_script_persist_calc(new_persistent_script, NULL, 0, 0);
+ memory_used = zend_accel_script_persist_calc(new_persistent_script, 0);
/* Allocate memory block */
#if defined(__AVX__) || defined(__SSE2__)
@@ -1390,7 +1400,7 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script
zend_shared_alloc_clear_xlat_table();
/* Copy into memory block */
- new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0, 0);
+ new_persistent_script = zend_accel_script_persist(new_persistent_script, 0);
zend_shared_alloc_destroy_xlat_table();
@@ -1430,7 +1440,7 @@ static zend_persistent_script *cache_script_in_file_cache(zend_persistent_script
return store_script_in_file_cache(new_persistent_script);
}
-static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_script *new_persistent_script, const char *key, unsigned int key_length, int *from_shared_memory)
+static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_script *new_persistent_script, zend_string *key, int *from_shared_memory)
{
zend_accel_hash_entry *bucket;
uint32_t memory_used;
@@ -1460,7 +1470,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
if (key &&
(!ZCG(accel_directives).validate_timestamps ||
(new_persistent_script->timestamp == existing_persistent_script->timestamp))) {
- zend_accel_add_key(key, key_length, bucket);
+ zend_accel_add_key(key, bucket);
}
zend_shared_alloc_unlock();
#if 1
@@ -1489,7 +1499,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
zend_shared_alloc_init_xlat_table();
/* Calculate the required memory size */
- memory_used = zend_accel_script_persist_calc(new_persistent_script, key, key_length, 1);
+ memory_used = zend_accel_script_persist_calc(new_persistent_script, 1);
/* Allocate shared memory */
#if defined(__AVX__) || defined(__SSE2__)
@@ -1547,7 +1557,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
zend_shared_alloc_clear_xlat_table();
/* Copy into shared memory */
- new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length, 1);
+ new_persistent_script = zend_accel_script_persist(new_persistent_script, 1);
zend_shared_alloc_destroy_xlat_table();
@@ -1573,15 +1583,21 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
if (key &&
/* key may contain non-persistent PHAR aliases (see issues #115 and #149) */
memcmp(key, "phar://", sizeof("phar://") - 1) != 0 &&
- (ZSTR_LEN(new_persistent_script->script.filename) != key_length ||
- memcmp(ZSTR_VAL(new_persistent_script->script.filename), key, key_length) != 0)) {
+ !zend_string_equals(new_persistent_script->script.filename, key)) {
/* link key to the same persistent script in hash table */
- if (zend_accel_hash_update(&ZCSG(hash), key, key_length, 1, bucket)) {
- zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", key);
+ char *new_key = zend_shared_alloc(ZSTR_LEN(key) + 1);
+
+ if (new_key) {
+ memcpy(new_key, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
+ if (zend_accel_hash_update(&ZCSG(hash), new_key, ZSTR_LEN(key), 1, bucket)) {
+ zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", ZSTR_VAL(key));
+ } else {
+ zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
+ ZSMMG(memory_exhausted) = 1;
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH);
+ }
} else {
- zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
- ZSMMG(memory_exhausted) = 1;
- zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH);
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
}
}
}
@@ -1701,7 +1717,7 @@ static void free_recorded_warnings() {
ZCG(num_warnings) = 0;
}
-static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handle, int type, const char *key, zend_op_array **op_array_p)
+static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handle, int type, zend_op_array **op_array_p)
{
zend_persistent_script *new_persistent_script;
uint32_t orig_functions_count, orig_class_count;
@@ -1714,13 +1730,13 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
/* Try to open file */
if (file_handle->type == ZEND_HANDLE_FILENAME) {
- if (accelerator_orig_zend_stream_open_function(file_handle->filename, file_handle) != SUCCESS) {
+ if (accelerator_orig_zend_stream_open_function(file_handle) != SUCCESS) {
*op_array_p = NULL;
if (!EG(exception)) {
if (type == ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
return NULL;
@@ -1852,7 +1868,7 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
if (file_handle->opened_path) {
new_persistent_script->script.filename = zend_string_copy(file_handle->opened_path);
} else {
- new_persistent_script->script.filename = zend_string_init(file_handle->filename, strlen(file_handle->filename), 0);
+ new_persistent_script->script.filename = zend_string_copy(file_handle->filename);
}
zend_string_hash_val(new_persistent_script->script.filename);
@@ -1866,19 +1882,19 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
zend_op_array *op_array = NULL;
int from_memory; /* if the script we've got is stored in SHM */
- if (is_stream_path(file_handle->filename) &&
- !is_cacheable_stream_path(file_handle->filename)) {
+ if (is_stream_path(ZSTR_VAL(file_handle->filename)) &&
+ !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename))) {
return accelerator_orig_compile_file(file_handle, type);
}
if (!file_handle->opened_path) {
if (file_handle->type == ZEND_HANDLE_FILENAME &&
- accelerator_orig_zend_stream_open_function(file_handle->filename, file_handle) == FAILURE) {
+ accelerator_orig_zend_stream_open_function(file_handle) == FAILURE) {
if (!EG(exception)) {
if (type == ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
return NULL;
@@ -1914,7 +1930,6 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
}
}
replay_warnings(persistent_script);
- zend_file_handle_dtor(file_handle);
if (persistent_script->ping_auto_globals_mask) {
zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask);
@@ -1923,7 +1938,7 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
return zend_accel_load_script(persistent_script, 1);
}
- persistent_script = opcache_compile_file(file_handle, type, NULL, &op_array);
+ persistent_script = opcache_compile_file(file_handle, type, &op_array);
if (persistent_script) {
from_memory = 0;
@@ -1961,8 +1976,7 @@ int check_persistent_script_access(zend_persistent_script *persistent_script)
zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
{
zend_persistent_script *persistent_script = NULL;
- char *key = NULL;
- int key_length;
+ zend_string *key = NULL;
int from_shared_memory; /* if the script we've got is stored in SHM */
if (!file_handle->filename || !ZCG(accelerator_enabled)) {
@@ -1994,7 +2008,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
* persistent script already found */
if (ZCG(cache_persistent_script) &&
((!EG(current_execute_data) &&
- file_handle->filename == SG(request_info).path_translated &&
+ file_handle->primary_script &&
ZCG(cache_opline) == NULL) ||
(EG(current_execute_data) &&
EG(current_execute_data)->func &&
@@ -2002,22 +2016,21 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
ZCG(cache_opline) == EG(current_execute_data)->opline))) {
persistent_script = ZCG(cache_persistent_script);
- if (ZCG(key_len)) {
- key = ZCG(key);
- key_length = ZCG(key_len);
+ if (ZSTR_LEN(&ZCG(key))) {
+ key = &ZCG(key);
}
} else {
if (!ZCG(accel_directives).revalidate_path) {
/* try to find cached script by key */
- key = accel_make_persistent_key(file_handle->filename, strlen(file_handle->filename), &key_length);
+ key = accel_make_persistent_key(file_handle->filename);
if (!key) {
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type);
}
- persistent_script = zend_accel_hash_str_find(&ZCSG(hash), key, key_length);
- } else if (UNEXPECTED(is_stream_path(file_handle->filename) && !is_cacheable_stream_path(file_handle->filename))) {
+ persistent_script = zend_accel_hash_find(&ZCSG(hash), key);
+ } else if (UNEXPECTED(is_stream_path(ZSTR_VAL(file_handle->filename)) && !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename)))) {
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type);
@@ -2028,13 +2041,13 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
zend_accel_hash_entry *bucket;
/* open file to resolve the path */
- if (file_handle->type == ZEND_HANDLE_FILENAME &&
- accelerator_orig_zend_stream_open_function(file_handle->filename, file_handle) == FAILURE) {
+ if (file_handle->type == ZEND_HANDLE_FILENAME
+ && accelerator_orig_zend_stream_open_function(file_handle) == FAILURE) {
if (!EG(exception)) {
if (type == ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
return NULL;
@@ -2050,7 +2063,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT();
zend_shared_alloc_lock();
- zend_accel_add_key(key, key_length, bucket);
+ zend_accel_add_key(key, bucket);
zend_shared_alloc_unlock();
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
@@ -2089,9 +2102,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
UNEXPECTED(check_persistent_script_access(persistent_script))) {
if (!EG(exception)) {
if (type == ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file_handle->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
}
}
return NULL;
@@ -2169,7 +2182,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
- persistent_script = opcache_compile_file(file_handle, type, key, &op_array);
+ persistent_script = opcache_compile_file(file_handle, type, &op_array);
HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT();
@@ -2178,7 +2191,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
*/
from_shared_memory = 0;
if (persistent_script) {
- persistent_script = cache_script_in_shared_memory(persistent_script, key, key ? key_length : 0, &from_shared_memory);
+ persistent_script = cache_script_in_shared_memory(persistent_script, key, &from_shared_memory);
}
/* Caching is disabled, returning op_array;
@@ -2234,7 +2247,6 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
}
}
replay_warnings(persistent_script);
- zend_file_handle_dtor(file_handle);
from_shared_memory = 1;
}
@@ -2478,12 +2490,12 @@ static int accel_gen_uname_id(void)
#endif
/* zend_stream_open_function() replacement for PHP 5.3 and above */
-static zend_result persistent_stream_open_function(const char *filename, zend_file_handle *handle)
+static zend_result persistent_stream_open_function(zend_file_handle *handle)
{
if (ZCG(cache_persistent_script)) {
/* check if callback is called from include_once or it's a main request */
if ((!EG(current_execute_data) &&
- filename == SG(request_info).path_translated &&
+ handle->primary_script &&
ZCG(cache_opline) == NULL) ||
(EG(current_execute_data) &&
EG(current_execute_data)->func &&
@@ -2491,25 +2503,23 @@ static zend_result persistent_stream_open_function(const char *filename, zend_fi
ZCG(cache_opline) == EG(current_execute_data)->opline)) {
/* we are in include_once or FastCGI request */
- zend_stream_init_filename(handle, (char*) filename);
handle->opened_path = zend_string_copy(ZCG(cache_persistent_script)->script.filename);
return SUCCESS;
}
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
}
- return accelerator_orig_zend_stream_open_function(filename, handle);
+ return accelerator_orig_zend_stream_open_function(handle);
}
/* zend_resolve_path() replacement for PHP 5.3 and above */
-static zend_string* persistent_zend_resolve_path(const char *filename, size_t filename_len)
+static zend_string* persistent_zend_resolve_path(zend_string *filename)
{
if (!file_cache_only &&
ZCG(accelerator_enabled)) {
/* check if callback is called from include_once or it's a main request */
- if ((!EG(current_execute_data) &&
- filename == SG(request_info).path_translated) ||
+ if ((!EG(current_execute_data)) ||
(EG(current_execute_data) &&
EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
@@ -2519,14 +2529,13 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi
/* we are in include_once or FastCGI request */
zend_string *resolved_path;
- int key_length;
- char *key = NULL;
+ zend_string *key = NULL;
if (!ZCG(accel_directives).revalidate_path) {
/* lookup by "not-real" path */
- key = accel_make_persistent_key(filename, filename_len, &key_length);
+ key = accel_make_persistent_key(filename);
if (key) {
- zend_accel_hash_entry *bucket = zend_accel_hash_str_find_entry(&ZCSG(hash), key, key_length);
+ zend_accel_hash_entry *bucket = zend_accel_hash_find_entry(&ZCSG(hash), key);
if (bucket != NULL) {
zend_persistent_script *persistent_script = (zend_persistent_script *)bucket->data;
if (!persistent_script->corrupted) {
@@ -2538,12 +2547,12 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi
} else {
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
- return accelerator_orig_zend_resolve_path(filename, filename_len);
+ return accelerator_orig_zend_resolve_path(filename);
}
}
/* find the full real path */
- resolved_path = accelerator_orig_zend_resolve_path(filename, filename_len);
+ resolved_path = accelerator_orig_zend_resolve_path(filename);
if (resolved_path) {
/* lookup by real path */
@@ -2556,12 +2565,12 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi
HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT();
zend_shared_alloc_lock();
- zend_accel_add_key(key, key_length, bucket);
+ zend_accel_add_key(key, bucket);
zend_shared_alloc_unlock();
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
} else {
- ZCG(key_len) = 0;
+ ZSTR_LEN(&ZCG(key)) = 0;
}
ZCG(cache_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL;
ZCG(cache_persistent_script) = persistent_script;
@@ -2577,7 +2586,7 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi
}
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
- return accelerator_orig_zend_resolve_path(filename, filename_len);
+ return accelerator_orig_zend_resolve_path(filename);
}
static void zend_reset_cache_vars(void)
@@ -4211,7 +4220,7 @@ static zend_string *preload_resolve_path(zend_string *filename)
if (is_stream_path(ZSTR_VAL(filename))) {
return NULL;
}
- return zend_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename));
+ return zend_resolve_path(filename);
}
static void preload_remove_empty_includes(void)
@@ -4393,7 +4402,7 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
checkpoint = zend_shared_alloc_checkpoint_xlat_table();
/* Calculate the required memory size */
- memory_used = zend_accel_script_persist_calc(new_persistent_script, NULL, 0, 1);
+ memory_used = zend_accel_script_persist_calc(new_persistent_script, 1);
/* Allocate shared memory */
#if defined(__AVX__) || defined(__SSE2__)
@@ -4445,7 +4454,7 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
zend_shared_alloc_restore_xlat_table(checkpoint);
/* Copy into shared memory */
- new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0, 1);
+ new_persistent_script = zend_accel_script_persist(new_persistent_script, 1);
new_persistent_script->is_phar = is_phar_file(new_persistent_script->script.filename);
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
index 663cffca14..fab1b71666 100644
--- a/ext/opcache/ZendAccelerator.h
+++ b/ext/opcache/ZendAccelerator.h
@@ -234,8 +234,8 @@ typedef struct _zend_accel_globals {
const zend_op *cache_opline;
zend_persistent_script *cache_persistent_script;
/* preallocated buffer for keys */
- int key_len;
- char key[MAXPATHLEN * 8];
+ zend_string key;
+ char _key[MAXPATHLEN * 8];
} zend_accel_globals;
typedef struct _zend_string_table {
@@ -317,11 +317,11 @@ void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason);
accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_t *size);
int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle);
int validate_timestamp_and_record_ex(zend_persistent_script *persistent_script, zend_file_handle *file_handle);
-int zend_accel_invalidate(const char *filename, size_t filename_len, bool force);
+int zend_accel_invalidate(zend_string *filename, bool force);
int accelerator_shm_read_lock(void);
void accelerator_shm_read_unlock(void);
-char *accel_make_persistent_key(const char *path, size_t path_length, int *key_len);
+zend_string *accel_make_persistent_key(zend_string *path);
zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type);
#define IS_ACCEL_INTERNED(str) \
diff --git a/ext/opcache/zend_accelerator_hash.c b/ext/opcache/zend_accelerator_hash.c
index b3f2dfce20..e18960fb7d 100644
--- a/ext/opcache/zend_accelerator_hash.c
+++ b/ext/opcache/zend_accelerator_hash.c
@@ -200,32 +200,6 @@ zend_accel_hash_entry* zend_accel_hash_find_entry(zend_accel_hash *accel_hash, z
0);
}
-/* Returns the data associated with key on success
- * Returns NULL if data doesn't exist
- */
-void* zend_accel_hash_str_find(zend_accel_hash *accel_hash, const char *key, uint32_t key_length)
-{
- return zend_accel_hash_find_ex(
- accel_hash,
- key,
- key_length,
- zend_inline_hash_func(key, key_length),
- 1);
-}
-
-/* Returns the hash entry associated with key on success
- * Returns NULL if it doesn't exist
- */
-zend_accel_hash_entry* zend_accel_hash_str_find_entry(zend_accel_hash *accel_hash, const char *key, uint32_t key_length)
-{
- return (zend_accel_hash_entry *)zend_accel_hash_find_ex(
- accel_hash,
- key,
- key_length,
- zend_inline_hash_func(key, key_length),
- 0);
-}
-
int zend_accel_hash_unlink(zend_accel_hash *accel_hash, const char *key, uint32_t key_length)
{
zend_ulong hash_value;
diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h
index 88edbd23d8..b2feba5ed2 100644
--- a/ext/opcache/zend_accelerator_hash.h
+++ b/ext/opcache/zend_accelerator_hash.h
@@ -79,16 +79,6 @@ zend_accel_hash_entry* zend_accel_hash_find_entry(
zend_accel_hash *accel_hash,
zend_string *key);
-void* zend_accel_hash_str_find(
- zend_accel_hash *accel_hash,
- const char *key,
- uint32_t key_length);
-
-zend_accel_hash_entry* zend_accel_hash_str_find_entry(
- zend_accel_hash *accel_hash,
- const char *key,
- uint32_t key_length);
-
int zend_accel_hash_unlink(
zend_accel_hash *accel_hash,
const char *key,
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
index a3c7bd7a14..d2d847678e 100644
--- a/ext/opcache/zend_accelerator_module.c
+++ b/ext/opcache/zend_accelerator_module.c
@@ -310,17 +310,21 @@ ZEND_INI_END()
static int filename_is_in_cache(zend_string *filename)
{
- char *key;
- int key_length;
+ zend_string *key;
- key = accel_make_persistent_key(ZSTR_VAL(filename), ZSTR_LEN(filename), &key_length);
+ key = accel_make_persistent_key(filename);
if (key != NULL) {
- zend_persistent_script *persistent_script = zend_accel_hash_str_find(&ZCSG(hash), key, key_length);
+ zend_persistent_script *persistent_script = zend_accel_hash_find(&ZCSG(hash), key);
if (persistent_script && !persistent_script->corrupted) {
if (ZCG(accel_directives).validate_timestamps) {
zend_file_handle handle;
- zend_stream_init_filename(&handle, ZSTR_VAL(filename));
- return validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS;
+ int ret;
+
+ zend_stream_init_filename_ex(&handle, filename);
+ ret = validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS
+ ? 1 : 0;
+ zend_destroy_file_handle(&handle);
+ return ret;
}
return 1;
@@ -836,11 +840,10 @@ ZEND_FUNCTION(opcache_reset)
/* {{{ Invalidates cached script (in necessary or forced) */
ZEND_FUNCTION(opcache_invalidate)
{
- char *script_name;
- size_t script_name_len;
+ zend_string *script_name;
bool force = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &script_name, &script_name_len, &force) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &script_name, &force) == FAILURE) {
RETURN_THROWS();
}
@@ -848,7 +851,7 @@ ZEND_FUNCTION(opcache_invalidate)
RETURN_FALSE;
}
- if (zend_accel_invalidate(script_name, script_name_len, force) == SUCCESS) {
+ if (zend_accel_invalidate(script_name, force) == SUCCESS) {
RETURN_TRUE;
} else {
RETURN_FALSE;
@@ -857,14 +860,13 @@ ZEND_FUNCTION(opcache_invalidate)
ZEND_FUNCTION(opcache_compile_file)
{
- char *script_name;
- size_t script_name_len;
+ zend_string *script_name;
zend_file_handle handle;
zend_op_array *op_array = NULL;
zend_execute_data *orig_execute_data = NULL;
uint32_t orig_compiler_options;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &script_name, &script_name_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &script_name) == FAILURE) {
RETURN_THROWS();
}
@@ -873,7 +875,7 @@ ZEND_FUNCTION(opcache_compile_file)
RETURN_FALSE;
}
- zend_stream_init_filename(&handle, script_name);
+ zend_stream_init_filename_ex(&handle, script_name);
orig_execute_data = EG(current_execute_data);
orig_compiler_options = CG(compiler_options);
@@ -889,7 +891,7 @@ ZEND_FUNCTION(opcache_compile_file)
op_array = persistent_compile_file(&handle, ZEND_INCLUDE);
} zend_catch {
EG(current_execute_data) = orig_execute_data;
- zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s", handle.filename);
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s", ZSTR_VAL(handle.filename));
} zend_end_try();
}
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index 1fb7281721..216b6a1eb0 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -1247,7 +1247,7 @@ static void zend_persist_warnings(zend_persistent_script *script) {
}
}
-zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, const char **key, unsigned int key_length, int for_shm)
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, int for_shm)
{
Bucket *p;
@@ -1256,10 +1256,6 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
script = zend_shared_memdup_free(script, sizeof(zend_persistent_script));
- if (key && *key) {
- *key = zend_shared_memdup_put((void*)*key, key_length + 1);
- }
-
script->corrupted = 0;
ZCG(current_persistent_script) = script;
diff --git a/ext/opcache/zend_persist.h b/ext/opcache/zend_persist.h
index 38afac39d9..f491cb8ca6 100644
--- a/ext/opcache/zend_persist.h
+++ b/ext/opcache/zend_persist.h
@@ -22,8 +22,8 @@
#ifndef ZEND_PERSIST_H
#define ZEND_PERSIST_H
-uint32_t zend_accel_script_persist_calc(zend_persistent_script *script, const char *key, unsigned int key_length, int for_shm);
-zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, const char **key, unsigned int key_length, int for_shm);
+uint32_t zend_accel_script_persist_calc(zend_persistent_script *script, int for_shm);
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, int for_shm);
void zend_persist_class_entry_calc(zend_class_entry *ce);
zend_class_entry *zend_persist_class_entry(zend_class_entry *ce);
diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c
index ad27d539be..092fcb0c67 100644
--- a/ext/opcache/zend_persist_calc.c
+++ b/ext/opcache/zend_persist_calc.c
@@ -558,7 +558,7 @@ static void zend_persist_warnings_calc(zend_persistent_script *script) {
}
}
-uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, const char *key, unsigned int key_length, int for_shm)
+uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, int for_shm)
{
Bucket *p;
@@ -573,10 +573,6 @@ uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_s
}
ADD_SIZE(sizeof(zend_persistent_script));
- if (key) {
- ADD_SIZE(key_length + 1);
- zend_shared_alloc_register_xlat_entry(key, key);
- }
ADD_STRING(new_persistent_script->script.filename);
#if defined(__AVX__) || defined(__SSE2__)
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index 7339b0eed2..99502478be 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -26,7 +26,7 @@
static void destroy_phar_data(zval *zv);
ZEND_DECLARE_MODULE_GLOBALS(phar)
-zend_string *(*phar_save_resolve_path)(const char *filename, size_t filename_len);
+static zend_string *(*phar_save_resolve_path)(zend_string *filename);
/**
* set's phar->is_writeable based on the current INI value
@@ -3292,41 +3292,41 @@ static size_t phar_zend_stream_fsizer(void *handle) /* {{{ */
} /* }}} */
zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type);
-#define phar_orig_zend_open zend_stream_open_function
-static zend_string *phar_resolve_path(const char *filename, size_t filename_len)
+static zend_string *phar_resolve_path(zend_string *filename)
{
- return phar_find_in_include_path((char *) filename, filename_len, NULL);
+ zend_string *ret = phar_find_in_include_path(ZSTR_VAL(filename), ZSTR_LEN(filename), NULL);
+ if (!ret) {
+ ret = phar_save_resolve_path(filename);
+ }
+ return ret;
}
static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) /* {{{ */
{
zend_op_array *res;
- char *name = NULL;
+ zend_string *name = NULL;
int failed;
phar_archive_data *phar;
if (!file_handle || !file_handle->filename) {
return phar_orig_compile_file(file_handle, type);
}
- if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) {
- if (SUCCESS == phar_open_from_filename((char*)file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL)) {
+ if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) {
+ if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, 0, &phar, NULL)) {
if (phar->is_zip || phar->is_tar) {
- zend_file_handle f = *file_handle;
+ zend_file_handle f;
/* zip or tar-based phar */
- spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
- if (SUCCESS == phar_orig_zend_open((const char *)name, &f)) {
-
- efree(name);
- name = NULL;
-
+ name = zend_strpprintf(4096, "phar://%s/%s", ZSTR_VAL(file_handle->filename), ".phar/stub.php");
+ zend_stream_init_filename_ex(&f, name);
+ if (SUCCESS == zend_stream_open_function(&f)) {
+ zend_string_release(f.filename);
f.filename = file_handle->filename;
if (f.opened_path) {
- efree(f.opened_path);
+ zend_string_release(f.opened_path);
}
f.opened_path = file_handle->opened_path;
- f.free_filename = file_handle->free_filename;
switch (file_handle->type) {
case ZEND_HANDLE_STREAM:
@@ -3341,7 +3341,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type)
*file_handle = f;
}
} else if (phar->flags & PHAR_FILE_COMPRESSION_MASK) {
- zend_file_handle_dtor(file_handle);
/* compressed phar */
file_handle->type = ZEND_HANDLE_STREAM;
/* we do our own reading directly from the phar, don't change the next line */
@@ -3367,7 +3366,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type)
} zend_end_try();
if (name) {
- efree(name);
+ zend_string_release(name);
}
if (failed) {
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index dab3688ba4..89344a3f22 100644
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -475,10 +475,6 @@ union _phar_entry_object {
phar_entry_info *entry;
};
-#ifndef PHAR_MAIN
-extern zend_string *(*phar_save_resolve_path)(const char *filename, size_t filename_len);
-#endif
-
BEGIN_EXTERN_C()
#ifdef PHP_WIN32
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 2100356d9b..f67855af18 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -247,13 +247,12 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
if (!new_op_array) {
zend_hash_str_del(&EG(included_files), name, name_len);
}
-
- zend_destroy_file_handle(&file_handle);
-
} else {
efree(name);
new_op_array = NULL;
}
+
+ zend_destroy_file_handle(&file_handle);
#ifdef PHP_WIN32
efree(arch);
#endif
diff --git a/ext/phar/util.c b/ext/phar/util.c
index 59362bbc72..4011a996ca 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -253,7 +253,7 @@ zend_string *phar_find_in_include_path(char *filename, size_t filename_len, phar
}
if (!zend_is_executing() || !PHAR_G(cwd)) {
- return phar_save_resolve_path(filename, filename_len);
+ return NULL;
}
fname = (char*)zend_get_executed_filename();
@@ -267,7 +267,7 @@ zend_string *phar_find_in_include_path(char *filename, size_t filename_len, phar
}
if (fname_len < 7 || memcmp(fname, "phar://", 7) || SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
- return phar_save_resolve_path(filename, filename_len);
+ return NULL;
}
efree(entry);
@@ -277,7 +277,7 @@ zend_string *phar_find_in_include_path(char *filename, size_t filename_len, phar
if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) {
efree(arch);
- return phar_save_resolve_path(filename, filename_len);
+ return NULL;
}
splitted:
if (pphar) {
diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c
index 2930796ae7..b13cd4ea81 100644
--- a/ext/readline/readline_cli.c
+++ b/ext/readline/readline_cli.c
@@ -598,8 +598,10 @@ static int readline_shell_run(void) /* {{{ */
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
zend_file_handle prepend_file;
+
zend_stream_init_filename(&prepend_file, PG(auto_prepend_file));
zend_execute_scripts(ZEND_REQUIRE, NULL, 1, &prepend_file);
+ zend_destroy_file_handle(&prepend_file);
}
#ifndef PHP_WIN32
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 5981d2385f..9520fb2a9e 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -239,20 +239,19 @@ PHP_FUNCTION(spl_classes)
static int spl_autoload(zend_string *class_name, zend_string *lc_name, const char *ext, int ext_len) /* {{{ */
{
- char *class_file;
- int class_file_len;
+ zend_string *class_file;
zval dummy;
zend_file_handle file_handle;
zend_op_array *new_op_array;
zval result;
int ret;
- class_file_len = (int)spprintf(&class_file, 0, "%s%.*s", ZSTR_VAL(lc_name), ext_len, ext);
+ class_file = zend_strpprintf(0, "%s%.*s", ZSTR_VAL(lc_name), ext_len, ext);
#if DEFAULT_SLASH != '\\'
{
- char *ptr = class_file;
- char *end = ptr + class_file_len;
+ char *ptr = ZSTR_VAL(class_file);
+ char *end = ptr + ZSTR_LEN(class_file);
while ((ptr = memchr(ptr, '\\', (end - ptr))) != NULL) {
*ptr = DEFAULT_SLASH;
@@ -260,21 +259,20 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha
}
#endif
- ret = php_stream_open_for_zend_ex(class_file, &file_handle, USE_PATH|STREAM_OPEN_FOR_INCLUDE);
+ zend_stream_init_filename_ex(&file_handle, class_file);
+ ret = php_stream_open_for_zend_ex(&file_handle, USE_PATH|STREAM_OPEN_FOR_INCLUDE);
if (ret == SUCCESS) {
zend_string *opened_path;
if (!file_handle.opened_path) {
- file_handle.opened_path = zend_string_init(class_file, class_file_len, 0);
+ file_handle.opened_path = zend_string_copy(class_file);
}
opened_path = zend_string_copy(file_handle.opened_path);
ZVAL_NULL(&dummy);
if (zend_hash_add(&EG(included_files), opened_path, &dummy)) {
new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE);
- zend_destroy_file_handle(&file_handle);
} else {
new_op_array = NULL;
- zend_file_handle_dtor(&file_handle);
}
zend_string_release_ex(opened_path, 0);
if (new_op_array) {
@@ -287,11 +285,13 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha
zval_ptr_dtor(&result);
}
- efree(class_file);
+ zend_destroy_file_handle(&file_handle);
+ zend_string_release(class_file);
return zend_hash_exists(EG(class_table), lc_name);
}
}
- efree(class_file);
+ zend_destroy_file_handle(&file_handle);
+ zend_string_release(class_file);
return 0;
} /* }}} */
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 1a6326624b..1f598aa540 100755
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -1900,32 +1900,32 @@ PHP_FUNCTION(highlight_file)
/* {{{ Return source with stripped comments and whitespace */
PHP_FUNCTION(php_strip_whitespace)
{
- char *filename;
- size_t filename_len;
+ zend_string *filename;
zend_lex_state original_lex_state;
zend_file_handle file_handle;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_PATH(filename, filename_len)
+ Z_PARAM_PATH_STR(filename)
ZEND_PARSE_PARAMETERS_END();
php_output_start_default();
- zend_stream_init_filename(&file_handle, filename);
+ zend_stream_init_filename_ex(&file_handle, filename);
zend_save_lexical_state(&original_lex_state);
if (open_file_for_scanning(&file_handle) == FAILURE) {
zend_restore_lexical_state(&original_lex_state);
php_output_end();
+ zend_destroy_file_handle(&file_handle);
RETURN_EMPTY_STRING();
}
zend_strip();
- zend_destroy_file_handle(&file_handle);
zend_restore_lexical_state(&original_lex_state);
php_output_get_contents(return_value);
php_output_discard();
+ zend_destroy_file_handle(&file_handle);
}
/* }}} */
@@ -2606,21 +2606,20 @@ static void php_ini_parser_cb_with_sections(zval *arg1, zval *arg2, zval *arg3,
/* {{{ Parse configuration file */
PHP_FUNCTION(parse_ini_file)
{
- char *filename = NULL;
- size_t filename_len = 0;
+ zend_string *filename = NULL;
bool process_sections = 0;
zend_long scanner_mode = ZEND_INI_SCANNER_NORMAL;
zend_file_handle fh;
zend_ini_parser_cb_t ini_parser_cb;
ZEND_PARSE_PARAMETERS_START(1, 3)
- Z_PARAM_PATH(filename, filename_len)
+ Z_PARAM_PATH_STR(filename)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(process_sections)
Z_PARAM_LONG(scanner_mode)
ZEND_PARSE_PARAMETERS_END();
- if (filename_len == 0) {
+ if (ZSTR_LEN(filename) == 0) {
zend_argument_value_error(1, "cannot be empty");
RETURN_THROWS();
}
@@ -2634,13 +2633,14 @@ PHP_FUNCTION(parse_ini_file)
}
/* Setup filehandle */
- zend_stream_init_filename(&fh, filename);
+ zend_stream_init_filename_ex(&fh, filename);
array_init(return_value);
if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
zend_array_destroy(Z_ARR_P(return_value));
- RETURN_FALSE;
+ RETVAL_FALSE;
}
+ zend_destroy_file_handle(&fh);
}
/* }}} */
diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c
index e5a565798b..8b53c29c09 100644
--- a/ext/standard/browscap.c
+++ b/ext/standard/browscap.c
@@ -406,16 +406,18 @@ static int browscap_read_file(char *filename, browser_data *browdata, int persis
{
zend_file_handle fh;
browscap_parser_ctx ctx = {0};
+ FILE *fp;
if (filename == NULL || filename[0] == '\0') {
return FAILURE;
}
- zend_stream_init_fp(&fh, VCWD_FOPEN(filename, "r"), filename);
- if (!fh.handle.fp) {
+ fp = VCWD_FOPEN(filename, "r");
+ if (!fp) {
zend_error(E_CORE_WARNING, "Cannot open \"%s\" for reading", filename);
return FAILURE;
}
+ zend_stream_init_fp(&fh, fp, filename);
browdata->htab = pemalloc(sizeof *browdata->htab, persistent);
zend_hash_init(browdata->htab, 0, NULL,
@@ -439,6 +441,7 @@ static int browscap_read_file(char *filename, browser_data *browdata, int persis
zend_string_release(ctx.current_section_name);
}
zend_hash_destroy(&ctx.str_interned);
+ zend_destroy_file_handle(&fh);
return SUCCESS;
}
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index 83471fcb62..128004bfc2 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -1525,15 +1525,14 @@ PHP_FUNCTION(stream_socket_enable_crypto)
/* {{{ Determine what file will be opened by calls to fopen() with a relative path */
PHP_FUNCTION(stream_resolve_include_path)
{
- char *filename;
- size_t filename_len;
+ zend_string *filename;
zend_string *resolved_path;
ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_PATH(filename, filename_len)
+ Z_PARAM_PATH_STR(filename)
ZEND_PARSE_PARAMETERS_END();
- resolved_path = zend_resolve_path(filename, filename_len);
+ resolved_path = zend_resolve_path(filename);
if (resolved_path) {
RETURN_STR(resolved_path);
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 633c5e3b2b..8d26b9cfc6 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -339,7 +339,7 @@ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, z
PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
{
char *path_info;
- char *filename = NULL;
+ zend_string *filename = NULL;
zend_string *resolved_path = NULL;
size_t length;
bool orig_display_errors;
@@ -378,9 +378,10 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
pw = getpwnam(user);
#endif
if (pw && pw->pw_dir) {
- spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
- } else {
- filename = SG(request_info).path_translated;
+ filename = zend_strpprintf(0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
+ } else if (SG(request_info).path_translated) {
+ filename = zend_string_init(SG(request_info).path_translated,
+ strlen(SG(request_info).path_translated), 0);
}
#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
efree(pwbuf);
@@ -391,29 +392,29 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
if (PG(doc_root) && path_info && (length = strlen(PG(doc_root))) &&
IS_ABSOLUTE_PATH(PG(doc_root), length)) {
size_t path_len = strlen(path_info);
- filename = emalloc(length + path_len + 2);
+ filename = zend_string_alloc(length + path_len + 2, 0);
memcpy(filename, PG(doc_root), length);
- if (!IS_SLASH(filename[length - 1])) { /* length is never 0 */
- filename[length++] = PHP_DIR_SEPARATOR;
+ if (!IS_SLASH(ZSTR_VAL(filename)[length - 1])) { /* length is never 0 */
+ ZSTR_VAL(filename)[length++] = PHP_DIR_SEPARATOR;
}
if (IS_SLASH(path_info[0])) {
length--;
}
- strncpy(filename + length, path_info, path_len + 1);
- } else {
- filename = SG(request_info).path_translated;
+ strncpy(ZSTR_VAL(filename) + length, path_info, path_len + 1);
+ ZSTR_LEN(filename) = length + path_len;
+ } else if (SG(request_info).path_translated) {
+ filename = zend_string_init(SG(request_info).path_translated,
+ strlen(SG(request_info).path_translated), 0);
}
if (filename) {
- resolved_path = zend_resolve_path(filename, strlen(filename));
+ resolved_path = zend_resolve_path(filename);
}
if (!resolved_path) {
- if (SG(request_info).path_translated != filename) {
- if (filename) {
- efree(filename);
- }
+ if (filename) {
+ zend_string_release(filename);
}
/* we have to free SG(request_info).path_translated here because
* php_destroy_request_info assumes that it will get
@@ -429,13 +430,13 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
orig_display_errors = PG(display_errors);
PG(display_errors) = 0;
- if (zend_stream_open(filename, file_handle) == FAILURE) {
+ zend_stream_init_filename_ex(file_handle, filename);
+ file_handle->primary_script = 1;
+ if (filename) {
+ zend_string_delref(filename);
+ }
+ if (zend_stream_open(file_handle) == FAILURE) {
PG(display_errors) = orig_display_errors;
- if (SG(request_info).path_translated != filename) {
- if (filename) {
- efree(filename);
- }
- }
if (SG(request_info).path_translated) {
efree(SG(request_info).path_translated);
SG(request_info).path_translated = NULL;
@@ -444,13 +445,6 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
}
PG(display_errors) = orig_display_errors;
- if (SG(request_info).path_translated != filename) {
- if (SG(request_info).path_translated) {
- efree(SG(request_info).path_translated);
- }
- SG(request_info).path_translated = filename;
- }
-
return SUCCESS;
}
/* }}} */
diff --git a/main/main.c b/main/main.c
index 1aa41da672..a32c89739f 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1442,9 +1442,10 @@ PHP_FUNCTION(set_time_limit)
/* }}} */
/* {{{ php_fopen_wrapper_for_zend */
-static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path)
+static FILE *php_fopen_wrapper_for_zend(zend_string *filename, zend_string **opened_path)
{
- return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path);
+ *opened_path = filename;
+ return php_stream_open_wrapper_as_file(ZSTR_VAL(filename), "rb", USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE|STREAM_OPEN_FOR_ZEND_STREAM, opened_path);
}
/* }}} */
@@ -1472,20 +1473,25 @@ static size_t php_zend_stream_fsizer(void *handle) /* {{{ */
}
/* }}} */
-static zend_result php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */
+static zend_result php_stream_open_for_zend(zend_file_handle *handle) /* {{{ */
{
- return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE);
+ return php_stream_open_for_zend_ex(handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE);
}
/* }}} */
-PHPAPI zend_result php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */
+PHPAPI zend_result php_stream_open_for_zend_ex(zend_file_handle *handle, int mode) /* {{{ */
{
zend_string *opened_path;
- php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &opened_path);
+ zend_string *filename;
+ php_stream *stream;
+
+ ZEND_ASSERT(handle->type == ZEND_HANDLE_FILENAME);
+ opened_path = filename = handle->filename;
+ stream = php_stream_open_wrapper((char *)ZSTR_VAL(filename), "rb", mode | STREAM_OPEN_FOR_ZEND_STREAM, &opened_path);
if (stream) {
memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_STREAM;
- handle->filename = (char*)filename;
+ handle->filename = filename;
handle->opened_path = opened_path;
handle->handle.stream.handle = stream;
handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read;
@@ -1503,9 +1509,9 @@ PHPAPI zend_result php_stream_open_for_zend_ex(const char *filename, zend_file_h
}
/* }}} */
-static zend_string *php_resolve_path_for_zend(const char *filename, size_t filename_len) /* {{{ */
+static zend_string *php_resolve_path_for_zend(zend_string *filename) /* {{{ */
{
- return php_resolve_path(filename, filename_len, PG(include_path));
+ return php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), PG(include_path));
}
/* }}} */
@@ -2142,9 +2148,11 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
/* this will read in php.ini, set up the configuration parameters,
load zend extensions and register php function extensions
to be loaded later */
+ zend_stream_init();
if (php_init_config() == FAILURE) {
return FAILURE;
}
+ zend_stream_shutdown();
/* Register PHP core ini entries */
REGISTER_INI_ENTRIES();
@@ -2450,18 +2458,18 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file)
#else
php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
#endif
- VCWD_CHDIR_FILE(primary_file->filename);
+ VCWD_CHDIR_FILE(ZSTR_VAL(primary_file->filename));
}
/* Only lookup the real file path and add it to the included_files list if already opened
* otherwise it will get opened and added to the included_files list in zend_execute_scripts
*/
- if (primary_file->filename &&
- strcmp("Standard input code", primary_file->filename) &&
+ if (primary_file->filename &&
+ strcmp("Standard input code", ZSTR_VAL(primary_file->filename)) &&
primary_file->opened_path == NULL &&
primary_file->type != ZEND_HANDLE_FILENAME
) {
- if (expand_filepath(primary_file->filename, realfile)) {
+ if (expand_filepath(ZSTR_VAL(primary_file->filename), realfile)) {
primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0);
zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path);
}
@@ -2490,6 +2498,14 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file)
retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);
} zend_end_try();
+ if (prepend_file_p) {
+ zend_destroy_file_handle(prepend_file_p);
+ }
+
+ if (append_file_p) {
+ zend_destroy_file_handle(append_file_p);
+ }
+
if (EG(exception)) {
zend_try {
zend_exception_error(EG(exception), E_ERROR);
@@ -2533,7 +2549,7 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret)
if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
- VCWD_CHDIR_FILE(primary_file->filename);
+ VCWD_CHDIR_FILE(ZSTR_VAL(primary_file->filename));
}
zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file);
} zend_end_try();
@@ -2609,7 +2625,6 @@ PHPAPI int php_lint_script(zend_file_handle *file)
zend_try {
op_array = zend_compile_file(file, ZEND_INCLUDE);
- zend_destroy_file_handle(file);
if (op_array) {
destroy_op_array(op_array);
diff --git a/main/php_ini.c b/main/php_ini.c
index 0fa3a33365..44c70c6a23 100644
--- a/main/php_ini.c
+++ b/main/php_ini.c
@@ -616,15 +616,14 @@ int php_init_config(void)
{
zval tmp;
- ZVAL_NEW_STR(&tmp, zend_string_init(fh.filename, strlen(fh.filename), 1));
+ ZVAL_NEW_STR(&tmp, zend_string_init(filename, strlen(filename), 1));
zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp);
if (opened_path) {
zend_string_release_ex(opened_path, 0);
- } else {
- efree((char *)fh.filename);
}
php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
}
+ zend_destroy_file_handle(&fh);
}
/* Check for PHP_INI_SCAN_DIR environment variable to override/set config file scan directory */
@@ -693,6 +692,7 @@ int php_init_config(void)
zend_llist_add_element(&scanned_ini_list, &p);
}
}
+ zend_destroy_file_handle(&fh);
}
}
free(namelist[i]);
@@ -771,17 +771,20 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename
if (VCWD_STAT(ini_file, &sb) == 0) {
if (S_ISREG(sb.st_mode)) {
zend_file_handle fh;
+ int ret = FAILURE;
+
zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file);
if (fh.handle.fp) {
/* Reset active ini section */
RESET_ACTIVE_INI_HASH();
- if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash) == SUCCESS) {
+ ret = zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash);
+ if (ret == SUCCESS) {
/* FIXME: Add parsed file to the list of user files read? */
- return SUCCESS;
}
- return FAILURE;
}
+ zend_destroy_file_handle(&fh);
+ return ret;
}
}
return FAILURE;
diff --git a/main/php_main.h b/main/php_main.h
index ee27209fbe..1beedd853e 100644
--- a/main/php_main.h
+++ b/main/php_main.h
@@ -40,7 +40,7 @@ PHPAPI void php_handle_aborted_connection(void);
PHPAPI int php_handle_auth_data(const char *auth);
PHPAPI void php_html_puts(const char *str, size_t siz);
-PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode);
+PHPAPI int php_stream_open_for_zend_ex(zend_file_handle *handle, int mode);
/* environment module */
extern int php_init_environ(void);
diff --git a/main/php_streams.h b/main/php_streams.h
index f7196b8437..3c1417ddd1 100644
--- a/main/php_streams.h
+++ b/main/php_streams.h
@@ -554,6 +554,9 @@ END_EXTERN_C()
/* Allow blocking reads on anonymous pipes on Windows. */
#define STREAM_USE_BLOCKING_PIPE 0x00008000
+/* this flag is only used by include/require functions */
+#define STREAM_OPEN_FOR_ZEND_STREAM 0x00010000
+
int php_init_stream_wrappers(int module_number);
int php_shutdown_stream_wrappers(int module_number);
void php_shutdown_stream_hashes(void);
diff --git a/main/streams/streams.c b/main/streams/streams.c
index 96d3aeb41e..9bf7444412 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -2043,10 +2043,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
php_stream_wrapper *wrapper = NULL;
const char *path_to_open;
int persistent = options & STREAM_OPEN_PERSISTENT;
+ zend_string *path_str = NULL;
zend_string *resolved_path = NULL;
char *copy_of_path = NULL;
if (opened_path) {
+ if (options & STREAM_OPEN_FOR_ZEND_STREAM) {
+ path_str = *opened_path;
+ }
*opened_path = NULL;
}
@@ -2056,7 +2060,11 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
}
if (options & USE_PATH) {
- resolved_path = zend_resolve_path(path, strlen(path));
+ if (path_str) {
+ resolved_path = zend_resolve_path(path_str);
+ } else {
+ resolved_path = php_resolve_path(path, strlen(path), PG(include_path));
+ }
if (resolved_path) {
path = ZSTR_VAL(resolved_path);
/* we've found this file, don't re-check include_path or run realpath */
diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c
index 2266b46e58..049f1b7d35 100644
--- a/sapi/apache2handler/sapi_apache2.c
+++ b/sapi/apache2handler/sapi_apache2.c
@@ -699,12 +699,14 @@ zend_first_try {
} else {
zend_file_handle zfd;
zend_stream_init_filename(&zfd, (char *) r->filename);
+ zfd.primary_script = 1;
if (!parent_req) {
php_execute_script(&zfd);
} else {
zend_execute_scripts(ZEND_INCLUDE, NULL, 1, &zfd);
}
+ zend_destroy_file_handle(&zfd);
apr_table_set(r->notes, "mod_php_memory_usage",
apr_psprintf(ctx->r->pool, "%" APR_SIZE_T_FMT, zend_memory_peak_usage(1)));
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index acde8c22cb..8673ec47df 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -2450,17 +2450,6 @@ parent_loop_end:
}
} /* end !cgi && !fastcgi */
- /*
- we never take stdin if we're (f)cgi, always
- rely on the web server giving us the info
- we need in the environment.
- */
- if (SG(request_info).path_translated || cgi || fastcgi) {
- zend_stream_init_filename(&file_handle, SG(request_info).path_translated);
- } else {
- zend_stream_init_fp(&file_handle, stdin, "Standard input code");
- }
-
/* request startup only after we've done all we can to
* get path_translated */
if (php_request_startup() == FAILURE) {
@@ -2520,6 +2509,10 @@ parent_loop_end:
free(bindpath);
return FAILURE;
}
+ } else {
+ /* we never take stdin if we're (f)cgi */
+ zend_stream_init_fp(&file_handle, stdin, "Standard input code");
+ file_handle.primary_script = 1;
}
if (CGIG(check_shebang_line)) {
@@ -2534,9 +2527,9 @@ parent_loop_end:
PG(during_request_startup) = 0;
exit_status = php_lint_script(&file_handle);
if (exit_status == SUCCESS) {
- zend_printf("No syntax errors detected in %s\n", file_handle.filename);
+ zend_printf("No syntax errors detected in %s\n", ZSTR_VAL(file_handle.filename));
} else {
- zend_printf("Errors parsing %s\n", file_handle.filename);
+ zend_printf("Errors parsing %s\n", ZSTR_VAL(file_handle.filename));
}
break;
case PHP_MODE_STRIP:
@@ -2557,22 +2550,22 @@ parent_loop_end:
}
fastcgi_request_done:
- {
- if (SG(request_info).path_translated) {
- efree(SG(request_info).path_translated);
- SG(request_info).path_translated = NULL;
- }
+ zend_destroy_file_handle(&file_handle);
- php_request_shutdown((void *) 0);
+ if (SG(request_info).path_translated) {
+ efree(SG(request_info).path_translated);
+ SG(request_info).path_translated = NULL;
+ }
- if (exit_status == 0) {
- exit_status = EG(exit_status);
- }
+ php_request_shutdown((void *) 0);
- if (free_query_string && SG(request_info).query_string) {
- free(SG(request_info).query_string);
- SG(request_info).query_string = NULL;
- }
+ if (exit_status == 0) {
+ exit_status = EG(exit_status);
+ }
+
+ if (free_query_string && SG(request_info).query_string) {
+ free(SG(request_info).query_string);
+ SG(request_info).query_string = NULL;
}
if (!fastcgi) {
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index 472ce013ea..835582df88 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -587,6 +587,7 @@ static int cli_seek_file_begin(zend_file_handle *file_handle, char *script_file)
}
zend_stream_init_fp(file_handle, fp, script_file);
+ file_handle->primary_script = 1;
return SUCCESS;
}
/* }}} */
@@ -620,6 +621,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
int num_repeats = 1;
pid_t pid = getpid();
+ file_handle.filename = NULL;
+
zend_try {
CG(in_compilation) = 0; /* not initialized but needed for several options */
@@ -907,28 +910,32 @@ do_repeat:
translated_path = strdup(real_path);
}
script_filename = script_file;
+ php_self = script_file;
}
} else {
/* We could handle PHP_MODE_PROCESS_STDIN in a different manner */
/* here but this would make things only more complicated. And it */
/* is consistent with the way -R works where the stdin file handle*/
/* is also accessible. */
- zend_stream_init_fp(&file_handle, stdin, "Standard input code");
+ php_self = "Standard input code";
+ if (behavior < PHP_MODE_CLI_DIRECT
+ && (!interactive || PHP_MODE_STANDARD != PHP_MODE_STANDARD)) {
+ zend_stream_init_fp(&file_handle, stdin, php_self);
+ file_handle.primary_script = 1;
+ }
}
- php_self = (char*)file_handle.filename;
/* before registering argv to module exchange the *new* argv[0] */
/* we can achieve this without allocating more memory */
SG(request_info).argc=argc-php_optind+1;
arg_excp = argv+php_optind-1;
arg_free = argv[php_optind-1];
- SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename;
- argv[php_optind-1] = (char*)file_handle.filename;
+ SG(request_info).path_translated = translated_path ? translated_path : php_self;
+ argv[php_optind-1] = php_self;
SG(request_info).argv=argv+php_optind-1;
if (php_request_startup()==FAILURE) {
*arg_excp = arg_free;
- fclose(file_handle.handle.fp);
PUTS("Could not startup.\n");
goto err;
}
@@ -954,7 +961,7 @@ do_repeat:
PG(during_request_startup) = 0;
switch (behavior) {
case PHP_MODE_STANDARD:
- if (strcmp(file_handle.filename, "Standard input code")) {
+ if (script_file) {
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
}
@@ -967,9 +974,9 @@ do_repeat:
case PHP_MODE_LINT:
EG(exit_status) = php_lint_script(&file_handle);
if (EG(exit_status) == SUCCESS) {
- zend_printf("No syntax errors detected in %s\n", file_handle.filename);
+ zend_printf("No syntax errors detected in %s\n", php_self);
} else {
- zend_printf("Errors parsing %s\n", file_handle.filename);
+ zend_printf("Errors parsing %s\n", php_self);
}
break;
case PHP_MODE_STRIP:
@@ -1000,6 +1007,11 @@ do_repeat:
size_t len, index = 0;
zval argn, argi;
+ if (!exec_run && script_file) {
+ zend_string_release_ex(file_handle.filename, 0);
+ file_handle.filename = NULL;
+ }
+
cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
if (exec_begin) {
@@ -1121,6 +1133,9 @@ do_repeat:
} zend_end_try();
out:
+ if (file_handle.filename) {
+ zend_destroy_file_handle(&file_handle);
+ }
if (request_started) {
php_request_shutdown((void *) 0);
}
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index 6d28b472d7..6511e08c9a 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -2015,9 +2015,11 @@ static int php_cli_server_dispatch_script(php_cli_server *server, php_cli_server
{
zend_file_handle zfd;
zend_stream_init_filename(&zfd, SG(request_info).path_translated);
+ zfd.primary_script = 1;
zend_try {
php_execute_script(&zfd);
} zend_end_try();
+ zend_destroy_file_handle(&zfd);
}
php_cli_server_log_response(client, SG(sapi_headers).http_response_code, NULL);
@@ -2136,6 +2138,7 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server
php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
zend_stream_init_filename(&zfd, server->router);
+ zfd.primary_script = 1;
zend_try {
zval retval;
@@ -2149,6 +2152,8 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server
}
} zend_end_try();
+ zend_destroy_file_handle(&zfd);
+
if (old_cwd[0] != '\0') {
php_ignore_value(VCWD_CHDIR(old_cwd));
}
diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c
index f4c21f7f1c..60665f62ab 100644
--- a/sapi/fuzzer/fuzzer-sapi.c
+++ b/sapi/fuzzer/fuzzer-sapi.c
@@ -250,6 +250,7 @@ int fuzzer_do_request_from_buffer(
zend_first_try {
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, filename);
+ file_handle.primary_script = 1;
file_handle.buf = estrndup(data, data_len);
file_handle.len = data_len;
@@ -261,6 +262,7 @@ int fuzzer_do_request_from_buffer(
destroy_op_array(op_array);
efree(op_array);
}
+ zend_destroy_file_handle(&file_handle);
} zend_end_try();
CG(compiled_filename) = NULL; /* ??? */
diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c
index 5b3f20ebfb..2ab2336aab 100644
--- a/sapi/litespeed/lsapi_main.c
+++ b/sapi/litespeed/lsapi_main.c
@@ -643,11 +643,13 @@ static void init_request_info( void )
php_handle_auth_data(pAuth);
}
-static int lsapi_execute_script( zend_file_handle * file_handle)
+static int lsapi_execute_script(void)
{
+ zend_file_handle file_handle;
char *p;
int len;
- zend_stream_init_filename(file_handle, SG(request_info).path_translated);
+ zend_stream_init_filename(&file_handle, SG(request_info).path_translated);
+ file_handle->primary_script = 1;
p = argv0;
*p++ = ':';
@@ -658,7 +660,8 @@ static int lsapi_execute_script( zend_file_handle * file_handle)
len = 0;
memccpy( p, SG(request_info).path_translated + len, 0, 46 );
- php_execute_script(file_handle);
+ php_execute_script(&file_handle);
+ zend_destroy_file_handle(&file_handle);
return 0;
}
@@ -740,8 +743,6 @@ static int lsapi_module_main(int show_source)
{
struct sigaction act;
int sa_rc;
- zend_file_handle file_handle;
- memset(&file_handle, 0, sizeof(file_handle));
if (php_request_startup() == FAILURE ) {
return -1;
}
@@ -767,7 +768,7 @@ static int lsapi_module_main(int show_source)
php_get_highlight_struct(&syntax_highlighter_ini);
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini);
} else {
- lsapi_execute_script( &file_handle);
+ lsapi_execute_script();
}
zend_try {
php_request_shutdown(NULL);
@@ -1308,8 +1309,9 @@ static int cli_main( int argc, char * argv[] )
}
if ( ret == -1 ) {
if ( *p ) {
- zend_file_handle file_handle;
+ zend_file_handle file_handle;
zend_stream_init_fp(&file_handle, VCWD_FOPEN(*p, "rb"), NULL);
+ file_handle.primary_script = 1;
if ( file_handle.handle.fp ) {
script_filename = *p;
@@ -1329,8 +1331,7 @@ static int cli_main( int argc, char * argv[] )
php_get_highlight_struct(&syntax_highlighter_ini);
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini);
} else if (source_highlight == 2) {
- file_handle.filename = *p;
- file_handle.free_filename = 0;
+ file_handle.filename = zend_string_init(*p, strlen(*p), 0);
file_handle.opened_path = NULL;
ret = php_lint_script(&file_handle);
if (ret==SUCCESS) {
@@ -1340,8 +1341,7 @@ static int cli_main( int argc, char * argv[] )
}
} else {
- file_handle.filename = *p;
- file_handle.free_filename = 0;
+ file_handle.filename = zend_string_init(*p, strlen(*p), 0);
file_handle.opened_path = NULL;
php_execute_script(&file_handle);
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index 0967e22f65..73f88d46a1 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -241,9 +241,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
* as it may invalidate the file handle. */
if (zend_stream_fixup(file, &bufptr, &len) == FAILURE) {
if (type == ZEND_REQUIRE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file->filename);
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, ZSTR_VAL(file->filename));
} else {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file->filename);
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file->filename));
}
return NULL;
}
@@ -279,22 +279,19 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
}
zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
- char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
+ zend_string *filename = file->opened_path ? file->opened_path : file->filename;
char resolved_path_buf[MAXPATHLEN];
zend_op_array *op_array;
phpdbg_file_source *dataptr;
- if (VCWD_REALPATH(filename, resolved_path_buf)) {
- filename = resolved_path_buf;
+ if (VCWD_REALPATH(ZSTR_VAL(filename), resolved_path_buf)) {
+ filename = zend_string_init(resolved_path_buf, strlen(resolved_path_buf), 0);
if (file->opened_path) {
zend_string_release(file->opened_path);
- file->opened_path = zend_string_init(filename, strlen(filename), 0);
+ file->opened_path = filename;
} else {
- if (file->free_filename) {
- efree((char *) file->filename);
- }
- file->free_filename = 0;
+ zend_string_release(file->filename);
file->filename = filename;
}
}
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 13026978bf..acdae17ce3 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -566,7 +566,8 @@ int phpdbg_compile(void) /* {{{ */
return FAILURE;
}
- if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE) == SUCCESS && zend_stream_fixup(&fh, &buf, &len) == SUCCESS) {
+ zend_stream_init_filename(&fh, PHPDBG_G(exec));
+ if (php_stream_open_for_zend_ex(&fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE) == SUCCESS && zend_stream_fixup(&fh, &buf, &len) == SUCCESS) {
CG(skip_shebang) = 1;
PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE);
zend_destroy_file_handle(&fh);
@@ -581,7 +582,7 @@ int phpdbg_compile(void) /* {{{ */
} else {
phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec));
}
-
+ zend_destroy_file_handle(&fh);
return FAILURE;
} /* }}} */