/** * Increments an object property */ int zephir_property_incr_decr(zval *object, char *property_name, unsigned int property_length, unsigned int increment) { zval tmp; zend_class_entry *ce; int separated = 0; ZVAL_UNDEF(&tmp); if (Z_TYPE_P(object) != IS_OBJECT) { php_error_docref(NULL, E_WARNING, "Attempt to assign property of non-object"); return FAILURE; } ce = Z_OBJCE_P(object); if (ce->parent) { ce = zephir_lookup_class_ce(ce, property_name, property_length); } zephir_read_property(&tmp, object, property_name, property_length, 0); if (Z_TYPE(tmp) > IS_UNDEF) { Z_TRY_DELREF(tmp); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp)) { if (Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } if (increment) { zephir_increment(&tmp); } else { zephir_decrement(&tmp); } if (separated) { zephir_update_property_zval(object, property_name, property_length, &tmp); } } return SUCCESS; }
/** * Appends a zval value to an array property */ int zephir_update_property_array_append(zval *object, char *property, unsigned int property_length, zval *value) { zval tmp; int separated = 0; ZVAL_UNDEF(&tmp); if (Z_TYPE_P(object) != IS_OBJECT) { return SUCCESS; } zephir_read_property(&tmp, object, property, property_length, PH_NOISY_CC); Z_TRY_DELREF(tmp); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp)) { if (Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } /** Convert the value to array if not is an array */ if (Z_TYPE(tmp) != IS_ARRAY) { if (separated) { convert_to_array(&tmp); } else { array_init(&tmp); separated = 1; } Z_DELREF(tmp); } Z_TRY_ADDREF_P(value); add_next_index_zval(&tmp, value); if (separated) { zephir_update_property_zval(object, property, property_length, &tmp); } return SUCCESS; }
/** * Updates an array property */ int zephir_update_property_array(zval *object, const char *property, zend_uint property_length, const zval *index, zval *value) { zval tmp; int separated = 0; if (Z_TYPE_P(object) == IS_OBJECT) { zephir_read_property(&tmp, object, property, property_length, PH_NOISY | PH_READONLY); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp)) { if (Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } /** Convert the value to array if not is an array */ if (Z_TYPE(tmp) != IS_ARRAY) { if (separated) { convert_to_array(&tmp); } else { array_init(&tmp); separated = 1; } Z_DELREF(tmp); } Z_TRY_ADDREF_P(value); if (Z_TYPE_P(index) == IS_STRING) { zend_symtable_str_update(Z_ARRVAL(tmp), Z_STRVAL_P(index), Z_STRLEN_P(index), value); } else if (Z_TYPE_P(index) == IS_LONG) { zend_hash_index_update(Z_ARRVAL(tmp), Z_LVAL_P(index), value); } else if (Z_TYPE_P(index) == IS_NULL) { zend_hash_next_index_insert(Z_ARRVAL(tmp), value); } if (separated) { zephir_update_property_zval(object, property, property_length, &tmp); } } return SUCCESS; }
/* * Multiple array-offset update */ int zephir_update_static_property_array_multi_ce(zend_class_entry *ce, const char *property, zend_uint property_length, zval *value, const char *types, int types_length, int types_count, ...) { va_list ap; zval tmp_arr; int separated = 0; ZVAL_UNDEF(&tmp_arr); zephir_read_static_property_ce(&tmp_arr, ce, property, property_length, PH_NOISY | PH_READONLY); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp_arr)) { if (Z_REFCOUNT(tmp_arr) > 1) { if (!Z_ISREF(tmp_arr)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp_arr); ZVAL_COPY_VALUE(&tmp_arr, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp_arr); ZVAL_COPY_VALUE(&tmp_arr, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } /** Convert the value to array if not is an array */ if (Z_TYPE(tmp_arr) != IS_ARRAY) { if (separated) { convert_to_array(&tmp_arr); } else { array_init(&tmp_arr); separated = 1; } Z_DELREF(tmp_arr); } va_start(ap, types_count); SEPARATE_ZVAL_IF_NOT_REF(&tmp_arr); zephir_array_update_multi_ex(&tmp_arr, value, types, types_length, types_count, ap); va_end(ap); if (separated) { zephir_update_static_property_ce(ce, property, property_length, &tmp_arr); } return SUCCESS; }
int php_com_saproxy_create(zend_object *com_object, zval *proxy_out, zval *index) { php_com_saproxy *proxy, *rel = NULL; proxy = ecalloc(1, sizeof(*proxy)); proxy->dimensions = 1; if (com_object->ce == php_com_saproxy_class_entry) { rel = (php_com_saproxy*) com_object; proxy->obj = rel->obj; proxy->dimensions += rel->dimensions; } else { proxy->obj = (php_com_dotnet_object*) com_object; } GC_ADDREF(&proxy->obj->zo); proxy->indices = safe_emalloc(proxy->dimensions, sizeof(zval *), 0); if (rel) { clone_indices(proxy, rel, rel->dimensions); } ZVAL_DUP(&proxy->indices[proxy->dimensions-1], index); zend_object_std_init(&proxy->std, php_com_saproxy_class_entry); proxy->std.handlers = &php_com_saproxy_handlers; ZVAL_OBJ(proxy_out, &proxy->std); return 1; }
/* {{{ mysqli_write_property */ void mysqli_write_property(zval *object, zval *member, zval *value, void **cache_slot) { zval tmp_member; mysqli_object *obj; mysqli_prop_handler *hnd = NULL; if (Z_TYPE_P(member) != IS_STRING) { ZVAL_DUP(&tmp_member, member); convert_to_string(&tmp_member); member = &tmp_member; } obj = Z_MYSQLI_P(object); if (obj->prop_handler != NULL) { hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member)); } if (hnd) { hnd->write_func(obj, value); /* ??? if (! PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) == 0) { Z_ADDREF_P(value); zval_ptr_dtor(&value); } */ } else { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); std_hnd->write_property(object, member, value, cache_slot); } if (member == &tmp_member) { zval_dtor(member); } }
/* {{{ mysqli_read_property */ zval *mysqli_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv) { zval tmp_member; zval *retval; mysqli_object *obj; mysqli_prop_handler *hnd = NULL; obj = Z_MYSQLI_P(object); if (Z_TYPE_P(member) != IS_STRING) { ZVAL_DUP(&tmp_member, member); convert_to_string(&tmp_member); member = &tmp_member; } if (obj->prop_handler != NULL) { hnd = zend_hash_find_ptr(obj->prop_handler, Z_STR_P(member)); } if (hnd) { retval = hnd->read_func(obj, rv); if (retval == NULL) { retval = &EG(uninitialized_zval); } } else { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); retval = std_hnd->read_property(object, member, type, cache_slot, rv); } if (member == &tmp_member) { zval_dtor(member); } return retval; }
/** * Unsets an index in an array property */ int zephir_unset_property_array(zval *object, char *property, unsigned int property_length, zval *index) { zval tmp; int separated = 0; if (Z_TYPE_P(object) == IS_OBJECT) { zephir_read_property(&tmp, object, property, property_length, PH_NOISY_CC); Z_TRY_DELREF(tmp); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp) && Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } zephir_array_unset(&tmp, index, PH_SEPARATE); if (separated) { zephir_update_property_zval(object, property, property_length, &tmp); } } return SUCCESS; }
static inline void clone_indices(php_com_saproxy *dest, php_com_saproxy *src, int ndims) { int i; for (i = 0; i < ndims; i++) { ZVAL_DUP(&dest->indices[i], &src->indices[i]); } }
static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_op *opline, zend_function *func) { if (func->type == ZEND_USER_FUNCTION && !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS)) && fcall->extended_value >= func->op_array.required_num_args && func->op_array.opcodes[func->op_array.num_args].opcode == ZEND_RETURN) { zend_op *ret_opline = func->op_array.opcodes + func->op_array.num_args; if (ret_opline->op1_type == IS_CONST) { uint32_t i, num_args = func->op_array.num_args; num_args += (func->op_array.fn_flags & ZEND_ACC_VARIADIC) != 0; if (fcall->opcode == ZEND_INIT_METHOD_CALL && fcall->op1_type == IS_UNUSED) { /* TODO: we can't inlne methods, because $this may be used * not in object context ??? */ return; } for (i = 0; i < num_args; i++) { /* Don't inline functions with by-reference arguments. This would require * correct handling of INDIRECT arguments. */ if (func->op_array.arg_info[i].pass_by_reference) { return; } } if (fcall->extended_value < func->op_array.num_args) { /* don't inline funcions with named constants in default arguments */ i = fcall->extended_value; do { if (Z_CONSTANT_P(RT_CONSTANT(&func->op_array, func->op_array.opcodes[i].op2))) { return; } i++; } while (i < func->op_array.num_args); } if (RETURN_VALUE_USED(opline)) { zval zv; ZVAL_DUP(&zv, RT_CONSTANT(&func->op_array, ret_opline->op1)); opline->opcode = ZEND_QM_ASSIGN; opline->op1_type = IS_CONST; opline->op1.constant = zend_optimizer_add_literal(op_array, &zv); SET_UNUSED(opline->op2); } else { MAKE_NOP(opline); } zend_delete_call_instructions(opline-1); } } }
static void litespeed_php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; size_t alloc_size = sizeof(buf); unsigned long nlen; /* ptrdiff_t is not portable */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]); return; } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } tsrm_env_lock(); for (env = environ; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); if (!p) { /* malformed entry? */ continue; } nlen = p - *env; if (nlen >= alloc_size) { alloc_size = nlen + 64; t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size)); } memcpy(t, *env, nlen); t[nlen] = '\0'; add_variable(t, nlen, p + 1, strlen( p + 1 ), array_ptr); } tsrm_env_unlock(); if (t != buf && t != NULL) { efree(t); } }
int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) { zval *val; if ((val = zend_hash_find(constants, Z_STR_P(name))) != NULL) { ZVAL_DUP(value, val); return 1; } return 0; }
void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value) { zval val; if (!ctx->constants) { ctx->constants = zend_arena_alloc(&ctx->arena, sizeof(HashTable)); zend_hash_init(ctx->constants, 16, NULL, zend_optimizer_zval_dtor_wrapper, 0); } ZVAL_DUP(&val, value); zend_hash_add(ctx->constants, Z_STR_P(name), &val); }
/* {{{ cfg_get_double */ PHPAPI int cfg_get_double(const char *varname, double *result) { zval *tmp, var; if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) { *result = (double) 0; return FAILURE; } ZVAL_DUP(&var, tmp); convert_to_double(&var); *result = Z_DVAL(var); return SUCCESS; }
RedisArray * ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev, zend_bool b_index, zend_bool b_pconnect, long retry_interval, zend_bool b_lazy_connect, double connect_timeout) { int count = zend_hash_num_elements(hosts); /* create object */ RedisArray *ra = emalloc(sizeof(RedisArray)); ra->hosts = emalloc(count * sizeof(char*)); ra->redis = emalloc(count * sizeof(zval*)); ra->count = count; ra->z_multi_exec = NULL; ra->index = b_index; ra->auto_rehash = 0; ra->pconnect = b_pconnect; ra->connect_timeout = connect_timeout; /* init array data structures */ ra_init_function_table(ra); if (NULL == ra_load_hosts(ra, hosts, retry_interval, b_lazy_connect)) { return NULL; } ra->prev = hosts_prev ? ra_make_array(hosts_prev, z_fun, z_dist, NULL, b_index, b_pconnect, retry_interval, b_lazy_connect, connect_timeout) : NULL; /* copy function if provided */ if (z_fun) { ZVAL_DUP(&ra->z_fun, z_fun); } /* copy distributor if provided */ if (z_dist) { ZVAL_DUP(&ra->z_dist, z_dist); } return ra; }
/* {{{ MYSQLI_WARNING *php_new_warning */ static MYSQLI_WARNING *php_new_warning(const zval * reason, int errorno) { MYSQLI_WARNING *w; w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING)); ZVAL_DUP(&w->reason, (zval *)reason); convert_to_string(&w->reason); //????ZVAL_UTF8_STRINGL(&(w->reason), Z_STRVAL(w->reason), Z_STRLEN(w->reason), ZSTR_AUTOFREE); ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, Zzend_string_dupLICATE); w->errorno = errorno; return w; }
/* laod array from INI settings */ RedisArray *ra_load_array(const char *name) { zval z_params_hosts, *z_hosts; zval z_params_prev, *z_prev; zval z_params_funs, *z_data_p, z_fun, z_dist; zval z_params_index; zval z_params_autorehash; zval z_params_retry_interval; zval z_params_pconnect; zval z_params_connect_timeout; zval z_params_lazy_connect; RedisArray *ra = NULL; zend_bool b_index = 0, b_autorehash = 0, b_pconnect = 0; long l_retry_interval = 0; zend_bool b_lazy_connect = 0; double d_connect_timeout = 0; HashTable *hHosts = NULL, *hPrev = NULL; /* find entry */ if (!ra_find_name(name)) { return ra; } /* find hosts */ array_init(&z_params_hosts); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.hosts")), &z_params_hosts); if ((z_hosts = zend_hash_str_find(Z_ARRVAL(z_params_hosts), name, strlen(name))) != NULL ) { hHosts = Z_ARRVAL_P(z_hosts); } /* find previous hosts */ array_init(&z_params_prev); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.previous")), &z_params_prev); if ((z_prev = zend_hash_str_find(Z_ARRVAL(z_params_prev), name, strlen(name))) != NULL ) { hPrev = Z_ARRVAL_P(z_prev); } /* find function */ array_init(&z_params_funs); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.functions")), &z_params_funs); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_funs), name, strlen(name))) != NULL ) { ZVAL_DUP(&z_fun, z_data_p); } /* find distributor */ array_init(&z_params_funs); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.distributor")), &z_params_funs); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_funs), name, strlen(name))) != NULL ) { ZVAL_DUP(&z_dist, z_data_p); } /* find index option */ array_init(&z_params_index); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.index")), &z_params_index); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_index), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_STRING && strncmp(Z_STRVAL_P(z_data_p), "1", 1) == 0) { b_index = 1; } } /* find autorehash option */ array_init(&z_params_autorehash); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.autorehash")), &z_params_autorehash); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_autorehash), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_STRING && strncmp(Z_STRVAL_P(z_data_p), "1", 1) == 0) { b_autorehash = 1; } } /* find retry interval option */ array_init(&z_params_retry_interval); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.retryinterval")), &z_params_retry_interval); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_retry_interval), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_LONG || Z_TYPE_P(z_data_p) == IS_STRING) { if (Z_TYPE_P(z_data_p) == IS_LONG) { l_retry_interval = Z_LVAL_P(z_data_p); } else { l_retry_interval = atol(Z_STRVAL_P(z_data_p)); } } } /* find pconnect option */ array_init(&z_params_pconnect); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.pconnect")), &z_params_pconnect); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_pconnect), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_STRING && strncmp(Z_STRVAL_P(z_data_p), "1", 1) == 0) { b_pconnect = 1; } } /* find lazy connect option */ array_init(&z_params_lazy_connect); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.lazyconnect")), &z_params_lazy_connect); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_lazy_connect), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_STRING && strncmp(Z_STRVAL_P(z_data_p), "1", 1) == 0) { b_lazy_connect = 1; } } /* find connect timeout option */ array_init(&z_params_connect_timeout); sapi_module.treat_data(PARSE_STRING, estrdup(INI_STR("redis.arrays.connecttimeout")), &z_params_connect_timeout); if ((z_data_p = zend_hash_str_find(Z_ARRVAL(z_params_connect_timeout), name, strlen(name))) != NULL ) { if (Z_TYPE_P(z_data_p) == IS_DOUBLE || Z_TYPE_P(z_data_p) == IS_STRING) { if (Z_TYPE_P(z_data_p) == IS_DOUBLE) { d_connect_timeout = Z_DVAL_P(z_data_p); } else { d_connect_timeout = atof(Z_STRVAL_P(z_data_p)); } } } /* create RedisArray object */ ra = ra_make_array(hHosts, &z_fun, &z_dist, hPrev, b_index, b_pconnect, l_retry_interval, b_lazy_connect, d_connect_timeout); ra->auto_rehash = b_autorehash; if (ra->prev) ra->prev->auto_rehash = b_autorehash; /* cleanup */ zval_dtor(&z_params_hosts); efree(&z_params_hosts); zval_dtor(&z_params_prev); efree(&z_params_prev); zval_dtor(&z_params_funs); efree(&z_params_funs); zval_dtor(&z_params_index); efree(&z_params_index); zval_dtor(&z_params_autorehash); efree(&z_params_autorehash); zval_dtor(&z_params_retry_interval); efree(&z_params_retry_interval); zval_dtor(&z_params_pconnect); efree(&z_params_pconnect); zval_dtor(&z_params_connect_timeout); efree(&z_params_connect_timeout); zval_dtor(&z_params_lazy_connect); efree(&z_params_lazy_connect); return ra; }
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, size_t inquery_len, char **outquery, size_t *outquery_len) { Scanner s; char *ptr, *newbuffer; int t; int bindno = 0; int ret = 0; size_t newbuffer_len; HashTable *params; struct pdo_bound_param_data *param; int query_type = PDO_PLACEHOLDER_NONE; struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL; ptr = *outquery; s.cur = inquery; s.end = inquery + inquery_len + 1; /* phase 1: look for args */ while((t = scan(&s)) != PDO_PARSER_EOI) { if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) { if (t == PDO_PARSER_BIND) { int len = s.cur - s.tok; if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; } else { query_type |= PDO_PLACEHOLDER_POSITIONAL; } plc = emalloc(sizeof(*plc)); memset(plc, 0, sizeof(*plc)); plc->next = NULL; plc->pos = s.tok; plc->len = s.cur - s.tok; plc->bindno = bindno++; if (placetail) { placetail->next = plc; } else { placeholders = plc; } placetail = plc; } } if (bindno == 0) { /* nothing to do; good! */ return 0; } /* did the query make sense to me? */ if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) { /* they mixed both types; punt */ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters"); ret = -1; goto clean_up; } if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) { /* query matches native syntax */ ret = 0; goto clean_up; } if (stmt->named_rewrite_template) { /* magic/hack. * We we pretend that the query was positional even if * it was named so that we fall into the * named rewrite case below. Not too pretty, * but it works. */ query_type = PDO_PLACEHOLDER_POSITIONAL; } params = stmt->bound_params; /* Do we have placeholders but no bound params */ if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound"); ret = -1; goto clean_up; } if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { /* extra bit of validation for instances when same params are bound more than once */ if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) { int ok = 1; for (plc = placeholders; plc; plc = plc->next) { if ((param = zend_hash_str_find_ptr(params, plc->pos, plc->len)) == NULL) { ok = 0; break; } } if (ok) { goto safe; } } pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens"); ret = -1; goto clean_up; } safe: /* what are we going to do ? */ if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { /* query generation */ newbuffer_len = inquery_len; /* let's quote all the values */ for (plc = placeholders; plc; plc = plc->next) { if (query_type == PDO_PLACEHOLDER_POSITIONAL) { param = zend_hash_index_find_ptr(params, plc->bindno); } else { param = zend_hash_str_find_ptr(params, plc->pos, plc->len); } if (param == NULL) { /* parameter was not defined */ ret = -1; pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined"); goto clean_up; } if (stmt->dbh->methods->quoter) { zval *parameter; if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(parameter) == IS_RESOURCE) { php_stream *stm; php_stream_from_zval_no_verify(stm, parameter); if (stm) { zend_string *buf; buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0); if (!buf) { buf = ZSTR_EMPTY_ALLOC(); } if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen, param->param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); if (buf) { zend_string_release(buf); } goto clean_up; } if (buf) { zend_string_release(buf); } } else { pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource"); ret = -1; goto clean_up; } plc->freeq = 1; } else { zval tmp_param; ZVAL_DUP(&tmp_param, parameter); switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; plc->freeq = 0; break; case IS_FALSE: case IS_TRUE: convert_to_long(&tmp_param); /* fall through */ case IS_LONG: case IS_DOUBLE: convert_to_string(&tmp_param); plc->qlen = Z_STRLEN(tmp_param); plc->quoted = estrdup(Z_STRVAL(tmp_param)); plc->freeq = 1; break; default: convert_to_string(&tmp_param); if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); goto clean_up; } plc->freeq = 1; } zval_dtor(&tmp_param); } } else { zval *parameter; if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } plc->quoted = Z_STRVAL_P(parameter); plc->qlen = Z_STRLEN_P(parameter); } newbuffer_len += plc->qlen; } rewrite: /* allocate output buffer */ newbuffer = emalloc(newbuffer_len + 1); *outquery = newbuffer; /* and build the query */ plc = placeholders; ptr = inquery; do { t = plc->pos - ptr; if (t) { memcpy(newbuffer, ptr, t); newbuffer += t; } memcpy(newbuffer, plc->quoted, plc->qlen); newbuffer += plc->qlen; ptr = plc->pos + plc->len; plc = plc->next; } while (plc); t = (inquery + inquery_len) - ptr; if (t) { memcpy(newbuffer, ptr, t); newbuffer += t; } *newbuffer = '\0'; *outquery_len = newbuffer - *outquery; ret = 1; goto clean_up; } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) { /* rewrite ? to :pdoX */ char *name, *idxbuf; const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d"; int bind_no = 1; newbuffer_len = inquery_len; if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0); } for (plc = placeholders; plc; plc = plc->next) { int skip_map = 0; char *p; name = estrndup(plc->pos, plc->len); /* check if bound parameter is already available */ if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) { spprintf(&idxbuf, 0, tmpl, bind_no++); } else { idxbuf = estrdup(p); skip_map = 1; } plc->quoted = idxbuf; plc->qlen = strlen(plc->quoted); plc->freeq = 1; newbuffer_len += plc->qlen; if (!skip_map && stmt->named_rewrite_template) { /* create a mapping */ zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1); } /* map number to name */ zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1); efree(name); } goto rewrite; } else { /* rewrite :name to ? */ newbuffer_len = inquery_len; if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0); } for (plc = placeholders; plc; plc = plc->next) { char *name; name = estrndup(plc->pos, plc->len); zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1); efree(name); plc->quoted = "?"; plc->qlen = 1; } goto rewrite; } clean_up: while (placeholders) { plc = placeholders; placeholders = plc->next; if (plc->freeq) { efree(plc->quoted); } efree(plc); } return ret; }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, const char *key_prefix, size_t key_prefix_len, const char *key_suffix, size_t key_suffix_len, zval *type, char *arg_sep, int enc_type) { zend_string *key = NULL; char *newprefix, *p; const char *prop_name; size_t arg_sep_len, newprefix_len, prop_len; zend_ulong idx; zval *zdata = NULL, copyzval; if (!ht) { return FAILURE; } if (ht->u.v.nApplyCount > 0) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, zdata) { /* handling for private & protected object properties */ if (key) { if (key->val[0] == '\0' && type != NULL) { const char *tmp; zend_object *zobj = Z_OBJ_P(type); if (zend_check_property_access(zobj, key) != SUCCESS) { /* private or protected property access outside of the class */ continue; } zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = key->val; prop_len = key->len; } } else { prop_name = NULL; prop_len = 0; } ZVAL_DEREF(zdata); if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } newprefix_len = key_suffix_len + ekey->len + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ekey->val, ekey->len); p += ekey->len; zend_string_free(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { char *ekey; size_t ekey_len; /* Is an integer key */ ekey_len = spprintf(&ekey, 0, "%pd", idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } if (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount++; } php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); if (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount--; } efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->s) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } smart_str_append(formstr, ekey); zend_string_free(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } smart_str_append_long(formstr, idx); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_P(zdata)) { case IS_STRING: { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } else { ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } smart_str_append(formstr, ekey); zend_string_free(ekey); } break; case IS_LONG: smart_str_append_long(formstr, Z_LVAL_P(zdata)); break; case IS_FALSE: smart_str_appendl(formstr, "0", sizeof("0")-1); break; case IS_TRUE: smart_str_appendl(formstr, "1", sizeof("1")-1); break; case IS_DOUBLE: { char *ekey; size_t ekey_len; ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata)); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } break; default: { zend_string *ekey; /* fall back on convert to string */ ZVAL_DUP(©zval, zdata); convert_to_string_ex(©zval); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } else { ekey = php_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } smart_str_append(formstr, ekey); zval_ptr_dtor(©zval); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END(); return SUCCESS; }
/* {{{ my_copy_zval */ static APC_HOTSPOT void my_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt) { apc_pool* pool = ctxt->pool; assert(dst != NULL); assert(src != NULL); memcpy(dst, src, sizeof(zval)); if (Z_REFCOUNTED_P(src)) { if (zend_hash_num_elements(&ctxt->copied)) { zval *rc = zend_hash_index_find( &ctxt->copied, (uintptr_t) Z_COUNTED_P(src)); if (rc) { ZVAL_COPY(dst, rc); return; } } } switch (Z_TYPE_P(src)) { case IS_RESOURCE: case IS_TRUE: case IS_FALSE: case IS_LONG: case IS_DOUBLE: case IS_NULL: break; case IS_REFERENCE: Z_REF_P(dst) = my_copy_reference(Z_REF_P(src), ctxt); break; case IS_INDIRECT: my_copy_zval(dst, Z_INDIRECT_P(src), ctxt); break; case IS_CONSTANT: case IS_STRING: if (ctxt->copy == APC_COPY_OUT) { ZVAL_DUP(dst, src); } else { Z_TYPE_INFO_P(dst) = IS_STRING_EX; Z_STR_P(dst) = apc_pstrcpy(Z_STR_P(src), pool); } break; case IS_ARRAY: if(ctxt->serializer == NULL) { Z_ARRVAL_P(dst) = my_copy_hashtable(Z_ARRVAL_P(src), ctxt); break; } /* break intentionally omitted */ case IS_OBJECT: if(ctxt->copy == APC_COPY_IN) { dst = my_serialize_object(dst, src, ctxt); } else dst = my_unserialize_object(dst, src, ctxt); break; case IS_CALLABLE: /* XXX implement this */ assert(0); break; default: assert(0); } if (Z_REFCOUNTED_P(dst) && ctxt->copied.nTableSize) { zend_hash_index_update(&ctxt->copied, (uintptr_t) Z_COUNTED_P(src), dst); } }
static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_headers, struct curl_pushheaders *push_headers, void *userp) /* {{{ */ { php_curl *ch; php_curl *parent; php_curlm *mh = (php_curlm *)userp; size_t rval = CURL_PUSH_DENY; php_curlm_server_push *t = mh->handlers->server_push; zval *pz_parent_ch = NULL; zval pz_ch; zval headers; zval retval; zend_resource *res; char *header; int error; zend_fcall_info fci = empty_fcall_info; pz_parent_ch = _php_curl_multi_find_easy_handle(mh, parent_ch); if (pz_parent_ch == NULL) { return rval; } parent = (php_curl*)zend_fetch_resource(Z_RES_P(pz_parent_ch), le_curl_name, le_curl); ch = alloc_curl_handle(); ch->cp = easy; _php_setup_easy_copy_handlers(ch, parent); Z_ADDREF_P(pz_parent_ch); res = zend_register_resource(ch, le_curl); ZVAL_RES(&pz_ch, res); size_t i; array_init(&headers); for(i=0; i<num_headers; i++) { header = curl_pushheader_bynum(push_headers, i); add_next_index_string(&headers, header); } zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL); zend_fcall_info_argn( &fci, 3, pz_parent_ch, &pz_ch, &headers ); fci.retval = &retval; error = zend_call_function(&fci, &t->fci_cache); zend_fcall_info_args_clear(&fci, 1); zval_dtor(&headers); if (error == FAILURE) { php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION"); } else if (!Z_ISUNDEF(retval)) { if (CURL_PUSH_DENY != zval_get_long(&retval)) { rval = CURL_PUSH_OK; /* we want to create a copy of this zval that we store in the multihandle structure element "easyh" */ zval tmp_val; ZVAL_DUP(&tmp_val, &pz_ch); zend_llist_add_element(&mh->easyh, &tmp_val); } else { /* libcurl will free this easy handle, avoid double free */ ch->cp = NULL; } } return rval; }