Is this possible in perl?

  • Thread starter madhav_a_kelkar
  • Start date
M

madhav_a_kelkar

Hi all,

I am doing XML processing in perl, i want to read a
function name from the XML file and call a function with that name at
runtime. Can I use the "require" statement for it? I was wondering if
it is possible in perl. Please help me.


Thanks,

Madhav.
 
S

Sherm Pendley

I am doing XML processing in perl, i want to read a
function name from the XML file and call a function with that name at
runtime.

Use a dispatch table. Construct a hash of code refs:

my %dispatch = (
do_this => \&this,
do_that => \&that,
do_other => \&other,
);

And then make your function call by way of the dispatch table:

# Assuming $func has been read from XML input,
if (exists $dispatch{$func}) {
$dispatch{$func}->();
} else {
# No function found for $func, so handle the error
}

See 'perldoc perlref' for lots of details. There is also an example in
'perldoc perlfaq7', at the end of the answer for "How do I create a
switch or case statement?"
Can I use the "require" statement for it?

What leads you to believe that require() has anything to do with calling
a function? See 'perldoc -f require'.

sherm--
 
J

Jürgen Exner

I am doing XML processing in perl, i want to read a
function name from the XML file and call a function with that name at
runtime.

Typically you would use a dispatch table.

You could also use eval(), but of course depending upon where your XML file
is coming from this may open a major security hole.
Can I use the "require" statement for it?

Maybe in some convoluted way. require() is certainly not something that
would come to my mind for calling a function.

jue
 
M

Mikael Andersson

Hi all,

I am doing XML processing in perl, i want to read a
function name from the XML file and call a function with that name at
runtime. Can I use the "require" statement for it? I was wondering if
it is possible in perl. Please help me.

You could create A package, lets call it Funcs.pm, and implement all you
functions there. And then do something similar to this.

use Funcs;

$toCall ="Funcs::$functionNameFromXML";
&$toCall;

/Mikael
 
S

Scott W Gifford

Hi all,

I am doing XML processing in perl, i want to read a
function name from the XML file and call a function with that name at
runtime. Can I use the "require" statement for it? I was wondering if
it is possible in perl. Please help me.

You can use eval to do that, but that will allow the XML file to cause
arbitrary code to execute on your machine:

$func = $xml->get_func_name();
eval "${func}()";

You can make that a bit more secure by only allowing word characters,
but it will still allow any function on the system to be called.

You can use symbolic references, which will allow any function to be
called:

{
no strict 'refs';
$func = $xml->get_func_name();
$func->();
}

But the most secure way would be to use "hard references" and make a
hash of allowed functions, mapping names to the reference:

my %allowed_funcs = (
func1 => \&func1,
func2 => \&func2,
);
$func = $xml->get_func_name();
$allowed_funcs{$func} or die "Can't run '$func'";
$allowed_funcs{$func}->();

That gives you precise control over what functions can be called, and
will run just fine under taint mode, "use strict", and "use warnings".

----ScottG.
 
B

Brian McCauley

Scott said:
You can use symbolic references, which will allow any function to be
called:

{
no strict 'refs';
$func = $xml->get_func_name();
$func->();
}

But the most secure way would be to use "hard references" and make a
hash of allowed functions, mapping names to the reference:

my %allowed_funcs = (
func1 => \&func1,
func2 => \&func2,
);
$func = $xml->get_func_name();
$allowed_funcs{$func} or die "Can't run '$func'";
$allowed_funcs{$func}->();

That gives you precise control over what functions can be called, and
will run just fine under taint mode, "use strict", and "use warnings".

You can keep the precise control and avoid the uglnessess of having to
list all the allowed funcs thrice by simply defining all the allowed
functions with a package prefix that you do not use for anything else.
This way you use get Perl to put the functions directly into a dispatch
table called %My::Module::XMLfunc:: and avoid the need to copy them into
another hash.

sub My::Module::XMLfunc::func1 {
# do stuff...
}

#...
{
no strict 'refs';
$func = $xml->get_func_name();
"My::Module::XMLfunc::$func"->();
}
 
P

Peter Scott

You can keep the precise control and avoid the uglnessess of having to
list all the allowed funcs thrice by simply defining all the allowed
functions with a package prefix that you do not use for anything else.
This way you use get Perl to put the functions directly into a dispatch
table called %My::Module::XMLfunc:: and avoid the need to copy them into
another hash.

sub My::Module::XMLfunc::func1 {
# do stuff...
}

#...
{
no strict 'refs';
$func = $xml->get_func_name();
"My::Module::XMLfunc::$func"->();
}

Why not

{
my $func = $xml->get_func_name();
My::Module::XMLfunc::{$func}->();
}

? Then you can use the stash for its hash advantages.
 
B

Brian McCauley

Peter said:
{


Why not

{
my $func = $xml->get_func_name();
My::Module::XMLfunc::{$func}->();
}

Well appart from the missing $ there's nothing wrong with that.

However I kinda prefer manipulations of the symbol table to look like
what they are.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top