Reputation: 4514
I have the following Perl script. One can (not right now because I just took it down) ping a URL like
http://www.joereddington.com/testsound/getsound.pl?text=hello%20mum
and then find that the file
http://www.joereddington.com/testsound/hope.wav
is a recording of a computer voice saying "hello mum".
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw(:standard -debug);
my $text = param('text');
$text =~ s/[^0-9a-zA-Z\s]//g;
print "Content-type: text/html\n\n";
system("/home8/projedf4/tts/espeak-1.48.04-source/src/speak \"$text\" -w hope.wav");
I'm a little nervous about having users possibly take advantage of injection attacks and the like. I believe I've done enough with the line
$text =~ s/[^0-9a-zA-Z\s]//g;
because I'm just extracting literally everything that could do damage from the string.
But is this enough? I could even go as far as
$text =~ s/[^0-9a-zA-Z\s\.,]//g;
Upvotes: 1
Views: 105
Reputation: 386541
Yeah, your code is fine (ignoring bugs in perl
, speak
, DOS attacks, etc.), assuming the only arguments that are special to speak
start with -
.
But it can be improved.
There's no need to remove so many characters.
sub shell_quote {
return map {
die if /\x00/;
my $lit = $_;
$lit =~ s/'/'\\''/g;
"'$lit'"
} @_;
}
$text =~ s/^-+//;
system(shell_quote('/.../speak', $text, '-w', 'hope.wav'));
or
use String::ShellQuote qw( shell_quote );
$text =~ s/^-+//;
system(shell_quote('/.../speak', $text, '-w', 'hope.wav'));
There's no need to launch a shell too.
die if $text =~ /\x00/;
$text =~ s/^-+//;
system('/.../speak', $text, '-w', 'hope.wav');
If your speak
supports --
, you could even use
die if $text =~ /\x00/;
system('/.../speak', '-w', 'hope.wav', '--', $text);
Upvotes: 6