3 Replies - 6469 Views - Last Post: 04 February 2013 - 05:23 AM

#1 apaddobs  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 16-May 12

Evaluate a line and return as a function

Posted 02 February 2013 - 07:25 PM

I have a file that always has only one line; which needs to be evaluated and returned.

Sample files :
1. File => a.val
a,b,c (this is equivalent to
[code]
return "a,b,c";
[\code]

2. File => b.val
$ENV{CONDITION} < 5 ? "Hola" : "Buzz off"
This should be equivalent to "
[code]
return $ENV{CONDITION} < 5 ? "Hola" : "Buzz off";
[\code]

3. File => c.val
$ENV{CONDITION} == 5 ? "Hola" : "Buzz off"
[code]
return $ENV{CONDITION} == 5 ? "Hola" : "Buzz off";
[\code]

Basically, the line in the file should be "return"ed with the condition evaluated, if any. Not that I need any parsing logic; but basically a way to say "evaluate and return the text".

So, from the calling function, I want something like
[code]
my $val = parse_file ("b.val") and I should either have $val as "Hola" or "Buzz off".

Is This A Good Question/Topic? 0
  • +

Replies To: Evaluate a line and return as a function

#2 dsherohman  Icon User is online

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: Evaluate a line and return as a function

Posted 03 February 2013 - 06:33 AM

In the general case, you can evaluate a string by using the eval function.

In this particular case, however, where you want to execute code contained in another file, you can use do instead:
my $val = do "b.val";



Either way, the evaluation will have the full context of the code where you call do or eval, so you can use variables to communicate with it normally. Relying on environment settings isn't necessary unless you happen to like doing it that way.

Both methods will execute any arbitrary Perl code, not just expressions, so be sure to consider the security implications of using do/eval and, in particular, don't use them to run code coming from an untrusted source without validating it first. Only accepting input from trusted sources and then validating it anyhow is the best way to go, but may not be possible in your case. If you say more about what you actually want to achieve by evaluating snippets from these external files, we may be able to suggest other, safer ways to accomplish that.
Was This Post Helpful? 0
  • +
  • -

#3 apaddobs  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 16-May 12

Re: Evaluate a line and return as a function

Posted 03 February 2013 - 09:32 AM

Interesting. Lemme rephrase it this way. I have one single file which contains a hash of name value pairs.
$hash {name} = "name, location, age, address";
$hash {location} = "city, state, country, continent";

Instead of maintaining them all in one file, I want to have the values all stored in their respective files (so that they act more as configuration files that can be modified by anyone without modifying the file that maintains the hashes).

So I would want $hash {name} = do "name.val";
where the name.val is a file containing the string
"name,location,age,address".

In its current form, where this architecture has been passed on to me, the file format is :
<condition> ? "name, location, age" : "address";

So, the file could either simply return a string or evaluate a condition and return a string. The person who wanted to implement this, unfortunately passed away; so i really dont know what he had on mind. But I have the onus of implementing the code with a bunch of "xyz.val" already checked in the source control.

Please let me know if you want more information.
Was This Post Helpful? 0
  • +
  • -

#4 dsherohman  Icon User is online

  • Perl Parson
  • member icon

Reputation: 226
  • View blog
  • Posts: 654
  • Joined: 29-March 09

Re: Evaluate a line and return as a function

Posted 04 February 2013 - 05:23 AM

In that case, using do would certainly be the easiest and most straightforward approach. If you have control of the machine where these files are stored (or at least sufficient control that the files can only be modified by you or other trusted entities), then it should be acceptable security for most low-value systems.

If you don't have that level of control over the files' contents or the system is prominent enough to be likely to come under attack or it deals with sensitive data, then I'd recommend writing a custom parser. So long as the only possible file contents are "constant string" or "condition ? string1 : string2" and the potential conditions are all simple comparisons, an appropriate parser shouldn't take more than a dozen or so lines to implement. Probably even less with some help from CPAN - I wouldn't be surprised if you could find a suitable expression evaluator there, already written and ready to install and use.

If your security needs are somewhere in between, you could also take a look at the Safe module, which is intended to help with this sort of situation by limiting what code can be executed within the Safe compartment. I haven't personally used it, but many respected Perl programmers speak highly of it. You may also be able to define a whitelist of allowable characters and use a regular expression match to verify that no disallowed characters are present prior to evaling the line from the file (e.g., die if $line =~ /[^-_a-zA-Z0-9<>={}$ ?:]/; return eval $line;).
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1