diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2017-03-27 10:52:36 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2017-03-27 22:45:59 +0200 |
commit | 251abbfcd137aafd1b6cb866ad9fe4d8089ad08c (patch) | |
tree | a0441bc6866cb0d4df493a221fc0c13f658a038b | |
parent | 3104629e317ca7e94473e433ff7445cd073e647a (diff) | |
parent | 7f013924a8ec8fac49e8c0b4d30e28bc0c3f10e4 (diff) | |
download | jgit-251abbfcd137aafd1b6cb866ad9fe4d8089ad08c.tar.gz jgit-251abbfcd137aafd1b6cb866ad9fe4d8089ad08c.zip |
Merge branch 'stable-4.6'
* stable-4.6:
Only mark packfile invalid if exception signals permanent problem
Don't flag a packfile invalid if opening existing file failed
Prepare 4.5.2-SNAPSHOT builds
Change-Id: Ife4efad1135d3870a5a0fb71e60b9524fb8777ab
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
6 files changed, 268 insertions, 18 deletions
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index 1554ce082d..6441232363 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -8,6 +8,33 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/errors/NoPackSignatureException.java" type="org.eclipse.jgit.errors.NoPackSignatureException"> + <filter comment="non-breaking addition of exception classes needed to cleanly fix error handling in PackFile" id="1108344834"> + <message_arguments> + <message_argument value="4.5"/> + <message_argument value="4.7"/> + <message_argument value="org.eclipse.jgit.errors.NoPackSignatureException"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/jgit/errors/UnsupportedPackIndexVersionException.java" type="org.eclipse.jgit.errors.UnsupportedPackIndexVersionException"> + <filter comment="non-breaking addition of exception classes needed to cleanly fix error handling in PackFile" id="1108344834"> + <message_arguments> + <message_argument value="4.5"/> + <message_argument value="4.7"/> + <message_argument value="org.eclipse.jgit.errors.UnsupportedPackIndexVersionException"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/jgit/errors/UnsupportedPackVersionException.java" type="org.eclipse.jgit.errors.UnsupportedPackVersionException"> + <filter comment="non-breaking addition of exception classes needed to cleanly fix error handling in PackFile" id="1108344834"> + <message_arguments> + <message_argument value="4.5"/> + <message_argument value="4.7"/> + <message_argument value="org.eclipse.jgit.errors.UnsupportedPackVersionException"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/jgit/lib/ObjectInserter.java" type="org.eclipse.jgit.lib.ObjectInserter"> <filter comment="changed return type of digest() breaking implementors which is ok in minor releases according to OSGi semantic versioning" id="338792546"> <message_arguments> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoPackSignatureException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoPackSignatureException.java new file mode 100644 index 0000000000..28e9788974 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoPackSignatureException.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.errors; + +import java.io.IOException; + +/** + * Thrown when a PackFile is found not to contain the pack signature defined by + * git. + * + * @since 4.5 + */ +public class NoPackSignatureException extends IOException { + private static final long serialVersionUID = 1L; + + /** + * Construct an exception. + * + * @param why + * description of the type of error. + */ + public NoPackSignatureException(final String why) { + super(why); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackIndexVersionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackIndexVersionException.java new file mode 100644 index 0000000000..0b7ccf5777 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackIndexVersionException.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.errors; + +import java.io.IOException; +import java.text.MessageFormat; + +import org.eclipse.jgit.internal.JGitText; + +/** + * Thrown when a PackIndex uses an index version not supported by JGit. + * + * @since 4.5 + */ +public class UnsupportedPackIndexVersionException extends IOException { + private static final long serialVersionUID = 1L; + + /** + * Construct an exception. + * + * @param version + * pack index version + */ + public UnsupportedPackIndexVersionException(final int version) { + super(MessageFormat.format(JGitText.get().unsupportedPackIndexVersion, + Integer.valueOf(version))); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackVersionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackVersionException.java new file mode 100644 index 0000000000..23611867be --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnsupportedPackVersionException.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.errors; + +import java.io.IOException; +import java.text.MessageFormat; + +import org.eclipse.jgit.internal.JGitText; + +/** + * Thrown when a PackFile uses a pack version not supported by JGit. + * + * @since 4.5 + */ +public class UnsupportedPackVersionException extends IOException { + private static final long serialVersionUID = 1L; + + /** + * Construct an exception. + * + * @param version + * pack version + */ + public UnsupportedPackVersionException(final long version) { + super(MessageFormat.format(JGitText.get().unsupportedPackVersion, + Long.valueOf(version))); + } +} 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 f4a77d2a2a..fcc47fb227 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 @@ -51,11 +51,14 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP; import java.io.EOFException; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InterruptedIOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; +import java.nio.file.AccessDeniedException; +import java.nio.file.NoSuchFileException; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; @@ -70,9 +73,13 @@ import java.util.zip.Inflater; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.LargeObjectException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.errors.NoPackSignatureException; import org.eclipse.jgit.errors.PackInvalidException; import org.eclipse.jgit.errors.PackMismatchException; import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; +import org.eclipse.jgit.errors.UnpackException; +import org.eclipse.jgit.errors.UnsupportedPackIndexVersionException; +import org.eclipse.jgit.errors.UnsupportedPackVersionException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.pack.BinaryDelta; import org.eclipse.jgit.internal.storage.pack.ObjectToPack; @@ -638,15 +645,25 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { // don't invalidate the pack, we are interrupted from another thread openFail(false); throw e; - } catch (IOException ioe) { + } catch (FileNotFoundException fn) { + // don't invalidate the pack if opening an existing file failed + // since it may be related to a temporary lack of resources (e.g. + // max open files) + openFail(!packFile.exists()); + throw fn; + } catch (EOFException | AccessDeniedException | NoSuchFileException + | CorruptObjectException | NoPackSignatureException + | PackMismatchException | UnpackException + | UnsupportedPackIndexVersionException + | UnsupportedPackVersionException pe) { + // exceptions signaling permanent problems with a pack openFail(true); - throw ioe; - } catch (RuntimeException re) { - openFail(true); - throw re; - } catch (Error re) { - openFail(true); - throw re; + throw pe; + } catch (IOException | RuntimeException ge) { + // generic exceptions could be transient so we should not mark the + // pack invalid to avoid false MissingObjectExceptions + openFail(false); + throw ge; } } @@ -713,28 +730,31 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { fd.seek(0); fd.readFully(buf, 0, 12); - if (RawParseUtils.match(buf, 0, Constants.PACK_SIGNATURE) != 4) - throw new IOException(JGitText.get().notAPACKFile); + if (RawParseUtils.match(buf, 0, Constants.PACK_SIGNATURE) != 4) { + throw new NoPackSignatureException(JGitText.get().notAPACKFile); + } final long vers = NB.decodeUInt32(buf, 4); final long packCnt = NB.decodeUInt32(buf, 8); - if (vers != 2 && vers != 3) - throw new IOException(MessageFormat.format( - JGitText.get().unsupportedPackVersion, Long.valueOf(vers))); + if (vers != 2 && vers != 3) { + throw new UnsupportedPackVersionException(vers); + } - if (packCnt != idx.getObjectCount()) + if (packCnt != idx.getObjectCount()) { throw new PackMismatchException(MessageFormat.format( JGitText.get().packObjectCountMismatch, Long.valueOf(packCnt), Long.valueOf(idx.getObjectCount()), getPackFile())); + } fd.seek(length - 20); fd.readFully(buf, 0, 20); - if (!Arrays.equals(buf, packChecksum)) + if (!Arrays.equals(buf, packChecksum)) { throw new PackMismatchException(MessageFormat.format( JGitText.get().packObjectCountMismatch , ObjectId.fromRaw(buf).name() , ObjectId.fromRaw(idx.packChecksum).name() , getPackFile())); + } } ObjectLoader load(final WindowCursor curs, long pos) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java index ac1b7a367d..2252778db0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java @@ -55,6 +55,7 @@ import java.util.Set; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.errors.UnsupportedPackIndexVersionException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.AnyObjectId; @@ -138,9 +139,7 @@ public abstract class PackIndex case 2: return new PackIndexV2(fd); default: - throw new IOException(MessageFormat.format( - JGitText.get().unsupportedPackIndexVersion, - Integer.valueOf(v))); + throw new UnsupportedPackIndexVersionException(v); } } return new PackIndexV1(fd, hdr); |