config::inifiles and retrieval of delimiter

D

Domenico Discepola

Hi all. I'm using the Config::IniFiles module & I want to store a literal
representation of a delimiter in an ini file. For ex, my ini file looks
like:

[GLOBAL]
#double quote, backslash, n, double quote
delimiter = "\n"

when I retrieve the value of the parameter delimiter, my perl variable
${delimiter} is obviously storing the literal '\n';

my ${my_iniinput} = Config::IniFiles->new( -file => "$file_ini", -nocase =>
1);
my ${delimiter} = ${my_iniinput}->val('GLOBAL', 'delimiter');

Is there a way to assign the "interpreted" value into my variable?

Unfortunately, I didn't know how to search for such a function in perldoc.

TIA
 
B

Bob Walton

Domenico said:
Hi all. I'm using the Config::IniFiles module & I want to store a literal
representation of a delimiter in an ini file. For ex, my ini file looks
like:

[GLOBAL]
#double quote, backslash, n, double quote
delimiter = "\n"

when I retrieve the value of the parameter delimiter, my perl variable
${delimiter} is obviously storing the literal '\n';

my ${my_iniinput} = Config::IniFiles->new( -file => "$file_ini", -nocase =>
1);
my ${delimiter} = ${my_iniinput}->val('GLOBAL', 'delimiter');

Is there a way to assign the "interpreted" value into my variable?


Sure. Just eval it in an interpolated string, like [untested]:

my $delimiter=eval "\"$my_iniinput->val('GLOBAL','delimiter')\"";

....
 
B

Ben Morrow

Domenico Discepola said:
Hi all. I'm using the Config::IniFiles module & I want to store a literal
representation of a delimiter in an ini file. For ex, my ini file looks
like:

[GLOBAL]
#double quote, backslash, n, double quote
delimiter = "\n"

when I retrieve the value of the parameter delimiter, my perl variable
${delimiter} is obviously storing the literal '\n';

my ${my_iniinput} = Config::IniFiles->new( -file => "$file_ini", -nocase =>
1);
my ${delimiter} = ${my_iniinput}->val('GLOBAL', 'delimiter');

<untested>

my %backwhacked = (
'\\n' => '"\n"',
'\\r' => '"\r"',
'\\t' => '"\t"',
'\\x{([[:xdigit:]]+)} => 'chr hex $1',
'\\x([[:xdigit:]]{2})' => 'chr hex $1',
'\\(0\d{1,3})' => 'chr oct $1',
etc...
);

$delimiter =~ s/$_/$backwhacked{$_}/ge for keys %backwhacked;

Ben
 
B

Ben Morrow

Domenico said:
Is there a way to assign the "interpreted" value into my variable?

Sure. Just eval it in an interpolated string, like [untested]:

my $delimiter=eval "\"$my_iniinput->val('GLOBAL','delimiter')\"";

Better is:

my $delimiter = $my_iniinput->val(...);
eval "\$delimiter = <<__EOS__;\n$delimiter\n__EOS__";
substr($delimiter, -1) = "";

as someone (Brian?) posted here not long ago. But

BE CAREFUL...

While this is the Right Answer, it will also intepolate all manner of
other things, most of which are probably undesirable. Consider
carefully before you use this.

(This is not to say that having the format of your config file be Perl
code is necessarily a bad thing, just that you need to be aware of the
implications of this.)

Ben
 
D

Domenico Discepola

Sure. Just eval it in an interpolated string, like [untested]:
my $delimiter=eval "\"$my_iniinput->val('GLOBAL','delimiter')\"";
Thank you for the code - I was able to use it to come up with this example
as well:

#!perl

use strict;
use warnings;

my $a = '\n';
my $b = eval "\"$a\"";
print "[$b]\n";
########################
Output:
[
]
 
B

Brian McCauley

Ben Morrow said:
Domenico said:
Is there a way to assign the "interpreted" value into my variable?

Sure. Just eval it in an interpolated string, like [untested]:

my $delimiter=eval "\"$my_iniinput->val('GLOBAL','delimiter')\"";

my $delimiter = $my_iniinput->val(...);
eval "\$delimiter = <<__EOS__;\n$delimiter\n__EOS__";

BTW ISTRT on older Perls you may need another \n on the end.

I would take the LHS of the assignment outside the eval(). Oh, and
semicolon is redundant:

$delimiter = eval "<<__EOS__\n$delimiter\n__EOS__";
substr($delimiter, -1) = "";

There is a special Perl function to remove the last character:

chop($delimter);

You can even combine them:

chop($delimiter = eval "<<__EOS__\n$delimiter\n__EOS__");
as someone (Brian?) posted here not long ago. But

While I do have a bee in my bonnet about this, I have to admit that I
didn't come up with the here-doc trick myself. I read about it here.
BE CAREFUL...

While this is the Right Answer, it will also intepolate all manner of
other things, most of which are probably undesirable. Consider
carefully before you use this.

(This is not to say that having the format of your config file be Perl
code is necessarily a bad thing, just that you need to be aware of the
implications of this.)

Indeed - there are many times when permission to edit the config file
already implies permission to execute arbritrary code. The most
obvious case is when the config file contains the path of an external
program to be run. When this condition exists anyhow there's no security
implication in using eval().

Consider using the String::Interpolate module. Be aware that while
String::Interpolate provides some safety it relies on the Safe module.
It plugs some of the known vulnerabilities of Safe but there are
almost certainly vulnerabilities it does not.

Oh, and the API of String::Interpolate is utterly Baroque, it was
kinda written as an example of all the different API models available
to a Perl module.

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 

Ask a Question

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.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top