diff --git a/disassembler.c b/disassembler.c index 8b807d8..51d9c35 100644 --- a/disassembler.c +++ b/disassembler.c @@ -3,21 +3,12 @@ #include "utils.h" #include "processor.h" -#define return_value dst - -/* sandbox {{{ */ -#undef TG -#undef OG -#define TG(x) (sandbox->tmp_##x) -#define OG(x) (sandbox->orig_##x) -/* }}} */ - #ifndef HAVE_XCACHE_OPCODE_SPEC_DEF #error disassembler cannot be built without xcache/opcode_spec_def.h #endif -static void xc_dasm(xc_sandbox_t *sandbox, zval *dst, zend_op_array *op_array TSRMLS_DC) /* {{{ */ +static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */ { - Bucket *b; + const Bucket *b; zval *zv, *list; xc_compile_result_t cr; int bufsize = 2; @@ -30,19 +21,18 @@ static void xc_dasm(xc_sandbox_t *sandbox, zval *dst, zend_op_array *op_array TS xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC); /* go */ - array_init(dst); + array_init(output); ALLOC_INIT_ZVAL(zv); array_init(zv); xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC); - add_assoc_zval_ex(dst, ZEND_STRS("op_array"), zv); + add_assoc_zval_ex(output, ZEND_STRS("op_array"), zv); buf = emalloc(bufsize); ALLOC_INIT_ZVAL(list); array_init(list); - b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead; - for (; b; b = b->pListNext) { + for (b = xc_sandbox_user_function_begin(); b; b = b->pListNext) { int keysize, keyLength; ALLOC_INIT_ZVAL(zv); @@ -74,12 +64,11 @@ static void xc_dasm(xc_sandbox_t *sandbox, zval *dst, zend_op_array *op_array TS add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv); } - add_assoc_zval_ex(dst, ZEND_STRS("function_table"), list); + add_assoc_zval_ex(output, ZEND_STRS("function_table"), list); ALLOC_INIT_ZVAL(list); array_init(list); - b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead; - for (; b; b = b->pListNext) { + for (b = xc_sandbox_user_class_begin(); b; b = b->pListNext) { int keysize, keyLength; ALLOC_INIT_ZVAL(zv); @@ -111,98 +100,93 @@ static void xc_dasm(xc_sandbox_t *sandbox, zval *dst, zend_op_array *op_array TS add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv); } efree(buf); - add_assoc_zval_ex(dst, ZEND_STRS("class_table"), list); + add_assoc_zval_ex(output, ZEND_STRS("class_table"), list); /*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/ xc_compile_result_free(&cr); - - return; } /* }}} */ -void xc_dasm_string(zval *dst, zval *source TSRMLS_DC) /* {{{ */ +typedef struct xc_dasm_sandboxed_t { /* {{{ */ + enum Type { + xc_dasm_file_t + , xc_dasm_string_t + } type; + union { + zval *zfilename; + struct { + zval *source; + char *eval_name; + } compile_string; + } input; + + zval *output; +} xc_dasm_sandboxed_t; /* {{{ */ + +zend_op_array *xc_dasm_sandboxed(void *data TSRMLS_DC) { - int catched; + zend_bool catched = 0; zend_op_array *op_array = NULL; - xc_sandbox_t sandbox; - char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC); + xc_dasm_sandboxed_t *sandboxed_dasm = (xc_dasm_sandboxed_t *) data; - xc_sandbox_init(&sandbox, eval_name TSRMLS_CC); - - catched = 0; zend_try { - op_array = compile_string(source, eval_name TSRMLS_CC); + if (sandboxed_dasm->type == xc_dasm_file_t) { + op_array = compile_filename(ZEND_REQUIRE, sandboxed_dasm->input.zfilename TSRMLS_CC); + } + else { + op_array = compile_string(sandboxed_dasm->input.compile_string.source, sandboxed_dasm->input.compile_string.eval_name TSRMLS_CC); + } } zend_catch { catched = 1; } zend_end_try(); if (catched || !op_array) { - goto err_compile; +#define return_value sandboxed_dasm->output + RETVAL_FALSE; +#undef return_value + return NULL; } - xc_dasm(&sandbox, dst, op_array TSRMLS_CC); + xc_dasm(sandboxed_dasm->output, op_array TSRMLS_CC); /* free */ - efree(eval_name); #ifdef ZEND_ENGINE_2 destroy_op_array(op_array TSRMLS_CC); #else destroy_op_array(op_array); #endif efree(op_array); - xc_sandbox_free(&sandbox, 0 TSRMLS_CC); - return; -err_compile: - efree(eval_name); - xc_sandbox_free(&sandbox, 0 TSRMLS_CC); + return NULL; +} /* }}} */ +void xc_dasm_string(zval *output, zval *source TSRMLS_DC) /* {{{ */ +{ + xc_dasm_sandboxed_t sandboxed_dasm; + char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC); - RETURN_FALSE; + sandboxed_dasm.output = output; + sandboxed_dasm.type = xc_dasm_string_t; + sandboxed_dasm.input.compile_string.source = source; + sandboxed_dasm.input.compile_string.eval_name = eval_name; + xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, eval_name TSRMLS_CC); + efree(eval_name); } /* }}} */ -void xc_dasm_file(zval *dst, const char *filename TSRMLS_DC) /* {{{ */ +void xc_dasm_file(zval *output, const char *filename TSRMLS_DC) /* {{{ */ { - int catched; - zend_op_array *op_array = NULL; - xc_sandbox_t sandbox; zval *zfilename; + xc_dasm_sandboxed_t sandboxed_dasm; MAKE_STD_ZVAL(zfilename); zfilename->value.str.val = estrdup(filename); zfilename->value.str.len = strlen(filename); zfilename->type = IS_STRING; - xc_sandbox_init(&sandbox, zfilename->value.str.val TSRMLS_CC); - - catched = 0; - zend_try { - op_array = compile_filename(ZEND_REQUIRE, zfilename TSRMLS_CC); - } zend_catch { - catched = 1; - } zend_end_try(); - - if (catched || !op_array) { - goto err_compile; - } - - xc_dasm(&sandbox, dst, op_array TSRMLS_CC); - - /* free */ -#ifdef ZEND_ENGINE_2 - destroy_op_array(op_array TSRMLS_CC); -#else - destroy_op_array(op_array); -#endif - efree(op_array); - xc_sandbox_free(&sandbox, 0 TSRMLS_CC); - zval_dtor(zfilename); - FREE_ZVAL(zfilename); - return; - -err_compile: - xc_sandbox_free(&sandbox, 0 TSRMLS_CC); + sandboxed_dasm.output = output; + sandboxed_dasm.type = xc_dasm_file_t; + sandboxed_dasm.input.zfilename = zfilename; + xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, zfilename->value.str.val TSRMLS_CC); zval_dtor(zfilename); FREE_ZVAL(zfilename); - RETURN_FALSE; } /* }}} */ diff --git a/utils.c b/utils.c index 4246b8f..327a96e 100644 --- a/utils.c +++ b/utils.c @@ -581,7 +581,40 @@ ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, } /* }}} */ -/* sandbox {{{ */ +typedef struct { /* sandbox {{{ */ + ZEND_24(NOTHING, const) char *filename; + + HashTable orig_included_files; + HashTable *tmp_included_files; + +#ifdef HAVE_XCACHE_CONSTANT + HashTable *orig_zend_constants; + HashTable tmp_zend_constants; +#endif + HashTable *orig_function_table; + HashTable *orig_class_table; + HashTable *orig_auto_globals; + HashTable tmp_function_table; + HashTable tmp_class_table; + HashTable tmp_auto_globals; +#ifdef HAVE_XCACHE_CONSTANT + Bucket *tmp_internal_constant_tail; +#endif + Bucket *tmp_internal_function_tail; + Bucket *tmp_internal_class_tail; + +#ifdef XCACHE_ERROR_CACHING + int orig_user_error_handler_error_reporting; + zend_uint compilererror_cnt; + zend_uint compilererror_size; + xc_compilererror_t *compilererrors; +#endif + +#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES + zend_uint orig_compiler_options; +#endif +} xc_sandbox_t; + #undef TG #undef OG #define TG(x) (sandbox->tmp_##x) @@ -730,6 +763,7 @@ void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{ } /* }}} */ #endif + xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */ { HashTable *h; @@ -824,7 +858,7 @@ static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS } /* }}} */ #endif -static void xc_sandbox_install(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_DC) /* {{{ */ +static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */ { zend_uint i; Bucket *b; @@ -873,15 +907,13 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox, xc_install_action_t instal } #endif - if (install != XC_InstallNoBinding) { #ifdef ZEND_COMPILE_DELAYED_BINDING - zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC); + zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC); #else - xc_undo_pass_two(CG(active_op_array) TSRMLS_CC); - xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC); - xc_redo_pass_two(CG(active_op_array) TSRMLS_CC); + xc_undo_pass_two(CG(active_op_array) TSRMLS_CC); + xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC); + xc_redo_pass_two(CG(active_op_array) TSRMLS_CC); #endif - } #ifdef XCACHE_ERROR_CACHING /* restore trigger errors */ @@ -897,7 +929,7 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox, xc_install_action_t instal zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL); } /* }}} */ -void xc_sandbox_free(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_DC) /* {{{ */ +void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */ { XG(sandbox) = NULL; #ifdef XCACHE_ERROR_CACHING @@ -915,11 +947,16 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_D CG(auto_globals) = OG(auto_globals); #endif - if (install != XC_NoInstall) { + if (op_array) { + zend_op_array *old_active_op_array = CG(active_op_array); CG(in_compilation) = 1; CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename; CG(zend_lineno) = 0; - xc_sandbox_install(sandbox, install TSRMLS_CC); + + CG(active_op_array) = op_array; + xc_sandbox_install(sandbox TSRMLS_CC); + CG(active_op_array) = old_active_op_array; + CG(in_compilation) = 0; CG(compiled_filename) = NULL; @@ -960,6 +997,34 @@ void xc_sandbox_free(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_D #endif } /* }}} */ +const Bucket *xc_sandbox_user_function_begin() /* {{{ */ +{ + xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); + assert(sandbox); + return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead; +} /* {{{ */ +const Bucket *xc_sandbox_user_class_begin() /* {{{ */ +{ + xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); + assert(sandbox); + return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead; +} /* {{{ */ +#ifdef XCACHE_ERROR_CACHING +xc_compilererror_t *xc_sandbox_compilererrors() /* {{{ */ +{ + xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); + assert(sandbox); + return sandbox->compilererrors; +} /* }}} */ +zend_uint xc_sandbox_compilererror_cnt() /* {{{ */ +{ + xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); + assert(sandbox); + return sandbox->compilererror_cnt; +} /* }}} */ +#endif + + int xc_vtrace(const char *fmt, va_list args) /* {{{ */ { return vfprintf(stderr, fmt, args); diff --git a/utils.h b/utils.h index a02a543..e1ad6bd 100644 --- a/utils.h +++ b/utils.h @@ -79,50 +79,18 @@ ZESW(xc_cest_t *, void) xc_install_class(ZEND_24(NOTHING, const) char *filename, #define XCACHE_ERROR_CACHING #endif -/* sandbox */ -typedef struct { - ZEND_24(NOTHING, const) char *filename; - - HashTable orig_included_files; - HashTable *tmp_included_files; - -#ifdef HAVE_XCACHE_CONSTANT - HashTable *orig_zend_constants; - HashTable tmp_zend_constants; -#endif - HashTable *orig_function_table; - HashTable *orig_class_table; - HashTable *orig_auto_globals; - HashTable tmp_function_table; - HashTable tmp_class_table; - HashTable tmp_auto_globals; -#ifdef HAVE_XCACHE_CONSTANT - Bucket *tmp_internal_constant_tail; -#endif - Bucket *tmp_internal_function_tail; - Bucket *tmp_internal_class_tail; - +/* return op_array to install */ +typedef zend_op_array *(*xc_sandboxed_func_t)(void *data TSRMLS_DC); +zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC); +const Bucket *xc_sandbox_user_function_begin(); +const Bucket *xc_sandbox_user_class_begin(); +zend_uint xc_sandbox_compilererror_cnt(); #ifdef XCACHE_ERROR_CACHING - int orig_user_error_handler_error_reporting; - zend_uint compilererror_cnt; - zend_uint compilererror_size; - xc_compilererror_t *compilererrors; +xc_compilererror_t *xc_sandbox_compilererrors(); +zend_uint xc_sandbox_compilererror_cnt(); #endif -#ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES - zend_uint orig_compiler_options; -#endif -} xc_sandbox_t; - -typedef enum _xc_install_action_t { - XC_NoInstall, - XC_Install, - XC_InstallNoBinding -} xc_install_action_t; - void xc_zend_class_add_ref(zend_class_entry ZESW(*ce, **ce)); -xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC); -void xc_sandbox_free(xc_sandbox_t *sandbox, xc_install_action_t install TSRMLS_DC); typedef zend_bool (*xc_if_func_t)(void *data); diff --git a/xcache.c b/xcache.c index 7504e6e..2a13cf9 100644 --- a/xcache.c +++ b/xcache.c @@ -1006,6 +1006,18 @@ static int xc_resolve_path_stat(const char *filepath, char *path_buffer, struct } /* }}} */ #endif +typedef struct xc_compiler_t { /* {{{ */ + /* XCache cached compile state */ + const char *filename; + size_t filename_len; + const char *opened_path; + char opened_path_buffer[MAXPATHLEN]; + + xc_entry_hash_t entry_hash; + xc_entry_php_t new_entry; + xc_entry_data_php_t new_php; +} xc_compiler_t; +/* }}} */ typedef struct xc_entry_resolve_path_data_t { /* {{{ */ xc_compiler_t *compiler; xc_entry_php_t **stored_entry; @@ -1797,8 +1809,8 @@ static void xc_compile_php(xc_compiler_t *compiler, zend_file_handle *h, int typ } /* }}} */ #ifdef XCACHE_ERROR_CACHING - compiler->new_php.compilererrors = ((xc_sandbox_t *) XG(sandbox))->compilererrors; - compiler->new_php.compilererror_cnt = ((xc_sandbox_t *) XG(sandbox))->compilererror_cnt; + compiler->new_php.compilererrors = xc_sandbox_compilererrors(); + compiler->new_php.compilererror_cnt = xc_sandbox_compilererror_cnt(); #endif #ifndef ZEND_COMPILE_DELAYED_BINDING /* {{{ find inherited classes that should be early-binding */ @@ -1881,7 +1893,118 @@ static zend_op_array *xc_check_initial_compile_file(zend_file_handle *h, int typ return origin_compile_file(h, type TSRMLS_CC); } /* }}} */ -static zend_op_array *xc_compile_file_ex(xc_compiler_t *compiler, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ +typedef struct xc_sandboxed_compiler_t { /* {{{ */ + xc_compiler_t *compiler; + /* input */ + zend_file_handle *h; + int type; + + /* sandbox output */ + xc_entry_php_t *stored_entry; + xc_entry_data_php_t *stored_php; +} xc_sandboxed_compiler_t; /* {{{ */ + +static zend_op_array *xc_compile_file_sandboxed(void *data TSRMLS_DC) /* {{{ */ +{ + xc_sandboxed_compiler_t *sandboxed_compiler = (xc_sandboxed_compiler_t *) data; + xc_compiler_t *compiler = sandboxed_compiler->compiler; + zend_bool catched = 0; + xc_cache_t *cache = xc_php_caches[compiler->entry_hash.cacheid]; + xc_entry_php_t *stored_entry; + xc_entry_data_php_t *stored_php; + + /* {{{ compile */ + /* make compile inside sandbox */ +#ifdef HAVE_XCACHE_CONSTANT + compiler->new_php.constinfos = NULL; +#endif + compiler->new_php.funcinfos = NULL; + compiler->new_php.classinfos = NULL; +#ifdef ZEND_ENGINE_2_1 + compiler->new_php.autoglobals = NULL; +#endif + memset(&compiler->new_php.op_array_info, 0, sizeof(compiler->new_php.op_array_info)); + + XG(initial_compile_file_called) = 0; + zend_try { + compiler->new_php.op_array = NULL; + xc_compile_php(compiler, sandboxed_compiler->h, sandboxed_compiler->type TSRMLS_CC); + } zend_catch { + catched = 1; + } zend_end_try(); + + if (catched + || !compiler->new_php.op_array /* possible ? */ + || !XG(initial_compile_file_called)) { + goto err_aftersandbox; + } + + /* }}} */ +#ifdef SHOW_DPRINT + compiler->new_entry.php = &compiler->new_php; + xc_dprint(&compiler->new_entry, 0 TSRMLS_CC); +#endif + + stored_entry = NULL; + stored_php = NULL; + ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ + /* php_store */ + stored_php = xc_php_store_unlocked(cache, &compiler->new_php TSRMLS_CC); + if (!stored_php) { + /* error */ + break; + } + /* entry_store */ + compiler->new_entry.php = stored_php; + stored_entry = xc_entry_php_store_unlocked(cache, compiler->entry_hash.entryslotid, &compiler->new_entry TSRMLS_CC); + if (stored_entry) { + xc_php_addref_unlocked(stored_php); + TRACE(" cached %d:%s, holding", compiler->new_entry.file_inode, stored_entry->entry.name.str.val); + xc_entry_hold_php_unlocked(cache, stored_entry TSRMLS_CC); + } + } LEAVE_LOCK_EX(cache); + /* }}} */ + TRACE("%s", stored_entry ? "stored" : "store failed"); + + if (catched || !stored_php) { + goto err_aftersandbox; + } + + cache->compiling = 0; + xc_free_php(&compiler->new_php TSRMLS_CC); + + if (stored_entry) { + if (compiler->new_php.op_array) { +#ifdef ZEND_ENGINE_2 + destroy_op_array(compiler->new_php.op_array TSRMLS_CC); +#else + destroy_op_array(compiler->new_php.op_array); +#endif + efree(compiler->new_php.op_array); + compiler->new_php.op_array = NULL; + sandboxed_compiler->h = NULL; + } + sandboxed_compiler->stored_entry = stored_entry; + sandboxed_compiler->stored_php = stored_php; + /* sandbox no install */ + return NULL; + } + else { + /* install it with sandbox */ + return compiler->new_php.op_array; + } + +err_aftersandbox: + xc_free_php(&compiler->new_php TSRMLS_CC); + + cache->compiling = 0; + if (catched) { + cache->errors ++; + zend_bailout(); + } + return compiler->new_php.op_array; +} /* }}} */ +static zend_op_array *xc_compile_file_cached(xc_compiler_t *compiler, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ { /* if (clog) { @@ -1898,8 +2021,11 @@ static zend_op_array *xc_compile_file_ex(xc_compiler_t *compiler, zend_file_hand if (clog) { return old; } - php = compile(); - entry = create entries[entry]; + + inside_sandbox { + php = compile; + entry = create entries[entry]; + } } entry.php = php; @@ -1911,8 +2037,9 @@ static zend_op_array *xc_compile_file_ex(xc_compiler_t *compiler, zend_file_hand xc_entry_data_php_t *stored_php; zend_bool gaveup = 0; zend_bool catched = 0; - xc_sandbox_t sandbox; + zend_op_array *op_array; xc_cache_t *cache = xc_php_caches[compiler->entry_hash.cacheid]; + xc_sandboxed_compiler_t sandboxed_compiler; /* stale clogs precheck */ if (XG(request_time) - cache->compiling < 30) { @@ -2001,98 +2128,18 @@ static zend_op_array *xc_compile_file_ex(xc_compiler_t *compiler, zend_file_hand } /* }}} */ - /* {{{ compile */ - /* make compile inside sandbox */ - -#ifdef HAVE_XCACHE_CONSTANT - compiler->new_php.constinfos = NULL; -#endif - compiler->new_php.funcinfos = NULL; - compiler->new_php.classinfos = NULL; -#ifdef ZEND_ENGINE_2_1 - compiler->new_php.autoglobals = NULL; -#endif - memset(&compiler->new_php.op_array_info, 0, sizeof(compiler->new_php.op_array_info)); - - XG(initial_compile_file_called) = 0; - zend_try { - xc_sandbox_init(&sandbox, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); - compiler->new_php.op_array = NULL; - xc_compile_php(compiler, h, type TSRMLS_CC); - } zend_catch { - catched = 1; - } zend_end_try(); - - if (catched - || !compiler->new_php.op_array /* possible ? */ - || !XG(initial_compile_file_called)) { - goto err_aftersandbox; - } - - /* }}} */ -#ifdef SHOW_DPRINT - compiler->new_entry.php = &compiler->new_php; - xc_dprint(&compiler->new_entry, 0 TSRMLS_CC); -#endif - ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ - /* php_store */ - stored_php = xc_php_store_unlocked(cache, &compiler->new_php TSRMLS_CC); - if (!stored_php) { - /* error */ - break; - } - /* entry_store */ - compiler->new_entry.php = stored_php; - stored_entry = xc_entry_php_store_unlocked(cache, compiler->entry_hash.entryslotid, &compiler->new_entry TSRMLS_CC); - if (stored_entry) { - xc_php_addref_unlocked(stored_php); - TRACE(" cached %d:%s, holding", compiler->new_entry.file_inode, stored_entry->entry.name.str.val); - xc_entry_hold_php_unlocked(cache, stored_entry TSRMLS_CC); - } - } LEAVE_LOCK_EX(cache); - /* }}} */ - TRACE("%s", stored_entry ? "stored" : "store failed"); - - if (catched || !stored_php) { - goto err_aftersandbox; - } - - cache->compiling = 0; - xc_free_php(&compiler->new_php TSRMLS_CC); - - if (stored_entry) { - if (compiler->new_php.op_array) { -#ifdef ZEND_ENGINE_2 - destroy_op_array(compiler->new_php.op_array TSRMLS_CC); -#else - destroy_op_array(compiler->new_php.op_array); -#endif - efree(compiler->new_php.op_array); - compiler->new_php.op_array = NULL; - h = NULL; - } - xc_sandbox_free(&sandbox, XC_NoInstall TSRMLS_CC); + sandboxed_compiler.compiler = compiler; + sandboxed_compiler.h = h; + sandboxed_compiler.type = type; + sandboxed_compiler.stored_php = NULL; + sandboxed_compiler.stored_entry = NULL; + op_array = xc_sandbox(xc_compile_file_sandboxed, (void *) &sandboxed_compiler, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); + if (sandboxed_compiler.stored_entry) { return xc_compile_restore(stored_entry, stored_php, h TSRMLS_CC); } else { - zend_op_array *old_active_op_array = CG(active_op_array); - /* install it */ - CG(active_op_array) = compiler->new_php.op_array; - xc_sandbox_free(&sandbox, XC_Install TSRMLS_CC); - CG(active_op_array) = old_active_op_array; - } - return compiler->new_php.op_array; - -err_aftersandbox: - xc_free_php(&compiler->new_php TSRMLS_CC); - xc_sandbox_free(&sandbox, XC_NoInstall TSRMLS_CC); - - cache->compiling = 0; - if (catched) { - cache->errors ++; - zend_bailout(); + return op_array; } - return compiler->new_php.op_array; } /* }}} */ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ @@ -2130,7 +2177,7 @@ static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) / } /* }}} */ - op_array = xc_compile_file_ex(&compiler, h, type TSRMLS_CC); + op_array = xc_compile_file_cached(&compiler, h, type TSRMLS_CC); xc_entry_free_key_php(&compiler.new_entry TSRMLS_CC); diff --git a/xcache.h b/xcache.h index 0376058..a1ed5a5 100644 --- a/xcache.h +++ b/xcache.h @@ -464,17 +464,6 @@ typedef struct xc_entry_hash_t { /* {{{ */ xc_hash_value_t entryslotid; } xc_entry_hash_t; /* }}} */ -typedef struct xc_compiler_t { /* {{{ */ - const char *filename; - size_t filename_len; - const char *opened_path; - char opened_path_buffer[MAXPATHLEN]; - - xc_entry_hash_t entry_hash; - xc_entry_php_t new_entry; - xc_entry_data_php_t new_php; -} xc_compiler_t; -/* }}} */ extern zend_module_entry xcache_module_entry; #define phpext_xcache_ptr &xcache_module_entry