From 1a318dca70b3396e5a8813ff83cc6430f61ead2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
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.
<https://sourceforge.net/p/gscan2pdf/bugs/233/>
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
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