| 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_CONSTANT |
| 588 | | HashTable *orig_zend_constants; |
| 589 | | HashTable tmp_zend_constants; |
| 590 | | #endif |
| 591 | | 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_CONSTANT |
| 598 | | Bucket *tmp_internal_constant_tail; |
| 599 | | #endif |
| 600 | | Bucket *tmp_internal_function_tail; |
| 601 | | Bucket *tmp_internal_class_tail; |
| 602 | | |
| 603 | | #ifdef XCACHE_ERROR_CACHING |
| 604 | | int orig_user_error_handler_error_reporting; |
| 605 | | zend_uint compilererror_cnt; |
| 606 | | zend_uint compilererror_size; |
| 607 | | xc_compilererror_t *compilererrors; |
| 608 | | #endif |
| 609 | | |
| 610 | | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
| 611 | | zend_uint orig_compiler_options; |
| 612 | | #endif |
| 613 | | } xc_sandbox_t; |
| 614 | | |
| 615 | | #undef TG |
| 616 | | #undef OG |
| 617 | | #define TG(x) (sandbox->tmp_##x) |
| 618 | | #define OG(x) (sandbox->orig_##x) |
| 619 | | /* }}} */ |
| 620 | | #ifdef XCACHE_ERROR_CACHING |
| 621 | | 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_STRICT |
| 635 | | case E_STRICT: |
| 636 | | #endif |
| 637 | | #ifdef E_DEPRECATED |
| 638 | | case E_DEPRECATED: |
| 639 | | #endif |
| 640 | | 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 | | #endif |
| 682 | | #ifdef ZEND_ENGINE_2_1 |
| 683 | | 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 | | #endif |
| 701 | | |
| 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_CONSTANT |
| 774 | | OG(zend_constants) = EG(zend_constants); |
| 775 | | EG(zend_constants) = &TG(zend_constants); |
| 776 | | #endif |
| 777 | | |
| 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_1 |
| 786 | | OG(auto_globals) = CG(auto_globals); |
| 787 | | CG(auto_globals) = &TG(auto_globals); |
| 788 | | #endif |
| 789 | | |
| 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_CONSTANT |
| 794 | | 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 | | #endif |
| 799 | | 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 && TODO |
| 810 | | { |
| 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 | | #endif |
| 815 | | TG(internal_class_tail) = TG(class_table).pListTail; |
| 816 | | |
| 817 | | #ifdef ZEND_ENGINE_2_1 |
| 818 | | /* 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 | | #endif |
| 828 | | |
| 829 | | sandbox->filename = filename; |
| 830 | | |
| 831 | | #ifdef XCACHE_ERROR_CACHING |
| 832 | | 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 | | #endif |
| 838 | | |
| 839 | | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
| 840 | | sandbox->orig_compiler_options = CG(compiler_options); |
| 841 | | /* Using ZEND_COMPILE_IGNORE_INTERNAL_CLASSES for ZEND_FETCH_CLASS_RT_NS_CHECK |
| 842 | | */ |
| 843 | | CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES | ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_DELAYED_BINDING; |
| 844 | | #endif |
| 845 | | |
| 846 | | XG(sandbox) = (void *) sandbox; |
| 847 | | return sandbox; |
| 848 | | } |
| 849 | | /* }}} */ |
| 850 | | #ifndef ZEND_COMPILE_DELAYED_BINDING |
| 851 | | 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 | | #endif |
| 858 | | static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */ |
| 859 | | { |
| 860 | | zend_uint i; |
| 861 | | Bucket *b; |
| 862 | | |
| 863 | | #ifdef HAVE_XCACHE_CONSTANT |
| 864 | | 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 | | #endif |
| 878 | | |
| 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_1 |
| 897 | | /* 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 | | #endif |
| 906 | | |
| 907 | | #ifdef ZEND_COMPILE_DELAYED_BINDING |
| 908 | | zend_do_delayed_early_binding(CG(active_op_array) TSRMLS_CC); |
| 909 | | #else |
| 910 | | 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 | | #endif |
| 914 | | |
| 915 | | #ifdef XCACHE_ERROR_CACHING |
| 916 | | /* 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 | | #endif |
| 924 | | |
| 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_CACHING |
| 934 | | EG(user_error_handler_error_reporting) = sandbox->orig_user_error_handler_error_reporting; |
| 935 | | #endif |
| 936 | | |
| 937 | | /* restore first first install function/class */ |
| 938 | | #ifdef HAVE_XCACHE_CONSTANT |
| 939 | | EG(zend_constants) = OG(zend_constants); |
| 940 | | #endif |
| 941 | | 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_1 |
| 945 | | CG(auto_globals) = OG(auto_globals); |
| 946 | | #endif |
| 947 | | |
| 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_CONSTANT |
| 963 | | TG(zend_constants).pDestructor = NULL; |
| 964 | | #endif |
| 965 | | TG(function_table).pDestructor = NULL; |
| 966 | | TG(class_table).pDestructor = NULL; |
| 967 | | } |
| 968 | | |
| 969 | | /* destroy all the tmp */ |
| 970 | | #ifdef HAVE_XCACHE_CONSTANT |
| 971 | | zend_hash_destroy(&TG(zend_constants)); |
| 972 | | #endif |
| 973 | | zend_hash_destroy(&TG(function_table)); |
| 974 | | zend_hash_destroy(&TG(class_table)); |
| 975 | | #ifdef ZEND_ENGINE_2_1 |
| 976 | | zend_hash_destroy(&TG(auto_globals)); |
| 977 | | #endif |
| 978 | | 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_CACHING |
| 984 | | 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 | | #endif |
| 992 | | |
| 993 | | #ifdef ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
| 994 | | CG(compiler_options) = sandbox->orig_compiler_options; |
| 995 | | #endif |
| 996 | | } |
| 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_CACHING |
| 1034 | | 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 | | #endif |
| 1049 | | |
| 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_3 |
| 1068 | | #include "ext/standard/php_string.h" |
| 1069 | | size_t xc_dirname(char *path, size_t len) /* {{{ */ |
| 1070 | | { |
| 1071 | | #ifdef ZEND_ENGINE_2 |
| 1072 | | return php_dirname(path, len); |
| 1073 | | #else |
| 1074 | | php_dirname(path, len); |
| 1075 | | return strlen(path); |
| 1076 | | #endif |
| 1077 | | } |
| 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 | | #endif |
| 1111 | | |
| 1112 | | /* init/destroy */ |
| 1113 | | int xc_util_init(int module_number TSRMLS_DC) /* {{{ */ |
| 1114 | | { |
| 1115 | | #ifdef XCACHE_ERROR_CACHING |
| 1116 | | old_zend_error_cb = zend_error_cb; |
| 1117 | | zend_error_cb = xc_sandbox_error_cb; |
| 1118 | | #endif |
| 1119 | | |
| 1120 | | return SUCCESS; |
| 1121 | | } |
| 1122 | | /* }}} */ |
| 1123 | | void xc_util_destroy() /* {{{ */ |
| 1124 | | { |
| 1125 | | #ifdef XCACHE_ERROR_CACHING |
| 1126 | | if (zend_error_cb == xc_sandbox_error_cb) { |
| 1127 | | zend_error_cb = old_zend_error_cb; |
| 1128 | | } |
| 1129 | | #endif |
| 1130 | | } |
| 1131 | | /* }}} */ |
| 1132 | | |