Merge branch 'rs/make-verify-path-really-verify-again'
Recent sparse-index work broke safety against attempts to add paths with trailing slashes to the index, which has been corrected. * rs/make-verify-path-really-verify-again: read-cache: let verify_path() reject trailing dir separators again read-cache: add verify_path_internal() t3905: show failure to ignore sub-repomaint
						commit
						a86ed75f32
					
				
							
								
								
									
										45
									
								
								read-cache.c
								
								
								
								
							
							
						
						
									
										45
									
								
								read-cache.c
								
								
								
								
							|  | @ -849,6 +849,19 @@ struct cache_entry *make_empty_transient_cache_entry(size_t len, | ||||||
| 	return xcalloc(1, cache_entry_size(len)); | 	return xcalloc(1, cache_entry_size(len)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | enum verify_path_result { | ||||||
|  | 	PATH_OK, | ||||||
|  | 	PATH_INVALID, | ||||||
|  | 	PATH_DIR_WITH_SEP, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static enum verify_path_result verify_path_internal(const char *, unsigned); | ||||||
|  |  | ||||||
|  | int verify_path(const char *path, unsigned mode) | ||||||
|  | { | ||||||
|  | 	return verify_path_internal(path, mode) == PATH_OK; | ||||||
|  | } | ||||||
|  |  | ||||||
| struct cache_entry *make_cache_entry(struct index_state *istate, | struct cache_entry *make_cache_entry(struct index_state *istate, | ||||||
| 				     unsigned int mode, | 				     unsigned int mode, | ||||||
| 				     const struct object_id *oid, | 				     const struct object_id *oid, | ||||||
|  | @ -859,7 +872,7 @@ struct cache_entry *make_cache_entry(struct index_state *istate, | ||||||
| 	struct cache_entry *ce, *ret; | 	struct cache_entry *ce, *ret; | ||||||
| 	int len; | 	int len; | ||||||
|  |  | ||||||
| 	if (!verify_path(path, mode)) { | 	if (verify_path_internal(path, mode) == PATH_INVALID) { | ||||||
| 		error(_("invalid path '%s'"), path); | 		error(_("invalid path '%s'"), path); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  | @ -993,60 +1006,62 @@ static int verify_dotfile(const char *rest, unsigned mode) | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| int verify_path(const char *path, unsigned mode) | static enum verify_path_result verify_path_internal(const char *path, | ||||||
|  | 						    unsigned mode) | ||||||
| { | { | ||||||
| 	char c = 0; | 	char c = 0; | ||||||
|  |  | ||||||
| 	if (has_dos_drive_prefix(path)) | 	if (has_dos_drive_prefix(path)) | ||||||
| 		return 0; | 		return PATH_INVALID; | ||||||
|  |  | ||||||
| 	if (!is_valid_path(path)) | 	if (!is_valid_path(path)) | ||||||
| 		return 0; | 		return PATH_INVALID; | ||||||
|  |  | ||||||
| 	goto inside; | 	goto inside; | ||||||
| 	for (;;) { | 	for (;;) { | ||||||
| 		if (!c) | 		if (!c) | ||||||
| 			return 1; | 			return PATH_OK; | ||||||
| 		if (is_dir_sep(c)) { | 		if (is_dir_sep(c)) { | ||||||
| inside: | inside: | ||||||
| 			if (protect_hfs) { | 			if (protect_hfs) { | ||||||
|  |  | ||||||
| 				if (is_hfs_dotgit(path)) | 				if (is_hfs_dotgit(path)) | ||||||
| 					return 0; | 					return PATH_INVALID; | ||||||
| 				if (S_ISLNK(mode)) { | 				if (S_ISLNK(mode)) { | ||||||
| 					if (is_hfs_dotgitmodules(path)) | 					if (is_hfs_dotgitmodules(path)) | ||||||
| 						return 0; | 						return PATH_INVALID; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if (protect_ntfs) { | 			if (protect_ntfs) { | ||||||
| #if defined GIT_WINDOWS_NATIVE || defined __CYGWIN__ | #if defined GIT_WINDOWS_NATIVE || defined __CYGWIN__ | ||||||
| 				if (c == '\\') | 				if (c == '\\') | ||||||
| 					return 0; | 					return PATH_INVALID; | ||||||
| #endif | #endif | ||||||
| 				if (is_ntfs_dotgit(path)) | 				if (is_ntfs_dotgit(path)) | ||||||
| 					return 0; | 					return PATH_INVALID; | ||||||
| 				if (S_ISLNK(mode)) { | 				if (S_ISLNK(mode)) { | ||||||
| 					if (is_ntfs_dotgitmodules(path)) | 					if (is_ntfs_dotgitmodules(path)) | ||||||
| 						return 0; | 						return PATH_INVALID; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			c = *path++; | 			c = *path++; | ||||||
| 			if ((c == '.' && !verify_dotfile(path, mode)) || | 			if ((c == '.' && !verify_dotfile(path, mode)) || | ||||||
| 			    is_dir_sep(c)) | 			    is_dir_sep(c)) | ||||||
| 				return 0; | 				return PATH_INVALID; | ||||||
| 			/* | 			/* | ||||||
| 			 * allow terminating directory separators for | 			 * allow terminating directory separators for | ||||||
| 			 * sparse directory entries. | 			 * sparse directory entries. | ||||||
| 			 */ | 			 */ | ||||||
| 			if (c == '\0') | 			if (c == '\0') | ||||||
| 				return S_ISDIR(mode); | 				return S_ISDIR(mode) ? PATH_DIR_WITH_SEP : | ||||||
|  | 						       PATH_INVALID; | ||||||
| 		} else if (c == '\\' && protect_ntfs) { | 		} else if (c == '\\' && protect_ntfs) { | ||||||
| 			if (is_ntfs_dotgit(path)) | 			if (is_ntfs_dotgit(path)) | ||||||
| 				return 0; | 				return PATH_INVALID; | ||||||
| 			if (S_ISLNK(mode)) { | 			if (S_ISLNK(mode)) { | ||||||
| 				if (is_ntfs_dotgitmodules(path)) | 				if (is_ntfs_dotgitmodules(path)) | ||||||
| 					return 0; | 					return PATH_INVALID; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -1349,7 +1364,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e | ||||||
|  |  | ||||||
| 	if (!ok_to_add) | 	if (!ok_to_add) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	if (!verify_path(ce->name, ce->ce_mode)) | 	if (verify_path_internal(ce->name, ce->ce_mode) == PATH_INVALID) | ||||||
| 		return error(_("invalid path '%s'"), ce->name); | 		return error(_("invalid path '%s'"), ce->name); | ||||||
|  |  | ||||||
| 	if (!skip_df_check && | 	if (!skip_df_check && | ||||||
|  |  | ||||||
|  | @ -422,4 +422,10 @@ test_expect_success 'stash show --{include,only}-untracked on stashes without un | ||||||
| 	test_must_be_empty actual | 	test_must_be_empty actual | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'stash -u ignores sub-repository' ' | ||||||
|  | 	test_when_finished "rm -rf sub-repo" && | ||||||
|  | 	git init sub-repo && | ||||||
|  | 	git stash -u | ||||||
|  | ' | ||||||
|  |  | ||||||
| test_done | test_done | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano