You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by fe...@apache.org on 2004/09/16 02:28:59 UTC

svn commit: rev 46140 - in spamassassin/trunk/lib/Mail/SpamAssassin: . Message

Author: felicity
Date: Wed Sep 15 17:28:58 2004
New Revision: 46140

Modified:
   spamassassin/trunk/lib/Mail/SpamAssassin/Message/Node.pm
   spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
Log:
bug 3780: if Message::Node->decode() is called with a length, and the encoding is base64, don't cache the result and only decode as much as necessary.

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Message/Node.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Message/Node.pm	(original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Message/Node.pm	Wed Sep 15 17:28:58 2004
@@ -282,8 +282,15 @@
     elsif ( $encoding eq 'base64' ) {
       dbg("decoding: base64");
 
-      # Generate the decoded output
-      $self->{'decoded'} = [ Mail::SpamAssassin::Util::base64_decode(join("", @{$self->{'raw'}})) ];
+      # if it's not defined or is 0, do the whole thing, otherwise only decode
+      # a portion
+      if ($bytes) {
+        return Mail::SpamAssassin::Util::base64_decode(join("", @{$self->{'raw'}}), $bytes);
+      }
+      else {
+        # Generate the decoded output
+        $self->{'decoded'} = [ Mail::SpamAssassin::Util::base64_decode(join("", @{$self->{'raw'}})) ];
+      }
 
       # If it's a type text or message, split it into an array of lines
       if ( $self->{'type'} =~ m@^(?:text|message)\b/@i ) {

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm	(original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Util.pm	Wed Sep 15 17:28:58 2004
@@ -428,6 +428,7 @@
 # characters to null.
 sub base64_decode {
   local $_ = shift;
+  my $decoded_length = shift;
 
   s/\s+//g;
   if (HAS_MIME_BASE64 && (length($_) % 4 == 0) &&
@@ -435,11 +436,21 @@
   {
     # only use MIME::Base64 when the XS and Perl are both correct and quiet
     s/(=+)(?!=*$)/'A' x length($1)/ge;
+
+    # If only a certain number of bytes are requested, truncate the encoded
+    # version down to the appropriate size and return the requested bytes
+    if (defined $decoded_length) {
+      $_ = substr $_, 0, 4 * (int($decoded_length/3) + 1);
+      my $decoded = MIME::Base64::decode_base64($_);
+      return substr $decoded, 0, $decoded_length;
+    }
+
+    # otherwise, just decode the whole thing and return it
     return MIME::Base64::decode_base64($_);
   }
-  tr|A-Za-z0-9+/=||cd;			# remove non-base64 characters
+  tr{A-Za-z0-9+/=}{}cd;			# remove non-base64 characters
   s/=+$//;				# remove terminating padding
-  tr|A-Za-z0-9+/=| -_`|;		# translate to uuencode
+  tr{A-Za-z0-9+/=}{ -_`};		# translate to uuencode
   s/.$// if (length($_) % 4 == 1);	# unpack cannot cope with extra byte
 
   my $length;
@@ -447,6 +458,13 @@
   while ($_) {
     $length = (length >= 84) ? 84 : length;
     $out .= unpack("u", chr(32 + $length * 3/4) . substr($_, 0, $length, ''));
+    last if (defined $decoded_length && length $out >= $decoded_length);
+  }
+
+  # If only a certain number of bytes are requested, truncate the encoded
+  # version down to the appropriate size and return the requested bytes
+  if (defined $decoded_length) {
+    return substr $out, 0, $decoded_length;
   }
 
   return $out;