| 1 | |
|---|
| 2 | #include "xcache.h" |
|---|
| 3 | #include "xc_sandbox.h" |
|---|
| 4 | #include "xc_utils.h" |
|---|
| 5 | #include "xcache_globals.h" |
|---|
| 6 | |
|---|
| 7 | /* utilities used by sandbox */ |
|---|
| 8 | static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL; |
|---|
| 9 | static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */ |
|---|
| 10 | { |
|---|
| 11 | va_list args; |
|---|
| 12 | va_start(args, format); |
|---|
| 13 | old_zend_error_cb(type, error_filename, error_lineno, format, args); |
|---|
| 14 | } |
|---|
| 15 | /* }}} */ |
|---|
| 16 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 17 | static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */ |
|---|
| 18 | { |
|---|
| 19 | return 0; |
|---|
| 20 | } |
|---|
| 21 | /* }}} */ |
|---|
| 22 | static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */ |
|---|
| 23 | { |
|---|
| 24 | if (auto_global->auto_global_callback) { |
|---|
| 25 | auto_global->armed = 1; |
|---|
| 26 | auto_global->auto_global_callback = xc_auto_global_callback; |
|---|
| 27 | } |
|---|
| 28 | else { |
|---|
| 29 | auto_global->armed = 0; |
|---|
| 30 | } |
|---|
| 31 | return ZEND_HASH_APPLY_KEEP; |
|---|
| 32 | } |
|---|
| 33 | /* }}} */ |
|---|
| 34 | #endif |
|---|
| 35 | |
|---|
| 36 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 37 | static void xc_free_zend_constant(zend_constant *c) /* {{{ */ |
|---|
| 38 | { |
|---|
| 39 | if (!(c->flags & CONST_PERSISTENT)) { |
|---|
| 40 | zval_dtor(&c->value); |
|---|
| 41 | } |
|---|
| 42 | free(ZSTR_V(c->name)); |
|---|
| 43 | } |
|---|
| 44 | /* }}} */ |
|---|
| 45 | #endif |
|---|
| 46 | |
|---|
| 47 | typedef struct { /* sandbox {{{ */ |
|---|
| 48 | ZEND_24(NOTHING, const) char *filename; |
|---|
| 49 | |
|---|
| 50 | HashTable orig_included_files; |
|---|
| 51 | HashTable *tmp_included_files; |
|---|
| 52 | |
|---|
| 53 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 54 | HashTable *orig_zend_constants; |
|---|
| 55 | HashTable tmp_zend_constants; |
|---|
| 56 | #endif |
|---|
| 57 | HashTable *orig_function_table; |
|---|
| 58 | HashTable *orig_class_table; |
|---|
| 59 | HashTable *orig_auto_globals; |
|---|
| 60 | HashTable tmp_function_table; |
|---|
| 61 | HashTable tmp_class_table; |
|---|
| 62 | HashTable tmp_auto_globals; |
|---|
| 63 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 64 | Bucket *tmp_internal_constant_tail; |
|---|
| 65 | #endif |
|---|
| 66 | Bucket *tmp_internal_function_tail; |
|---|
| 67 | Bucket *tmp_internal_class_tail; |
|---|
| 68 | |
|---|
| 69 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 70 | int orig_user_error_handler_error_reporting; |
|---|
| 71 | zend_uint compilererror_cnt; |
|---|
| 72 | zend_uint compilererror_size; |
|---|
| 73 | xc_compilererror_t *compilererrors; |
|---|
| 74 | #endif |
|---|
| 75 | |
|---|
| 76 | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
|---|
| 77 | zend_uint orig_compiler_options; |
|---|
| 78 | #endif |
|---|
| 79 | } xc_sandbox_t; |
|---|
| 80 | |
|---|
| 81 | #undef TG |
|---|
| 82 | #undef OG |
|---|
| 83 | #define TG(x) (sandbox->tmp_##x) |
|---|
| 84 | #define OG(x) (sandbox->orig_##x) |
|---|
| 85 | /* }}} */ |
|---|
| 86 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 87 | static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */ |
|---|
| 88 | { |
|---|
| 89 | xc_compilererror_t *compilererror; |
|---|
| 90 | xc_sandbox_t *sandbox; |
|---|
| 91 | TSRMLS_FETCH(); |
|---|
| 92 | |
|---|
| 93 | sandbox = (xc_sandbox_t *) XG(sandbox); |
|---|
| 94 | if (!sandbox) { |
|---|
| 95 | old_zend_error_cb(type, error_filename, error_lineno, format, args); |
|---|
| 96 | return; |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | switch (type) { |
|---|
| 100 | #ifdef E_STRICT |
|---|
| 101 | case E_STRICT: |
|---|
| 102 | #endif |
|---|
| 103 | #ifdef E_DEPRECATED |
|---|
| 104 | case E_DEPRECATED: |
|---|
| 105 | #endif |
|---|
| 106 | if (sandbox->compilererror_cnt <= sandbox->compilererror_size) { |
|---|
| 107 | if (sandbox->compilererror_size) { |
|---|
| 108 | sandbox->compilererror_size += 16; |
|---|
| 109 | sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors)); |
|---|
| 110 | } |
|---|
| 111 | else { |
|---|
| 112 | sandbox->compilererror_size = 16; |
|---|
| 113 | sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors)); |
|---|
| 114 | } |
|---|
| 115 | } |
|---|
| 116 | compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++]; |
|---|
| 117 | compilererror->type = type; |
|---|
| 118 | compilererror->lineno = error_lineno; |
|---|
| 119 | compilererror->error_len = vspprintf(&compilererror->error, 0, format, args); |
|---|
| 120 | break; |
|---|
| 121 | |
|---|
| 122 | default: { |
|---|
| 123 | /* give up, and user handler is not supported in this case */ |
|---|
| 124 | zend_uint i; |
|---|
| 125 | zend_uint old_lineno = CG(zend_lineno); |
|---|
| 126 | |
|---|
| 127 | for (i = 0; i < sandbox->compilererror_cnt; i ++) { |
|---|
| 128 | compilererror = &sandbox->compilererrors[i]; |
|---|
| 129 | CG(zend_lineno) = compilererror->lineno; |
|---|
| 130 | call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error); |
|---|
| 131 | efree(compilererror->error); |
|---|
| 132 | } |
|---|
| 133 | if (sandbox->compilererrors) { |
|---|
| 134 | efree(sandbox->compilererrors); |
|---|
| 135 | sandbox->compilererrors = NULL; |
|---|
| 136 | } |
|---|
| 137 | sandbox->compilererror_cnt = 0; |
|---|
| 138 | sandbox->compilererror_size = 0; |
|---|
| 139 | |
|---|
| 140 | CG(zend_lineno) = old_lineno; |
|---|
| 141 | old_zend_error_cb(type, error_filename, error_lineno, format, args); |
|---|
| 142 | break; |
|---|
| 143 | } |
|---|
| 144 | } |
|---|
| 145 | } |
|---|
| 146 | /* }}} */ |
|---|
| 147 | #endif |
|---|
| 148 | |
|---|
| 149 | static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */ |
|---|
| 150 | { |
|---|
| 151 | HashTable *h; |
|---|
| 152 | |
|---|
| 153 | assert(sandbox); |
|---|
| 154 | memset(sandbox, 0, sizeof(sandbox[0])); |
|---|
| 155 | |
|---|
| 156 | memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files))); |
|---|
| 157 | |
|---|
| 158 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 159 | OG(zend_constants) = EG(zend_constants); |
|---|
| 160 | EG(zend_constants) = &TG(zend_constants); |
|---|
| 161 | #endif |
|---|
| 162 | |
|---|
| 163 | OG(function_table) = CG(function_table); |
|---|
| 164 | CG(function_table) = &TG(function_table); |
|---|
| 165 | |
|---|
| 166 | OG(class_table) = CG(class_table); |
|---|
| 167 | CG(class_table) = &TG(class_table); |
|---|
| 168 | EG(class_table) = CG(class_table); |
|---|
| 169 | |
|---|
| 170 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 171 | OG(auto_globals) = CG(auto_globals); |
|---|
| 172 | CG(auto_globals) = &TG(auto_globals); |
|---|
| 173 | #endif |
|---|
| 174 | |
|---|
| 175 | TG(included_files) = &EG(included_files); |
|---|
| 176 | |
|---|
| 177 | zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1); |
|---|
| 178 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 179 | h = OG(zend_constants); |
|---|
| 180 | zend_hash_init_ex(&TG(zend_constants), 20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection); |
|---|
| 181 | xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table)); |
|---|
| 182 | TG(internal_constant_tail) = TG(zend_constants).pListTail; |
|---|
| 183 | #endif |
|---|
| 184 | h = OG(function_table); |
|---|
| 185 | zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection); |
|---|
| 186 | { |
|---|
| 187 | zend_function tmp_func; |
|---|
| 188 | zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func)); |
|---|
| 189 | } |
|---|
| 190 | TG(internal_function_tail) = TG(function_table).pListTail; |
|---|
| 191 | |
|---|
| 192 | h = OG(class_table); |
|---|
| 193 | zend_hash_init_ex(&TG(class_table), 16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection); |
|---|
| 194 | #if 0 && TODO |
|---|
| 195 | { |
|---|
| 196 | xc_cest_t tmp_cest; |
|---|
| 197 | zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest)); |
|---|
| 198 | } |
|---|
| 199 | #endif |
|---|
| 200 | TG(internal_class_tail) = TG(class_table).pListTail; |
|---|
| 201 | |
|---|
| 202 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 203 | /* shallow copy, don't destruct */ |
|---|
| 204 | h = OG(auto_globals); |
|---|
| 205 | zend_hash_init_ex(&TG(auto_globals), 8, NULL, NULL, h->persistent, h->bApplyProtection); |
|---|
| 206 | { |
|---|
| 207 | zend_auto_global tmp_autoglobal; |
|---|
| 208 | |
|---|
| 209 | zend_hash_copy(&TG(auto_globals), OG(auto_globals), NULL, (void *) &tmp_autoglobal, sizeof(tmp_autoglobal)); |
|---|
| 210 | zend_hash_apply(&TG(auto_globals), (apply_func_t) xc_auto_global_arm TSRMLS_CC); |
|---|
| 211 | } |
|---|
| 212 | #endif |
|---|
| 213 | |
|---|
| 214 | sandbox->filename = filename; |
|---|
| 215 | |
|---|
| 216 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 217 | sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting); |
|---|
| 218 | EG(user_error_handler_error_reporting) = 0; |
|---|
| 219 | |
|---|
| 220 | sandbox->compilererror_cnt = 0; |
|---|
| 221 | sandbox->compilererror_size = 0; |
|---|
| 222 | #endif |
|---|
| 223 | |
|---|
| 224 | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
|---|
| 225 | sandbox->orig_compiler_options = CG(compiler_options); |
|---|
| 226 | /* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK |
|---|
| 227 | */ |
|---|
| 228 | CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING; |
|---|
| 229 | #endif |
|---|
| 230 | |
|---|
| 231 | XG(sandbox) = (void *) sandbox; |
|---|
| 232 | return sandbox; |
|---|
| 233 | } |
|---|
| 234 | /* }}} */ |
|---|
| 235 | |
|---|
| 236 | #ifndef ZEND_COMPILE_DELAYED_BINDING |
|---|
| 237 | static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */ |
|---|
| 238 | { |
|---|
| 239 | xc_sandbox_t *sandbox = (xc_sandbox_t *) data; |
|---|
| 240 | xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC); |
|---|
| 241 | } |
|---|
| 242 | /* }}} */ |
|---|
| 243 | #endif |
|---|
| 244 | static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */ |
|---|
| 245 | { |
|---|
| 246 | zend_uint i; |
|---|
| 247 | Bucket *b; |
|---|
| 248 | |
|---|
| 249 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 250 | for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) { |
|---|
| 251 | zend_constant *c = (zend_constant*) b->pData; |
|---|
| 252 | xc_free_zend_constant(c); |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : TG(zend_constants).pListHead; |
|---|
| 256 | /* install constants */ |
|---|
| 257 | while (b != NULL) { |
|---|
| 258 | zend_constant *c = (zend_constant*) b->pData; |
|---|
| 259 | xc_install_constant(sandbox->filename, c, |
|---|
| 260 | BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC); |
|---|
| 261 | b = b->pListNext; |
|---|
| 262 | } |
|---|
| 263 | #endif |
|---|
| 264 | |
|---|
| 265 | b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead; |
|---|
| 266 | /* install function */ |
|---|
| 267 | while (b != NULL) { |
|---|
| 268 | zend_function *func = (zend_function*) b->pData; |
|---|
| 269 | xc_install_function(sandbox->filename, func, |
|---|
| 270 | BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC); |
|---|
| 271 | b = b->pListNext; |
|---|
| 272 | } |
|---|
| 273 | |
|---|
| 274 | b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead; |
|---|
| 275 | /* install class */ |
|---|
| 276 | while (b != NULL) { |
|---|
| 277 | xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1, |
|---|
| 278 | BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC); |
|---|
| 279 | b = b->pListNext; |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 283 | /* trigger auto_globals jit */ |
|---|
| 284 | for (b = TG(auto_globals).pListHead; b != NULL; b = b->pListNext) { |
|---|
| 285 | zend_auto_global *auto_global = (zend_auto_global *) b->pData; |
|---|
| 286 | /* check if actived */ |
|---|
| 287 | if (auto_global->auto_global_callback && !auto_global->armed) { |
|---|
| 288 | zend_u_is_auto_global(BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), auto_global->name_len TSRMLS_CC); |
|---|
| 289 | } |
|---|
| 290 | } |
|---|
| 291 | #endif |
|---|
| 292 | |
|---|
| 293 | #ifdef ZEND_COMPILE_DELAYED_BINDING |
|---|
| 294 | zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC); |
|---|
| 295 | #else |
|---|
| 296 | xc_undo_pass_two(CG(active_op_array) TSRMLS_CC); |
|---|
| 297 | xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC); |
|---|
| 298 | xc_redo_pass_two(CG(active_op_array) TSRMLS_CC); |
|---|
| 299 | #endif |
|---|
| 300 | |
|---|
| 301 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 302 | /* restore trigger errors */ |
|---|
| 303 | for (i = 0; i < sandbox->compilererror_cnt; i ++) { |
|---|
| 304 | xc_compilererror_t *error = &sandbox->compilererrors[i]; |
|---|
| 305 | CG(zend_lineno) = error->lineno; |
|---|
| 306 | zend_error(error->type, "%s", error->error); |
|---|
| 307 | } |
|---|
| 308 | CG(zend_lineno) = 0; |
|---|
| 309 | #endif |
|---|
| 310 | |
|---|
| 311 | i = 1; |
|---|
| 312 | /* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */ |
|---|
| 313 | zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL); |
|---|
| 314 | } |
|---|
| 315 | /* }}} */ |
|---|
| 316 | static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */ |
|---|
| 317 | { |
|---|
| 318 | XG(sandbox) = NULL; |
|---|
| 319 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 320 | EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting; |
|---|
| 321 | #endif |
|---|
| 322 | |
|---|
| 323 | /* restore first first install function/class */ |
|---|
| 324 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 325 | EG(zend_constants) = OG(zend_constants); |
|---|
| 326 | #endif |
|---|
| 327 | CG(function_table) = OG(function_table); |
|---|
| 328 | CG(class_table) = OG(class_table); |
|---|
| 329 | EG(class_table) = CG(class_table); |
|---|
| 330 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 331 | CG(auto_globals) = OG(auto_globals); |
|---|
| 332 | #endif |
|---|
| 333 | |
|---|
| 334 | if (op_array) { |
|---|
| 335 | zend_op_array *old_active_op_array = CG(active_op_array); |
|---|
| 336 | CG(in_compilation) = 1; |
|---|
| 337 | CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename; |
|---|
| 338 | CG(zend_lineno) = 0; |
|---|
| 339 | |
|---|
| 340 | CG(active_op_array) = op_array; |
|---|
| 341 | xc_sandbox_install(sandbox TSRMLS_CC); |
|---|
| 342 | CG(active_op_array) = old_active_op_array; |
|---|
| 343 | |
|---|
| 344 | CG(in_compilation) = 0; |
|---|
| 345 | CG(compiled_filename) = NULL; |
|---|
| 346 | |
|---|
| 347 | /* no free as it's installed */ |
|---|
| 348 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 349 | TG(zend_constants).pDestructor = NULL; |
|---|
| 350 | #endif |
|---|
| 351 | TG(function_table).pDestructor = NULL; |
|---|
| 352 | TG(class_table).pDestructor = NULL; |
|---|
| 353 | } |
|---|
| 354 | |
|---|
| 355 | /* destroy all the tmp */ |
|---|
| 356 | #ifdef HAVE_XCACHE_CONSTANT |
|---|
| 357 | zend_hash_destroy(&TG(zend_constants)); |
|---|
| 358 | #endif |
|---|
| 359 | zend_hash_destroy(&TG(function_table)); |
|---|
| 360 | zend_hash_destroy(&TG(class_table)); |
|---|
| 361 | #ifdef ZEND_ENGINE_2_1 |
|---|
| 362 | zend_hash_destroy(&TG(auto_globals)); |
|---|
| 363 | #endif |
|---|
| 364 | zend_hash_destroy(TG(included_files)); |
|---|
| 365 | |
|---|
| 366 | /* restore orig here, as EG/CG holded tmp before */ |
|---|
| 367 | memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files))); |
|---|
| 368 | |
|---|
| 369 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 370 | if (sandbox->compilererrors) { |
|---|
| 371 | zend_uint i; |
|---|
| 372 | for (i = 0; i < sandbox->compilererror_cnt; i ++) { |
|---|
| 373 | efree(sandbox->compilererrors[i].error); |
|---|
| 374 | } |
|---|
| 375 | efree(sandbox->compilererrors); |
|---|
| 376 | } |
|---|
| 377 | #endif |
|---|
| 378 | |
|---|
| 379 | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
|---|
| 380 | CG(compiler_options) = sandbox->orig_compiler_options; |
|---|
| 381 | #endif |
|---|
| 382 | } |
|---|
| 383 | /* }}} */ |
|---|
| 384 | zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */ |
|---|
| 385 | { |
|---|
| 386 | xc_sandbox_t sandbox; |
|---|
| 387 | zend_op_array *op_array = NULL; |
|---|
| 388 | zend_bool catched = 0; |
|---|
| 389 | |
|---|
| 390 | memset(&sandbox, 0, sizeof(sandbox)); |
|---|
| 391 | zend_try { |
|---|
| 392 | xc_sandbox_init(&sandbox, filename TSRMLS_CC); |
|---|
| 393 | op_array = sandboxed_func(data TSRMLS_CC); |
|---|
| 394 | } zend_catch { |
|---|
| 395 | catched = 1; |
|---|
| 396 | } zend_end_try(); |
|---|
| 397 | |
|---|
| 398 | xc_sandbox_free(&sandbox, op_array TSRMLS_CC); |
|---|
| 399 | if (catched) { |
|---|
| 400 | zend_bailout(); |
|---|
| 401 | } |
|---|
| 402 | return op_array; |
|---|
| 403 | } |
|---|
| 404 | /* }}} */ |
|---|
| 405 | const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */ |
|---|
| 406 | { |
|---|
| 407 | xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); |
|---|
| 408 | assert(sandbox); |
|---|
| 409 | return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead; |
|---|
| 410 | } |
|---|
| 411 | /* }}} */ |
|---|
| 412 | const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */ |
|---|
| 413 | { |
|---|
| 414 | xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); |
|---|
| 415 | assert(sandbox); |
|---|
| 416 | return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead; |
|---|
| 417 | } |
|---|
| 418 | /* }}} */ |
|---|
| 419 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 420 | xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */ |
|---|
| 421 | { |
|---|
| 422 | xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); |
|---|
| 423 | assert(sandbox); |
|---|
| 424 | return sandbox->compilererrors; |
|---|
| 425 | } |
|---|
| 426 | /* }}} */ |
|---|
| 427 | zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */ |
|---|
| 428 | { |
|---|
| 429 | xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox); |
|---|
| 430 | assert(sandbox); |
|---|
| 431 | return sandbox->compilererror_cnt; |
|---|
| 432 | } |
|---|
| 433 | /* }}} */ |
|---|
| 434 | #endif |
|---|
| 435 | |
|---|
| 436 | /* init/destroy */ |
|---|
| 437 | int xc_util_init(int module_number TSRMLS_DC) /* {{{ */ |
|---|
| 438 | { |
|---|
| 439 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 440 | old_zend_error_cb = zend_error_cb; |
|---|
| 441 | zend_error_cb = xc_sandbox_error_cb; |
|---|
| 442 | #endif |
|---|
| 443 | |
|---|
| 444 | return SUCCESS; |
|---|
| 445 | } |
|---|
| 446 | /* }}} */ |
|---|
| 447 | void xc_util_destroy() /* {{{ */ |
|---|
| 448 | { |
|---|
| 449 | #ifdef XCACHE_ERROR_CACHING |
|---|
| 450 | if (zend_error_cb == xc_sandbox_error_cb) { |
|---|
| 451 | zend_error_cb = old_zend_error_cb; |
|---|
| 452 | } |
|---|
| 453 | #endif |
|---|
| 454 | } |
|---|
| 455 | /* }}} */ |
|---|
| 456 | |
|---|