ikitat has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
RE: variable interpolation from a filehandle
by jjhorner (Hermit) on Jun 20, 2000 at 17:26 UTC | |
Would 'eval' work? Look up perldoc -f eval to see. Update: merlyn pointed out that I should be a little more helpful. Here is the quick and dirty from the man page:
eval EXPR
eval BLOCK
In the first form, the return value of EXPR is
parsed and executed as if it were a little Perl
program. The value of the expression (which is
itself determined within scalar context) is first
parsed, and if there weren't any errors, executed
in the context of the current Perl program, so
that any variable settings or subroutine and
format definitions remain afterwards. Note that
the value is parsed every time the eval executes.
If EXPR is omitted, evaluates `$_'. This form is
typically used to delay parsing and subsequent
execution of the text of EXPR until run time.
In the second form, the code within the BLOCK is
parsed only once--at the same time the code
surrounding the eval itself was parsed--and
executed within the context of the current Perl
program. This form is typically used to trap
exceptions more efficiently than the first (see
below), while also providing the benefit of
checking the code within BLOCK at compile time.
.....
With an `eval', you should be especially careful
to remember what's being looked at when:
eval $x; # CASE 1
eval "$x"; # CASE 2
eval '$x'; # CASE 3
eval { $x }; # CASE 4
eval "\$$x++"; # CASE 5
$$x++; # CASE 6
Cases 1 and 2 above behave identically: they run
the code contained in the variable $x. (Although
case 2 has misleading double quotes making the
reader wonder what else might be happening
(nothing is).) Cases 3 and 4 likewise behave in
the same way: they run the code `'$x'', which does
nothing but return the value of $x. (Case 4 is
preferred for purely visual reasons, but it also
has the advantage of compiling at compile-time
instead of at run-time.) Case 5 is a place where
normally you would like to use double quotes,
except that in this particular situation, you can
just use symbolic references instead, as in case
6.
The short of it is this: Any perl code 'eval'ed is interpretted. You will have to figure out which fits for you. J. J. Horner Linux, Perl, Apache, Stronghold, Unix jhorner@knoxlug.org http://www.knoxlug.org/ | [reply] |
|
Re: variable interpolation from a filehandle
by ikitat (Acolyte) on Jun 20, 2000 at 18:36 UTC | |
is the answer I was looking for, works great. | [reply] [d/l] |
|
A note about security
by Fastolfe (Vicar) on Jun 21, 2000 at 00:23 UTC | |
An alternative would be to do the interpolation by hand: You could even go so far as to force the variables to come from a specific package, by using, say, ${"${package}::$1"}. That should keep them out of your regular name space. | [reply] [d/l] |
by markjugg (Curate) on Oct 05, 2000 at 03:37 UTC | |
| [reply] |
by tye (Sage) on Oct 05, 2000 at 19:00 UTC | |
Just to emphasize what "something rather malicious" can mean: I put the "echo" in so any fool who wonders what that does and cuts-and-pastes it into Perl doesn't get too burnt. So, how far do you want to trust string interpolation now? Me, I don't trust string interpolation even if I'm not doing something obviously dangerous like CGI. It becomes very easy to forget to properly guard access to your templates and end up running code that you didn't want to. Now, as for the code (slightly rewritten, just for variety -- I don't claim my version is not worse): we are quite safe. This code cannot create variables. It cannot even access variables from other packages (\w matches neither ":" nor the Perl4-ish "'") nor the built-in variables (unless you use English in your package). Even fairly nasty stuff like a tied variable whose FETCH routine sends threatening e-mail to your boss isn't a problem unless your script created such a tied variable before we interpolate the arbitrary string. So I don't see any use for the ${"${package}::$1"} suggestion in this particular case, since the same thing could be accomplished via (with yet another variation thrown in):
Finally, you can't throw a TCP/IP packet at CPAN without hitting yet another templating module. Some of these do "safe" templating. Some of them do "full power" templating where all the dangers of eval apply. Some support both modes and stuff in between. Just be careful. - tye (but my friends call me "Tye") | [reply] [d/l] [select] |
by Fastolfe (Vicar) on Oct 05, 2000 at 18:53 UTC | |
Generally so long as you have taint checking enabled and those internal taint checks are satisfied with the way you're handling untrusted data ("Trust no one."), you will typically be OK. The only places you have to be careful is in untainting data, such as where I was using a regular expression to pull variable names out of the untrusted string. So long as you know what you're doing in cases like this and trust the mechanism enough to guarantee that the data you're pulling out is trustworthy (and untainted), you should be safe. | [reply] [d/l] |
|
Re: variable interpolation from a filehandle
by lhoward (Vicar) on Jun 20, 2000 at 17:33 UTC | |
| [reply] |
|
Re: variable interpolation from a filehandle
by cbraga (Pilgrim) on Jun 20, 2000 at 18:12 UTC | |
Where $lineold contais the string to be interpolated and $linenew will contain the interpolated string. Naturally, you'll have to do that for every element in the array. Don't forget to escape all characters that can have special meanings for perl, specially if you are interpolating within html code. | [reply] [d/l] |