示例#1
0
ONPHP_METHOD(Joiner, getTablesCount)
{
	zval *tables = ONPHP_READ_PROPERTY(getThis(), "tables");
	
	RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(tables)));
}
示例#2
0
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
	zend_op *opline, *end;
	int i, j, n, *map, cache_size;
	zval zv, *pos;
	literal_info *info;
	int l_null = -1;
	int l_false = -1;
	int l_true = -1;
	int l_empty_arr = -1;
	HashTable hash;
	zend_string *key = NULL;
	void *checkpoint = zend_arena_checkpoint(ctx->arena);
	int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;

	if (op_array->last_literal) {
		info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info));

	    /* Mark literals of specific types */
		opline = op_array->opcodes;
		end = opline + op_array->last;
		while (opline < end) {
			switch (opline->opcode) {
				case ZEND_INIT_FCALL:
					LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1);
					break;
				case ZEND_INIT_FCALL_BY_NAME:
					LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 2);
					break;
				case ZEND_INIT_NS_FCALL_BY_NAME:
					LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 3);
					break;
				case ZEND_INIT_METHOD_CALL:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
					}
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_METHOD, 2);
					}
					break;
				case ZEND_INIT_STATIC_METHOD_CALL:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2);
					}
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_STATIC_METHOD, 2);
					}
					break;
				case ZEND_CATCH:
					LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2);
					break;
				case ZEND_DEFINED:
					LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 2);
					break;
				case ZEND_FETCH_CONSTANT:
					if ((opline->op1.num & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
						LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 5);
					} else {
						LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 3);
					}
					break;
				case ZEND_FETCH_CLASS_CONSTANT:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2);
					}
					LITERAL_INFO(opline->op2.constant, LITERAL_CLASS_CONST, 1);
					break;
				case ZEND_FETCH_STATIC_PROP_R:
				case ZEND_FETCH_STATIC_PROP_W:
				case ZEND_FETCH_STATIC_PROP_RW:
				case ZEND_FETCH_STATIC_PROP_IS:
				case ZEND_FETCH_STATIC_PROP_UNSET:
				case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
				case ZEND_UNSET_STATIC_PROP:
				case ZEND_ISSET_ISEMPTY_STATIC_PROP:
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2);
					}
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_STATIC_PROPERTY, 1);
					}
					break;
				case ZEND_FETCH_CLASS:
				case ZEND_INSTANCEOF:
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2);
					}
					break;
				case ZEND_NEW:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2);
					}
					break;
				case ZEND_ASSIGN_OBJ:
				case ZEND_FETCH_OBJ_R:
				case ZEND_FETCH_OBJ_W:
				case ZEND_FETCH_OBJ_RW:
				case ZEND_FETCH_OBJ_IS:
				case ZEND_FETCH_OBJ_UNSET:
				case ZEND_FETCH_OBJ_FUNC_ARG:
				case ZEND_UNSET_OBJ:
				case ZEND_PRE_INC_OBJ:
				case ZEND_PRE_DEC_OBJ:
				case ZEND_POST_INC_OBJ:
				case ZEND_POST_DEC_OBJ:
				case ZEND_ISSET_ISEMPTY_PROP_OBJ:
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
					}
					break;
				case ZEND_ASSIGN_ADD:
				case ZEND_ASSIGN_SUB:
				case ZEND_ASSIGN_MUL:
				case ZEND_ASSIGN_DIV:
				case ZEND_ASSIGN_POW:
				case ZEND_ASSIGN_MOD:
				case ZEND_ASSIGN_SL:
				case ZEND_ASSIGN_SR:
				case ZEND_ASSIGN_CONCAT:
				case ZEND_ASSIGN_BW_OR:
				case ZEND_ASSIGN_BW_AND:
				case ZEND_ASSIGN_BW_XOR:
					if (opline->op2_type == IS_CONST) {
						if (opline->extended_value == ZEND_ASSIGN_OBJ) {
							LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
						} else if (opline->extended_value == ZEND_ASSIGN_DIM) {
							if (Z_EXTRA(op_array->literals[opline->op2.constant]) == ZEND_EXTRA_VALUE) {
								LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
							} else {
								LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
							}
						} else {
							LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
						}
					}
					break;
				case ZEND_BIND_GLOBAL:
					LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 1);
					break;
				case ZEND_RECV_INIT:
					LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
					break;
				case ZEND_DECLARE_FUNCTION:
				case ZEND_DECLARE_CLASS:
					LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2);
					break;
				case ZEND_DECLARE_INHERITED_CLASS:
				case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
					LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2);
					LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
					break;
				case ZEND_DECLARE_ANON_INHERITED_CLASS:
					LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
					LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
					break;
				case ZEND_ISSET_ISEMPTY_DIM_OBJ:
				case ZEND_ASSIGN_DIM:
				case ZEND_UNSET_DIM:
				case ZEND_FETCH_DIM_R:
				case ZEND_FETCH_DIM_W:
				case ZEND_FETCH_DIM_RW:
				case ZEND_FETCH_DIM_IS:
				case ZEND_FETCH_DIM_FUNC_ARG:
				case ZEND_FETCH_DIM_UNSET:
				case ZEND_FETCH_LIST_R:
				case ZEND_FETCH_LIST_W:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
					}
					if (opline->op2_type == IS_CONST) {
						if (Z_EXTRA(op_array->literals[opline->op2.constant]) == ZEND_EXTRA_VALUE) {
							LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
						} else {
							LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
						}
					}
					break;
				default:
					if (opline->op1_type == IS_CONST) {
						LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
					}
					if (opline->op2_type == IS_CONST) {
						LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
					}
					break;
			}
			opline++;
		}

#if DEBUG_COMPACT_LITERALS
		{
			int i, use_copy;
			fprintf(stderr, "File %s func %s\n", op_array->filename->val,
					op_array->function_name ? op_array->function_name->val : "main");
			fprintf(stderr, "Literlas table size %d\n", op_array->last_literal);

			for (i = 0; i < op_array->last_literal; i++) {
				zval zv;
				ZVAL_COPY_VALUE(&zv, op_array->literals + i);
				use_copy = zend_make_printable_zval(op_array->literals + i, &zv);
				fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv));
				if (use_copy) {
					zval_ptr_dtor_nogc(&zv);
				}
			}
			fflush(stderr);
		}
#endif

		/* Merge equal constants */
		j = 0;
		zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0);
		map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int));
		memset(map, 0, op_array->last_literal * sizeof(int));
		for (i = 0; i < op_array->last_literal; i++) {
			if (!info[i].flags) {
				/* unset literal */
				zval_ptr_dtor_nogc(&op_array->literals[i]);
				continue;
			}
			switch (Z_TYPE(op_array->literals[i])) {
				case IS_NULL:
					if (l_null < 0) {
						l_null = j;
						if (i != j) {
							op_array->literals[j] = op_array->literals[i];
							info[j] = info[i];
						}
						j++;
					}
					map[i] = l_null;
					break;
				case IS_FALSE:
					if (l_false < 0) {
						l_false = j;
						if (i != j) {
							op_array->literals[j] = op_array->literals[i];
							info[j] = info[i];
						}
						j++;
					}
					map[i] = l_false;
					break;
				case IS_TRUE:
					if (l_true < 0) {
						l_true = j;
						if (i != j) {
							op_array->literals[j] = op_array->literals[i];
							info[j] = info[i];
						}
						j++;
					}
					map[i] = l_true;
					break;
				case IS_LONG:
					if (LITERAL_NUM_RELATED(info[i].flags) == 1) {
						if ((pos = zend_hash_index_find(&hash, Z_LVAL(op_array->literals[i]))) != NULL) {
							map[i] = Z_LVAL_P(pos);
						} else {
							map[i] = j;
							ZVAL_LONG(&zv, j);
							zend_hash_index_add_new(&hash, Z_LVAL(op_array->literals[i]), &zv);
							if (i != j) {
								op_array->literals[j] = op_array->literals[i];
								info[j] = info[i];
							}
							j++;
						}
					} else {
						ZEND_ASSERT(LITERAL_NUM_RELATED(info[i].flags) == 2);
						key = zend_string_init(Z_STRVAL(op_array->literals[i+1]), Z_STRLEN(op_array->literals[i+1]), 0);
						ZSTR_H(key) = ZSTR_HASH(Z_STR(op_array->literals[i+1])) + 100 +
							LITERAL_NUM_RELATED(info[i].flags) - 1;
						if ((pos = zend_hash_find(&hash, key)) != NULL
						 && LITERAL_NUM_RELATED(info[Z_LVAL_P(pos)].flags) == 2) {
							map[i] = Z_LVAL_P(pos);
							zval_ptr_dtor_nogc(&op_array->literals[i+1]);
						} else {
							map[i] = j;
							ZVAL_LONG(&zv, j);
							zend_hash_add_new(&hash, key, &zv);
							if (i != j) {
								op_array->literals[j] = op_array->literals[i];
								info[j] = info[i];
								op_array->literals[j+1] = op_array->literals[i+1];
								info[j+1] = info[i+1];
							}
							j += 2;
						}
						zend_string_release_ex(key, 0);
						i++;
					}
					break;
				case IS_DOUBLE:
					if ((pos = zend_hash_str_find(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != NULL) {
						map[i] = Z_LVAL_P(pos);
					} else {
						map[i] = j;
						ZVAL_LONG(&zv, j);
						zend_hash_str_add(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), &zv);
						if (i != j) {
							op_array->literals[j] = op_array->literals[i];
							info[j] = info[i];
						}
						j++;
					}
					break;
				case IS_STRING:
					if (LITERAL_NUM_RELATED(info[i].flags) == 1) {
						key = zend_string_copy(Z_STR(op_array->literals[i]));
					} else {
						key = zend_string_init(Z_STRVAL(op_array->literals[i]), Z_STRLEN(op_array->literals[i]), 0);
						ZSTR_H(key) = ZSTR_HASH(Z_STR(op_array->literals[i])) +
							LITERAL_NUM_RELATED(info[i].flags) - 1;
					}
					pos = zend_hash_find(&hash, key);
					if (pos != NULL &&
					    Z_TYPE(op_array->literals[Z_LVAL_P(pos)]) == IS_STRING &&
					    LITERAL_NUM_RELATED(info[i].flags) == LITERAL_NUM_RELATED(info[Z_LVAL_P(pos)].flags) &&
					    (LITERAL_NUM_RELATED(info[i].flags) != 2 ||
					     ((info[i].flags & LITERAL_KIND_MASK) != LITERAL_VALUE &&
					      (info[Z_LVAL_P(pos)].flags & LITERAL_KIND_MASK) != LITERAL_VALUE))) {
						zend_string_release_ex(key, 0);
						map[i] = Z_LVAL_P(pos);
						zval_ptr_dtor_nogc(&op_array->literals[i]);
						n = LITERAL_NUM_RELATED(info[i].flags);
						while (n > 1) {
							i++;
							zval_ptr_dtor_nogc(&op_array->literals[i]);
							n--;
						}
					} else {
						map[i] = j;
						ZVAL_LONG(&zv, j);
						zend_hash_add_new(&hash, key, &zv);
						zend_string_release_ex(key, 0);
						if (i != j) {
							op_array->literals[j] = op_array->literals[i];
							info[j] = info[i];
						}
						j++;
						n = LITERAL_NUM_RELATED(info[i].flags);
						while (n > 1) {
							i++;
							if (i != j) op_array->literals[j] = op_array->literals[i];
							j++;
							n--;
						}
					}
					break;
				case IS_ARRAY:
					if (zend_hash_num_elements(Z_ARRVAL(op_array->literals[i])) == 0) {
						if (l_empty_arr < 0) {
							l_empty_arr = j;
							if (i != j) {
								op_array->literals[j] = op_array->literals[i];
								info[j] = info[i];
							}
							j++;
						} else {
							zval_ptr_dtor_nogc(&op_array->literals[i]);
						}
						map[i] = l_empty_arr;
						break;
					}
					/* break missing intentionally */
				default:
					/* don't merge other types */
					map[i] = j;
					if (i != j) {
						op_array->literals[j] = op_array->literals[i];
						info[j] = info[i];
					}
					j++;
					break;
			}
		}
		zend_hash_clean(&hash);
		op_array->last_literal = j;

		const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
		memset(const_slot, -1, j * 6 * sizeof(int));
		class_slot = const_slot + j;
		func_slot = class_slot + j;
		bind_var_slot = func_slot + j;
		property_slot = bind_var_slot + j;
		method_slot = property_slot + j;

		/* Update opcodes to use new literals table */
		cache_size = 0;
		opline = op_array->opcodes;
		end = opline + op_array->last;
		while (opline < end) {
			if (opline->op1_type == IS_CONST) {
				opline->op1.constant = map[opline->op1.constant];
			}
			if (opline->op2_type == IS_CONST) {
				opline->op2.constant = map[opline->op2.constant];
			}
			switch (opline->opcode) {
				case ZEND_RECV_INIT:
					if (class_name_type_hint(op_array, opline->op1.num)) {
						opline->extended_value = cache_size;
						cache_size += sizeof(void *);
					}
					break;
				case ZEND_RECV:
				case ZEND_RECV_VARIADIC:
					if (class_name_type_hint(op_array, opline->op1.num)) {
						opline->op2.num = cache_size;
						cache_size += sizeof(void *);
					}
					break;
				case ZEND_VERIFY_RETURN_TYPE:
					if (class_name_type_hint(op_array, 0)) {
						opline->op2.num = cache_size;
						cache_size += sizeof(void *);
					}
					break;
				case ZEND_ASSIGN_ADD:
				case ZEND_ASSIGN_SUB:
				case ZEND_ASSIGN_MUL:
				case ZEND_ASSIGN_DIV:
				case ZEND_ASSIGN_POW:
				case ZEND_ASSIGN_MOD:
				case ZEND_ASSIGN_SL:
				case ZEND_ASSIGN_SR:
				case ZEND_ASSIGN_CONCAT:
				case ZEND_ASSIGN_BW_OR:
				case ZEND_ASSIGN_BW_AND:
				case ZEND_ASSIGN_BW_XOR:
					if (opline->extended_value != ZEND_ASSIGN_OBJ) {
						break;
					}
					if (opline->op2_type == IS_CONST) {
						// op2 property
						if (opline->op1_type == IS_UNUSED &&
						    property_slot[opline->op2.constant] >= 0) {
							(opline+1)->extended_value = property_slot[opline->op2.constant];
						} else {
							(opline+1)->extended_value = cache_size;
							cache_size += 2 * sizeof(void *);
							if (opline->op1_type == IS_UNUSED) {
								property_slot[opline->op2.constant] = (opline+1)->extended_value;
							}
						}
					}
					break;
				case ZEND_ASSIGN_OBJ:
				case ZEND_FETCH_OBJ_R:
				case ZEND_FETCH_OBJ_W:
				case ZEND_FETCH_OBJ_RW:
				case ZEND_FETCH_OBJ_IS:
				case ZEND_FETCH_OBJ_UNSET:
				case ZEND_FETCH_OBJ_FUNC_ARG:
				case ZEND_UNSET_OBJ:
				case ZEND_PRE_INC_OBJ:
				case ZEND_PRE_DEC_OBJ:
				case ZEND_POST_INC_OBJ:
				case ZEND_POST_DEC_OBJ:
					if (opline->op2_type == IS_CONST) {
						// op2 property
						if (opline->op1_type == IS_UNUSED &&
						    property_slot[opline->op2.constant] >= 0) {
							opline->extended_value = property_slot[opline->op2.constant];
						} else {
							opline->extended_value = cache_size;
							cache_size += 2 * sizeof(void *);
							if (opline->op1_type == IS_UNUSED) {
								property_slot[opline->op2.constant] = opline->extended_value;
							}
						}
					}
					break;
				case ZEND_ISSET_ISEMPTY_PROP_OBJ:
					if (opline->op2_type == IS_CONST) {
						// op2 property
						if (opline->op1_type == IS_UNUSED &&
						    property_slot[opline->op2.constant] >= 0) {
							opline->extended_value = property_slot[opline->op2.constant] | (opline->extended_value & ZEND_ISEMPTY);
						} else {
							opline->extended_value = cache_size | (opline->extended_value & ZEND_ISEMPTY);
							cache_size += 2 * sizeof(void *);
							if (opline->op1_type == IS_UNUSED) {
								property_slot[opline->op2.constant] = opline->extended_value & ~ZEND_ISEMPTY;
							}
						}
					}
					break;
				case ZEND_INIT_FCALL:
				case ZEND_INIT_FCALL_BY_NAME:
				case ZEND_INIT_NS_FCALL_BY_NAME:
					// op2 func
					if (func_slot[opline->op2.constant] >= 0) {
						opline->result.num = func_slot[opline->op2.constant];
					} else {
						opline->result.num = cache_size;
						cache_size += sizeof(void *);
						func_slot[opline->op2.constant] = opline->result.num;
					}
					break;
				case ZEND_INIT_METHOD_CALL:
					if (opline->op2_type == IS_CONST) {
						// op2 method
						if (opline->op1_type == IS_UNUSED &&
						    method_slot[opline->op2.constant] >= 0) {
							opline->result.num = method_slot[opline->op2.constant];
						} else {
							opline->result.num = cache_size;
							cache_size += 2 * sizeof(void *);
							if (opline->op1_type == IS_UNUSED) {
								method_slot[opline->op2.constant] = opline->result.num;
							}
						}
					}
					break;
				case ZEND_INIT_STATIC_METHOD_CALL:
					if (opline->op2_type == IS_CONST) {
						// op2 static method
						if (opline->op1_type == IS_CONST) {
							opline->result.num = add_static_slot(&hash, op_array,
								opline->op1.constant,
								opline->op2.constant,
								LITERAL_STATIC_METHOD,
								&cache_size);
						} else {
							opline->result.num = cache_size;
							cache_size += 2 * sizeof(void *);
						}
					} else if (opline->op1_type == IS_CONST) {
						// op1 class
						if (class_slot[opline->op1.constant] >= 0) {
							opline->result.num = class_slot[opline->op1.constant];
						} else {
							opline->result.num = cache_size;
							cache_size += sizeof(void *);
							class_slot[opline->op1.constant] = opline->result.num;
						}
					}
					break;
				case ZEND_DEFINED:
					// op1 const
					if (const_slot[opline->op1.constant] >= 0) {
						opline->extended_value = const_slot[opline->op1.constant];
					} else {
						opline->extended_value = cache_size;
						cache_size += sizeof(void *);
						const_slot[opline->op1.constant] = opline->extended_value;
					}
					break;
				case ZEND_FETCH_CONSTANT:
					// op2 const
					if (const_slot[opline->op2.constant] >= 0) {
						opline->extended_value = const_slot[opline->op2.constant];
					} else {
						opline->extended_value = cache_size;
						cache_size += sizeof(void *);
						const_slot[opline->op2.constant] = opline->extended_value;
					}
					break;
				case ZEND_FETCH_CLASS_CONSTANT:
					if (opline->op1_type == IS_CONST) {
						// op1/op2 class_const
						opline->extended_value = add_static_slot(&hash, op_array,
							opline->op1.constant,
							opline->op2.constant,
							LITERAL_CLASS_CONST,
							&cache_size);
					} else {
						opline->extended_value = cache_size;
						cache_size += 2 * sizeof(void *);
					}
					break;
				case ZEND_FETCH_STATIC_PROP_R:
				case ZEND_FETCH_STATIC_PROP_W:
				case ZEND_FETCH_STATIC_PROP_RW:
				case ZEND_FETCH_STATIC_PROP_IS:
				case ZEND_FETCH_STATIC_PROP_UNSET:
				case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
				case ZEND_UNSET_STATIC_PROP:
					if (opline->op1_type == IS_CONST) {
						// op1 static property
						if (opline->op2_type == IS_CONST) {
							opline->extended_value = add_static_slot(&hash, op_array,
								opline->op2.constant,
								opline->op1.constant,
								LITERAL_STATIC_PROPERTY,
								&cache_size);
						} else {
							opline->extended_value = cache_size;
							cache_size += 2 * sizeof(void *);
						}
					} else if (opline->op2_type == IS_CONST) {
						// op2 class
						if (class_slot[opline->op2.constant] >= 0) {
							opline->extended_value = class_slot[opline->op2.constant];
						} else {
							opline->extended_value = cache_size;
							cache_size += sizeof(void *);
							class_slot[opline->op2.constant] = opline->extended_value;
						}
					}
					break;
				case ZEND_ISSET_ISEMPTY_STATIC_PROP:
					if (opline->op1_type == IS_CONST) {
						// op1 static property
						if (opline->op2_type == IS_CONST) {
							opline->extended_value = add_static_slot(&hash, op_array,
								opline->op2.constant,
								opline->op1.constant,
								LITERAL_STATIC_PROPERTY,
								&cache_size) | (opline->extended_value & ZEND_ISEMPTY);
						} else {
							opline->extended_value = cache_size | (opline->extended_value & ZEND_ISEMPTY);
							cache_size += 2 * sizeof(void *);
						}
					} else if (opline->op2_type == IS_CONST) {
						// op2 class
						if (class_slot[opline->op2.constant] >= 0) {
							opline->extended_value = class_slot[opline->op2.constant] | (opline->extended_value & ZEND_ISEMPTY);
						} else {
							opline->extended_value = cache_size | (opline->extended_value & ZEND_ISEMPTY);
							cache_size += sizeof(void *);
							class_slot[opline->op2.constant] = opline->extended_value & ~ZEND_ISEMPTY;
						}
					}
					break;
				case ZEND_FETCH_CLASS:
				case ZEND_INSTANCEOF:
					if (opline->op2_type == IS_CONST) {
						// op2 class
						if (class_slot[opline->op2.constant] >= 0) {
							opline->extended_value = class_slot[opline->op2.constant];
						} else {
							opline->extended_value = cache_size;
							cache_size += sizeof(void *);
							class_slot[opline->op2.constant] = opline->extended_value;
						}
					}
					break;
				case ZEND_NEW:
					if (opline->op1_type == IS_CONST) {
						// op1 class
						if (class_slot[opline->op1.constant] >= 0) {
							opline->op2.num = class_slot[opline->op1.constant];
						} else {
							opline->op2.num = cache_size;
							cache_size += sizeof(void *);
							class_slot[opline->op1.constant] = opline->op2.num;
						}
					}
					break;
				case ZEND_CATCH:
					if (opline->op1_type == IS_CONST) {
						// op1 class
						if (class_slot[opline->op1.constant] >= 0) {
							opline->extended_value = class_slot[opline->op1.constant] | (opline->extended_value & ZEND_LAST_CATCH);
						} else {
							opline->extended_value = cache_size | (opline->extended_value & ZEND_LAST_CATCH);
							cache_size += sizeof(void *);
							class_slot[opline->op1.constant] = opline->extended_value & ~ZEND_LAST_CATCH;
						}
					}
					break;
				case ZEND_BIND_GLOBAL:
					// op2 bind var
					if (bind_var_slot[opline->op2.constant] >= 0) {
						opline->extended_value = bind_var_slot[opline->op2.constant];
					} else {
						opline->extended_value = cache_size;
						cache_size += sizeof(void *);
						bind_var_slot[opline->op2.constant] = opline->extended_value;
					}
					break;
			}
			opline++;
		}
		op_array->cache_size = cache_size;
		zend_hash_destroy(&hash);
		zend_arena_release(&ctx->arena, checkpoint);

		if (1) {
			opline = op_array->opcodes;
			while (1) {
				if (opline->opcode == ZEND_RECV_INIT) {
					zval *val = &op_array->literals[opline->op2.constant];

					if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
						uint32_t slot = ZEND_MM_ALIGNED_SIZE_EX(op_array->cache_size, 8);

						Z_CACHE_SLOT_P(val) = slot;
						op_array->cache_size += sizeof(zval);
					}
				} else if (opline->opcode != ZEND_RECV) {
					break;
				}
				opline++;
			}
		}

#if DEBUG_COMPACT_LITERALS
		{
			int i, use_copy;
			fprintf(stderr, "Optimized literlas table size %d\n", op_array->last_literal);

			for (i = 0; i < op_array->last_literal; i++) {
				zval zv;
				ZVAL_COPY_VALUE(&zv, op_array->literals + i);
				use_copy = zend_make_printable_zval(op_array->literals + i, &zv);
				fprintf(stderr, "Literal %d, val (%d):%s\n", i, Z_STRLEN(zv), Z_STRVAL(zv));
				if (use_copy) {
					zval_ptr_dtor_nogc(&zv);
				}
			}
			fflush(stderr);
		}
#endif
	}
}
示例#3
0
#include "msgformat_helpers.h"
#include "intl_convert.h"

#ifndef Z_ADDREF_P
#define Z_ADDREF_P(z) ((z)->refcount++)
#endif

/* {{{ */
static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value TSRMLS_DC)
{
    int count;
    UChar* formatted = NULL;
    int formatted_len = 0;
    HashTable *args_copy;

    count = zend_hash_num_elements(Z_ARRVAL_P(args));

    ALLOC_HASHTABLE(args_copy);
    zend_hash_init(args_copy, count, NULL, ZVAL_PTR_DTOR, 0);
    zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref,
                   NULL, sizeof(zval*));

    umsg_format_helper(mfo, args_copy, &formatted, &formatted_len TSRMLS_CC);

    zend_hash_destroy(args_copy);
    efree(args_copy);

    if (formatted && U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
        efree(formatted);
    }
示例#4
0
void binary_serialize(int8_t thrift_typeID, PHPOutputTransport& transport, zval** value, HashTable* fieldspec) {
    // At this point the typeID (and field num, if applicable) should've already been written to the output so all we need to do is write the payload.
    switch (thrift_typeID) {
    case T_STOP:
    case T_VOID:
        return;
    case T_STRUCT: {
        TSRMLS_FETCH();
        if (Z_TYPE_PP(value) != IS_OBJECT) {
            throw_tprotocolexception("Attempt to send non-object type as a T_STRUCT", INVALID_DATA);
        }
        zval* spec = zend_read_static_property(zend_get_class_entry(*value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC);
        binary_serialize_spec(*value, transport, Z_ARRVAL_P(spec));
    }
    return;
    case T_BOOL:
        if (Z_TYPE_PP(value) != IS_BOOL) convert_to_boolean(*value);
        transport.writeI8(Z_BVAL_PP(value) ? 1 : 0);
        return;
    case T_BYTE:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI8(Z_LVAL_PP(value));
        return;
    case T_I16:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI16(Z_LVAL_PP(value));
        return;
    case T_I32:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI32(Z_LVAL_PP(value));
        return;
    case T_I64:
    case T_U64:
        if (Z_TYPE_PP(value) != IS_LONG) convert_to_long(*value);
        transport.writeI64(Z_LVAL_PP(value));
        return;
    case T_DOUBLE: {
        union {
            int64_t c;
            double d;
        } a;
        if (Z_TYPE_PP(value) != IS_DOUBLE) convert_to_double(*value);
        a.d = Z_DVAL_PP(value);
        transport.writeI64(a.c);
    }
    return;
    //case T_UTF7:
    case T_UTF8:
    case T_UTF16:
    case T_STRING:
        if (Z_TYPE_PP(value) != IS_STRING) convert_to_string(*value);
        transport.writeString(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
        return;
    case T_MAP: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_MAP)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "ktype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);
        zend_hash_find(fieldspec, "vtype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_LIST: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_LIST)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t valtype = Z_LVAL_PP(val_ptr);
        transport.writeI8(valtype);

        zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr);
        HashTable* valspec = Z_ARRVAL_PP(val_ptr);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize(valtype, transport, val_ptr, valspec);
        }
    }
    return;
    case T_SET: {
        if (Z_TYPE_PP(value) != IS_ARRAY) convert_to_array(*value);
        if (Z_TYPE_PP(value) != IS_ARRAY) {
            throw_tprotocolexception("Attempt to send an incompatible type as an array (T_SET)", INVALID_DATA);
        }
        HashTable* ht = Z_ARRVAL_PP(value);
        zval** val_ptr;

        zend_hash_find(fieldspec, "etype", 6, (void**)&val_ptr);
        if (Z_TYPE_PP(val_ptr) != IS_LONG) convert_to_long(*val_ptr);
        uint8_t keytype = Z_LVAL_PP(val_ptr);
        transport.writeI8(keytype);

        transport.writeI32(zend_hash_num_elements(ht));
        HashPosition key_ptr;
        for (zend_hash_internal_pointer_reset_ex(ht, &key_ptr); zend_hash_get_current_data_ex(ht, (void**)&val_ptr, &key_ptr) == SUCCESS; zend_hash_move_forward_ex(ht, &key_ptr)) {
            binary_serialize_hashtable_key(keytype, transport, ht, key_ptr);
        }
    }
    return;
    };
    char errbuf[128];
    sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID);
    throw_tprotocolexception(errbuf, INVALID_DATA);
}
示例#5
0
/* {{{ _php_array_to_envp */
static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent TSRMLS_DC)
{
	zval **element;
	php_process_env_t env;
	char *string_key, *data;
#ifndef PHP_WIN32
	char **ep;
#endif
	char *p;
	uint string_length, cnt, l, sizeenv=0, el_len;
	ulong num_key;
	HashTable *target_hash;
	HashPosition pos;

	memset(&env, 0, sizeof(env));
	
	if (!environment) {
		return env;
	}
	
	cnt = zend_hash_num_elements(Z_ARRVAL_P(environment));
	
	if (cnt < 1) {
		return env;
	}

	target_hash = HASH_OF(environment);
	if (!target_hash) {
		return env;
	}

	/* first, we have to get the size of all the elements in the hash */
	for (zend_hash_internal_pointer_reset_ex(target_hash, &pos);
			zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS;
			zend_hash_move_forward_ex(target_hash, &pos)) {
		
		convert_to_string_ex(element);
		el_len = Z_STRLEN_PP(element);
		if (el_len == 0) {
			continue;
		}
		
		sizeenv += el_len+1;
		
		switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length, &num_key, 0, &pos)) {
			case HASH_KEY_IS_STRING:
				if (string_length == 0) {
					continue;
				}
				sizeenv += string_length+1;
				break;
		}
	}

#ifndef PHP_WIN32
	ep = env.envarray = (char **) pecalloc(cnt + 1, sizeof(char *), is_persistent);
#endif
	p = env.envp = (char *) pecalloc(sizeenv + 4, 1, is_persistent);

	for (zend_hash_internal_pointer_reset_ex(target_hash, &pos);
			zend_hash_get_current_data_ex(target_hash, (void **) &element, &pos) == SUCCESS;
			zend_hash_move_forward_ex(target_hash, &pos)) {
		
		convert_to_string_ex(element);
		el_len = Z_STRLEN_PP(element);
		
		if (el_len == 0) {
			continue;
		}
		
		data = Z_STRVAL_PP(element);
		switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_length, &num_key, 0, &pos)) {
			case HASH_KEY_IS_STRING:
				if (string_length == 0) {
					continue;
				}
				l = string_length + el_len + 1;
				memcpy(p, string_key, string_length);
				strcat(p, "=");
				strcat(p, data);
				
#ifndef PHP_WIN32
				*ep = p;
				++ep;
#endif
				p += l;
				break;
			case HASH_KEY_IS_LONG:
				memcpy(p,data,el_len);
#ifndef PHP_WIN32
				*ep = p;
				++ep;
#endif
				p += el_len + 1;
				break;
			case HASH_KEY_NON_EXISTANT:
				break;
		}
	}	

	assert(p - env.envp <= sizeenv);
	
	zend_hash_internal_pointer_reset_ex(target_hash, &pos);

	return env;
}
示例#6
0
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;

	if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) {
		switch (event_type) {
			case PDO_PARAM_EVT_FREE:
				if (param->driver_data) {
					efree(param->driver_data);
				}
				break;

			case PDO_PARAM_EVT_NORMALIZE:
				/* decode name from $1, $2 into 0, 1 etc. */
				if (param->name) {
					if (param->name->val[0] == '$') {
						ZEND_ATOL(param->paramno, param->name->val + 1);
					} else {
						/* resolve parameter name to rewritten name */
						char *namevar;

						if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map,
								param->name)) != NULL) {
							ZEND_ATOL(param->paramno, namevar + 1);
							param->paramno--;
						} else {
							pdo_raise_impl_error(stmt->dbh, stmt, "HY093", param->name->val);
							return 0;
						}
					}
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
			case PDO_PARAM_EVT_EXEC_POST:
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
				/* work is handled by EVT_NORMALIZE */
				return 1;

			case PDO_PARAM_EVT_EXEC_PRE:
				if (!stmt->bound_param_map) {
					return 0;
				}
				if (!S->param_values) {
					S->param_values = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(char*));
					S->param_lengths = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_formats = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_types = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(Oid));
				}
				if (param->paramno >= 0) {
					zval *parameter;

					if (param->paramno >= zend_hash_num_elements(stmt->bound_params)) {
						pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
						return 0;
					}

					if (Z_ISREF(param->parameter)) {
						parameter = Z_REFVAL(param->parameter);
					} else {
						parameter = &param->parameter;
					}

					if (PDO_PARAM_TYPE(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) {
							if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
								struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
								pdo_pgsql_bound_param *P = param->driver_data;

								if (P == NULL) {
									P = ecalloc(1, sizeof(*P));
									param->driver_data = P;
								}
								P->oid = htonl(self->oid);
								S->param_values[param->paramno] = (char*)&P->oid;
								S->param_lengths[param->paramno] = sizeof(P->oid);
								S->param_formats[param->paramno] = 1;
								S->param_types[param->paramno] = OIDOID;
								return 1;
							} else {
								zend_string *str = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
								if (str != NULL) {
									//??SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
									ZVAL_STR(parameter, str);
								} else {
									ZVAL_EMPTY_STRING(parameter);
								}
							}
						} else {
							/* expected a stream resource */
							pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
							return 0;
						}
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
							Z_TYPE_P(parameter) == IS_NULL) {
						S->param_values[param->paramno] = NULL;
						S->param_lengths[param->paramno] = 0;
					} else if (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE) {
						S->param_values[param->paramno] = Z_TYPE_P(parameter) == IS_TRUE ? "t" : "f";
						S->param_lengths[param->paramno] = 1;
						S->param_formats[param->paramno] = 0;
					} else {
						//SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
						convert_to_string_ex(parameter);
						S->param_values[param->paramno] = Z_STRVAL_P(parameter);
						S->param_lengths[param->paramno] = Z_STRLEN_P(parameter);
						S->param_formats[param->paramno] = 0;
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
						S->param_types[param->paramno] = 0;
						S->param_formats[param->paramno] = 1;
					} else {
						S->param_types[param->paramno] = 0;
					}
				}
				break;
		}
	} else if (param->is_param) {
		/* We need to manually convert to a pg native boolean value */
		if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
			((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
			SEPARATE_ZVAL(&param->parameter);
			param->param_type = PDO_PARAM_STR;
			convert_to_boolean(&param->parameter);
			ZVAL_STRINGL(&param->parameter, Z_TYPE_P(&param->parameter) == IS_TRUE ? "t" : "f", 1);
		}
	}
	return 1;
}
void zend_accel_copy_internal_functions(void)
{
	zend_hash_apply_with_argument(CG(function_table), (apply_func_arg_t)copy_internal_function, &ZCG(function_table));
	ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
}
示例#8
0
static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type, HashTable *vars) /* {{{ */
{
	char *decode = NULL;

	switch (type &~ EXT_TYPE_UNUSED) {
		case IS_CV: {
			zend_string *var = ops->vars[EX_VAR_TO_NUM(op->var)];
			asprintf(&decode, "$%.*s%c", var->len <= 19 ? (int) var->len : 18, var->val, var->len <= 19 ? 0 : '+');
		} break;

		case IS_VAR:
		case IS_TMP_VAR: {
			zend_ulong id = 0, *pid = NULL;
			if (vars != NULL) {
				if ((pid = zend_hash_index_find_ptr(vars, (zend_ulong) ops->vars - op->var))) {
					id = *pid;
				} else {
					id = zend_hash_num_elements(vars);
					zend_hash_index_update_mem(vars, (zend_ulong) ops->vars - op->var, &id, sizeof(zend_ulong));
				}
			}
			asprintf(&decode, "@" ZEND_ULONG_FMT, id);
		} break;

		case IS_CONST: {
			zval *literal = RT_CONSTANT(ops, *op);
			switch (Z_TYPE_P(literal)) {
				case IS_UNDEF:
					decode = zend_strndup("", 0);
					break;
				case IS_NULL:
					decode = zend_strndup(ZEND_STRL("null"));
					break;
				case IS_FALSE:
					decode = zend_strndup(ZEND_STRL("false"));
					break;
				case IS_TRUE:
					decode = zend_strndup(ZEND_STRL("true"));
					break;
				case IS_LONG:
					asprintf(&decode, "%lld", Z_LVAL_P(literal));
					break;
				case IS_DOUBLE:
					asprintf(&decode, "%.*G", 14, Z_DVAL_P(literal));
					break;
				case IS_STRING: {
					int i;
					zend_string *str = php_addcslashes(Z_STR_P(literal), 0, "\\\"", 2);
					for (i = 0; i < str->len; i++) {
						if (str->val[i] < 32) {
							str->val[i] = ' ';
						}
					}
					asprintf(&decode, "\"%.*s\"%c", str->len <= 18 ? (int) str->len : 17, str->val, str->len <= 18 ? 0 : '+');
					zend_string_release(str);
					} break;
				case IS_RESOURCE:
					asprintf(&decode, "Rsrc #%d", Z_RES_HANDLE_P(literal));
					break;
				case IS_ARRAY:
					asprintf(&decode, "array(%d)", zend_hash_num_elements(Z_ARR_P(literal)));
					break;
				case IS_OBJECT: {
					zend_string *str = Z_OBJCE_P(literal)->name;
					asprintf(&decode, "%.*s%c", str->len <= 18 ? (int) str->len : 18, str->val, str->len <= 18 ? 0 : '+');
					} break;
				case IS_CONSTANT:
					decode = zend_strndup(ZEND_STRL("<constant>"));
					break;
				case IS_CONSTANT_AST:
					decode = zend_strndup(ZEND_STRL("<ast>"));
					break;
				default:
					asprintf(&decode, "unknown type: %d", Z_TYPE_P(literal));
					break;
			}
		} break;

		case IS_UNUSED:
			asprintf(&decode, "<unused>");
		break;
	}
	return decode;
} /* }}} */
示例#9
0
ZEND_METHOD(Vedis, hmset)
{
    char *key;
    int key_len;
    zval **val, *members;
    HashPosition pos;
    size_t n;
    VEDIS_PARAM(HMSET, 5);

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa",
                              &key, &key_len, &members) == FAILURE) {
        return;
    }

    VEDIS_SELF(intern);

    n = zend_hash_num_elements(HASH_OF(members));
    if (n == 0) {
        RETURN_FALSE;
    }

    VEDIS_ARGS_INIT((n * 2) + 1);

    VEDIS_ARGS_STRING(key, key_len);

    zend_hash_internal_pointer_reset_ex(HASH_OF(members), &pos);
    while (zend_hash_get_current_data_ex(HASH_OF(members),
                                         (void **)&val, &pos) == SUCCESS) {
        char *str_key;
        uint str_key_len;
        long num_key;
        int flags;

        flags = zend_hash_get_current_key_ex(HASH_OF(members),
                                             &str_key, &str_key_len,
                                             &num_key, 0, &pos);
        if (flags == HASH_KEY_NON_EXISTANT) {
            break;
        }

        if (Z_TYPE_PP(val) != IS_STRING) {
            convert_to_string(*val);
        }

        if (flags == HASH_KEY_IS_STRING) {
            VEDIS_ARGS_STRING(str_key, str_key_len - 1);
        } else {
            smart_str buf = {0};
            smart_str_append_long(&buf, num_key);
            smart_str_0(&buf);
            VEDIS_ARGS_STRING(buf.c, buf.len);
            smart_str_free(&buf);
        }
        VEDIS_ARGS_STRING(Z_STRVAL_PP(val), Z_STRLEN_PP(val));

        zend_hash_move_forward_ex(HASH_OF(members), &pos);
    }

    VEDIS_ARGS_EXEC(RETURN_FALSE);

    VEDIS_RETURN_BOOL();
}
示例#10
0
/* }}} */
static void xc_coverager_save_cov(char *srcfile, char *outfilename, coverager_t cov TSRMLS_DC) /* {{{ */
{
	long *buf = NULL, *p;
	long covlines, *phits;
	int fd = -1;
	int size;
	int newfile;
	struct stat srcstat, outstat;
	HashPosition pos;
	char *contents = NULL;
	long len;

	if (stat(srcfile, &srcstat) != 0) {
		return;
	}

	newfile = 0;
	if (stat(outfilename, &outstat) != 0) {
		newfile = 1;
	}
	else {
		if (srcstat.st_mtime > outstat.st_mtime) {
			newfile = 1;
		}
	}

	fd = open(outfilename, O_RDWR | O_CREAT, 0600);
	if (fd < 0) {
		char *chr;
		chr = strrchr(srcfile, PHP_DIR_SEPARATOR);
		if (chr) {
			*chr = '\0';
			xcache_mkdirs_ex(xc_coveragedump_dir, strlen(xc_coveragedump_dir), srcfile, chr - srcfile TSRMLS_CC);
			*chr = PHP_DIR_SEPARATOR;
		}
		fd = open(outfilename, O_RDWR | O_CREAT, 0600);
		if (fd < 0) {
			goto bailout;
		}
	}
	if (flock(fd, LOCK_EX) != SUCCESS) {
		goto bailout;
	}

	if (newfile) {
		TRACE("%s", "new file");
	}
	else if (outstat.st_size) {
		len = outstat.st_size;
		contents = emalloc(len);
		if (read(fd, (void *) contents, len) != len) {
			goto bailout;
		}
		TRACE("oldsize %d", (int) len);
		do {
			p = (long *) contents;
			len -= sizeof(long);
			if (len < 0) {
				break;
			}
			if (*p++ != PCOV_HEADER_MAGIC) {
				TRACE("wrong magic in file %s", outfilename);
				break;
			}

			p += 2; /* skip covliens */
			len -= sizeof(long) * 2;
			if (len < 0) {
				break;
			}

			for (; len >= (int) sizeof(long) * 2; len -= sizeof(long) * 2, p += 2) {
				if (zend_hash_index_find(cov, p[0], (void**)&phits) == SUCCESS) {
					if (p[1] == -1) {
						/* OPTIMIZE: already marked */
						continue;
					}
					if (*phits != -1) {
						p[1] += *phits;
					}
				}
				zend_hash_index_update(cov, p[0], &p[1], sizeof(p[1]), NULL);
			}
		} while (0);
		efree(contents);
		contents = NULL;
	}


	/* serialize */
	size = (zend_hash_num_elements(cov) + 1) * sizeof(long) * 2 + sizeof(long);
	p = buf = emalloc(size);
	*p++ = PCOV_HEADER_MAGIC;
	p += 2; /* for covlines */
	covlines = 0;

	zend_hash_internal_pointer_reset_ex(cov, &pos);
	while (zend_hash_get_current_data_ex(cov, (void**)&phits, &pos) == SUCCESS) {
		*p++ = pos->h;
		*p++ = *phits;
		if (*phits > 0) {
			covlines ++;
		}
		zend_hash_move_forward_ex(cov, &pos);
	}
	p = buf + 1;
	p[0] = 0;
	p[1] = covlines;

	if (ftruncate(fd, 0) != 0) {
		goto bailout;
	}
	lseek(fd, 0, SEEK_SET);
	if (write(fd, (char *) buf, size) != size) {
		goto bailout;
	}

bailout:
	if (contents) efree(contents);
	if (fd >= 0) close(fd);
	if (buf) efree(buf);
}
示例#11
0
文件: ini.c 项目: dreamsxin/cphalcon7
/**
 * Load config file
 *
 * @param string $filePath
 */
PHP_METHOD(Phalcon_Config_Adapter_Ini, read){

	zval *file_path, *absolute_path = NULL, *scanner_mode = NULL, config_dir_path = {}, base_path = {}, ini_config = {}, config = {}, *directives;
	zend_string *str_key;
	ulong idx;

	phalcon_fetch_params(0, 1, 2, &file_path, &absolute_path, &scanner_mode);
	PHALCON_ENSURE_IS_STRING(file_path);

	if (!absolute_path) {
		absolute_path = &PHALCON_GLOBAL(z_false);
	}

	if (zend_is_true(absolute_path)) {
		PHALCON_CPY_WRT_CTOR(&config_dir_path, file_path);
	} else {
		phalcon_return_static_property_ce(&base_path, phalcon_config_adapter_ce, SL("_basePath"));

		PHALCON_CONCAT_VV(&config_dir_path, &base_path, file_path);
	}

	/** 
	 * Use the standard parse_ini_file
	 */
	if (scanner_mode && Z_TYPE_P(scanner_mode) == IS_LONG) {
		PHALCON_CALL_FUNCTIONW(&ini_config, "parse_ini_file", &config_dir_path, &PHALCON_GLOBAL(z_true), scanner_mode);
	} else {
		PHALCON_CALL_FUNCTIONW(&ini_config, "parse_ini_file", &config_dir_path, &PHALCON_GLOBAL(z_true));
	}

	/** 
	 * Check if the file had errors
	 */
	if (Z_TYPE(ini_config) != IS_ARRAY) {
		zend_throw_exception_ex(phalcon_config_exception_ce, 0, "Configuration file '%s' cannot be read", Z_STRVAL(config_dir_path));
		return;
	}

	array_init(&config);

	ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(ini_config), idx, str_key, directives) {
		zval section = {}, *value;
		if (str_key) {
			ZVAL_STR(&section, str_key);
		} else {
			ZVAL_LONG(&section, idx);
		}

		if (unlikely(Z_TYPE_P(directives) != IS_ARRAY) || zend_hash_num_elements(Z_ARRVAL_P(directives)) == 0) {
			phalcon_array_update_zval(&config, &section, directives, PH_COPY);
		} else {
			ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(directives), idx, str_key, value) {
				zval key = {}, directive_parts = {};
				if (str_key) {
					ZVAL_STR(&key, str_key);
				} else {
					ZVAL_LONG(&key, idx);
				}

				if (str_key && memchr(Z_STRVAL(key), '.', Z_STRLEN(key))) {
					phalcon_fast_explode_str(&directive_parts, SL("."), &key);
					phalcon_config_adapter_ini_update_zval_directive(&config, &section, &directive_parts, value);
				} else {
					phalcon_array_update_multi_2(&config, &section, &key, value, PH_COPY);
				}
			} ZEND_HASH_FOREACH_END();
		}
示例#12
0
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;

	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;
		(*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;
		}
	}
}
示例#13
0
/* {{{ php_runkit_import_functions
 */
static int php_runkit_import_functions(HashTable *function_table, long flags TSRMLS_DC)
{
    HashPosition pos;
    int i, func_count = zend_hash_num_elements(function_table);

    zend_hash_internal_pointer_reset_ex(function_table, &pos);
    for(i = 0; i < func_count; i++) {
        zend_function *fe = NULL;
        char *key, *new_key;
        int key_len, new_key_len, type;
        long idx;
        zend_bool add_function = 1;
        zend_bool exists = 0;

        zend_hash_get_current_data_ex(function_table, (void**)&fe, &pos);

        new_key = fe->common.function_name;
        new_key_len = strlen(new_key) + 1;

        if (((type = zend_hash_get_current_key_ex(function_table, &key, &key_len, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT) &&
                fe && fe->type == ZEND_USER_FUNCTION) {

            if (type == HASH_KEY_IS_STRING) {
                new_key = key;
                new_key_len = key_len;
                exists = zend_hash_exists(EG(function_table), new_key, new_key_len);
            } else {
                exists = zend_hash_index_exists(EG(function_table), idx);
            }

            if (exists) {
                if (flags & PHP_RUNKIT_IMPORT_OVERRIDE) {
                    if (type == HASH_KEY_IS_STRING) {
                        if (zend_hash_del(EG(function_table), new_key, new_key_len) == FAILURE) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Inconsistency cleaning up import environment");
                            return FAILURE;
                        }
                    } else {
                        if (zend_hash_index_del(EG(function_table), idx) == FAILURE) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Inconsistency cleaning up import environment");
                            return FAILURE;
                        }
                    }
                } else {
                    add_function = 0;
                }
            }
        }

        if (add_function) {
            if (zend_hash_add(EG(function_table), new_key, new_key_len, fe, sizeof(zend_function), NULL) == FAILURE) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failure importing %s()", fe->common.function_name);
                PHP_RUNKIT_DESTROY_FUNCTION(fe);
                return FAILURE;
            } else {
                PHP_RUNKIT_FUNCTION_ADD_REF(fe);
            }
        }
        zend_hash_move_forward_ex(function_table, &pos);
    }

    return SUCCESS;
}
示例#14
0
/* $Id$ */

#include "php_runkit.h"
#include "php_runkit_zval.h"

#ifdef PHP_RUNKIT_MANIPULATION
/* {{{ php_runkit_import_functions
 */
static int php_runkit_import_functions(HashTable *function_table, long flags
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
                                       , zend_bool *clear_cache
#endif
                                       TSRMLS_DC)
{
	HashPosition pos;
	int i, func_count = zend_hash_num_elements(function_table);

	zend_hash_internal_pointer_reset_ex(function_table, &pos);
	for(i = 0; i < func_count; i++) {
		zend_function *fe = NULL, *orig_fe;
		char *key;
		const char *new_key;
		uint key_len, new_key_len;
		int type;
		ulong idx;
		zend_bool add_function = 1;
		zend_bool exists = 0;

		zend_hash_get_current_data_ex(function_table, (void*)&fe, &pos);

		new_key = fe->common.function_name;
示例#15
0
void *php_array_to_c_array(zval *param,int type,int size,int *array_size)
{
	HashTable *param_ht = param->value.ht;
	zval **cur;
	void *params;
	int i,tmp_size = zend_hash_num_elements(param_ht);

	zend_hash_internal_pointer_reset(param_ht);
	params = (void *)emalloc(size * tmp_size);

	i = 0;
	while(zend_hash_get_current_data(param_ht,(void **)&cur) == SUCCESS)
	{
		if((*cur)->type == IS_ARRAY)
		{
			int new_array_size;
			void *array = php_array_to_c_array(*cur,type,size,&new_array_size);
			params = erealloc(params, (tmp_size + new_array_size) * size);
			memcpy(&((char*)params)[i*size],array,new_array_size * size);
			i += (new_array_size - 1);
			efree(array);
		}
		else
		{
			switch(type)
			{
			case TO_C_FLOAT:
				convert_to_double(*cur);
				((float*)params)[i] = (float)Z_DVAL_P(*cur);
				break;
			case TO_C_DOUBLE:
				convert_to_double(*cur);
				((double*)params)[i] = Z_DVAL_P(*cur);
				break;
			case TO_C_INT:
				convert_to_long(*cur);
				((int*)params)[i] = (int)Z_LVAL_P(*cur);
				break;
			case TO_C_LONG:
				convert_to_long(*cur);
				((long*)params)[i] = Z_LVAL_P(*cur);
				break;
			case TO_C_UCHAR:
				convert_to_long(*cur);
				((unsigned char*)params)[i] = (unsigned char)Z_LVAL_P(*cur);
				break;
			case TO_C_SCHAR:
				convert_to_long(*cur);
				((signed char*)params)[i] = (signed char)Z_LVAL_P(*cur);
				break;
			case TO_C_USHORT:
				convert_to_long(*cur);
				((unsigned short*)params)[i] = (unsigned short)Z_LVAL_P(*cur);
				break;
			case TO_C_SHORT:
				convert_to_long(*cur);
				((short*)params)[i] = (short)Z_LVAL_P(*cur);
				break;
			case TO_C_UINT:
				convert_to_long(*cur);
				((unsigned int*)params)[i] = (unsigned int)Z_LVAL_P(*cur);
				break;
			case TO_C_STRING:
				convert_to_string(*cur);
				((char **)params)[i] = estrdup(Z_STRVAL_P(*cur));
			}
		}
		zend_hash_move_forward(param_ht);
		i++;
	}
	if(array_size != NULL)
		*array_size = i;
	return (void *)params;
}
示例#16
0
ZEND_METHOD(Vedis, hmget)
{
    char *key;
    int key_len;
    zval **val, *fields;
    HashPosition pos;
    size_t n;
    VEDIS_PARAM(HMGET, 5);

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa",
                              &key, &key_len, &fields) == FAILURE) {
        return;
    }

    VEDIS_SELF(intern);

    n = zend_hash_num_elements(HASH_OF(fields));
    if (n == 0) {
        RETURN_FALSE;
    }

    VEDIS_ARGS_INIT(n + 1);

    VEDIS_ARGS_STRING(key, key_len);

    zend_hash_internal_pointer_reset_ex(HASH_OF(fields), &pos);
    while (zend_hash_get_current_data_ex(HASH_OF(fields),
                                         (void **)&val, &pos) == SUCCESS) {
        if (Z_TYPE_PP(val) != IS_STRING) {
            convert_to_string(*val);
        }
        VEDIS_ARGS_STRING(Z_STRVAL_PP(val), Z_STRLEN_PP(val));
        zend_hash_move_forward_ex(HASH_OF(fields), &pos);
    }

    VEDIS_ARGS_EXEC(RETURN_FALSE);

    array_init(return_value);

    if (vedis_value_is_array(result)) {
        vedis_value *entry;
        zend_hash_internal_pointer_reset_ex(HASH_OF(fields), &pos);
        while (1) {
            if (zend_hash_get_current_data_ex(HASH_OF(fields),
                                              (void **)&val, &pos) != SUCCESS) {
                break;
            }
            if ((entry = vedis_array_next_elem(result)) == 0) {
                break;
            }

            if (Z_TYPE_PP(val) != IS_STRING) {
                convert_to_string(*val);
            }

            if (Z_STRLEN_PP(val) > 0) {
                if (vedis_value_is_null(entry)) {
                    add_assoc_null_ex(return_value,
                                      Z_STRVAL_PP(val), Z_STRLEN_PP(val) + 1);
                } else {
                    int len = 0;
                    const char *str = vedis_value_to_string(entry, &len);
                    add_assoc_stringl_ex(return_value,
                                         Z_STRVAL_PP(val), Z_STRLEN_PP(val) + 1,
                                         (char *)str, len, 1);
                }
            }

            zend_hash_move_forward_ex(HASH_OF(fields), &pos);
        }
    }
}
示例#17
0
static int pgsql_stmt_execute(pdo_stmt_t *stmt)
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
	pdo_pgsql_db_handle *H = S->H;
	ExecStatusType status;

	/* ensure that we free any previous unfetched results */
	if(S->result) {
		PQclear(S->result);
		S->result = NULL;
	}

	S->current_row = 0;

	if (S->cursor_name) {
		char *q = NULL;

		if (S->is_prepared) {
			spprintf(&q, 0, "CLOSE %s", S->cursor_name);
			S->result = PQexec(H->server, q);
			efree(q);
		}

		spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, stmt->active_query_string);
		S->result = PQexec(H->server, q);
		efree(q);

		/* check if declare failed */
		status = PQresultStatus(S->result);
		if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
			pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
			return 0;
		}

		/* the cursor was declared correctly */
		S->is_prepared = 1;

		/* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */
		spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name);
		S->result = PQexec(H->server, q);
		efree(q);
	} else if (S->stmt_name) {
		/* using a prepared statement */

		if (!S->is_prepared) {
stmt_retry:
			/* we deferred the prepare until now, because we didn't
			 * know anything about the parameter types; now we do */
			S->result = PQprepare(H->server, S->stmt_name, S->query,
						stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
						S->param_types);
			status = PQresultStatus(S->result);
			switch (status) {
				case PGRES_COMMAND_OK:
				case PGRES_TUPLES_OK:
					/* it worked */
					S->is_prepared = 1;
					PQclear(S->result);
					break;
				default: {
					char *sqlstate = pdo_pgsql_sqlstate(S->result);
					/* 42P05 means that the prepared statement already existed. this can happen if you use
					 * a connection pooling software line pgpool which doesn't close the db-connection once
					 * php disconnects. if php dies (no chance to run RSHUTDOWN) during execution it has no
					 * chance to DEALLOCATE the prepared statements it has created. so, if we hit a 42P05 we
					 * deallocate it and retry ONCE (thies 2005.12.15)
					 */
					if (sqlstate && !strcmp(sqlstate, "42P05")) {
						char buf[100]; /* stmt_name == "pdo_crsr_%08x" */
						PGresult *res;
						snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name);
						res = PQexec(H->server, buf);
						if (res) {
							PQclear(res);
						}
						goto stmt_retry;
					} else {
						pdo_pgsql_error_stmt(stmt, status, sqlstate);
						return 0;
					}
				}
			}
		}
		S->result = PQexecPrepared(H->server, S->stmt_name,
				stmt->bound_params ?
					zend_hash_num_elements(stmt->bound_params) :
					0,
				(const char**)S->param_values,
				S->param_lengths,
				S->param_formats,
				0);
	} else if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED) {
		/* execute query with parameters */
		S->result = PQexecParams(H->server, S->query,
				stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0,
				S->param_types,
				(const char**)S->param_values,
				S->param_lengths,
				S->param_formats,
				0);
	} else {
		/* execute plain query (with embedded parameters) */
		S->result = PQexec(H->server, stmt->active_query_string);
	}
	status = PQresultStatus(S->result);

	if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) {
		pdo_pgsql_error_stmt(stmt, status, pdo_pgsql_sqlstate(S->result));
		return 0;
	}

	if (!stmt->executed && (!stmt->column_count || S->cols == NULL)) {
		stmt->column_count = (int) PQnfields(S->result);
		S->cols = ecalloc(stmt->column_count, sizeof(pdo_pgsql_column));
	}

	if (status == PGRES_COMMAND_OK) {
		ZEND_ATOL(stmt->row_count, PQcmdTuples(S->result));
		H->pgoid = PQoidValue(S->result);
	} else {
		stmt->row_count = (zend_long)PQntuples(S->result);
	}

	return 1;
}
示例#18
0
/* {{{ void *get_pointinfo_array(zval *coordinate_array, int *num_elements TSRMLS_DC)
*/
void *get_pointinfo_array(zval *coordinate_array, int *num_elements TSRMLS_DC)
{
	PointInfo *coordinates;
	long elements_count, sub_elements_count, i;
	HashTable *coords;
	zval *current, *pz_x, *pz_y;
	HashTable *sub_array;

	*num_elements = 0;
	i = 0;

	coords = HASH_OF(coordinate_array);
	elements_count = zend_hash_num_elements(coords);

	if (elements_count < 1) {
		coordinates = (PointInfo *)NULL;
		return coordinates;
	}

	coordinates = (PointInfo *)emalloc(sizeof(PointInfo) * elements_count);

	ZEND_HASH_FOREACH_VAL(coords, current) {
		ZVAL_DEREF(current);
		/* If its something than array lets error here */
		if(current == NULL || Z_TYPE_P(current) != IS_ARRAY) {
			efree(coordinates);
			coordinates = (PointInfo *)NULL;			
			return coordinates;
示例#19
0
U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo,
								HashTable *args,
								UChar **formatted,
								int32_t *formatted_len)
{
	int arg_count = zend_hash_num_elements(args);
	std::vector<Formattable> fargs;
	std::vector<UnicodeString> farg_names;
	MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
	HashTable *types;
	intl_error& err = INTL_DATA_ERROR(mfo);

	if (U_FAILURE(err.code)) {
		return;
	}

	types = umsg_get_types(mfo, err);

	umsg_set_timezone(mfo, err);

	fargs.resize(arg_count);
	farg_names.resize(arg_count);

	int				argNum = 0;
	zval			*elem;

	// Key related variables
	zend_string		*str_index;
	zend_ulong		 num_index;

	ZEND_HASH_FOREACH_KEY_VAL(args, num_index, str_index, elem) {
		Formattable& formattable = fargs[argNum];
		UnicodeString& key = farg_names[argNum];
		Formattable::Type argType = Formattable::kObject, //unknown
						  *storedArgType = NULL;
		if (!U_SUCCESS(err.code)) {
			break;
		}
		/* Process key and retrieve type */
		if (str_index == NULL) {
			/* includes case where index < 0 because it's exposed as unsigned */
			if (num_index > (zend_ulong)INT32_MAX) {
				intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
					"Found negative or too large array key", 0);
				continue;
			}

		   UChar temp[16];
		   int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index);
		   key.append(temp, len);

		   storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, (zend_ulong)num_index);
		} else { //string; assumed to be in UTF-8
			intl_stringFromChar(key, ZSTR_VAL(str_index), ZSTR_LEN(str_index), &err.code);

			if (U_FAILURE(err.code)) {
				char *message;
				spprintf(&message, 0,
					"Invalid UTF-8 data in argument key: '%s'", ZSTR_VAL(str_index));
				intl_errors_set(&err, err.code,	message, 1);
				efree(message);
				continue;
			}

			storedArgType = (Formattable::Type*)zend_hash_str_find_ptr(types, (char*)key.getBuffer(), key.length());
		}

		if (storedArgType != NULL) {
			argType = *storedArgType;
		}

		/* Convert zval to formattable according to message format type
		 * or (as a fallback) the zval type */
		if (argType != Formattable::kObject) {
			switch (argType) {
			case Formattable::kString:
				{
	string_arg:
					/* This implicitly converts objects
					 * Note that our vectors will leak if object conversion fails
					 * and PHP ends up with a fatal error and calls longjmp
					 * as a result of that.
					 */
					convert_to_string_ex(elem);

					UnicodeString *text = new UnicodeString();
					intl_stringFromChar(*text,
						Z_STRVAL_P(elem), Z_STRLEN_P(elem), &err.code);

					if (U_FAILURE(err.code)) {
						char *message;
						spprintf(&message, 0, "Invalid UTF-8 data in string argument: "
							"'%s'", Z_STRVAL_P(elem));
						intl_errors_set(&err, err.code, message, 1);
						efree(message);
						delete text;
						continue;
					}
					formattable.adoptString(text);
					break;
				}
			case Formattable::kDouble:
				{
					double d;
					if (Z_TYPE_P(elem) == IS_DOUBLE) {
						d = Z_DVAL_P(elem);
					} else if (Z_TYPE_P(elem) == IS_LONG) {
						d = (double)Z_LVAL_P(elem);
					} else {
						SEPARATE_ZVAL_IF_NOT_REF(elem);
						convert_scalar_to_number(elem);
						d = (Z_TYPE_P(elem) == IS_DOUBLE)
							? Z_DVAL_P(elem)
							: (double)Z_LVAL_P(elem);
					}
					formattable.setDouble(d);
					break;
				}
			case Formattable::kLong:
				{
					int32_t tInt32 = 0;
retry_klong:
					if (Z_TYPE_P(elem) == IS_DOUBLE) {
						if (Z_DVAL_P(elem) > (double)INT32_MAX ||
								Z_DVAL_P(elem) < (double)INT32_MIN) {
							intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
								"Found PHP float with absolute value too large for "
								"32 bit integer argument", 0);
						} else {
							tInt32 = (int32_t)Z_DVAL_P(elem);
						}
					} else if (Z_TYPE_P(elem) == IS_LONG) {
						if (Z_LVAL_P(elem) > INT32_MAX ||
								Z_LVAL_P(elem) < INT32_MIN) {
							intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
								"Found PHP integer with absolute value too large "
								"for 32 bit integer argument", 0);
						} else {
							tInt32 = (int32_t)Z_LVAL_P(elem);
						}
					} else {
						SEPARATE_ZVAL_IF_NOT_REF(elem);
						convert_scalar_to_number(elem);
						goto retry_klong;
					}
					formattable.setLong(tInt32);
					break;
				}
			case Formattable::kInt64:
				{
					int64_t tInt64 = 0;
retry_kint64:
					if (Z_TYPE_P(elem) == IS_DOUBLE) {
						if (Z_DVAL_P(elem) > (double)U_INT64_MAX ||
								Z_DVAL_P(elem) < (double)U_INT64_MIN) {
							intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
								"Found PHP float with absolute value too large for "
								"64 bit integer argument", 0);
						} else {
							tInt64 = (int64_t)Z_DVAL_P(elem);
						}
					} else if (Z_TYPE_P(elem) == IS_LONG) {
						/* assume long is not wider than 64 bits */
						tInt64 = (int64_t)Z_LVAL_P(elem);
					} else {
						SEPARATE_ZVAL_IF_NOT_REF(elem);
						convert_scalar_to_number(elem);
						goto retry_kint64;
					}
					formattable.setInt64(tInt64);
					break;
				}
			case Formattable::kDate:
				{
					double dd = intl_zval_to_millis(elem, &err, "msgfmt_format");
					if (U_FAILURE(err.code)) {
						char *message;
						zend_string *u8key;
						UErrorCode status = UErrorCode();
						u8key = intl_charFromString(key, &status);
						if (u8key) {
							spprintf(&message, 0, "The argument for key '%s' "
								"cannot be used as a date or time", ZSTR_VAL(u8key));
							intl_errors_set(&err, err.code, message, 1);
							zend_string_release(u8key);
							efree(message);
						}
						continue;
					}
					formattable.setDate(dd);
					break;
				}
			default:
				intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
					"Found unsupported argument type", 0);
				break;
			}
		} else {
			/* We couldn't find any information about the argument in the pattern, this
			 * means it's an extra argument. So convert it to a number if it's a number or
			 * bool or null and to a string if it's anything else except arrays . */
			switch (Z_TYPE_P(elem)) {
			case IS_DOUBLE:
				formattable.setDouble(Z_DVAL_P(elem));
				break;
			case IS_TRUE:
			case IS_FALSE:
				convert_to_long_ex(elem);
				/* Intentional fallthrough */
			case IS_LONG:
				formattable.setInt64((int64_t)Z_LVAL_P(elem));
				break;
			case IS_NULL:
				formattable.setInt64((int64_t)0);
				break;
			case IS_STRING:
			case IS_OBJECT:
				goto string_arg;
			default:
				{
					char *message;
					zend_string *u8key;
					UErrorCode status = UErrorCode();
					u8key = intl_charFromString(key, &status);
					if (u8key) {
						spprintf(&message, 0, "No strategy to convert the "
							"value given for the argument with key '%s' "
							"is available", ZSTR_VAL(u8key));
						intl_errors_set(&err,
							U_ILLEGAL_ARGUMENT_ERROR, message, 1);
						zend_string_release(u8key);
						efree(message);
					}
				}
			}
		}
		argNum++;
	} ZEND_HASH_FOREACH_END(); // visiting each argument
示例#20
0
文件: zlib.c 项目: Furgas/php-src
static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) {
	zval *option_buffer;

	if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) {
		ZVAL_DEREF(option_buffer);
		switch (Z_TYPE_P(option_buffer)) {
			case IS_STRING: {
				zend_string *str = Z_STR_P(option_buffer);
				int i;
				zend_bool last_null = 1;

				for (i = 0; i < ZSTR_LEN(str); i++) {
					if (ZSTR_VAL(str)[i]) {
						last_null = 0;
					} else {
						if (last_null) {
							php_error_docref(NULL, E_WARNING, "dictionary string must not contain empty entries (two consecutive NULL-bytes or one at the very beginning)");
							return 0;
						}
						last_null = 1;
					}
				}
				if (!last_null) {
					php_error_docref(NULL, E_WARNING, "dictionary string must be NULL-byte terminated (each dictionary entry has to be NULL-terminated)");
				}

				*dict = emalloc(ZSTR_LEN(str));
				memcpy(*dict, ZSTR_VAL(str), ZSTR_LEN(str));
				*dictlen = ZSTR_LEN(str);
			} break;

			case IS_ARRAY: {
				HashTable *dictionary = Z_ARR_P(option_buffer);

				if (zend_hash_num_elements(dictionary) > 0) {
					char *dictptr;
					zval *cur;
					zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary));
					zend_string **end, **ptr = strings - 1;

					ZEND_HASH_FOREACH_VAL(dictionary, cur) {
						int i;

						*++ptr = zval_get_string(cur);
						if (!*ptr || ZSTR_LEN(*ptr) == 0) {
							if (*ptr) {
								efree(*ptr);
							}
							while (--ptr >= strings) {
								efree(ptr);
							}
							efree(strings);
							php_error_docref(NULL, E_WARNING, "dictionary entries must be non-empty strings");
							return 0;
						}
						for (i = 0; i < ZSTR_LEN(*ptr); i++) {
							if (ZSTR_VAL(*ptr)[i] == 0) {
								do {
									efree(ptr);
								} while (--ptr >= strings);
								efree(strings);
								php_error_docref(NULL, E_WARNING, "dictionary entries must not contain a NULL-byte");
								return 0;
							}
						}

						*dictlen += ZSTR_LEN(*ptr) + 1;
					} ZEND_HASH_FOREACH_END();

					dictptr = *dict = emalloc(*dictlen);
					ptr = strings;
					end = strings + zend_hash_num_elements(dictionary);
					do {
						memcpy(dictptr, ZSTR_VAL(*ptr), ZSTR_LEN(*ptr));
						dictptr += ZSTR_LEN(*ptr);
						*dictptr++ = 0;
						zend_string_release(*ptr);
					} while (++ptr != end);
					efree(strings);
				}
			} break;
zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory)
{
	zend_op_array *op_array;

	op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
	*op_array = persistent_script->main_op_array;

	if (EXPECTED(from_shared_memory)) {
		zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);

		ZCG(current_persistent_script) = persistent_script;
		ZCG(arena_mem) = NULL;
		if (EXPECTED(persistent_script->arena_size)) {
#ifdef __SSE2__
			/* Target address must be aligned to 64-byte boundary */
			ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size + 64);
			ZCG(arena_mem) = (void*)(((zend_uintptr_t)ZCG(arena_mem) + 63L) & ~63L);
			fast_memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size);
#else
			ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size);
			memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size);
#endif
		}

		/* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */
		if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
			zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, (unique_copy_ctor_func_t) zend_class_copy_ctor);
		}
		/* we must first to copy all classes and then prepare functions, since functions may try to bind
		   classes - which depend on pre-bind class entries existent in the class table */
		if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
			zend_accel_function_hash_copy_from_shm(CG(function_table), &persistent_script->function_table);
		}

		/* Register __COMPILER_HALT_OFFSET__ constant */
		if (persistent_script->compiler_halt_offset != 0 &&
		    persistent_script->full_path) {
			zend_string *name;
			char haltoff[] = "__COMPILER_HALT_OFFSET__";

			name = zend_mangle_property_name(haltoff, sizeof(haltoff) - 1, persistent_script->full_path->val, persistent_script->full_path->len, 0);
			if (!zend_hash_exists(EG(zend_constants), name)) {
				zend_register_long_constant(name->val, name->len, persistent_script->compiler_halt_offset, CONST_CS, 0);
			}
			zend_string_release(name);
		}

		zend_hash_destroy(&ZCG(bind_hash));
		ZCG(current_persistent_script) = NULL;
	} else /* if (!from_shared_memory) */ {
		if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
			zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table);
		}
		if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
			zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, NULL);
		}
	}

	if (op_array->early_binding != (uint32_t)-1) {
		zend_string *orig_compiled_filename = CG(compiled_filename);
		CG(compiled_filename) = persistent_script->full_path;
		zend_do_delayed_early_binding(op_array);
		CG(compiled_filename) = orig_compiled_filename;
	}

	if (UNEXPECTED(!from_shared_memory)) {
		free_persistent_script(persistent_script, 0); /* free only hashes */
	}

	return op_array;
}
示例#22
0
static int getfields(zval * fields, char * output){
	zval ** data;
	HashTable *fields_hash;
	HashPosition pointer;
	int fields_count;

	fields_hash = Z_ARRVAL_P(fields);
	fields_count = zend_hash_num_elements(fields_hash);

	char *key;
	int key_len;
	long index;
	zval ** type, ** min, ** max;
	char *temp;

	for(zend_hash_internal_pointer_reset_ex(fields_hash, &pointer);
			zend_hash_get_current_data_ex(fields_hash, (void**) &data, &pointer) == SUCCESS;
			zend_hash_move_forward_ex(fields_hash, &pointer))
	 {
		 if (zend_hash_get_current_key_ex(fields_hash, &key, &key_len,&index, 0, &pointer) == HASH_KEY_IS_STRING)
		 {
			 switch(Z_TYPE_P(*data)){
			 case IS_ARRAY:
				 if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&type) == FAILURE)
				 {
					 php_error_docref(NULL TSRMLS_CC, E_WARNING, "wrong value with:%s",key);
				 }
				 if (zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&min) == FAILURE)
				 {
					 php_error_docref(NULL TSRMLS_CC, E_WARNING, "wrong value with:%s",key);
				 }
				 if (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&max) == FAILURE)
				 {
					 php_error_docref(NULL TSRMLS_CC, E_WARNING, "wrong value with:%s",key);
				 }
				 if(strcmp(Z_STRVAL_PP(type), "int") == 0)
				 {
					 temp = (char *)emalloc(Z_LVAL_PP(max) * sizeof(int) + 2);
					 sprintf(temp, "%ld,", Z_LVAL_PP(min) + rand() % (Z_LVAL_PP(max) - Z_LVAL_PP(min)));
					 strcat(output, temp);
				 }else if(strcmp(Z_STRVAL_PP(type), "string") == 0)
				 {
					 temp = (char *)emalloc(Z_LVAL_PP(max) * sizeof(char) + 1);
					 get_rand_str(temp, Z_LVAL_PP(min), Z_LVAL_PP(max));
					 strcat(output, temp);
					 strcat(output, ",");
				 }else if(strcmp(Z_STRVAL_PP(type), "increment") == 0){
					int minvalue= Z_LVAL_PP(min);
					int step = Z_LVAL_PP(max);
					if(increment == 0){
						increment = (int)minvalue;
					}
					if(step == 0){
						step = 1;
					}
					increment+=(int)step;
					temp = (char *)emalloc(Z_LVAL_PP(max) * sizeof(int) + 2);
					sprintf(temp, "%d", increment);
					strcat(output, temp);
					strcat(output, ",");
				 }
				 break;
			 case IS_STRING:
				 temp = (char *)emalloc((Z_STRLEN_PP(data)) * sizeof(char) + 2);
				 sprintf(temp, "%s,", Z_STRVAL_PP(data));
				 strcat(output, temp);
				 break;
			 case IS_LONG:
				 temp = (char *)emalloc((Z_STRLEN_PP(data)) * sizeof(long) + 2);
				 sprintf(temp, "%ld,", Z_LVAL_PP(data));
				 strcat(output, temp);
				 break;
			 case IS_DOUBLE:
				 temp = (char *)emalloc((Z_STRLEN_PP(data)) * sizeof(double) + 2);
				 sprintf(temp, "%f,", Z_DVAL_PP(data));
				 strcat(output, temp);
				 break;
			 default:
				 break;
			 }
			 efree(temp);
		 }
	 }
	 trim(output,',',2);
}
示例#23
0
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 = &param->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 = &param->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;
}
示例#24
0
/* php_formatted_print() {{{
 * New sprintf implementation for PHP.
 *
 * Modifiers:
 *
 *  " "   pad integers with spaces
 *  "-"   left adjusted field
 *   n    field size
 *  "."n  precision (floats only)
 *  "+"   Always place a sign (+ or -) in front of a number
 *
 * Type specifiers:
 *
 *  "%"   literal "%", modifiers are ignored.
 *  "b"   integer argument is printed as binary
 *  "c"   integer argument is printed as a single character
 *  "d"   argument is an integer
 *  "f"   the argument is a float
 *  "o"   integer argument is printed as octal
 *  "s"   argument is a string
 *  "x"   integer argument is printed as lowercase hexadecimal
 *  "X"   integer argument is printed as uppercase hexadecimal
 *
 */
static char *
php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC)
{
	zval ***args, **z_format;
	int argc, size = 240, inpos = 0, outpos = 0, temppos;
	int alignment, currarg, adjusting, argnum, width, precision;
	char *format, *result, padding;
	int always_sign;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
		return NULL;
	}

	/* verify the number of args */
	if ((use_array && argc != (2 + format_offset)) 
			|| (!use_array && argc < (1 + format_offset))) {
		efree(args);
		WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
	}
	
	if (use_array) {
		int i = 1;
		zval ***newargs;
		zval **array;

		z_format = args[format_offset];
		array = args[1 + format_offset];
		
		SEPARATE_ZVAL(array);
		convert_to_array_ex(array);
		
		argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array));
		newargs = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
		newargs[0] = z_format;
		
		for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array));
			 zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS;
			 zend_hash_move_forward(Z_ARRVAL_PP(array)));

		efree(args);
		args = newargs;
		format_offset = 0;
	}
	
	convert_to_string_ex(args[format_offset]);
	format = Z_STRVAL_PP(args[format_offset]);
	result = emalloc(size);

	currarg = 1;

	while (inpos<Z_STRLEN_PP(args[format_offset])) {
		int expprec = 0, multiuse = 0;
		zval *tmp;

		PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
		PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos));
		if (format[inpos] != '%') {
			php_sprintf_appendchar(&result, &outpos, &size, format[inpos++] TSRMLS_CC);
		} else if (format[inpos + 1] == '%') {
			php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
			inpos += 2;
		} else {
			/* starting a new format specifier, reset variables */
			alignment = ALIGN_RIGHT;
			adjusting = 0;
			padding = ' ';
			always_sign = 0;
			inpos++;			/* skip the '%' */

			PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n",
						  format[inpos], inpos));
			if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) {
				/* first look for argnum */
				temppos = inpos;
				while (isdigit((int)format[temppos])) temppos++;
				if (format[temppos] == '$') {
					argnum = php_sprintf_getnumber(format, &inpos);

					if (argnum <= 0) {
						efree(result);
						efree(args);
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero");
						return NULL;
					}

					multiuse = 1;
					inpos++;  /* skip the '$' */
				} else {
					argnum = currarg++;
				}

				argnum += format_offset;

				/* after argnum comes modifiers */
				PRINTF_DEBUG(("sprintf: looking for modifiers\n"
							  "sprintf: now looking at '%c', inpos=%d\n",
							  format[inpos], inpos));
				for (;; inpos++) {
					if (format[inpos] == ' ' || format[inpos] == '0') {
						padding = format[inpos];
					} else if (format[inpos] == '-') {
						alignment = ALIGN_LEFT;
						/* space padding, the default */
					} else if (format[inpos] == '+') {
						always_sign = 1;
					} else if (format[inpos] == '\'') {
						padding = format[++inpos];
					} else {
						PRINTF_DEBUG(("sprintf: end of modifiers\n"));
						break;
					}
				}
				PRINTF_DEBUG(("sprintf: padding='%c'\n", padding));
				PRINTF_DEBUG(("sprintf: alignment=%s\n",
							  (alignment == ALIGN_LEFT) ? "left" : "right"));


				/* after modifiers comes width */
				if (isdigit((int)format[inpos])) {
					PRINTF_DEBUG(("sprintf: getting width\n"));
					if ((width = php_sprintf_getnumber(format, &inpos)) < 0) {
						efree(result);
						efree(args);
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
						return NULL;
					}
					adjusting |= ADJ_WIDTH;
				} else {
					width = 0;
				}
				PRINTF_DEBUG(("sprintf: width=%d\n", width));

				/* after width and argnum comes precision */
				if (format[inpos] == '.') {
					inpos++;
					PRINTF_DEBUG(("sprintf: getting precision\n"));
					if (isdigit((int)format[inpos])) {
						if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) {
							efree(result);
							efree(args);
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
							return NULL;
						}
						adjusting |= ADJ_PRECISION;
						expprec = 1;
					} else {
						precision = 0;
					}
				} else {
					precision = 0;
				}
				PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
			} else {
				width = precision = 0;
				argnum = currarg++ + format_offset;
			}

			if (argnum >= argc) {
				efree(result);
				efree(args);
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
				return NULL;
			}

			if (format[inpos] == 'l') {
				inpos++;
			}
			PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos]));
			/* now we expect to find a type specifier */
			if (multiuse) {
				MAKE_STD_ZVAL(tmp);
				*tmp = **(args[argnum]);
				INIT_PZVAL(tmp);
				zval_copy_ctor(tmp);
			} else {
				SEPARATE_ZVAL(args[argnum]);
				tmp = *(args[argnum]);
			}

			switch (format[inpos]) {
				case 's': {
					zval *var, var_copy;
					int use_copy;

					zend_make_printable_zval(tmp, &var_copy, &use_copy);
					if (use_copy) {
						var = &var_copy;
					} else {
						var = tmp;
					}
					php_sprintf_appendstring(&result, &outpos, &size,
											 Z_STRVAL_P(var),
											 width, precision, padding,
											 alignment,
											 Z_STRLEN_P(var),
											 0, expprec, 0);
					if (use_copy) {
						zval_dtor(&var_copy);
					}
					break;
				}

				case 'd':
					convert_to_long(tmp);
					php_sprintf_appendint(&result, &outpos, &size,
										  Z_LVAL_P(tmp),
										  width, padding, alignment,
										  always_sign);
					break;

				case 'u':
					convert_to_long(tmp);
					php_sprintf_appenduint(&result, &outpos, &size,
										  Z_LVAL_P(tmp),
										  width, padding, alignment);
					break;

				case 'g':
				case 'G':
				case 'e':
				case 'E':
				case 'f':
				case 'F':
					convert_to_double(tmp);
					php_sprintf_appenddouble(&result, &outpos, &size,
											 Z_DVAL_P(tmp),
											 width, padding, alignment,
											 precision, adjusting,
											 format[inpos], always_sign
											 TSRMLS_CC);
					break;
					
				case 'c':
					convert_to_long(tmp);
					php_sprintf_appendchar(&result, &outpos, &size,
										(char) Z_LVAL_P(tmp) TSRMLS_CC);
					break;

				case 'o':
					convert_to_long(tmp);
					php_sprintf_append2n(&result, &outpos, &size,
										 Z_LVAL_P(tmp),
										 width, padding, alignment, 3,
										 hexchars, expprec);
					break;

				case 'x':
					convert_to_long(tmp);
					php_sprintf_append2n(&result, &outpos, &size,
										 Z_LVAL_P(tmp),
										 width, padding, alignment, 4,
										 hexchars, expprec);
					break;

				case 'X':
					convert_to_long(tmp);
					php_sprintf_append2n(&result, &outpos, &size,
										 Z_LVAL_P(tmp),
										 width, padding, alignment, 4,
										 HEXCHARS, expprec);
					break;

				case 'b':
					convert_to_long(tmp);
					php_sprintf_append2n(&result, &outpos, &size,
										 Z_LVAL_P(tmp),
										 width, padding, alignment, 1,
										 hexchars, expprec);
					break;

				case '%':
					php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);

					break;
				default:
					break;
			}
			if (multiuse) {
				zval_ptr_dtor(&tmp);
			}
			inpos++;
		}
	}
	
	efree(args);
	
	/* possibly, we have to make sure we have room for the terminating null? */
	result[outpos]=0;
	*len = outpos;	
	return result;
}
示例#25
0
文件: json.c 项目: 0x1111/php-src
{
	php_info_print_table_start();
	php_info_print_table_row(2, "json support", "enabled");
	php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
	php_info_print_table_end();
}
/* }}} */

static void json_escape_string(smart_str *buf, char *s, size_t len, int options TSRMLS_DC);

static int json_determine_array_type(zval *val TSRMLS_DC) /* {{{ */
{
	int i;
	HashTable *myht = HASH_OF(val);

	i = myht ? zend_hash_num_elements(myht) : 0;
	if (i > 0) {
		zend_string *key;
		zend_ulong index, idx;

		idx = 0;
		ZEND_HASH_FOREACH_KEY(myht, index, key) {
			if (key) {
				return PHP_JSON_OUTPUT_OBJECT;
			} else {
				if (index != idx) {
					return PHP_JSON_OUTPUT_OBJECT;
				}
			}
			idx++;
		} ZEND_HASH_FOREACH_END();
static int php_mimepart_process_line(php_mimepart *workpart)
{
	size_t origcount, linelen;
	char *c;

	/* sanity check */
	if (zend_hash_num_elements(&workpart->children) > MAXPARTS) {
		php_error_docref(NULL, E_WARNING, "MIME message too complex");
		return FAILURE;
	}

	c = workpart->parsedata.workbuf.c;
	smart_string_0(&workpart->parsedata.workbuf);

	/* strip trailing \r\n -- we always have a trailing \n */
	origcount = workpart->parsedata.workbuf.len;
	linelen = origcount - 1;
	if (linelen && c[linelen-1] == '\r')
		--linelen;

	/* Discover which part we were last working on */
	while (workpart->parsedata.lastpart) {
		size_t bound_len;
		php_mimepart *lastpart = workpart->parsedata.lastpart;

		if (lastpart->parsedata.completed) {
			php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + origcount, 1);
			return SUCCESS;
		}
		if (workpart->boundary == NULL || workpart->parsedata.in_header) {
			workpart = lastpart;
			continue;
		}
		bound_len = strlen(workpart->boundary);

		/* Look for a boundary */
		if (c[0] == '-' && c[1] == '-' && linelen >= 2+bound_len && strncasecmp(workpart->boundary, c+2, bound_len) == 0) {
			php_mimepart *newpart;

			/* is it the final boundary ? */
			if (linelen >= 4 + bound_len && strncmp(c+2+bound_len, "--", 2) == 0) {
				lastpart->parsedata.completed = 1;
				php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + origcount, 1);
				return SUCCESS;
			}

			newpart = alloc_new_child_part(workpart, workpart->endpos + origcount, 1);
			php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + linelen, 1);
			newpart->mime_version = estrdup(workpart->mime_version);
			newpart->parsedata.in_header = 1;
			return SUCCESS;
		}
		workpart = lastpart;
	}

	if (!workpart->parsedata.in_header) {
		if (!workpart->parsedata.completed && !workpart->parsedata.lastpart) {
			/* update the body/part end positions.
			 * For multipart messages, the final newline belongs to the boundary.
			 * Otherwise it belongs to the body
			 * */
			if (workpart->parent && CONTENT_TYPE_ISL(workpart->parent, "multipart/", 10)) {
				php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + linelen, 1);
			} else {
				php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + origcount, 1);
			}
		}
	} else {

		if (linelen > 0) {

			php_mimepart_update_positions(workpart, workpart->endpos + origcount, workpart->endpos + linelen, 1);

      if(*c == ' ' || *c == '\t') {
        /* This doesn't technically confirm to rfc2822, as we're replacing \t with \s, but this seems to fix
         * cases where clients incorrectly fold by inserting a \t character.
         */
				smart_string_appendl(&workpart->parsedata.headerbuf, " ", 1);
        c++; linelen--;
			} else {
				php_mimepart_process_header(workpart);
			}
			/* save header for possible continuation */
			smart_string_appendl(&workpart->parsedata.headerbuf, c, linelen);

		} else {
			/* end of headers */
			php_mimepart_process_header(workpart);

			/* start of body */
			workpart->parsedata.in_header = 0;
			workpart->bodystart = workpart->endpos + origcount;
			php_mimepart_update_positions(workpart, workpart->bodystart, workpart->bodystart, 1);
			--workpart->nbodylines;

			/* some broken mailers include the content-type header but not a mime-version header.
			 * Let's relax and pretend they said they were mime 1.0 compatible */
			if (workpart->mime_version == NULL && workpart->content_type != NULL)
				workpart->mime_version = estrdup("1.0");

			if (!IS_MIME_1(workpart)) {
				/* if we don't understand the MIME version, discard the content-type and
				 * boundary */
				if (workpart->content_disposition) {
					php_mimeheader_free(workpart->content_disposition);
					workpart->content_disposition = NULL;
				}
				if (workpart->boundary) {
					efree(workpart->boundary);
					workpart->boundary = NULL;
				}
				if (workpart->content_type) {
					php_mimeheader_free(workpart->content_type);
					workpart->content_type = NULL;
				}
				workpart->content_type = php_mimeheader_alloc("text/plain");
			}
			/* if there is no content type, default to text/plain, but use multipart/digest when in
			 * a multipart/rfc822 message */
			if (IS_MIME_1(workpart) && workpart->content_type == NULL) {
				char *def_type = "text/plain";

				if (workpart->parent && CONTENT_TYPE_IS(workpart->parent, "multipart/digest"))
					def_type = "message/rfc822";

				workpart->content_type = php_mimeheader_alloc(def_type);
			}

			/* if no charset had previously been set, either through inheritance or by an
			 * explicit content-type header, default to us-ascii */
			if (workpart->charset == NULL) {
				workpart->charset = estrdup(MAILPARSEG(def_charset));
			}

			if (CONTENT_TYPE_IS(workpart, "message/rfc822")) {
				workpart = alloc_new_child_part(workpart, workpart->bodystart, 0);
				workpart->parsedata.in_header = 1;
				return SUCCESS;

			}

			/* create a section for the preamble that precedes the first boundary */
			if (workpart->boundary) {
				workpart = alloc_new_child_part(workpart, workpart->bodystart, 1);
				workpart->parsedata.in_header = 0;
				workpart->parsedata.is_dummy = 1;
				return SUCCESS;
			}

			return SUCCESS;
		}

	}

	return SUCCESS;
}
示例#27
0
/* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
   Returns true if the copy worked fine or false if error */
static PHP_METHOD(PDO, pgsqlCopyFromArray)
{
	pdo_dbh_t *dbh;
	pdo_pgsql_db_handle *H;

	zval *pg_rows;

	char *table_name, *pg_delim = NULL, *pg_null_as = NULL, *pg_fields = NULL;
	size_t table_name_len, pg_delim_len = 0, pg_null_as_len = 0, pg_fields_len;
	char *query;

	PGresult *pgsql_result;
	ExecStatusType status;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s/a|sss",
					&table_name, &table_name_len, &pg_rows,
					&pg_delim, &pg_delim_len, &pg_null_as, &pg_null_as_len, &pg_fields, &pg_fields_len) == FAILURE) {
		return;
	}

	if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) {
		php_error_docref(NULL, E_WARNING, "Cannot copy from an empty array");
		RETURN_FALSE;
	}

	dbh = Z_PDO_DBH_P(getThis());
	PDO_CONSTRUCT_CHECK;
	PDO_DBH_CLEAR_ERR();

	/* using pre-9.0 syntax as PDO_pgsql is 7.4+ compatible */
	if (pg_fields) {
		spprintf(&query, 0, "COPY %s (%s) FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, pg_fields, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
	} else {
		spprintf(&query, 0, "COPY %s FROM STDIN WITH DELIMITER E'%c' NULL AS E'%s'", table_name, (pg_delim_len ? *pg_delim : '\t'), (pg_null_as_len ? pg_null_as : "\\\\N"));
	}

	/* Obtain db Handle */
	H = (pdo_pgsql_db_handle *)dbh->driver_data;

	while ((pgsql_result = PQgetResult(H->server))) {
		PQclear(pgsql_result);
	}
	pgsql_result = PQexec(H->server, query);

	efree(query);
	query = NULL;

	if (pgsql_result) {
		status = PQresultStatus(pgsql_result);
	} else {
		status = (ExecStatusType) PQstatus(H->server);
	}

	if (status == PGRES_COPY_IN && pgsql_result) {
		int command_failed = 0;
		size_t buffer_len = 0;
		zval *tmp;

		PQclear(pgsql_result);
		ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pg_rows), tmp) {
			size_t query_len;
			convert_to_string_ex(tmp);

			if (buffer_len < Z_STRLEN_P(tmp)) {
				buffer_len = Z_STRLEN_P(tmp);
				query = erealloc(query, buffer_len + 2); /* room for \n\0 */
			}
			memcpy(query, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
			query_len = Z_STRLEN_P(tmp);
			if (query[query_len - 1] != '\n') {
				query[query_len++] = '\n';
			}
			query[query_len] = '\0';
			if (PQputCopyData(H->server, query, query_len) != 1) {
				efree(query);
				pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
				PDO_HANDLE_DBH_ERR();
				RETURN_FALSE;
			}
		} ZEND_HASH_FOREACH_END();
示例#28
0
/* Must prevent duplicates ... if there are duplicates, replace new by old! */
static void phpdbg_add_watch_collision(phpdbg_watchpoint_t *watch) {
	phpdbg_watch_collision *cur;

	/* Check for either recursive or (simple and/or implicit) */
	ZEND_ASSERT(((watch->flags & PHPDBG_WATCH_RECURSIVE) == 0) ^ ((watch->flags & (PHPDBG_WATCH_IMPLICIT | PHPDBG_WATCH_SIMPLE)) == 0));

	if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref))) {
		phpdbg_watchpoint_t *old;
		int flags = 0;
		if ((old = zend_hash_find_ptr(&cur->watches, watch->str)) || (old = zend_hash_find_ptr(&cur->implicit_watches, watch->str))) {
			if (((old->flags ^ watch->flags) & (PHPDBG_WATCH_NORMAL|PHPDBG_WATCH_IMPLICIT)) == 0) {
				return; /* there was no change ... */
			}

			flags = old->flags;

			if (flags & PHPDBG_WATCH_RECURSIVE) {
				if (!(watch->flags & PHPDBG_WATCH_RECURSIVE) && !--cur->refs) {
					phpdbg_delete_watchpoints_recursive(watch);
				}
			}
			if (flags & PHPDBG_WATCH_NORMAL) {
				zend_hash_del(&cur->watches, watch->str);
				if (zend_hash_num_elements(&cur->watches) > 0) {
					cur->watch = Z_PTR_P(zend_hash_get_current_data_ex(&cur->watches, NULL));
				} else {
					cur->watch = Z_PTR_P(zend_hash_get_current_data_ex(&cur->implicit_watches, NULL));
				}
			}
			if (flags & PHPDBG_WATCH_IMPLICIT) {
				zend_hash_del(&cur->implicit_watches, watch->str);
			}

			old->flags = watch->flags;
			phpdbg_free_watch(watch);
			efree(watch);
			watch = old;
		}
		if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
			if (!(flags & PHPDBG_WATCH_RECURSIVE) && !cur->refs++) {
				phpdbg_create_recursive_zval_watch(watch->parent);
			}
		}
	} else {
		phpdbg_watch_collision coll;
		coll.refs = (watch->flags & PHPDBG_WATCH_RECURSIVE) != 0;
		coll.watch = watch;
		zend_hash_init(&coll.watches, 8, arghs, NULL, 0);
		zend_hash_init(&coll.implicit_watches, 8, ..., NULL, 0);
		cur = zend_hash_index_add_mem(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref, &coll, sizeof(phpdbg_watch_collision));
		phpdbg_store_watchpoint(cur->watch);
		phpdbg_activate_watchpoint(cur->watch);
		if (coll.refs) {
			phpdbg_create_recursive_zval_watch(watch->parent);
		}
	}

	if (watch->flags & PHPDBG_WATCH_NORMAL) {
		cur->watch = watch;
		zend_hash_add_ptr(&cur->watches, watch->str, watch->parent);
	}
	if (watch->flags & PHPDBG_WATCH_IMPLICIT) {
		zend_hash_add_ptr(&cur->implicit_watches, watch->str, watch->parent);
	}
}
示例#29
0
PHPAPI void php_var_dump(zval *struc, int level TSRMLS_DC) /* {{{ */
{
	HashTable *myht;
	zend_string *class_name;
	int is_temp;
	int is_ref = 0;
	zend_ulong num;
	zend_string *key;
	zval *val;

	if (level > 1) {
		php_printf("%*c", level - 1, ' ');
	}

again:
	switch (Z_TYPE_P(struc)) {
		case IS_FALSE:
			php_printf("%sbool(false)\n", COMMON);
			break;
		case IS_TRUE:
			php_printf("%sbool(true)\n", COMMON);
			break;
		case IS_NULL:
			php_printf("%sNULL\n", COMMON);
			break;
		case IS_LONG:
			php_printf("%sint(" ZEND_LONG_FMT ")\n", COMMON, Z_LVAL_P(struc));
			break;
		case IS_DOUBLE:
			php_printf("%sfloat(%.*G)\n", COMMON, (int) EG(precision), Z_DVAL_P(struc));
			break;
		case IS_STRING:
			php_printf("%sstring(%d) \"", COMMON, Z_STRLEN_P(struc));
			PHPWRITE(Z_STRVAL_P(struc), Z_STRLEN_P(struc));
			PUTS("\"\n");
			break;
		case IS_ARRAY:
			myht = Z_ARRVAL_P(struc);
			if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) {
				PUTS("*RECURSION*\n");
				--myht->u.v.nApplyCount;
				return;
			}
			php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
			is_temp = 0;

			ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
				php_array_element_dump(val, num, key, level TSRMLS_CC);
			} ZEND_HASH_FOREACH_END();
			if (level > 1 && ZEND_HASH_APPLY_PROTECTION(myht)) {
				--myht->u.v.nApplyCount;
			}
			if (is_temp) {
				zend_hash_destroy(myht);
				efree(myht);
			}
			if (level > 1) {
				php_printf("%*c", level-1, ' ');
			}
			PUTS("}\n");
			break;
		case IS_OBJECT:
			myht = Z_OBJDEBUG_P(struc, is_temp);
			if (myht && ++myht->u.v.nApplyCount > 1) {
				PUTS("*RECURSION*\n");
				--myht->u.v.nApplyCount;
				return;
			}

			if (Z_OBJ_HANDLER_P(struc, get_class_name)) {
				class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc), 0 TSRMLS_CC);
				php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
				zend_string_release(class_name);
			} else {
				php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
			}
			if (myht) {
				zend_ulong num;
				zend_string *key;
				zval *val;

				ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
					php_object_property_dump(val, num, key, level TSRMLS_CC);
				} ZEND_HASH_FOREACH_END();
				--myht->u.v.nApplyCount;
				if (is_temp) {
					zend_hash_destroy(myht);
					efree(myht);
				}
			}
示例#30
0
/* {{{ mysqlnd_res_meta::set_mode */
static void
MYSQLND_METHOD(mysqlnd_debug, set_mode)(MYSQLND_DEBUG * self, const char * const mode)
{
	unsigned int mode_len = strlen(mode), i;
	enum mysqlnd_debug_parser_state state = PARSER_WAIT_MODIFIER;

	self->flags = 0;
	self->nest_level_limit = 0;
	if (self->file_name && self->file_name != mysqlnd_debug_default_trace_file) {
		efree(self->file_name);
		self->file_name = NULL;
	}
	if (zend_hash_num_elements(&self->not_filtered_functions)) {
		zend_hash_destroy(&self->not_filtered_functions);
		zend_hash_init(&self->not_filtered_functions, 0, NULL, NULL, 0);
	}

	for (i = 0; i < mode_len; i++) {
		switch (mode[i]) {
			case 'O':
			case 'A':
				self->flags |= MYSQLND_DEBUG_FLUSH;
			case 'a':
			case 'o':
				if (mode[i] == 'a' || mode[i] == 'A') {
					self->flags |= MYSQLND_DEBUG_APPEND;
				}
				if (i + 1 < mode_len && mode[i+1] == ',') {
					unsigned int j = i + 2;
					while (j < mode_len) {
						if (mode[j] == ':') {
							break;
						}
						j++;
					}
					if (j > i + 2) {
						self->file_name = estrndup(mode + i + 2, j - i - 2);
					}
					i = j;
				} else {
					if (!self->file_name)
						self->file_name = (char *) mysqlnd_debug_default_trace_file;
				}
				state = PARSER_WAIT_COLON;
				break;
			case ':':
#if 0
				if (state != PARSER_WAIT_COLON) {
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Consecutive semicolons at position %u", i);
				}
#endif
				state = PARSER_WAIT_MODIFIER;
				break;
			case 'f': /* limit output to these functions */
				if (i + 1 < mode_len && mode[i+1] == ',') {
					unsigned int j = i + 2;
					i++;
					while (j < mode_len) {
						if (mode[j] == ':') {
							/* function names with :: */
							if ((j + 1 < mode_len) && mode[j+1] == ':') {
								j += 2;
								continue;
							}
						}
						if (mode[j] == ',' || mode[j] == ':') {
							if (j > i + 2) {
								char func_name[1024];
								unsigned int func_name_len = MIN(sizeof(func_name) - 1, j - i - 1);
								memcpy(func_name, mode + i + 1, func_name_len);
								func_name[func_name_len] = '\0'; 

								zend_hash_add_empty_element(&self->not_filtered_functions,
															func_name, func_name_len + 1);
								i = j;
							}
							if (mode[j] == ':') {
								break;
							}
						}
						j++;
					}
					i = j;
				} else {
#if 0
					php_error_docref(NULL TSRMLS_CC, E_WARNING,
									 "Expected list of functions for '%c' found none", mode[i]);				
#endif
				}
				state = PARSER_WAIT_COLON;
				break;
			case 'D':
			case 'd':
			case 'g':
			case 'p':
				/* unsupported */
				if ((i + 1) < mode_len && mode[i+1] == ',') {
					i+= 2;
					while (i < mode_len) {
						if (mode[i] == ':') {
							break;
						}
						i++;
					}
				}
				state = PARSER_WAIT_COLON;
				break;
			case 'F':
				self->flags |= MYSQLND_DEBUG_DUMP_FILE;
				state = PARSER_WAIT_COLON;
				break;
			case 'i':
				self->flags |= MYSQLND_DEBUG_DUMP_PID;
				state = PARSER_WAIT_COLON;
				break;
			case 'L':
				self->flags |= MYSQLND_DEBUG_DUMP_LINE;
				state = PARSER_WAIT_COLON;
				break;
			case 'n':
				self->flags |= MYSQLND_DEBUG_DUMP_LEVEL;
				state = PARSER_WAIT_COLON;
				break;
			case 't':
				if (mode[i+1] == ',') {
					unsigned int j = i + 2;
					while (j < mode_len) {
						if (mode[j] == ':') {
							break;
						}
						j++;
					}
					if (j > i + 2) {
						char *value_str = estrndup(mode + i + 2, j - i - 2);
						self->nest_level_limit = atoi(value_str);
						efree(value_str);
					}
					i = j;
				} else {
					self->nest_level_limit = 200; /* default value for FF DBUG */
				}
				self->flags |= MYSQLND_DEBUG_DUMP_TRACE;
				state = PARSER_WAIT_COLON;
				break;
			case 'T':
				self->flags |= MYSQLND_DEBUG_DUMP_TIME;
				state = PARSER_WAIT_COLON;
				break;
			case 'N':
			case 'P':
			case 'r':
			case 'S':
				state = PARSER_WAIT_COLON;
				break;
			case 'm': /* mysqlnd extension - trace memory functions */
				self->flags |= MYSQLND_DEBUG_TRACE_MEMORY_CALLS;
				state = PARSER_WAIT_COLON;
				break;
			default:
				if (state == PARSER_WAIT_MODIFIER) {
#if 0
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized format '%c'", mode[i]);
#endif
					if (i+1 < mode_len && mode[i+1] == ',') {
						i+= 2;
						while (i < mode_len) {
							if (mode[i] == ':') {
								break;
							}
							i++;
						}
					}
					state = PARSER_WAIT_COLON;
				} else if (state == PARSER_WAIT_COLON) {
#if 0
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Colon expected, '%c' found", mode[i]);				
#endif
				}
				break;
		}
	}
}