www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - make safe "non-escapable"?

reply Robert <jfanatiker gmx.at> writes:
Making the following code illegal:

import std.stdio;
 safe {
int test1()  system {
    int* p=new int;
    *p++=8;
    return 7;
}
}

So if you mark code with  safe you can not mark parts of it to be
 system. This would make things possible like compile time import of
configurations, which would currently impossible in a safe way.

For importing the config file you would simply do:

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

Guaranteeing that the code in app.cfg has to be safe.

I thought of some wrapper like safeImport() which searches the code for
 system or  trusted and rejects the code if one of them is found. But
this is quite hard to do it right, especially with mixin's. So it's
probably best if the compiler handles this.

What do you think. Should I file a bug report?

Best regards,

Robert
Feb 06 2013
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02/06/2013 07:26 PM, Robert wrote:
 Making the following code illegal:

 import std.stdio;
  safe {
 int test1()  system {
      int* p=new int;
      *p++=8;
      return 7;
 }
 }

 So if you mark code with  safe you can not mark parts of it to be
  system. This would make things possible like compile time import of
 configurations, which would currently impossible in a safe way.

 For importing the config file you would simply do:

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

 Guaranteeing that the code in app.cfg has to be safe.

 I thought of some wrapper like safeImport() which searches the code for
  system or  trusted and rejects the code if one of them is found. But
 this is quite hard to do it right, especially with mixin's. So it's
 probably best if the compiler handles this.

 What do you think. Should I file a bug report?
 ...

I think so, yes.
Feb 06 2013
prev sibling next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
06-Feb-2013 22:26, Robert пишет:
 Making the following code illegal:

 import std.stdio;
  safe {
 int test1()  system {
      int* p=new int;
      *p++=8;
      return 7;
 }
 }

 So if you mark code with  safe you can not mark parts of it to be
  system. This would make things possible like compile time import of
 configurations, which would currently impossible in a safe way.

 For importing the config file you would simply do:

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

Nice example.
 Guaranteeing that the code in app.cfg has to be safe.

 I thought of some wrapper like safeImport() which searches the code for
  system or  trusted and rejects the code if one of them is found. But
 this is quite hard to do it right, especially with mixin's. So it's
 probably best if the compiler handles this.

 What do you think. Should I file a bug report?

Yup. -- Dmitry Olshansky
Feb 06 2013
prev sibling next sibling parent Robert <jfanatiker gmx.at> writes:
Done: http://d.puremagic.com/issues/show_bug.cgi?id=9463

Best regards,

Robert


 What do you think. Should I file a bug report?

Yup.

Feb 06 2013
prev sibling next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Wednesday, 6 February 2013 at 18:26:17 UTC, Robert wrote:
 Making the following code illegal:

 import std.stdio;
  safe {
 int test1()  system {
     int* p=new int;
     *p++=8;
     return 7;
 }
 }

 So if you Mark code with  safe you can not Mark parts of it to 
 be  system. This would make things possible like compile time 
 import of configurations, which would currently impossible in a 
 safe way.

Agreed, although you can always tighten the code rather than limit it. trusted would be the in between cases. So this would be the behavior? system { int test1() {} // system int test1() safe {} //of course! int test1() trusted {} //of course! a = b; } trusted { //disallowed for (bulk) function/type declarations //intended only for bits of code or for functions: //Otherwise an easy unchecked breeding ground for bugs! int test1() {} //error int test1() safe {} //error int test1() system {} //error int test1() trusted {} //error, yes it is, even if explicit a = b; } safe { int test1() {} // safe int test1() trusted {} //will happen from time to time. int test1() system {} //error, cannot weaken code's restrictions a = b; //only if safe }
Feb 06 2013
prev sibling next sibling parent Robert <jfanatiker gmx.at> writes:
   So this would be the behavior?
 
     system {
      int test1() {} // system
      int test1()  safe {}    //of course!
      int test1()  trusted {} //of course!
      a = b;
    }

 
     trusted { //disallowed for (bulk) function/type declarations
               //intended only for bits of code or for functions:
               //Otherwise an easy unchecked breeding ground for 
 bugs!
      int test1() {}          //error
      int test1()  safe {}    //error
      int test1()  system {}  //error
      int test1()  trusted {} //error, yes it is, even if explicit
      a = b;
    }

Why would the safe definition be an error?
 
     safe {
      int test1() {} // safe
      int test1()  trusted {} //will happen from time to time.
      int test1()  system {}  //error, cannot weaken code's 
 restrictions
      a = b; //only if safe
    }

The trusted definition must not be allowed either. trusted good is as good as system code in this context, because the compiler guarantees nothing.
Feb 06 2013
prev sibling next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Wednesday, 6 February 2013 at 22:56:56 UTC, Robert wrote:
   So this would be the behavior?
 
     system {
      int test1() {} // system
      int test1()  safe {}    //of course!
      int test1()  trusted {} //of course!
      a = b;
    }


     trusted { //disallowed for (bulk) function/type 
 declarations
               //intended only for bits of code or for 
 functions:
               //Otherwise an easy unchecked breeding ground 
 for bugs!
      int test1() {}          //error
      int test1()  safe {}    //error
      int test1()  system {}  //error
      int test1()  trusted {} //error, yes it is
                              //even if explicit
      a = b;
    }

Why would the safe definition be an error?

Because getting adding functions to a trusted area would allow some lazy programmers to say 'it just works', it would be so easy to just remove safe (and it would work). In general trusted (code blocks) in my mind shouldn't allow function/structs/any type of extra declarations as it would be so easy to make it 'seem safe' while not properly checked, or adding a new function in while not wanting to move it back and forth between writing & testing. Sides allowing safe in a trusted zone while nothing else works doesn't make sense. It would be better to disallow period all rather than give an easy route for problems later. At least with system and safe code you know where you stand. This is a personal opinion though.
     safe {
      int test1() {} // safe
      int test1()  trusted {} //will happen from time to time.
      int test1()  system {}  //error, cannot weaken code's
                              //restrictions
      a = b; //only if safe
    }

The trusted definition must not be allowed either. trusted good is as good as system code in this context, because the compiler guarantees nothing.

True, but if you have one or two functions that break safe but you know are safe, then you need to override it. Otherwise you have extra hoops to go through. If safe code can't call trusted code, then this is a non-issue (as it's just another step/tier towards safe). safe struct S { void func1(); void func2(); void func3(); void func4() trusted; } vs struct S { void func1() safe; void func2() safe; void func3() safe; void func4() trusted; } or struct S { safe { void func1(); void func2(); void func3(); } void func4() trusted; } Also seems like if you had to add a trusted function you'd have a lot of extra work just to get it 'correct' rather than allowing a trusted.
Feb 06 2013
prev sibling next sibling parent Robert <jfanatiker gmx.at> writes:
The purpose of my proposal was to be able to sandbox code. It is quite
different, whether you allow the sandboxed code calling a trusted
function, you declared or allowing the sandboxed code to declare a
trusted function, which would simply break the sandbox.
On Thu, 2013-02-07 at 01:07 +0100, Era Scarecrow wrote:
 True, but if you have one or two functions that break  safe but 
 you know are safe, then you need to override it. Otherwise you 
 have extra hoops to go through. If  safe code can't call  trusted 
 code, then this is a non-issue (as it's just another step/tier 
 towards safe).

Feb 06 2013
prev sibling next sibling parent Robert <jfanatiker gmx.at> writes:
Ok. Now I see what you mean. Good point, maybe it makes sense to extend
my proposal to simply state that  trusted,  system and  safe are simple
not overridable.

On Thu, 2013-02-07 at 01:07 +0100, Era Scarecrow wrote:
     trusted { //disallowed for (bulk) function/type 
 declarations
               //intended only for bits of code or for 
 functions:
               //Otherwise an easy unchecked breeding ground 
 for bugs!
      int test1() {}          //error
      int test1()  safe {}    //error
      int test1()  system {}  //error
      int test1()  trusted {} //error, yes it is
                              //even if explicit
      a = b;
    }

Why would the safe definition be an error?

Because getting adding functions to a trusted area would allow some lazy programmers to say 'it just works', it would be so easy to just remove safe (and it would work). In general trusted (code blocks) in my mind shouldn't allow function/structs/any type of extra declarations as it would be so easy to make it 'seem safe' while not properly checked, or adding a new function in while not wanting to move it back and forth between writing & testing. Sides allowing safe in a trusted zone while nothing else works doesn't make sense. It would be better to disallow period all rather than give an easy route for problems later. At least with system and safe code you know where you stand.

Feb 06 2013
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Wed, 06 Feb 2013 22:46:50 +0400
schrieb Dmitry Olshansky <dmitry.olsh gmail.com>:

 06-Feb-2013 22:26, Robert =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
 Guaranteeing that the code in app.cfg has to be safe.

 I thought of some wrapper like safeImport() which searches the code
 for  system or  trusted and rejects the code if one of them is
 found. But this is quite hard to do it right, especially with
 mixin's. So it's probably best if the compiler handles this.

 What do you think. Should I file a bug report?

Yup. =20

But isn't system completely useless if it can't overwrite safe as system is always the default?
Feb 06 2013
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Thu, 7 Feb 2013 08:46:55 +0100
schrieb Johannes Pfau <nospam example.com>:

 Am Wed, 06 Feb 2013 22:46:50 +0400
 schrieb Dmitry Olshansky <dmitry.olsh gmail.com>:
=20
 06-Feb-2013 22:26, Robert =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
 Guaranteeing that the code in app.cfg has to be safe.

 I thought of some wrapper like safeImport() which searches the
 code for  system or  trusted and rejects the code if one of them
 is found. But this is quite hard to do it right, especially with
 mixin's. So it's probably best if the compiler handles this.

 What do you think. Should I file a bug report?

Yup. =20

But isn't system completely useless if it can't overwrite safe as system is always the default? =20

Seems this was already discussed on the bug tracker, I should have read the bug report first :-)
Feb 06 2013
prev sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Thursday, 7 February 2013 at 07:47:00 UTC, Johannes Pfau wrote:
 But isn't  system completely useless if it can't overwrite 
  safe as  system is always the default?

safe: //not in struct/larger declaration so is acceptable system { void func(); }
Feb 07 2013