[EGIT PATCH 1/4] Detect path names which overflow the name length field in the index

Subsystems: the rest

DORMANTno replies

4 messages, 1 author, 2016-06-15 · open the first message on its own page

[EGIT PATCH 1/4] Detect path names which overflow the name length field in the index

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:45:10

C Git allows a path name to be longer than 4095 bytes by storing 4095
into the path name length field within flags and then searching for a
null terminator at the end of the path name, instead of relying on the
length indicatior.  We cannot do this (easily) from an InputStream so
we are currently going to just abort with an exception if we find such
an extremely long path name.

Signed-off-by: Shawn O. Pearce <redacted>
---
 .../org/spearce/jgit/dircache/DirCacheEntry.java   |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
index c481e43..bcf5596 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
@@ -81,6 +81,9 @@
 
 	private static final int P_FLAGS = 60;
 
+	/** Mask applied to data in {@link #P_FLAGS} to get the name length. */
+	private static final int NAME_MASK = 0xfff;
+
 	static final int INFO_LEN = 62;
 
 	private static final int ASSUME_VALID = 0x80;
@@ -101,7 +104,9 @@ DirCacheEntry(final byte[] sharedInfo, final int infoAt,
 
 		NB.readFully(in, info, infoOffset, INFO_LEN);
 
-		int pathLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & 0xfff;
+		int pathLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK;
+		if (pathLen == NAME_MASK)
+			throw new IOException("Path name too long for jgit");
 		path = new byte[pathLen];
 		NB.readFully(in, path, 0, pathLen);
 
@@ -135,6 +140,8 @@ public DirCacheEntry(final byte[] newPath) {
 		infoOffset = 0;
 
 		path = newPath;
+		if (path.length >= NAME_MASK)
+			throw new IllegalArgumentException("Path name too long for jgit");
 		NB.encodeInt16(info, infoOffset + P_FLAGS, path.length);
 	}
 
@@ -364,10 +371,10 @@ public String getPathString() {
 	 *            the entry to copy ObjectId and meta fields from.
 	 */
 	public void copyMetaData(final DirCacheEntry src) {
-		final int pLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & 0xfff;
+		final int pLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK;
 		System.arraycopy(src.info, src.infoOffset, info, infoOffset, INFO_LEN);
 		NB.encodeInt16(info, infoOffset + P_FLAGS, pLen
-				| NB.decodeUInt16(info, infoOffset + P_FLAGS) & ~0xfff);
+				| NB.decodeUInt16(info, infoOffset + P_FLAGS) & ~NAME_MASK);
 	}
 
 	private long decodeTS(final int pIdx) {
-- 
1.6.0.87.g2858d

[EGIT PATCH 4/4] Fix DirCache's skip over null byte padding when reading a DIRC file

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:45:10

Sometimes we hit EOFException while reading from a 'DIRC' file with
the new DirCache API.  This was caused by BufferedInputStream.skip
skipping only part of the range we asked it to skip if the range we
asked it to skip spanned over the end of the current buffer block.
Two skip requests are necessary in this case: one to force the stream
to skip to the end of the buffer, and another to skip over data in
the source stream before reading the next buffer block into memory.

NB.skipFully handles this by abstracting the necessary loop into
a utility function, much like NB.readFully handles the necessary
read loop to ensure we read a full block of data.

DirCacheEntry and DirCache both need to use this routine to skip
over the parts of the DIRC file they do not wish to read.

Signed-off-by: Shawn O. Pearce <redacted>
---

  This actually fixes the bug EOFException bug identified by John Franey.

 .../src/org/spearce/jgit/dircache/DirCache.java    |    2 +-
 .../org/spearce/jgit/dircache/DirCacheEntry.java   |    2 +-
 org.spearce.jgit/src/org/spearce/jgit/util/NB.java |   27 ++++++++++++++++++++
 3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCache.java b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCache.java
index 995942c..76657c4 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCache.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCache.java
@@ -370,7 +370,7 @@ private void readFrom(final FileInputStream inStream) throws IOException,
 					// a performance optimization. Since we do not
 					// understand it, we can safely skip past it.
 					//
-					in.skip(NB.decodeInt32(hdr, 4));
+					NB.skipFully(in, NB.decodeUInt32(hdr, 4));
 				} else {
 					// The extension is not an optimization and is
 					// _required_ to understand this index format.
diff --git a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
index bcf5596..011bc16 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheEntry.java
@@ -116,7 +116,7 @@ DirCacheEntry(final byte[] sharedInfo, final int infoAt,
 		final int actLen = INFO_LEN + pathLen;
 		final int expLen = (actLen + 8) & ~7;
 		if (actLen != expLen)
-			in.skip(expLen - actLen);
+			NB.skipFully(in, expLen - actLen);
 	}
 
 	/**
diff --git a/org.spearce.jgit/src/org/spearce/jgit/util/NB.java b/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
index fa13354..759caf5 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
@@ -71,6 +71,33 @@ public static void readFully(final InputStream fd, final byte[] dst,
 	}
 
 	/**
+	 * Skip an entire region of an input stream.
+	 * <p>
+	 * The input stream's position is moved forward by the number of requested
+	 * bytes, discarding them from the input. This method does not return until
+	 * the exact number of bytes requested has been skipped.
+	 * 
+	 * @param fd
+	 *            the stream to skip bytes from.
+	 * @param toSkip
+	 *            total number of bytes to be discarded. Must be >= 0.
+	 * @throws EOFException
+	 *             the stream ended before the requested number of bytes were
+	 *             skipped.
+	 * @throws IOException
+	 *             there was an error reading from the stream.
+	 */
+	public static void skipFully(final InputStream fd, long toSkip)
+			throws IOException {
+		while (toSkip > 0) {
+			final long r = fd.skip(toSkip);
+			if (r <= 0)
+				throw new EOFException("Short skip of block");
+			toSkip -= r;
+		}
+	}
+
+	/**
 	 * Compare a 32 bit unsigned integer stored in a 32 bit signed integer.
 	 * <p>
 	 * This function performs an unsigned compare operation, even though Java
-- 
1.6.0.87.g2858d

[EGIT PATCH 3/4] Add test cases for NB.encode and NB.decode family of routines

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:45:10

We really need to ensure these methods work correctly, and since
we just suffered from a bug in NB.decodeUInt16 we now have a set
of test cases for the corner conditions of each encode and decode
method pair we support.

Signed-off-by: Shawn O. Pearce <redacted>
---
 .../tst/org/spearce/jgit/util/NBTest.java          |  328 ++++++++++++++++++++
 1 files changed, 328 insertions(+), 0 deletions(-)
 create mode 100644 org.spearce.jgit.test/tst/org/spearce/jgit/util/NBTest.java
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/util/NBTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/util/NBTest.java
new file mode 100644
index 0000000..217db7f
--- /dev/null
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/util/NBTest.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ *
+ * 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 Git Development Community 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.spearce.jgit.util;
+
+import junit.framework.TestCase;
+
+public class NBTest extends TestCase {
+	public void testCompareUInt32() {
+		assertTrue(NB.compareUInt32(0, 0) == 0);
+		assertTrue(NB.compareUInt32(1, 0) > 0);
+		assertTrue(NB.compareUInt32(0, 1) < 0);
+		assertTrue(NB.compareUInt32(-1, 0) > 0);
+		assertTrue(NB.compareUInt32(0, -1) < 0);
+		assertTrue(NB.compareUInt32(-1, 1) > 0);
+		assertTrue(NB.compareUInt32(1, -1) < 0);
+	}
+
+	public void testDecodeUInt16() {
+		assertEquals(0, NB.decodeUInt16(b(0, 0), 0));
+		assertEquals(0, NB.decodeUInt16(padb(3, 0, 0), 3));
+
+		assertEquals(3, NB.decodeUInt16(b(0, 3), 0));
+		assertEquals(3, NB.decodeUInt16(padb(3, 0, 3), 3));
+
+		assertEquals(0xde03, NB.decodeUInt16(b(0xde, 3), 0));
+		assertEquals(0xde03, NB.decodeUInt16(padb(3, 0xde, 3), 3));
+
+		assertEquals(0x03de, NB.decodeUInt16(b(3, 0xde), 0));
+		assertEquals(0x03de, NB.decodeUInt16(padb(3, 3, 0xde), 3));
+
+		assertEquals(0xffff, NB.decodeUInt16(b(0xff, 0xff), 0));
+		assertEquals(0xffff, NB.decodeUInt16(padb(3, 0xff, 0xff), 3));
+	}
+
+	public void testDecodeInt32() {
+		assertEquals(0, NB.decodeInt32(b(0, 0, 0, 0), 0));
+		assertEquals(0, NB.decodeInt32(padb(3, 0, 0, 0, 0), 3));
+
+		assertEquals(3, NB.decodeInt32(b(0, 0, 0, 3), 0));
+		assertEquals(3, NB.decodeInt32(padb(3, 0, 0, 0, 3), 3));
+
+		assertEquals(0xdeadbeef, NB.decodeInt32(b(0xde, 0xad, 0xbe, 0xef), 0));
+		assertEquals(0xdeadbeef, NB.decodeInt32(
+				padb(3, 0xde, 0xad, 0xbe, 0xef), 3));
+
+		assertEquals(0x0310adef, NB.decodeInt32(b(0x03, 0x10, 0xad, 0xef), 0));
+		assertEquals(0x0310adef, NB.decodeInt32(
+				padb(3, 0x03, 0x10, 0xad, 0xef), 3));
+
+		assertEquals(0xffffffff, NB.decodeInt32(b(0xff, 0xff, 0xff, 0xff), 0));
+		assertEquals(0xffffffff, NB.decodeInt32(
+				padb(3, 0xff, 0xff, 0xff, 0xff), 3));
+	}
+
+	public void testDecodeUInt32() {
+		assertEquals(0L, NB.decodeUInt32(b(0, 0, 0, 0), 0));
+		assertEquals(0L, NB.decodeUInt32(padb(3, 0, 0, 0, 0), 3));
+
+		assertEquals(3L, NB.decodeUInt32(b(0, 0, 0, 3), 0));
+		assertEquals(3L, NB.decodeUInt32(padb(3, 0, 0, 0, 3), 3));
+
+		assertEquals(0xdeadbeefL, NB.decodeUInt32(b(0xde, 0xad, 0xbe, 0xef), 0));
+		assertEquals(0xdeadbeefL, NB.decodeUInt32(padb(3, 0xde, 0xad, 0xbe,
+				0xef), 3));
+
+		assertEquals(0x0310adefL, NB.decodeUInt32(b(0x03, 0x10, 0xad, 0xef), 0));
+		assertEquals(0x0310adefL, NB.decodeUInt32(padb(3, 0x03, 0x10, 0xad,
+				0xef), 3));
+
+		assertEquals(0xffffffffL, NB.decodeUInt32(b(0xff, 0xff, 0xff, 0xff), 0));
+		assertEquals(0xffffffffL, NB.decodeUInt32(padb(3, 0xff, 0xff, 0xff,
+				0xff), 3));
+	}
+
+	public void testDecodeUInt64() {
+		assertEquals(0L, NB.decodeUInt64(b(0, 0, 0, 0, 0, 0, 0, 0), 0));
+		assertEquals(0L, NB.decodeUInt64(padb(3, 0, 0, 0, 0, 0, 0, 0, 0), 3));
+
+		assertEquals(3L, NB.decodeUInt64(b(0, 0, 0, 0, 0, 0, 0, 3), 0));
+		assertEquals(3L, NB.decodeUInt64(padb(3, 0, 0, 0, 0, 0, 0, 0, 3), 3));
+
+		assertEquals(0xdeadbeefL, NB.decodeUInt64(b(0, 0, 0, 0, 0xde, 0xad,
+				0xbe, 0xef), 0));
+		assertEquals(0xdeadbeefL, NB.decodeUInt64(padb(3, 0, 0, 0, 0, 0xde,
+				0xad, 0xbe, 0xef), 3));
+
+		assertEquals(0x0310adefL, NB.decodeUInt64(b(0, 0, 0, 0, 0x03, 0x10,
+				0xad, 0xef), 0));
+		assertEquals(0x0310adefL, NB.decodeUInt64(padb(3, 0, 0, 0, 0, 0x03,
+				0x10, 0xad, 0xef), 3));
+
+		assertEquals(0xc0ffee78deadbeefL, NB.decodeUInt64(b(0xc0, 0xff, 0xee,
+				0x78, 0xde, 0xad, 0xbe, 0xef), 0));
+		assertEquals(0xc0ffee78deadbeefL, NB.decodeUInt64(padb(3, 0xc0, 0xff,
+				0xee, 0x78, 0xde, 0xad, 0xbe, 0xef), 3));
+
+		assertEquals(0x00000000ffffffffL, NB.decodeUInt64(b(0, 0, 0, 0, 0xff,
+				0xff, 0xff, 0xff), 0));
+		assertEquals(0x00000000ffffffffL, NB.decodeUInt64(padb(3, 0, 0, 0, 0,
+				0xff, 0xff, 0xff, 0xff), 3));
+		assertEquals(0xffffffffffffffffL, NB.decodeUInt64(b(0xff, 0xff, 0xff,
+				0xff, 0xff, 0xff, 0xff, 0xff), 0));
+		assertEquals(0xffffffffffffffffL, NB.decodeUInt64(padb(3, 0xff, 0xff,
+				0xff, 0xff, 0xff, 0xff, 0xff, 0xff), 3));
+	}
+
+	public void testEncodeInt16() {
+		final byte[] out = new byte[16];
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 0, 0);
+		assertOutput(b(0, 0), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 3, 0);
+		assertOutput(b(0, 0), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 0, 3);
+		assertOutput(b(0, 3), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 3, 3);
+		assertOutput(b(0, 3), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 0, 0xdeac);
+		assertOutput(b(0xde, 0xac), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 3, 0xdeac);
+		assertOutput(b(0xde, 0xac), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt16(out, 3, -1);
+		assertOutput(b(0xff, 0xff), out, 3);
+	}
+
+	public void testEncodeInt32() {
+		final byte[] out = new byte[16];
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 0, 0);
+		assertOutput(b(0, 0, 0, 0), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 3, 0);
+		assertOutput(b(0, 0, 0, 0), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 0, 3);
+		assertOutput(b(0, 0, 0, 3), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 3, 3);
+		assertOutput(b(0, 0, 0, 3), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 0, 0xdeac);
+		assertOutput(b(0, 0, 0xde, 0xac), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 3, 0xdeac);
+		assertOutput(b(0, 0, 0xde, 0xac), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 0, 0xdeac9853);
+		assertOutput(b(0xde, 0xac, 0x98, 0x53), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 3, 0xdeac9853);
+		assertOutput(b(0xde, 0xac, 0x98, 0x53), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt32(out, 3, -1);
+		assertOutput(b(0xff, 0xff, 0xff, 0xff), out, 3);
+	}
+
+	public void testEncodeInt64() {
+		final byte[] out = new byte[16];
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 0, 0L);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0, 0), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, 0L);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0, 0), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 0, 3L);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0, 3), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, 3L);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0, 3), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 0, 0xdeacL);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0xde, 0xac), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, 0xdeacL);
+		assertOutput(b(0, 0, 0, 0, 0, 0, 0xde, 0xac), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 0, 0xdeac9853L);
+		assertOutput(b(0, 0, 0, 0, 0xde, 0xac, 0x98, 0x53), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, 0xdeac9853L);
+		assertOutput(b(0, 0, 0, 0, 0xde, 0xac, 0x98, 0x53), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 0, 0xac431242deac9853L);
+		assertOutput(b(0xac, 0x43, 0x12, 0x42, 0xde, 0xac, 0x98, 0x53), out, 0);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, 0xac431242deac9853L);
+		assertOutput(b(0xac, 0x43, 0x12, 0x42, 0xde, 0xac, 0x98, 0x53), out, 3);
+
+		prepareOutput(out);
+		NB.encodeInt64(out, 3, -1L);
+		assertOutput(b(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), out, 3);
+	}
+
+	private static void prepareOutput(final byte[] buf) {
+		for (int i = 0; i < buf.length; i++)
+			buf[i] = (byte) (0x77 + i);
+	}
+
+	private static void assertOutput(final byte[] expect, final byte[] buf,
+			final int offset) {
+		for (int i = 0; i < offset; i++)
+			assertEquals((byte) (0x77 + i), buf[i]);
+		for (int i = 0; i < expect.length; i++)
+			assertEquals(expect[i], buf[offset + i]);
+		for (int i = offset + expect.length; i < buf.length; i++)
+			assertEquals((byte) (0x77 + i), buf[i]);
+	}
+
+	private static byte[] b(final int a, final int b) {
+		return new byte[] { (byte) a, (byte) b };
+	}
+
+	private static byte[] padb(final int len, final int a, final int b) {
+		final byte[] r = new byte[len + 2];
+		for (int i = 0; i < len; i++)
+			r[i] = (byte) 0xaf;
+		r[len] = (byte) a;
+		r[len + 1] = (byte) b;
+		return r;
+	}
+
+	private static byte[] b(final int a, final int b, final int c, final int d) {
+		return new byte[] { (byte) a, (byte) b, (byte) c, (byte) d };
+	}
+
+	private static byte[] padb(final int len, final int a, final int b,
+			final int c, final int d) {
+		final byte[] r = new byte[len + 4];
+		for (int i = 0; i < len; i++)
+			r[i] = (byte) 0xaf;
+		r[len] = (byte) a;
+		r[len + 1] = (byte) b;
+		r[len + 2] = (byte) c;
+		r[len + 3] = (byte) d;
+		return r;
+	}
+
+	private static byte[] b(final int a, final int b, final int c, final int d,
+			final int e, final int f, final int g, final int h) {
+		return new byte[] { (byte) a, (byte) b, (byte) c, (byte) d, (byte) e,
+				(byte) f, (byte) g, (byte) h };
+	}
+
+	private static byte[] padb(final int len, final int a, final int b,
+			final int c, final int d, final int e, final int f, final int g,
+			final int h) {
+		final byte[] r = new byte[len + 8];
+		for (int i = 0; i < len; i++)
+			r[i] = (byte) 0xaf;
+		r[len] = (byte) a;
+		r[len + 1] = (byte) b;
+		r[len + 2] = (byte) c;
+		r[len + 3] = (byte) d;
+		r[len + 4] = (byte) e;
+		r[len + 5] = (byte) f;
+		r[len + 6] = (byte) g;
+		r[len + 7] = (byte) h;
+		return r;
+	}
+}
-- 
1.6.0.87.g2858d

[EGIT PATCH 2/4] Fix NB.decodeUInt16 to correctly handle the high byte

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:45:10

Our decodeUInt16 method was buggy and always cleared the high byte
of the pair.  This meant we always lost the upper 8 bits when we
read in a 16 bit unsigned integer, possibly causing us to misread
the data associated with that pair.

Signed-off-by: Shawn O. Pearce <redacted>
---
 org.spearce.jgit/src/org/spearce/jgit/util/NB.java |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/util/NB.java b/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
index c6176f8..fa13354 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/util/NB.java
@@ -102,7 +102,7 @@ public static int compareUInt32(final int a, final int b) {
 	 * @return unsigned integer value that matches the 16 bits read.
 	 */
 	public static int decodeUInt16(final byte[] intbuf, final int offset) {
-		int r = (intbuf[offset] << 8) & 0xff;
+		int r = (intbuf[offset] & 0xff) << 8;
 		return r | (intbuf[offset + 1] & 0xff);
 	}
 
-- 
1.6.0.87.g2858d
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help