git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Fix in Git.pm cat_blob crashes on large files

From
Joshua Clayton <stillcompiling@gmail.com>
Date
Feb 21, 2013, 22:13 UTC
Message-ID
<CAMB+bfKYLjmDavcLaO7scBPfTLmzqAmH+k9uBj0WJ+dzj9vuyA@mail.gmail.com>

Greetings. This is my first patch here. Hopefully I get the stylistic & political details right... :) Patch applies against maint and master

(If I understand the mechanics, in theory a negative offset should work,
 if the values lined up just right, but would be very wrong, overwriting the
lower contents of the file)
        Developer's Certificate of Origin 1.1
        By making a contribution to this project, I certify that:
        (a) The contribution was created in whole or in part by me and I
            have the right to submit it under the open source license
            indicated in the file; or
        (b) The contribution is based upon previous work that, to the best
            of my knowledge, is covered under an appropriate open source
            license and I have the right under that license to submit that
            work with modifications, whether created in whole or in part
            by me, under the same open source license (unless I am
            permitted to submit under a different license), as indicated
            in the file; or
        (c) The contribution was provided directly to me by some other
            person who certified (a), (b) or (c) and I have not modified
            it.

(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.

Affects git svn clone/fetch Original code loaded entire file contents into a variable before writing to disk. If the offset within the variable passed 2 GiB, it becrame negative, resulting in a crash. On a 32 bit system, or a system with low memory it may crash before reaching 2 GiB due to memory exhaustion. Fix writes in smaller 64K increments. Tested to work on git svn fetch

Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
---
 perl/Git.pm |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 931047c..e55840f 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -942,6 +942,8 @@ sub cat_blob {
 	my $size = $1;

 	my $blob;
+	my $blobSize = 0;
+	my $flushSize = 1024*64;
 	my $bytesRead = 0;

 	while (1) {
@@ -949,13 +951,21 @@ sub cat_blob {
 		last unless $bytesLeft;

 		my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
-		my $read = read($in, $blob, $bytesToRead, $bytesRead);
+		my $read = read($in, $blob, $bytesToRead, $blobSize);
 		unless (defined($read)) {
 			$self->_close_cat_blob();
 			throw Error::Simple("in pipe went bad");
 		}
-
 		$bytesRead += $read;
+		$blobSize += $read;
+		if (($blobSize >= $flushSize) || ($bytesLeft <= 1024)) {
+			unless (print $fh $blob) {
+				$self->_close_cat_blob();
+				throw Error::Simple("couldn't write to passed in filehandle");
+			}
+			$blob = "";
+			$blobSize = 0;
+		}
 	}

 	# Skip past the trailing newline.
@@ -970,11 +980,6 @@ sub cat_blob {
 		throw Error::Simple("didn't find newline after blob");
 	}

-	unless (print $fh $blob) {
-		$self->_close_cat_blob();
-		throw Error::Simple("couldn't write to passed in filehandle");
-	}
-
 	return $size;
 }
-- 
1.7.10.4
Next: Jeff King
Message 1 of 6 in “Fix in Git.pm cat_blob crashes on large files”
  1. Fix in Git.pm cat_blob crashes on large filesJoshua Clayton, Feb 21, 2013
  2. Jeff KingFeb 21, 2013
  3. Joshua ClaytonFeb 21, 2013
  4. Jeff KingFeb 21, 2013
  5. Joshua ClaytonFeb 22, 2013
  6. Jeff KingFeb 22, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.