/** * @brief Reads an item from @a arr at position @a index using the precomputed hash @c key and stores it to @a return_value * @param return_value[out] Return value * @param arr Array * @param index Index * @param index Index length; must contain the trailing zero, if any * @param key Precomputed hash of @c 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_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 */ int zephir_array_fetch_quick_string(zval **return_value, zval *arr, const char *index, uint index_length, unsigned long key, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC) { zval **zv; if (likely(Z_TYPE_P(arr) == IS_ARRAY)) { if (zephir_hash_quick_find(Z_ARRVAL_P(arr), index, index_length, key, (void**) &zv) == SUCCESS) { *return_value = *zv; if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return SUCCESS; } if ((flags & PH_NOISY) == PH_NOISY) { zend_error(E_NOTICE, "Undefined index: %s", index); } } else { if ((flags & PH_NOISY) == PH_NOISY) { zend_error(E_NOTICE, "Cannot use a scalar value as an array in %s on line %d", file, line); } } *return_value = ZEPHIR_GLOBAL(global_null); if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return FAILURE; }
int zephir_array_isset_quick_string_fetch(zval **fetched, zval *arr, char *index, uint index_length, unsigned long key, int readonly TSRMLS_DC) { zval **zv; if (likely(Z_TYPE_P(arr) == IS_ARRAY)) { if (zephir_hash_quick_find(Z_ARRVAL_P(arr), index, index_length, key, (void**) &zv) == SUCCESS) { *fetched = *zv; if (!readonly) { Z_ADDREF_P(*fetched); } return 1; } } *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; }
/** * 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; }