/*
 * 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 java.nio.charset.StandardCharsets.UTF_8;
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())) {
			ObjectId blobId;
			try (ObjectInserter newObjectInserter = git.getRepository()
					.newObjectInserter()) {
				blobId = newObjectInserter.insert(Constants.OBJ_BLOB,
					"data".getBytes(UTF_8));
			}
			FileMode mode = FileMode.REGULAR_FILE;
			ObjectId insertId = blobId;
			try (ObjectInserter newObjectInserter = git.getRepository()
					.newObjectInserter()) {
				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;
				}
			}
			ObjectId firstCommitId;
			try (ObjectInserter newObjectInserter = git.getRepository()
					.newObjectInserter()) {
				CommitBuilder commitBuilder = new CommitBuilder();
				commitBuilder.setAuthor(author);
				commitBuilder.setCommitter(committer);
				commitBuilder.setMessage("foo#1");
				commitBuilder.setTreeId(insertId);
				firstCommitId = newObjectInserter.insert(commitBuilder);
			}
			ObjectId commitId;
			try (ObjectInserter 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].getBytes(UTF_8), 0,
							path[i].getBytes(UTF_8).length, mode, insertId,
							true);
					insertId = newObjectInserter.insert(treeFormatter);
					mode = FileMode.TREE;
				}

				// Create another commit
				CommitBuilder commitBuilder = new CommitBuilder();
				commitBuilder.setAuthor(author);
				commitBuilder.setCommitter(committer);
				commitBuilder.setMessage("foo#2");
				commitBuilder.setTreeId(insertId);
				commitBuilder.setParentId(firstCommitId);
				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"));
			}
		}
	}

}
