diff options
Diffstat (limited to 'org.eclipse.jgit/src')
5 files changed, 12 insertions, 628 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedDeltaObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedDeltaObject.java deleted file mode 100644 index 18f15b068c..0000000000 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedDeltaObject.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2010, Google Inc. - * 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.internal.storage.file; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.DataFormatException; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.InflaterInputStream; - -import org.eclipse.jgit.errors.IncorrectObjectTypeException; -import org.eclipse.jgit.errors.LargeObjectException; -import org.eclipse.jgit.errors.MissingObjectException; -import org.eclipse.jgit.internal.storage.pack.BinaryDelta; -import org.eclipse.jgit.internal.storage.pack.DeltaStream; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.ObjectLoader; -import org.eclipse.jgit.lib.ObjectStream; -import org.eclipse.jgit.util.io.TeeInputStream; - -class LargePackedDeltaObject extends ObjectLoader { - private static final long SIZE_UNKNOWN = -1; - - private int type; - - private long size; - - private final long objectOffset; - - private final long baseOffset; - - private final int headerLength; - - private final PackFile pack; - - private final FileObjectDatabase db; - - LargePackedDeltaObject(long objectOffset, - long baseOffset, int headerLength, PackFile pack, - FileObjectDatabase db) { - this.type = Constants.OBJ_BAD; - this.size = SIZE_UNKNOWN; - this.objectOffset = objectOffset; - this.baseOffset = baseOffset; - this.headerLength = headerLength; - this.pack = pack; - this.db = db; - } - - @Override - public int getType() { - if (type == Constants.OBJ_BAD) { - WindowCursor wc = new WindowCursor(db); - try { - type = pack.getObjectType(wc, objectOffset); - } catch (IOException packGone) { - // If the pack file cannot be pinned into the cursor, it - // probably was repacked recently. Go find the object - // again and get the type from that location instead. - // - try { - type = wc.open(getObjectId()).getType(); - } catch (IOException packGone2) { - // "He's dead, Jim." We just can't discover the type - // and the interface isn't supposed to be lazy here. - // Report an invalid type code instead, callers will - // wind up bailing out with an error at some point. - } - } finally { - wc.release(); - } - } - return type; - } - - @Override - public long getSize() { - if (size == SIZE_UNKNOWN) { - WindowCursor wc = new WindowCursor(db); - try { - byte[] b = pack.getDeltaHeader(wc, objectOffset + headerLength); - size = BinaryDelta.getResultSize(b); - } catch (DataFormatException objectCorrupt) { - // The zlib stream for the delta is corrupt. We probably - // cannot access the object. Keep the size negative and - // report that bogus result to the caller. - } catch (IOException packGone) { - // If the pack file cannot be pinned into the cursor, it - // probably was repacked recently. Go find the object - // again and get the size from that location instead. - // - try { - size = wc.open(getObjectId()).getSize(); - } catch (IOException packGone2) { - // "He's dead, Jim." We just can't discover the size - // and the interface isn't supposed to be lazy here. - // Report an invalid type code instead, callers will - // wind up bailing out with an error at some point. - } - } finally { - wc.release(); - } - } - return size; - } - - @Override - public boolean isLarge() { - return true; - } - - @Override - public byte[] getCachedBytes() throws LargeObjectException { - try { - throw new LargeObjectException(getObjectId()); - } catch (IOException cannotObtainId) { - LargeObjectException err = new LargeObjectException(); - err.initCause(cannotObtainId); - throw err; - } - } - - @Override - public ObjectStream openStream() throws MissingObjectException, IOException { - // If the object was recently unpacked, its available loose. - // The loose format is going to be faster to access than a - // delta applied on top of a base. Use that whenever we can. - // - final ObjectId myId = getObjectId(); - final WindowCursor wc = new WindowCursor(db); - ObjectLoader ldr = db.openLooseObject(wc, myId); - if (ldr != null) - return ldr.openStream(); - - InputStream in = open(wc); - in = new BufferedInputStream(in, 8192); - - // While we inflate the object, also deflate it back as a loose - // object. This will later be cleaned up by a gc pass, but until - // then we will reuse the loose form by the above code path. - // - int myType = getType(); - long mySize = getSize(); - final ObjectDirectoryInserter odi = db.newInserter(); - final File tmp = odi.newTempFile(); - DeflaterOutputStream dOut = odi.compress(new FileOutputStream(tmp)); - odi.writeHeader(dOut, myType, mySize); - - in = new TeeInputStream(in, dOut); - return new ObjectStream.Filter(myType, mySize, in) { - @Override - public void close() throws IOException { - super.close(); - - odi.release(); - wc.release(); - db.insertUnpackedObject(tmp, myId, true /* force creation */); - } - }; - } - - private InputStream open(final WindowCursor wc) - throws MissingObjectException, IOException, - IncorrectObjectTypeException { - InputStream delta; - try { - delta = new PackInputStream(pack, objectOffset + headerLength, wc); - } catch (IOException packGone) { - // If the pack file cannot be pinned into the cursor, it - // probably was repacked recently. Go find the object - // again and open the stream from that location instead. - // - return wc.open(getObjectId()).openStream(); - } - delta = new InflaterInputStream(delta); - - final ObjectLoader base = pack.load(wc, baseOffset); - DeltaStream ds = new DeltaStream(delta) { - private long baseSize = SIZE_UNKNOWN; - - @Override - protected InputStream openBase() throws IOException { - InputStream in; - if (base instanceof LargePackedDeltaObject) - in = ((LargePackedDeltaObject) base).open(wc); - else - in = base.openStream(); - if (baseSize == SIZE_UNKNOWN) { - if (in instanceof DeltaStream) - baseSize = ((DeltaStream) in).getSize(); - else if (in instanceof ObjectStream) - baseSize = ((ObjectStream) in).getSize(); - } - return in; - } - - @Override - protected long getBaseSize() throws IOException { - if (baseSize == SIZE_UNKNOWN) { - // This code path should never be used as DeltaStream - // is supposed to open the stream first, which would - // initialize the size for us directly from the stream. - baseSize = base.getSize(); - } - return baseSize; - } - }; - if (type == Constants.OBJ_BAD) { - if (!(base instanceof LargePackedDeltaObject)) - type = base.getType(); - } - if (size == SIZE_UNKNOWN) - size = ds.getSize(); - return ds; - } - - private ObjectId getObjectId() throws IOException { - return pack.findObjectForOffset(objectOffset); - } -} 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 5e1e2b1a38..81f8ab6756 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 @@ -65,6 +65,7 @@ import java.util.zip.DataFormatException; 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.PackInvalidException; import org.eclipse.jgit.errors.PackMismatchException; @@ -701,7 +702,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { } ObjectLoader load(final WindowCursor curs, long pos) - throws IOException { + throws IOException, LargeObjectException { try { final byte[] ib = curs.tempId; Delta delta = null; @@ -727,7 +728,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { - if (sz < curs.getStreamFileThreshold()) + if (delta != null || sz < curs.getStreamFileThreshold()) data = decompress(pos + p, (int) sz, curs); if (delta != null) { @@ -796,7 +797,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { // (Whole objects with no deltas to apply return early above.) if (data == null) - return delta.large(this, curs); + throw new IOException(JGitText.get().inMemoryBufferLimitExceeded); do { // Cache only the base immediately before desired object. @@ -811,19 +812,19 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { delta.deltaSize, curs); if (cmds == null) { data = null; // Discard base in case of OutOfMemoryError - return delta.large(this, curs); + throw new LargeObjectException.OutOfMemory(new OutOfMemoryError()); } final long sz = BinaryDelta.getResultSize(cmds); if (Integer.MAX_VALUE <= sz) - return delta.large(this, curs); + throw new LargeObjectException.ExceedsByteArrayLimit(); final byte[] result; try { result = new byte[(int) sz]; } catch (OutOfMemoryError tooBig) { data = null; // Discard base in case of OutOfMemoryError - return delta.large(this, curs); + throw new LargeObjectException.OutOfMemory(tooBig); } BinaryDelta.apply(data, cmds, result); @@ -875,18 +876,6 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { this.hdrLen = hdrLen; this.basePos = baseOffset; } - - ObjectLoader large(PackFile pack, WindowCursor wc) { - Delta d = this; - while (d.next != null) - d = d.next; - return d.newLargeLoader(pack, wc); - } - - private ObjectLoader newLargeLoader(PackFile pack, WindowCursor wc) { - return new LargePackedDeltaObject(deltaPos, basePos, hdrLen, - pack, wc.db); - } } byte[] getDeltaHeader(WindowCursor wc, long pos) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java index de3c59ab5d..2a2a463b80 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java @@ -51,8 +51,8 @@ import java.io.OutputStream; * <p> * The index can be passed a result buffer, and output an instruction sequence * that transforms the source buffer used by the index into the result buffer. - * The instruction sequence can be executed by {@link BinaryDelta} or - * {@link DeltaStream} to recreate the result buffer. + * The instruction sequence can be executed by {@link BinaryDelta} to recreate + * the result buffer. * <p> * An index stores the entire contents of the source buffer, but also a table of * block identities mapped to locations where the block appears in the source diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaStream.java deleted file mode 100644 index 28b4d605e5..0000000000 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaStream.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com> - * Copyright (C) 2006-2007, Shawn O. Pearce <spearce@spearce.org> - * Copyright (C) 2010, Google Inc. - * 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.internal.storage.pack; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.jgit.errors.CorruptObjectException; -import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.util.IO; - -/** - * Inflates a delta in an incremental way. - * <p> - * Implementations must provide a means to access a stream for the base object. - * This stream may be accessed multiple times, in order to randomly position it - * to match the copy instructions. A {@code DeltaStream} performs an efficient - * skip by only moving through the delta stream, making restarts of stacked - * deltas reasonably efficient. - */ -public abstract class DeltaStream extends InputStream { - private static final int CMD_COPY = 0; - - private static final int CMD_INSERT = 1; - - private static final int CMD_EOF = 2; - - private final InputStream deltaStream; - - private long baseSize; - - private long resultSize; - - private final byte[] cmdbuf = new byte[512]; - - private int cmdptr; - - private int cmdcnt; - - /** Stream to read from the base object. */ - private InputStream baseStream; - - /** Current position within {@link #baseStream}. */ - private long baseOffset; - - private int curcmd; - - /** If {@code curcmd == CMD_COPY}, position the base has to be at. */ - private long copyOffset; - - /** Total number of bytes in this current command. */ - private int copySize; - - /** - * Construct a delta application stream, reading instructions. - * - * @param deltaStream - * the stream to read delta instructions from. - * @throws IOException - * the delta instruction stream cannot be read, or is - * inconsistent with the the base object information. - */ - public DeltaStream(final InputStream deltaStream) throws IOException { - this.deltaStream = deltaStream; - if (!fill(cmdbuf.length)) - throw new EOFException(); - - // Length of the base object. - // - int c, shift = 0; - do { - c = cmdbuf[cmdptr++] & 0xff; - baseSize |= ((long) (c & 0x7f)) << shift; - shift += 7; - } while ((c & 0x80) != 0); - - // Length of the resulting object. - // - shift = 0; - do { - c = cmdbuf[cmdptr++] & 0xff; - resultSize |= ((long) (c & 0x7f)) << shift; - shift += 7; - } while ((c & 0x80) != 0); - - curcmd = next(); - } - - /** - * Open the base stream. - * <p> - * The {@code DeltaStream} may close and reopen the base stream multiple - * times if copy instructions use offsets out of order. This can occur if a - * large block in the file was moved from near the top, to near the bottom. - * In such cases the reopened stream is skipped to the target offset, so - * {@code skip(long)} should be as efficient as possible. - * - * @return stream to read from the base object. This stream should not be - * buffered (or should be only minimally buffered), and does not - * need to support mark/reset. - * @throws IOException - * the base object cannot be opened for reading. - */ - protected abstract InputStream openBase() throws IOException; - - /** - * @return length of the base object, in bytes. - * @throws IOException - * the length of the base cannot be determined. - */ - protected abstract long getBaseSize() throws IOException; - - /** @return total size of this stream, in bytes. */ - public long getSize() { - return resultSize; - } - - @Override - public int read() throws IOException { - byte[] buf = new byte[1]; - int n = read(buf, 0, 1); - return n == 1 ? buf[0] & 0xff : -1; - } - - @Override - public void close() throws IOException { - deltaStream.close(); - if (baseStream != null) - baseStream.close(); - } - - @Override - public long skip(long len) throws IOException { - long act = 0; - while (0 < len) { - long n = Math.min(len, copySize); - switch (curcmd) { - case CMD_COPY: - copyOffset += n; - break; - - case CMD_INSERT: - cmdptr += n; - break; - - case CMD_EOF: - return act; - default: - throw new CorruptObjectException( - JGitText.get().unsupportedCommand0); - } - - act += n; - len -= n; - copySize -= n; - if (copySize == 0) - curcmd = next(); - } - return act; - } - - @Override - public int read(byte[] buf, int off, int len) throws IOException { - int act = 0; - while (0 < len) { - int n = Math.min(len, copySize); - switch (curcmd) { - case CMD_COPY: - seekBase(); - n = baseStream.read(buf, off, n); - if (n < 0) - throw new CorruptObjectException( - JGitText.get().baseLengthIncorrect); - copyOffset += n; - baseOffset = copyOffset; - break; - - case CMD_INSERT: - System.arraycopy(cmdbuf, cmdptr, buf, off, n); - cmdptr += n; - break; - - case CMD_EOF: - return 0 < act ? act : -1; - - default: - throw new CorruptObjectException( - JGitText.get().unsupportedCommand0); - } - - act += n; - off += n; - len -= n; - copySize -= n; - if (copySize == 0) - curcmd = next(); - } - return act; - } - - private boolean fill(final int need) throws IOException { - int n = have(); - if (need < n) - return true; - if (n == 0) { - cmdptr = 0; - cmdcnt = 0; - } else if (cmdbuf.length - cmdptr < need) { - // There isn't room for the entire worst-case copy command, - // so shift the array down to make sure we can use the entire - // command without having it span across the end of the array. - // - System.arraycopy(cmdbuf, cmdptr, cmdbuf, 0, n); - cmdptr = 0; - cmdcnt = n; - } - - do { - n = deltaStream.read(cmdbuf, cmdcnt, cmdbuf.length - cmdcnt); - if (n < 0) - return 0 < have(); - cmdcnt += n; - } while (cmdcnt < cmdbuf.length); - return true; - } - - private int next() throws IOException { - if (!fill(8)) - return CMD_EOF; - - final int cmd = cmdbuf[cmdptr++] & 0xff; - if ((cmd & 0x80) != 0) { - // Determine the segment of the base which should - // be copied into the output. The segment is given - // as an offset and a length. - // - copyOffset = 0; - if ((cmd & 0x01) != 0) - copyOffset = cmdbuf[cmdptr++] & 0xff; - if ((cmd & 0x02) != 0) - copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 8; - if ((cmd & 0x04) != 0) - copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 16; - if ((cmd & 0x08) != 0) - copyOffset |= ((long) (cmdbuf[cmdptr++] & 0xff)) << 24; - - copySize = 0; - if ((cmd & 0x10) != 0) - copySize = cmdbuf[cmdptr++] & 0xff; - if ((cmd & 0x20) != 0) - copySize |= (cmdbuf[cmdptr++] & 0xff) << 8; - if ((cmd & 0x40) != 0) - copySize |= (cmdbuf[cmdptr++] & 0xff) << 16; - if (copySize == 0) - copySize = 0x10000; - return CMD_COPY; - - } else if (cmd != 0) { - // Anything else the data is literal within the delta - // itself. Page the entire thing into the cmdbuf, if - // its not already there. - // - fill(cmd); - copySize = cmd; - return CMD_INSERT; - - } else { - // cmd == 0 has been reserved for future encoding but - // for now its not acceptable. - // - throw new CorruptObjectException(JGitText.get().unsupportedCommand0); - } - } - - private int have() { - return cmdcnt - cmdptr; - } - - private void seekBase() throws IOException { - if (baseStream == null) { - baseStream = openBase(); - if (getBaseSize() != baseSize) - throw new CorruptObjectException( - JGitText.get().baseLengthIncorrect); - IO.skipFully(baseStream, copyOffset); - baseOffset = copyOffset; - - } else if (baseOffset < copyOffset) { - IO.skipFully(baseStream, copyOffset - baseOffset); - baseOffset = copyOffset; - - } else if (baseOffset > copyOffset) { - baseStream.close(); - baseStream = openBase(); - IO.skipFully(baseStream, copyOffset); - baseOffset = copyOffset; - } - } -} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java index 36d429a021..65e9d4dc55 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java @@ -117,6 +117,9 @@ public abstract class JschConfigSessionFactory extends SshSessionFactory { } catch (JSchException e) { session.disconnect(); session = null; + // Make sure our known_hosts is not outdated + knownHosts(getJSch(hc, fs), fs); + // if authentication failed maybe credentials changed at the // remote end therefore reset credentials and retry if (credentialsProvider != null && e.getCause() == null |