diff options
author | Luca Milanesio <luca.milanesio@gmail.com> | 2019-03-10 22:03:40 +0000 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2019-03-12 15:06:05 +0100 |
commit | bf3d1ded35707432f62318dbcb1f7139cc67b28d (patch) | |
tree | 1ae73e591d84d8e7df1aef47b777c582f8ae6870 /org.eclipse.jgit/src/org/eclipse/jgit | |
parent | afef866a44cd65fef292c174cad445b3fb526400 (diff) | |
download | jgit-bf3d1ded35707432f62318dbcb1f7139cc67b28d.tar.gz jgit-bf3d1ded35707432f62318dbcb1f7139cc67b28d.zip |
Check for packfile validity and fd before reading
When reading from a packfile, make sure that is valid
and has a non-null file-descriptor.
Because of concurrency between a thread invalidating a packfile
and another trying to read it, the read() may result into a NPE
that won't be able to be automatically recovered.
Throwing a PackInvalidException would instead cause the packlist
to be refreshed and the read to eventually succeed.
Bug: 544199
Change-Id: I27788b3db759d93ec3212de35c0094ecaafc2434
Signed-off-by: Luca Milanesio <luca.milanesio@gmail.com>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java index cbf7452131..7a51a5a02f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java @@ -702,6 +702,14 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { ByteArrayWindow read(final long pos, int size) throws IOException { synchronized (readLock) { + if (invalid || fd == null) { + // Due to concurrency between a read and another packfile invalidation thread + // one thread could come up to this point and then fail with NPE. + // Detect the situation and throw a proper exception so that can be properly + // managed by the main packfile search loop and the Git client won't receive + // any failures. + throw new PackInvalidException(packFile); + } if (length < pos + size) size = (int) (length - pos); final byte[] buf = new byte[size]; |