|
|
@ -304,6 +304,154 @@ public class PackParserTest extends RepositoryTestCase { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void testNonMarkingInputStream() throws Exception { |
|
|
|
|
|
|
|
TestRepository d = new TestRepository(db); |
|
|
|
|
|
|
|
RevBlob a = d.blob("a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); |
|
|
|
|
|
|
|
packHeader(pack, 1); |
|
|
|
|
|
|
|
pack.write((Constants.OBJ_REF_DELTA) << 4 | 4); |
|
|
|
|
|
|
|
a.copyRawTo(pack); |
|
|
|
|
|
|
|
deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' }); |
|
|
|
|
|
|
|
digest(pack); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InputStream in = new ByteArrayInputStream(pack.toByteArray()) { |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean markSupported() { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void mark(int maxlength) { |
|
|
|
|
|
|
|
fail("Mark should not be called"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PackParser p = index(in); |
|
|
|
|
|
|
|
p.setAllowThin(true); |
|
|
|
|
|
|
|
p.setCheckEofAfterPackFooter(false); |
|
|
|
|
|
|
|
p.setExpectDataAfterPackFooter(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
p.parse(NullProgressMonitor.INSTANCE); |
|
|
|
|
|
|
|
fail("PackParser should have failed"); |
|
|
|
|
|
|
|
} catch (IOException e) { |
|
|
|
|
|
|
|
assertEquals(e.getMessage(), |
|
|
|
|
|
|
|
JGitText.get().inputStreamMustSupportMark); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void testDataAfterPackFooterSingleRead() throws Exception { |
|
|
|
|
|
|
|
TestRepository d = new TestRepository(db); |
|
|
|
|
|
|
|
RevBlob a = d.blob("a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32*1024); |
|
|
|
|
|
|
|
packHeader(pack, 1); |
|
|
|
|
|
|
|
pack.write((Constants.OBJ_REF_DELTA) << 4 | 4); |
|
|
|
|
|
|
|
a.copyRawTo(pack); |
|
|
|
|
|
|
|
deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' }); |
|
|
|
|
|
|
|
digest(pack); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte packData[] = pack.toByteArray(); |
|
|
|
|
|
|
|
byte streamData[] = new byte[packData.length + 1]; |
|
|
|
|
|
|
|
System.arraycopy(packData, 0, streamData, 0, packData.length); |
|
|
|
|
|
|
|
streamData[packData.length] = 0x7e; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InputStream in = new ByteArrayInputStream(streamData); |
|
|
|
|
|
|
|
PackParser p = index(in); |
|
|
|
|
|
|
|
p.setAllowThin(true); |
|
|
|
|
|
|
|
p.setCheckEofAfterPackFooter(false); |
|
|
|
|
|
|
|
p.setExpectDataAfterPackFooter(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.parse(NullProgressMonitor.INSTANCE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(0x7e, in.read()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void testDataAfterPackFooterSplitObjectRead() throws Exception { |
|
|
|
|
|
|
|
final byte[] data = Constants.encode("0123456789"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Build a pack ~17k
|
|
|
|
|
|
|
|
int objects = 900; |
|
|
|
|
|
|
|
TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32 * 1024); |
|
|
|
|
|
|
|
packHeader(pack, objects); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < objects; i++) { |
|
|
|
|
|
|
|
pack.write((Constants.OBJ_BLOB) << 4 | 10); |
|
|
|
|
|
|
|
deflate(pack, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
digest(pack); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte packData[] = pack.toByteArray(); |
|
|
|
|
|
|
|
byte streamData[] = new byte[packData.length + 1]; |
|
|
|
|
|
|
|
System.arraycopy(packData, 0, streamData, 0, packData.length); |
|
|
|
|
|
|
|
streamData[packData.length] = 0x7e; |
|
|
|
|
|
|
|
InputStream in = new ByteArrayInputStream(streamData); |
|
|
|
|
|
|
|
PackParser p = index(in); |
|
|
|
|
|
|
|
p.setAllowThin(true); |
|
|
|
|
|
|
|
p.setCheckEofAfterPackFooter(false); |
|
|
|
|
|
|
|
p.setExpectDataAfterPackFooter(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.parse(NullProgressMonitor.INSTANCE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(0x7e, in.read()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void testDataAfterPackFooterSplitHeaderRead() throws Exception { |
|
|
|
|
|
|
|
TestRepository d = new TestRepository(db); |
|
|
|
|
|
|
|
final byte[] data = Constants.encode("a"); |
|
|
|
|
|
|
|
RevBlob b = d.blob(data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int objects = 248; |
|
|
|
|
|
|
|
TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32 * 1024); |
|
|
|
|
|
|
|
packHeader(pack, objects + 1); |
|
|
|
|
|
|
|
int offset = 13; |
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
|
|
|
for (int i = 0; i < offset; i++) |
|
|
|
|
|
|
|
sb.append(i); |
|
|
|
|
|
|
|
offset = sb.toString().length(); |
|
|
|
|
|
|
|
int lenByte = (Constants.OBJ_BLOB) << 4 | (offset & 0x0F); |
|
|
|
|
|
|
|
offset >>= 4; |
|
|
|
|
|
|
|
if (offset > 0) |
|
|
|
|
|
|
|
lenByte |= 1 << 7; |
|
|
|
|
|
|
|
pack.write(lenByte); |
|
|
|
|
|
|
|
while (offset > 0) { |
|
|
|
|
|
|
|
lenByte = offset & 0x7F; |
|
|
|
|
|
|
|
offset >>= 6; |
|
|
|
|
|
|
|
if (offset > 0) |
|
|
|
|
|
|
|
lenByte |= 1 << 7; |
|
|
|
|
|
|
|
pack.write(lenByte); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
deflate(pack, Constants.encode(sb.toString())); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < objects; i++) { |
|
|
|
|
|
|
|
// The last pack header written falls across the 8192 byte boundary
|
|
|
|
|
|
|
|
// between [8189:8210]
|
|
|
|
|
|
|
|
pack.write((Constants.OBJ_REF_DELTA) << 4 | 4); |
|
|
|
|
|
|
|
b.copyRawTo(pack); |
|
|
|
|
|
|
|
deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
digest(pack); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte packData[] = pack.toByteArray(); |
|
|
|
|
|
|
|
byte streamData[] = new byte[packData.length + 1]; |
|
|
|
|
|
|
|
System.arraycopy(packData, 0, streamData, 0, packData.length); |
|
|
|
|
|
|
|
streamData[packData.length] = 0x7e; |
|
|
|
|
|
|
|
InputStream in = new ByteArrayInputStream(streamData); |
|
|
|
|
|
|
|
PackParser p = index(in); |
|
|
|
|
|
|
|
p.setAllowThin(true); |
|
|
|
|
|
|
|
p.setCheckEofAfterPackFooter(false); |
|
|
|
|
|
|
|
p.setExpectDataAfterPackFooter(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p.parse(NullProgressMonitor.INSTANCE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(0x7e, in.read()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt) |
|
|
|
private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt) |
|
|
|
throws IOException { |
|
|
|
throws IOException { |
|
|
|
final byte[] hdr = new byte[8]; |
|
|
|
final byte[] hdr = new byte[8]; |
|
|
|