@@ -853,17 +853,31 @@ static void index_entry_adjust_namemask(
853853 entry -> flags |= GIT_IDXENTRY_NAMEMASK ;
854854}
855855
856+ /* When `from_workdir` is true, we will validate the paths to avoid placing
857+ * paths that are invalid for the working directory on the current filesystem
858+ * (eg, on Windows, we will disallow `GIT~1`, `AUX`, `COM1`, etc). This
859+ * function will *always* prevent `.git` and directory traversal `../` from
860+ * being added to the index.
861+ */
856862static int index_entry_create (
857863 git_index_entry * * out ,
858864 git_repository * repo ,
859- const char * path )
865+ const char * path ,
866+ bool from_workdir )
860867{
861868 size_t pathlen = strlen (path ), alloclen ;
862869 struct entry_internal * entry ;
870+ unsigned int path_valid_flags = GIT_PATH_REJECT_INDEX_DEFAULTS ;
871+
872+ /* always reject placing `.git` in the index and directory traversal.
873+ * when requested, disallow platform-specific filenames and upgrade to
874+ * the platform-specific `.git` tests (eg, `git~1`, etc).
875+ */
876+ if (from_workdir )
877+ path_valid_flags |= GIT_PATH_REJECT_WORKDIR_DEFAULTS ;
863878
864- if (!git_path_isvalid (repo , path ,
865- GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT )) {
866- giterr_set (GITERR_INDEX , "Invalid path: '%s'" , path );
879+ if (!git_path_isvalid (repo , path , path_valid_flags )) {
880+ giterr_set (GITERR_INDEX , "invalid path: '%s'" , path );
867881 return -1 ;
868882 }
869883
@@ -895,7 +909,7 @@ static int index_entry_init(
895909 "Could not initialize index entry. "
896910 "Index is not backed up by an existing repository." );
897911
898- if (index_entry_create (& entry , INDEX_OWNER (index ), rel_path ) < 0 )
912+ if (index_entry_create (& entry , INDEX_OWNER (index ), rel_path , true ) < 0 )
899913 return -1 ;
900914
901915 /* write the blob to disk and get the oid and stat info */
@@ -975,7 +989,7 @@ static int index_entry_dup(
975989 git_index * index ,
976990 const git_index_entry * src )
977991{
978- if (index_entry_create (out , INDEX_OWNER (index ), src -> path ) < 0 )
992+ if (index_entry_create (out , INDEX_OWNER (index ), src -> path , false ) < 0 )
979993 return -1 ;
980994
981995 index_entry_cpy (* out , src );
@@ -997,7 +1011,7 @@ static int index_entry_dup_nocache(
9971011 git_index * index ,
9981012 const git_index_entry * src )
9991013{
1000- if (index_entry_create (out , INDEX_OWNER (index ), src -> path ) < 0 )
1014+ if (index_entry_create (out , INDEX_OWNER (index ), src -> path , false ) < 0 )
10011015 return -1 ;
10021016
10031017 index_entry_cpy_nocache (* out , src );
@@ -1402,7 +1416,7 @@ static int add_repo_as_submodule(git_index_entry **out, git_index *index, const
14021416 struct stat st ;
14031417 int error ;
14041418
1405- if (index_entry_create (& entry , INDEX_OWNER (index ), path ) < 0 )
1419+ if (index_entry_create (& entry , INDEX_OWNER (index ), path , true ) < 0 )
14061420 return -1 ;
14071421
14081422 if ((error = git_buf_joinpath (& abspath , git_repository_workdir (repo ), path )) < 0 )
@@ -2788,7 +2802,7 @@ static int read_tree_cb(
27882802 if (git_buf_joinpath (& path , root , tentry -> filename ) < 0 )
27892803 return -1 ;
27902804
2791- if (index_entry_create (& entry , INDEX_OWNER (data -> index ), path .ptr ) < 0 )
2805+ if (index_entry_create (& entry , INDEX_OWNER (data -> index ), path .ptr , false ) < 0 )
27922806 return -1 ;
27932807
27942808 entry -> mode = tentry -> attr ;
0 commit comments