yoooPai
yoooPai

Reputation: 26

How to get all variable names in a tcl script by not executing it?

Is it possible to return all the variable name (just like what [info globals *] does), but not even source / execute it?

Method [info globals *] is all based on that you source the tcl script file and all variables have been set in the compiler. Now I have a script, and its variable names and numbers are varing each time, or say with version changed. To prevent variable name conflicts:

  1. I want to get all variable name and unset them first (and this script cannot be written as a proc).

Upvotes: 0

Views: 268

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137627

Since it is possible to compute variable names, you could make them with a random number as part of the name. Obviously that isn't a good idea (for many reasons), but it shows why your request cannot be satisfied as you describe it.

The usual way handling this is to run the script in a separate interpreter (created with the interp create command). The script will be able to communicate with your main code by way of special commands, aliases (made with interp alias), that you can use to provide exactly the API that you want to expose. When you're done, you just interp delete and all that uncontrolled state just goes away; you simply don't have to know what variables or commands it might have made. These interpreters are considered to be security domains; care is taken to ensure that nothing leaks across by accident (or malice in the untrusted side). The main thing to watch out for is that you don't blindly trust the arguments given to you by an alias (unless that is what you want).

It isn't hard to do:

# Protected API
proc mySetter {x y} {
    global settings
    set settings($x) $y
    return
}

# Do some interpreter setup
set other [interp create]
interp alias $other setA {} mySetter A
interp alias $other setB {} mySetter B

# Run the untrusted code
interp eval $other $untrustedCode
# Or: interp eval $other [list source $filename]

# Clean up
interp delete $other

# List what settings were done
parray settings

In the above, the untrusted code can call setA 123 or setB $complicatedThing but can't alter anything else in your main interpreter. Except the global env array, because that wasn't marked as a safe interp; safe interpreters lose capabilities that can be abused (like operating system access).

Upvotes: 0

Related Questions