On 5/19/17 9:46 AM, Moritz Maxeiner wrote:
On Friday, 19 May 2017 at 11:53:57 UTC, Steven Schveighoffer wrote:
This provides a foundation to build completely @safe libraries.
Agreed if you mean libraries being marked completely as @safe (which I
assume).
Disagreed if you mean libraries that are proven to never corrupt memory
(not possible with unsafe operating system).
I mean libraries which only contain @safe and @system calls.
i.e.:
$ grep -R '@trusted' libsafe | wc -l
0
2. @trusted blocks in any project need to be considered red flags. You
should not need to audit @safe code.
Yes you do, because it can call into @trusted like this:
---
void foo(int[] bar) @safe
{
() @trusted {
// Exploitable code here
}();
}
---
You *must* audit third party @safe code for such hidden @trusted code
(e.g. grep recursively through such third party code for @trusted and
verify).
This is what I mean by auditing @trusted when it interacts with @safe code.
Using your example, if we confirm that no matter how you call foo, the
@trusted block cannot break memory safety, then foo becomes a verified
@safe function. Then any @safe function that calls foo can be considered
@safe without auditing.
This is actually a necessity, because templates can infer safety, so you
may not even know the call needs to be audited. The most dangerous thing
I think is to have @trusted blocks which use templated types.
A real example recently was a PR that added @safe to a function, and
made the following call:
() @trusted { return CreateDirectoryW(pathname.tempCStringW(), null); }
Where pathname was a range. The trusted block is to allow the call to
CreateDirectoryW, but inadvertently, you are trusting all the range
functions inside pathname, whatever that type is!
The correct solution is:
auto cstr = pathname.tempCStringW();
() @trusted { return CreateDirectoryW(cstr, null); }
So yes, if the third party has @trusted code, you need to audit it. But
once you have audited the *block* of trusted code, and how it interacts
within its function, you can consider the calling @safe functions
actually safe without auditing.
If we get into "@safe really means @trusted" territory, we have lost.
For code that you write yourself, @safe means @safe, of course. For code
other people write and you want to call, it being marked @safe does
really mean @trusted as long as you yourself have not looked inside it
and verified there either is no hidden @trusted, or verified *yourself*
that the hidden @trusted is memory safe.
I consider any other behaviour to be negligent to the degree of "you
don't actually care about memory safety at all".
I think there will be a good market for separating libraries between
@trusted-containing libraries, and only @safe-containing libraries. This
will make the auditing more focused, and more shareable. I don't expect
people to use Phobos and audit all the @trusted blocks personally. If "D
is memory safe" means "D is memory safe ONLY if you verify all of the
standard library personally", we still have lost.
-Steve