Skip to content

Undefined behavior in Delegate::equals() #2106

@jiixyj

Description

@jiixyj

Expected behavior

equals() in Delegate.h does not trigger undefined behavior.

Actual behavior

equals() triggers UB; clang UBSan (-fsanitize=undefined) complains because of invalid member access. The reason for UB is that "other.unwrap()" can have a different type than "Delegate".

Steps to reproduce the problem

Compare two Delegates of different types with equals(). I'll try to write a simple test program.

POCO version

1.8.1

Compiler and version

Clang 5.0

Operating system and version

Ubuntu 17.10.1

Other relevant information

Maybe something like this could be workable? Still, the usage of offsetof could be problematic since it was UB before C++17 when used on non-trivial types...

	bool equals(const AbstractDelegate<TArgs>& other) const
	{
		const unsigned char* pOtherDelegate = reinterpret_cast<const unsigned char*>(other.unwrap());
		return pOtherDelegate &&
		    !std::memcmp(&_receiverObject, pOtherDelegate + offsetof(Delegate, _receiverObject), sizeof(_receiverObject)) &&
		    !std::memcmp(&_receiverMethod, pOtherDelegate + offsetof(Delegate, _receiverMethod), sizeof(_receiverMethod));
	}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions