[Python-Dev] PEP 215 redux: toward a simplified consensus?
Paul Prescod
paul@prescod.net
Mon, 25 Feb 2002 13:37:26 -0800
Jeff Epler wrote:
>
> ...
>
> Imagine that you have:
> def print_crypted_passwd(name, plaintext, salt="Xx"):
> crypted = crypt.crypt(plaintext, salt)
> print _("""%(name)s, your crypted password is %(crypted)s.""") % locals()
>
> and that some crafty devil translates this as
> msgstr "%(name)s, your plaintext password is %(plaintext). HA HA HA"
>
> i.e., the translator (or other person who can influence the format
> string) can access other information in the dict you pass in, even if
> you didn't intend it.
Right. I don't claim that this is a killer problem. I'm actually much
more concerned about the usability aspects. But if we can improve
security at the same time, then lets.
> Personally, I tend to view this as showing that using % locals() is
> unsanitary. But that means that the problem is in using the locals()
> dictionary, a problem made worse by making the use of locals() implicit.
If it is done a compile time then the crafty devil couldn't get in the
alternate string!
On the other hand, if you're doing runtime translation stuff then of
course you need to use a runtime function, like "%" or maybe a new
"interpol". I am not against the existence of such a thing. I'm against
it being the default way to do interpolation. It's like "eval" a
compile-time tool that sophisticated users have access to at runtime.
> (And under $-substitution, if locals() is implicit, how do I substitute
> with a dictionary other than locals()?
Well I don't think you should have to, because you could use the
"interpol" function (maybe from the "interpol" module). But anyhow, your
question has a factual answer and you already gave it!
> def print_crypted_passwd(accountinfo):
> def really_subst(name, crypted):
> return $"$name, your crypted password is $crypted"
> print really_subst(accountinfo.name, accountinfo.crypted)
> or
> def print_crypted_passwd(accountinfo):
> name = accountinfo.name
> crypted = accountinfo.crypted
> print $"$name, your crypted password is $crypted"
This last one looks very clear and simple to me! What's the problem with
it?
Still, I don't argue against the need for something at runtime -- as a
power tool. Either we could just keep "%" or make a function.
Okay, so my proposal for $ doesn't do everything that % does. It was
never spec'd to do everything "%" does. For instance it doesn't do float
formatting tricks.
Paul Prescod