Pack: ensure packfile is still valid while still recoverable

When copyAsIs2() needs to send a large object requiring multiple read
iterations — any of which could fail if the object isn't already in the
WindowCache — verify first that the packfile is still valid at the
latest possible moment, just before sending the header that would make
recovery impossible.

Change-Id: I234fd4b315b579a0506c8fbdea0c6787bdc09fcd
Signed-off-by: Martin Fick <mfick@nvidia.com>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
index 9073c16..61577a9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
@@ -597,13 +597,19 @@ private void copyAsIs2(PackOutputStream out, LocalObjectToPack src,
 						assert(crc2 != null);
 						crc2.update(buf, 0, n);
 					}
+					cnt -= n;
 					if (!isHeaderWritten) {
+						if (invalid && cnt > 0) {
+							// Since this is not the last iteration and the packfile is invalid,
+							// better to assume the iterations will not all complete here while
+							// it is still likely recoverable.
+							throw new StoredObjectRepresentationNotAvailableException(invalidatingCause);
+						}
 						out.writeHeader(src, inflatedLength);
 						isHeaderWritten = true;
 					}
 					out.write(buf, 0, n);
 					pos += n;
-					cnt -= n;
 				}
 				if (validate) {
 					assert(crc2 != null);