Changeset 986 for trunk/main/xc_utils.c
- Timestamp:
- 2012-07-18T05:13:28+02:00 (11 months ago)
- File:
-
- 1 edited
-
trunk/main/xc_utils.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/main/xc_utils.c
r983 r986 27 27 #endif 28 28 29 static void (*old_zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) = NULL;30 static void call_old_zend_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, ...) /* {{{ */31 {32 va_list args;33 va_start(args, format);34 old_zend_error_cb(type, error_filename, error_lineno, format, args);35 }36 29 /* }}} */ 37 30 … … 579 572 /* }}} */ 580 573 581 typedef struct { /* sandbox {{{ */582 ZEND_24(NOTHING, const) char *filename;583 584 HashTable orig_included_files;585 HashTable *tmp_included_files;586 587 #ifdef HAVE_XCACHE_CONSTANT588 HashTable *orig_zend_constants;589 HashTable tmp_zend_constants;590 #endif591 HashTable *orig_function_table;592 HashTable *orig_class_table;593 HashTable *orig_auto_globals;594 HashTable tmp_function_table;595 HashTable tmp_class_table;596 HashTable tmp_auto_globals;597 #ifdef HAVE_XCACHE_CONSTANT598 Bucket *tmp_internal_constant_tail;599 #endif600 Bucket *tmp_internal_function_tail;601 Bucket *tmp_internal_class_tail;602 603 #ifdef XCACHE_ERROR_CACHING604 int orig_user_error_handler_error_reporting;605 zend_uint compilererror_cnt;606 zend_uint compilererror_size;607 xc_compilererror_t *compilererrors;608 #endif609 610 #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES611 zend_uint orig_compiler_options;612 #endif613 } xc_sandbox_t;614 615 #undef TG616 #undef OG617 #define TG(x) (sandbox->tmp_##x)618 #define OG(x) (sandbox->orig_##x)619 /* }}} */620 #ifdef XCACHE_ERROR_CACHING621 static void xc_sandbox_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) /* {{{ */622 {623 xc_compilererror_t *compilererror;624 xc_sandbox_t *sandbox;625 TSRMLS_FETCH();626 627 sandbox = (xc_sandbox_t *) XG(sandbox);628 if (!sandbox) {629 old_zend_error_cb(type, error_filename, error_lineno, format, args);630 return;631 }632 633 switch (type) {634 #ifdef E_STRICT635 case E_STRICT:636 #endif637 #ifdef E_DEPRECATED638 case E_DEPRECATED:639 #endif640 if (sandbox->compilererror_cnt <= sandbox->compilererror_size) {641 if (sandbox->compilererror_size) {642 sandbox->compilererror_size += 16;643 sandbox->compilererrors = erealloc(sandbox->compilererrors, sandbox->compilererror_size * sizeof(sandbox->compilererrors));644 }645 else {646 sandbox->compilererror_size = 16;647 sandbox->compilererrors = emalloc(sandbox->compilererror_size * sizeof(sandbox->compilererrors));648 }649 }650 compilererror = &sandbox->compilererrors[sandbox->compilererror_cnt++];651 compilererror->type = type;652 compilererror->lineno = error_lineno;653 compilererror->error_len = vspprintf(&compilererror->error, 0, format, args);654 break;655 656 default: {657 /* give up, and user handler is not supported in this case */658 zend_uint i;659 zend_uint old_lineno = CG(zend_lineno);660 661 for (i = 0; i < sandbox->compilererror_cnt; i ++) {662 compilererror = &sandbox->compilererrors[i];663 CG(zend_lineno) = compilererror->lineno;664 call_old_zend_error_cb(compilererror->type, error_filename, error_lineno, "%s", compilererror->error);665 efree(compilererror->error);666 }667 if (sandbox->compilererrors) {668 efree(sandbox->compilererrors);669 sandbox->compilererrors = NULL;670 }671 sandbox->compilererror_cnt = 0;672 sandbox->compilererror_size = 0;673 674 CG(zend_lineno) = old_lineno;675 old_zend_error_cb(type, error_filename, error_lineno, format, args);676 break;677 }678 }679 }680 /* }}} */681 #endif682 #ifdef ZEND_ENGINE_2_1683 static zend_bool xc_auto_global_callback(ZEND_24(NOTHING, const) char *name, uint name_len TSRMLS_DC) /* {{{ */684 {685 return 0;686 }687 /* }}} */688 static int xc_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */689 {690 if (auto_global->auto_global_callback) {691 auto_global->armed = 1;692 auto_global->auto_global_callback = xc_auto_global_callback;693 }694 else {695 auto_global->armed = 0;696 }697 return ZEND_HASH_APPLY_KEEP;698 }699 /* }}} */700 #endif701 702 574 void xc_hash_copy_if(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, xc_if_func_t checker) /* {{{ */ 703 575 { … … 746 618 } 747 619 /* }}} */ 748 static void xc_free_zend_constant(zend_constant *c) /* {{{ */749 {750 if (!(c->flags & CONST_PERSISTENT)) {751 zval_dtor(&c->value);752 }753 free(ZSTR_V(c->name));754 }755 /* }}} */756 620 void xc_copy_internal_zend_constants(HashTable *target, HashTable *source) /* {{{ */ 757 621 { … … 761 625 /* }}} */ 762 626 #endif 763 764 static xc_sandbox_t *xc_sandbox_init(xc_sandbox_t *sandbox, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */765 {766 HashTable *h;767 768 assert(sandbox);769 memset(sandbox, 0, sizeof(sandbox[0]));770 771 memcpy(&OG(included_files), &EG(included_files), sizeof(EG(included_files)));772 773 #ifdef HAVE_XCACHE_CONSTANT774 OG(zend_constants) = EG(zend_constants);775 EG(zend_constants) = &TG(zend_constants);776 #endif777 778 OG(function_table) = CG(function_table);779 CG(function_table) = &TG(function_table);780 781 OG(class_table) = CG(class_table);782 CG(class_table) = &TG(class_table);783 EG(class_table) = CG(class_table);784 785 #ifdef ZEND_ENGINE_2_1786 OG(auto_globals) = CG(auto_globals);787 CG(auto_globals) = &TG(auto_globals);788 #endif789 790 TG(included_files) = &EG(included_files);791 792 zend_hash_init_ex(TG(included_files), 5, NULL, NULL, 0, 1);793 #ifdef HAVE_XCACHE_CONSTANT794 h = OG(zend_constants);795 zend_hash_init_ex(&TG(zend_constants), 20, NULL, (dtor_func_t) xc_free_zend_constant, h->persistent, h->bApplyProtection);796 xc_copy_internal_zend_constants(&TG(zend_constants), &XG(internal_constant_table));797 TG(internal_constant_tail) = TG(zend_constants).pListTail;798 #endif799 h = OG(function_table);800 zend_hash_init_ex(&TG(function_table), 128, NULL, ZEND_FUNCTION_DTOR, h->persistent, h->bApplyProtection);801 {802 zend_function tmp_func;803 zend_hash_copy(&TG(function_table), &XG(internal_function_table), NULL, (void *) &tmp_func, sizeof(tmp_func));804 }805 TG(internal_function_tail) = TG(function_table).pListTail;806 807 h = OG(class_table);808 zend_hash_init_ex(&TG(class_table), 16, NULL, ZEND_CLASS_DTOR, h->persistent, h->bApplyProtection);809 #if 0 && TODO810 {811 xc_cest_t tmp_cest;812 zend_hash_copy(&TG(class_table), &XG(internal_class_table), NULL, (void *) &tmp_cest, sizeof(tmp_cest));813 }814 #endif815 TG(internal_class_tail) = TG(class_table).pListTail;816 817 #ifdef ZEND_ENGINE_2_1818 /* shallow copy, don't destruct */819 h = OG(auto_globals);820 zend_hash_init_ex(&TG(auto_globals), 8, NULL, NULL, h->persistent, h->bApplyProtection);821 {822 zend_auto_global tmp_autoglobal;823 824 zend_hash_copy(&TG(auto_globals), OG(auto_globals), NULL, (void *) &tmp_autoglobal, sizeof(tmp_autoglobal));825 zend_hash_apply(&TG(auto_globals), (apply_func_t) xc_auto_global_arm TSRMLS_CC);826 }827 #endif828 829 sandbox->filename = filename;830 831 #ifdef XCACHE_ERROR_CACHING832 sandbox->orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting);833 EG(user_error_handler_error_reporting) = 0;834 835 sandbox->compilererror_cnt = 0;836 sandbox->compilererror_size = 0;837 #endif838 839 #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES840 sandbox->orig_compiler_options = CG(compiler_options);841 /* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK842 */843 CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING;844 #endif845 846 XG(sandbox) = (void *) sandbox;847 return sandbox;848 }849 /* }}} */850 #ifndef ZEND_COMPILE_DELAYED_BINDING851 static void xc_early_binding_cb(zend_op *opline, int oplineno, void *data TSRMLS_DC) /* {{{ */852 {853 xc_sandbox_t *sandbox = (xc_sandbox_t *) data;854 xc_do_early_binding(CG(active_op_array), OG(class_table), oplineno TSRMLS_CC);855 }856 /* }}} */857 #endif858 static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */859 {860 zend_uint i;861 Bucket *b;862 863 #ifdef HAVE_XCACHE_CONSTANT864 for (b = TG(zend_constants).pListHead; b != NULL && b != TG(internal_constant_tail); b = b->pListNext) {865 zend_constant *c = (zend_constant*) b->pData;866 xc_free_zend_constant(c);867 }868 869 b = TG(internal_constant_tail) ? TG(internal_constant_tail)->pListNext : TG(zend_constants).pListHead;870 /* install constants */871 while (b != NULL) {872 zend_constant *c = (zend_constant*) b->pData;873 xc_install_constant(sandbox->filename, c,874 BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);875 b = b->pListNext;876 }877 #endif878 879 b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;880 /* install function */881 while (b != NULL) {882 zend_function *func = (zend_function*) b->pData;883 xc_install_function(sandbox->filename, func,884 BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);885 b = b->pListNext;886 }887 888 b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;889 /* install class */890 while (b != NULL) {891 xc_install_class(sandbox->filename, (xc_cest_t*) b->pData, -1,892 BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h TSRMLS_CC);893 b = b->pListNext;894 }895 896 #ifdef ZEND_ENGINE_2_1897 /* trigger auto_globals jit */898 for (b = TG(auto_globals).pListHead; b != NULL; b = b->pListNext) {899 zend_auto_global *auto_global = (zend_auto_global *) b->pData;900 /* check if actived */901 if (auto_global->auto_global_callback && !auto_global->armed) {902 zend_u_is_auto_global(BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), auto_global->name_len TSRMLS_CC);903 }904 }905 #endif906 907 #ifdef ZEND_COMPILE_DELAYED_BINDING908 zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC);909 #else910 xc_undo_pass_two(CG(active_op_array) TSRMLS_CC);911 xc_foreach_early_binding_class(CG(active_op_array), xc_early_binding_cb, (void *) sandbox TSRMLS_CC);912 xc_redo_pass_two(CG(active_op_array) TSRMLS_CC);913 #endif914 915 #ifdef XCACHE_ERROR_CACHING916 /* restore trigger errors */917 for (i = 0; i < sandbox->compilererror_cnt; i ++) {918 xc_compilererror_t *error = &sandbox->compilererrors[i];919 CG(zend_lineno) = error->lineno;920 zend_error(error->type, "%s", error->error);921 }922 CG(zend_lineno) = 0;923 #endif924 925 i = 1;926 /* still needed because in zend_language_scanner.l, require()/include() check file_handle.handle.stream.handle */927 zend_hash_add(&OG(included_files), sandbox->filename, strlen(sandbox->filename) + 1, (void *)&i, sizeof(int), NULL);928 }929 /* }}} */930 static void xc_sandbox_free(xc_sandbox_t *sandbox, zend_op_array *op_array TSRMLS_DC) /* {{{ */931 {932 XG(sandbox) = NULL;933 #ifdef XCACHE_ERROR_CACHING934 EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting;935 #endif936 937 /* restore first first install function/class */938 #ifdef HAVE_XCACHE_CONSTANT939 EG(zend_constants) = OG(zend_constants);940 #endif941 CG(function_table) = OG(function_table);942 CG(class_table) = OG(class_table);943 EG(class_table) = CG(class_table);944 #ifdef ZEND_ENGINE_2_1945 CG(auto_globals) = OG(auto_globals);946 #endif947 948 if (op_array) {949 zend_op_array *old_active_op_array = CG(active_op_array);950 CG(in_compilation) = 1;951 CG(compiled_filename) = ZEND_24(NOTHING, (char *)) sandbox->filename;952 CG(zend_lineno) = 0;953 954 CG(active_op_array) = op_array;955 xc_sandbox_install(sandbox TSRMLS_CC);956 CG(active_op_array) = old_active_op_array;957 958 CG(in_compilation) = 0;959 CG(compiled_filename) = NULL;960 961 /* no free as it's installed */962 #ifdef HAVE_XCACHE_CONSTANT963 TG(zend_constants).pDestructor = NULL;964 #endif965 TG(function_table).pDestructor = NULL;966 TG(class_table).pDestructor = NULL;967 }968 969 /* destroy all the tmp */970 #ifdef HAVE_XCACHE_CONSTANT971 zend_hash_destroy(&TG(zend_constants));972 #endif973 zend_hash_destroy(&TG(function_table));974 zend_hash_destroy(&TG(class_table));975 #ifdef ZEND_ENGINE_2_1976 zend_hash_destroy(&TG(auto_globals));977 #endif978 zend_hash_destroy(TG(included_files));979 980 /* restore orig here, as EG/CG holded tmp before */981 memcpy(&EG(included_files), &OG(included_files), sizeof(EG(included_files)));982 983 #ifdef XCACHE_ERROR_CACHING984 if (sandbox->compilererrors) {985 zend_uint i;986 for (i = 0; i < sandbox->compilererror_cnt; i ++) {987 efree(sandbox->compilererrors[i].error);988 }989 efree(sandbox->compilererrors);990 }991 #endif992 993 #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES994 CG(compiler_options) = sandbox->orig_compiler_options;995 #endif996 }997 /* }}} */998 zend_op_array *xc_sandbox(xc_sandboxed_func_t sandboxed_func, void *data, ZEND_24(NOTHING, const) char *filename TSRMLS_DC) /* {{{ */999 {1000 xc_sandbox_t sandbox;1001 zend_op_array *op_array = NULL;1002 zend_bool catched = 0;1003 1004 memset(&sandbox, 0, sizeof(sandbox));1005 zend_try {1006 xc_sandbox_init(&sandbox, filename TSRMLS_CC);1007 op_array = sandboxed_func(data TSRMLS_CC);1008 } zend_catch {1009 catched = 1;1010 } zend_end_try();1011 1012 xc_sandbox_free(&sandbox, op_array TSRMLS_CC);1013 if (catched) {1014 zend_bailout();1015 }1016 return op_array;1017 }1018 /* {{{ */1019 const Bucket *xc_sandbox_user_function_begin(TSRMLS_D) /* {{{ */1020 {1021 xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);1022 assert(sandbox);1023 return TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;1024 }1025 /* {{{ */1026 const Bucket *xc_sandbox_user_class_begin(TSRMLS_D) /* {{{ */1027 {1028 xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);1029 assert(sandbox);1030 return TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;1031 }1032 /* {{{ */1033 #ifdef XCACHE_ERROR_CACHING1034 xc_compilererror_t *xc_sandbox_compilererrors(TSRMLS_D) /* {{{ */1035 {1036 xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);1037 assert(sandbox);1038 return sandbox->compilererrors;1039 }1040 /* }}} */1041 zend_uint xc_sandbox_compilererror_cnt(TSRMLS_D) /* {{{ */1042 {1043 xc_sandbox_t *sandbox = (xc_sandbox_t *) XG(sandbox);1044 assert(sandbox);1045 return sandbox->compilererror_cnt;1046 }1047 /* }}} */1048 #endif1049 1050 int xc_vtrace(const char *fmt, va_list args) /* {{{ */1051 {1052 return vfprintf(stderr, fmt, args);1053 }1054 /* }}} */1055 int xc_trace(const char *fmt, ...) /* {{{ */1056 {1057 va_list args;1058 int ret;1059 1060 va_start(args, fmt);1061 ret = xc_vtrace(fmt, args);1062 va_end(args);1063 return ret;1064 }1065 /* }}} */1066 1067 #ifndef ZEND_ENGINE_2_31068 #include "ext/standard/php_string.h"1069 size_t xc_dirname(char *path, size_t len) /* {{{ */1070 {1071 #ifdef ZEND_ENGINE_21072 return php_dirname(path, len);1073 #else1074 php_dirname(path, len);1075 return strlen(path);1076 #endif1077 }1078 /* }}} */1079 1080 long xc_atol(const char *str, int str_len) /* {{{ */1081 {1082 long retval;1083 1084 if (!str_len) {1085 str_len = strlen(str);1086 }1087 1088 retval = strtol(str, NULL, 0);1089 if (str_len > 0) {1090 switch (str[str_len - 1]) {1091 case 'g':1092 case 'G':1093 retval *= 1024;1094 /* break intentionally missing */1095 case 'm':1096 case 'M':1097 retval *= 1024;1098 /* break intentionally missing */1099 case 'k':1100 case 'K':1101 retval *= 1024;1102 break;1103 }1104 }1105 1106 return retval;1107 }1108 /* }}} */1109 1110 #endif1111 1112 /* init/destroy */1113 int xc_util_init(int module_number TSRMLS_DC) /* {{{ */1114 {1115 #ifdef XCACHE_ERROR_CACHING1116 old_zend_error_cb = zend_error_cb;1117 zend_error_cb = xc_sandbox_error_cb;1118 #endif1119 1120 return SUCCESS;1121 }1122 /* }}} */1123 void xc_util_destroy() /* {{{ */1124 {1125 #ifdef XCACHE_ERROR_CACHING1126 if (zend_error_cb == xc_sandbox_error_cb) {1127 zend_error_cb = old_zend_error_cb;1128 }1129 #endif1130 }1131 /* }}} */1132
Note: See TracChangeset
for help on using the changeset viewer.

