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 <hanwen@google.com>
This commit is contained in:
Han-Wen Nienhuys 2019-09-09 15:07:25 +02:00
parent 726bcc4fdb
commit 90efbd216f
2 changed files with 44 additions and 4 deletions

View File

@ -566,6 +566,44 @@ public void reflogReader() throws IOException {
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<String> 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);

View File

@ -169,11 +169,13 @@ public RefCursor allRefs() throws IOException {
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;
}