Subject: | Single quotes in message text breaks shell quoting |
When the message body contains a single quote, the shell quoting breaks,
resulting in an uncaught/uncaptured error from the shell along the lines
of "sh: command ' | /path/to/openssl ... not found'".
Please consider using String::ShellQuote to handle quoting of the
message text. Attached is a patch that updates the SendMail() routine to
do so.
This patch also contains a new test script that shows the (broken)
behavior of the existing code (that uses _str_replace()) and exercises
the new code that uses String::ShellQuote.
Thanks for your work on this module, it is a much better solution than
writing files to disk.
-Evan
Subject: | Crypt-Simple-SMIME.quoting.patch |
diff -Naur Crypt-Simple-SMIME-0.9.orig/lib/Crypt/Simple/SMIME.pm Crypt-Simple-SMIME-0.9/lib/Crypt/Simple/SMIME.pm
--- Crypt-Simple-SMIME-0.9.orig/lib/Crypt/Simple/SMIME.pm 2005-01-29 09:52:13.000000000 -0500
+++ Crypt-Simple-SMIME-0.9/lib/Crypt/Simple/SMIME.pm 2006-11-01 11:40:44.340919688 -0500
@@ -137,6 +137,7 @@
#
package Crypt::Simple::SMIME;
use strict;
+use String::ShellQuote qw/ shell_quote /;
use File::Temp qw/ :mktemp /;
use vars qw($VERSION);
@@ -268,7 +269,7 @@
my $result;
- $self->{encrypt_command} = "echo '\n" . $self->_str_replace('"', '\\"', $message ) . "' | $openssl smime -to '$to' -subject '$subject' -from '$from' -encrypt $pub_cert 2> $openssl_err | $sendmail -f$from -t > $sendmail_out 2> $sendmail_err";
+ $self->{encrypt_command} = "echo " . shell_quote($message) . " | $openssl smime -to '$to' -subject '$subject' -from '$from' -encrypt $pub_cert 2> $openssl_err | $sendmail -f$from -t > $sendmail_out 2> $sendmail_err";
$result = system($self->{encrypt_command});
diff -Naur Crypt-Simple-SMIME-0.9.orig/Makefile.PL Crypt-Simple-SMIME-0.9/Makefile.PL
--- Crypt-Simple-SMIME-0.9.orig/Makefile.PL 2004-10-09 17:02:50.000000000 -0400
+++ Crypt-Simple-SMIME-0.9/Makefile.PL 2006-11-01 11:59:17.124750832 -0500
@@ -6,7 +6,8 @@
VERSION_FROM => 'lib/Crypt/Simple/SMIME.pm',
PREREQ_PM => {
'File::Temp' => 0,
+ 'String::ShellQuote' => 0,
},
);
-
\ No newline at end of file
+
diff -Naur Crypt-Simple-SMIME-0.9.orig/MANIFEST Crypt-Simple-SMIME-0.9/MANIFEST
--- Crypt-Simple-SMIME-0.9.orig/MANIFEST 2005-01-29 09:47:54.000000000 -0500
+++ Crypt-Simple-SMIME-0.9/MANIFEST 2006-11-01 11:41:46.435479880 -0500
@@ -5,6 +5,7 @@
t/tmp/sendmail
t/tmp/crt
t/01_init.t
+t/02_quoting.t
t/crt/bob_cert.pem
t/crt/message.eml
t/crt/duane.pem
diff -Naur Crypt-Simple-SMIME-0.9.orig/t/02_quoting.t Crypt-Simple-SMIME-0.9/t/02_quoting.t
--- Crypt-Simple-SMIME-0.9.orig/t/02_quoting.t 1969-12-31 19:00:00.000000000 -0500
+++ Crypt-Simple-SMIME-0.9/t/02_quoting.t 2006-11-01 11:56:47.746459784 -0500
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+#
+# check for proper shell quoting
+
+use strict;
+use lib qw( ./lib ../lib );
+
+use Test::More tests => 10;
+
+use_ok('Crypt::Simple::SMIME');
+
+my $c = new Crypt::Simple::SMIME();
+
+isa_ok( $c, 'Crypt::Simple::SMIME' );
+
+{
+ my $message = q{Please don't hurt em.};
+
+ my $cmd = "echo '\n" . $c->_str_replace('"', '\\"', $message ) . "'";
+
+ # hide errors from system (`sh -c' on my system)
+ local *SAVE;
+ open( SAVE, '>&STDERR' );
+ close( STDERR );
+
+ ok( system($cmd) != 0,
+ "message with one single quote breaks shell quoting" );
+
+ open( STDERR, '>&SAVE' );
+ close( SAVE );
+}
+
+{
+ my $message = q{Please don't hurt 'em.};
+
+ my $cmd = "echo '\n" . $c->_str_replace('"', '\\"', $message ) . "'";
+
+ ok( system($cmd) == 0,
+ "message with two single quotes passes shell quoting" );
+}
+
+{
+ my $message = q{Please don"t hurt em.};
+
+ my $cmd = "echo '\n" . $c->_str_replace('"', '\\"', $message ) . "'";
+
+ ok( system($cmd) == 0,
+ "message with one double quote passes shell quoting" );
+}
+
+{
+ my $message = q{Please don"t hurt "em.};
+
+ my $cmd = "echo '\n" . $c->_str_replace('"', '\\"', $message ) . "'";
+
+ ok( system($cmd) == 0,
+ "message with two double quotes passes shell quoting" );
+}
+
+SKIP: {
+ eval { require String::ShellQuote; };
+ skip "Need String::ShellQuote for next tests", 4
+ if $@;
+
+ my $message = q{Please don't hurt em.};
+
+ my $cmd = "echo " . String::ShellQuote::shell_quote($message);
+
+ ok( system("$cmd") == 0,
+ "message with one single quote passes shell quoting" );
+
+ $message = q{Please don't hurt 'em.};
+
+ $cmd = "echo " . String::ShellQuote::shell_quote($message);
+
+ ok( system("$cmd") == 0,
+ "message with two single quotes passes shell quoting" );
+
+ $message = q{Please don"t hurt em.};
+
+ $cmd = "echo " . String::ShellQuote::shell_quote($message);
+
+ ok( system("$cmd") == 0,
+ "message with one double quote passes shell quoting" );
+
+ $message = q{Please don"t hurt "em.};
+
+ $cmd = "echo " . String::ShellQuote::shell_quote($message);
+
+ ok( system("$cmd") == 0,
+ "message with two double quotes passes shell quoting" );
+}
+