ONPHP_METHOD(Joiner, getTablesCount) { zval *tables = ONPHP_READ_PROPERTY(getThis(), "tables"); RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(tables))); }
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 } }
#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); }
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); }
/* {{{ _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; }
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 = ¶m->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(¶m->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(¶m->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(¶m->parameter); param->param_type = PDO_PARAM_STR; convert_to_boolean(¶m->parameter); ZVAL_STRINGL(¶m->parameter, Z_TYPE_P(¶m->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)); }
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; } /* }}} */
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(); }
/* }}} */ 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); }
/** * 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(§ion, str_key); } else { ZVAL_LONG(§ion, idx); } if (unlikely(Z_TYPE_P(directives) != IS_ARRAY) || zend_hash_num_elements(Z_ARRVAL_P(directives)) == 0) { phalcon_array_update_zval(&config, §ion, 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, §ion, &directive_parts, value); } else { phalcon_array_update_multi_2(&config, §ion, &key, value, PH_COPY); } } ZEND_HASH_FOREACH_END(); }
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; } } }
/* {{{ 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; }
/* $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;
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; }
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); } } }
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; }
/* {{{ 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;
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
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; }
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); }
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, size_t inquery_len, char **outquery, size_t *outquery_len) { Scanner s; char *ptr, *newbuffer; int t; int bindno = 0; int ret = 0; size_t newbuffer_len; HashTable *params; struct pdo_bound_param_data *param; int query_type = PDO_PLACEHOLDER_NONE; struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL; ptr = *outquery; s.cur = inquery; s.end = inquery + inquery_len + 1; /* phase 1: look for args */ while((t = scan(&s)) != PDO_PARSER_EOI) { if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) { if (t == PDO_PARSER_BIND) { int len = s.cur - s.tok; if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; } else { query_type |= PDO_PLACEHOLDER_POSITIONAL; } plc = emalloc(sizeof(*plc)); memset(plc, 0, sizeof(*plc)); plc->next = NULL; plc->pos = s.tok; plc->len = s.cur - s.tok; plc->bindno = bindno++; if (placetail) { placetail->next = plc; } else { placeholders = plc; } placetail = plc; } } if (bindno == 0) { /* nothing to do; good! */ return 0; } /* did the query make sense to me? */ if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) { /* they mixed both types; punt */ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters"); ret = -1; goto clean_up; } if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) { /* query matches native syntax */ ret = 0; goto clean_up; } if (stmt->named_rewrite_template) { /* magic/hack. * We we pretend that the query was positional even if * it was named so that we fall into the * named rewrite case below. Not too pretty, * but it works. */ query_type = PDO_PLACEHOLDER_POSITIONAL; } params = stmt->bound_params; /* Do we have placeholders but no bound params */ if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound"); ret = -1; goto clean_up; } if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { /* extra bit of validation for instances when same params are bound more than once */ if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) { int ok = 1; for (plc = placeholders; plc; plc = plc->next) { if ((param = zend_hash_str_find_ptr(params, plc->pos, plc->len)) == NULL) { ok = 0; break; } } if (ok) { goto safe; } } pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens"); ret = -1; goto clean_up; } safe: /* what are we going to do ? */ if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { /* query generation */ newbuffer_len = inquery_len; /* let's quote all the values */ for (plc = placeholders; plc; plc = plc->next) { if (query_type == PDO_PLACEHOLDER_POSITIONAL) { param = zend_hash_index_find_ptr(params, plc->bindno); } else { param = zend_hash_str_find_ptr(params, plc->pos, plc->len); } if (param == NULL) { /* parameter was not defined */ ret = -1; pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined"); goto clean_up; } if (stmt->dbh->methods->quoter) { zval *parameter; if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(parameter) == IS_RESOURCE) { php_stream *stm; php_stream_from_zval_no_verify(stm, parameter); if (stm) { zend_string *buf; buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0); if (!buf) { buf = ZSTR_EMPTY_ALLOC(); } if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen, param->param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); if (buf) { zend_string_release(buf); } goto clean_up; } if (buf) { zend_string_release(buf); } } else { pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource"); ret = -1; goto clean_up; } plc->freeq = 1; } else { zval tmp_param; ZVAL_DUP(&tmp_param, parameter); switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; plc->freeq = 0; break; case IS_FALSE: case IS_TRUE: convert_to_long(&tmp_param); /* fall through */ case IS_LONG: case IS_DOUBLE: convert_to_string(&tmp_param); plc->qlen = Z_STRLEN(tmp_param); plc->quoted = estrdup(Z_STRVAL(tmp_param)); plc->freeq = 1; break; default: convert_to_string(&tmp_param); if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); goto clean_up; } plc->freeq = 1; } zval_dtor(&tmp_param); } } else { zval *parameter; if (Z_ISREF(param->parameter)) { parameter = Z_REFVAL(param->parameter); } else { parameter = ¶m->parameter; } plc->quoted = Z_STRVAL_P(parameter); plc->qlen = Z_STRLEN_P(parameter); } newbuffer_len += plc->qlen; } rewrite: /* allocate output buffer */ newbuffer = emalloc(newbuffer_len + 1); *outquery = newbuffer; /* and build the query */ plc = placeholders; ptr = inquery; do { t = plc->pos - ptr; if (t) { memcpy(newbuffer, ptr, t); newbuffer += t; } memcpy(newbuffer, plc->quoted, plc->qlen); newbuffer += plc->qlen; ptr = plc->pos + plc->len; plc = plc->next; } while (plc); t = (inquery + inquery_len) - ptr; if (t) { memcpy(newbuffer, ptr, t); newbuffer += t; } *newbuffer = '\0'; *outquery_len = newbuffer - *outquery; ret = 1; goto clean_up; } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) { /* rewrite ? to :pdoX */ char *name, *idxbuf; const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d"; int bind_no = 1; newbuffer_len = inquery_len; if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0); } for (plc = placeholders; plc; plc = plc->next) { int skip_map = 0; char *p; name = estrndup(plc->pos, plc->len); /* check if bound parameter is already available */ if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) { spprintf(&idxbuf, 0, tmpl, bind_no++); } else { idxbuf = estrdup(p); skip_map = 1; } plc->quoted = idxbuf; plc->qlen = strlen(plc->quoted); plc->freeq = 1; newbuffer_len += plc->qlen; if (!skip_map && stmt->named_rewrite_template) { /* create a mapping */ zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1); } /* map number to name */ zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1); efree(name); } goto rewrite; } else { /* rewrite :name to ? */ newbuffer_len = inquery_len; if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0); } for (plc = placeholders; plc; plc = plc->next) { char *name; name = estrndup(plc->pos, plc->len); zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1); efree(name); plc->quoted = "?"; plc->qlen = 1; } goto rewrite; } clean_up: while (placeholders) { plc = placeholders; placeholders = plc->next; if (plc->freeq) { efree(plc->quoted); } efree(plc); } return ret; }
/* php_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; }
{ 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; }
/* {{{ 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();
/* 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); } }
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); } }
/* {{{ 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; } } }