From 3b82d4adcab49e38e4905857e3298ca97eed1784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Fri, 18 Sep 2020 10:10:26 +0200 Subject: [PATCH] Fix InterfaceProxy to work with null values. Previously caused crashes and opCast!bool to return true for null instances. --- source/vibe/internal/interfaceproxy.d | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/vibe/internal/interfaceproxy.d b/source/vibe/internal/interfaceproxy.d index 203443a..47d6ad1 100644 --- a/source/vibe/internal/interfaceproxy.d +++ b/source/vibe/internal/interfaceproxy.d @@ -97,16 +97,26 @@ struct InterfaceProxy(I) if (is(I == interface)) { } this(O)(O object) @trusted + if (is(O == struct) || is(O == class) || is(O == interface)) { static assert(O.sizeof % m_value[0].sizeof == 0, "Sizeof object ("~O.stringof~") must be a multiple of a pointer size."); static assert(O.sizeof <= maxSize, "Object ("~O.stringof~") is too big to be stored in an InterfaceProxy."); import std.conv : emplace; + + static if (is(O == class) || is(O == interface)) { + if (!object) return; + } + m_intf = ProxyImpl!O.get(); static if (is(O == struct)) emplace!O(m_value[0 .. O.sizeof/m_value[0].sizeof]); swap((cast(O[])m_value[0 .. O.sizeof/m_value[0].sizeof])[0], object); } + this(typeof(null)) + { + } + ~this() @safe { clear(); @@ -304,6 +314,12 @@ struct InterfaceProxy(I) if (is(I == interface)) { } } +unittest { + static interface I {} + assert(!InterfaceProxy!I(null)); + assert(!InterfaceProxy!I(cast(I)null)); +} + private string parameterDecls(alias F, size_t idx)() { import std.format : format;