www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9463] New: make safe "non-escapable"

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463

           Summary: make  safe "non-escapable"
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: jfanatiker gmx.at



Currently the following code is valid:
 safe {
int test1()  system {
    int* p=new int;
    *p++=8;
    return 7;
}
}

So you can mark code system in an already safe section, this makes it
impossible to import code into an application in a safe way. With un-escapable
' safe' the above code would be invalid and one could do for example the
following:

 safe {
 mixin(import("app.cfg"));
}

for simply guaranteeing that app.cfg only contains safe code.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 06 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463


Jesse Phillips <Jesse.K.Phillips+D gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Jesse.K.Phillips+D gmail.co
                   |                            |m



13:59:51 PST ---
Just thought I'd mention implementation shouldn't affect

 safe:

int test1()  system {
    int* p=new int;
    *p++=8;
    return 7;
}

or at minimum:

 safe:

 system:
int test1() {
    int* p=new int;
    *p++=8;
    return 7;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463




I personally would prefer the simple consistent rule, that you can not weaken
 safe,  trusted once you declared it. If you don't want the whole file  safe,
then don't say so.

-> So when I look at code and at the beginning is  safe:, then I would know ok
this module is safe and I can use it for my mission critical stuff.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com



PST ---
The only difference between using : and {} with attributes is that {} has an
end to its scope, whereas : only ends if it's overriden by a conflicting
attribute. Differentiating between the two in terms of what they affect seems
like a really bad idea to me.

I'd argue that it's up to the functions being mixed in to guarantee that
they're  safe, not the code that's mixing them in. And attributes get ignored
all the time if they don't apply. Relying on attributes which are applied
globally with : or {} is often a bad idea precisely because dmd will happily
ignore attributes that it doesn't think are applicable.

 I personally would prefer the simple consistent rule, that you can not weaken
  safe,  trusted once you declared it. If you don't want the whole file  safe,
 then don't say so.
Except that that's always up to the function. You can't weaken safe because it was never applied in the first place. All that attribute{} or attribute: do is mark symbols with those attributes if applicable, and it doesn't apply if there's a conflicting attribute. The same happens with access levels. private { public int foo() { return 42; } } dmd quite happily makes foo public. There generally are no special cases with attributes in D (and I can't think of _any_ at the moment). If there were, it would be required to put const on the right-hand side of a function rather than the left (due to the confusion it causes by being on the left, since it looks like it applies to the return type when it doesn't), but Walter refuses to special case attributes like that. They're all treated the same on purpose. And I think that it would be a mistake to treat safe or system any differently from the rest. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463





 The only difference between using : and {} with attributes is that {} has an
 end to its scope, whereas : only ends if it's overriden by a conflicting
 attribute. Differentiating between the two in terms of what they affect seems
 like a really bad idea to me.
 
 I'd argue that it's up to the functions being mixed in to guarantee that
 they're  safe, not the code that's mixing them in. And attributes get ignored
 all the time if they don't apply. Relying on attributes which are applied
 globally with : or {} is often a bad idea precisely because dmd will happily
 ignore attributes that it doesn't think are applicable.
Yeah, but what if you can not trust the code you are mixing in to declare it self safe, like in the example with the imported configuration. You could validate the code, by greping for system and trusted but this would be pretty unreliable, especially with mixins. So you would end up writing your own D parser. The goal of this feature is to make D more viable for problems one would usually pick a scripting language.
 
 I personally would prefer the simple consistent rule, that you can not weaken
  safe,  trusted once you declared it. If you don't want the whole file  safe,
 then don't say so.
Except that that's always up to the function. You can't weaken safe because it was never applied in the first place. All that attribute{} or attribute: do is mark symbols with those attributes if applicable, and it doesn't apply if there's a conflicting attribute. The same happens with access levels. private { public int foo() { return 42; } } dmd quite happily makes foo public. There generally are no special cases with attributes in D (and I can't think of _any_ at the moment). If there were, it would be required to put const on the right-hand side of a function rather
Thanks for this good explanation. But maybe there is a good solution, simply say that safe is not applicable if a function was previously marked system or trusted. (Might be a problem, because system is the default, but this could easily be worked around by internally distinguishing between explicitly assigned system and implicit system). So it bails down to the meaning of "applicable". I just think that this would greatly enhance the usefulness of safe code. (Easy and efficient sandboxing) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463




PST ---
 But maybe there is a good solution, simply say that  safe is not applicable if
> a function was previously marked  system or  trusted
That's what it does. The function in your example is system, so the the fact that there's an safe block around it doesn't affect it.
 Yeah, but what if you can not trust the code you are mixing in to declare it
 self  safe, like in the example with the imported configuration. You could
 validate the code, by greping for  system and  trusted but this would be
 pretty unreliable, especially with mixins. So you would end up writing your
 own D parser.
Except that you should know what you're mixing in. And you probably shouldn't be mixing in anything that you haven't written yourself. That's just asking for it IMHO. And whether it's safe or trusted or whatever doesn't matter much except to the caller, and the caller protects itself by marking itself safe. You'll then get a compilation error if a function isn't safe like it's supposed to be. And if you're mixing in code like that as part of your API (in which case, the only way that you'd catch the problem would be unit testse), then you should probably rethink your API anyway. Mixed in code doesn't appear in the documentation. And if your issue is with scripting, then you're not writing an API. You're writing a script. So, you have full control over your code even if you don't control the code that you're mixing in for some reason (as bad as that would be), and anything safe calling the functions will immediately give an error for system functions. In that case, the only ways an system function wouldn't be caught is if it's never used (in which case it doesn't matter) or if it's called by another system or trusted function. I honestly don't understand what you're doing that would require you to validate that the functions being mixed and are safe at the point that they're mixed in. That validation will happen when they're used. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463




 it IMHO. And whether it's  safe or  trusted or whatever doesn't matter much
 except to the caller, and the caller protects itself by marking itself  safe.
You are absolutely right, except for static this(). Maybe for importing stuff, pre-evaluation and rejecting things like static this() might be the way to go. For having modules dynamically linked in, (instead of extending an application via scripts), maybe a compiler switch -safe causing the compiler only to accept safe code would be a better idea. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 06 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463


jfanatiker gmx.at changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



Thanks Jonathan!

By simply mixing in the code in a safe function like this:

 safe void parseConfig() {
  mixin(import("app.cfg"));
}

you have all guarantees you need.

For extending an application in a safe way, a compiler switch '-safe' would be
the better way. It would be simpler to implement and completely backwards
compatible. 

Closing this issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 06 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9463




Sadly, this compiles:

 safe int test2() {
    class Test {
         system static this()  {
            int *p=new int;
            *p++=8;
        }
    }
    return 10;
}

So no silver bullet either, but smart filtering of source code, disallowing
mixin and static this, should do the trick.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 07 2013