File libgit2-boo1095219.patch of Package libgit2.9827

diff -urp libgit2-0.24.1.orig/src/checkout.c libgit2-0.24.1/src/checkout.c
--- libgit2-0.24.1.orig/src/checkout.c	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/src/checkout.c	2018-07-31 13:50:10.325585380 -0500
@@ -1229,14 +1229,14 @@ static int checkout_verify_paths(
 	unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS;
 
 	if (action & CHECKOUT_ACTION__REMOVE) {
-		if (!git_path_isvalid(repo, delta->old_file.path, flags)) {
+		if (!git_path_isvalid(repo, delta->old_file.path, delta->old_file.mode, flags)) {
 			giterr_set(GITERR_CHECKOUT, "Cannot remove invalid path '%s'", delta->old_file.path);
 			return -1;
 		}
 	}
 
 	if (action & ~CHECKOUT_ACTION__REMOVE) {
-		if (!git_path_isvalid(repo, delta->new_file.path, flags)) {
+		if (!git_path_isvalid(repo, delta->new_file.path, delta->new_file.mode, flags)) {
 			giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->new_file.path);
 			return -1;
 		}
diff -urp libgit2-0.24.1.orig/src/index.c libgit2-0.24.1/src/index.c
--- libgit2-0.24.1.orig/src/index.c	2018-07-31 11:07:19.252526089 -0500
+++ libgit2-0.24.1/src/index.c	2018-07-31 13:43:18.955178997 -0500
@@ -863,11 +863,13 @@ static int index_entry_create(
 	git_index_entry **out,
 	git_repository *repo,
 	const char *path,
+	struct stat *st,
 	bool from_workdir)
 {
 	size_t pathlen = strlen(path), alloclen;
 	struct entry_internal *entry;
 	unsigned int path_valid_flags = GIT_PATH_REJECT_INDEX_DEFAULTS;
+	uint16_t mode = 0;
 
 	/* always reject placing `.git` in the index and directory traversal.
 	 * when requested, disallow platform-specific filenames and upgrade to
@@ -875,8 +877,10 @@ static int index_entry_create(
 	 */
 	if (from_workdir)
 		path_valid_flags |= GIT_PATH_REJECT_WORKDIR_DEFAULTS;
+	if (st)
+		mode = st->st_mode;
 
-	if (!git_path_isvalid(repo, path, path_valid_flags)) {
+	if (!git_path_isvalid(repo, path, mode, path_valid_flags)) {
 		giterr_set(GITERR_INDEX, "invalid path: '%s'", path);
 		return -1;
 	}
@@ -901,15 +905,35 @@ static int index_entry_init(
 {
 	int error = 0;
 	git_index_entry *entry = NULL;
+	git_buf path = GIT_BUF_INIT;
 	struct stat st;
 	git_oid oid;
+	git_repository *repo;
 
 	if (INDEX_OWNER(index) == NULL)
 		return create_index_error(-1,
 			"Could not initialize index entry. "
 			"Index is not backed up by an existing repository.");
 
-	if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, true) < 0)
+	/*
+	 * FIXME: this is duplicated with the work in
+	 * git_blob__create_from_paths. It should accept an optional stat
+	 * structure so we can pass in the one we have to do here.
+	 */
+	repo = INDEX_OWNER(index);
+	if (git_repository__ensure_not_bare(repo, "create blob from file") < 0)
+		return GIT_EBAREREPO;
+
+	if (git_buf_joinpath(&path, git_repository_workdir(repo), rel_path) < 0)
+		return -1;
+
+	error = git_path_lstat(path.ptr, &st);
+	git_buf_free(&path);
+
+	if (error < 0)
+		return error;
+
+	if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, &st, true) < 0)
 		return -1;
 
 	/* write the blob to disk and get the oid and stat info */
@@ -995,7 +1019,7 @@ static int index_entry_dup(
 	git_index *index,
 	const git_index_entry *src)
 {
-	if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
+	if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
 		return -1;
 
 	index_entry_cpy(*out, src);
@@ -1017,7 +1041,7 @@ static int index_entry_dup_nocache(
 	git_index *index,
 	const git_index_entry *src)
 {
-	if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
+	if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
 		return -1;
 
 	index_entry_cpy_nocache(*out, src);
@@ -1436,9 +1460,6 @@ static int add_repo_as_submodule(git_ind
 	struct stat st;
 	int error;
 
-	if (index_entry_create(&entry, INDEX_OWNER(index), path, true) < 0)
-		return -1;
-
 	if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
 		return error;
 
@@ -1447,6 +1468,9 @@ static int add_repo_as_submodule(git_ind
 		return -1;
 	}
 
+	if (index_entry_create(&entry, INDEX_OWNER(index), path, &st, true) < 0)
+		return -1;
+
 	git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
 
 	if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
@@ -2836,7 +2860,7 @@ static int read_tree_cb(
 	if (git_buf_joinpath(&path, root, tentry->filename) < 0)
 		return -1;
 
-	if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, false) < 0)
+	if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, NULL, false) < 0)
 		return -1;
 
 	entry->mode = tentry->attr;
diff -urp libgit2-0.24.1.orig/src/path.c libgit2-0.24.1/src/path.c
--- libgit2-0.24.1.orig/src/path.c	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/src/path.c	2018-07-31 13:59:09.320731875 -0500
@@ -1502,18 +1502,31 @@ static int32_t next_hfs_char(const char
 	return 0; /* NULL byte -- end of string */
 }
 
-static bool verify_dotgit_hfs(const char *path, size_t len)
+static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len)
 {
-	if (next_hfs_char(&path, &len) != '.' ||
-		next_hfs_char(&path, &len) != 'g' ||
-		next_hfs_char(&path, &len) != 'i' ||
-		next_hfs_char(&path, &len) != 't' ||
-		next_hfs_char(&path, &len) != 0)
+	size_t i;
+	char c;
+
+	if (next_hfs_char(&path, &len) != '.')
+		return true;
+
+	for (i = 0; i < needle_len; i++) {
+		c = next_hfs_char(&path, &len);
+		if (c != needle[i])
+			return true;
+	}
+
+	if (next_hfs_char(&path, &len) != '\0')
 		return true;
 
 	return false;
 }
 
+static bool verify_dotgit_hfs(const char *path, size_t len)
+{
+	return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git"));
+}
+
 GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
 {
 	git_buf *reserved = git_repository__reserved_names_win32;
@@ -1549,6 +1562,57 @@ GIT_INLINE(bool) verify_dotgit_ntfs(git_
 	return false;
 }
 
+GIT_INLINE(bool) only_spaces_and_dots(const char *path)
+{
+	const char *c = path;
+
+	for (;; c++) {
+		if (*c == '\0')
+			return true;
+		if (*c != ' ' && *c != '.')
+			return false;
+	}
+
+	return true;
+}
+
+GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix)
+{
+	int i, saw_tilde;
+
+	if (name[0] == '.' && len >= dotgit_len &&
+	    !strncasecmp(name + 1, dotgit_name, dotgit_len)) {
+		return !only_spaces_and_dots(name + dotgit_len + 1);
+	}
+
+	/* Detect the basic NTFS shortname with the first six chars */
+	if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
+	    name[7] >= '1' && name[7] <= '4')
+		return !only_spaces_and_dots(name + 8);
+
+	/* Catch fallback names */
+	for (i = 0, saw_tilde = 0; i < 8; i++) {
+		if (name[i] == '\0') {
+			return true;
+		} else if (saw_tilde) {
+			if (name[i] < '0' || name[i] > '9')
+				return true;
+		} else if (name[i] == '~') {
+			if (name[i+1] < '1' || name[i+1]  > '9')
+				return true;
+			saw_tilde = 1;
+		} else if (i >= 6) {
+			return true;
+		} else if (name[i] < 0) {
+			return true;
+		} else if (git__tolower(name[i]) != shortname_pfix[i]) {
+			return true;
+		}
+	}
+
+	return !only_spaces_and_dots(name + i);
+}
+
 GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
 {
 	if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\')
@@ -1577,6 +1641,24 @@ GIT_INLINE(bool) verify_char(unsigned ch
 }
 
 /*
+ * Return the length of the common prefix between str and prefix, comparing them
+ * case-insensitively (must be ASCII to match).
+ */
+GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char *prefix)
+{
+	size_t count = 0;
+
+	while (len >0 && tolower(*str) == tolower(*prefix)) {
+		count++;
+		str++;
+		prefix++;
+		len--;
+	}
+
+	return count;
+}
+
+/*
  * We fundamentally don't like some paths when dealing with user-inputted
  * strings (in checkout or ref names): we don't want dot or dot-dot
  * anywhere, we want to avoid writing weird paths on Windows that can't
@@ -1589,6 +1671,7 @@ static bool verify_component(
 	git_repository *repo,
 	const char *component,
 	size_t len,
+	uint16_t mode,
 	unsigned int flags)
 {
 	if (len == 0)
@@ -1621,26 +1704,38 @@ static bool verify_component(
 			return false;
 	}
 
-	if (flags & GIT_PATH_REJECT_DOT_GIT_HFS &&
-		!verify_dotgit_hfs(component, len))
-		return false;
+	if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
+		if (!verify_dotgit_hfs(component, len))
+			return false;
+		if (S_ISLNK(mode) && git_path_is_hfs_dotgit_modules(component, len))
+			return false;
+	}
 
-	if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS &&
-		!verify_dotgit_ntfs(repo, component, len))
-		return false;
+	if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
+		if (!verify_dotgit_ntfs(repo, component, len))
+			return false;
+		if (S_ISLNK(mode) && git_path_is_ntfs_dotgit_modules(component, len))
+			return false;
+	}
 
 	/* don't bother rerunning the `.git` test if we ran the HFS or NTFS
 	 * specific tests, they would have already rejected `.git`.
 	 */
 	if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
-		(flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
-		(flags & GIT_PATH_REJECT_DOT_GIT_LITERAL) &&
-		len == 4 &&
-		component[0] == '.' &&
-		(component[1] == 'g' || component[1] == 'G') &&
-		(component[2] == 'i' || component[2] == 'I') &&
-		(component[3] == 't' || component[3] == 'T'))
-		return false;
+	    (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
+	    (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) {
+		if (len >= 4 &&
+		    component[0] == '.' &&
+		    (component[1] == 'g' || component[1] == 'G') &&
+		    (component[2] == 'i' || component[2] == 'I') &&
+		    (component[3] == 't' || component[3] == 'T')) {
+			if (len == 4)
+				return false;
+
+			if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len)
+				return false;
+		}
+	    }
 
 	return true;
 }
@@ -1677,6 +1772,7 @@ GIT_INLINE(unsigned int) dotgit_flags(
 bool git_path_isvalid(
 	git_repository *repo,
 	const char *path,
+	uint16_t mode,
 	unsigned int flags)
 {
 	const char *start, *c;
@@ -1690,14 +1786,14 @@ bool git_path_isvalid(
 			return false;
 
 		if (*c == '/') {
-			if (!verify_component(repo, start, (c - start), flags))
+			if (!verify_component(repo, start, (c - start), mode, flags))
 				return false;
 
 			start = c+1;
 		}
 	}
 
-	return verify_component(repo, start, (c - start), flags);
+	return verify_component(repo, start, (c - start), mode, flags);
 }
 
 int git_path_normalize_slashes(git_buf *out, const char *path)
@@ -1715,3 +1811,65 @@ int git_path_normalize_slashes(git_buf *
 
 	return 0;
 }
+
+static int verify_dotgit_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix)
+{
+	if (!verify_dotgit_ntfs_generic(name, len, dotgit_name, dotgit_len, shortname_pfix))
+		return false;
+
+	return verify_dotgit_hfs_generic(name, len, dotgit_name, dotgit_len);
+}
+
+int git_path_is_ntfs_dotgit_modules(const char *name, size_t len)
+{
+	return !verify_dotgit_ntfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"), "gi7eba");
+}
+
+int git_path_is_hfs_dotgit_modules(const char *name, size_t len)
+{
+	return !verify_dotgit_hfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"));
+}
+
+int git_path_is_dotgit_modules(const char *name, size_t len)
+{
+	if (git_path_is_hfs_dotgit_modules(name, len))
+		return 1;
+
+	return git_path_is_ntfs_dotgit_modules(name, len);
+}
+
+int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len)
+{
+	return !verify_dotgit_ntfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"), "gi250a");
+}
+
+int git_path_is_hfs_dotgit_ignore(const char *name, size_t len)
+{
+	return !verify_dotgit_hfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"));
+}
+
+int git_path_is_dotgit_ignore(const char *name, size_t len)
+{
+	if (git_path_is_hfs_dotgit_ignore(name, len))
+		return 1;
+
+	return git_path_is_ntfs_dotgit_ignore(name, len);
+}
+
+int git_path_is_hfs_dotgit_attributes(const char *name, size_t len)
+{
+	return !verify_dotgit_hfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"));
+}
+
+int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len)
+{
+	return !verify_dotgit_ntfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"), "gi7d29");
+}
+
+int git_path_is_dotgit_attributes(const char *name, size_t len)
+{
+	if (git_path_is_hfs_dotgit_attributes(name, len))
+		return 1;
+
+	return git_path_is_ntfs_dotgit_attributes(name, len);
+}
diff -urp libgit2-0.24.1.orig/src/path.h libgit2-0.24.1/src/path.h
--- libgit2-0.24.1.orig/src/path.h	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/src/path.h	2018-07-31 13:43:18.959179021 -0500
@@ -605,6 +605,7 @@ extern int git_path_from_url_or_path(git
 extern bool git_path_isvalid(
 	git_repository *repo,
 	const char *path,
+	uint16_t mode,
 	unsigned int flags);
 
 /**
@@ -612,4 +613,76 @@ extern bool git_path_isvalid(
  */
 int git_path_normalize_slashes(git_buf *out, const char *path);
 
+/**
+ * Check whether a path component corresponds to a .gitmodules file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitmodules file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitmodules file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_modules(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_ignore(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitignore file
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_dotgit_attributes(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitattributes file in NTFS
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len);
+
+/**
+ * Check whether a path component corresponds to a .gitattributes file in HFS+
+ *
+ * @param name the path component to check
+ * @param len the length of `name`
+ */
+extern int git_path_is_hfs_dotgit_attributes(const char *name, size_t len);
+
 #endif
diff -urp libgit2-0.24.1.orig/src/refdb_fs.c libgit2-0.24.1/src/refdb_fs.c
--- libgit2-0.24.1.orig/src/refdb_fs.c	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/src/refdb_fs.c	2018-07-31 13:52:41.418468113 -0500
@@ -717,7 +717,7 @@ static int loose_lock(git_filebuf *file,
 
 	assert(file && backend && name);
 
-	if (!git_path_isvalid(backend->repo, name, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
+	if (!git_path_isvalid(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
 		giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", name);
 		return GIT_EINVALIDSPEC;
 	}
@@ -1672,7 +1672,7 @@ static int lock_reflog(git_filebuf *file
 
 	repo = backend->repo;
 
-	if (!git_path_isvalid(backend->repo, refname, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
+	if (!git_path_isvalid(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) {
 		giterr_set(GITERR_INVALID, "Invalid reference name '%s'.", refname);
 		return GIT_EINVALIDSPEC;
 	}
diff -urp libgit2-0.24.1.orig/src/submodule.c libgit2-0.24.1/src/submodule.c
--- libgit2-0.24.1.orig/src/submodule.c	2018-07-31 11:08:37.504990323 -0500
+++ libgit2-0.24.1/src/submodule.c	2018-07-31 15:35:43.198106562 -0500
@@ -148,38 +148,64 @@ static int find_by_path(const git_config
 }
 
 /**
- * Find out the name of a submodule from its path
+ * Release the name map returned by 'load_submodule_names'.
  */
-static int name_from_path(git_buf *out, git_config *cfg, const char *path)
+static void free_submodule_names(git_strmap *names)
+{
+	git_buf *name = 0;
+	if (names == NULL)
+		return;
+	git_strmap_foreach_value(names, name, {
+		git__free(name);
+	});
+	git_strmap_free(names);
+	return;
+}
+
+/**
+ * Map submodule paths to names.
+ * TODO: for some use-cases, this might need case-folding on a
+ * case-insensitive filesystem
+ */
+static int load_submodule_names(git_strmap *out, git_repository *repo, git_config *cfg)
 {
 	const char *key = "submodule\\..*\\.path";
 	git_config_iterator *iter;
 	git_config_entry *entry;
-	int error;
+	git_buf buf = GIT_BUF_INIT;
+	int rval, isvalid;
+	int error = 0;
 
 	if ((error = git_config_iterator_glob_new(&iter, cfg, key)) < 0)
 		return error;
 
-	while ((error = git_config_next(&entry, iter)) == 0) {
+	while (git_config_next(&entry, iter) == 0) {
 		const char *fdot, *ldot;
-		/* TODO: this should maybe be strcasecmp on a case-insensitive fs */
-		if (strcmp(path, entry->value) != 0)
-			continue;
-
 		fdot = strchr(entry->name, '.');
 		ldot = strrchr(entry->name, '.');
 
-		git_buf_clear(out);
-		git_buf_put(out, fdot + 1, ldot - fdot - 1);
-		goto cleanup;
-	}
+		git_buf_clear(&buf);
+		git_buf_put(&buf, fdot + 1, ldot - fdot - 1);
+		isvalid = git_submodule_name_is_valid(repo, buf.ptr, 0);
+		if (isvalid < 0) {
+			error = isvalid;
+			goto out;
+		}
+		if (!isvalid)
+			continue;
 
-	if (error == GIT_ITEROVER) {
-		giterr_set(GITERR_SUBMODULE, "could not find a submodule name for '%s'", path);
-		error = GIT_ENOTFOUND;
+		git_strmap_insert(out, entry->value, git_buf_detach(&buf), rval);
+		if (rval < 0) {
+			giterr_set(GITERR_NOMEMORY, "Error inserting submodule into hash table");
+			free_submodule_names(out);
+			return -1;
+		}
 	}
+	if (error == GIT_ITEROVER)
+		error = 0;
 
-cleanup:
+out:
+	git_buf_free(&buf);
 	git_config_iterator_free(iter);
 	return error;
 }
@@ -284,6 +310,28 @@ int git_submodule_lookup(
 	return 0;
 }
 
+int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags)
+{
+	git_buf buf = GIT_BUF_INIT;
+	int error, isvalid;
+
+	if (flags == 0)
+		flags = GIT_PATH_REJECT_FILESYSTEM_DEFAULTS;
+
+	/* Avoid allocating a new string if we can avoid it */
+	if (strchr(name, '\\') != NULL) {
+		if ((error = git_path_normalize_slashes(&buf, name)) < 0)
+			return error;
+	} else {
+		git_buf_attach_notowned(&buf, name, strlen(name));
+	}
+
+	isvalid =  git_path_isvalid(repo, buf.ptr, 0, flags);
+	git_buf_free(&buf);
+
+	return isvalid;
+}
+
 static void submodule_free_dup(void *sm)
 {
 	git_submodule_free(sm);
@@ -326,20 +374,18 @@ static int submodules_from_index(git_str
        int error;
        git_iterator *i;
        const git_index_entry *entry;
-       git_buf name = GIT_BUF_INIT;
+	git_strmap *names = 0;
+	git_strmap_alloc(&names);
+	if ((error = load_submodule_names(names, git_index_owner(idx), cfg)))
+		goto done;
 
        if ((error = git_iterator_for_index(&i, git_index_owner(idx), idx, NULL)) < 0)
-               return error;
+               goto done;
 
        while (!(error = git_iterator_advance(&entry, i))) {
                khiter_t pos = git_strmap_lookup_index(map, entry->path);
                git_submodule *sm;
 
-	       git_buf_clear(&name);
-	       if (!name_from_path(&name, cfg, entry->path)) {
-		       git_strmap_lookup_index(map, name.ptr);
-	       }
-
                if (git_strmap_valid_index(map, pos)) {
                        sm = git_strmap_value_at(map, pos);
 
@@ -348,7 +394,17 @@ static int submodules_from_index(git_str
                        else
                                sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
                } else if (S_ISGITLINK(entry->mode)) {
-                       if (!submodule_get_or_create(&sm, git_index_owner(idx), map, name.ptr ? name.ptr : entry->path)) {
+			khiter_t name_pos;
+			const char *name;
+
+			name_pos = git_strmap_lookup_index(names, entry->path);
+			if (git_strmap_valid_index(names, name_pos)) {
+				name = git_strmap_value_at(names, name_pos);
+			} else {
+				name = entry->path;
+			}
+
+			if (!submodule_get_or_create(&sm, git_index_owner(idx), map, name)) {
                                submodule_update_from_index_entry(sm, entry);
                                git_submodule_free(sm);
                        }
@@ -358,8 +414,9 @@ static int submodules_from_index(git_str
        if (error == GIT_ITEROVER)
                error = 0;
 
-       git_buf_free(&name);
+done:
        git_iterator_free(i);
+	free_submodule_names(names);
 
        return error;
 }
@@ -369,20 +426,18 @@ static int submodules_from_head(git_strm
        int error;
        git_iterator *i;
        const git_index_entry *entry;
-       git_buf name = GIT_BUF_INIT;
+	git_strmap *names = 0;
+	git_strmap_alloc(&names);
+	if ((error = load_submodule_names(names, git_tree_owner(head), cfg)))
+		goto done;
 
        if ((error = git_iterator_for_tree(&i, head, NULL)) < 0)
-               return error;
+               goto done;
 
        while (!(error = git_iterator_advance(&entry, i))) {
                khiter_t pos = git_strmap_lookup_index(map, entry->path);
                git_submodule *sm;
 
-	       git_buf_clear(&name);
-	       if (!name_from_path(&name, cfg, entry->path)) {
-		       git_strmap_lookup_index(map, name.ptr);
-	       }
-
                if (git_strmap_valid_index(map, pos)) {
                        sm = git_strmap_value_at(map, pos);
 
@@ -391,7 +446,17 @@ static int submodules_from_head(git_strm
                        else
                                sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
                } else if (S_ISGITLINK(entry->mode)) {
-                       if (!submodule_get_or_create(&sm, git_tree_owner(head), map, name.ptr ? name.ptr : entry->path)) {
+			khiter_t name_pos;
+			const char *name;
+
+			name_pos = git_strmap_lookup_index(names, entry->path);
+			if (git_strmap_valid_index(names, name_pos)) {
+				name = git_strmap_value_at(names, name_pos);
+			} else {
+				name = entry->path;
+			}
+
+			if (!submodule_get_or_create(&sm, git_tree_owner(head), map, name)) {
                                submodule_update_from_head_data(
                                        sm, entry->mode, &entry->id);
                                git_submodule_free(sm);
@@ -402,8 +467,9 @@ static int submodules_from_head(git_strm
        if (error == GIT_ITEROVER)
                error = 0;
 
-       git_buf_free(&name);
+done:
        git_iterator_free(i);
+	free_submodule_names(names);
 
        return error;
 }
@@ -415,7 +481,7 @@ typedef struct {
 	git_repository *repo;
 } lfc_data;
 
-static int all_submodules(git_repository *repo, git_strmap *map)
+int git_submodule__map(git_repository *repo, git_strmap *map)
 {
 	int error = 0;
 	git_index *idx = NULL;
@@ -508,7 +574,7 @@ int git_submodule_foreach(
 	if ((error = git_strmap_alloc(&submodules)) < 0)
 		return error;
 
-	if ((error = all_submodules(repo, submodules)) < 0)
+	if ((error = git_submodule__map(repo, submodules)) < 0)
 		goto done;
 
 	if (!(error = git_vector_init(
@@ -1426,13 +1492,19 @@ static int submodule_update_head(git_sub
 
 int git_submodule_reload(git_submodule *sm, int force)
 {
-	int error = 0;
+	int error = 0, isvalid;
 	git_config *mods;
 
 	GIT_UNUSED(force);
 
 	assert(sm);
 
+	isvalid = git_submodule_name_is_valid(sm->repo, sm->name, 0);
+	if (isvalid <= 0) {
+		/* This should come with a warning, but we've no API for that */
+		return isvalid;
+	}
+
 	if (!git_repository_is_bare(sm->repo)) {
 		/* refresh config data */
 		mods = gitmodules_snapshot(sm->repo);
@@ -1554,7 +1626,6 @@ int git_submodule_location(unsigned int
 		location, NULL, NULL, NULL, sm, GIT_SUBMODULE_IGNORE_ALL);
 }
 
-
 /*
  * INTERNAL FUNCTIONS
  */
@@ -1765,7 +1836,7 @@ static int submodule_load_each(const git
 	git_strmap *map = data->map;
 	git_buf name = GIT_BUF_INIT;
 	git_submodule *sm;
-	int error;
+	int error, isvalid;
 
 	if (git__prefixcmp(entry->name, "submodule.") != 0)
 		return 0;
@@ -1781,6 +1852,12 @@ static int submodule_load_each(const git
 	if ((error = git_buf_set(&name, namestart, property - namestart -1)) < 0)
 		return error;
 
+	isvalid = git_submodule_name_is_valid(data->repo, name.ptr, 0);
+	if (isvalid <= 0) {
+		error = isvalid;
+		goto done;
+	}
+
 	/*
 	 * Now that we have the submodule's name, we can use that to
 	 * figure out whether it's in the map. If it's not, we create
diff -urp libgit2-0.24.1.orig/src/submodule.h libgit2-0.24.1/src/submodule.h
--- libgit2-0.24.1.orig/src/submodule.h	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/src/submodule.h	2018-07-31 13:59:42.252923908 -0500
@@ -143,4 +143,20 @@ extern int git_submodule_parse_ignore(
 extern int git_submodule_parse_update(
 	git_submodule_update_t *out, const char *value);
 
+extern int git_submodule__map(
+	git_repository *repo,
+	git_strmap *map);
+
+/**
+ * Check whether a submodule's name is valid.
+ *
+ * Check the path against the path validity rules, either the filesystem
+ * defaults (like checkout does) or whichever you want to compare against.
+ *
+ * @param repo the repository which contains the submodule
+ * @param name the name to check
+ * @param flags the `GIT_PATH` flags to use for the check (0 to use filesystem defaults)
+ */
+extern int git_submodule_name_is_valid(git_repository *repo, const char *name, int flags);
+
 #endif
diff -urp libgit2-0.24.1.orig/src/tree.c libgit2-0.24.1/src/tree.c
--- libgit2-0.24.1.orig/src/tree.c	2018-07-31 11:05:58.936049397 -0500
+++ libgit2-0.24.1/src/tree.c	2018-07-31 13:43:18.967179067 -0500
@@ -56,7 +56,7 @@ GIT_INLINE(git_filemode_t) normalize_fil
 static int valid_entry_name(git_repository *repo, const char *filename)
 {
 	return *filename != '\0' &&
-		git_path_isvalid(repo, filename,
+		git_path_isvalid(repo, filename, 0,
 		GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH);
 }
 
diff -urp libgit2-0.24.1.orig/tests/online/clone.c libgit2-0.24.1/tests/online/clone.c
--- libgit2-0.24.1.orig/tests/online/clone.c	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/tests/online/clone.c	2018-07-30 14:49:52.394321187 -0500
@@ -339,7 +339,7 @@ void test_online_clone__credentials(void
 void test_online_clone__bitbucket_style(void)
 {
 	git_cred_userpass_payload user_pass = {
-		"libgit2", "libgit2"
+		"libgit3", "libgit3"
 	};
 
 	g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
@@ -348,15 +348,45 @@ void test_online_clone__bitbucket_style(
 	cl_git_pass(git_clone(&g_repo, BB_REPO_URL, "./foo", &g_options));
 	git_repository_free(g_repo); g_repo = NULL;
 	cl_fixture_cleanup("./foo");
+}
+
+void test_online_clone__bitbucket_uses_creds_in_url(void)
+{
+	git_cred_userpass_payload user_pass = {
+		"libgit2", "wrong"
+	};
 
-	/* User and pass from URL */
-	user_pass.password = "wrong";
+	g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
+	g_options.fetch_opts.callbacks.payload = &user_pass;
+
+	/*
+	 * Correct user and pass are in the URL; the (incorrect) creds in
+	 * the `git_cred_userpass_payload` should be ignored.
+	 */
 	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_PASS, "./foo", &g_options));
 	git_repository_free(g_repo); g_repo = NULL;
 	cl_fixture_cleanup("./foo");
+}
+
+void test_online_clone__bitbucket_falls_back_to_specified_creds(void)
+{
+	git_cred_userpass_payload user_pass = {
+		"libgit2", "libgit2"
+	};
+
+	g_options.fetch_opts.callbacks.credentials = git_cred_userpass;
+	g_options.fetch_opts.callbacks.payload = &user_pass;
+
+	/*
+	 * TODO: as of March 2018, bitbucket sporadically fails with
+	 * 403s instead of replying with a 401 - but only sometimes.
+	 */
+	cl_skip();
 
-	/* Wrong password in URL, fall back to user_pass */
-	user_pass.password = "libgit2";
+	/*
+	 * Incorrect user and pass are in the URL; the (correct) creds in
+	 * the `git_cred_userpass_payload` should be used as a fallback.
+	 */
 	cl_git_pass(git_clone(&g_repo, BB_REPO_URL_WITH_WRONG_PASS, "./foo", &g_options));
 	git_repository_free(g_repo); g_repo = NULL;
 	cl_fixture_cleanup("./foo");
diff -urp libgit2-0.24.1.orig/tests/path/core.c libgit2-0.24.1/tests/path/core.c
--- libgit2-0.24.1.orig/tests/path/core.c	2016-04-11 17:18:17.000000000 -0500
+++ libgit2-0.24.1/tests/path/core.c	2018-07-31 13:43:18.967179067 -0500
@@ -54,256 +54,256 @@ void test_path_core__make_relative(void)
 
 void test_path_core__isvalid_standard(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0, 0));
 }
 
 void test_path_core__isvalid_empty_dir_component(void)
 {
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0, 0));
 
 	/* leading slash */
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0, 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0, 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0, 0));
 
 	/* trailing slash */
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0, 0));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0, 0));
 }
 
 void test_path_core__isvalid_dot_and_dotdot(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", GIT_PATH_REJECT_TRAVERSAL));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "..", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", GIT_PATH_REJECT_TRAVERSAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
 }
 
 void test_path_core__isvalid_dot_git(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", GIT_PATH_REJECT_DOT_GIT_LITERAL));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0, 0));
 }
 
 void test_path_core__isvalid_backslash(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", GIT_PATH_REJECT_BACKSLASH));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", GIT_PATH_REJECT_BACKSLASH));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", GIT_PATH_REJECT_BACKSLASH));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH));
 }
 
 void test_path_core__isvalid_trailing_dot(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", GIT_PATH_REJECT_TRAILING_DOT));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", GIT_PATH_REJECT_TRAILING_DOT));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", GIT_PATH_REJECT_TRAILING_DOT));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT));
 }
 
 void test_path_core__isvalid_trailing_space(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo   ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", GIT_PATH_REJECT_TRAILING_SPACE));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo   ", GIT_PATH_REJECT_TRAILING_SPACE));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", GIT_PATH_REJECT_TRAILING_SPACE));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, " ", GIT_PATH_REJECT_TRAILING_SPACE));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo   ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo   ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE));
 }
 
 void test_path_core__isvalid_trailing_colon(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", GIT_PATH_REJECT_TRAILING_COLON));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", GIT_PATH_REJECT_TRAILING_COLON));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ":", GIT_PATH_REJECT_TRAILING_COLON));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON));
 }
 
 void test_path_core__isvalid_dotgit_ntfs(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", GIT_PATH_REJECT_DOT_GIT_NTFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0, 0));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
 }
 
 void test_path_core__isvalid_dos_paths(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "con", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", GIT_PATH_REJECT_DOS_PATHS));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
 }
 
 void test_path_core__isvalid_dos_paths_withnum(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", GIT_PATH_REJECT_DOS_PATHS));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", GIT_PATH_REJECT_DOS_PATHS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS));
 }
 
 void test_path_core__isvalid_nt_chars(void)
 {
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", GIT_PATH_REJECT_NT_CHARS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0, 0));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0, 0));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS));
 }
 
 void test_path_core__isvalid_dotgit_with_hfs_ignorables(void)
 {
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
-
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", GIT_PATH_REJECT_DOT_GIT_HFS));
-
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", GIT_PATH_REJECT_DOT_GIT_HFS));
-	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
+	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
 }
 
 static void test_join_unrooted(
openSUSE Build Service is sponsored by