diff options
author | Christian Halstrick <christian.halstrick@sap.com> | 2015-10-28 13:25:09 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2015-11-27 23:23:09 +0100 |
commit | 5d9f595eb87fba31c2253051102116fc7876e6c0 (patch) | |
tree | 3c20ebe72c89617a7c575612f46699d18ca40833 /org.eclipse.jgit.test | |
parent | 75697adc5a0024449351aacac89618c3b83add11 (diff) | |
download | jgit-5d9f595eb87fba31c2253051102116fc7876e6c0.tar.gz jgit-5d9f595eb87fba31c2253051102116fc7876e6c0.zip |
Add support for clean filters
When filters are defined for certain paths in gitattributes make
sure that clean filters are processed when adding new content to the
object database.
Change-Id: Iffd72914cec5b434ba4d0de232e285b7492db868
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java index 2abed3adc8..a5ad18d102 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; @@ -52,11 +53,13 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; +import org.eclipse.jgit.api.errors.FilterFailedException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; +import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; @@ -112,6 +115,191 @@ public class AddCommandTest extends RepositoryTestCase { } @Test + public void testCleanFilter() throws IOException, + GitAPIException { + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile("src/a.tmp", "foo"); + // Caution: we need a trailing '\n' since sed on mac always appends + // linefeeds if missing + writeTrashFile("src/a.txt", "foo\n"); + File script = writeTempFile("sed s/o/e/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + slashify(script.getPath())); + config.save(); + + git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp") + .call(); + + assertEquals( + "[src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:fee\n]", + indexState(CONTENT)); + } + + @Test + public void testCleanFilterEnvironment() + throws IOException, GitAPIException { + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile("src/a.txt", "foo"); + File script = writeTempFile("echo $GIT_DIR; echo 1 >xyz"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + slashify(script.getPath())); + config.save(); + git.add().addFilepattern("src/a.txt").call(); + + String gitDir = db.getDirectory().getAbsolutePath(); + assertEquals("[src/a.txt, mode:100644, content:" + gitDir + + "\n]", indexState(CONTENT)); + assertTrue(new File(db.getWorkTree(), "xyz").exists()); + } + + @Test + public void testMultipleCleanFilter() throws IOException, GitAPIException { + writeTrashFile(".gitattributes", + "*.txt filter=tstFilter\n*.tmp filter=tstFilter2"); + // Caution: we need a trailing '\n' since sed on mac always appends + // linefeeds if missing + writeTrashFile("src/a.tmp", "foo\n"); + writeTrashFile("src/a.txt", "foo\n"); + File script = writeTempFile("sed s/o/e/g"); + File script2 = writeTempFile("sed s/f/x/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + slashify(script.getPath())); + config.setString("filter", "tstFilter2", "clean", + "sh " + slashify(script2.getPath())); + config.save(); + + git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp") + .call(); + + assertEquals( + "[src/a.tmp, mode:100644, content:xoo\n][src/a.txt, mode:100644, content:fee\n]", + indexState(CONTENT)); + + // TODO: multiple clean filters for one file??? + } + + /** + * The path of an added file name contains ';' and afterwards malicious + * commands. Make sure when calling filter commands to properly escape the + * filenames + * + * @throws IOException + * @throws GitAPIException + */ + @Test + public void testCommandInjection() throws IOException, GitAPIException { + // Caution: we need a trailing '\n' since sed on mac always appends + // linefeeds if missing + writeTrashFile("; echo virus", "foo\n"); + File script = writeTempFile("sed s/o/e/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + slashify(script.getPath()) + " %f"); + writeTrashFile(".gitattributes", "* filter=tstFilter"); + + git.add().addFilepattern("; echo virus").call(); + // Without proper escaping the content would be "feovirus". The sed + // command and the "echo virus" would contribute to the content + assertEquals("[; echo virus, mode:100644, content:fee\n]", + indexState(CONTENT)); + } + + @Test + public void testBadCleanFilter() throws IOException, GitAPIException { + writeTrashFile("a.txt", "foo"); + File script = writeTempFile("sedfoo s/o/e/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + script.getPath()); + config.save(); + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + + try { + git.add().addFilepattern("a.txt").call(); + fail("Didn't received the expected exception"); + } catch (FilterFailedException e) { + assertEquals(127, e.getReturnCode()); + } + } + + @Test + public void testBadCleanFilter2() throws IOException, GitAPIException { + writeTrashFile("a.txt", "foo"); + File script = writeTempFile("sed s/o/e/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "shfoo " + script.getPath()); + config.save(); + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + + try { + git.add().addFilepattern("a.txt").call(); + fail("Didn't received the expected exception"); + } catch (FilterFailedException e) { + assertEquals(127, e.getReturnCode()); + } + } + + @Test + public void testCleanFilterReturning12() throws IOException, + GitAPIException { + writeTrashFile("a.txt", "foo"); + File script = writeTempFile("exit 12"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "clean", + "sh " + slashify(script.getPath())); + config.save(); + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + + try { + git.add().addFilepattern("a.txt").call(); + fail("Didn't received the expected exception"); + } catch (FilterFailedException e) { + assertEquals(12, e.getReturnCode()); + } + } + + @Test + public void testNotApplicableFilter() throws IOException, GitAPIException { + writeTrashFile("a.txt", "foo"); + File script = writeTempFile("sed s/o/e/g"); + + Git git = new Git(db); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "tstFilter", "something", + "sh " + script.getPath()); + config.save(); + writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + + git.add().addFilepattern("a.txt").call(); + + assertEquals("[a.txt, mode:100644, content:foo]", indexState(CONTENT)); + } + + private File writeTempFile(String body) throws IOException { + File f = File.createTempFile("AddCommandTest_", ""); + JGitTestUtil.write(f, body); + return f; + } + + @Test public void testAddExistingSingleSmallFileWithNewLine() throws IOException, GitAPIException { File file = new File(db.getWorkTree(), "a.txt"); |