git-svn: eol_cp corner-case fixes
authorEric Wong <normalperson@yhbt.net>
Sat, 10 Jun 2006 06:27:01 +0000 (23:27 -0700)
committerEric Wong <normalperson@yhbt.net>
Fri, 16 Jun 2006 10:04:19 +0000 (03:04 -0700)
If we read the maximum size of our buffer into $buf, and the
last character is '\015', there's a chance that the character is
'\012', which means our regex won't work correctly. At the
worst case, this could introduce an extra newline into the code.
We'll now read an extra character if we see '\015' is the last
character in $buf.

We also forgot to recalculate the length of $buf after doing the
newline substitution, causing some files to appeare truncated.
We'll do that now and force byte semantics in length() for good
measure.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
contrib/git-svn/git-svn.perl
index 7ed11ef0a559f1d8877a798983fb1f19a2981f76..8d2e7f74ea15d27d8380a756f41b0f22b7d88013 100755 (executable)
@@ -866,19 +866,26 @@ sub eol_cp {
        binmode $wfd or croak $!;
 
        my $eol = $EOL{$es} or undef;
-       if ($eol) {
-               print  "$eol: $from => $to\n";
-       }
        my $buf;
+       use bytes;
        while (1) {
                my ($r, $w, $t);
                defined($r = sysread($rfd, $buf, 4096)) or croak $!;
                return unless $r;
-               $buf =~ s/(?:\015|\012|\015\012)/$eol/gs if $eol;
+               if ($eol) {
+                       if ($buf =~ /\015$/) {
+                               my $c;
+                               defined($r = sysread($rfd,$c,1)) or croak $!;
+                               $buf .= $c if $r > 0;
+                       }
+                       $buf =~ s/(?:\015\012|\015|\012)/$eol/gs;
+                       $r = length($buf);
+               }
                for ($w = 0; $w < $r; $w += $t) {
                        $t = syswrite($wfd, $buf, $r - $w, $w) or croak $!;
                }
        }
+       no bytes;
 }
 
 sub do_update_index {