develooper Front page | perl.perl5.porters | Postings from January 2006

[perl #38387] Net::Cmd does not handle CR and LF correctly

From:
alexander_bluhm @ genua . de
Date:
January 31, 2006 16:31
Subject:
[perl #38387] Net::Cmd does not handle CR and LF correctly
Message ID:
rt-3.0.11-38387-129088.2.35545406678717@perl.org
# New Ticket Created by  alexander_bluhm@genua.de 
# Please include the string:  [perl #38387]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=38387 >



This is a bug report for perl from alexander_bluhm@genua.de,
generated with the help of perlbug 1.35 running under perl v5.8.6.


-----------------------------------------------------------------
[Please enter your report here]

Hi,

The escaping of CR and LF in Net::Cmd->dataend is somewhat broken.
A sequence "a\r" is escaped as "a\015\015\012.\015\012".
There is even a test for this behavior.  But it does not conform
to RFC 2821 Section 2.3.7:

   In addition, the appearance of "bare" "CR" or "LF" characters in text
   (i.e., either without the other) has a long history of causing
   problems in mail implementations and applications that use the mail
   system as a tool.  SMTP client implementations MUST NOT transmit
   these characters except when they are intended as line terminators
   and then MUST, as indicated above, transmit them only as a <CRLF>
   sequence.

So sending the sequence "\015\015" is illegal because the first
"\015" is not followed by a "\012".

I have made a patch for that bug.  I have also added a lot of other
test cases to the t/datasend.t test.  I wrote these tests, after
we had encountered real world SMTP problems with different versions
of Net::Cmd.

I am using Net::Cmd Version 2.26 from the libnet-1.19 package in
the Perl 5.8.6 core.

Alexander


--- ./Net/Cmd.pm.orig	Wed Jun 30 15:56:11 2004
+++ ./Net/Cmd.pm	Tue Jan 31 21:52:14 2006
@@ -512,6 +512,9 @@
  if (!defined $ch) {
    return 1;
  }
+ elsif ($ch eq "\015") {
+   $tosend = "\012";
+ }
  elsif ($ch ne "\012") {
    $tosend = "\015\012";
  }
--- ./t/datasend.t.orig	Wed Jun 30 15:56:10 2004
+++ ./t/datasend.t	Tue Jan 31 22:56:21 2006
@@ -30,7 +33,7 @@
 (my $libnet_t = __FILE__) =~ s/datasend.t/libnet_t.pl/;
 require $libnet_t or die;
 
-print "1..51\n";
+print "1..212\n";
 
 sub check {
   my $expect = pop;
@@ -46,8 +49,6 @@
   );
 }
 
-my $cmd;
-
 check(
   # nothing
 
@@ -63,7 +64,7 @@
 check(
   "a\r",
 
-  "a\015\015\012.\015\012",
+  "a\015\012.\015\012",
 );
 
 check(
@@ -144,3 +145,67 @@
   "a\015\012..\015\012.\015\012",
 );
 
+# Send data with \r\n on block break.
+my @rn = (
+  [ "single line" ],
+  [ "two\nlines" ],
+  [ "endnl\n" ],
+  [ "endcr\r" ],
+  [ "blockendnl", "\n" ],
+  [ "\n", "blockstartnl" ],
+  [ "\nbothnl\n" ],
+  [ "\n", "blockbothnl", "\n" ],
+  [ "separate", "lines" ],
+  [ "separate\n", "newlines\n" ],
+  [ "only\rcr" ],
+  [ "end\rcr\r" ],
+  [ "after", "\nbreak", "\r\ncr" ],
+  [ "before\n", "break\r\n", "cr" ],
+  [ "both\n", "\nbreak\r", "\ncr" ],
+  [ "break\r", "\ncr\nnewline" ],
+  [ "a\r\n\r\n", "b\r\n\r", "\nc\r\n", "\r\nd\r", "\n\r\ne", "\r\n\r\nf" ],
+  [ "\r\r\nx\r", "\r\ny", "\r\r\nz\r\r" ],
+  [ "foo\r", "\nbar\n", "Hello\nworld\r" ],
+  [ "newlines\n\n" ],
+  [ "tripple\r", "\n\n\n" ],
+);
+
+# Send data with 0. on block break.
+my @zd = (
+  [ "foo\n.\nbar" ],
+  [ "foo", "\n.\nbar" ],
+  [ "foo\n", ".\nbar" ],
+  [ "foo\n.", "\nbar" ],
+  [ "foo\n.\n", "bar" ],
+
+  [ "foo\n." ],
+  [ "foo", "\n." ],
+  [ "foo\n", "." ],
+
+  [ ".\nbar" ],
+  [ ".", "\nbar" ],
+  [ ".\n", "bar" ],
+
+  [ "foo0.\nbar" ],
+  [ "foo", "0.\nbar" ],
+  [ "foo0", ".\nbar" ],
+  [ "foo0.", "\nbar" ],
+  [ "foo0.\n", "bar" ],
+
+  [ "foo0\n." ],
+  [ "foo", "0\n." ],
+  [ "foo0", "\n." ],
+  [ "foo0\n", "." ],
+);
+
+foreach (@rn, @zd) {
+  my @data = @$_;
+  my $expect = join("", @data);
+  $expect .= "\n" if $expect !~ /\n$/;
+  $expect =~ s/\r?\n/\r\n/gs;
+  $expect =~ s/(?:^|(?<=\r\n))\.\r\n/..\r\n/gs;
+  $expect .= ".\r\n";
+  $expect =~ tr/\r/\015/;
+  $expect =~ tr/\n/\012/;
+  check(@data, $expect);
+}

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=library
    severity=medium
---
Site configuration information for perl v5.8.6:

Configured by root at Thu Jan  1  0:00:00 UTC 1970.

Summary of my perl5 (revision 5 version 8 subversion 6) configuration:
  Platform:
    osname=openbsd, osvers=3.9, archname=i386-openbsd
    uname='openbsd'
    config_args='-dsE -Dopenbsd_distribution=defined'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -fno-delete-null-pointer-checks -pipe -I/usr/local/include',
    optimize='-O2',
    cppflags='-fno-strict-aliasing -fno-delete-null-pointer-checks -pipe -I/usr/local/include'
    ccversion='', gccversion='3.3.5 (propolice)', gccosandvers='openbsd3.9'
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-Wl,-E '
    libpth=/usr/lib
    libs=-lm -lutil -lc
    perllibs=-lm -lutil -lc
    libc=/usr/lib/libc.so.39.0, so=so, useshrplib=true, libperl=libperl.so.10.0
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-R/usr/libdata/perl5/i386-openbsd/5.8.6/CORE'
    cccdlflags='-DPIC -fPIC ', lddlflags='-shared -fPIC '

Locally applied patches:
    SUIDPERLIO1 - fix PERLIO_DEBUG buffer overflow (CAN-2005-0156)
    SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962

---
@INC for perl v5.8.6:
    /usr/libdata/perl5/i386-openbsd/5.8.6
    /usr/local/libdata/perl5/i386-openbsd/5.8.6
    /usr/libdata/perl5
    /usr/local/libdata/perl5
    /usr/local/libdata/perl5/site_perl/i386-openbsd
    /usr/libdata/perl5/site_perl/i386-openbsd
    /usr/local/libdata/perl5/site_perl
    /usr/libdata/perl5/site_perl
    /usr/local/lib/perl5/site_perl
    .

---
Environment for perl v5.8.6:
    HOME=/home/bluhm
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/home/bluhm/bin
    PERL_BADLANG (unset)
    SHELL=/bin/ksh




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About