F
flyaflya
a = "(1,2,3)"
I want convert a to tuple
1,2,3),but tuple(a) return ('(', '1', ',',
'2', ',', '3', ')') not (1,2,3)
I want convert a to tuple
'2', ',', '3', ')') not (1,2,3)
flyaflya said:a = "(1,2,3)"
I want convert a to tuple1,2,3),but tuple(a) return ('(', '1', ',',
'2', ',', '3', ')') not (1,2,3)
a = "(1,2,3)"
I want convert a to tuple1,2,3),but tuple(a) return ('(', '1', ',',
'2', ',', '3', ')') not (1,2,3)
a = "(1,2,3)"
I want convert a to tuple1,2,3),but tuple(a) return ('(', '1', ',',
'2', ',', '3', ')') not (1,2,3)
Simon said:Short answer - use eval().
Long answer - *don't* use eval unless you are in control of the source
of the string that you are evaluating.
Have you tried giving it the string '__import__("os").system("rm -rf *")'?Dan said:Simon said:[...]
Or if you do use eval, don't give it access to any names.
os.system("rm -rf *")[...]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 0, in ?
NameError: name 'os' is not defined
Duncan Booth said:Have you tried giving it the string '__import__("os").system("rm -rf *")'?Dan said:Simon said:[...]
Or if you do use eval, don't give it access to any names.
os.system("rm -rf *")[...]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 0, in ?
NameError: name 'os' is not defined
[Don't try that at home children!]
Even if you take steps to avoid that working by hiding the builtins, there
are still too many ways to do nasty things with eval for it ever to be
safe.
Duncan said:Dan said:Or if you do use eval, don't give it access to any names. [snip]
os.system("rm -rf *")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 0, in ?
NameError: name 'os' is not defined
Have you tried giving it the string '__import__("os").system("rm -rf *")'?
[Don't try that at home children!]
I guess you are referring to things like this not working when you use evalSteven said:Have you tried giving it the string '__import__("os").system("rm -rf
*")'? [Don't try that at home children!]
But you can try it at home if you set __builtins__ to something other
than the default:
py> eval("""__import__("os").system('echo "hello"')""",
dict(__builtins__=None))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<string>", line 0, in ?
NameError: name '__import__' is not defined
If you're just doing work with constants, the lack of access to any
builtins is ok:
py> eval("(1,2,3)", dict(__builtins__=None))
(1, 2, 3)
I know there have been security holes in this technique before, but I
looked at the archives, and all the old ones I found have been
patched.
(Or at least I wasn't able to reproduce them.)
Duncan said:Steven said:But you can try it at home if you set __builtins__ to something other
than the default:
py> eval("""__import__("os").system('echo "hello"')""",
dict(__builtins__=None))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<string>", line 0, in ?
NameError: name '__import__' is not defined
[snip]
I know there have been security holes in this technique before, but I
looked at the archives, and all the old ones I found have been
patched.
(Or at least I wasn't able to reproduce them.)
I guess you are referring to things like this not working when you use eval
with an empty __builtins__:
eval('''[ cls for cls in {}.__class__.__bases__[0].__subclasses__()
if '_Printer' in `cls`
][0]._Printer__setup.func_globals['__builtins__']['__import__']''',
dict(__builtins__=None))
That gets blocked because func_globals is a 'restricted attribute', so I
can't get directly at __import__ that way
but what I can do is to access
any new style class you have defined and call any of its methods with
whatever arguments I wish.
Any new style class you have defined is accessible throughSteven said:Any new style class that I've defined? Or just any one I pass in as
part of dict(__builtins__=None, ...)? If the former, could you
elaborate? If the latter, then yes, I can see the problem. However
for the case where all you pass in is dict(__builtins__=None), is
there still a risk? Note that in the OP's case, all that is necessary
is constant parsing, so no names need to be available.
if 'MyDatabase' in `cls`eval('''[ cls for cls in {}.__class__.__bases__[0].__subclasses__()
Duncan said:e.g. Assuming that the MyDatabase class does something nasty to a file:
def __init__(self, filename):
self.filename = filename
def initialise(self):
print "Splat %s" % self.filename
eval('''[ cls for cls in {}.__class__.__bases__[0].__subclasses__()
if 'MyDatabase' in `cls`
][0]('importantfile').initialise()''', dict(__builtins__=None))
Splat importantfile
Steven said:Interestingly, I don't seem to be able to create a file object as a
class attribute in restricted mode:
py> class C(object):
... def __init__(self):
... self.f = file('temp.txt', 'w')
...
py> eval('''[ cls for cls in
{}.__class__.__bases__[0].__subclasses__() if cls.__name__ ==
'C'][0]().f.write("stuff")''', dict(__builtins__=None)) Traceback
(most recent call last):
File "<interactive input>", line 1, in ?
File "<string>", line 0, in ?
AttributeError: 'C' object has no attribute 'f'
py> eval('''[ cls for cls in
{}.__class__.__bases__[0].__subclasses__() if cls.__name__ ==
'C'][0]().__dict__''', dict(__builtins__=None)) {}
flyaflya said:a = "(1,2,3)"
I want convert a to tuple1,2,3),but tuple(a) return ('(', '1', ',',
'2', ',', '3', ')') not (1,2,3)
Duncan said:Steven Bethard wrote:
Interestingly, I don't seem to be able to create a file object as a
class attribute in restricted mode:
py> class C(object):
... def __init__(self):
... self.f = file('temp.txt', 'w')
...
py> eval('''[ cls for cls in
{}.__class__.__bases__[0].__subclasses__() if cls.__name__ ==
'C'][0]().f.write("stuff")''', dict(__builtins__=None)) Traceback
(most recent call last):
File "<interactive input>", line 1, in ?
File "<string>", line 0, in ?
AttributeError: 'C' object has no attribute 'f'
py> eval('''[ cls for cls in
{}.__class__.__bases__[0].__subclasses__() if cls.__name__ ==
'C'][0]().__dict__''', dict(__builtins__=None)) {}
Weird. I copied and paste your class and eval exactly (apart from deleting
the ... prompts) and it worked exactly as expected: writing 'stuff' to
temp.txt. (Python 2.4)
But unless the person eval-ing your code *only* writes immaculate code I
can see that you can probably screw them.I wonder why
__subclasses__ isn't a restricted attribute... Is it ever used for
something that isn't evil?
STeVe
Ruud said:Steven Bethard schreef:
Completely off topic, but I just cannot resist showing off.
Some time ago I used __subclasses__ in a way that is not evil. I
think.
The details are described in the following thread:
http://groups.google.nl/group/comp.lang.python/browse_thread/thread/5c1
ccb986c66cdc1/
A summary: I used __subclasses__ to apply the Chain-of-Responsibility
pattern to object creation. The code would appear to instantiate
an object of the root of a class hierarchy, but the actual object
that was created would be an instance of a subclass.
So to get back to your question: yes, there are non-evil
uses for __subclasses__. Weird perhaps, but non-evil.
Non-standard, sure . Too clever for my own good, very likely.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.