Version 7 of private namespace

Updated 2005-03-20 11:21:39 by CMCc

It should be possible to define a private namespace such that no external references to variables are possible, and no invocation of namespace-local procs are possible except via namespace exported names.

This would provide a nice degree of encapsulation, perhaps even a cheap sandbox and would be easy to implement.

Implementation: I suggest a form of name of namespace which can't be present in a variable or proc invocation. This means an explicit namespace-path can't be constructed for a private namespace. -- CMcC 20 Mar 2005

RS: Sandboxes are for playing - I'd hate a closed box that says "hey, you cannot see or touch my sand" in interactive debugging... Also, with escaping as needed, any string can be the name of a variable or proc. In general, I'm more happy with Tcl's spirit "You can do anything you can think of, and more" as opposed to Bondage & Discipline languages that say "Good girls don't".

CMcC RS, there's a difference between license and freedom. What you seem to be suggesting is that I can do anything I can think of except establish a private namespace, and this in the name of freedom. Sandboxing is a technical term, btw.

PWQ CMC:', What is the point of this?. We have safe interpreters, can redefine every command, what would be achieved by private namespaces?. Don't you trust your own code?

CMcC a private namespace would be cheaper and lighter weight than a safe interpreter and provide some of the same facilities. Simple as that.

NEM You can mock up a cheap sort of access-control via variable traces:

 % proc private varname {
        set varname [uplevel 1 [list namespace which -variable $varname]]
        upvar 1 $varname v
        trace add variable v {read write unset} [list CheckPerms $varname]
 }
 % proc CheckPerms {varname args} {
        set n [namespace qualifiers $varname]
        set c [string trimright [uplevel 1 [list namespace current]] "::"]
        if {$n ne $c} {
            return -code error "access violation: $c cannot access $varname"
        }
 }
 % namespace eval foo {
     variable name "Neil"
     private name
     variable age 24
     private age
 }
 % set foo::name
 can't read "foo::name": access violation:  cannot access ::foo::name
 % namespace eval foo { set name }
 Neil

The presence of namespace eval allows it to be defeated, though. You could perhaps do something more clever with checking [info level -1] to see what namespace the calling proc is in, but I don't know if you could make it absolutely secure. If you just want some protection against coding mistakes, then something like the above should do. If you really want security, then I'd go with an interp. A lightweight "better namespace" which could handle all these sorts of situations would be cool, though.

CMcC I wrote a system where untrusted code could be run from the net, in safe interps, of course. However it was quite expensive (each of the fragments of code had to persist) in that it required an interpreter per fragment. A single safe interp would suffice to protect the system from malicious code, but not to protect one piece of code from another. I think that private namespaces would go some way to achieving this goal more cheaply than safe interp.


[ Category Discussion ]