import java.io.File;
import java.io.IOException;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.events.ListenerHandle;
import org.eclipse.jgit.events.RefsChangedEvent;
assertSame(master_p2, refdir.peel(master_p2));
}
+ @Test
+ public void testRefsChangedStackOverflow() throws Exception {
+ final FileRepository newRepo = createBareRepository();
+ final RefDatabase refDb = newRepo.getRefDatabase();
+ File packedRefs = new File(newRepo.getDirectory(), "packed-refs");
+ assertTrue(packedRefs.createNewFile());
+ final AtomicReference<StackOverflowError> error = new AtomicReference<StackOverflowError>();
+ final AtomicReference<IOException> exception = new AtomicReference<IOException>();
+ final AtomicInteger changeCount = new AtomicInteger();
+ newRepo.getListenerList().addRefsChangedListener(
+ new RefsChangedListener() {
+
+ public void onRefsChanged(RefsChangedEvent event) {
+ try {
+ refDb.getRefs("ref");
+ changeCount.incrementAndGet();
+ } catch (StackOverflowError soe) {
+ error.set(soe);
+ } catch (IOException ioe) {
+ exception.set(ioe);
+ }
+ }
+ });
+ refDb.getRefs("ref");
+ refDb.getRefs("ref");
+ assertNull(error.get());
+ assertNull(exception.get());
+ assertEquals(1, changeCount.get());
+ }
+
private void writeLooseRef(String name, AnyObjectId id) throws IOException {
writeLooseRef(name, id.name() + "\n");
}
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.LinkedList;
return curList;
final PackedRefList newList = readPackedRefs();
- if (packedRefs.compareAndSet(curList, newList))
+ if (packedRefs.compareAndSet(curList, newList)
+ && !curList.id.equals(newList.id))
modCnt.incrementAndGet();
return newList;
}
- private PackedRefList readPackedRefs()
- throws IOException {
+ private PackedRefList readPackedRefs() throws IOException {
final FileSnapshot snapshot = FileSnapshot.save(packedRefsFile);
final BufferedReader br;
+ final MessageDigest digest = Constants.newMessageDigest();
try {
- br = new BufferedReader(new InputStreamReader(new FileInputStream(
- packedRefsFile), CHARSET));
+ br = new BufferedReader(new InputStreamReader(
+ new DigestInputStream(new FileInputStream(packedRefsFile),
+ digest), CHARSET));
} catch (FileNotFoundException noPackedRefs) {
// Ignore it and leave the new list empty.
return PackedRefList.NO_PACKED_REFS;
}
try {
- return new PackedRefList(parsePackedRefs(br), snapshot);
+ return new PackedRefList(parsePackedRefs(br), snapshot,
+ ObjectId.fromRaw(digest.digest()));
} finally {
br.close();
}
if (!lck.commit())
throw new ObjectWritingException(MessageFormat.format(JGitText.get().unableToWrite, name));
- packedRefs.compareAndSet(oldPackedList, new PackedRefList(
- refs, lck.getCommitSnapshot()));
+ byte[] digest = Constants.newMessageDigest().digest(content);
+ packedRefs.compareAndSet(oldPackedList, new PackedRefList(refs,
+ lck.getCommitSnapshot(), ObjectId.fromRaw(digest)));
}
}.writePackedRefs();
}
private static class PackedRefList extends RefList<Ref> {
static final PackedRefList NO_PACKED_REFS = new PackedRefList(
- RefList.emptyList(), FileSnapshot.MISSING_FILE);
+ RefList.emptyList(), FileSnapshot.MISSING_FILE,
+ ObjectId.zeroId());
final FileSnapshot snapshot;
- PackedRefList(RefList<Ref> src, FileSnapshot s) {
+ final ObjectId id;
+
+ PackedRefList(RefList<Ref> src, FileSnapshot s, ObjectId i) {
super(src);
snapshot = s;
+ id = i;
}
}