From 90efbd216f5a8ae616008490253a654f8cca4d16 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 9 Sep 2019 15:07:25 +0200 Subject: [PATCH] reftable: read file footer in ReftableReader#allRefs allRefs determined the end of the ref block without accounting for index or log blocks. This could cause other blocks to be interpreted as ref blocks, leading to "invalid block" error messages. Change-Id: I7b9323e7d5e0e7d64535b3ec1efd576aed1e9870 Signed-off-by: Han-Wen Nienhuys --- .../storage/reftable/ReftableTest.java | 38 +++++++++++++++++++ .../storage/reftable/ReftableReader.java | 10 +++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java index bd8714747..a45548d1e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java @@ -566,6 +566,44 @@ public class ReftableTest { assertEquals(all, more); } + @Test + public void allRefs() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ReftableConfig cfg = new ReftableConfig(); + cfg.setRefBlockSize(1024); + cfg.setLogBlockSize(1024); + cfg.setAlignBlocks(true); + ReftableWriter writer = new ReftableWriter() + .setMinUpdateIndex(1) + .setMaxUpdateIndex(1) + .setConfig(cfg) + .begin(buffer); + PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); + + // Fill out the 1st ref block. + List names = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + String name = new String(new char[220]).replace("\0", String.format("%c", i + 'a')); + names.add(name); + writer.writeRef(ref(name, i)); + } + + // Add some log data. + writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), "msg"); + writer.finish(); + byte[] table = buffer.toByteArray(); + + ReftableReader t = read(table); + RefCursor c = t.allRefs(); + + int j = 0; + while (c.next()) { + assertEquals(names.get(j), c.getRef().getName()); + j++; + } + } + + @Test public void reflogSeek() throws IOException { PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java index 4f0ff2d1d..02c2f5bba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java @@ -169,11 +169,13 @@ public class ReftableReader extends Reftable { readFileHeader(); } - long end = refEnd > 0 ? refEnd : (src.size() - FILE_FOOTER_LEN); - src.adviseSequentialRead(0, end); + if (refEnd == 0) { + readFileFooter(); + } + src.adviseSequentialRead(0, refEnd); - RefCursorImpl i = new RefCursorImpl(end, null, false); - i.block = readBlock(0, end); + RefCursorImpl i = new RefCursorImpl(refEnd, null, false); + i.block = readBlock(0, refEnd); return i; }