Esempio n. 1
0
PHPAPI zend_long spl_offset_convert_to_long(zval *offset) /* {{{ */
{
    zend_ulong idx;

try_again:
    switch (Z_TYPE_P(offset)) {
    case IS_STRING:
        if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), idx)) {
            return idx;
        }
        break;
    case IS_DOUBLE:
        return (zend_long)Z_DVAL_P(offset);
    case IS_LONG:
        return Z_LVAL_P(offset);
    case IS_FALSE:
        return 0;
    case IS_TRUE:
        return 1;
    case IS_REFERENCE:
        offset = Z_REFVAL_P(offset);
        goto try_again;
    case IS_RESOURCE:
        return Z_RES_HANDLE_P(offset);
    }
    return -1;
}
Esempio n. 2
0
/* {{{ mysqlnd_res_meta::read_metadata */
static enum_func_status
MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn)
{
	unsigned int i = 0;
	MYSQLND_PACKET_RES_FIELD * field_packet;

	DBG_ENTER("mysqlnd_res_meta::read_metadata");

	field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE);
	if (!field_packet) {
		SET_OOM_ERROR(conn->error_info);
		DBG_RETURN(FAIL);
	}
	field_packet->persistent_alloc = meta->persistent;
	for (;i < meta->field_count; i++) {
		zend_ulong idx;

		if (meta->fields[i].root) {
			/* We re-read metadata for PS */
			mnd_pefree(meta->fields[i].root, meta->persistent);
			meta->fields[i].root = NULL;
		}

		field_packet->metadata = &(meta->fields[i]);
		if (FAIL == PACKET_READ(field_packet)) {
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}
		if (field_packet->error_info.error_no) {
			COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info);
			/* Return back from CONN_QUERY_SENT */
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}

		if (mysqlnd_ps_fetch_functions[meta->fields[i].type].func == NULL) {
			DBG_ERR_FMT("Unknown type %u sent by the server.  Please send a report to the developers", meta->fields[i].type);
			php_error_docref(NULL, E_WARNING, "Unknown type %u sent by the server. Please send a report to the developers", meta->fields[i].type);
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}

		/* For BC we have to check whether the key is numeric and use it like this */
		if ((meta->zend_hash_keys[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet->metadata->sname, idx))) {
			meta->zend_hash_keys[i].key = idx;
		}
	}
	PACKET_FREE(field_packet);

	DBG_RETURN(PASS);
}
Esempio n. 3
0
static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops)
{
	while (elements-- > 0) {
		zval key, *data, d, *old_data;
		zend_ulong idx;

		ZVAL_UNDEF(&key);

		if (!php_var_unserialize_ex(&key, p, max, NULL, classes)) {
			zval_dtor(&key);
			return 0;
		}

		data = NULL;
		ZVAL_UNDEF(&d);

		if (!objprops) {
			if (Z_TYPE(key) == IS_LONG) {
				idx = Z_LVAL(key);
numeric_key:
				if (UNEXPECTED((old_data = zend_hash_index_find(ht, idx)) != NULL)) {
					//??? update hash
					var_push_dtor(var_hash, old_data);
					data = zend_hash_index_update(ht, idx, &d);
				} else {
					data = zend_hash_index_add_new(ht, idx, &d);
				}
			} else if (Z_TYPE(key) == IS_STRING) {
				if (UNEXPECTED(ZEND_HANDLE_NUMERIC(Z_STR(key), idx))) {
					goto numeric_key;
				}
				if (UNEXPECTED((old_data = zend_hash_find(ht, Z_STR(key))) != NULL)) {
					//??? update hash
					var_push_dtor(var_hash, old_data);
					data = zend_hash_update(ht, Z_STR(key), &d);
				} else {
					data = zend_hash_add_new(ht, Z_STR(key), &d);
				}
			} else {
				zval_dtor(&key);
				return 0;
			}
		} else {
			if (EXPECTED(Z_TYPE(key) == IS_STRING)) {
string_key:
				if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
					if (Z_TYPE_P(old_data) == IS_INDIRECT) {
						old_data = Z_INDIRECT_P(old_data);
					}
					var_push_dtor(var_hash, old_data);
					data = zend_hash_update_ind(ht, Z_STR(key), &d);
				} else {
					data = zend_hash_add_new(ht, Z_STR(key), &d);
				}
			} else if (Z_TYPE(key) == IS_LONG) {
				/* object properties should include no integers */
				convert_to_string(&key);
				goto string_key;
			} else {
				zval_dtor(&key);
				return 0;
			}
		}

		if (!php_var_unserialize_ex(data, p, max, var_hash, classes)) {
			zval_dtor(&key);
			return 0;
		}

		if (UNEXPECTED(Z_ISUNDEF_P(data))) {
			if (Z_TYPE(key) == IS_LONG) {
				zend_hash_index_del(ht, Z_LVAL(key));
			} else {
				zend_hash_del_ind(ht, Z_STR(key));
			}
		} else {
			var_push_dtor(var_hash, data);
		}

		zval_dtor(&key);

		if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
			(*p)--;
			return 0;
		}
	}

	return 1;
}
Esempio n. 4
0
void zend_optimizer_update_op2_const(zend_op_array *op_array,
                                     zend_op       *opline,
                                     zval          *val)
{
	ZEND_OP2_TYPE(opline) = IS_CONST;
	if (opline->opcode == ZEND_INIT_FCALL) {
		zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
		opline->op2.constant = zend_optimizer_add_literal(op_array, val);
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
		Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
		op_array->cache_size += sizeof(void*);
		return;
	} else if (opline->opcode == ZEND_ROPE_INIT ||
			opline->opcode == ZEND_ROPE_ADD ||
			opline->opcode == ZEND_ROPE_END ||
			opline->opcode == ZEND_CONCAT ||
			opline->opcode == ZEND_FAST_CONCAT) {
		convert_to_string(val);
	}
	opline->op2.constant = zend_optimizer_add_literal(op_array, val);
	if (Z_TYPE_P(val) == IS_STRING) {
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
		switch (opline->opcode) {
			case ZEND_FETCH_CLASS:
			case ZEND_INIT_FCALL_BY_NAME:
			/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
			case ZEND_ADD_INTERFACE:
			case ZEND_ADD_TRAIT:
			case ZEND_INSTANCEOF:
			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:
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += sizeof(void*);
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				break;
			case ZEND_INIT_DYNAMIC_CALL:
				opline->opcode = ZEND_INIT_FCALL_BY_NAME;
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += sizeof(void*);
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				break;
			case ZEND_INIT_METHOD_CALL:
			case ZEND_INIT_STATIC_METHOD_CALL:
				zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
				zend_optimizer_add_literal(op_array, val);
				zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
				/* break missing intentionally */
			/*case ZEND_FETCH_CLASS_CONSTANT:*/
			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:
				Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
				op_array->cache_size += 2 * 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) {
					Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
					op_array->cache_size += 2 * sizeof(void*);
				}
				break;
			case ZEND_OP_DATA:
				if ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
				    ((opline-1)->extended_value == ZEND_ASSIGN_DIM &&
				     ((opline-1)->opcode == ZEND_ASSIGN_ADD ||
				     (opline-1)->opcode == ZEND_ASSIGN_SUB ||
				     (opline-1)->opcode == ZEND_ASSIGN_MUL ||
				     (opline-1)->opcode == ZEND_ASSIGN_DIV ||
				     (opline-1)->opcode == ZEND_ASSIGN_POW ||
				     (opline-1)->opcode == ZEND_ASSIGN_MOD ||
				     (opline-1)->opcode == ZEND_ASSIGN_SL ||
				     (opline-1)->opcode == ZEND_ASSIGN_SR ||
				     (opline-1)->opcode == ZEND_ASSIGN_CONCAT ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_OR ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_AND ||
				     (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))) {
					goto check_numeric;
				}
				break;
			case ZEND_ISSET_ISEMPTY_DIM_OBJ:
			case ZEND_ADD_ARRAY_ELEMENT:
			case ZEND_INIT_ARRAY:
			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:
check_numeric:
				{
					zend_ulong index;

					if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
						zval_dtor(val);
						ZVAL_LONG(val, index);
						op_array->literals[opline->op2.constant] = *val;
		        	}
				}
				break;
			default:
				break;
		}
	}
}
Esempio n. 5
0
/* {{{ mysqlnd_res_meta::read_metadata */
static enum_func_status
MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn)
{
	unsigned int i = 0;
	MYSQLND_PACKET_RES_FIELD * field_packet;

	DBG_ENTER("mysqlnd_res_meta::read_metadata");

	field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE);
	if (!field_packet) {
		SET_OOM_ERROR(conn->error_info);
		DBG_RETURN(FAIL);
	}
	field_packet->persistent_alloc = meta->persistent;
	for (;i < meta->field_count; i++) {
		zend_ulong idx;

		if (meta->fields[i].root) {
			/* We re-read metadata for PS */
			mnd_pefree(meta->fields[i].root, meta->persistent);
			meta->fields[i].root = NULL;
		}

		field_packet->metadata = &(meta->fields[i]);
		if (FAIL == PACKET_READ(field_packet)) {
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}
		if (field_packet->error_info.error_no) {
			COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info);
			/* Return back from CONN_QUERY_SENT */
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}

		if (mysqlnd_ps_fetch_functions[meta->fields[i].type].func == NULL) {
			DBG_ERR_FMT("Unknown type %u sent by the server.  Please send a report to the developers", meta->fields[i].type);
			php_error_docref(NULL, E_WARNING, "Unknown type %u sent by the server. Please send a report to the developers", meta->fields[i].type);
			PACKET_FREE(field_packet);
			DBG_RETURN(FAIL);
		}
		if (meta->fields[i].type == MYSQL_TYPE_BIT) {
			size_t field_len;
			DBG_INF("BIT");
			++meta->bit_fields_count;
			/* .length is in bits */
			field_len = meta->fields[i].length / 8;
			/*
			  If there is rest, add one byte :
			  8 bits = 1 byte but 9 bits = 2 bytes
			*/
			if (meta->fields[i].length % 8) {
				++field_len;
			}
			switch (field_len) {
				case 8:
				case 7:
				case 6:
				case 5:
					meta->bit_fields_total_len += 20;/* 21 digis, no sign*/
					break;
				case 4:
					meta->bit_fields_total_len += 10;/* 2 000 000 000*/
					break;
				case 3:
					meta->bit_fields_total_len += 8;/*  12 000 000*/
					break;
				case 2:
					meta->bit_fields_total_len += 5;/* 32 500 */
					break;
				case 1:
					meta->bit_fields_total_len += 3;/* 120 */
					break;
			}
		}

		/* For BC we have to check whether the key is numeric and use it like this */
		if ((meta->zend_hash_keys[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet->metadata->sname, idx))) {
			meta->zend_hash_keys[i].key = idx;
		}
	}
	PACKET_FREE(field_packet);

	DBG_RETURN(PASS);
}
Esempio n. 6
0
static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops)
{
	while (elements-- > 0) {
		zval key, *data, d, *old_data;
		zend_ulong idx;

		ZVAL_UNDEF(&key);

		if (!php_var_unserialize_internal(&key, p, max, NULL)) {
			zval_ptr_dtor(&key);
			return 0;
		}

		data = NULL;
		ZVAL_UNDEF(&d);

		if (!objprops) {
			if (Z_TYPE(key) == IS_LONG) {
				idx = Z_LVAL(key);
numeric_key:
				if (UNEXPECTED((old_data = zend_hash_index_find(ht, idx)) != NULL)) {
					//??? update hash
					var_push_dtor(var_hash, old_data);
					data = zend_hash_index_update(ht, idx, &d);
				} else {
					data = zend_hash_index_add_new(ht, idx, &d);
				}
			} else if (Z_TYPE(key) == IS_STRING) {
				if (UNEXPECTED(ZEND_HANDLE_NUMERIC(Z_STR(key), idx))) {
					goto numeric_key;
				}
				if (UNEXPECTED((old_data = zend_hash_find(ht, Z_STR(key))) != NULL)) {
					//??? update hash
					var_push_dtor(var_hash, old_data);
					data = zend_hash_update(ht, Z_STR(key), &d);
				} else {
					data = zend_hash_add_new(ht, Z_STR(key), &d);
				}
			} else {
				zval_ptr_dtor(&key);
				return 0;
			}
		} else {
			if (EXPECTED(Z_TYPE(key) == IS_STRING)) {
string_key:
				{
					zend_property_info *existing_propinfo;
					zend_string *new_key, *unmangled;
					const char *unmangled_class = NULL; 
					const char *unmangled_prop;
					size_t unmangled_prop_len;

					if (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) {
						zval_ptr_dtor(&key);
						return 0;
					}

					unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
					if (Z_TYPE_P(rval) == IS_OBJECT
							&& ((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled)) != NULL) 
							&& (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
						if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
							new_key = zend_mangle_property_name(
								"*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
							zend_string_release(unmangled);
						} else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
							if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
								new_key = zend_mangle_property_name(
									unmangled_class, strlen(unmangled_class),
									ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
									Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
							} else {
								new_key = zend_mangle_property_name(
									ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
									ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
									Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS);
							}
							zend_string_release(unmangled);
						} else {
							ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
							new_key = unmangled;
						}
						zend_string_release(Z_STR(key));
						ZVAL_STR(&key, new_key);
					} else {
						zend_string_release(unmangled);
					}

					if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
						if (Z_TYPE_P(old_data) == IS_INDIRECT) {
							old_data = Z_INDIRECT_P(old_data);
						}
						var_push_dtor(var_hash, old_data);
						data = zend_hash_update_ind(ht, Z_STR(key), &d);
					} else {
						data = zend_hash_add_new(ht, Z_STR(key), &d);
					}
				}
			} else if (Z_TYPE(key) == IS_LONG) {
				/* object properties should include no integers */
				convert_to_string(&key);
				goto string_key;
			} else {
				zval_ptr_dtor(&key);
				return 0;
			}
		}

		if (!php_var_unserialize_internal(data, p, max, var_hash)) {
			zval_ptr_dtor(&key);
			return 0;
		}

		var_push_dtor(var_hash, data);
		zval_ptr_dtor(&key);

		if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
			(*p)--;
			return 0;
		}
	}

	return 1;
}
Esempio n. 7
0
int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
{
	zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
	int removed_ops = 0;

	if (func_info->callee_info) {
		zend_call_info *call_info = func_info->callee_info;

		do {
			if (call_info->caller_call_opline->opcode == ZEND_DO_ICALL
			 && call_info->callee_func
			 && ZSTR_LEN(call_info->callee_func->common.function_name) == sizeof("in_array")-1
			 && memcmp(ZSTR_VAL(call_info->callee_func->common.function_name), "in_array", sizeof("in_array")-1) == 0
			 && (call_info->caller_init_opline->extended_value == 2
			  || (call_info->caller_init_opline->extended_value == 3
			   && (call_info->caller_call_opline - 1)->opcode == ZEND_SEND_VAL
			   && (call_info->caller_call_opline - 1)->op1_type == IS_CONST))) {

				zend_op *send_array;
				zend_op *send_needly;
				zend_bool strict = 0;

				if (call_info->caller_init_opline->extended_value == 2) {
					send_array = call_info->caller_call_opline - 1;
					send_needly = call_info->caller_call_opline - 2;
				} else {
					if (zend_is_true(CT_CONSTANT_EX(op_array, (call_info->caller_call_opline - 1)->op1.constant))) {
						strict = 1;
					}
					send_array = call_info->caller_call_opline - 2;
					send_needly = call_info->caller_call_opline - 3;
				}

				if (send_array->opcode == ZEND_SEND_VAL
				 && send_array->op1_type == IS_CONST
				 && Z_TYPE_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)) == IS_ARRAY
				 && (send_needly->opcode == ZEND_SEND_VAL
				  || send_needly->opcode == ZEND_SEND_VAR)
			    ) {
					int ok = 1;

					HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, send_array->op1.constant));
					HashTable *dst;
					zval *val, tmp;
					zend_ulong idx;

					ZVAL_TRUE(&tmp);
					dst = zend_new_array(zend_hash_num_elements(src));
					if (strict) {
						ZEND_HASH_FOREACH_VAL(src, val) {
							if (Z_TYPE_P(val) == IS_STRING) {
								zend_hash_add(dst, Z_STR_P(val), &tmp);
							} else if (Z_TYPE_P(val) == IS_LONG) {
								zend_hash_index_add(dst, Z_LVAL_P(val), &tmp);
							} else {
								zend_array_destroy(dst);
								ok = 0;
								break;
							}
						} ZEND_HASH_FOREACH_END();
					} else {
						ZEND_HASH_FOREACH_VAL(src, val) {
							if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) {
								zend_array_destroy(dst);
								ok = 0;
								break;
							}
							zend_hash_add(dst, Z_STR_P(val), &tmp);
						} ZEND_HASH_FOREACH_END();
					}

					if (ok) {
						uint32_t op_num = send_needly - op_array->opcodes;
						zend_ssa_op *ssa_op = ssa->ops + op_num;

						if (ssa_op->op1_use >= 0) {
							/* Reconstruct SSA */
							int var_num = ssa_op->op1_use;
							zend_ssa_var *var = ssa->vars + var_num;

							ZEND_ASSERT(ssa_op->op1_def < 0);
							zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use);
							ssa_op->op1_use = -1;
							ssa_op->op1_use_chain = -1;
							op_num = call_info->caller_call_opline - op_array->opcodes;
							ssa_op = ssa->ops + op_num;
							ssa_op->op1_use = var_num;
							ssa_op->op1_use_chain = var->use_chain;
							var->use_chain = op_num;
						}

						ZVAL_ARR(&tmp, dst);

						/* Update opcode */
						call_info->caller_call_opline->opcode = ZEND_IN_ARRAY;
						call_info->caller_call_opline->extended_value = strict;
						call_info->caller_call_opline->op1_type = send_needly->op1_type;
						call_info->caller_call_opline->op1.num = send_needly->op1.num;
						call_info->caller_call_opline->op2_type = IS_CONST;
						call_info->caller_call_opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
						if (call_info->caller_init_opline->extended_value == 3) {
							MAKE_NOP(call_info->caller_call_opline - 1);
						}
						MAKE_NOP(call_info->caller_init_opline);
						MAKE_NOP(send_needly);
						MAKE_NOP(send_array);
						removed_ops++;

					}
				}
Esempio n. 8
0
int zend_optimizer_update_op2_const(zend_op_array *op_array,
                                    zend_op       *opline,
                                    zval          *val)
{
	switch (opline->opcode) {
		case ZEND_ASSIGN_REF:
			zval_dtor(val);
			return 0;
		case ZEND_FETCH_CLASS:
		case ZEND_INIT_FCALL_BY_NAME:
		/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
		case ZEND_ADD_INTERFACE:
		case ZEND_ADD_TRAIT:
		case ZEND_INSTANCEOF:
		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:
			REQUIRES_STRING(val);
			drop_leading_backslash(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
			alloc_cache_slots_op2(op_array, opline, 1);
			break;
		case ZEND_INIT_FCALL:
			REQUIRES_STRING(val);
			zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			alloc_cache_slots_op2(op_array, opline, 1);
			break;
		case ZEND_INIT_DYNAMIC_CALL:
			if (Z_TYPE_P(val) == IS_STRING) {
				if (zend_memrchr(Z_STRVAL_P(val), ':', Z_STRLEN_P(val))) {
					zval_dtor(val);
					return 0;
				}

				opline->opcode = ZEND_INIT_FCALL_BY_NAME;
				drop_leading_backslash(val);
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
				alloc_cache_slots_op2(op_array, opline, 1);
			} else {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			}
			break;
		case ZEND_INIT_METHOD_CALL:
		case ZEND_INIT_STATIC_METHOD_CALL:
			REQUIRES_STRING(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
			alloc_cache_slots_op2(op_array, opline, 2);
			break;
		/*case ZEND_FETCH_CLASS_CONSTANT:*/
		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:
			TO_STRING_NOWARN(val);
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			alloc_cache_slots_op2(op_array, opline, 2);
			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) {
				TO_STRING_NOWARN(val);
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				alloc_cache_slots_op2(op_array, opline, 2);
			} else {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			}
			break;
		case ZEND_OP_DATA:
			if ((opline-1)->opcode != ZEND_ASSIGN_DIM &&
				((opline-1)->extended_value != ZEND_ASSIGN_DIM ||
				 ((opline-1)->opcode != ZEND_ASSIGN_ADD &&
				 (opline-1)->opcode != ZEND_ASSIGN_SUB &&
				 (opline-1)->opcode != ZEND_ASSIGN_MUL &&
				 (opline-1)->opcode != ZEND_ASSIGN_DIV &&
				 (opline-1)->opcode != ZEND_ASSIGN_POW &&
				 (opline-1)->opcode != ZEND_ASSIGN_MOD &&
				 (opline-1)->opcode != ZEND_ASSIGN_SL &&
				 (opline-1)->opcode != ZEND_ASSIGN_SR &&
				 (opline-1)->opcode != ZEND_ASSIGN_CONCAT &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_OR &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_AND &&
				 (opline-1)->opcode != ZEND_ASSIGN_BW_XOR))
			) {
				opline->op2.constant = zend_optimizer_add_literal(op_array, val);
				break;
			}
			/* break missing intentionally */
		case ZEND_ISSET_ISEMPTY_DIM_OBJ:
		case ZEND_ADD_ARRAY_ELEMENT:
		case ZEND_INIT_ARRAY:
		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:
			if (Z_TYPE_P(val) == IS_STRING) {
				zend_ulong index;
				if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
					zval_dtor(val);
					ZVAL_LONG(val, index);
				}
			}
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			break;
		case ZEND_ROPE_INIT:
		case ZEND_ROPE_ADD:
		case ZEND_ROPE_END:
		case ZEND_CONCAT:
		case ZEND_FAST_CONCAT:
			TO_STRING_NOWARN(val);
			/* break missing intentionally */
		default:
			opline->op2.constant = zend_optimizer_add_literal(op_array, val);
			break;
	}

	ZEND_OP2_TYPE(opline) = IS_CONST;
	if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
		zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
	}
	return 1;
}