@@ -732,7 +732,7 @@ struct cache_entry *make_cache_entry(unsigned int mode,
732732 int size , len ;
733733 struct cache_entry * ce , * ret ;
734734
735- if (!verify_path (path )) {
735+ if (!verify_path (path , mode )) {
736736 error ("Invalid path '%s'" , path );
737737 return NULL ;
738738 }
@@ -796,7 +796,7 @@ int ce_same_name(const struct cache_entry *a, const struct cache_entry *b)
796796 * Also, we don't want double slashes or slashes at the
797797 * end that can make pathnames ambiguous.
798798 */
799- static int verify_dotfile (const char * rest )
799+ static int verify_dotfile (const char * rest , unsigned mode )
800800{
801801 /*
802802 * The first character was '.', but that
@@ -810,25 +810,39 @@ static int verify_dotfile(const char *rest)
810810
811811 switch (* rest ) {
812812 /*
813- * ".git" followed by NUL or slash is bad. This
814- * shares the path end test with the ".." case.
813+ * ".git" followed by NUL or slash is bad. Note that we match
814+ * case-insensitively here, even if ignore_case is not set.
815+ * This outlaws ".GIT" everywhere out of an abundance of caution,
816+ * since there's really no good reason to allow it.
817+ *
818+ * Once we've seen ".git", we can also find ".gitmodules", etc (also
819+ * case-insensitively).
815820 */
816821 case 'g' :
817822 case 'G' :
818823 if (rest [1 ] != 'i' && rest [1 ] != 'I' )
819824 break ;
820825 if (rest [2 ] != 't' && rest [2 ] != 'T' )
821826 break ;
822- rest += 2 ;
823- /* fallthrough */
827+ if (rest [3 ] == '\0' || is_dir_sep (rest [3 ]))
828+ return 0 ;
829+ if (S_ISLNK (mode )) {
830+ rest += 3 ;
831+ if ((skip_iprefix (rest , "modules" , & rest ) ||
832+ skip_iprefix (rest , "ignore" , & rest ) ||
833+ skip_iprefix (rest , "attributes" , & rest )) &&
834+ (* rest == '\0' || is_dir_sep (* rest )))
835+ return 0 ;
836+ }
837+ break ;
824838 case '.' :
825839 if (rest [1 ] == '\0' || is_dir_sep (rest [1 ]))
826840 return 0 ;
827841 }
828842 return 1 ;
829843}
830844
831- int verify_path (const char * path )
845+ int verify_path (const char * path , unsigned mode )
832846{
833847 char c ;
834848
@@ -841,12 +855,29 @@ int verify_path(const char *path)
841855 return 1 ;
842856 if (is_dir_sep (c )) {
843857inside :
844- if (protect_hfs && is_hfs_dotgit (path ))
845- return 0 ;
846- if (protect_ntfs && is_ntfs_dotgit (path ))
847- return 0 ;
858+ if (protect_hfs ) {
859+ if (is_hfs_dotgit (path ))
860+ return 0 ;
861+ if (S_ISLNK (mode )) {
862+ if (is_hfs_dotgitmodules (path ) ||
863+ is_hfs_dotgitignore (path ) ||
864+ is_hfs_dotgitattributes (path ))
865+ return 0 ;
866+ }
867+ }
868+ if (protect_ntfs ) {
869+ if (is_ntfs_dotgit (path ))
870+ return 0 ;
871+ if (S_ISLNK (mode )) {
872+ if (is_ntfs_dotgitmodules (path ) ||
873+ is_ntfs_dotgitignore (path ) ||
874+ is_ntfs_dotgitattributes (path ))
875+ return 0 ;
876+ }
877+ }
878+
848879 c = * path ++ ;
849- if ((c == '.' && !verify_dotfile (path )) ||
880+ if ((c == '.' && !verify_dotfile (path , mode )) ||
850881 is_dir_sep (c ) || c == '\0' )
851882 return 0 ;
852883 }
@@ -1163,7 +1194,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
11631194
11641195 if (!ok_to_add )
11651196 return -1 ;
1166- if (!verify_path (ce -> name ))
1197+ if (!verify_path (ce -> name , ce -> ce_mode ))
11671198 return error ("Invalid path '%s'" , ce -> name );
11681199
11691200 if (!skip_df_check &&
0 commit comments