aboutsummaryrefslogtreecommitdiff
path: root/t/lib-chunk/corrupt-chunk-file.pl
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-10-23 13:56:36 -0700
committerJunio C Hamano <gitster@pobox.com>2023-10-23 13:56:36 -0700
commitf32af12ceec1c19d8a8a7874523d3a7ceef6eebf (patch)
tree9078d206b9956c89334901fd04f8a884f01379d6 /t/lib-chunk/corrupt-chunk-file.pl
parentceadf0f3cf51550166a387ec8508bb55e7883057 (diff)
parent7538f9d89b001be33a1b682b5cf207c4ba8fd8c5 (diff)
downloadgit-f32af12ceec1c19d8a8a7874523d3a7ceef6eebf.tar.xz
Merge branch 'jk/chunk-bounds'
The codepaths that read "chunk" formatted files have been corrected to pay attention to the chunk size and notice broken files. * jk/chunk-bounds: (21 commits) t5319: make corrupted large-offset test more robust chunk-format: drop pair_chunk_unsafe() commit-graph: detect out-of-order BIDX offsets commit-graph: check bounds when accessing BIDX chunk commit-graph: check bounds when accessing BDAT chunk commit-graph: bounds-check generation overflow chunk commit-graph: check size of generations chunk commit-graph: bounds-check base graphs chunk commit-graph: detect out-of-bounds extra-edges pointers commit-graph: check size of commit data chunk midx: check size of revindex chunk midx: bounds-check large offset chunk midx: check size of object offset chunk midx: enforce chunk alignment on reading midx: check size of pack names chunk commit-graph: check consistency of fanout table midx: check size of oid lookup chunk commit-graph: check size of oid fanout chunk midx: stop ignoring malformed oid fanout chunk t: add library for munging chunk-format files ...
Diffstat (limited to 't/lib-chunk/corrupt-chunk-file.pl')
-rw-r--r--t/lib-chunk/corrupt-chunk-file.pl66
1 files changed, 66 insertions, 0 deletions
diff --git a/t/lib-chunk/corrupt-chunk-file.pl b/t/lib-chunk/corrupt-chunk-file.pl
new file mode 100644
index 0000000000..cd6d386fef
--- /dev/null
+++ b/t/lib-chunk/corrupt-chunk-file.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl
+
+my ($chunk, $seek, $bytes) = @ARGV;
+$bytes =~ s/../chr(hex($&))/ge;
+
+binmode STDIN;
+binmode STDOUT;
+
+# A few helpers to read bytes, or read and copy them to the
+# output.
+sub get {
+ my $n = shift;
+ return unless $n;
+ read(STDIN, my $buf, $n)
+ or die "read error or eof: $!\n";
+ return $buf;
+}
+sub copy {
+ my $buf = get(@_);
+ print $buf;
+ return $buf;
+}
+
+# read until we find table-of-contents entry for chunk;
+# note that we cheat a bit by assuming 4-byte alignment and
+# that no ToC entry will accidentally look like a header.
+#
+# If we don't find the entry, copy() will hit EOF and exit
+# (which should cause the caller to fail the test).
+while (copy(4) ne $chunk) { }
+my $offset = unpack("Q>", copy(8));
+
+# In clear mode, our length will change. So figure out
+# the length by comparing to the offset of the next chunk, and
+# then adjust that offset (and all subsequent) ones.
+my $len;
+if ($seek eq "clear") {
+ my $id;
+ do {
+ $id = copy(4);
+ my $next = unpack("Q>", get(8));
+ if (!defined $len) {
+ $len = $next - $offset;
+ }
+ print pack("Q>", $next - $len + length($bytes));
+ } while (unpack("N", $id));
+}
+
+# and now copy up to our existing chunk data
+copy($offset - tell(STDIN));
+if ($seek eq "clear") {
+ # if clearing, skip past existing data
+ get($len);
+} else {
+ # otherwise, copy up to the requested offset,
+ # and skip past the overwritten bytes
+ copy($seek);
+ get(length($bytes));
+}
+
+# now write out the requested bytes, along
+# with any other remaining data
+print $bytes;
+while (read(STDIN, my $buf, 4096)) {
+ print $buf;
+}