From 1a318dca70b3396e5a8813ff83cc6430f61ead2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Tue, 1 Nov 2016 14:49:50 +0100 Subject: [PATCH] Save image without a shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When saving into an image format, a shell meta-characters in a file name could clash with a shell used to execute convert command. This patch replaces the system() calls with safert IPC::Run3 calls. Signed-off-by: Petr Písař --- Makefile.PL | 1 + lib/Gscan2pdf/Document.pm | 44 +++++++++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index 937a023..f4fac2e 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -49,6 +49,7 @@ WriteMakefile( Gtk2::Ex::Simple::List => 0, Gtk2::ImageView => 0, Image::Magick => 0, + IPC::Run3 => 0, Locale::gettext => 1.05, Config::General => 2.40, PDF::API2 => 0, diff --git a/lib/Gscan2pdf/Document.pm b/lib/Gscan2pdf/Document.pm index 809cf72..c0e3eed 100644 --- a/lib/Gscan2pdf/Document.pm +++ b/lib/Gscan2pdf/Document.pm @@ -24,6 +24,7 @@ use Archive::Tar; # For session files use Proc::Killfam; use Locale::gettext 1.05; # For translations use IPC::Open3 'open3'; +use IPC::Run3 (); use Symbol; # for gensym use Try::Tiny; use Set::IntSpan 1.10; # For size method for page numbering issues @@ -2621,17 +2622,38 @@ sub _thread_rotate { return; } +sub _exec_command { + my ($pidfile, $command) = @_; + + open(my $fh, '>', $pidfile) or return -1; + $fh->print($PROCESS_ID); + close($fh) or return -1; + + $logger->info(join(' ', @$command)); + IPC::Run3::run3($command, undef, undef, undef, + { return_if_system_error => 1 }); + if ($? == 0) { + return 0; + } + + if ($? == -1) { + $logger->info("Could not execute the command: $!"); + } elsif ($? & 127) { + $logger->info("Command died with signal " . ($? & 127)); + } else { + $logger->info("Command failed with exit code " . ($? >> 8)); + } + return -1; +} + sub _thread_save_image { my ( $self, $path, $list_of_pages, $pidfile ) = @_; - # Escape quotes and spaces - $path =~ s/(['" ])/\\$1/gxsm; - if ( @{$list_of_pages} == 1 ) { - my $cmd = -"convert $list_of_pages->[0]{filename} -density $list_of_pages->[0]{resolution} $path"; - $logger->info($cmd); - my $status = system "echo $PROCESS_ID > $pidfile;$cmd"; + my $status = _exec_command($pidfile, + ['convert', $list_of_pages->[0]{filename}, '-density', + $list_of_pages->[0]{resolution}, $path] + ); return if $_self->{cancel}; if ($status) { $self->{status} = 1; @@ -2643,10 +2665,10 @@ sub _thread_save_image { my $i = 1; foreach ( @{$list_of_pages} ) { $current_filename = sprintf $path, $i++; - my $cmd = sprintf 'convert %s -density %d %s', - $_->{filename}, $_->{resolution}, - $current_filename; - my $status = system "echo $PROCESS_ID > $pidfile;$cmd"; + my $status = _exec_command($pidfile, + ['convert', $_->{filename}, '-density', $_->{resolution}, + $current_filename] + ); return if $_self->{cancel}; if ($status) { $self->{status} = 1; -- 2.7.4