Change Zend Stream API to use zend_string* instead of char*.

This allows to eliminate re-calculation of string lenght and hash value.
See the detailed list of changes in UPGRADING.INTERNALS.
This commit is contained in:
Dmitry Stogov 2021-03-16 20:31:36 +03:00
parent 9bbeb0555b
commit c732ab400a
45 changed files with 441 additions and 404 deletions

View file

@ -2,6 +2,7 @@ PHP 8.1 INTERNALS UPGRADE NOTES
1. Internal API changes 1. Internal API changes
a. Removed Zend APIs a. Removed Zend APIs
b. Zend Stream API
2. Build system changes 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, 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_arrayaccess, zend_ce_countable, zend_ce_iterator, zend_ce_serializable, zend_ce_stringable,
zend_ce_traversable. 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 2. Build system changes

View file

@ -73,15 +73,15 @@ static uint32_t zend_version_info_length;
ZEND_API zend_class_entry *zend_standard_class_def = NULL; ZEND_API zend_class_entry *zend_standard_class_def = NULL;
ZEND_API size_t (*zend_printf)(const char *format, ...); ZEND_API size_t (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write; ZEND_API zend_write_func_t zend_write;
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path); ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle); ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
ZEND_API void (*zend_ticks_function)(int ticks); ZEND_API void (*zend_ticks_function)(int ticks);
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data); 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); 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_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); 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 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 zend_result (*zend_post_startup_cb)(void) = NULL;
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL; ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = 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) { 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 (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; continue;
} }
@ -1684,7 +1681,6 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count
if (file_handle->opened_path) { if (file_handle->opened_path) {
zend_hash_add_empty_element(&EG(included_files), 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) { if (op_array) {
zend_execute(op_array, retval); zend_execute(op_array, retval);
zend_exception_restore(); zend_exception_restore();

View file

@ -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); 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 (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
size_t (*write_function)(const char *str, size_t str_length); 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); void (*message_handler)(zend_long message, const void *data);
zval *(*get_configuration_directive)(zend_string *name); zval *(*get_configuration_directive)(zend_string *name);
void (*ticks_function)(int ticks); void (*ticks_function)(int ticks);
void (*on_timeout)(int seconds); 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_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); 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); 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; } zend_utility_functions;
typedef struct _zend_utility_values { typedef struct _zend_utility_values {
@ -303,16 +303,16 @@ END_EXTERN_C()
BEGIN_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 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 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_ticks_function)(int ticks);
extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data); 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_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 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_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 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 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 */ /* These two callbacks are especially for opcache */
extern ZEND_API zend_result (*zend_post_startup_cb)(void); extern ZEND_API zend_result (*zend_post_startup_cb)(void);

View file

@ -398,13 +398,6 @@ static bool zend_have_seen_symbol(zend_string *name, uint32_t kind) {
return zv && (Z_LVAL_P(zv) & kind) != 0; 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) /* {{{ */ void init_compiler(void) /* {{{ */
{ {
CG(arena) = zend_arena_create(64 * 1024); CG(arena) = zend_arena_create(64 * 1024);
@ -412,7 +405,7 @@ void init_compiler(void) /* {{{ */
memset(&CG(context), 0, sizeof(CG(context))); memset(&CG(context), 0, sizeof(CG(context)));
zend_init_compiler_data_structures(); zend_init_compiler_data_structures();
zend_init_rsrc_list(); 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(unclean_shutdown) = 0;
CG(delayed_variance_obligations) = NULL; CG(delayed_variance_obligations) = NULL;

View file

@ -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_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type)
{ {
zend_op_array *res; 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); 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; return res;
} }

View file

@ -4222,10 +4222,12 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval
zend_file_handle file_handle; zend_file_handle file_handle;
zend_string *resolved_path; 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 (EXPECTED(resolved_path)) {
if (zend_hash_exists(&EG(included_files), 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))) { } else if (UNEXPECTED(EG(exception))) {
break; 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)); 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) { if (!file_handle.opened_path) {
file_handle.opened_path = zend_string_copy(resolved_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; return op_array;
} else { } else {
zend_file_handle_dtor(&file_handle);
already_compiled:
new_op_array = ZEND_FAKE_OP_ARRAY; new_op_array = ZEND_FAKE_OP_ARRAY;
} }
} else if (!EG(exception)) { } else if (!EG(exception)) {
@ -4264,6 +4265,7 @@ already_compiled:
ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN, ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN,
Z_STRVAL_P(inc_filename)); Z_STRVAL_P(inc_filename));
} }
zend_destroy_file_handle(&file_handle);
zend_string_release_ex(resolved_path, 0); zend_string_release_ex(resolved_path, 0);
} }
break; break;

View file

@ -264,7 +264,7 @@ void shutdown_executor(void) /* {{{ */
#endif #endif
zend_try { zend_try {
zend_llist_destroy(&CG(open_files)); zend_stream_shutdown();
} zend_end_try(); } zend_end_try();
EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN; EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;

View file

@ -270,7 +270,7 @@ struct _zend_ini_scanner_globals {
int yy_state; int yy_state;
zend_stack state_stack; zend_stack state_stack;
char *filename; zend_string *filename;
int lineno; int lineno;
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */ /* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */

View file

@ -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; CG(ini_parser_unbuffered_errors) = unbuffered_errors;
retval = ini_parse(); retval = ini_parse();
zend_file_handle_dtor(fh);
shutdown_ini_scanner(); shutdown_ini_scanner();

View file

@ -231,7 +231,7 @@ static zend_result init_ini_scanner(int scanner_mode, zend_file_handle *fh)
SCNG(yy_in) = fh; SCNG(yy_in) = fh;
if (fh != NULL) { if (fh != NULL) {
ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); ini_filename = zend_string_copy(fh->filename);
} else { } else {
ini_filename = NULL; ini_filename = NULL;
} }
@ -248,7 +248,7 @@ void shutdown_ini_scanner(void)
{ {
zend_stack_destroy(&SCNG(state_stack)); zend_stack_destroy(&SCNG(state_stack));
if (ini_filename) { 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_ini_scanner_get_filename() */
ZEND_COLD char *zend_ini_scanner_get_filename(void) 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) { if (init_ini_scanner(scanner_mode, fh) == FAILURE) {
zend_file_handle_dtor(fh);
return FAILURE; return FAILURE;
} }

View file

@ -297,16 +297,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state)
RESET_DOC_COMMENT(); 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) ZEND_API zend_result zend_lex_tstring(zval *zv, unsigned char *ident)
{ {
unsigned char *end = 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) { if (zend_stream_fixup(file_handle, &buf, &size) == FAILURE) {
/* Still add it to open_files to make destroy_file_handle work */ /* Still add it to open_files to make destroy_file_handle work */
zend_llist_add_element(&CG(open_files), file_handle); zend_llist_add_element(&CG(open_files), file_handle);
file_handle->in_list = 1;
return FAILURE; return FAILURE;
} }
ZEND_ASSERT(!EG(exception) && "stream_fixup() should have failed"); ZEND_ASSERT(!EG(exception) && "stream_fixup() should have failed");
zend_llist_add_element(&CG(open_files), file_handle); zend_llist_add_element(&CG(open_files), file_handle);
file_handle->in_list = 1;
/* Reset the scanner for scanning the new file */ /* Reset the scanner for scanning the new file */
SCNG(yy_in) = file_handle; 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) { if (file_handle->opened_path) {
compiled_filename = zend_string_copy(file_handle->opened_path); compiled_filename = zend_string_copy(file_handle->opened_path);
} else { } 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); 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 (open_file_for_scanning(file_handle)==FAILURE) {
if (!EG(exception)) { if (!EG(exception)) {
if (type==ZEND_REQUIRE) { 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 { } else {
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename); zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file_handle->filename));
} }
} }
} else { } else {
@ -715,7 +707,7 @@ zend_op_array *compile_filename(int type, zval *filename)
ZVAL_STR(&tmp, zval_get_string(filename)); ZVAL_STR(&tmp, zval_get_string(filename));
filename = &tmp; 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); retval = zend_compile_file(&file_handle, type);
if (retval && file_handle.handle.stream.handle) { 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); zend_save_lexical_state(&original_lex_state);
if (open_file_for_scanning(&file_handle)==FAILURE) { if (open_file_for_scanning(&file_handle)==FAILURE) {
zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename); zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename);
zend_destroy_file_handle(&file_handle);
zend_restore_lexical_state(&original_lex_state); zend_restore_lexical_state(&original_lex_state);
return FAILURE; return FAILURE;
} }

View file

@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
current = next; current = next;
} }
l->head = NULL;
l->tail = NULL;
l->count = 0; l->count = 0;
} }

View file

@ -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)); memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_FP; handle->type = ZEND_HANDLE_FP;
handle->handle.fp = 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) { ZEND_API void zend_stream_init_filename(zend_file_handle *handle, const char *filename) {
memset(handle, 0, sizeof(zend_file_handle)); memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_FILENAME; 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_string *opened_path;
ZEND_ASSERT(handle->type == ZEND_HANDLE_FILENAME);
if (zend_stream_open_function) { 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->handle.fp = zend_fopen(handle->filename, &opened_path);
handle->opened_path = opened_path; if (!handle->handle.fp) {
return handle->handle.fp ? SUCCESS : FAILURE; return FAILURE;
}
handle->type = ZEND_HANDLE_FP;
return SUCCESS;
} /* }}} */ } /* }}} */
static int zend_stream_getc(zend_file_handle *file_handle) /* {{{ */ 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 (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; return FAILURE;
} }
} }
@ -199,7 +210,7 @@ ZEND_API zend_result zend_stream_fixup(zend_file_handle *file_handle, char **buf
return SUCCESS; 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) { switch (fh->type) {
case ZEND_HANDLE_FP: case ZEND_HANDLE_FP:
@ -225,22 +236,22 @@ ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) /* {{{ */
efree(fh->buf); efree(fh->buf);
fh->buf = NULL; fh->buf = NULL;
} }
if (fh->free_filename && fh->filename) { if (fh->filename) {
efree((char*)fh->filename); zend_string_release(fh->filename);
fh->filename = NULL; fh->filename = NULL;
} }
} }
/* }}} */ /* }}} */
/* return int to be compatible with Zend linked list API */ /* 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) { if (fh1->type != fh2->type) {
return 0; return 0;
} }
switch (fh1->type) { switch (fh1->type) {
case ZEND_HANDLE_FILENAME: case ZEND_HANDLE_FILENAME:
return strcmp(fh1->filename, fh2->filename) == 0; return zend_string_equals(fh1->filename, fh2->filename);
case ZEND_HANDLE_FP: case ZEND_HANDLE_FP:
return fh1->handle.fp == fh2->handle.fp; return fh1->handle.fp == fh2->handle.fp;
case ZEND_HANDLE_STREAM: case ZEND_HANDLE_STREAM:
@ -250,3 +261,25 @@ ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *
} }
return 0; 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));
} /* }}} */

View file

@ -53,12 +53,11 @@ typedef struct _zend_file_handle {
FILE *fp; FILE *fp;
zend_stream stream; zend_stream stream;
} handle; } handle;
const char *filename; zend_string *filename;
zend_string *opened_path; zend_string *opened_path;
zend_stream_type type; zend_uchar type; /* packed zend_stream_type */
/* free_filename is used by wincache */ bool primary_script;
/* TODO: Clean up filename vs opened_path mess */ bool in_list; /* added into CG(open_file) */
bool free_filename;
char *buf; char *buf;
size_t len; size_t len;
} zend_file_handle; } zend_file_handle;
@ -66,10 +65,13 @@ typedef struct _zend_file_handle {
BEGIN_EXTERN_C() 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_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 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 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 void zend_destroy_file_handle(zend_file_handle *file_handle);
ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
void zend_stream_init(void);
void zend_stream_shutdown(void);
END_EXTERN_C() END_EXTERN_C()
#ifdef ZEND_WIN32 #ifdef ZEND_WIN32

View file

@ -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_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_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_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_result (*accelerator_orig_zend_stream_open_function)(zend_file_handle *handle );
static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len); 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 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 zif_handler orig_chdir = NULL;
static ZEND_INI_MH((*orig_include_path_on_modify)) = 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 && if (sapi_module.get_stat &&
!EG(current_execute_data) && !EG(current_execute_data) &&
file_handle->filename == SG(request_info).path_translated) { file_handle->primary_script) {
zend_stat_t *tmpbuf = sapi_module.get_stat(); 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) { switch (file_handle->type) {
case ZEND_HANDLE_FP: case ZEND_HANDLE_FP:
if (zend_fstat(fileno(file_handle->handle.fp), &statbuf) == -1) { 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; 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; return 0;
} }
break; break;
@ -1039,6 +1039,7 @@ static inline int do_validate_timestamps(zend_persistent_script *persistent_scri
{ {
zend_file_handle ps_handle; zend_file_handle ps_handle;
zend_string *full_path_ptr = NULL; zend_string *full_path_ptr = NULL;
int ret;
/** check that the persistent script is indeed the same file we cached /** 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) * (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; return FAILURE;
} }
} else { } 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 && if (full_path_ptr &&
persistent_script->script.filename != full_path_ptr && persistent_script->script.filename != full_path_ptr &&
!zend_string_equal_content(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; 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; ps_handle.opened_path = persistent_script->script.filename;
if (zend_get_file_handle_timestamp(&ps_handle, NULL) == persistent_script->timestamp) { ret = zend_get_file_handle_timestamp(&ps_handle, NULL) == persistent_script->timestamp
return SUCCESS; ? 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) 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, /* 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 * we create a key that consist from requested file name, current working
* directory, current include_path, etc */ * 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; int key_length;
ZSTR_LEN(&ZCG(key)) = 0;
/* CWD and include_path don't matter for absolute file names and streams */ /* CWD and include_path don't matter for absolute file names and streams */
if (IS_ABSOLUTE_PATH(path, path_length)) { if (IS_ABSOLUTE_PATH(path, path_length)) {
/* pass */ /* pass */
ZCG(key_len) = 0;
} else if (UNEXPECTED(is_stream_path(path))) { } else if (UNEXPECTED(is_stream_path(path))) {
if (!is_cacheable_stream_path(path)) { if (!is_cacheable_stream_path(path)) {
return NULL; return NULL;
} }
/* pass */ /* pass */
ZCG(key_len) = 0;
} else if (UNEXPECTED(!ZCG(accel_directives).use_cwd)) { } else if (UNEXPECTED(!ZCG(accel_directives).use_cwd)) {
/* pass */ /* pass */
ZCG(key_len) = 0;
} else { } else {
const char *include_path = NULL, *cwd = NULL; const char *include_path = NULL, *cwd = NULL;
int include_path_len = 0, cwd_len = 0; 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 */ /* 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; 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 * since in itself, it may include colons (which we use to separate
* different components of the key) * different components of the key)
*/ */
memcpy(ZCG(key), path, path_length); key = ZSTR_VAL(&ZCG(key));
ZCG(key)[path_length] = ':'; memcpy(key, path, path_length);
key[path_length] = ':';
key_length = path_length + 1; key_length = path_length + 1;
memcpy(ZCG(key) + key_length, cwd, cwd_len); memcpy(key + key_length, cwd, cwd_len);
key_length += cwd_len; key_length += cwd_len;
if (include_path_len) { if (include_path_len) {
ZCG(key)[key_length] = ':'; key[key_length] = ':';
key_length += 1; 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; 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); parent_script_len = ZSTR_LEN(parent_script);
while ((--parent_script_len > 0) && !IS_SLASH(ZSTR_VAL(parent_script)[parent_script_len])); 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; return NULL;
} }
ZCG(key)[key_length] = ':'; key[key_length] = ':';
key_length += 1; 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; key_length += parent_script_len;
} }
ZCG(key)[key_length] = '\0'; key[key_length] = '\0';
*key_len = ZCG(key_len) = key_length; GC_SET_REFCOUNT(&ZCG(key), 1);
return ZCG(key); GC_TYPE_INFO(&ZCG(key)) = GC_STRING;
ZSTR_H(&ZCG(key)) = 0;
ZSTR_LEN(&ZCG(key)) = key_length;
return &ZCG(key);
} }
/* not use_cwd */ /* not use_cwd */
*key_len = path_length; return str;
return (char*)path;
} }
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_string *realpath;
zend_persistent_script *persistent_script; zend_persistent_script *persistent_script;
@ -1292,7 +1299,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
return FAILURE; return FAILURE;
} }
realpath = accelerator_orig_zend_resolve_path(filename, filename_len); realpath = accelerator_orig_zend_resolve_path(filename);
if (!realpath) { if (!realpath) {
return FAILURE; 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); persistent_script = zend_accel_hash_find(&ZCSG(hash), realpath);
if (persistent_script && !persistent_script->corrupted) { if (persistent_script && !persistent_script->corrupted) {
zend_file_handle file_handle; 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; file_handle.opened_path = realpath;
if (force || if (force ||
@ -1328,6 +1335,9 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, bool force)
SHM_PROTECT(); SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS(); HANDLE_UNBLOCK_INTERRUPTIONS();
} }
file_handle.opened_path = NULL;
zend_destroy_file_handle(&file_handle);
} }
accelerator_shm_read_unlock(); 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 */ /* 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))) { if (zend_accel_hash_is_full(&ZCSG(hash))) {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1; ZSMMG(memory_exhausted) = 1;
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH); zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH);
} else { } else {
char *new_key = zend_shared_alloc(key_length + 1); char *new_key = zend_shared_alloc(ZSTR_LEN(key) + 1);
if (new_key) { if (new_key) {
memcpy(new_key, key, key_length + 1); memcpy(new_key, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
if (zend_accel_hash_update(&ZCSG(hash), new_key, key_length, 1, bucket)) { 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); zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", new_key);
} }
} else { } else {
@ -1372,7 +1382,7 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script
zend_shared_alloc_init_xlat_table(); zend_shared_alloc_init_xlat_table();
/* Calculate the required memory size */ /* 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 */ /* Allocate memory block */
#if defined(__AVX__) || defined(__SSE2__) #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(); zend_shared_alloc_clear_xlat_table();
/* Copy into memory block */ /* 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(); 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); 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; zend_accel_hash_entry *bucket;
uint32_t memory_used; uint32_t memory_used;
@ -1460,7 +1470,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
if (key && if (key &&
(!ZCG(accel_directives).validate_timestamps || (!ZCG(accel_directives).validate_timestamps ||
(new_persistent_script->timestamp == existing_persistent_script->timestamp))) { (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(); zend_shared_alloc_unlock();
#if 1 #if 1
@ -1489,7 +1499,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
zend_shared_alloc_init_xlat_table(); zend_shared_alloc_init_xlat_table();
/* Calculate the required memory size */ /* 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 */ /* Allocate shared memory */
#if defined(__AVX__) || defined(__SSE2__) #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(); zend_shared_alloc_clear_xlat_table();
/* Copy into shared memory */ /* 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(); zend_shared_alloc_destroy_xlat_table();
@ -1573,16 +1583,22 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
if (key && if (key &&
/* key may contain non-persistent PHAR aliases (see issues #115 and #149) */ /* key may contain non-persistent PHAR aliases (see issues #115 and #149) */
memcmp(key, "phar://", sizeof("phar://") - 1) != 0 && memcmp(key, "phar://", sizeof("phar://") - 1) != 0 &&
(ZSTR_LEN(new_persistent_script->script.filename) != key_length || !zend_string_equals(new_persistent_script->script.filename, key)) {
memcmp(ZSTR_VAL(new_persistent_script->script.filename), key, key_length) != 0)) {
/* link key to the same persistent script in hash table */ /* link key to the same persistent script in hash table */
if (zend_accel_hash_update(&ZCSG(hash), key, key_length, 1, bucket)) { char *new_key = zend_shared_alloc(ZSTR_LEN(key) + 1);
zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", key);
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 { } else {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!"); zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1; ZSMMG(memory_exhausted) = 1;
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH); zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH);
} }
} else {
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
}
} }
} }
@ -1701,7 +1717,7 @@ static void free_recorded_warnings() {
ZCG(num_warnings) = 0; 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; zend_persistent_script *new_persistent_script;
uint32_t orig_functions_count, orig_class_count; 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 */ /* Try to open file */
if (file_handle->type == ZEND_HANDLE_FILENAME) { 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; *op_array_p = NULL;
if (!EG(exception)) { if (!EG(exception)) {
if (type == ZEND_REQUIRE) { 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 { } 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; return NULL;
@ -1852,7 +1868,7 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
if (file_handle->opened_path) { if (file_handle->opened_path) {
new_persistent_script->script.filename = zend_string_copy(file_handle->opened_path); new_persistent_script->script.filename = zend_string_copy(file_handle->opened_path);
} else { } 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); 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; zend_op_array *op_array = NULL;
int from_memory; /* if the script we've got is stored in SHM */ int from_memory; /* if the script we've got is stored in SHM */
if (is_stream_path(file_handle->filename) && if (is_stream_path(ZSTR_VAL(file_handle->filename)) &&
!is_cacheable_stream_path(file_handle->filename)) { !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename))) {
return accelerator_orig_compile_file(file_handle, type); return accelerator_orig_compile_file(file_handle, type);
} }
if (!file_handle->opened_path) { if (!file_handle->opened_path) {
if (file_handle->type == ZEND_HANDLE_FILENAME && 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 (!EG(exception)) {
if (type == ZEND_REQUIRE) { 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 { } 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; return NULL;
@ -1914,7 +1930,6 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
} }
} }
replay_warnings(persistent_script); replay_warnings(persistent_script);
zend_file_handle_dtor(file_handle);
if (persistent_script->ping_auto_globals_mask) { if (persistent_script->ping_auto_globals_mask) {
zend_accel_set_auto_globals(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); 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) { if (persistent_script) {
from_memory = 0; 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_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
{ {
zend_persistent_script *persistent_script = NULL; zend_persistent_script *persistent_script = NULL;
char *key = NULL; zend_string *key = NULL;
int key_length;
int from_shared_memory; /* if the script we've got is stored in SHM */ int from_shared_memory; /* if the script we've got is stored in SHM */
if (!file_handle->filename || !ZCG(accelerator_enabled)) { 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 */ * persistent script already found */
if (ZCG(cache_persistent_script) && if (ZCG(cache_persistent_script) &&
((!EG(current_execute_data) && ((!EG(current_execute_data) &&
file_handle->filename == SG(request_info).path_translated && file_handle->primary_script &&
ZCG(cache_opline) == NULL) || ZCG(cache_opline) == NULL) ||
(EG(current_execute_data) && (EG(current_execute_data) &&
EG(current_execute_data)->func && 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))) { ZCG(cache_opline) == EG(current_execute_data)->opline))) {
persistent_script = ZCG(cache_persistent_script); persistent_script = ZCG(cache_persistent_script);
if (ZCG(key_len)) { if (ZSTR_LEN(&ZCG(key))) {
key = ZCG(key); key = &ZCG(key);
key_length = ZCG(key_len);
} }
} else { } else {
if (!ZCG(accel_directives).revalidate_path) { if (!ZCG(accel_directives).revalidate_path) {
/* try to find cached script by key */ /* 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) { if (!key) {
ZCG(cache_opline) = NULL; ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL; ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type); return accelerator_orig_compile_file(file_handle, type);
} }
persistent_script = zend_accel_hash_str_find(&ZCSG(hash), key, key_length); persistent_script = zend_accel_hash_find(&ZCSG(hash), key);
} else if (UNEXPECTED(is_stream_path(file_handle->filename) && !is_cacheable_stream_path(file_handle->filename))) { } 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_opline) = NULL;
ZCG(cache_persistent_script) = NULL; ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type); 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; zend_accel_hash_entry *bucket;
/* open file to resolve the path */ /* open file to resolve the path */
if (file_handle->type == ZEND_HANDLE_FILENAME && 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 (!EG(exception)) {
if (type == ZEND_REQUIRE) { 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 { } 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; return NULL;
@ -2050,7 +2063,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
HANDLE_BLOCK_INTERRUPTIONS(); HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT(); SHM_UNPROTECT();
zend_shared_alloc_lock(); zend_shared_alloc_lock();
zend_accel_add_key(key, key_length, bucket); zend_accel_add_key(key, bucket);
zend_shared_alloc_unlock(); zend_shared_alloc_unlock();
SHM_PROTECT(); SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS(); 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))) { UNEXPECTED(check_persistent_script_access(persistent_script))) {
if (!EG(exception)) { if (!EG(exception)) {
if (type == ZEND_REQUIRE) { 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 { } 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; return NULL;
@ -2169,7 +2182,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
SHM_PROTECT(); SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS(); 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(); HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT(); SHM_UNPROTECT();
@ -2178,7 +2191,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
*/ */
from_shared_memory = 0; from_shared_memory = 0;
if (persistent_script) { 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; /* 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); replay_warnings(persistent_script);
zend_file_handle_dtor(file_handle);
from_shared_memory = 1; from_shared_memory = 1;
} }
@ -2478,12 +2490,12 @@ static int accel_gen_uname_id(void)
#endif #endif
/* zend_stream_open_function() replacement for PHP 5.3 and above */ /* 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)) { if (ZCG(cache_persistent_script)) {
/* check if callback is called from include_once or it's a main request */ /* check if callback is called from include_once or it's a main request */
if ((!EG(current_execute_data) && if ((!EG(current_execute_data) &&
filename == SG(request_info).path_translated && handle->primary_script &&
ZCG(cache_opline) == NULL) || ZCG(cache_opline) == NULL) ||
(EG(current_execute_data) && (EG(current_execute_data) &&
EG(current_execute_data)->func && 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)) { ZCG(cache_opline) == EG(current_execute_data)->opline)) {
/* we are in include_once or FastCGI request */ /* 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); handle->opened_path = zend_string_copy(ZCG(cache_persistent_script)->script.filename);
return SUCCESS; return SUCCESS;
} }
ZCG(cache_opline) = NULL; ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = 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 */ /* 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 && if (!file_cache_only &&
ZCG(accelerator_enabled)) { ZCG(accelerator_enabled)) {
/* check if callback is called from include_once or it's a main request */ /* check if callback is called from include_once or it's a main request */
if ((!EG(current_execute_data) && if ((!EG(current_execute_data)) ||
filename == SG(request_info).path_translated) ||
(EG(current_execute_data) && (EG(current_execute_data) &&
EG(current_execute_data)->func && EG(current_execute_data)->func &&
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) && 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 */ /* we are in include_once or FastCGI request */
zend_string *resolved_path; zend_string *resolved_path;
int key_length; zend_string *key = NULL;
char *key = NULL;
if (!ZCG(accel_directives).revalidate_path) { if (!ZCG(accel_directives).revalidate_path) {
/* lookup by "not-real" path */ /* lookup by "not-real" path */
key = accel_make_persistent_key(filename, filename_len, &key_length); key = accel_make_persistent_key(filename);
if (key) { 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) { if (bucket != NULL) {
zend_persistent_script *persistent_script = (zend_persistent_script *)bucket->data; zend_persistent_script *persistent_script = (zend_persistent_script *)bucket->data;
if (!persistent_script->corrupted) { if (!persistent_script->corrupted) {
@ -2538,12 +2547,12 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi
} else { } else {
ZCG(cache_opline) = NULL; ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = 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 */ /* 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) { if (resolved_path) {
/* lookup by real 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(); HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT(); SHM_UNPROTECT();
zend_shared_alloc_lock(); zend_shared_alloc_lock();
zend_accel_add_key(key, key_length, bucket); zend_accel_add_key(key, bucket);
zend_shared_alloc_unlock(); zend_shared_alloc_unlock();
SHM_PROTECT(); SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS(); HANDLE_UNBLOCK_INTERRUPTIONS();
} else { } 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_opline) = EG(current_execute_data) ? EG(current_execute_data)->opline : NULL;
ZCG(cache_persistent_script) = persistent_script; 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_opline) = NULL;
ZCG(cache_persistent_script) = 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) 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))) { if (is_stream_path(ZSTR_VAL(filename))) {
return NULL; return NULL;
} }
return zend_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename)); return zend_resolve_path(filename);
} }
static void preload_remove_empty_includes(void) 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(); checkpoint = zend_shared_alloc_checkpoint_xlat_table();
/* Calculate the required memory size */ /* 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 */ /* Allocate shared memory */
#if defined(__AVX__) || defined(__SSE2__) #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); zend_shared_alloc_restore_xlat_table(checkpoint);
/* Copy into shared memory */ /* 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); new_persistent_script->is_phar = is_phar_file(new_persistent_script->script.filename);

View file

@ -234,8 +234,8 @@ typedef struct _zend_accel_globals {
const zend_op *cache_opline; const zend_op *cache_opline;
zend_persistent_script *cache_persistent_script; zend_persistent_script *cache_persistent_script;
/* preallocated buffer for keys */ /* preallocated buffer for keys */
int key_len; zend_string key;
char key[MAXPATHLEN * 8]; char _key[MAXPATHLEN * 8];
} zend_accel_globals; } zend_accel_globals;
typedef struct _zend_string_table { 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); 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(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 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); int accelerator_shm_read_lock(void);
void accelerator_shm_read_unlock(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); zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type);
#define IS_ACCEL_INTERNED(str) \ #define IS_ACCEL_INTERNED(str) \

View file

@ -200,32 +200,6 @@ zend_accel_hash_entry* zend_accel_hash_find_entry(zend_accel_hash *accel_hash, z
0); 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) int zend_accel_hash_unlink(zend_accel_hash *accel_hash, const char *key, uint32_t key_length)
{ {
zend_ulong hash_value; zend_ulong hash_value;

View file

@ -79,16 +79,6 @@ zend_accel_hash_entry* zend_accel_hash_find_entry(
zend_accel_hash *accel_hash, zend_accel_hash *accel_hash,
zend_string *key); 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( int zend_accel_hash_unlink(
zend_accel_hash *accel_hash, zend_accel_hash *accel_hash,
const char *key, const char *key,

View file

@ -310,17 +310,21 @@ ZEND_INI_END()
static int filename_is_in_cache(zend_string *filename) static int filename_is_in_cache(zend_string *filename)
{ {
char *key; zend_string *key;
int key_length;
key = accel_make_persistent_key(ZSTR_VAL(filename), ZSTR_LEN(filename), &key_length); key = accel_make_persistent_key(filename);
if (key != NULL) { 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 (persistent_script && !persistent_script->corrupted) {
if (ZCG(accel_directives).validate_timestamps) { if (ZCG(accel_directives).validate_timestamps) {
zend_file_handle handle; zend_file_handle handle;
zend_stream_init_filename(&handle, ZSTR_VAL(filename)); int ret;
return validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS;
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; return 1;
@ -836,11 +840,10 @@ ZEND_FUNCTION(opcache_reset)
/* {{{ Invalidates cached script (in necessary or forced) */ /* {{{ Invalidates cached script (in necessary or forced) */
ZEND_FUNCTION(opcache_invalidate) ZEND_FUNCTION(opcache_invalidate)
{ {
char *script_name; zend_string *script_name;
size_t script_name_len;
bool force = 0; 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(); RETURN_THROWS();
} }
@ -848,7 +851,7 @@ ZEND_FUNCTION(opcache_invalidate)
RETURN_FALSE; RETURN_FALSE;
} }
if (zend_accel_invalidate(script_name, script_name_len, force) == SUCCESS) { if (zend_accel_invalidate(script_name, force) == SUCCESS) {
RETURN_TRUE; RETURN_TRUE;
} else { } else {
RETURN_FALSE; RETURN_FALSE;
@ -857,14 +860,13 @@ ZEND_FUNCTION(opcache_invalidate)
ZEND_FUNCTION(opcache_compile_file) ZEND_FUNCTION(opcache_compile_file)
{ {
char *script_name; zend_string *script_name;
size_t script_name_len;
zend_file_handle handle; zend_file_handle handle;
zend_op_array *op_array = NULL; zend_op_array *op_array = NULL;
zend_execute_data *orig_execute_data = NULL; zend_execute_data *orig_execute_data = NULL;
uint32_t orig_compiler_options; 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(); RETURN_THROWS();
} }
@ -873,7 +875,7 @@ ZEND_FUNCTION(opcache_compile_file)
RETURN_FALSE; 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_execute_data = EG(current_execute_data);
orig_compiler_options = CG(compiler_options); orig_compiler_options = CG(compiler_options);
@ -889,7 +891,7 @@ ZEND_FUNCTION(opcache_compile_file)
op_array = persistent_compile_file(&handle, ZEND_INCLUDE); op_array = persistent_compile_file(&handle, ZEND_INCLUDE);
} zend_catch { } zend_catch {
EG(current_execute_data) = orig_execute_data; 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(); } zend_end_try();
} }

View file

@ -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; 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 */ ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
script = zend_shared_memdup_free(script, sizeof(zend_persistent_script)); 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; script->corrupted = 0;
ZCG(current_persistent_script) = script; ZCG(current_persistent_script) = script;

View file

@ -22,8 +22,8 @@
#ifndef ZEND_PERSIST_H #ifndef ZEND_PERSIST_H
#define 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); 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, const char **key, unsigned int key_length, 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); void zend_persist_class_entry_calc(zend_class_entry *ce);
zend_class_entry *zend_persist_class_entry(zend_class_entry *ce); zend_class_entry *zend_persist_class_entry(zend_class_entry *ce);

View file

@ -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; 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)); 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); ADD_STRING(new_persistent_script->script.filename);
#if defined(__AVX__) || defined(__SSE2__) #if defined(__AVX__) || defined(__SSE2__)

View file

@ -26,7 +26,7 @@
static void destroy_phar_data(zval *zv); static void destroy_phar_data(zval *zv);
ZEND_DECLARE_MODULE_GLOBALS(phar) 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 * 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); 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) /* {{{ */ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) /* {{{ */
{ {
zend_op_array *res; zend_op_array *res;
char *name = NULL; zend_string *name = NULL;
int failed; int failed;
phar_archive_data *phar; phar_archive_data *phar;
if (!file_handle || !file_handle->filename) { if (!file_handle || !file_handle->filename) {
return phar_orig_compile_file(file_handle, type); return phar_orig_compile_file(file_handle, type);
} }
if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) { if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) {
if (SUCCESS == phar_open_from_filename((char*)file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL)) { 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) { if (phar->is_zip || phar->is_tar) {
zend_file_handle f = *file_handle; zend_file_handle f;
/* zip or tar-based phar */ /* zip or tar-based phar */
spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php"); name = zend_strpprintf(4096, "phar://%s/%s", ZSTR_VAL(file_handle->filename), ".phar/stub.php");
if (SUCCESS == phar_orig_zend_open((const char *)name, &f)) { zend_stream_init_filename_ex(&f, name);
if (SUCCESS == zend_stream_open_function(&f)) {
efree(name); zend_string_release(f.filename);
name = NULL;
f.filename = file_handle->filename; f.filename = file_handle->filename;
if (f.opened_path) { if (f.opened_path) {
efree(f.opened_path); zend_string_release(f.opened_path);
} }
f.opened_path = file_handle->opened_path; f.opened_path = file_handle->opened_path;
f.free_filename = file_handle->free_filename;
switch (file_handle->type) { switch (file_handle->type) {
case ZEND_HANDLE_STREAM: 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; *file_handle = f;
} }
} else if (phar->flags & PHAR_FILE_COMPRESSION_MASK) { } else if (phar->flags & PHAR_FILE_COMPRESSION_MASK) {
zend_file_handle_dtor(file_handle);
/* compressed phar */ /* compressed phar */
file_handle->type = ZEND_HANDLE_STREAM; file_handle->type = ZEND_HANDLE_STREAM;
/* we do our own reading directly from the phar, don't change the next line */ /* 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(); } zend_end_try();
if (name) { if (name) {
efree(name); zend_string_release(name);
} }
if (failed) { if (failed) {

View file

@ -475,10 +475,6 @@ union _phar_entry_object {
phar_entry_info *entry; 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() BEGIN_EXTERN_C()
#ifdef PHP_WIN32 #ifdef PHP_WIN32

View file

@ -247,13 +247,12 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
if (!new_op_array) { if (!new_op_array) {
zend_hash_str_del(&EG(included_files), name, name_len); zend_hash_str_del(&EG(included_files), name, name_len);
} }
zend_destroy_file_handle(&file_handle);
} else { } else {
efree(name); efree(name);
new_op_array = NULL; new_op_array = NULL;
} }
zend_destroy_file_handle(&file_handle);
#ifdef PHP_WIN32 #ifdef PHP_WIN32
efree(arch); efree(arch);
#endif #endif

View file

@ -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)) { if (!zend_is_executing() || !PHAR_G(cwd)) {
return phar_save_resolve_path(filename, filename_len); return NULL;
} }
fname = (char*)zend_get_executed_filename(); 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)) { 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); 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)) { if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) {
efree(arch); efree(arch);
return phar_save_resolve_path(filename, filename_len); return NULL;
} }
splitted: splitted:
if (pphar) { if (pphar) {

View file

@ -598,8 +598,10 @@ static int readline_shell_run(void) /* {{{ */
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) { if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
zend_file_handle prepend_file; zend_file_handle prepend_file;
zend_stream_init_filename(&prepend_file, PG(auto_prepend_file)); zend_stream_init_filename(&prepend_file, PG(auto_prepend_file));
zend_execute_scripts(ZEND_REQUIRE, NULL, 1, &prepend_file); zend_execute_scripts(ZEND_REQUIRE, NULL, 1, &prepend_file);
zend_destroy_file_handle(&prepend_file);
} }
#ifndef PHP_WIN32 #ifndef PHP_WIN32

View file

@ -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) /* {{{ */ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const char *ext, int ext_len) /* {{{ */
{ {
char *class_file; zend_string *class_file;
int class_file_len;
zval dummy; zval dummy;
zend_file_handle file_handle; zend_file_handle file_handle;
zend_op_array *new_op_array; zend_op_array *new_op_array;
zval result; zval result;
int ret; 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 != '\\' #if DEFAULT_SLASH != '\\'
{ {
char *ptr = class_file; char *ptr = ZSTR_VAL(class_file);
char *end = ptr + class_file_len; char *end = ptr + ZSTR_LEN(class_file);
while ((ptr = memchr(ptr, '\\', (end - ptr))) != NULL) { while ((ptr = memchr(ptr, '\\', (end - ptr))) != NULL) {
*ptr = DEFAULT_SLASH; *ptr = DEFAULT_SLASH;
@ -260,21 +259,20 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha
} }
#endif #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) { if (ret == SUCCESS) {
zend_string *opened_path; zend_string *opened_path;
if (!file_handle.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); opened_path = zend_string_copy(file_handle.opened_path);
ZVAL_NULL(&dummy); ZVAL_NULL(&dummy);
if (zend_hash_add(&EG(included_files), opened_path, &dummy)) { if (zend_hash_add(&EG(included_files), opened_path, &dummy)) {
new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE); new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE);
zend_destroy_file_handle(&file_handle);
} else { } else {
new_op_array = NULL; new_op_array = NULL;
zend_file_handle_dtor(&file_handle);
} }
zend_string_release_ex(opened_path, 0); zend_string_release_ex(opened_path, 0);
if (new_op_array) { 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); 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); 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; return 0;
} /* }}} */ } /* }}} */

View file

@ -1900,32 +1900,32 @@ PHP_FUNCTION(highlight_file)
/* {{{ Return source with stripped comments and whitespace */ /* {{{ Return source with stripped comments and whitespace */
PHP_FUNCTION(php_strip_whitespace) PHP_FUNCTION(php_strip_whitespace)
{ {
char *filename; zend_string *filename;
size_t filename_len;
zend_lex_state original_lex_state; zend_lex_state original_lex_state;
zend_file_handle file_handle; zend_file_handle file_handle;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(filename, filename_len) Z_PARAM_PATH_STR(filename)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
php_output_start_default(); 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); zend_save_lexical_state(&original_lex_state);
if (open_file_for_scanning(&file_handle) == FAILURE) { if (open_file_for_scanning(&file_handle) == FAILURE) {
zend_restore_lexical_state(&original_lex_state); zend_restore_lexical_state(&original_lex_state);
php_output_end(); php_output_end();
zend_destroy_file_handle(&file_handle);
RETURN_EMPTY_STRING(); RETURN_EMPTY_STRING();
} }
zend_strip(); zend_strip();
zend_destroy_file_handle(&file_handle);
zend_restore_lexical_state(&original_lex_state); zend_restore_lexical_state(&original_lex_state);
php_output_get_contents(return_value); php_output_get_contents(return_value);
php_output_discard(); 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 */ /* {{{ Parse configuration file */
PHP_FUNCTION(parse_ini_file) PHP_FUNCTION(parse_ini_file)
{ {
char *filename = NULL; zend_string *filename = NULL;
size_t filename_len = 0;
bool process_sections = 0; bool process_sections = 0;
zend_long scanner_mode = ZEND_INI_SCANNER_NORMAL; zend_long scanner_mode = ZEND_INI_SCANNER_NORMAL;
zend_file_handle fh; zend_file_handle fh;
zend_ini_parser_cb_t ini_parser_cb; zend_ini_parser_cb_t ini_parser_cb;
ZEND_PARSE_PARAMETERS_START(1, 3) ZEND_PARSE_PARAMETERS_START(1, 3)
Z_PARAM_PATH(filename, filename_len) Z_PARAM_PATH_STR(filename)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
Z_PARAM_BOOL(process_sections) Z_PARAM_BOOL(process_sections)
Z_PARAM_LONG(scanner_mode) Z_PARAM_LONG(scanner_mode)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
if (filename_len == 0) { if (ZSTR_LEN(filename) == 0) {
zend_argument_value_error(1, "cannot be empty"); zend_argument_value_error(1, "cannot be empty");
RETURN_THROWS(); RETURN_THROWS();
} }
@ -2634,13 +2633,14 @@ PHP_FUNCTION(parse_ini_file)
} }
/* Setup filehandle */ /* Setup filehandle */
zend_stream_init_filename(&fh, filename); zend_stream_init_filename_ex(&fh, filename);
array_init(return_value); array_init(return_value);
if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) { if (zend_parse_ini_file(&fh, 0, (int)scanner_mode, ini_parser_cb, return_value) == FAILURE) {
zend_array_destroy(Z_ARR_P(return_value)); zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE; RETVAL_FALSE;
} }
zend_destroy_file_handle(&fh);
} }
/* }}} */ /* }}} */

View file

@ -406,16 +406,18 @@ static int browscap_read_file(char *filename, browser_data *browdata, int persis
{ {
zend_file_handle fh; zend_file_handle fh;
browscap_parser_ctx ctx = {0}; browscap_parser_ctx ctx = {0};
FILE *fp;
if (filename == NULL || filename[0] == '\0') { if (filename == NULL || filename[0] == '\0') {
return FAILURE; return FAILURE;
} }
zend_stream_init_fp(&fh, VCWD_FOPEN(filename, "r"), filename); fp = VCWD_FOPEN(filename, "r");
if (!fh.handle.fp) { if (!fp) {
zend_error(E_CORE_WARNING, "Cannot open \"%s\" for reading", filename); zend_error(E_CORE_WARNING, "Cannot open \"%s\" for reading", filename);
return FAILURE; return FAILURE;
} }
zend_stream_init_fp(&fh, fp, filename);
browdata->htab = pemalloc(sizeof *browdata->htab, persistent); browdata->htab = pemalloc(sizeof *browdata->htab, persistent);
zend_hash_init(browdata->htab, 0, NULL, 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_string_release(ctx.current_section_name);
} }
zend_hash_destroy(&ctx.str_interned); zend_hash_destroy(&ctx.str_interned);
zend_destroy_file_handle(&fh);
return SUCCESS; return SUCCESS;
} }

View file

@ -1525,15 +1525,14 @@ PHP_FUNCTION(stream_socket_enable_crypto)
/* {{{ Determine what file will be opened by calls to fopen() with a relative path */ /* {{{ Determine what file will be opened by calls to fopen() with a relative path */
PHP_FUNCTION(stream_resolve_include_path) PHP_FUNCTION(stream_resolve_include_path)
{ {
char *filename; zend_string *filename;
size_t filename_len;
zend_string *resolved_path; zend_string *resolved_path;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH(filename, filename_len) Z_PARAM_PATH_STR(filename)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
resolved_path = zend_resolve_path(filename, filename_len); resolved_path = zend_resolve_path(filename);
if (resolved_path) { if (resolved_path) {
RETURN_STR(resolved_path); RETURN_STR(resolved_path);

View file

@ -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) PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
{ {
char *path_info; char *path_info;
char *filename = NULL; zend_string *filename = NULL;
zend_string *resolved_path = NULL; zend_string *resolved_path = NULL;
size_t length; size_t length;
bool orig_display_errors; bool orig_display_errors;
@ -378,9 +378,10 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
pw = getpwnam(user); pw = getpwnam(user);
#endif #endif
if (pw && pw->pw_dir) { 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 */ 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 { } else if (SG(request_info).path_translated) {
filename = 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) #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
efree(pwbuf); 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))) && if (PG(doc_root) && path_info && (length = strlen(PG(doc_root))) &&
IS_ABSOLUTE_PATH(PG(doc_root), length)) { IS_ABSOLUTE_PATH(PG(doc_root), length)) {
size_t path_len = strlen(path_info); 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); memcpy(filename, PG(doc_root), length);
if (!IS_SLASH(filename[length - 1])) { /* length is never 0 */ if (!IS_SLASH(ZSTR_VAL(filename)[length - 1])) { /* length is never 0 */
filename[length++] = PHP_DIR_SEPARATOR; ZSTR_VAL(filename)[length++] = PHP_DIR_SEPARATOR;
} }
if (IS_SLASH(path_info[0])) { if (IS_SLASH(path_info[0])) {
length--; length--;
} }
strncpy(filename + length, path_info, path_len + 1); strncpy(ZSTR_VAL(filename) + length, path_info, path_len + 1);
} else { ZSTR_LEN(filename) = length + path_len;
filename = SG(request_info).path_translated; } 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) { if (filename) {
resolved_path = zend_resolve_path(filename, strlen(filename)); resolved_path = zend_resolve_path(filename);
} }
if (!resolved_path) { if (!resolved_path) {
if (SG(request_info).path_translated != filename) {
if (filename) { if (filename) {
efree(filename); zend_string_release(filename);
}
} }
/* we have to free SG(request_info).path_translated here because /* we have to free SG(request_info).path_translated here because
* php_destroy_request_info assumes that it will get * 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); orig_display_errors = PG(display_errors);
PG(display_errors) = 0; PG(display_errors) = 0;
if (zend_stream_open(filename, file_handle) == FAILURE) { zend_stream_init_filename_ex(file_handle, filename);
PG(display_errors) = orig_display_errors; file_handle->primary_script = 1;
if (SG(request_info).path_translated != filename) {
if (filename) { if (filename) {
efree(filename); zend_string_delref(filename);
}
} }
if (zend_stream_open(file_handle) == FAILURE) {
PG(display_errors) = orig_display_errors;
if (SG(request_info).path_translated) { if (SG(request_info).path_translated) {
efree(SG(request_info).path_translated); efree(SG(request_info).path_translated);
SG(request_info).path_translated = NULL; 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; 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; return SUCCESS;
} }
/* }}} */ /* }}} */

View file

@ -1442,9 +1442,10 @@ PHP_FUNCTION(set_time_limit)
/* }}} */ /* }}} */
/* {{{ php_fopen_wrapper_for_zend */ /* {{{ 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; 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) { if (stream) {
memset(handle, 0, sizeof(zend_file_handle)); memset(handle, 0, sizeof(zend_file_handle));
handle->type = ZEND_HANDLE_STREAM; handle->type = ZEND_HANDLE_STREAM;
handle->filename = (char*)filename; handle->filename = filename;
handle->opened_path = opened_path; handle->opened_path = opened_path;
handle->handle.stream.handle = stream; handle->handle.stream.handle = stream;
handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; 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, /* this will read in php.ini, set up the configuration parameters,
load zend extensions and register php function extensions load zend extensions and register php function extensions
to be loaded later */ to be loaded later */
zend_stream_init();
if (php_init_config() == FAILURE) { if (php_init_config() == FAILURE) {
return FAILURE; return FAILURE;
} }
zend_stream_shutdown();
/* Register PHP core ini entries */ /* Register PHP core ini entries */
REGISTER_INI_ENTRIES(); REGISTER_INI_ENTRIES();
@ -2450,18 +2458,18 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file)
#else #else
php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1)); php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
#endif #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 /* 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 * otherwise it will get opened and added to the included_files list in zend_execute_scripts
*/ */
if (primary_file->filename && if (primary_file->filename &&
strcmp("Standard input code", primary_file->filename) && strcmp("Standard input code", ZSTR_VAL(primary_file->filename)) &&
primary_file->opened_path == NULL && primary_file->opened_path == NULL &&
primary_file->type != ZEND_HANDLE_FILENAME 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); primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0);
zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path); 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); retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);
} zend_end_try(); } 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)) { if (EG(exception)) {
zend_try { zend_try {
zend_exception_error(EG(exception), E_ERROR); 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)) { if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1)); 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_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file);
} zend_end_try(); } zend_end_try();
@ -2609,7 +2625,6 @@ PHPAPI int php_lint_script(zend_file_handle *file)
zend_try { zend_try {
op_array = zend_compile_file(file, ZEND_INCLUDE); op_array = zend_compile_file(file, ZEND_INCLUDE);
zend_destroy_file_handle(file);
if (op_array) { if (op_array) {
destroy_op_array(op_array); destroy_op_array(op_array);

View file

@ -616,15 +616,14 @@ int php_init_config(void)
{ {
zval tmp; 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); zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp);
if (opened_path) { if (opened_path) {
zend_string_release_ex(opened_path, 0); zend_string_release_ex(opened_path, 0);
} else {
efree((char *)fh.filename);
} }
php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); 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 */ /* 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_llist_add_element(&scanned_ini_list, &p);
} }
} }
zend_destroy_file_handle(&fh);
} }
} }
free(namelist[i]); 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 (VCWD_STAT(ini_file, &sb) == 0) {
if (S_ISREG(sb.st_mode)) { if (S_ISREG(sb.st_mode)) {
zend_file_handle fh; zend_file_handle fh;
int ret = FAILURE;
zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file); zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file);
if (fh.handle.fp) { if (fh.handle.fp) {
/* Reset active ini section */ /* Reset active ini section */
RESET_ACTIVE_INI_HASH(); 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? */ /* FIXME: Add parsed file to the list of user files read? */
return SUCCESS;
} }
return FAILURE;
} }
zend_destroy_file_handle(&fh);
return ret;
} }
} }
return FAILURE; return FAILURE;

View file

@ -40,7 +40,7 @@ PHPAPI void php_handle_aborted_connection(void);
PHPAPI int php_handle_auth_data(const char *auth); PHPAPI int php_handle_auth_data(const char *auth);
PHPAPI void php_html_puts(const char *str, size_t siz); 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 */ /* environment module */
extern int php_init_environ(void); extern int php_init_environ(void);

View file

@ -554,6 +554,9 @@ END_EXTERN_C()
/* Allow blocking reads on anonymous pipes on Windows. */ /* Allow blocking reads on anonymous pipes on Windows. */
#define STREAM_USE_BLOCKING_PIPE 0x00008000 #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_init_stream_wrappers(int module_number);
int php_shutdown_stream_wrappers(int module_number); int php_shutdown_stream_wrappers(int module_number);
void php_shutdown_stream_hashes(void); void php_shutdown_stream_hashes(void);

View file

@ -2043,10 +2043,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod
php_stream_wrapper *wrapper = NULL; php_stream_wrapper *wrapper = NULL;
const char *path_to_open; const char *path_to_open;
int persistent = options & STREAM_OPEN_PERSISTENT; int persistent = options & STREAM_OPEN_PERSISTENT;
zend_string *path_str = NULL;
zend_string *resolved_path = NULL; zend_string *resolved_path = NULL;
char *copy_of_path = NULL; char *copy_of_path = NULL;
if (opened_path) { if (opened_path) {
if (options & STREAM_OPEN_FOR_ZEND_STREAM) {
path_str = *opened_path;
}
*opened_path = NULL; *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) { 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) { if (resolved_path) {
path = ZSTR_VAL(resolved_path); path = ZSTR_VAL(resolved_path);
/* we've found this file, don't re-check include_path or run realpath */ /* we've found this file, don't re-check include_path or run realpath */

View file

@ -699,12 +699,14 @@ zend_first_try {
} else { } else {
zend_file_handle zfd; zend_file_handle zfd;
zend_stream_init_filename(&zfd, (char *) r->filename); zend_stream_init_filename(&zfd, (char *) r->filename);
zfd.primary_script = 1;
if (!parent_req) { if (!parent_req) {
php_execute_script(&zfd); php_execute_script(&zfd);
} else { } else {
zend_execute_scripts(ZEND_INCLUDE, NULL, 1, &zfd); zend_execute_scripts(ZEND_INCLUDE, NULL, 1, &zfd);
} }
zend_destroy_file_handle(&zfd);
apr_table_set(r->notes, "mod_php_memory_usage", apr_table_set(r->notes, "mod_php_memory_usage",
apr_psprintf(ctx->r->pool, "%" APR_SIZE_T_FMT, zend_memory_peak_usage(1))); apr_psprintf(ctx->r->pool, "%" APR_SIZE_T_FMT, zend_memory_peak_usage(1)));

View file

@ -2450,17 +2450,6 @@ parent_loop_end:
} }
} /* end !cgi && !fastcgi */ } /* 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 /* request startup only after we've done all we can to
* get path_translated */ * get path_translated */
if (php_request_startup() == FAILURE) { if (php_request_startup() == FAILURE) {
@ -2520,6 +2509,10 @@ parent_loop_end:
free(bindpath); free(bindpath);
return FAILURE; 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)) { if (CGIG(check_shebang_line)) {
@ -2534,9 +2527,9 @@ parent_loop_end:
PG(during_request_startup) = 0; PG(during_request_startup) = 0;
exit_status = php_lint_script(&file_handle); exit_status = php_lint_script(&file_handle);
if (exit_status == SUCCESS) { 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 { } else {
zend_printf("Errors parsing %s\n", file_handle.filename); zend_printf("Errors parsing %s\n", ZSTR_VAL(file_handle.filename));
} }
break; break;
case PHP_MODE_STRIP: case PHP_MODE_STRIP:
@ -2557,7 +2550,8 @@ parent_loop_end:
} }
fastcgi_request_done: fastcgi_request_done:
{ zend_destroy_file_handle(&file_handle);
if (SG(request_info).path_translated) { if (SG(request_info).path_translated) {
efree(SG(request_info).path_translated); efree(SG(request_info).path_translated);
SG(request_info).path_translated = NULL; SG(request_info).path_translated = NULL;
@ -2573,7 +2567,6 @@ fastcgi_request_done:
free(SG(request_info).query_string); free(SG(request_info).query_string);
SG(request_info).query_string = NULL; SG(request_info).query_string = NULL;
} }
}
if (!fastcgi) { if (!fastcgi) {
if (benchmark) { if (benchmark) {

View file

@ -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); zend_stream_init_fp(file_handle, fp, script_file);
file_handle->primary_script = 1;
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -620,6 +621,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
int num_repeats = 1; int num_repeats = 1;
pid_t pid = getpid(); pid_t pid = getpid();
file_handle.filename = NULL;
zend_try { zend_try {
CG(in_compilation) = 0; /* not initialized but needed for several options */ CG(in_compilation) = 0; /* not initialized but needed for several options */
@ -907,28 +910,32 @@ do_repeat:
translated_path = strdup(real_path); translated_path = strdup(real_path);
} }
script_filename = script_file; script_filename = script_file;
php_self = script_file;
} }
} else { } else {
/* We could handle PHP_MODE_PROCESS_STDIN in a different manner */ /* We could handle PHP_MODE_PROCESS_STDIN in a different manner */
/* here but this would make things only more complicated. And it */ /* here but this would make things only more complicated. And it */
/* is consistent with the way -R works where the stdin file handle*/ /* is consistent with the way -R works where the stdin file handle*/
/* is also accessible. */ /* 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] */ /* before registering argv to module exchange the *new* argv[0] */
/* we can achieve this without allocating more memory */ /* we can achieve this without allocating more memory */
SG(request_info).argc=argc-php_optind+1; SG(request_info).argc=argc-php_optind+1;
arg_excp = argv+php_optind-1; arg_excp = argv+php_optind-1;
arg_free = argv[php_optind-1]; arg_free = argv[php_optind-1];
SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename; SG(request_info).path_translated = translated_path ? translated_path : php_self;
argv[php_optind-1] = (char*)file_handle.filename; argv[php_optind-1] = php_self;
SG(request_info).argv=argv+php_optind-1; SG(request_info).argv=argv+php_optind-1;
if (php_request_startup()==FAILURE) { if (php_request_startup()==FAILURE) {
*arg_excp = arg_free; *arg_excp = arg_free;
fclose(file_handle.handle.fp);
PUTS("Could not startup.\n"); PUTS("Could not startup.\n");
goto err; goto err;
} }
@ -954,7 +961,7 @@ do_repeat:
PG(during_request_startup) = 0; PG(during_request_startup) = 0;
switch (behavior) { switch (behavior) {
case PHP_MODE_STANDARD: 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); cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
} }
@ -967,9 +974,9 @@ do_repeat:
case PHP_MODE_LINT: case PHP_MODE_LINT:
EG(exit_status) = php_lint_script(&file_handle); EG(exit_status) = php_lint_script(&file_handle);
if (EG(exit_status) == SUCCESS) { 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 { } else {
zend_printf("Errors parsing %s\n", file_handle.filename); zend_printf("Errors parsing %s\n", php_self);
} }
break; break;
case PHP_MODE_STRIP: case PHP_MODE_STRIP:
@ -1000,6 +1007,11 @@ do_repeat:
size_t len, index = 0; size_t len, index = 0;
zval argn, argi; 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); cli_register_file_handles(/* no_close */ PHP_DEBUG || num_repeats > 1);
if (exec_begin) { if (exec_begin) {
@ -1121,6 +1133,9 @@ do_repeat:
} zend_end_try(); } zend_end_try();
out: out:
if (file_handle.filename) {
zend_destroy_file_handle(&file_handle);
}
if (request_started) { if (request_started) {
php_request_shutdown((void *) 0); php_request_shutdown((void *) 0);
} }

View file

@ -2015,9 +2015,11 @@ static int php_cli_server_dispatch_script(php_cli_server *server, php_cli_server
{ {
zend_file_handle zfd; zend_file_handle zfd;
zend_stream_init_filename(&zfd, SG(request_info).path_translated); zend_stream_init_filename(&zfd, SG(request_info).path_translated);
zfd.primary_script = 1;
zend_try { zend_try {
php_execute_script(&zfd); php_execute_script(&zfd);
} zend_end_try(); } zend_end_try();
zend_destroy_file_handle(&zfd);
} }
php_cli_server_log_response(client, SG(sapi_headers).http_response_code, NULL); 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)); php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
zend_stream_init_filename(&zfd, server->router); zend_stream_init_filename(&zfd, server->router);
zfd.primary_script = 1;
zend_try { zend_try {
zval retval; zval retval;
@ -2149,6 +2152,8 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server
} }
} zend_end_try(); } zend_end_try();
zend_destroy_file_handle(&zfd);
if (old_cwd[0] != '\0') { if (old_cwd[0] != '\0') {
php_ignore_value(VCWD_CHDIR(old_cwd)); php_ignore_value(VCWD_CHDIR(old_cwd));
} }

View file

@ -250,6 +250,7 @@ int fuzzer_do_request_from_buffer(
zend_first_try { zend_first_try {
zend_file_handle file_handle; zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, filename); zend_stream_init_filename(&file_handle, filename);
file_handle.primary_script = 1;
file_handle.buf = estrndup(data, data_len); file_handle.buf = estrndup(data, data_len);
file_handle.len = data_len; file_handle.len = data_len;
@ -261,6 +262,7 @@ int fuzzer_do_request_from_buffer(
destroy_op_array(op_array); destroy_op_array(op_array);
efree(op_array); efree(op_array);
} }
zend_destroy_file_handle(&file_handle);
} zend_end_try(); } zend_end_try();
CG(compiled_filename) = NULL; /* ??? */ CG(compiled_filename) = NULL; /* ??? */

View file

@ -643,11 +643,13 @@ static void init_request_info( void )
php_handle_auth_data(pAuth); 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; char *p;
int len; 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 = argv0;
*p++ = ':'; *p++ = ':';
@ -658,7 +660,8 @@ static int lsapi_execute_script( zend_file_handle * file_handle)
len = 0; len = 0;
memccpy( p, SG(request_info).path_translated + len, 0, 46 ); 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; return 0;
} }
@ -740,8 +743,6 @@ static int lsapi_module_main(int show_source)
{ {
struct sigaction act; struct sigaction act;
int sa_rc; int sa_rc;
zend_file_handle file_handle;
memset(&file_handle, 0, sizeof(file_handle));
if (php_request_startup() == FAILURE ) { if (php_request_startup() == FAILURE ) {
return -1; return -1;
} }
@ -767,7 +768,7 @@ static int lsapi_module_main(int show_source)
php_get_highlight_struct(&syntax_highlighter_ini); php_get_highlight_struct(&syntax_highlighter_ini);
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini); highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini);
} else { } else {
lsapi_execute_script( &file_handle); lsapi_execute_script();
} }
zend_try { zend_try {
php_request_shutdown(NULL); php_request_shutdown(NULL);
@ -1310,6 +1311,7 @@ static int cli_main( int argc, char * argv[] )
if ( *p ) { if ( *p ) {
zend_file_handle file_handle; zend_file_handle file_handle;
zend_stream_init_fp(&file_handle, VCWD_FOPEN(*p, "rb"), NULL); zend_stream_init_fp(&file_handle, VCWD_FOPEN(*p, "rb"), NULL);
file_handle.primary_script = 1;
if ( file_handle.handle.fp ) { if ( file_handle.handle.fp ) {
script_filename = *p; script_filename = *p;
@ -1329,8 +1331,7 @@ static int cli_main( int argc, char * argv[] )
php_get_highlight_struct(&syntax_highlighter_ini); php_get_highlight_struct(&syntax_highlighter_ini);
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini); highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini);
} else if (source_highlight == 2) { } else if (source_highlight == 2) {
file_handle.filename = *p; file_handle.filename = zend_string_init(*p, strlen(*p), 0);
file_handle.free_filename = 0;
file_handle.opened_path = NULL; file_handle.opened_path = NULL;
ret = php_lint_script(&file_handle); ret = php_lint_script(&file_handle);
if (ret==SUCCESS) { if (ret==SUCCESS) {
@ -1340,8 +1341,7 @@ static int cli_main( int argc, char * argv[] )
} }
} else { } else {
file_handle.filename = *p; file_handle.filename = zend_string_init(*p, strlen(*p), 0);
file_handle.free_filename = 0;
file_handle.opened_path = NULL; file_handle.opened_path = NULL;
php_execute_script(&file_handle); php_execute_script(&file_handle);

View file

@ -241,9 +241,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
* as it may invalidate the file handle. */ * as it may invalidate the file handle. */
if (zend_stream_fixup(file, &bufptr, &len) == FAILURE) { if (zend_stream_fixup(file, &bufptr, &len) == FAILURE) {
if (type == ZEND_REQUIRE) { 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 { } else {
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file->filename); zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, ZSTR_VAL(file->filename));
} }
return NULL; 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) { 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]; char resolved_path_buf[MAXPATHLEN];
zend_op_array *op_array; zend_op_array *op_array;
phpdbg_file_source *dataptr; phpdbg_file_source *dataptr;
if (VCWD_REALPATH(filename, resolved_path_buf)) { if (VCWD_REALPATH(ZSTR_VAL(filename), resolved_path_buf)) {
filename = resolved_path_buf; filename = zend_string_init(resolved_path_buf, strlen(resolved_path_buf), 0);
if (file->opened_path) { if (file->opened_path) {
zend_string_release(file->opened_path); zend_string_release(file->opened_path);
file->opened_path = zend_string_init(filename, strlen(filename), 0); file->opened_path = filename;
} else { } else {
if (file->free_filename) { zend_string_release(file->filename);
efree((char *) file->filename);
}
file->free_filename = 0;
file->filename = filename; file->filename = filename;
} }
} }

View file

@ -566,7 +566,8 @@ int phpdbg_compile(void) /* {{{ */
return FAILURE; 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; CG(skip_shebang) = 1;
PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE); PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE);
zend_destroy_file_handle(&fh); zend_destroy_file_handle(&fh);
@ -581,7 +582,7 @@ int phpdbg_compile(void) /* {{{ */
} else { } else {
phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec)); phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec));
} }
zend_destroy_file_handle(&fh);
return FAILURE; return FAILURE;
} /* }}} */ } /* }}} */