diff options
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; } /* }}} */ |