diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2009-09-11 12:33:05 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2010-02-03 19:58:20 -0800 |
commit | 29b8fa84e680ce090ed355afd6052c4be9137a0c (patch) | |
tree | fe7cb5afcd2272d1c7bdbd89e6d0167d92e34c12 /org.eclipse.jgit.test/tst/org | |
parent | 329abf721214f60077c9b17cc2c4235bdeed2c4f (diff) | |
download | jgit-29b8fa84e680ce090ed355afd6052c4be9137a0c.tar.gz jgit-29b8fa84e680ce090ed355afd6052c4be9137a0c.zip |
Don't allow DirCacheEntry with mode of 0
A 0 file mode in a DirCacheEntry is not a valid mode. To C git
such a value indicates the record should not be present. We already
were catching this bad state and exceptioning out when writing tree
objects to disk, but we did not fail when writing the dircache back
to disk. This allowed JGit applications to create a dircache file
which C git would not like to read.
Instead of checking the mode during writes, we now check during
mutation. This allows application bugs to be detected sooner and
closer to the cause site. It also allows us to avoid checking most
of the records which we read in from disk, as we can assume these
are formatted correctly.
Some of our unit tests were not setting the FileMode on their test
entry, so they had to be updated to use REGULAR_FILE.
Change-Id: Ie412053c390b737c0ece57b8e063e4355ee32437
Originally: http://thread.gmane.org/gmane.comp.version-control.git/128214/focus=128213
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
CC: Adam W. Hawks <awhawks@writeme.com>
Diffstat (limited to 'org.eclipse.jgit.test/tst/org')
7 files changed, 213 insertions, 14 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index cc37c2bf8b..b35fc76175 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.dircache; import java.io.File; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheBasicTest extends RepositoryTestCase { @@ -176,8 +177,10 @@ public class DirCacheBasicTest extends RepositoryTestCase { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index fe02a1b23e..e919e41f4d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -65,6 +65,20 @@ public class DirCacheBuilderTest extends RepositoryTestCase { } } + public void testBuildRejectsUnsetFileMode() throws Exception { + final DirCache dc = DirCache.newInCore(); + final DirCacheBuilder b = dc.builder(); + assertNotNull(b); + + final DirCacheEntry e = new DirCacheEntry("a"); + assertEquals(0, e.getRawMode()); + try { + b.add(e); + } catch (IllegalArgumentException err) { + assertEquals("FileMode not set for path a", err.getMessage()); + } + } + public void testBuildOneFile_FinishWriteCommit() throws Exception { final String path = "a-file-path"; final FileMode mode = FileMode.REGULAR_FILE; @@ -168,6 +182,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase { assertNotNull(b); final DirCacheEntry entOrig = new DirCacheEntry(path); + entOrig.setFileMode(FileMode.REGULAR_FILE); assertNotSame(path, entOrig.getPathString()); assertEquals(path, entOrig.getPathString()); b.add(entOrig); @@ -191,8 +206,10 @@ public class DirCacheBuilderTest extends RepositoryTestCase { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) @@ -213,8 +230,10 @@ public class DirCacheBuilderTest extends RepositoryTestCase { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = ents.length - 1; i >= 0; i--) @@ -235,8 +254,10 @@ public class DirCacheBuilderTest extends RepositoryTestCase { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } { final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java new file mode 100644 index 0000000000..446fd70601 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2009, 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.dircache; + +import junit.framework.TestCase; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; + +public class DirCacheEntryTest extends TestCase { + public void testIsValidPath() { + assertTrue(isValidPath("a")); + assertTrue(isValidPath("a/b")); + assertTrue(isValidPath("ab/cd/ef")); + + assertFalse(isValidPath("")); + assertFalse(isValidPath("/a")); + assertFalse(isValidPath("a//b")); + assertFalse(isValidPath("ab/cd//ef")); + assertFalse(isValidPath("a/")); + assertFalse(isValidPath("ab/cd/ef/")); + assertFalse(isValidPath("a\u0000b")); + } + + private static boolean isValidPath(final String path) { + return DirCacheEntry.isValidPath(Constants.encode(path)); + } + + public void testCreate_ByStringPath() { + assertEquals("a", new DirCacheEntry("a").getPathString()); + assertEquals("a/b", new DirCacheEntry("a/b").getPathString()); + + try { + new DirCacheEntry("/a"); + fail("Incorrectly created DirCacheEntry"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid path: /a", err.getMessage()); + } + } + + public void testCreate_ByStringPathAndStage() { + DirCacheEntry e; + + e = new DirCacheEntry("a", 0); + assertEquals("a", e.getPathString()); + assertEquals(0, e.getStage()); + + e = new DirCacheEntry("a/b", 1); + assertEquals("a/b", e.getPathString()); + assertEquals(1, e.getStage()); + + e = new DirCacheEntry("a/c", 2); + assertEquals("a/c", e.getPathString()); + assertEquals(2, e.getStage()); + + e = new DirCacheEntry("a/d", 3); + assertEquals("a/d", e.getPathString()); + assertEquals(3, e.getStage()); + + try { + new DirCacheEntry("/a", 1); + fail("Incorrectly created DirCacheEntry"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid path: /a", err.getMessage()); + } + + try { + new DirCacheEntry("a", -11); + fail("Incorrectly created DirCacheEntry"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid stage -11 for path a", err.getMessage()); + } + + try { + new DirCacheEntry("a", 4); + fail("Incorrectly created DirCacheEntry"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid stage 4 for path a", err.getMessage()); + } + } + + public void testSetFileMode() { + final DirCacheEntry e = new DirCacheEntry("a"); + + assertEquals(0, e.getRawMode()); + + e.setFileMode(FileMode.REGULAR_FILE); + assertSame(FileMode.REGULAR_FILE, e.getFileMode()); + assertEquals(FileMode.REGULAR_FILE.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.EXECUTABLE_FILE); + assertSame(FileMode.EXECUTABLE_FILE, e.getFileMode()); + assertEquals(FileMode.EXECUTABLE_FILE.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.SYMLINK); + assertSame(FileMode.SYMLINK, e.getFileMode()); + assertEquals(FileMode.SYMLINK.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.GITLINK); + assertSame(FileMode.GITLINK, e.getFileMode()); + assertEquals(FileMode.GITLINK.getBits(), e.getRawMode()); + + try { + e.setFileMode(FileMode.MISSING); + fail("incorrectly accepted FileMode.MISSING"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid mode 0 for path a", err.getMessage()); + } + + try { + e.setFileMode(FileMode.TREE); + fail("incorrectly accepted FileMode.TREE"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid mode 40000 for path a", err.getMessage()); + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java index cdc659a21c..d5a632c48c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -43,6 +43,7 @@ package org.eclipse.jgit.dircache; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheFindTest extends RepositoryTestCase { @@ -51,8 +52,10 @@ public class DirCacheFindTest extends RepositoryTestCase { final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 3; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java index db9f684fed..efea117388 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -74,8 +74,10 @@ public class DirCacheIteratorTest extends RepositoryTestCase { final String[] paths = { "a.", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java index ceaadf97b6..0926ab9899 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -46,6 +46,7 @@ package org.eclipse.jgit.dircache; import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheLargePathTest extends RepositoryTestCase { @@ -76,6 +77,10 @@ public class DirCacheLargePathTest extends RepositoryTestCase { final DirCacheEntry longEnt = new DirCacheEntry(longPath); final DirCacheEntry shortEnt = new DirCacheEntry(shortPath); + + longEnt.setFileMode(FileMode.REGULAR_FILE); + shortEnt.setFileMode(FileMode.REGULAR_FILE); + assertEquals(longPath, longEnt.getPathString()); assertEquals(shortPath, shortEnt.getPathString()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java index f74a35cd35..8345c5d83d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -46,6 +46,7 @@ package org.eclipse.jgit.dircache; import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheTreeTest extends RepositoryTestCase { @@ -81,8 +82,10 @@ public class DirCacheTreeTest extends RepositoryTestCase { final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 3; @@ -116,8 +119,10 @@ public class DirCacheTreeTest extends RepositoryTestCase { final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 4; final int acFirst = 2; @@ -173,8 +178,10 @@ public class DirCacheTreeTest extends RepositoryTestCase { final String B = String.format("b%2000s", "b"); final String[] paths = { A + ".", A + "." + B, A + "/" + B, A + "0" + B }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) |