Beispiel #1
0
void mysqlnd_alloc_zval_ptr_dtor(zval **zv, MYSQLND_ZVAL_CACHE * const cache)
{
	if (!cache || Z_REFCOUNT_PP(zv) > 1 || cache->max_items == cache->free_items) {
#ifndef MYSQLND_SILENT
		php_printf("[mysqlnd_alloc_zval_ptr_dtor %p]1 last_added-1=%p *zv=%p\n", cache->free_list->last_added, *zv);
#endif
		/* We can't cache zval's with refcount > 1 */
		zval_ptr_dtor(zv);
		if (cache) {
			if (cache->max_items == cache->free_items) {
				++cache->put_full_misses;
			} else {
				++cache->put_refcount_misses;
			}
		}
	} else {
		/* refcount is 1 and there is place. Go, cache it! */
		++cache->free_items;
		zval_dtor(*zv);
		ZVAL_NULL(*zv);
		*(--cache->free_list->last_added) = *zv;
		++cache->put_hits;
	}
#ifndef MYSQLND_SILENT
	php_printf("[mysqlnd_alloc_zval_ptr_dtor %p] free_items=%d\n", cache, cache->free_items);
#endif
}
Beispiel #2
0
/**
 * Updates values on arrays by long indexes only
 */
int phalcon_array_update_long(zval **arr, ulong index, zval **value, int flags TSRMLS_DC){

	if (Z_TYPE_PP(arr) != IS_ARRAY) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
		return FAILURE;
	}

	if ((flags & PH_CTOR) == PH_CTOR) {
		zval *new_zv;
		Z_DELREF_PP(value);
		ALLOC_ZVAL(new_zv);
		INIT_PZVAL_COPY(new_zv, *value);
		*value = new_zv;
		zval_copy_ctor(new_zv);
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
	    }
	}

	if ((flags & PH_COPY) == PH_COPY) {
		Z_ADDREF_PP(value);
	}

	return zend_hash_index_update(Z_ARRVAL_PP(arr), index, value, sizeof(zval *), NULL);
}
Beispiel #3
0
/**
 * Updates values on arrays by string or long indexes
 */
int phalcon_array_update_zval(zval **arr, zval *index, zval **value, int flags TSRMLS_DC){

	if (Z_TYPE_PP(arr) != IS_ARRAY) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
		return FAILURE;
	}

	if (Z_TYPE_P(index) == IS_NULL) {
		convert_to_string(index);
	} else {
		if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) {
			convert_to_long(index);
		}
	}

	if ((flags & PH_CTOR) == PH_CTOR) {
		zval *new_zv;
		Z_DELREF_PP(value);
		ALLOC_ZVAL(new_zv);
		INIT_PZVAL_COPY(new_zv, *value);
		*value = new_zv;
		zval_copy_ctor(new_zv);
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
	    }
	}

	if ((flags & PH_COPY) == PH_COPY) {
		Z_ADDREF_PP(value);
	}

 	if(Z_TYPE_P(index) == IS_STRING){
		return zend_hash_update(Z_ARRVAL_PP(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1, value, sizeof(zval *), NULL);
	} else {
		if (Z_TYPE_P(index) == IS_LONG) {
			return zend_hash_index_update(Z_ARRVAL_PP(arr), Z_LVAL_P(index), value, sizeof(zval *), NULL);
		} else {
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Illegal offset type");
		}
	}

	return FAILURE;
}
Beispiel #4
0
/**
 * Unsets zval index from array
 */
int PHALCON_FASTCALL phalcon_array_unset(zval **arr, zval *index, int flags) {

	zval *copy;
	int exists, copied = 0;

	if (Z_TYPE_PP(arr) != IS_ARRAY) {
		return 0;
	}

	if (Z_TYPE_P(index) == IS_NULL) {
		ALLOC_INIT_ZVAL(copy);
		ZVAL_ZVAL(copy, index, 1, 0);
		convert_to_string(copy);
		index = copy;
		copied = 1;
	} else {
		if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) {
			ALLOC_INIT_ZVAL(copy);
			ZVAL_ZVAL(copy, index, 1, 0);
			convert_to_long(copy);
			index = copy;
			copied = 1;
		}
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
		}
	}

	if (Z_TYPE_P(index) == IS_STRING) {
		exists = zend_hash_del(Z_ARRVAL_PP(arr), Z_STRVAL_P(index), Z_STRLEN_P(index) + 1);
	} else {
		exists = zend_hash_index_del(Z_ARRVAL_PP(arr), Z_LVAL_P(index));
	}

	if (copied) {
		zval_ptr_dtor(&copy);
	}

	return exists;
}
Beispiel #5
0
/**
 * Push one or more elements onto the end of an array
 */
int phalcon_array_append(zval **arr, zval *value, int flags TSRMLS_DC){
	if (Z_TYPE_PP(arr) == IS_ARRAY) {
		if((flags & PH_SEPARATE) == PH_SEPARATE){
			if (Z_REFCOUNT_PP(arr) > 1) {
				zval *new_zv;
				Z_DELREF_PP(arr);
				ALLOC_ZVAL(new_zv);
				INIT_PZVAL_COPY(new_zv, *arr);
				*arr = new_zv;
				zval_copy_ctor(new_zv);
			}
		}
		Z_ADDREF_P(value);
		return add_next_index_zval(*arr, value);
	} else {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
	}
	return FAILURE;
}
Beispiel #6
0
/**
 * Unsets long index from array
 */
int PHALCON_FASTCALL phalcon_array_unset_long(zval **arr, unsigned long index, int flags) {

	if (Z_TYPE_PP(arr) != IS_ARRAY) {
		return 0;
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
		}
	}

	return zend_hash_index_del(Z_ARRVAL_PP(arr), index);
}
Beispiel #7
0
void ptask_thread_fn(void *arg)
{
    struct ptask_ctx *ctx = (struct ptask_ctx *)arg;
    zval fname, retval;
    zval *params[1];

    ZVAL_STRING(&fname, ctx->func, 0); /* create new function name zval */

    params[0] = ctx->arg;

    TSRMLS_FETCH();
    call_user_function(EG(function_table), NULL, &fname,
        &retval, 1, params TSRMLS_CC);

    /* free all memory */
    Z_DELREF_PP(&(ctx->arg));
    if (Z_REFCOUNT_PP(&(ctx->arg)) == 0) {
        zval_dtor(ctx->arg);
    }
    efree(ctx->func);
    efree(ctx);
}
Beispiel #8
0
/**
 * Restore a memory stack applying GC to all observed variables
 */
static void zephir_memory_restore_stack_common(zend_zephir_globals_def *g)
{
	size_t i;
	zephir_memory_entry *prev, *active_memory;
	zephir_symbol_table *active_symbol_table;
	zval *ptr;
#ifndef ZEPHIR_RELEASE
	int show_backtrace = 0;
#endif

	active_memory = g->active_memory;
	assert(active_memory != NULL);

	if (EXPECTED(!CG(unclean_shutdown))) {
		/* Clean active symbol table */
		if (g->active_symbol_table) {
			active_symbol_table = g->active_symbol_table;
			if (active_symbol_table->scope == active_memory) {
				zend_execute_data *ex = EG(current_execute_data);
				//zend_hash_destroy(EG(current_execute_data)->symbol_table);
				//FREE_HASHTABLE(EG(current_execute_data)->symbol_table);
				//EG(current_execute_data)->symbol_table = active_symbol_table->symbol_table;
				ex->symbol_table = active_symbol_table->symbol_table;
				g->active_symbol_table = active_symbol_table->prev;
				efree(active_symbol_table);
			}
		}

		/* Check for non freed hash key zvals, mark as null to avoid string freeing */
		for (i = 0; i < active_memory->hash_pointer; ++i) {
			assert(active_memory->hash_addresses[i] != NULL);
			if (!Z_REFCOUNTED_P(active_memory->hash_addresses[i])) continue;
			if (Z_REFCOUNT_P(active_memory->hash_addresses[i]) <= 1) {
				ZVAL_NULL(active_memory->hash_addresses[i]);
			} else {
				zval_copy_ctor(active_memory->hash_addresses[i]);
			}
		}

#ifndef ZEPHIR_RELEASE
		for (i = 0; i < active_memory->pointer; ++i) {
			if (active_memory->addresses[i] != NULL) {
				zval *var = active_memory->addresses[i];
				if (Z_TYPE_P(var) > IS_CALLABLE) {
					fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func);
					show_backtrace = 1;
				}

				if (!Z_REFCOUNTED_P(var)) {
					continue;
				}

				if (Z_REFCOUNT_P(var) == 0) {
					fprintf(stderr, "%s: observed variable #%d (%p) has 0 references, type=%d [%s]\n", __func__, (int)i, var, Z_TYPE_P(var), active_memory->func);
					show_backtrace = 1;
				}
				else if (Z_REFCOUNT_P(var) >= 1000000) {
					fprintf(stderr, "%s: observed variable #%d (%p) has too many references (%u), type=%d  [%s]\n", __func__, (int)i, var, Z_REFCOUNT_P(var), Z_TYPE_P(var), active_memory->func);
					show_backtrace = 1;
				}
#if 0
				/* Skip this check, PDO does return variables with is_ref = 1 and refcount = 1*/
				else if (Z_REFCOUNT_PP(var) == 1 && Z_ISREF_PP(var)) {
					fprintf(stderr, "%s: observed variable #%d (%p) is a reference with reference count = 1, type=%d  [%s]\n", __func__, (int)i, *var, Z_TYPE_PP(var), active_memory->func);
				}
#endif
			}
		}
#endif

		/* Traverse all zvals allocated, reduce the reference counting or free them */
		for (i = 0; i < active_memory->pointer; ++i) {
			ptr = active_memory->addresses[i];
			if (EXPECTED(ptr != NULL)) {
				if (!Z_REFCOUNTED_P(ptr)) continue;
				if (Z_REFCOUNT_P(ptr) == 1) {
					zval_ptr_dtor(ptr);
				} else {
					Z_DELREF_P(ptr);
				}
			}
		}
	}

#ifndef ZEPHIR_RELEASE
	active_memory->func = NULL;
#endif

	prev = active_memory->prev;

	if (active_memory >= g->end_memory || active_memory < g->start_memory) {
#ifndef ZEPHIR_RELEASE
		assert(g->active_memory->permanent == 0);
#endif
		assert(prev != NULL);

		if (active_memory->hash_addresses != NULL) {
			efree(active_memory->hash_addresses);
		}

		if (active_memory->addresses != NULL) {
			efree(active_memory->addresses);
		}

		efree(g->active_memory);
		g->active_memory = prev;
		prev->next = NULL;
	} else {
#ifndef ZEPHIR_RELEASE
		assert(g->active_memory->permanent == 1);
#endif
		active_memory->pointer      = 0;
		active_memory->hash_pointer = 0;
		g->active_memory = prev;
	}

#ifndef ZEPHIR_RELEASE
	if (g->active_memory) {
		zephir_memory_entry *f = g->active_memory;
		if (f >= g->start_memory && f < g->end_memory - 1) {
			assert(f->permanent == 1);
			assert(f->next != NULL);

			if (f > g->start_memory) {
				assert(f->prev != NULL);
			}
		}
	}

	if (show_backtrace == 1) {
		zephir_print_backtrace();
	}
#endif

}
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval)
{
	var_dtor_entries *var_hash = (*var_hashx)->last_dtor;
#if VAR_ENTRIES_DBG
	fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
#endif

	if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
		var_hash = emalloc(sizeof(var_dtor_entries));
		var_hash->used_slots = 0;
		var_hash->next = 0;

		if (!(*var_hashx)->first_dtor) {
			(*var_hashx)->first_dtor = var_hash;
		} else {
			((var_entries *) (*var_hashx)->last_dtor)->next = var_hash;
		}

		(*var_hashx)->last_dtor = var_hash;
	}

	ZVAL_COPY_VALUE(&var_hash->data[var_hash->used_slots], rval);
	var_hash->used_slots++;
}
Beispiel #10
0
	ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_protocolbuffers_helper_zigzag_decode64, 0, 0, 1)
	ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()

static void php_protocolbuffers_helper_debug_zval(zval **value TSRMLS_DC)
{
	zval *val = *value;

	php_printf("{\n");
	php_printf("  address: 0x%x,\n", (unsigned int)val);
	php_printf("  type: %d,\n", val->type);
	php_printf("  is_ref: %d,\n", PZVAL_IS_REF(val));
	php_printf("  refcount: %d,\n", Z_REFCOUNT_PP(value));
	php_printf("  value: {\n");
	php_printf("    lval: %ld,\n", val->value.lval);
	php_printf("    double: %f,\n", val->value.dval);
	if (val->type == 4) {
		php_printf("    ht: {\n");
		php_printf("      address: 0x%x,\n", (unsigned int)val->value.ht);
		php_printf("      num_of_elements: %d,\n", (unsigned int)val->value.ht->nNumOfElements);
		php_printf("      next_free_elements: %d,\n", (unsigned int)val->value.ht->nNextFreeElement);
		php_printf("    },\n");
	}
	php_printf("    object: {\n");
	php_printf("      handle: 0x%x,\n", val->value.obj.handle);
	php_printf("      handlers: 0x%x,\n", (unsigned int)val->value.obj.handlers);
	php_printf("    },\n");
	php_printf("  }\n");
static HashTable *php_runkit_sandbox_parent_resolve_symbol_table(php_runkit_sandbox_parent_object *objval)
{
	int i;
	HashTable *oldActiveSymbolTable, *result;
	zend_execute_data *oldCurExData;
	zend_execute_data *ex = EG(current_execute_data);

	if (!EG(active_symbol_table)) {
		zend_rebuild_symbol_table();
	}

	if (objval->self->parent_scope <= 0) {
		HashTable *ht = &EG(symbol_table);

		if (objval->self->parent_scope_name) {
			zval **symtable;

			if ((symtable = zend_hash_str_find(ht, objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1)) != NULL) {
				if (Z_TYPE_PP(symtable) == IS_ARRAY) {
					ht = Z_ARRVAL_PP(symtable);
				} else {
					/* Variable exists but is not an array,
					 * Make a dummy array that contains this var */
					zval *hidden;

					ALLOC_INIT_ZVAL(hidden);
					array_init(hidden);
					ht = Z_ARRVAL_P(hidden);
					if (Z_REFCOUNT_PP(symtable) > 1 &&
						!(*symtable)->RUNKIT_IS_REF) {
						zval *cv;

						MAKE_STD_ZVAL(cv);
						*cv = **symtable;
						zval_copy_ctor(cv);
						zval_ptr_dtor(symtable);
						INIT_PZVAL(cv);
						*symtable = cv;
					}
					(*symtable)->RUNKIT_IS_REF = 1;
					(*symtable)->RUNKIT_REFCOUNT++;  // TODO fix
					zend_hash_update(ht, objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1, (void*)symtable, sizeof(zval*), NULL);

					/* Store that dummy array in the sandbox's hidden properties table so that it gets cleaned up on dtor */
					zend_hash_update(objval->obj.properties, "scope", sizeof("scope"), (void*)&hidden, sizeof(zval*), NULL);
				}
			} else {
				/* Create variable as an array */
				zval *newval;

				ALLOC_INIT_ZVAL(newval);
				array_init(newval);
				zend_hash_update(&EG(symbol_table), objval->self->parent_scope_name, objval->self->parent_scope_namelen + 1, (void*)&newval, sizeof(zval*), NULL);
				ht = Z_ARRVAL_P(newval);
			}
		}

		return ht;
	}

	if (objval->self->parent_scope == 1) {
		return EG(active_symbol_table);
	}

	for(i = 1; i < objval->self->parent_scope; i++) {
		if (!ex->prev_execute_data) {
			/* Symbol table exceeded */
			return &EG(symbol_table);
		}
		ex = ex->prev_execute_data;
	}

	oldActiveSymbolTable = EG(active_symbol_table);
	EG(active_symbol_table) = NULL;
	oldCurExData = EG(current_execute_data);
	EG(current_execute_data) = ex;
	zend_rebuild_symbol_table();
	result = EG(active_symbol_table);
	EG(active_symbol_table) = oldActiveSymbolTable;
	EG(current_execute_data) = oldCurExData;
	return result;
}