Skip to content
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Zend/tests/add_002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Notice: You have to implement the __add function in class stdClass to use this operator with an object in %sadd_002.php on line %d
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notice doesn't make sense for non-user defined classes!
I see no point in emitting it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this message does not make sense here, but I'm fine with having a notice on object to int conversion (which is undefined behavior) here.


Notice: Object of class stdClass could not be converted to number in %sadd_002.php on line %d

Exception: Unsupported operand types

Notice: You have to implement the __add function in class stdClass to use this operator with an object in %sadd_002.php on line %d

Notice: Object of class stdClass could not be converted to number in %s on line %d

Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Expand Down
4 changes: 4 additions & 0 deletions Zend/tests/add_003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ var_dump($c);
echo "Done\n";
?>
--EXPECTF--
Notice: You have to implement the __add function in class stdClass to use this operator with an object in %sadd_003.php on line %d

Notice: Object of class stdClass could not be converted to number in %sadd_003.php on line %d

Exception: Unsupported operand types

Notice: You have to implement the __add function in class stdClass to use this operator with an object in %sadd_003.php on line %d

Notice: Object of class stdClass could not be converted to number in %s on line %d

Fatal error: Uncaught Error: Unsupported operand types in %s:%d
Expand Down
16 changes: 16 additions & 0 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ struct _zend_class_entry {
zend_function *__callstatic;
zend_function *__tostring;
zend_function *__debugInfo;

/* magic functions for operator overloading */
zend_function *__add;
zend_function *__sub;
zend_function *__mul;
zend_function *__pow;
zend_function *__div;
zend_function *__concat;
zend_function *__mod;
zend_function *__shiftLeft;
zend_function *__shiftRight;
zend_function *__bitwiseOr;
zend_function *__bitwiseAnd;
zend_function *__bitwiseXor;
zend_function *__bitwiseNot;

zend_function *serialize_func;
zend_function *unserialize_func;

Expand Down
145 changes: 145 additions & 0 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,110 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce,
} else if (name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1 &&
!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && fptr->common.num_args != 0) {
zend_error(error_type, "Method %s::%s() cannot take arguments", ZSTR_VAL(ce->name), ZEND_DEBUGINFO_FUNC_NAME);
} else if (name_len == sizeof(ZEND_ADD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ADD_FUNC_NAME, sizeof(ZEND_ADD_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_ADD_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_ADD_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_ADD_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_SUB_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SUB_FUNC_NAME, sizeof(ZEND_SUB_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_SUB_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_SUB_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_SUB_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_MUL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_MUL_FUNC_NAME, sizeof(ZEND_MUL_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_MUL_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_MUL_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_MUL_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_DIV_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DIV_FUNC_NAME, sizeof(ZEND_DIV_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_DIV_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_DIV_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_DIV_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_POW_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_POW_FUNC_NAME, sizeof(ZEND_POW_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_POW_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_POW_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_POW_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_MOD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_MOD_FUNC_NAME, sizeof(ZEND_MOD_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_MOD_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_MOD_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_MOD_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_CONCAT_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CONCAT_FUNC_NAME, sizeof(ZEND_CONCAT_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), ZEND_CONCAT_FUNC_NAME);
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_CONCAT_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), ZEND_CONCAT_FUNC_NAME);
}
} else if (name_len == sizeof(ZEND_SHIFT_LEFT_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SHIFT_LEFT_FUNC_NAME, sizeof(ZEND_SHIFT_LEFT_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), "__shiftLeft");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), "__shiftLeft");
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__shiftLeft");
}
} else if (name_len == sizeof(ZEND_SHIFT_RIGHT_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SHIFT_RIGHT_FUNC_NAME, sizeof(ZEND_SHIFT_RIGHT_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), "__shiftRight");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), "__shiftRight");
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__shiftRight");
}
} else if (name_len == sizeof(ZEND_OR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_OR_FUNC_NAME, sizeof(ZEND_OR_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), "__bitwiseOr");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), "__bitwiseOr");
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__bitwiseOr");
}
} else if (name_len == sizeof(ZEND_AND_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AND_FUNC_NAME, sizeof(ZEND_AND_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), "__bitwiseAnd");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints", ZSTR_VAL(ce->name), ZEND_ADD_FUNC_NAME);
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__bitwisAnd");
}
} else if (name_len == sizeof(ZEND_XOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_XOR_FUNC_NAME, sizeof(ZEND_XOR_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 2) {
zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ZSTR_VAL(ce->name), "__bitwiseXor");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints.", ZSTR_VAL(ce->name), "__bitwiseXor");
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__bitwiseXor");
}
} else if (name_len == sizeof(ZEND_NOT_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_NOT_FUNC_NAME, sizeof(ZEND_NOT_FUNC_NAME) - 1)) {
if (fptr->common.num_args != 1) {
zend_error(error_type, "Method %s::%s() must take exactly 1 arguments", ZSTR_VAL(ce->name), "__bitwiseNot");
} else if (fptr->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_error(error_type, "Method %s::%s() can not declare argument typehints.", ZSTR_VAL(ce->name), "__bitwiseNot");
} else if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || QUICK_ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) {
zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ZSTR_VAL(ce->name), "__bitwiseNot");
}
}
}
/* }}} */
Expand All @@ -1981,6 +2085,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
HashTable *target_function_table = function_table;
int error_type;
zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL, *serialize_func = NULL, *unserialize_func = NULL;
zend_function *__add = NULL, *__sub = NULL, *__mul = NULL, *__div = NULL, *__pow = NULL, *__concat = NULL, *__mod = NULL, *__bitwiseAnd = NULL, *__bitwiseOr = NULL, *__bitwiseXor = NULL, *__bitwiseNot = NULL, *__shiftLeft = NULL, *__shiftRight = NULL;
zend_string *lowercase_name;
size_t fname_len;
const char *lc_class_name = NULL;
Expand Down Expand Up @@ -2176,6 +2281,32 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
scope->ce_flags |= ZEND_ACC_USE_GUARDS;
} else if (zend_string_equals_literal(lowercase_name, ZEND_DEBUGINFO_FUNC_NAME)) {
__debugInfo = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_ADD_FUNC_NAME)) {
__add = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_SUB_FUNC_NAME)) {
__sub = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_MUL_FUNC_NAME)) {
__mul = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_DIV_FUNC_NAME)) {
__div = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_POW_FUNC_NAME)) {
__pow = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_MOD_FUNC_NAME)) {
__mod = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_CONCAT_FUNC_NAME)) {
__concat = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_AND_FUNC_NAME)) {
__bitwiseAnd = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_OR_FUNC_NAME)) {
__bitwiseOr = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_XOR_FUNC_NAME)) {
__bitwiseXor = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_NOT_FUNC_NAME)) {
__bitwiseNot = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_SHIFT_LEFT_FUNC_NAME)) {
__shiftLeft = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_SHIFT_RIGHT_FUNC_NAME)) {
__shiftRight = reg_function;
} else {
reg_function = NULL;
}
Expand Down Expand Up @@ -2218,6 +2349,19 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
scope->__debugInfo = __debugInfo;
scope->serialize_func = serialize_func;
scope->unserialize_func = unserialize_func;
scope->__add = __add;
scope->__sub = __sub;
scope->__mul = __mul;
scope->__div = __div;
scope->__pow = __pow;
scope->__mod = __mod;
scope->__bitwiseAnd = __bitwiseAnd;
scope->__bitwiseOr = __bitwiseOr;
scope->__bitwiseXor = __bitwiseXor;
scope->__bitwiseNot = __bitwiseNot;
scope->__concat = __concat;
scope->__shiftLeft = __shiftLeft;
scope->__shiftRight = __shiftRight;
if (ctor) {
ctor->common.fn_flags |= ZEND_ACC_CTOR;
if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
Expand Down Expand Up @@ -2288,6 +2432,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
if (clone && (clone->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
zend_error_noreturn(E_CORE_ERROR, "%s::%s() cannot declare a return type", ZSTR_VAL(scope->name), ZSTR_VAL(clone->common.function_name));
}

efree((char*)lc_class_name);
}
return SUCCESS;
Expand Down
52 changes: 52 additions & 0 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,19 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
ce->serialize_func = NULL;
ce->unserialize_func = NULL;
ce->__debugInfo = NULL;
ce->__add = NULL;
ce->__sub = NULL;
ce->__mul = NULL;
ce->__div = NULL;
ce->__pow = NULL;
ce->__mod = NULL;
ce->__concat = NULL;
ce->__shiftLeft = NULL;
ce->__shiftRight = NULL;
ce->__bitwiseAnd = NULL;
ce->__bitwiseOr = NULL;
ce->__bitwiseXor = NULL;
ce->__bitwiseNot = NULL;
if (ce->type == ZEND_INTERNAL_CLASS) {
ce->info.internal.module = NULL;
ce->info.internal.builtin_functions = NULL;
Expand Down Expand Up @@ -6092,6 +6105,45 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
} else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__debugInfo", 0);
ce->__debugInfo = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__add", 1);
ce->__add = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__sub", 1);
ce->__sub = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__mul", 1);
ce->__mul = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__pow", 1);
ce->__pow = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__div", 1);
ce->__div = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_CONCAT_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__concat", 1);
ce->__concat = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__mod", 1);
ce->__mod = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_SHIFT_LEFT_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__shiftLeft", 1);
ce->__shiftLeft = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_SHIFT_RIGHT_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__shiftRight", 1);
ce->__shiftRight = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_OR_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__bitwiseOr", 1);
ce->__bitwiseOr = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_AND_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__bitwiseAnd", 1);
ce->__bitwiseAnd = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_XOR_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__bitwiseXor", 1);
ce->__bitwiseXor = (zend_function *) op_array;
} else if (zend_string_equals_literal(lcname, ZEND_NOT_FUNC_NAME)) {
zend_check_magic_method_attr(fn_flags, "__bitwiseNot", 1);
ce->__bitwiseNot = (zend_function *) op_array;
}

zend_string_release_ex(lcname, 0);
Expand Down
16 changes: 16 additions & 0 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,22 @@ END_EXTERN_C()
#define ZEND_INVOKE_FUNC_NAME "__invoke"
#define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo"


#define ZEND_ADD_FUNC_NAME "__add"
#define ZEND_SUB_FUNC_NAME "__sub"
#define ZEND_MUL_FUNC_NAME "__mul"
#define ZEND_DIV_FUNC_NAME "__div"
#define ZEND_POW_FUNC_NAME "__pow"
#define ZEND_CONCAT_FUNC_NAME "__concat"
#define ZEND_MOD_FUNC_NAME "__mod"
#define ZEND_SHIFT_LEFT_FUNC_NAME "__shiftleft"
#define ZEND_SHIFT_RIGHT_FUNC_NAME "__shiftright"
#define ZEND_OR_FUNC_NAME "__bitwiseor"
#define ZEND_AND_FUNC_NAME "__bitwiseand"
#define ZEND_XOR_FUNC_NAME "__bitwisexor"
#define ZEND_NOT_FUNC_NAME "__bitwisenot"


/* The following constants may be combined in CG(compiler_options)
* to change the default compiler behavior */

Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ void zend_register_standard_constants(void)
REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT);
REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT);

/** Operand Type not supported constant */
REGISTER_MAIN_NULL_CONSTANT("PHP_OPERAND_TYPES_NOT_SUPPORTED", CONST_PERSISTENT);

true_const = zend_hash_str_find_ptr(EG(zend_constants), "TRUE", sizeof("TRUE")-1);
false_const = zend_hash_str_find_ptr(EG(zend_constants), "FALSE", sizeof("FALSE")-1);
null_const = zend_hash_str_find_ptr(EG(zend_constants), "NULL", sizeof("NULL")-1);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1597,7 +1597,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
string_len = Z_STRLEN_P(value);
c = (zend_uchar)Z_STRVAL_P(value)[0];
}

if (string_len != 1) {
if (string_len == 0) {
/* Error on empty input string */
Expand Down
Loading