From c35d4aa26efd0907ccb48d7406dffc50f470971c Mon Sep 17 00:00:00 2001 From: "H. S. Teoh" Date: Wed, 17 Feb 2016 22:29:58 -0800 Subject: [PATCH] Fix issue 14137: std.socket.getAddressInfo breaks @safe Remove abuse of @trusted in template function getAddressInfo that cannot guarantee that the incoming type argument is @safe. Localize @trusted block of the function to the single call to getAddressInfoImpl(), so that any @system code in T will be caught by the type system. Add unittest to ensure such examples of T will be rejected at compile-time. Mark normal unittest for getAddressInfo as @safe to ensure that the function body itself does not introduce any non-@safe code. --- std/socket.d | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/std/socket.d b/std/socket.d index 94f5e321d..a98d7668e 100644 --- a/std/socket.d +++ b/std/socket.d @@ -945,7 +945,7 @@ private string formatGaiError(int err) @trusted * AddressFamily.INET6); * --- */ -AddressInfo[] getAddressInfo(T...)(in char[] node, T options) @trusted +AddressInfo[] getAddressInfo(T...)(in char[] node, T options) { const(char)[] service = null; addrinfo hints; @@ -971,7 +971,23 @@ AddressInfo[] getAddressInfo(T...)(in char[] node, T options) @trusted static assert(0, "Unknown getAddressInfo option type: " ~ typeof(option).stringof); } - return getAddressInfoImpl(node, service, &hints); + return () @trusted { return getAddressInfoImpl(node, service, &hints); }(); +} + +@system unittest +{ + struct Oops + { + const(char[]) breakSafety() + { + *cast(int*) 0xcafebabe = 0xdeadbeef; + return null; + } + alias breakSafety this; + } + assert(!__traits(compiles, () { + getAddressInfo("", Oops.init); + }), "getAddressInfo breaks @safe"); } private AddressInfo[] getAddressInfoImpl(in char[] node, in char[] service, addrinfo* hints) @system @@ -1009,7 +1025,7 @@ private AddressInfo[] getAddressInfoImpl(in char[] node, in char[] service, addr } -unittest +@safe unittest { softUnittest({ if (getaddrinfoPointer)