/** * Copies of internal methods from Zend/zend_execute_API.c * These are used to call internal methods (not in the function table) from the external method. * TODO: See if xdebug works */ int runkit_forward_call_user_function(zend_function *fbc, zend_function *fbc_inner, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { uint32_t i; zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local = {0}; zend_function *func; /* {{{ patch for runkit */ zend_fcall_info fci = {0}; zend_fcall_info_cache *fci_cache = NULL; fci.size = sizeof(fci); fci.object = NULL; // FIXME for methods? // object ? Z_OBJ_P(object) : NULL; ZVAL_STR(&fci.function_name, fbc_inner->common.function_name); zend_string_addref(fbc_inner->common.function_name); fci.retval = return_value; fci.param_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); fci.params = ZEND_CALL_ARG(EG(current_execute_data), 1); // params and param_count From zend_API.c fci.no_separation = (zend_bool)1; // ??? /* end patch for runkit }}} */ ZVAL_UNDEF(fci.retval); if (!EG(active)) { return FAILURE; /* executor is already inactive */ } if (EG(exception)) { return FAILURE; /* we would result in an unstable executor otherwise */ } /* Initialize execute_data */ if (!EG(current_execute_data)) { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, * but it may make bugs easier to spot */ memset(&dummy_execute_data, 0, sizeof(zend_execute_data)); EG(current_execute_data) = &dummy_execute_data; } else if (EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type) && EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL && EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL && EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL && EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) { /* Insert fake frame in case of include or magic calls */ dummy_execute_data = *EG(current_execute_data); dummy_execute_data.prev_execute_data = EG(current_execute_data); dummy_execute_data.call = NULL; dummy_execute_data.opline = NULL; dummy_execute_data.func = NULL; EG(current_execute_data) = &dummy_execute_data; } if (!fci_cache || !RUNKIT_IS_FCI_CACHE_INITIALIZED(fci_cache)) { zend_string *callable_name; char *error = NULL; if (!fci_cache) { fci_cache = &fci_cache_local; } if (!zend_is_callable_ex(&fci.function_name, fci.object, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error)) { if (error) { zend_error(E_WARNING, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error); efree(error); } if (callable_name) { zend_string_release(callable_name); } if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } return FAILURE; } else if (error) { /* Capitalize the first latter of the error message */ if (error[0] >= 'a' && error[0] <= 'z') { error[0] += ('A' - 'a'); } zend_error(E_DEPRECATED, "%s", error); efree(error); } zend_string_release(callable_name); } func = fbc_inner; fci.object = (func->common.fn_flags & ZEND_ACC_STATIC) ? NULL : fci_cache->object; call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC, func, fci.param_count, fci_cache->called_scope, fci.object); if (fci.object && (!EG(objects_store).object_buckets || !IS_OBJ_VALID(EG(objects_store).object_buckets[fci.object->handle]))) { if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } return FAILURE; } if (func->common.fn_flags & (ZEND_ACC_ABSTRACT | ZEND_ACC_DEPRECATED)) { if (func->common.fn_flags & ZEND_ACC_ABSTRACT) { zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } return FAILURE; } if (func->common.fn_flags & ZEND_ACC_DEPRECATED) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", func->common.scope ? ZSTR_VAL(func->common.scope->name) : "", func->common.scope ? "::" : "", ZSTR_VAL(func->common.function_name)); } } for (i = 0; i < fci.param_count; i++) { zval *param; zval *arg = &fci.params[i]; if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) { if (UNEXPECTED(!Z_ISREF_P(arg))) { if (!fci.no_separation) { /* Separation is enabled -- create a ref */ ZVAL_NEW_REF(arg, arg); } else if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) { /* By-value send is not allowed -- emit a warning, * but still perform the call with a by-value send. */ zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", i + 1, func->common.scope ? ZSTR_VAL(func->common.scope->name) : "", func->common.scope ? "::" : "", ZSTR_VAL(func->common.function_name)); } } } else { if (Z_ISREF_P(arg) && !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { /* don't separate references for __call */ arg = Z_REFVAL_P(arg); } } param = ZEND_CALL_ARG(call, i + 1); ZVAL_COPY(param, arg); } if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { ZEND_ASSERT(GC_TYPE((zend_object *)func->op_array.prototype) == IS_OBJECT); GC_ADDREF((zend_object *)func->op_array.prototype); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE); } if (func->type == ZEND_USER_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; zend_init_execute_data(call, &func->op_array, fci.retval); zend_execute_ex(call); if (call_via_handler) { /* We must re-initialize function again */ RUNKIT_CLEAR_FCI_CACHE(fci_cache); } } else if (func->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; ZVAL_NULL(fci.retval); call->prev_execute_data = EG(current_execute_data); call->return_value = NULL; /* this is not a constructor call */ EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ func->internal_function.handler(call, fci.retval); } else { zend_execute_internal(call, fci.retval); } EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) { INIT_PZVAL(f->retval); }*/ if (EG(exception)) { zval_ptr_dtor(fci.retval); ZVAL_UNDEF(fci.retval); } if (call_via_handler) { /* We must re-initialize function again */ RUNKIT_CLEAR_FCI_CACHE(fci_cache); } } else { /* ZEND_OVERLOADED_FUNCTION */ ZVAL_NULL(fci.retval); /* Not sure what should be done here if it's a static method */ if (fci.object) { call->prev_execute_data = EG(current_execute_data); EG(current_execute_data) = call; fci.object->handlers->call_method(func->common.function_name, fci.object, call, fci.retval); EG(current_execute_data) = call->prev_execute_data; } else { zend_throw_error(NULL, "Cannot call overloaded function for non-object"); } zend_vm_stack_free_args(call); if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { zend_string_release(func->common.function_name); } efree(func); if (EG(exception)) { zval_ptr_dtor(fci.retval); ZVAL_UNDEF(fci.retval); } } zend_vm_stack_free_call_frame(call); if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } if (EG(exception)) { zend_throw_exception_internal(NULL); } return SUCCESS; }
static zend_function *zend_closure_get_constructor(zend_object *object) /* {{{ */ { zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not allowed"); return NULL; }
ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zval *this_ptr) /* {{{ */ { zend_closure *closure; object_init_ex(res, zend_ce_closure); closure = (zend_closure *)Z_OBJ_P(res); closure->func = *func; closure->func.common.prototype = NULL; closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; if ((scope == NULL) && this_ptr && (Z_TYPE_P(this_ptr) != IS_UNDEF)) { /* use dummy scope if we're binding an object without specifying a scope */ /* maybe it would be better to create one for this purpose */ scope = zend_ce_closure; } if (closure->func.type == ZEND_USER_FUNCTION) { if (closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; ALLOC_HASHTABLE(closure->func.op_array.static_variables); zend_hash_init(closure->func.op_array.static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0); zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables); } closure->func.op_array.run_time_cache = NULL; if (closure->func.op_array.refcount) { (*closure->func.op_array.refcount)++; } } else { /* verify that we aren't binding internal function to a wrong scope */ if(func->common.scope != NULL) { if(scope && !instanceof_function(scope, func->common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name->val, func->common.function_name->val, scope->name->val); scope = NULL; } if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 && !instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name->val, func->common.function_name->val, Z_OBJCE_P(this_ptr)->name->val); scope = NULL; this_ptr = NULL; } } else { /* if it's a free function, we won't set scope & this since they're meaningless */ this_ptr = NULL; scope = NULL; } } ZVAL_UNDEF(&closure->this_ptr); /* Invariants: * If the closure is unscoped, it has no bound object. * The the closure is scoped, it's either static or it's bound */ closure->func.common.scope = scope; if (scope) { closure->func.common.fn_flags |= ZEND_ACC_PUBLIC; if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { ZVAL_COPY(&closure->this_ptr, this_ptr); } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; } } }
/* {{{ pthreads_call_method */ int pthreads_call_method(PTHREADS_CALL_METHOD_PASSTHRU_D) { zval ***argv = NULL, zmethod, *zresult; zend_function *call = NULL; zend_fcall_info info; zend_fcall_info_cache cache; zend_class_entry *scope; int called = -1, argc = ZEND_NUM_ARGS(), access = ZEND_ACC_PUBLIC, mlength = 0; char *lcname; zend_bool unprotect; if (getThis()) { PTHREAD thread = PTHREADS_FETCH; if (thread) { switch((access=pthreads_modifiers_get(thread->modifiers, method TSRMLS_CC))){ case ZEND_ACC_PRIVATE: case ZEND_ACC_PROTECTED: { scope = Z_OBJCE_P(getThis()); /* * Stop invalid private method calls */ if (access == ZEND_ACC_PRIVATE && !PTHREADS_IN_THREAD(thread)) { zend_error( E_ERROR, "pthreads detected an attempt to call private method %s::%s from outside the threading context", scope->name, method ); return FAILURE; } /* * Get arguments from stack */ if (ZEND_NUM_ARGS()) { argv = safe_emalloc(sizeof(zval **), argc, 0); if (argv) { zend_get_parameters_array_ex(argc, argv); } } mlength = strlen(method); lcname = calloc(1, mlength+1); zend_str_tolower_copy(lcname, method, mlength); if (zend_hash_find(&scope->function_table, lcname, mlength+1, (void**)&call)==SUCCESS) { if (call) { /* * Make protected method call */ { if (access != ZEND_ACC_PROTECTED || pthreads_modifiers_protect(thread->modifiers, method, &unprotect TSRMLS_CC)) { ZVAL_STRINGL(&zmethod, method, strlen(method), 0); info.size = sizeof(info); info.object_ptr = getThis(); info.function_name = &zmethod; info.retval_ptr_ptr = &zresult; info.no_separation = 1; info.symbol_table = NULL; info.param_count = argc; info.params = argv; cache.initialized = 1; cache.function_handler = call; cache.calling_scope = EG(scope); cache.called_scope = scope; cache.object_ptr = getThis(); if ((called=zend_call_function(&info, &cache TSRMLS_CC))!=SUCCESS) { zend_error( E_ERROR, "pthreads has experienced an internal error while calling %s method %s::%s and cannot continue", (access == ZEND_ACC_PROTECTED) ? "protected" : "private", scope->name, method ); called = FAILURE; } else { #if PHP_VERSION_ID > 50399 { zend_op_array *ops = (zend_op_array*) call; if (ops) { if (ops->run_time_cache) { efree(ops->run_time_cache); ops->run_time_cache = NULL; } } } #endif if (zresult) { if (!return_value_used) { zval_ptr_dtor(&zresult); } else { ZVAL_ZVAL(return_value, zresult, 1, 1); } } } if (access == ZEND_ACC_PROTECTED) { pthreads_modifiers_unprotect(thread->modifiers, method, unprotect TSRMLS_CC); } } else { zend_error( E_ERROR, "pthreads has experienced an internal error while calling %s method %s::%s and cannot continue", (access == ZEND_ACC_PROTECTED) ? "protected" : "private", scope->name, method ); called = FAILURE; } } } else { zend_error( E_ERROR, "pthreads has experienced an internal error while finding %s method %s::%s and cannot continue", (access == ZEND_ACC_PROTECTED) ? "protected" : "private", scope->name, method ); called = FAILURE; } } /* * Free unstacked arguments */ if (argc) { efree(argv); } free(lcname); return called; } break; } } } switch (called) { case -1: return zend_handlers->call_method(PTHREADS_CALL_METHOD_PASSTHRU_C); default: return called; } } /* }}} */
/* {{{ proto XmlIndexLookup::XmlIndexLookup() Create a new index specification object */ PHP_DBXML_METHOD_BEGIN(XmlIndexLookup, XmlIndexLookup) { zend_error(E_ERROR, "XmlIndexLookup can not be instantiated from PHP"); } PHP_DBXML_METHOD_END()
/* }}} */ static void xc_fcntl_unlock(xc_fcntl_mutex_t *fcntl_mutex) /* {{{ */ { if (dolock(fcntl_mutex, LCK_UN) < 0) { zend_error(E_ERROR, "xc_fcntl_unlock failed errno:%d", errno); } }
PHP_METHOD(MongoDB, command) { zval limit, *temp, *cmd, *cursor, *ns, *options = 0; mongo_db *db; mongo_link *link; char *cmd_ns; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &cmd, &options) == FAILURE) { return; } if (IS_SCALAR_P(cmd)) { zend_error(E_WARNING, "MongoDB::command() expects parameter 1 to be an array or object"); return; } PHP_MONGO_GET_DB(getThis()); // create db.$cmd MAKE_STD_ZVAL(ns); cmd_ns = get_cmd_ns(Z_STRVAL_P(db->name), Z_STRLEN_P(db->name)); ZVAL_STRING(ns, cmd_ns, 0); // create cursor MAKE_STD_ZVAL(cursor); object_init_ex(cursor, mongo_ce_Cursor); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD3(MongoCursor, __construct, temp, cursor, db->link, ns, cmd); zval_ptr_dtor(&ns); zval_ptr_dtor(&temp); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); // limit Z_TYPE(limit) = IS_LONG; Z_LVAL(limit) = -1; MONGO_METHOD1(MongoCursor, limit, temp, cursor, &limit); zval_ptr_dtor(&temp); if (options) { zval **timeout; if (zend_hash_find(HASH_P(options), "timeout", strlen("timeout")+1, (void**)&timeout) == SUCCESS) { MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD1(MongoCursor, timeout, temp, cursor, *timeout); zval_ptr_dtor(&temp); } } // make sure commands aren't be sent to slaves PHP_MONGO_GET_LINK(db->link); if (link->rs) { zval slave_okay; Z_TYPE(slave_okay) = IS_BOOL; Z_LVAL(slave_okay) = 0; MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD1(MongoCursor, slaveOkay, temp, cursor, &slave_okay); zval_ptr_dtor(&temp); } // query MONGO_METHOD(MongoCursor, getNext, return_value, cursor); clear_exception(return_value TSRMLS_CC); zend_objects_store_del_ref(cursor TSRMLS_CC); zval_ptr_dtor(&cursor); }
/* {{{ install_class */ static int install_class(apc_class_t cl, apc_context_t* ctxt, int lazy TSRMLS_DC) { zend_class_entry* class_entry = cl.class_entry; zend_class_entry* parent = NULL; int status; /* Special case for mangled names. Mangled names are unique to a file. * There is no way two classes with the same mangled name will occur, * unless a file is included twice. And if in case, a file is included * twice, all mangled name conflicts can be ignored and the class redeclaration * error may be deferred till runtime of the corresponding DECLARE_CLASS * calls. */ if(cl.name_len != 0 && cl.name[0] == '\0') { if(zend_hash_exists(CG(class_table), cl.name, cl.name_len+1)) { return SUCCESS; } } if(lazy && cl.name_len != 0 && cl.name[0] != '\0') { status = zend_hash_add(APCG(lazy_class_table), cl.name, cl.name_len+1, &cl, sizeof(apc_class_t), NULL); if(status == FAILURE) { zend_error(E_ERROR, "Cannot redeclare class %s", cl.name); } return status; } class_entry = apc_copy_class_entry_for_execution(cl.class_entry, ctxt TSRMLS_CC); if (class_entry == NULL) return FAILURE; /* restore parent class pointer for compile-time inheritance */ if (cl.parent_name != NULL) { zend_class_entry** parent_ptr = NULL; /* * __autoload brings in the old issues with mixed inheritance. * When a statically inherited class triggers autoload, it runs * afoul of a potential require_once "parent.php" in the previous * line, which when executed provides the parent class, but right * now goes and hits __autoload which could fail. * * missing parent == re-compile. * * whether __autoload is enabled or not, because __autoload errors * cause php to die. * * Aside: Do NOT pass *strlen(cl.parent_name)+1* because * zend_lookup_class_ex does it internally anyway! */ status = zend_lookup_class_ex(cl.parent_name, strlen(cl.parent_name), #ifdef ZEND_ENGINE_2_4 NULL, #endif 0, &parent_ptr TSRMLS_CC); if (status == FAILURE) { if(APCG(report_autofilter)) { apc_warning("Dynamic inheritance detected for class %s" TSRMLS_CC, cl.name); } class_entry->parent = NULL; return status; } else { parent = *parent_ptr; class_entry->parent = parent; zend_do_inheritance(class_entry, parent TSRMLS_CC); } } status = zend_hash_add(EG(class_table), cl.name, cl.name_len+1, &class_entry, sizeof(zend_class_entry*), NULL); if (status == FAILURE) { apc_error("Cannot redeclare class %s" TSRMLS_CC, cl.name); } return status; }
void orbit_class_function_call( zend_class_entry * pClass, int dataType, zend_property_reference *pPropertyReference, Class_Constructor pConstructor, Class_CallFunction pCallFunction, INTERNAL_FUNCTION_PARAMETERS) { /* get object */ zval * object = pPropertyReference->object; /* get function name */ zend_overloaded_element * function_name = (zend_overloaded_element *)pPropertyReference->elements_list->tail->data; /* handle parameters */ zval ** arguments = orbit_new_n(zval *, ZEND_NUM_ARGS()); /*(zval **)emalloc(sizeof(zval *) * ZEND_NUM_ARGS());*/ if (getParametersArray(ht, ZEND_NUM_ARGS(), arguments) == FAILURE) { /* TODO: handle error */ } /* constructor or normal function? */ if (zend_llist_count(pPropertyReference->elements_list) == 1 && !strcasecmp(function_name->element.value.str.val, pClass->name)) { /* constructor */ if (pConstructor) { void * p_data = NULL; zend_bool success = (*pConstructor)(&p_data, ZEND_NUM_ARGS(), arguments); if (success) orbit_save_data(object, dataType, p_data); } else { zend_error(E_WARNING, "(Satellite) This class has no constructor"); \ } } else { /* normal function */ if (pCallFunction) { void * p_data = orbit_retrieve_data(object, dataType); if (p_data == NULL) { /* * this means that the constructor has failed earlier! * -- or should NULL be allowed here? */ php_error(E_WARNING, "(Satellite) Class has no data!"); RETVAL_NULL(); goto orbit_class_function_call_exit; } /* pval * return_value is a part of INTERNAL_FUNCTION_PARAMETERS */ (*pCallFunction)(p_data, function_name->element.value.str.val, ZEND_NUM_ARGS(), arguments, return_value); } else { zend_error(E_WARNING, "(Satellite) Can't call functions in this class"); \ } } orbit_class_function_call_exit: satellite_delete(arguments); /* seems to be required! */ zval_dtor(&function_name->element); }
ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */ { zend_closure *closure; object_init_ex(res, zend_ce_closure); closure = (zend_closure *)Z_OBJ_P(res); if ((scope == NULL) && this_ptr && (Z_TYPE_P(this_ptr) != IS_UNDEF)) { /* use dummy scope if we're binding an object without specifying a scope */ /* maybe it would be better to create one for this purpose */ scope = zend_ce_closure; } if (func->type == ZEND_USER_FUNCTION) { memcpy(&closure->func, func, sizeof(zend_op_array)); closure->func.common.prototype = (zend_function*)closure; closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; if (closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; ALLOC_HASHTABLE(closure->func.op_array.static_variables); zend_hash_init(closure->func.op_array.static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0); zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables); } if (UNEXPECTED(!closure->func.op_array.run_time_cache)) { closure->func.op_array.run_time_cache = func->op_array.run_time_cache = zend_arena_alloc(&CG(arena), func->op_array.cache_size); memset(func->op_array.run_time_cache, 0, func->op_array.cache_size); } if (closure->func.op_array.refcount) { (*closure->func.op_array.refcount)++; } } else { memcpy(&closure->func, func, sizeof(zend_internal_function)); closure->func.common.prototype = (zend_function*)closure; closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; /* wrap internal function handler to avoid memory leak */ if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) { /* avoid infinity recursion, by taking handler from nested closure */ zend_closure *nested = (zend_closure*)((char*)func - XtOffsetOf(zend_closure, func)); ZEND_ASSERT(nested->std.ce == zend_ce_closure); closure->orig_internal_handler = nested->orig_internal_handler; } else { closure->orig_internal_handler = closure->func.internal_function.handler; } closure->func.internal_function.handler = zend_closure_internal_handler; /* verify that we aren't binding internal function to a wrong scope */ if(func->common.scope != NULL) { if(scope && !instanceof_function(scope, func->common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name), ZSTR_VAL(scope->name)); scope = NULL; } if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 && !instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name), ZSTR_VAL(Z_OBJCE_P(this_ptr)->name)); scope = NULL; this_ptr = NULL; } } else { /* if it's a free function, we won't set scope & this since they're meaningless */ this_ptr = NULL; scope = NULL; } } ZVAL_UNDEF(&closure->this_ptr); /* Invariant: * If the closure is unscoped or static, it has no bound object. */ closure->func.common.scope = scope; closure->called_scope = called_scope; if (scope) { closure->func.common.fn_flags |= ZEND_ACC_PUBLIC; if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { ZVAL_COPY(&closure->this_ptr, this_ptr); } } }
/* {{{ proto mixed Closure::call(object to [, mixed parameter] [, mixed ...] ) Call closure, binding to a given object with its class as the scope */ ZEND_METHOD(Closure, call) { zval *zclosure, *newthis, closure_result; zend_closure *closure; zend_fcall_info fci; zend_fcall_info_cache fci_cache; zval *my_params; int my_param_count = 0; zend_function my_function; zend_object *newobj; if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &my_params, &my_param_count) == FAILURE) { return; } zclosure = getThis(); closure = (zend_closure *) Z_OBJ_P(zclosure); if (closure->func.common.fn_flags & ZEND_ACC_STATIC) { zend_error(E_WARNING, "Cannot bind an instance to a static closure"); return; } if (closure->func.type == ZEND_INTERNAL_FUNCTION) { /* verify that we aren't binding internal function to a wrong object */ if ((closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0 && closure->func.common.scope && !instanceof_function(Z_OBJCE_P(newthis), closure->func.common.scope)) { zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", ZSTR_VAL(closure->func.common.scope->name), ZSTR_VAL(closure->func.common.function_name), ZSTR_VAL(Z_OBJCE_P(newthis)->name)); return; } } newobj = Z_OBJ_P(newthis); if (newobj->ce != closure->func.common.scope && newobj->ce->type == ZEND_INTERNAL_CLASS) { /* rebinding to internal class is not allowed */ zend_error(E_WARNING, "Cannot bind closure to object of internal class %s", ZSTR_VAL(newobj->ce->name)); return; } /* This should never happen as closures will always be callable */ if (zend_fcall_info_init(zclosure, 0, &fci, &fci_cache, NULL, NULL) != SUCCESS) { ZEND_ASSERT(0); } fci.retval = &closure_result; fci.params = my_params; fci.param_count = my_param_count; fci.object = fci_cache.object = newobj; fci_cache.initialized = 1; if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) { zval new_closure; zend_create_closure(&new_closure, fci_cache.function_handler, Z_OBJCE_P(newthis), closure->called_scope, newthis); closure = (zend_closure *) Z_OBJ(new_closure); fci_cache.function_handler = &closure->func; } else { memcpy(&my_function, fci_cache.function_handler, fci_cache.function_handler->type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function)); /* use scope of passed object */ my_function.common.scope = Z_OBJCE_P(newthis); fci_cache.function_handler = &my_function; /* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */ if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) { my_function.op_array.run_time_cache = emalloc(my_function.op_array.cache_size); memset(my_function.op_array.run_time_cache, 0, my_function.op_array.cache_size); } } if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) { ZVAL_COPY_VALUE(return_value, &closure_result); } if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) { /* copied upon generator creation */ --GC_REFCOUNT(&closure->std); } else if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) { efree(my_function.op_array.run_time_cache); } }
/* {{{ proto Closure Closure::bind(callable old, object to [, mixed scope]) Create a closure from another one and bind to another object and scope */ ZEND_METHOD(Closure, bind) { zval *newthis, *zclosure, *scope_arg = NULL; zend_closure *closure, *new_closure; zend_class_entry *ce, *called_scope; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oo!|z", &zclosure, zend_ce_closure, &newthis, &scope_arg) == FAILURE) { RETURN_NULL(); } closure = (zend_closure *)Z_OBJ_P(zclosure); if ((newthis != NULL) && (closure->func.common.fn_flags & ZEND_ACC_STATIC)) { zend_error(E_WARNING, "Cannot bind an instance to a static closure"); } if (newthis == NULL && !(closure->func.common.fn_flags & ZEND_ACC_STATIC) && closure->func.common.scope && closure->func.type == ZEND_INTERNAL_FUNCTION) { zend_error(E_WARNING, "Cannot unbind $this of internal method"); return; } if (scope_arg != NULL) { /* scope argument was given */ if (Z_TYPE_P(scope_arg) == IS_OBJECT) { ce = Z_OBJCE_P(scope_arg); } else if (Z_TYPE_P(scope_arg) == IS_NULL) { ce = NULL; } else { zend_string *class_name = zval_get_string(scope_arg); if (zend_string_equals_literal(class_name, "static")) { ce = closure->func.common.scope; } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) { zend_error(E_WARNING, "Class '%s' not found", ZSTR_VAL(class_name)); zend_string_release(class_name); RETURN_NULL(); } zend_string_release(class_name); } if(ce && ce != closure->func.common.scope && ce->type == ZEND_INTERNAL_CLASS) { /* rebinding to internal class is not allowed */ zend_error(E_WARNING, "Cannot bind closure to scope of internal class %s", ZSTR_VAL(ce->name)); return; } } else { /* scope argument not given; do not change the scope by default */ ce = closure->func.common.scope; } if (newthis) { called_scope = Z_OBJCE_P(newthis); } else { called_scope = ce; } zend_create_closure(return_value, &closure->func, ce, called_scope, newthis); new_closure = (zend_closure *) Z_OBJ_P(return_value); /* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */ if (ZEND_USER_CODE(closure->func.type) && (closure->func.common.scope != new_closure->func.common.scope || (closure->func.op_array.fn_flags & ZEND_ACC_NO_RT_ARENA))) { new_closure->func.op_array.run_time_cache = emalloc(new_closure->func.op_array.cache_size); memset(new_closure->func.op_array.run_time_cache, 0, new_closure->func.op_array.cache_size); new_closure->func.op_array.fn_flags |= ZEND_ACC_NO_RT_ARENA; } }
/* }}} */ static XC_SHM_INIT(xc_mmap_init) /* {{{ */ { #ifdef ZEND_WIN32 # define TMP_PATH "XCache" #else # define TMP_PATH "/tmp/XCache" int fd = -1; #endif xc_shm_t *shm = NULL; int ro_ok; volatile void *romem; char tmpname[sizeof(TMP_PATH) - 1 + 4 * 10 + 100] = { 0 }; const char *errstr = NULL; const char *path = (const char *) arg1; static int instanceId = 0; CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM"); shm->size = size; if (path == NULL || !path[0]) { snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d", TMP_PATH, (int) getuid(), (int) getpid(), ++instanceId); path = tmpname; } #ifdef ZEND_WIN32 else { snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d", path, (int) getuid(), (int) getpid(), ++instanceId); path = tmpname; } #endif shm->name = strdup(path); #ifndef ZEND_WIN32 # define XCACHE_MMAP_PERMISSION (S_IRUSR | S_IWUSR) fd = open(shm->name, O_RDWR, XCACHE_MMAP_PERMISSION); if (fd == -1) { /* do not create file in /dev */ if (strncmp(shm->name, "/dev", 4) == 0) { perror(shm->name); errstr = "Cannot open file set by xcache.mmap_path, check the xcache.size/var_size against system limitation"; goto err; } fd = open(shm->name, O_CREAT | O_RDWR, XCACHE_MMAP_PERMISSION); shm->newfile = 1; if (fd == -1) { perror(shm->name); errstr = "Cannot open or create file set by xcache.mmap_path, check the path permission or check xcache.size/var_size against system limitation"; goto err; } } if (ftruncate(fd, size) != 0 && errno != EINVAL) { perror(shm->name); errstr = "Failed to ftruncate the file"; goto err; } #endif #ifdef ZEND_WIN32 shm->hmap = XCacheCreateFileMapping(size, PAGE_READWRITE, shm->name); shm->ptr = (LPSTR) MapViewOfFile(shm->hmap, FILE_MAP_WRITE, 0, 0, 0); #else shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); #endif if (shm->ptr == XCACHE_MAP_FAILED) { perror(shm->name); errstr = "Failed creating file mapping"; shm->ptr = NULL; goto err; } /* {{{ readonly protection, mmap it readonly and check if ptr_ro works */ if (readonly_protection) { ro_ok = 0; #ifdef ZEND_WIN32 shm->hmap_ro = XCacheCreateFileMapping(size, PAGE_READONLY, shm->name); shm->ptr_ro = (LPSTR) MapViewOfFile(shm->hmap_ro, FILE_MAP_READ, 0, 0, 0); #else shm->ptr_ro = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); #endif if (shm->ptr_ro == XCACHE_MAP_FAILED) { shm->ptr_ro = NULL; } romem = shm->ptr_ro; do { if (romem == NULL || romem == shm->ptr) { break; } *(char *)shm->ptr = 1; if (*(char *)romem != 1) { break; } *(char *)shm->ptr = 2; if (*(char *)romem != 2) { break; } ro_ok = 1; } while (0); if (ro_ok) { shm->diff = PTR_SUB(shm->ptr_ro, (char *) shm->ptr); /* no overlap */ assert((xc_shmsize_t) abs(shm->diff) >= size); } else { if (shm->ptr_ro) { munmap(shm->ptr_ro, size); } #ifdef ZEND_WIN32 if (shm->hmap_ro) { CloseHandle(shm->hmap_ro); } #endif shm->ptr_ro = NULL; shm->diff = 0; } } /* }}} */ #ifndef ZEND_WIN32 close(fd); # ifndef __CYGWIN__ if (shm->newfile) { unlink(shm->name); } # endif #endif return shm; err: #ifndef ZEND_WIN32 if (fd != -1) { close(fd); } #endif if (shm) { xc_mmap_destroy(shm); } if (errstr) { fprintf(stderr, "%s\n", errstr); zend_error(E_ERROR, "%s", errstr); } return NULL; }
/* {{{ proto object ffmpeg_movie(string filename) Constructor for ffmpeg_movie objects */ FFMPEG_PHP_CONSTRUCTOR(ffmpeg_movie, __construct) { int persistent = 0, hashkey_length = 0; char *filename = NULL, *fullpath = NULL, *hashkey = NULL; zval ***argv; ff_movie_context *ffmovie_ctx = NULL; /* retrieve arguments */ argv = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), argv) != SUCCESS) { efree(argv); php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error parsing arguments"); } switch (ZEND_NUM_ARGS()) { case 2: convert_to_boolean_ex(argv[1]); if (! INI_BOOL("ffmpeg.allow_persistent") && Z_LVAL_PP(argv[1])) { zend_error(E_WARNING, "Persistent movies have been disabled in php.ini"); break; } persistent = Z_LVAL_PP(argv[1]); /* fallthru */ case 1: convert_to_string_ex(argv[0]); filename = Z_STRVAL_PP(argv[0]); break; default: WRONG_PARAM_COUNT; } if (persistent) { list_entry *le; /* resolve the fully-qualified path name to use as the hash key */ fullpath = expand_filepath(filename, NULL TSRMLS_CC); hashkey_length = sizeof("ffmpeg-php_")-1 + strlen(SAFE_STRING(filename)); hashkey = (char *) emalloc(hashkey_length+1); snprintf(hashkey, hashkey_length, "ffmpeg-php_%s", SAFE_STRING(filename)); /* do we have an existing persistent movie? */ if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, hashkey_length+1, (void**)&le)) { int type; if (Z_TYPE_P(le) != le_ffmpeg_pmovie) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to retrieve persistent resource"); } ffmovie_ctx = (ff_movie_context*)le->ptr; /* sanity check to ensure that the resource is still a valid * regular resource number */ if (zend_list_find(ffmovie_ctx->rsrc_id, &type) == ffmovie_ctx) { /* add a reference to the persistent movie */ zend_list_addref(ffmovie_ctx->rsrc_id); } else { //php_error_docref(NULL TSRMLS_CC, E_ERROR, //"Not a valid persistent movie resource"); ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ffmovie_ctx, le_ffmpeg_pmovie); } } else { /* no existing persistant movie, create one */ list_entry new_le; ffmovie_ctx = _php_alloc_ffmovie_ctx(1); if (_php_open_movie_file(ffmovie_ctx, filename)) { zend_error(E_WARNING, "Can't open movie file %s", filename); efree(argv); ZVAL_BOOL(getThis(), 0); RETURN_FALSE; } Z_TYPE(new_le) = le_ffmpeg_pmovie; new_le.ptr = ffmovie_ctx; if (FAILURE == zend_hash_update(&EG(persistent_list), hashkey, hashkey_length+1, (void *)&new_le, sizeof(list_entry), NULL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent resource"); } ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ffmovie_ctx, le_ffmpeg_pmovie); } } else { ffmovie_ctx = _php_alloc_ffmovie_ctx(0); if (_php_open_movie_file(ffmovie_ctx, Z_STRVAL_PP(argv[0]))) { zend_error(E_WARNING, "Can't open movie file %s", Z_STRVAL_PP(argv[0])); efree(argv); ZVAL_BOOL(getThis(), 0); RETURN_FALSE; } /* pass NULL for resource result since we're not returning the resource directly, but adding it to the returned object. */ ffmovie_ctx->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ffmovie_ctx, le_ffmpeg_movie); } object_init_ex(getThis(), ffmpeg_movie_class_entry_ptr); add_property_resource(getThis(), "ffmpeg_movie", ffmovie_ctx->rsrc_id); efree(argv); if (fullpath) { efree(fullpath); } if (hashkey) { efree(hashkey); } }
ZEND_API void wrong_param_count() { zend_error(E_WARNING,"Wrong parameter count for %s()",get_active_function_name()); }
/** * Checks if a method is callable */ static int zephir_alt_is_callable_check_method(zend_class_entry *ce, int check_flags, char *method_name, unsigned int method_len, zend_fcall_info_cache *fcc, char **error, unsigned long method_key TSRMLS_DC) { int retval = 0; #ifndef ZEPHIR_RELEASE int call_via_handler = 0; #endif if (error) { *error = NULL; } if (!method_key) { method_key = zend_inline_hash_func(method_name, method_len + 1); } /* Try to fetch find static method of given class. */ if (likely(zephir_hash_quick_find(&ce->function_table, method_name, method_len + 1, method_key, (void**) &fcc->function_handler) == SUCCESS)) { retval = 1; if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) && ZEPHIR_EG(scope) && instanceof_function(fcc->function_handler->common.scope, EG(scope) TSRMLS_CC)) { zend_function *priv_fbc; if (zephir_hash_quick_find(&ZEPHIR_EG(scope)->function_table, method_name, method_len + 1, method_key, (void **) &priv_fbc)==SUCCESS && (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE) && priv_fbc->common.scope == EG(scope)) { fcc->function_handler = priv_fbc; } } #ifndef ZEPHIR_RELEASE if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 && (fcc->calling_scope && (fcc->calling_scope->__call || fcc->calling_scope->__callstatic))) { if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) { if (!zend_check_private(fcc->function_handler, ce, method_name, method_len TSRMLS_CC)) { retval = 0; fcc->function_handler = NULL; goto get_function_via_handler; } } else { if (fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED) { if (!zend_check_protected(fcc->function_handler->common.scope, ZEPHIR_EG(scope))) { retval = 0; fcc->function_handler = NULL; goto get_function_via_handler; } } } } #endif } else { #ifndef ZEPHIR_RELEASE get_function_via_handler: if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) { #if PHP_VERSION_ID < 50400 fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method_name, method_len TSRMLS_CC); #else fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, method_name, method_len, NULL TSRMLS_CC); #endif if (fcc->function_handler) { retval = 1; call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; } } #endif } if (retval) { #ifndef ZEPHIR_RELEASE if (fcc->calling_scope && !call_via_handler) { if (!fcc->object_ptr && (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT)) { if (error) { zephir_spprintf(error, 0, "cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); retval = 0; } else { zend_error(E_ERROR, "Cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); } } if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) { if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) { if (!zend_check_private(fcc->function_handler, ce, method_name, method_len TSRMLS_CC)) { if (error) { if (*error) { efree(*error); } zephir_spprintf(error, 0, "cannot access private method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); } retval = 0; } } else { if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) { if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) { if (error) { if (*error) { efree(*error); } zephir_spprintf(error, 0, "cannot access protected method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); } retval = 0; } } } } } #endif } else { if (error && !(check_flags & IS_CALLABLE_CHECK_SILENT)) { if (fcc->calling_scope) { if (error) { zephir_spprintf(error, 0, "class '%s' does not have a method '%s'", fcc->calling_scope->name, method_name); } } else { if (error) { zephir_spprintf(error, 0, "function '%s' does not exist", method_name); } } } } if (retval) { fcc->initialized = 1; } return retval; }
void sapnwrfc_throw_connection_exception(RFC_ERROR_INFO error_info, char *msg, ...) { va_list args; zend_string *message; zval info; zval ex; va_start(args, msg); message = vstrpprintf(0, msg, args); va_end(args); array_init(&info); zend_replace_error_handling(EH_THROW, sapnwrfc_connection_exception_ce, NULL); object_init_ex(&ex, sapnwrfc_connection_exception_ce); zend_update_property_string(sapnwrfc_connection_exception_ce, &ex, "message", sizeof("message") - 1, ZSTR_VAL(message)); zend_update_property_long(sapnwrfc_connection_exception_ce, &ex, "code", sizeof("code") - 1, error_info.code); // populate errorInfo array add_assoc_long(&info, "code", error_info.code); add_assoc_str(&info, "key", sapuc_to_zend_string(error_info.key)); add_assoc_str(&info, "message", sapuc_to_zend_string(error_info.message)); switch(error_info.group) { case LOGON_FAILURE: // Error message raised when logon fails case COMMUNICATION_FAILURE: // Problems with the network connection (or backend broke down and killed the connection) case EXTERNAL_RUNTIME_FAILURE: // Problems in the RFC runtime of the external program (i.e "this" library) // no additional properties, just the generic one's from above break; case ABAP_APPLICATION_FAILURE: // ABAP Exception raised in ABAP function modules case ABAP_RUNTIME_FAILURE: // ABAP Message raised in ABAP function modules or in ABAP runtime of the backend (e.g Kernel) case EXTERNAL_APPLICATION_FAILURE: // Problems in the external program (e.g in the external server implementation) case EXTERNAL_AUTHORIZATION_FAILURE: // Problems raised in the authorization check handler provided by the external server implementation add_assoc_str(&info, "abapMsgClass", sapuc_to_zend_string(error_info.abapMsgClass)); add_assoc_str(&info, "abapMsgType", sapuc_to_zend_string(error_info.abapMsgType)); add_assoc_str(&info, "abapMsgNumber", sapuc_to_zend_string(error_info.abapMsgNumber)); add_assoc_str(&info, "abapMsgV1", sapuc_to_zend_string(error_info.abapMsgV1)); add_assoc_str(&info, "abapMsgV2", sapuc_to_zend_string(error_info.abapMsgV2)); add_assoc_str(&info, "abapMsgV3", sapuc_to_zend_string(error_info.abapMsgV3)); add_assoc_str(&info, "abapMsgV4", sapuc_to_zend_string(error_info.abapMsgV4)); break; case RFC_OK: // LCOV_EXCL_START zend_error(E_ERROR, "Internal error: exception handler called for RFC_OK"); zend_replace_error_handling(EH_NORMAL, NULL, NULL); zend_string_release(message); return; // LCOV_EXCL_STOP default: zend_error(E_ERROR, "Internal error: unknown error group"); zend_replace_error_handling(EH_NORMAL, NULL, NULL); zend_string_release(message); return; } zend_update_property(sapnwrfc_connection_exception_ce, &ex, "errorInfo", sizeof("errorInfo") - 1, &info); zval_ptr_dtor(&info); zend_string_release(message); zend_throw_exception_object(&ex); zend_replace_error_handling(EH_NORMAL, NULL, NULL); }
void bc_out_of_memory (void) { zend_error(E_ERROR, "bcmath: out of memory!"); }
static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg) /* {{{ */ { browser_data *bdata = arg; int persistent = bdata->htab->u.flags & HASH_FLAG_PERSISTENT; if (!arg1) { return; } switch (callback_type) { case ZEND_INI_PARSER_ENTRY: if (Z_TYPE(bdata->current_section) != IS_UNDEF && arg2) { zval new_property; zend_string *new_key; /* parent entry can not be same as current section -> causes infinite loop! */ if (!strcasecmp(Z_STRVAL_P(arg1), "parent") && bdata->current_section_name != NULL && !strcasecmp(bdata->current_section_name, Z_STRVAL_P(arg2)) ) { zend_error(E_CORE_ERROR, "Invalid browscap ini file: " "'Parent' value cannot be same as the section name: %s " "(in file %s)", bdata->current_section_name, INI_STR("browscap")); return; } /* Set proper value for true/false settings */ if ((Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "on", sizeof("on") - 1)) || (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "yes", sizeof("yes") - 1)) || (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "true", sizeof("true") - 1)) ) { ZVAL_NEW_STR(&new_property, zend_string_init("1", sizeof("1")-1, persistent)); } else if ( (Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "no", sizeof("no") - 1)) || (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "off", sizeof("off") - 1)) || (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "none", sizeof("none") - 1)) || (Z_STRLEN_P(arg2) == 5 && !strncasecmp(Z_STRVAL_P(arg2), "false", sizeof("false") - 1)) ) { // TODO: USE ZSTR_EMPTY_ALLOC()? ZVAL_NEW_STR(&new_property, zend_string_init("", sizeof("")-1, persistent)); } else { /* Other than true/false setting */ ZVAL_STR(&new_property, zend_string_dup(Z_STR_P(arg2), persistent)); } new_key = zend_string_dup(Z_STR_P(arg1), persistent); zend_str_tolower(ZSTR_VAL(new_key), ZSTR_LEN(new_key)); zend_hash_update(Z_ARRVAL(bdata->current_section), new_key, &new_property); zend_string_release(new_key); } break; case ZEND_INI_PARSER_SECTION: { zval processed; zval unprocessed; /*printf("'%s' (%d)\n",$1.value.str.val,$1.value.str.len + 1);*/ if (persistent) { ZVAL_NEW_PERSISTENT_ARR(&bdata->current_section); } else { ZVAL_NEW_ARR(&bdata->current_section); } zend_hash_init(Z_ARRVAL(bdata->current_section), 0, NULL, (dtor_func_t) (persistent?browscap_entry_dtor_persistent :browscap_entry_dtor_request), persistent); if (bdata->current_section_name) { pefree(bdata->current_section_name, persistent); } bdata->current_section_name = pestrndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), persistent); zend_hash_update(bdata->htab, Z_STR_P(arg1), &bdata->current_section); ZVAL_STR(&processed, Z_STR_P(arg1)); ZVAL_STR(&unprocessed, zend_string_dup(Z_STR_P(arg1), persistent)); convert_browscap_pattern(&processed, persistent); zend_hash_str_update(Z_ARRVAL(bdata->current_section), "browser_name_regex", sizeof("browser_name_regex")-1, &processed); zend_hash_str_update(Z_ARRVAL(bdata->current_section), "browser_name_pattern", sizeof("browser_name_pattern")-1, &unprocessed); } break; } }
/* PHP */ static ZEND_FUNCTION(hs_compress) { zval *data; size_t data_len; size_t sink_sz = 0; size_t poll_sz = 0; HSE_sink_res sres; HSE_poll_res pres; HSE_finish_res fres; //Default window_sz2 and lookahead_sz2 values uint8_t window = DEF_WINDOW_SZ2; uint8_t lookahead = DEF_LOOKAHEAD_SZ2; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &data, &window, &lookahead) == FAILURE) { RETURN_FALSE; } if (Z_TYPE_P(data) != IS_STRING) { zend_error(E_WARNING, "hs_compress : expects parameter to be string."); RETURN_FALSE; } //Allocate encoder heatshrink_encoder *hse = heatshrink_encoder_alloc(window, lookahead); if (hse == NULL) { zend_error(E_WARNING, "hs_compress : heatshrink_encoder_alloc error. Check window and lookahead values."); RETURN_FALSE; } data_len = Z_STRLEN_P(data); //TODO: think of better way to compute outbuff size size_t outbuff_len = data_len+1; unsigned char *outbuff = (unsigned char *) emalloc(outbuff_len); size_t sunk = 0; do { sres = heatshrink_encoder_sink(hse, (unsigned char *) &(Z_STRVAL_P(data)[sunk]), data_len - sunk, &sink_sz); if (sres < 0) { zend_error(E_WARNING, "hs_compress : heatshrink_encoder_sink error"); efree(outbuff); heatshrink_encoder_free(hse); RETURN_FALSE; } sunk += sink_sz; do { do { pres = heatshrink_encoder_poll(hse, &outbuff[poll_sz], outbuff_len - poll_sz, &sink_sz); if (pres < 0) { zend_error(E_WARNING, "hs_compress : heatshrink_encoder_poll error"); efree(outbuff); heatshrink_encoder_free(hse); RETURN_FALSE; } poll_sz += sink_sz; if (poll_sz == outbuff_len && pres == HSER_POLL_MORE) { //TODO: think of bettery way to compute buffer reallocation size outbuff_len += data_len/2; outbuff = erealloc(outbuff, outbuff_len); } } while (pres == HSER_POLL_MORE); if (sunk == data_len) { fres = heatshrink_encoder_finish(hse); if (fres < 0) { zend_error(E_WARNING, "hs_compress : heatshrink_encoder_finish error"); efree(outbuff); heatshrink_encoder_free(hse); RETURN_FALSE; } if (fres == HSER_FINISH_DONE) { RETVAL_STRINGL((char *) outbuff, poll_sz, 1); efree(outbuff); heatshrink_encoder_free(hse); return; } } } while (fres == HSER_FINISH_MORE); } while (sunk < data_len); zend_error(E_WARNING, "hs_compress : general error"); efree(outbuff); heatshrink_encoder_free(hse); RETURN_FALSE; }
/* {{{ writes a property to a thread in the appropriate way */ void pthreads_write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_D) { PTHREAD pthreads = PTHREADS_FETCH_FROM(object); zval *mstring = NULL; zend_bool nulled = 0; zend_bool locked; if (member == NULL || Z_TYPE_P(member) == IS_NULL) { /* for anonymous members, we acquire the lock and increment a counter we do not store any additional information or perform any lookups */ pthreads_lock_acquire(pthreads->store->lock, &locked TSRMLS_CC); { if (member == NULL) { MAKE_STD_ZVAL(member); nulled = 1; } ZVAL_LONG(member, pthreads->store->next++); } pthreads_lock_release(pthreads->store->lock, locked TSRMLS_CC); } if (Z_TYPE_P(member) != IS_STRING) { ALLOC_ZVAL(mstring); *mstring = *member; zval_copy_ctor( mstring ); INIT_PZVAL(mstring); convert_to_string(mstring); if(nulled) FREE_ZVAL(member); member = mstring; #if PHP_VERSION_ID > 50399 key = NULL; #endif } if (Z_TYPE_P(member)==IS_STRING) { switch(Z_TYPE_P(value)){ case IS_STRING: case IS_LONG: case IS_ARRAY: case IS_OBJECT: case IS_NULL: case IS_DOUBLE: case IS_RESOURCE: case IS_BOOL: { if (pthreads_store_write(pthreads->store, Z_STRVAL_P(member), Z_STRLEN_P(member), &value TSRMLS_CC)!=SUCCESS){ zend_error( E_WARNING, "pthreads failed to write member %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member) ); } } break; default: { zend_error( E_WARNING, "pthreads detected an attempt to use an unsupported kind of data for %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member) ); } } } else zend_error( E_WARNING, "pthreads detected an attempt to use an unsupported kind of key in %s", Z_OBJCE_P(object)->name ); if (mstring != NULL) { zval_ptr_dtor(&mstring); } }
/** * @brief Reads an item from @a arr at position @a index and stores it to @a return_value * @param return_value[out] Return value * @param arr Array * @param index Index * @param silent 0 to suppress all warnings, @c PH_NOISY to enable * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @c arr is not an array and @c silent = @c PH_NOISY * @throw @c E_WARNING if @c index is not of the supported type and @c silent = @c PH_NOISY * @throw @c E_NOTICE if @c index does not exist and @c silent = @c PH_NOISY * @warning @c *return_value should be either @c NULL (preferred) or point to not initialized memory; if @c *return_value points to a valid variable, mmemory leak is possible * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer */ int zephir_array_fetch(zval **return_value, zval *arr, zval *index, int flags TSRMLS_DC){ zval **zv; HashTable *ht; int result; ulong uidx = 0; char *sidx = NULL; if (Z_TYPE_P(arr) == IS_ARRAY) { ht = Z_ARRVAL_P(arr); switch (Z_TYPE_P(index)) { case IS_NULL: result = zephir_hash_find(ht, ZEND_STRS(""), (void**) &zv); sidx = ""; break; case IS_DOUBLE: uidx = (ulong)Z_DVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: uidx = Z_LVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_STRING: sidx = Z_STRLEN_P(index) ? Z_STRVAL_P(index) : ""; result = zend_symtable_find(ht, Z_STRVAL_P(index), Z_STRLEN_P(index)+1, (void**) &zv); break; default: if ((flags & PH_NOISY) == PH_NOISY) { zend_error(E_WARNING, "Illegal offset type"); } result = FAILURE; break; } if (result != FAILURE) { *return_value = *zv; if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return SUCCESS; } if ((flags & PH_NOISY) == PH_NOISY) { if (sidx == NULL) { zend_error(E_NOTICE, "Undefined index: %ld", uidx); } else { zend_error(E_NOTICE, "Undefined index: %s", sidx); } } } *return_value = ZEPHIR_GLOBAL(global_null); return FAILURE; }
zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref) { php_com_dotnet_object *obj; struct php_com_iterator *I; IEnumVARIANT *iev = NULL; DISPPARAMS dp; VARIANT v; unsigned long n_fetched; zval ptr; if (by_ref) { zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); } obj = CDNO_FETCH(object); if (V_VT(&obj->v) != VT_DISPATCH && !V_ISARRAY(&obj->v)) { php_error_docref(NULL, E_WARNING, "variant is not an object or array VT=%d", V_VT(&obj->v)); return NULL; } memset(&dp, 0, sizeof(dp)); VariantInit(&v); I = (struct php_com_iterator*)ecalloc(1, sizeof(*I)); zend_iterator_init(&I->iter); I->iter.funcs = &com_iter_funcs; Z_PTR(I->iter.data) = I; I->code_page = obj->code_page; ZVAL_UNDEF(&I->zdata); VariantInit(&I->safe_array); VariantInit(&I->v); if (V_ISARRAY(&obj->v)) { LONG bound; UINT dims; dims = SafeArrayGetDim(V_ARRAY(&obj->v)); if (dims != 1) { php_error_docref(NULL, E_WARNING, "Can only handle single dimension variant arrays (this array has %d)", dims); goto fail; } /* same semantics as foreach on a PHP array; * make a copy and enumerate that copy */ VariantCopy(&I->safe_array, &obj->v); /* determine the key value for the array */ SafeArrayGetLBound(V_ARRAY(&I->safe_array), 1, &bound); SafeArrayGetUBound(V_ARRAY(&I->safe_array), 1, &I->sa_max); /* pre-fetch the element */ if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound)) { I->key = bound; ZVAL_NULL(&ptr); php_com_zval_from_variant(&ptr, &I->v, I->code_page); ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { I->key = (ulong)-1; } } else { /* can we enumerate it? */ if (FAILED(IDispatch_Invoke(V_DISPATCH(&obj->v), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dp, &v, NULL, NULL))) { goto fail; } /* get something useful out of it */ if (V_VT(&v) == VT_UNKNOWN) { IUnknown_QueryInterface(V_UNKNOWN(&v), &IID_IEnumVARIANT, (void**)&iev); } else if (V_VT(&v) == VT_DISPATCH) { IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IEnumVARIANT, (void**)&iev); } VariantClear(&v); if (iev == NULL) { goto fail; } I->ev = iev; /* Get the first element now */ if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) { /* indicate that we have element 0 */ I->key = 0; ZVAL_NULL(&ptr); php_com_zval_from_variant(&ptr, &I->v, I->code_page); ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { /* indicate that there are no more items */ I->key = (ulong)-1; } } return &I->iter; fail: if (I) { VariantClear(&I->safe_array); VariantClear(&I->v); efree(I); } return NULL; }
int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage) { TYPEATTR *attr; FUNCDESC *func; int i; OLECHAR *olename; char *ansiname = NULL; size_t ansinamelen; int ret = 0; if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) { return 0; } /* verify that it is suitable */ if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) { if (guid) { memcpy(guid, &attr->guid, sizeof(GUID)); } if (printdef) { char *guidstring; ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL); ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage); SysFreeString(olename); guidstring = php_com_string_from_clsid(&attr->guid, codepage); php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring); efree(guidstring); efree(ansiname); } if (id_to_name) { zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0); } /* So we've got the dispatch interface; lets list the event methods */ for (i = 0; i < attr->cFuncs; i++) { zval tmp; DISPID lastid = 0; /* for props */ int isprop; if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func))) break; isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT); if (!isprop || lastid != func->memid) { lastid = func->memid; ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL); ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage); SysFreeString(olename); if (printdef) { int j; char *funcdesc; size_t funcdesclen; unsigned int cnames = 0; BSTR *names; names = (BSTR*)safe_emalloc((func->cParams + 1), sizeof(BSTR), 0); ITypeInfo_GetNames(typeinfo, func->memid, names, func->cParams + 1, &cnames); /* first element is the function name */ SysFreeString(names[0]); php_printf("\t/* DISPID=%d */\n", func->memid); if (func->elemdescFunc.tdesc.vt != VT_VOID) { php_printf("\t/* %s [%d] */\n", vt_to_string(func->elemdescFunc.tdesc.vt), func->elemdescFunc.tdesc.vt ); } if (isprop) { ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL); if (olename) { funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage); SysFreeString(olename); php_printf("\t/* %s */\n", funcdesc); efree(funcdesc); } php_printf("\tvar $%s;\n\n", ansiname); } else { /* a function */ php_printf("\tfunction %s(\n", ansiname); for (j = 0; j < func->cParams; j++) { ELEMDESC *elem = &func->lprgelemdescParam[j]; php_printf("\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt); if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN) php_printf("[in]"); if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT) php_printf("[out]"); if (elem->tdesc.vt == VT_PTR) { /* what does it point to ? */ php_printf(" --> %s [%d] ", vt_to_string(elem->tdesc.lptdesc->vt), elem->tdesc.lptdesc->vt ); } /* when we handle prop put and get, this will look nicer */ if (j+1 < (int)cnames) { funcdesc = php_com_olestring_to_string(names[j+1], &funcdesclen, codepage); SysFreeString(names[j+1]); } else { funcdesc = "???"; } php_printf(" */ %s%s%c\n", elem->tdesc.vt == VT_PTR ? "&$" : "$", funcdesc, j == func->cParams - 1 ? ' ' : ',' ); if (j+1 < (int)cnames) { efree(funcdesc); } } php_printf("\t\t)\n\t{\n"); ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL); if (olename) { funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage); SysFreeString(olename); php_printf("\t\t/* %s */\n", funcdesc); efree(funcdesc); } php_printf("\t}\n"); } efree(names); } if (id_to_name) { zend_str_tolower(ansiname, ansinamelen); ZVAL_STRINGL(&tmp, ansiname, ansinamelen); zend_hash_index_update(id_to_name, func->memid, &tmp); // TODO: avoid reallocation??? efree(ansiname); } } ITypeInfo_ReleaseFuncDesc(typeinfo, func); } if (printdef) { php_printf("}\n"); } ret = 1; } else { zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind); } ITypeInfo_ReleaseTypeAttr(typeinfo, attr); return ret; }
/* {{{ MongoCursor->__construct */ PHP_METHOD(MongoCursor, __construct) { zval *zlink = 0, *zns = 0, *zquery = 0, *zfields = 0, *empty, *timeout; zval **data; mongo_cursor *cursor; mongo_link *link; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oz|zz", &zlink, mongo_ce_Mongo, &zns, &zquery, &zfields) == FAILURE) { return; } if ((zquery && IS_SCALAR_P(zquery)) || (zfields && IS_SCALAR_P(zfields))) { zend_error(E_WARNING, "MongoCursor::__construct() expects parameters 3 and 4 to be arrays or objects"); return; } // if query or fields weren't passed, make them default to an empty array MAKE_STD_ZVAL(empty); object_init(empty); // these are both initialized to the same zval, but that's okay because // there's no way to change them without creating a new cursor if (!zquery || (Z_TYPE_P(zquery) == IS_ARRAY && zend_hash_num_elements(HASH_P(zquery)) == 0)) { zquery = empty; } if (!zfields) { zfields = empty; } cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); // db connection cursor->resource = zlink; zval_add_ref(&zlink); // db connection resource PHP_MONGO_GET_LINK(zlink); cursor->link = link; // change ['x', 'y', 'z'] into {'x' : 1, 'y' : 1, 'z' : 1} if (Z_TYPE_P(zfields) == IS_ARRAY) { HashPosition pointer; zval *fields; MAKE_STD_ZVAL(fields); array_init(fields); // fields to return for(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(zfields), &pointer); zend_hash_get_current_data_ex(Z_ARRVAL_P(zfields), (void**) &data, &pointer) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(zfields), &pointer)) { int key_type, key_len; ulong index; char *key; key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(zfields), &key, (uint*)&key_len, &index, NO_DUP, &pointer); if (key_type == HASH_KEY_IS_LONG) { if (Z_TYPE_PP(data) == IS_STRING) { add_assoc_long(fields, Z_STRVAL_PP(data), 1); } else { zval_ptr_dtor(&empty); zval_ptr_dtor(&fields); zend_throw_exception(mongo_ce_Exception, "field names must be strings", 0 TSRMLS_CC); return; } } else { add_assoc_zval(fields, key, *data); zval_add_ref(data); } } cursor->fields = fields; } // if it's already an object, we don't have to worry else { cursor->fields = zfields; zval_add_ref(&zfields); } // ns convert_to_string(zns); cursor->ns = estrdup(Z_STRVAL_P(zns)); // query cursor->query = zquery; zval_add_ref(&zquery); // reset iteration pointer, just in case MONGO_METHOD(MongoCursor, reset, return_value, getThis()); cursor->at = 0; cursor->num = 0; cursor->special = 0; cursor->persist = 0; timeout = zend_read_static_property(mongo_ce_Cursor, "timeout", strlen("timeout"), NOISY TSRMLS_CC); cursor->timeout = Z_LVAL_P(timeout); cursor->opts = link->slave_okay ? (1 << 2) : 0; // get rid of extra ref zval_ptr_dtor(&empty); }
PHP_METHOD(swoole_lock, __construct) { long type = SW_MUTEX; char *filelock; int filelock_len = 0; int ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &type, &filelock, &filelock_len) == FAILURE) { RETURN_FALSE; } swLock *lock = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swLock)); if(lock == NULL) { zend_error(E_WARNING, "SwooleLock: alloc fail"); RETURN_FALSE; } switch(type) { case SW_RWLOCK: ret = swRWLock_create(lock, 1); break; case SW_FILELOCK: if(filelock_len <= 0) { zend_error(E_ERROR, "SwooleLock: filelock require lock file name."); RETURN_FALSE; } int fd; if ((fd = open(filelock, O_RDWR | O_CREAT, 0666)) < 0) { zend_error(E_WARNING, "SwooleLock: open file[%s] fail. Error: %s [%d]", filelock, strerror(errno), errno); RETURN_FALSE; } ret = swFileLock_create(lock, fd); break; case SW_SEM: ret = swSem_create(lock, IPC_PRIVATE, 1); break; #ifdef HAVE_SPINLOCK case SW_SPINLOCK: ret = swSpinLock_create(lock, 1); break; #endif case SW_MUTEX: default: ret = swMutex_create(lock, 1); break; } if(ret < 0) { zend_error(E_WARNING, "SwooleLock: create lock fail"); RETURN_FALSE; } zval *zres; MAKE_STD_ZVAL(zres); ZEND_REGISTER_RESOURCE(zres, lock, le_swoole_lock); zend_update_property(swoole_lock_class_entry_ptr, getThis(), ZEND_STRL("_lock"), zres TSRMLS_CC); RETURN_TRUE; }
/* {{{ proto Closure::__construct() Private constructor preventing instantiation */ ZEND_METHOD(Closure, __construct) { zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not allowed"); }
ZEND_METHOD(afk_app, run){/*{{{*/ zval **uri; char *c=NULL, *a=NULL; zval *arr = PG(http_globals)[TRACK_VARS_GET]; //从http_globals中寻找get参数,确认Controller和action的值。 if(arr && Z_TYPE_P(arr) == IS_ARRAY){ if(zend_hash_find(HASH_OF(arr), HTTP_CONTRONLLER_PARAM, strlen(HTTP_CONTRONLLER_PARAM)+1, (void **)&uri) == SUCCESS){ c = Z_STRVAL_PP(uri); }else{ c = "index"; } if(zend_hash_find(HASH_OF(arr), HTTP_ACTION_PARAM, strlen(HTTP_ACTION_PARAM)+1, (void **)&uri) == SUCCESS){ a = Z_STRVAL_PP(uri); }else{ a = "index"; } } //寻找对应的Controller和action方法所在的文件。 char *controller_path; spprintf(&controller_path, 0, "%s/controller/%s.php", APP_DIR, c); FILE *fp; //php_printf("%s\n", controller_path); //文件存在则引入该文件。不存在则报错。 if( (fp = fopen(controller_path, "r")) != NULL){ fclose(fp); int dummy = 1; zend_file_handle file_handle; zend_op_array *op_array; file_handle.filename = controller_path; file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; file_handle.handle.fp = NULL; op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC); if (op_array && file_handle.handle.stream.handle) { int dummy = 1; if (!file_handle.opened_path) { file_handle.opened_path = controller_path; } php_printf("opened_path: %s\n", file_handle.opened_path); zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL); } zend_destroy_file_handle(&file_handle TSRMLS_CC); if(op_array){ php_printf("execute op_array \n"); //保存旧的环境变量 zval ** __old_return_value_pp = EG(return_value_ptr_ptr); zend_op ** __old_opline_ptr = EG(opline_ptr); zend_op_array * __old_op_array = EG(active_op_array); zend_function_state * __old_func_state = EG(function_state_ptr); //执行op_array zval *result = NULL; EG(return_value_ptr_ptr) = &result; EG(active_op_array) = op_array; zend_execute(op_array TSRMLS_CC); destroy_op_array(op_array TSRMLS_CC); efree(op_array); //恢复旧的环境变量 EG(return_value_ptr_ptr) = __old_return_value_pp; EG(opline_ptr) = __old_opline_ptr; EG(active_op_array) = __old_op_array; EG(function_state_ptr) = __old_func_state; } }else{ char *error; spprintf(&error, 0, "cann't find file %s", controller_path); zend_error(1, error); } //dispatcher 调用分发的请求。 /** *在EG(class_table)查找相应的类,然后调用它的方法。 */ zend_class_entry **class = NULL; char *class_name = emalloc(strlen(c)+strlen("Controller")+1); class_name = strcpy(class_name, c); class_name = strcat(class_name, zend_str_tolower_dup("Controller", strlen("Controller")+1)); //Notice: class name need tolower. if(zend_hash_find(EG(class_table), class_name, strlen(class_name)+1, (void *)&class) != SUCCESS){ char *error; spprintf(&error, 0, "cann't find the controller class: %s ", class_name); php_printf("%s", class_name); efree(class_name); efree(class); zend_error(1, error); } efree(class_name); zval *obj, *function_name, *retval; MAKE_STD_ZVAL(obj); MAKE_STD_ZVAL(function_name); MAKE_STD_ZVAL(retval); object_init_ex(obj, *class); //php_var_dump(&obj, 1 TSRMLS_CC); ZVAL_STRINGL(function_name, "indexaction", strlen("indexaction"), 1); call_user_function(&((*class)->function_table), &obj, function_name, retval, 0, NULL TSRMLS_CC); zval_ptr_dtor(&obj); zval_ptr_dtor(&function_name); zval_ptr_dtor(&retval); //efree(class); RETURN_BOOL(1); }/*}}}*/
/* {{{ proto XmlTransaction::XmlTransaction(object dbenv [, string name]) Create a new container using an optional dbenv (can be null) and name */ PHP_DBXML_METHOD_BEGIN(XmlTransaction, XmlTransaction) { zend_error(E_ERROR, "XmlTransaction can not be instantiated from PHP"); } PHP_DBXML_METHOD_END()
PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC) { char *cookie; int len=sizeof("Set-Cookie: "); zend_string *dt; sapi_header_line ctr = {0}; int result; zend_string *encoded_value = NULL; if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" ); return FAILURE; } if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" ); return FAILURE; } len += name_len; if (value && url_encode) { encoded_value = php_url_encode(value, value_len); len += encoded_value->len; } else if (value) { encoded_value = zend_string_init(value, value_len, 0); len += encoded_value->len; } if (path) { len += path_len; } if (domain) { len += domain_len; } cookie = emalloc(len + 100); if (value && value_len == 0) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt->val); zend_string_free(dt); } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value->val : ""); if (expires > 0) { const char *p; char tsdelta[13]; strlcat(cookie, COOKIE_EXPIRES, len + 100); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); /* check to make sure that the year does not exceed 4 digits in length */ p = zend_memrchr(dt->val, '-', dt->len); if (!p || *(p + 5) != ' ') { zend_string_free(dt); efree(cookie); zend_string_free(encoded_value); zend_error(E_WARNING, "Expiry date cannot have a year greater than 9999"); return FAILURE; } strlcat(cookie, dt->val, len + 100); zend_string_free(dt); snprintf(tsdelta, sizeof(tsdelta), ZEND_LONG_FMT, (zend_long) difftime(expires, time(NULL))); strlcat(cookie, COOKIE_MAX_AGE, len + 100); strlcat(cookie, tsdelta, len + 100); } } if (encoded_value) { zend_string_free(encoded_value); } if (path && path_len > 0) { strlcat(cookie, COOKIE_PATH, len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { strlcat(cookie, COOKIE_DOMAIN, len + 100); strlcat(cookie, domain, len + 100); } if (secure) { strlcat(cookie, COOKIE_SECURE, len + 100); } if (httponly) { strlcat(cookie, COOKIE_HTTPONLY, len + 100); } ctr.line = cookie; ctr.line_len = strlen(cookie); result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); efree(cookie); return result; }