November 19, 2019
https://issues.dlang.org/show_bug.cgi?id=20409

          Issue ID: 20409
           Summary: Interface parameter conversion inversed - breaking all
                    attributes enforcement
           Product: D
           Version: D2
          Hardware: All
               URL: http://dlang.org/
                OS: All
            Status: NEW
          Severity: critical
          Priority: P3
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: eyal@weka.io

Here is a simple piece of code that uses interfaces to "strengthen" any delegate arbitrarily (and incorrectly):


alias StrongDelegate = void delegate() @safe @nogc pure nothrow;
alias WeakDelegate = void delegate();

interface Interface {
    @safe @nogc pure nothrow
    StrongDelegate strengthen(WeakDelegate dlg);
}

class Class : Interface {
    @safe @nogc pure nothrow
    override StrongDelegate strengthen(StrongDelegate dlg) { return dlg; }
}


Now if you have a Class instance as an Interface, you can freely strengthen any delegate and break the type systsem. e.g:

auto func() {
    import std.typecons: scoped;
    Interface i = new Class();
    i.strengthen({
            import std.stdio: writeln;
            int i = 0x31323334;
            writeln("I'll do whatever I want, @safe-ly: ", *cast(char[4]*)&i);
        })();
}

@safe pure nothrow unittest {
    func(); // func does un-@safe things, as well as impure and throwing
things!
}

--