/*
 * Copyright (C) 2011, Robin Rosenberg <robin.rosenberg@dewire.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.lib;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.dircache.InvalidPathException;
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Test;

public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase {

	protected ObjectId theHead;
	protected ObjectId theMerge;

	@Test
	public void testMaliciousAbsolutePathIsOk() throws Exception {
		testMaliciousPathGoodFirstCheckout("ok");
	}

	@Test
	public void testMaliciousAbsolutePathIsOkSecondCheckout() throws Exception {
		testMaliciousPathGoodSecondCheckout("ok");
	}

	@Test
	public void testMaliciousAbsolutePathIsOkTwoLevels() throws Exception {
		testMaliciousPathGoodSecondCheckout("a", "ok");
	}

	@Test
	public void testMaliciousAbsolutePath() throws Exception {
		testMaliciousPathBadFirstCheckout("/tmp/x");
	}

	@Test
	public void testMaliciousAbsolutePathSecondCheckout() throws Exception {
		testMaliciousPathBadSecondCheckout("/tmp/x");
	}

	@Test
	public void testMaliciousAbsolutePathTwoLevelsFirstBad() throws Exception {
		testMaliciousPathBadFirstCheckout("/tmp/x", "y");
	}

	@Test
	public void testMaliciousAbsolutePathTwoLevelsSecondBad() throws Exception {
		testMaliciousPathBadFirstCheckout("y", "/tmp/x");
	}

	@Test
	public void testMaliciousAbsoluteCurDrivePathWindows() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("\\somepath");
	}

	@Test
	public void testMaliciousAbsoluteCurDrivePathWindowsOnUnix()
			throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathGoodFirstCheckout("\\somepath");
	}

	@Test
	public void testMaliciousAbsoluteUNCPathWindows1() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("\\\\somepath");
	}

	@Test
	public void testMaliciousAbsoluteUNCPathWindows1OnUnix() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathGoodFirstCheckout("\\\\somepath");
	}

	@Test
	public void testMaliciousAbsoluteUNCPathWindows2() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("\\/somepath");
	}

	@Test
	public void testMaliciousAbsoluteUNCPathWindows2OnUnix() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathBadFirstCheckout("\\/somepath");
	}

	@Test
	public void testMaliciousAbsoluteWindowsPath1() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("c:\\temp\\x");
	}

	@Test
	public void testMaliciousAbsoluteWindowsPath1OnUnix() throws Exception {
		if (File.separatorChar == '\\')
			return; // cannot emulate Unix on Windows for this test
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathGoodFirstCheckout("c:\\temp\\x");
	}

	@Test
	public void testMaliciousAbsoluteWindowsPath2() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setCurrentPlatform();
		testMaliciousPathBadFirstCheckout("c:/temp/x");
	}

	@Test
	public void testMaliciousGitPath1() throws Exception {
		testMaliciousPathBadFirstCheckout(".git/konfig");
	}

	@Test
	public void testMaliciousGitPath2() throws Exception {
		testMaliciousPathBadFirstCheckout(".git", "konfig");
	}

	@Test
	public void testMaliciousGitPath1Case() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows(); // or OS X
		testMaliciousPathBadFirstCheckout(".Git/konfig");
	}

	@Test
	public void testMaliciousGitPath2Case() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows(); // or OS X
		testMaliciousPathBadFirstCheckout(".gIt", "konfig");
	}

	@Test
	public void testMaliciousGitPath3Case() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows(); // or OS X
		testMaliciousPathBadFirstCheckout(".giT", "konfig");
	}

	@Test
	public void testMaliciousGitPathEndSpaceWindows() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout(".git ", "konfig");
	}

	@Test
	public void testMaliciousGitPathEndSpaceUnixOk() throws Exception {
		testMaliciousPathBadFirstCheckout(".git ", "konfig");
	}

	@Test
	public void testMaliciousGitPathEndDotWindows1() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout(".git.", "konfig");
	}

	@Test
	public void testMaliciousGitPathEndDotWindows2() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout(".f.");
	}

	@Test
	public void testMaliciousGitPathEndDotWindows3() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathGoodFirstCheckout(".f");
	}

	@Test
	public void testMaliciousGitPathEndDotUnixOk() throws Exception {
		testMaliciousPathBadFirstCheckout(".git.", "konfig");
	}

	@Test
	public void testMaliciousPathDotDot() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setCurrentPlatform();
		testMaliciousPathBadFirstCheckout("..", "no");
	}

	@Test
	public void testMaliciousPathDot() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setCurrentPlatform();
		testMaliciousPathBadFirstCheckout(".", "no");
	}

	@Test
	public void testMaliciousPathEmptyUnix() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathBadFirstCheckout("", "no");
	}

	@Test
	public void testMaliciousPathEmptyWindows() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("", "no");
	}

	@Test
	public void testMaliciousWindowsADS() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("some:path");
	}

	@Test
	public void testMaliciousWindowsADSOnUnix() throws Exception {
		if (File.separatorChar == '\\')
			return; // cannot emulate Unix on Windows for this test
		((MockSystemReader) SystemReader.getInstance()).setUnix();
		testMaliciousPathGoodFirstCheckout("some:path");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgCon() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("con");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgConDotSuffix() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("con.txt");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgLpt1() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("lpt1");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgLpt1DotSuffix() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathBadFirstCheckout("lpt1.txt");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgDotCon() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathGoodFirstCheckout(".con");
	}

	@Test
	public void testForbiddenNamesOnWindowsEgLpr() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathGoodFirstCheckout("lpt"); // good name
	}

	@Test
	public void testForbiddenNamesOnWindowsEgCon1() throws Exception {
		((MockSystemReader) SystemReader.getInstance()).setWindows();
		testMaliciousPathGoodFirstCheckout("con1"); // good name
	}

	@Test
	public void testForbiddenWindowsNamesOnUnixEgCon() throws Exception {
		if (File.separatorChar == '\\')
			return; // cannot emulate Unix on Windows for this test
		testMaliciousPathGoodFirstCheckout("con");
	}

	@Test
	public void testForbiddenWindowsNamesOnUnixEgLpt1() throws Exception {
		if (File.separatorChar == '\\')
			return; // cannot emulate Unix on Windows for this test
		testMaliciousPathGoodFirstCheckout("lpt1");
	}

	private void testMaliciousPathBadFirstCheckout(String... paths)
			throws Exception {
		testMaliciousPath(false, false, paths);
	}

	private void testMaliciousPathBadSecondCheckout(String... paths) throws Exception {
		testMaliciousPath(false, true, paths);
	}

	private void testMaliciousPathGoodFirstCheckout(String... paths)
			throws Exception {
		testMaliciousPath(true, false, paths);
	}

	private void testMaliciousPathGoodSecondCheckout(String... paths) throws Exception {
		testMaliciousPath(true, true, paths);
	}

	/**
	 * Create a bad tree and tries to check it out
	 *
	 * @param good
	 *            true if we expect this to pass
	 * @param secondCheckout
	 *            perform the actual test on the second checkout
	 * @param path
	 *            to the blob, one or more levels
	 * @throws GitAPIException
	 * @throws IOException
	 */
	private void testMaliciousPath(boolean good, boolean secondCheckout,
			String... path) throws GitAPIException, IOException {
		try (Git git = new Git(db);
				RevWalk revWalk = new RevWalk(git.getRepository())) {
			ObjectInserter newObjectInserter;
			newObjectInserter = git.getRepository().newObjectInserter();
			ObjectId blobId = newObjectInserter.insert(Constants.OBJ_BLOB,
					"data".getBytes());
			newObjectInserter = git.getRepository().newObjectInserter();
			FileMode mode = FileMode.REGULAR_FILE;
			ObjectId insertId = blobId;
			for (int i = path.length - 1; i >= 0; --i) {
				TreeFormatter treeFormatter = new TreeFormatter();
				treeFormatter.append("goodpath", mode, insertId);
				insertId = newObjectInserter.insert(treeFormatter);
				mode = FileMode.TREE;
			}
			newObjectInserter = git.getRepository().newObjectInserter();
			CommitBuilder commitBuilder = new CommitBuilder();
			commitBuilder.setAuthor(author);
			commitBuilder.setCommitter(committer);
			commitBuilder.setMessage("foo#1");
			commitBuilder.setTreeId(insertId);
			ObjectId firstCommitId = newObjectInserter.insert(commitBuilder);

			newObjectInserter = git.getRepository().newObjectInserter();
			mode = FileMode.REGULAR_FILE;
			insertId = blobId;
			for (int i = path.length - 1; i >= 0; --i) {
				TreeFormatter treeFormatter = new TreeFormatter();
				treeFormatter.append(path[i], mode, insertId);
				insertId = newObjectInserter.insert(treeFormatter);
				mode = FileMode.TREE;
			}

			// Create another commit
			commitBuilder = new CommitBuilder();
			commitBuilder.setAuthor(author);
			commitBuilder.setCommitter(committer);
			commitBuilder.setMessage("foo#2");
			commitBuilder.setTreeId(insertId);
			commitBuilder.setParentId(firstCommitId);
			ObjectId commitId = newObjectInserter.insert(commitBuilder);

			if (!secondCheckout)
				git.checkout().setStartPoint(revWalk.parseCommit(firstCommitId))
						.setName("refs/heads/master").setCreateBranch(true).call();
			try {
				if (secondCheckout) {
					git.checkout().setStartPoint(revWalk.parseCommit(commitId))
							.setName("refs/heads/master").setCreateBranch(true)
							.call();
				} else {
					git.branchCreate().setName("refs/heads/next")
							.setStartPoint(commitId.name()).call();
					git.checkout().setName("refs/heads/next")
							.call();
				}
				if (!good)
					fail("Checkout of Tree " + Arrays.asList(path) + " should fail");
			} catch (InvalidPathException e) {
				if (good)
					throw e;
				assertTrue(e.getMessage().startsWith("Invalid path"));
			}
		}
	}

}
