From 95117d4744cf5a66f2bcde7991a925e9852d9b1e Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 31 Oct 2021 09:45:46 -0400 Subject: path: separate git-specific path functions from util Introduce `git_fs_path`, which operates on generic filesystem paths. `git_path` will be kept for only git-specific path functionality (for example, checking for `.git` in a path). --- fuzzers/standalone_driver.c | 2 +- src/attr.c | 8 +- src/attr_file.c | 6 +- src/attrcache.c | 8 +- src/blob.c | 4 +- src/checkout.c | 25 +- src/clone.c | 16 +- src/config.c | 2 +- src/config_file.c | 22 +- src/diff_generate.c | 4 +- src/diff_stats.c | 2 +- src/diff_tform.c | 4 +- src/filebuf.c | 14 +- src/filter.c | 4 +- src/fs_path.c | 1839 ++++++++++++++++++++++++++++++++++ src/fs_path.h | 728 ++++++++++++++ src/futils.c | 50 +- src/futils.h | 2 +- src/ignore.c | 22 +- src/index.c | 9 +- src/iterator.c | 29 +- src/mailmap.c | 6 +- src/merge.c | 2 +- src/midx.c | 8 +- src/odb.c | 4 +- src/odb_loose.c | 20 +- src/odb_pack.c | 6 +- src/pack.c | 2 +- src/patch_parse.c | 4 +- src/path.c | 1867 ++--------------------------------- src/path.h | 723 +------------- src/posix.c | 6 +- src/rebase.c | 8 +- src/refdb_fs.c | 43 +- src/refs.c | 8 +- src/repository.c | 118 +-- src/submodule.c | 37 +- src/sysdir.c | 4 +- src/transport.c | 6 +- src/transports/local.c | 6 +- src/tree.c | 11 +- src/win32/findfile.c | 2 +- src/win32/path_w32.c | 14 +- src/win32/posix_w32.c | 10 +- src/worktree.c | 48 +- tests/attr/repo.c | 2 +- tests/checkout/conflict.c | 24 +- tests/checkout/crlf.c | 18 +- tests/checkout/head.c | 24 +- tests/checkout/icase.c | 22 +- tests/checkout/index.c | 62 +- tests/checkout/nasty.c | 6 +- tests/checkout/tree.c | 192 ++-- tests/checkout/typechange.c | 34 +- tests/cherrypick/workdir.c | 18 +- tests/clar_libgit2.c | 20 +- tests/clone/nonetwork.c | 16 +- tests/config/global.c | 8 +- tests/config/read.c | 8 +- tests/config/readonly.c | 10 +- tests/config/stress.c | 6 +- tests/core/copy.c | 80 +- tests/core/dirent.c | 48 +- tests/core/env.c | 6 +- tests/core/filebuf.c | 24 +- tests/core/futils.c | 6 +- tests/core/iconv.c | 20 +- tests/core/mkdir.c | 108 +- tests/core/path.c | 98 +- tests/core/posix.c | 12 +- tests/core/rmdir.c | 26 +- tests/core/stat.c | 2 +- tests/diff/drivers.c | 2 +- tests/diff/workdir.c | 10 +- tests/fetchhead/nonetwork.c | 8 +- tests/ignore/path.c | 4 +- tests/index/crlf.c | 16 +- tests/index/tests.c | 4 +- tests/iterator/index.c | 2 +- tests/iterator/workdir.c | 2 +- tests/merge/merge_helpers.c | 2 +- tests/merge/workdir/setup.c | 178 ++-- tests/merge/workdir/simple.c | 2 +- tests/object/blob/write.c | 4 +- tests/object/raw/write.c | 4 +- tests/odb/alternates.c | 2 +- tests/odb/emptyobjects.c | 2 +- tests/online/clone.c | 6 +- tests/online/customcert.c | 4 +- tests/pack/indexer.c | 2 +- tests/pack/packbuilder.c | 4 +- tests/path/core.c | 384 +++---- tests/path/dotgit.c | 86 ++ tests/refs/branches/create.c | 2 +- tests/refs/branches/delete.c | 8 +- tests/refs/delete.c | 4 +- tests/refs/pack.c | 4 +- tests/refs/ref_helpers.c | 2 +- tests/refs/reflog/reflog.c | 18 +- tests/refs/rename.c | 12 +- tests/refs/revparse.c | 4 +- tests/repo/config.c | 22 +- tests/repo/discover.c | 6 +- tests/repo/env.c | 10 +- tests/repo/init.c | 26 +- tests/repo/open.c | 10 +- tests/repo/setters.c | 2 +- tests/repo/template.c | 6 +- tests/reset/hard.c | 12 +- tests/revert/workdir.c | 10 +- tests/stash/drop.c | 14 +- tests/stash/save.c | 20 +- tests/status/submodules.c | 12 +- tests/status/worktree.c | 10 +- tests/submodule/add.c | 16 +- tests/submodule/init.c | 6 +- tests/submodule/open.c | 10 +- tests/submodule/repository_init.c | 8 +- tests/submodule/submodule_helpers.c | 2 +- tests/worktree/merge.c | 2 +- tests/worktree/refs.c | 4 +- tests/worktree/submodule.c | 2 +- tests/worktree/worktree.c | 14 +- 123 files changed, 3894 insertions(+), 3775 deletions(-) create mode 100644 src/fs_path.c create mode 100644 src/fs_path.h diff --git a/fuzzers/standalone_driver.c b/fuzzers/standalone_driver.c index 88c8cfbda..c29102e65 100644 --- a/fuzzers/standalone_driver.c +++ b/fuzzers/standalone_driver.c @@ -52,7 +52,7 @@ int main(int argc, char **argv) fprintf(stderr, "Running %s against %s\n", argv[0], argv[1]); LLVMFuzzerInitialize(&argc, &argv); - if (git_path_dirload(&corpus_files, argv[1], 0, 0x0) < 0) { + if (git_fs_path_dirload(&corpus_files, argv[1], 0, 0x0) < 0) { fprintf(stderr, "Failed to scan corpus directory '%s': %s\n", argv[1], git_error_last()->message); error = -1; diff --git a/src/attr.c b/src/attr.c index 5849e701f..409c30b01 100644 --- a/src/attr.c +++ b/src/attr.c @@ -629,7 +629,7 @@ static int collect_attr_files( const char *workdir = git_repository_workdir(repo); attr_walk_up_info info = { NULL }; - GIT_ASSERT(!git_path_is_absolute(path)); + GIT_ASSERT(!git_fs_path_is_absolute(path)); if ((error = attr_setup(repo, attr_session, opts)) < 0) return error; @@ -637,10 +637,10 @@ static int collect_attr_files( /* Resolve path in a non-bare repo */ if (workdir != NULL) { if (!(error = git_repository_workdir_path(&dir, repo, path))) - error = git_path_find_dir(&dir); + error = git_fs_path_find_dir(&dir); } else { - error = git_path_dirname_r(&dir, path); + error = git_fs_path_dirname_r(&dir, path); } if (error < 0) @@ -670,7 +670,7 @@ static int collect_attr_files( if (!strcmp(dir.ptr, ".")) error = push_one_attr(&info, ""); else - error = git_path_walk_up(&dir, workdir, push_one_attr, &info); + error = git_fs_path_walk_up(&dir, workdir, push_one_attr, &info); if (error < 0) goto cleanup; diff --git a/src/attr_file.c b/src/attr_file.c index 09f0ce1b8..0eb881a9b 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -345,7 +345,7 @@ int git_attr_file__parse_buffer( int error = 0; /* If subdir file path, convert context for file paths */ - if (attrs->entry && git_path_root(attrs->entry->path) < 0 && + if (attrs->entry && git_fs_path_root(attrs->entry->path) < 0 && !git__suffixcmp(attrs->entry->path, "/" GIT_ATTR_FILE)) context = attrs->entry->path; @@ -560,7 +560,7 @@ int git_attr_path__init( /* build full path as best we can */ git_str_init(&info->full, 0); - if (git_path_join_unrooted(&info->full, path, base, &root) < 0) + if (git_fs_path_join_unrooted(&info->full, path, base, &root) < 0) return -1; info->path = info->full.ptr + root; @@ -596,7 +596,7 @@ int git_attr_path__init( case GIT_DIR_FLAG_UNKNOWN: default: - info->is_dir = (int)git_path_isdir(info->full.ptr); + info->is_dir = (int)git_fs_path_isdir(info->full.ptr); break; } diff --git a/src/attrcache.c b/src/attrcache.c index 98d73cbc3..15c7fab48 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -47,7 +47,7 @@ int git_attr_cache__alloc_file_entry( size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1; git_attr_file_entry *ce; - if (base != NULL && git_path_root(path) < 0) { + if (base != NULL && git_fs_path_root(path) < 0) { baselen = strlen(base); cachesize += baselen; @@ -66,7 +66,7 @@ int git_attr_cache__alloc_file_entry( } memcpy(&ce->fullpath[baselen], path, pathlen); - if (git_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) + if (git_fs_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) return -1; ce->path = &ce->fullpath[baselen]; @@ -169,11 +169,11 @@ static int attr_cache_lookup( git_attr_file *file = NULL; /* join base and path as needed */ - if (source->base != NULL && git_path_root(source->filename) < 0) { + if (source->base != NULL && git_fs_path_root(source->filename) < 0) { git_str *p = attr_session ? &attr_session->tmp : &path; if (git_str_joinpath(p, source->base, source->filename) < 0 || - git_path_validate_workdir_buf(repo, p) < 0) + git_fs_path_validate_workdir_buf(repo, p) < 0) return -1; filename = p->ptr; diff --git a/src/blob.c b/src/blob.c index 6f57d09e4..65841ab03 100644 --- a/src/blob.c +++ b/src/blob.c @@ -205,7 +205,7 @@ int git_blob__create_from_paths( content_path = path.ptr; } - if ((error = git_path_lstat(content_path, &st)) < 0 || + if ((error = git_fs_path_lstat(content_path, &st)) < 0 || (error = git_repository_odb(&odb, repo)) < 0) goto done; @@ -280,7 +280,7 @@ int git_blob_create_from_disk( git_str full_path = GIT_STR_INIT; const char *workdir, *hintpath = NULL; - if ((error = git_path_prettify(&full_path, path, NULL)) < 0) { + if ((error = git_fs_path_prettify(&full_path, path, NULL)) < 0) { git_str_dispose(&full_path); return error; } diff --git a/src/checkout.c b/src/checkout.c index b31918fc8..96ba4da38 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -27,10 +27,11 @@ #include "diff_generate.h" #include "pathspec.h" #include "diff_xdiff.h" -#include "path.h" +#include "fs_path.h" #include "attr.h" #include "pool.h" #include "strmap.h" +#include "path.h" /* See docs/checkout-internals.md for more information */ @@ -328,7 +329,7 @@ static int checkout_target_fullpath( if (path && git_str_puts(&data->target_path, path) < 0) return -1; - if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + if (git_fs_path_validate_workdir_buf(data->repo, &data->target_path) < 0) return -1; *out = &data->target_path; @@ -347,7 +348,7 @@ static bool wd_item_is_removable( if (checkout_target_fullpath(&full, data, wd->path) < 0) return false; - return !full || !git_path_contains(full, DOT_GIT); + return !full || !git_fs_path_contains(full, DOT_GIT); } static int checkout_queue_remove(checkout_data *data, const char *path) @@ -481,7 +482,7 @@ static bool checkout_is_empty_dir(checkout_data *data, const char *path) if (checkout_target_fullpath(&fullpath, data, path) < 0) return false; - return git_path_is_empty_dir(fullpath->ptr); + return git_fs_path_is_empty_dir(fullpath->ptr); } static int checkout_action_with_wd( @@ -1201,12 +1202,12 @@ static int checkout_conflicts_mark_directoryfile( goto done; } - prefixed = git_path_equal_or_prefixed(path, entry->path, NULL); + prefixed = git_fs_path_equal_or_prefixed(path, entry->path, NULL); - if (prefixed == GIT_PATH_EQUAL) + if (prefixed == GIT_FS_PATH_EQUAL) continue; - if (prefixed == GIT_PATH_PREFIX) + if (prefixed == GIT_FS_PATH_PREFIX) conflict->directoryfile = 1; break; @@ -1949,7 +1950,7 @@ static int checkout_path_suffixed(git_str *path, const char *suffix) path_len = git_str_len(path); - while (git_path_exists(git_str_cstr(path)) && i < INT_MAX) { + while (git_fs_path_exists(git_str_cstr(path)) && i < INT_MAX) { git_str_truncate(path, path_len); if ((error = git_str_putc(path, '_')) < 0 || @@ -2034,7 +2035,7 @@ static int checkout_merge_path( int error = 0; if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 || - (error = git_path_validate_workdir_buf(data->repo, out)) < 0) + (error = git_fs_path_validate_workdir_buf(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ @@ -2337,10 +2338,10 @@ static int validate_target_directory(checkout_data *data) { int error; - if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + if ((error = git_fs_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) return error; - if (git_path_isdir(data->opts.target_directory)) + if (git_fs_path_isdir(data->opts.target_directory)) return 0; error = checkout_mkdir(data, data->opts.target_directory, NULL, @@ -2507,7 +2508,7 @@ static int checkout_data_init( (error = git_vector_init(&data->remove_conflicts, 0, NULL)) < 0 || (error = git_vector_init(&data->update_conflicts, 0, NULL)) < 0 || (error = git_str_puts(&data->target_path, data->opts.target_directory)) < 0 || - (error = git_path_to_dir(&data->target_path)) < 0 || + (error = git_fs_path_to_dir(&data->target_path)) < 0 || (error = git_strmap_new(&data->mkdir_map)) < 0) goto cleanup; diff --git a/src/clone.c b/src/clone.c index cf4cc3c7f..1843875f8 100644 --- a/src/clone.c +++ b/src/clone.c @@ -19,7 +19,7 @@ #include "remote.h" #include "futils.h" #include "refs.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "odb.h" @@ -333,7 +333,7 @@ static int create_and_configure_origin( void *payload = options->remote_cb_payload; /* If the path exists and is a dir, the url should be the absolute path */ - if (git_path_root(url) < 0 && git_path_exists(url) && git_path_isdir(url)) { + if (git_fs_path_root(url) < 0 && git_fs_path_exists(url) && git_fs_path_isdir(url)) { if (p_realpath(url, buf) == NULL) return -1; @@ -433,8 +433,8 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc if (local == GIT_CLONE_NO_LOCAL) return 0; - if ((is_url = git_path_is_local_file_url(url_or_path)) != 0) { - if (git_path_fromurl(&fromurl, url_or_path) < 0) { + if ((is_url = git_fs_path_is_local_file_url(url_or_path)) != 0) { + if (git_fs_path_fromurl(&fromurl, url_or_path) < 0) { is_local = -1; goto done; } @@ -443,7 +443,7 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc } is_local = (!is_url || local != GIT_CLONE_LOCAL_AUTO) && - git_path_isdir(path); + git_fs_path_isdir(path); done: git_str_dispose(&fromurl); @@ -474,14 +474,14 @@ static int git__clone( GIT_ERROR_CHECK_VERSION(&options, GIT_CLONE_OPTIONS_VERSION, "git_clone_options"); /* Only clone to a new directory or an empty directory */ - if (git_path_exists(local_path) && !use_existing && !git_path_is_empty_dir(local_path)) { + if (git_fs_path_exists(local_path) && !use_existing && !git_fs_path_is_empty_dir(local_path)) { git_error_set(GIT_ERROR_INVALID, "'%s' exists and is not an empty directory", local_path); return GIT_EEXISTS; } /* Only remove the root directory on failure if we create it */ - if (git_path_exists(local_path)) + if (git_fs_path_exists(local_path)) rmdir_flags |= GIT_RMDIR_SKIP_ROOT; if (options.repository_cb) @@ -602,7 +602,7 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_ * repo, if it's not rooted, the path should be relative to * the repository's worktree/gitdir. */ - if ((error = git_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0) + if ((error = git_fs_path_from_url_or_path(&src_path, git_remote_url(remote))) < 0) return error; /* Copy .git/objects/ from the source to the target */ diff --git a/src/config.c b/src/config.c index 9033a92c5..88da34c5e 100644 --- a/src/config.c +++ b/src/config.c @@ -1177,7 +1177,7 @@ int git_config__find_programdata(git_str *path) if (ret != GIT_OK) return ret; - return git_path_validate_system_file_ownership(path->ptr); + return git_fs_path_validate_system_file_ownership(path->ptr); } int git_config__global_location(git_str *buf) diff --git a/src/config_file.c b/src/config_file.c index 9c3d2ceb8..11b444094 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -108,7 +108,7 @@ static int config_file_open(git_config_backend *cfg, git_config_level_t level, c if ((res = git_config_entries_new(&b->entries)) < 0) return res; - if (!git_path_exists(b->file.path)) + if (!git_fs_path_exists(b->file.path)) return 0; /* @@ -529,7 +529,7 @@ static int included_path(git_str *out, const char *dir, const char *path) if (path[0] == '~' && path[1] == '/') return git_sysdir_expand_global_file(out, &path[1]); - return git_path_join_unrooted(out, path, dir, NULL); + return git_fs_path_join_unrooted(out, path, dir, NULL); } /* Escape the values to write them to the file */ @@ -574,7 +574,7 @@ static int parse_include(config_file_parse_data *parse_data, const char *file) if (!file) return 0; - if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0) + if ((result = git_fs_path_dirname_r(&path, parse_data->file->path)) < 0) return result; dir = git_str_detach(&path); @@ -611,17 +611,17 @@ static int do_match_gitdir( git_str pattern = GIT_STR_INIT, gitdir = GIT_STR_INIT; int error; - if (condition[0] == '.' && git_path_is_dirsep(condition[1])) { - git_path_dirname_r(&pattern, cfg_file); + if (condition[0] == '.' && git_fs_path_is_dirsep(condition[1])) { + git_fs_path_dirname_r(&pattern, cfg_file); git_str_joinpath(&pattern, pattern.ptr, condition + 2); - } else if (condition[0] == '~' && git_path_is_dirsep(condition[1])) + } else if (condition[0] == '~' && git_fs_path_is_dirsep(condition[1])) git_sysdir_expand_global_file(&pattern, condition + 1); - else if (!git_path_is_absolute(condition)) + else if (!git_fs_path_is_absolute(condition)) git_str_joinpath(&pattern, "**", condition); else git_str_sets(&pattern, condition); - if (git_path_is_dirsep(condition[strlen(condition) - 1])) + if (git_fs_path_is_dirsep(condition[strlen(condition) - 1])) git_str_puts(&pattern, "**"); if (git_str_oom(&pattern)) { @@ -632,7 +632,7 @@ static int do_match_gitdir( if ((error = git_repository__item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0) goto out; - if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1])) + if (git_fs_path_is_dirsep(gitdir.ptr[gitdir.size - 1])) git_str_truncate(&gitdir, gitdir.size - 1); *matches = wildmatch(pattern.ptr, gitdir.ptr, @@ -699,7 +699,7 @@ static int conditional_match_onbranch( */ if ((error = git_str_sets(&buf, condition)) < 0) goto out; - if (git_path_is_dirsep(condition[strlen(condition) - 1]) && + if (git_fs_path_is_dirsep(condition[strlen(condition) - 1]) && (error = git_str_puts(&buf, "**")) < 0) goto out; @@ -861,7 +861,7 @@ static int config_file_read( int error; if (p_stat(file->path, &st) < 0) { - error = git_path_set_error(errno, file->path, "stat"); + error = git_fs_path_set_error(errno, file->path, "stat"); goto out; } diff --git a/src/diff_generate.c b/src/diff_generate.c index dc690aa9b..dca16d51a 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -605,7 +605,7 @@ int git_diff__oid_for_entry( diff->base.perf.stat_calls++; if (p_stat(full_path.ptr, &st) < 0) { - error = git_path_set_error(errno, entry.path, "stat"); + error = git_fs_path_set_error(errno, entry.path, "stat"); git_str_dispose(&full_path); return error; } @@ -1026,7 +1026,7 @@ static int handle_unmatched_new_item( git_str *full = NULL; if (git_iterator_current_workdir_path(&full, info->new_iter) < 0) return -1; - if (full && git_path_contains(full, DOT_GIT)) { + if (full && git_fs_path_contains(full, DOT_GIT)) { /* TODO: warning if not a valid git repository */ recurse_into_dir = false; } diff --git a/src/diff_stats.c b/src/diff_stats.c index 228f6f892..259939844 100644 --- a/src/diff_stats.c +++ b/src/diff_stats.c @@ -70,7 +70,7 @@ static int diff_file_stats_full_to_buf( padding = stats->max_name - strlen(old_path) - strlen(new_path); - if ((common_dirlen = git_path_common_dirlen(old_path, new_path)) && + if ((common_dirlen = git_fs_path_common_dirlen(old_path, new_path)) && common_dirlen <= INT_MAX) { error = git_str_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}", (int) common_dirlen, old_path, diff --git a/src/diff_tform.c b/src/diff_tform.c index be55de6c3..d14134071 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -13,7 +13,7 @@ #include "diff.h" #include "diff_generate.h" -#include "path.h" +#include "fs_path.h" #include "futils.h" #include "config.h" @@ -481,7 +481,7 @@ static int similarity_sig( return error; /* if path is not a regular file, just skip this item */ - if (!git_path_isfile(info->data.ptr)) + if (!git_fs_path_isfile(info->data.ptr)) return 0; /* TODO: apply wd-to-odb filters to file data if necessary */ diff --git a/src/filebuf.c b/src/filebuf.c index 10f8c5813..f0bd0004f 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -43,7 +43,7 @@ static int verify_last_error(git_filebuf *file) static int lock_file(git_filebuf *file, int flags, mode_t mode) { - if (git_path_exists(file->path_lock) == true) { + if (git_fs_path_exists(file->path_lock) == true) { git_error_clear(); /* actual OS error code just confuses */ git_error_set(GIT_ERROR_OS, "failed to lock file '%s' for writing", file->path_lock); @@ -63,7 +63,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode) file->fd_is_open = true; - if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) { + if ((flags & GIT_FILEBUF_APPEND) && git_fs_path_exists(file->path_original) == true) { git_file source; char buffer[FILEIO_BUFSIZE]; ssize_t read_bytes; @@ -103,7 +103,7 @@ void git_filebuf_cleanup(git_filebuf *file) if (file->fd_is_open && file->fd >= 0) p_close(file->fd); - if (file->created_lock && !file->did_rename && file->path_lock && git_path_exists(file->path_lock)) + if (file->created_lock && !file->did_rename && file->path_lock && git_fs_path_exists(file->path_lock)) p_unlink(file->path_lock); if (file->compute_digest) { @@ -241,20 +241,20 @@ static int resolve_symlink(git_str *out, const char *path) target.ptr[ret] = '\0'; target.size = ret; - root = git_path_root(target.ptr); + root = git_fs_path_root(target.ptr); if (root >= 0) { if ((error = git_str_sets(&curpath, target.ptr)) < 0) goto cleanup; } else { git_str dir = GIT_STR_INIT; - if ((error = git_path_dirname_r(&dir, curpath.ptr)) < 0) + if ((error = git_fs_path_dirname_r(&dir, curpath.ptr)) < 0) goto cleanup; git_str_swap(&curpath, &dir); git_str_dispose(&dir); - if ((error = git_path_apply_relative(&curpath, target.ptr)) < 0) + if ((error = git_fs_path_apply_relative(&curpath, target.ptr)) < 0) goto cleanup; } } @@ -366,7 +366,7 @@ int git_filebuf_open_withsize(git_filebuf *file, const char *path, int flags, mo memcpy(file->path_lock, file->path_original, path_len); memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH); - if (git_path_isdir(file->path_original)) { + if (git_fs_path_isdir(file->path_original)) { git_error_set(GIT_ERROR_FILESYSTEM, "path '%s' is a directory", file->path_original); error = GIT_EDIRECTORY; goto cleanup; diff --git a/src/filter.c b/src/filter.c index 417d9cb8b..950296033 100644 --- a/src/filter.c +++ b/src/filter.c @@ -1094,8 +1094,8 @@ int git_filter_list_stream_file( if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || - (error = git_path_join_unrooted(&abspath, path, base, NULL)) < 0 || - (error = git_path_validate_workdir_buf(repo, &abspath)) < 0) + (error = git_fs_path_join_unrooted(&abspath, path, base, NULL)) < 0 || + (error = git_fs_path_validate_workdir_buf(repo, &abspath)) < 0) goto done; initialized = 1; diff --git a/src/fs_path.c b/src/fs_path.c new file mode 100644 index 000000000..e180d5866 --- /dev/null +++ b/src/fs_path.c @@ -0,0 +1,1839 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "fs_path.h" + +#include "posix.h" +#include "repository.h" +#ifdef GIT_WIN32 +#include "win32/posix.h" +#include "win32/w32_buffer.h" +#include "win32/w32_util.h" +#include "win32/version.h" +#include +#else +#include +#endif +#include +#include + +static int dos_drive_prefix_length(const char *path) +{ + int i; + + /* + * Does it start with an ASCII letter (i.e. highest bit not set), + * followed by a colon? + */ + if (!(0x80 & (unsigned char)*path)) + return *path && path[1] == ':' ? 2 : 0; + + /* + * While drive letters must be letters of the English alphabet, it is + * possible to assign virtually _any_ Unicode character via `subst` as + * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff + * like this: + * + * subst ֍: %USERPROFILE%\Desktop + */ + for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++) + ; /* skip first UTF-8 character */ + return path[i] == ':' ? i + 1 : 0; +} + +#ifdef GIT_WIN32 +static bool looks_like_network_computer_name(const char *path, int pos) +{ + if (pos < 3) + return false; + + if (path[0] != '/' || path[1] != '/') + return false; + + while (pos-- > 2) { + if (path[pos] == '/') + return false; + } + + return true; +} +#endif + +/* + * Based on the Android implementation, BSD licensed. + * http://android.git.kernel.org/ + * + * Copyright (C) 2008 The Android Open Source Project + * 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. + * + * 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. + */ +int git_fs_path_basename_r(git_str *buffer, const char *path) +{ + const char *endp, *startp; + int len, result; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + startp = "."; + len = 1; + goto Exit; + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + startp = "/"; + len = 1; + goto Exit; + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + /* Cast is safe because max path < max int */ + len = (int)(endp - startp + 1); + +Exit: + result = len; + + if (buffer != NULL && git_str_set(buffer, startp, len) < 0) + return -1; + + return result; +} + +/* + * Determine if the path is a Windows prefix and, if so, returns + * its actual lentgh. If it is not a prefix, returns -1. + */ +static int win32_prefix_length(const char *path, int len) +{ +#ifndef GIT_WIN32 + GIT_UNUSED(path); + GIT_UNUSED(len); +#else + /* + * Mimic unix behavior where '/.git' returns '/': 'C:/.git' + * will return 'C:/' here + */ + if (dos_drive_prefix_length(path) == len) + return len; + + /* + * Similarly checks if we're dealing with a network computer name + * '//computername/.git' will return '//computername/' + */ + if (looks_like_network_computer_name(path, len)) + return len; +#endif + + return -1; +} + +/* + * Based on the Android implementation, BSD licensed. + * Check http://android.git.kernel.org/ + */ +int git_fs_path_dirname_r(git_str *buffer, const char *path) +{ + const char *endp; + int is_prefix = 0, len; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + path = "."; + len = 1; + goto Exit; + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + if (endp - path + 1 > INT_MAX) { + git_error_set(GIT_ERROR_INVALID, "path too long"); + len = -1; + goto Exit; + } + + if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { + is_prefix = 1; + goto Exit; + } + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + path = (*endp == '/') ? "/" : "."; + len = 1; + goto Exit; + } + + do { + endp--; + } while (endp > path && *endp == '/'); + + if (endp - path + 1 > INT_MAX) { + git_error_set(GIT_ERROR_INVALID, "path too long"); + len = -1; + goto Exit; + } + + if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { + is_prefix = 1; + goto Exit; + } + + /* Cast is safe because max path < max int */ + len = (int)(endp - path + 1); + +Exit: + if (buffer) { + if (git_str_set(buffer, path, len) < 0) + return -1; + if (is_prefix && git_str_putc(buffer, '/') < 0) + return -1; + } + + return len; +} + + +char *git_fs_path_dirname(const char *path) +{ + git_str buf = GIT_STR_INIT; + char *dirname; + + git_fs_path_dirname_r(&buf, path); + dirname = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ + + return dirname; +} + +char *git_fs_path_basename(const char *path) +{ + git_str buf = GIT_STR_INIT; + char *basename; + + git_fs_path_basename_r(&buf, path); + basename = git_str_detach(&buf); + git_str_dispose(&buf); /* avoid memleak if error occurs */ + + return basename; +} + +size_t git_fs_path_basename_offset(git_str *buffer) +{ + ssize_t slash; + + if (!buffer || buffer->size <= 0) + return 0; + + slash = git_str_rfind_next(buffer, '/'); + + if (slash >= 0 && buffer->ptr[slash] == '/') + return (size_t)(slash + 1); + + return 0; +} + +int git_fs_path_root(const char *path) +{ + int offset = 0, prefix_len; + + /* Does the root of the path look like a windows drive ? */ + if ((prefix_len = dos_drive_prefix_length(path))) + offset += prefix_len; + +#ifdef GIT_WIN32 + /* Are we dealing with a windows network path? */ + else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') || + (path[0] == '\\' && path[1] == '\\' && path[2] != '\\')) + { + offset += 2; + + /* Skip the computer name segment */ + while (path[offset] && path[offset] != '/' && path[offset] != '\\') + offset++; + } + + if (path[offset] == '\\') + return offset; +#endif + + if (path[offset] == '/') + return offset; + + return -1; /* Not a real error - signals that path is not rooted */ +} + +static void path_trim_slashes(git_str *path) +{ + int ceiling = git_fs_path_root(path->ptr) + 1; + + if (ceiling < 0) + return; + + while (path->size > (size_t)ceiling) { + if (path->ptr[path->size-1] != '/') + break; + + path->ptr[path->size-1] = '\0'; + path->size--; + } +} + +int git_fs_path_join_unrooted( + git_str *path_out, const char *path, const char *base, ssize_t *root_at) +{ + ssize_t root; + + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); + + root = (ssize_t)git_fs_path_root(path); + + if (base != NULL && root < 0) { + if (git_str_joinpath(path_out, base, path) < 0) + return -1; + + root = (ssize_t)strlen(base); + } else { + if (git_str_sets(path_out, path) < 0) + return -1; + + if (root < 0) + root = 0; + else if (base) + git_fs_path_equal_or_prefixed(base, path, &root); + } + + if (root_at) + *root_at = root; + + return 0; +} + +void git_fs_path_squash_slashes(git_str *path) +{ + char *p, *q; + + if (path->size == 0) + return; + + for (p = path->ptr, q = path->ptr; *q; p++, q++) { + *p = *q; + + while (*q == '/' && *(q+1) == '/') { + path->size--; + q++; + } + } + + *p = '\0'; +} + +int git_fs_path_prettify(git_str *path_out, const char *path, const char *base) +{ + char buf[GIT_PATH_MAX]; + + GIT_ASSERT_ARG(path_out); + GIT_ASSERT_ARG(path); + + /* construct path if needed */ + if (base != NULL && git_fs_path_root(path) < 0) { + if (git_str_joinpath(path_out, base, path) < 0) + return -1; + path = path_out->ptr; + } + + if (p_realpath(path, buf) == NULL) { + /* git_error_set resets the errno when dealing with a GIT_ERROR_OS kind of error */ + int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1; + git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path); + + git_str_clear(path_out); + + return error; + } + + return git_str_sets(path_out, buf); +} + +int git_fs_path_prettify_dir(git_str *path_out, const char *path, const char *base) +{ + int error = git_fs_path_prettify(path_out, path, base); + return (error < 0) ? error : git_fs_path_to_dir(path_out); +} + +int git_fs_path_to_dir(git_str *path) +{ + if (path->asize > 0 && + git_str_len(path) > 0 && + path->ptr[git_str_len(path) - 1] != '/') + git_str_putc(path, '/'); + + return git_str_oom(path) ? -1 : 0; +} + +void git_fs_path_string_to_dir(char *path, size_t size) +{ + size_t end = strlen(path); + + if (end && path[end - 1] != '/' && end < size) { + path[end] = '/'; + path[end + 1] = '\0'; + } +} + +int git__percent_decode(git_str *decoded_out, const char *input) +{ + int len, hi, lo, i; + + GIT_ASSERT_ARG(decoded_out); + GIT_ASSERT_ARG(input); + + len = (int)strlen(input); + git_str_clear(decoded_out); + + for(i = 0; i < len; i++) + { + char c = input[i]; + + if (c != '%') + goto append; + + if (i >= len - 2) + goto append; + + hi = git__fromhex(input[i + 1]); + lo = git__fromhex(input[i + 2]); + + if (hi < 0 || lo < 0) + goto append; + + c = (char)(hi << 4 | lo); + i += 2; + +append: + if (git_str_putc(decoded_out, c) < 0) + return -1; + } + + return 0; +} + +static int error_invalid_local_file_uri(const char *uri) +{ + git_error_set(GIT_ERROR_CONFIG, "'%s' is not a valid local file URI", uri); + return -1; +} + +static int local_file_url_prefixlen(const char *file_url) +{ + int len = -1; + + if (git__prefixcmp(file_url, "file://") == 0) { + if (file_url[7] == '/') + len = 8; + else if (git__prefixcmp(file_url + 7, "localhost/") == 0) + len = 17; + } + + return len; +} + +bool git_fs_path_is_local_file_url(const char *file_url) +{ + return (local_file_url_prefixlen(file_url) > 0); +} + +int git_fs_path_fromurl(git_str *local_path_out, const char *file_url) +{ + int offset; + + GIT_ASSERT_ARG(local_path_out); + GIT_ASSERT_ARG(file_url); + + if ((offset = local_file_url_prefixlen(file_url)) < 0 || + file_url[offset] == '\0' || file_url[offset] == '/') + return error_invalid_local_file_uri(file_url); + +#ifndef GIT_WIN32 + offset--; /* A *nix absolute path starts with a forward slash */ +#endif + + git_str_clear(local_path_out); + return git__percent_decode(local_path_out, file_url + offset); +} + +int git_fs_path_walk_up( + git_str *path, + const char *ceiling, + int (*cb)(void *data, const char *), + void *data) +{ + int error = 0; + git_str iter; + ssize_t stop = 0, scan; + char oldc = '\0'; + + GIT_ASSERT_ARG(path); + GIT_ASSERT_ARG(cb); + + if (ceiling != NULL) { + if (git__prefixcmp(path->ptr, ceiling) == 0) + stop = (ssize_t)strlen(ceiling); + else + stop = git_str_len(path); + } + scan = git_str_len(path); + + /* empty path: yield only once */ + if (!scan) { + error = cb(data, ""); + if (error) + git_error_set_after_callback(error); + return error; + } + + iter.ptr = path->ptr; + iter.size = git_str_len(path); + iter.asize = path->asize; + + while (scan >= stop) { + error = cb(data, iter.ptr); + iter.ptr[scan] = oldc; + + if (error) { + git_error_set_after_callback(error); + break; + } + + scan = git_str_rfind_next(&iter, '/'); + if (scan >= 0) { + scan++; + oldc = iter.ptr[scan]; + iter.size = scan; + iter.ptr[scan] = '\0'; + } + } + + if (scan >= 0) + iter.ptr[scan] = oldc; + + /* relative path: yield for the last component */ + if (!error && stop == 0 && iter.ptr[0] != '/') { + error = cb(data, ""); + if (error) + git_error_set_after_callback(error); + } + + return error; +} + +bool git_fs_path_exists(const char *path) +{ + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + return p_access(path, F_OK) == 0; +} + +bool git_fs_path_isdir(const char *path) +{ + struct stat st; + if (p_stat(path, &st) < 0) + return false; + + return S_ISDIR(st.st_mode) != 0; +} + +bool git_fs_path_isfile(const char *path) +{ + struct stat st; + + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + if (p_stat(path, &st) < 0) + return false; + + return S_ISREG(st.st_mode) != 0; +} + +bool git_fs_path_islink(const char *path) +{ + struct stat st; + + GIT_ASSERT_ARG_WITH_RETVAL(path, false); + if (p_lstat(path, &st) < 0) + return false; + + return S_ISLNK(st.st_mode) != 0; +} + +#ifdef GIT_WIN32 + +bool git_fs_path_is_empty_dir(const char *path) +{ + git_win32_path filter_w; + bool empty = false; + + if (git_win32__findfirstfile_filter(filter_w, path)) { + WIN32_FIND_DATAW findData; + HANDLE hFind = FindFirstFileW(filter_w, &findData); + + /* FindFirstFile will fail if there are no children to the given + * path, which can happen if the given path is a file (and obviously + * has no children) or if the given path is an empty mount point. + * (Most directories have at least directory entries '.' and '..', + * but ridiculously another volume mounted in another drive letter's + * path space do not, and thus have nothing to enumerate.) If + * FindFirstFile fails, check if this is a directory-like thing + * (a mount point). + */ + if (hFind == INVALID_HANDLE_VALUE) + return git_fs_path_isdir(path); + + /* If the find handle was created successfully, then it's a directory */ + empty = true; + + do { + /* Allow the enumeration to return . and .. and still be considered + * empty. In the special case of drive roots (i.e. C:\) where . and + * .. do not occur, we can still consider the path to be an empty + * directory if there's nothing there. */ + if (!git_fs_path_is_dot_or_dotdotW(findData.cFileName)) { + empty = false; + break; + } + } while (FindNextFileW(hFind, &findData)); + + FindClose(hFind); + } + + return empty; +} + +#else + +static int path_found_entry(void *payload, git_str *path) +{ + GIT_UNUSED(payload); + return !git_fs_path_is_dot_or_dotdot(path->ptr); +} + +bool git_fs_path_is_empty_dir(const char *path) +{ + int error; + git_str dir = GIT_STR_INIT; + + if (!git_fs_path_isdir(path)) + return false; + + if ((error = git_str_sets(&dir, path)) != 0) + git_error_clear(); + else + error = git_fs_path_direach(&dir, 0, path_found_entry, NULL); + + git_str_dispose(&dir); + + return !error; +} + +#endif + +int git_fs_path_set_error(int errno_value, const char *path, const char *action) +{ + switch (errno_value) { + case ENOENT: + case ENOTDIR: + git_error_set(GIT_ERROR_OS, "could not find '%s' to %s", path, action); + return GIT_ENOTFOUND; + + case EINVAL: + case ENAMETOOLONG: + git_error_set(GIT_ERROR_OS, "invalid path for filesystem '%s'", path); + return GIT_EINVALIDSPEC; + + case EEXIST: + git_error_set(GIT_ERROR_OS, "failed %s - '%s' already exists", action, path); + return GIT_EEXISTS; + + case EACCES: + git_error_set(GIT_ERROR_OS, "failed %s - '%s' is locked", action, path); + return GIT_ELOCKED; + + default: + git_error_set(GIT_ERROR_OS, "could not %s '%s'", action, path); + return -1; + } +} + +int git_fs_path_lstat(const char *path, struct stat *st) +{ + if (p_lstat(path, st) == 0) + return 0; + + return git_fs_path_set_error(errno, path, "stat"); +} + +static bool _check_dir_contents( + git_str *dir, + const char *sub, + bool (*predicate)(const char *)) +{ + bool result; + size_t dir_size = git_str_len(dir); + size_t sub_size = strlen(sub); + size_t alloc_size; + + /* leave base valid even if we could not make space for subdir */ + if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || + GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || + git_str_try_grow(dir, alloc_size, false) < 0) + return false; + + /* save excursion */ + if (git_str_joinpath(dir, dir->ptr, sub) < 0) + return false; + + result = predicate(dir->ptr); + + /* restore path */ + git_str_truncate(dir, dir_size); + return result; +} + +bool git_fs_path_contains(git_str *dir, const char *item) +{ + return _check_dir_contents(dir, item, &git_fs_path_exists); +} + +bool git_fs_path_contains_dir(git_str *base, const char *subdir) +{ + return _check_dir_contents(base, subdir, &git_fs_path_isdir); +} + +bool git_fs_path_contains_file(git_str *base, const char *file) +{ + return _check_dir_contents(base, file, &git_fs_path_isfile); +} + +int git_fs_path_find_dir(git_str *dir) +{ + int error = 0; + char buf[GIT_PATH_MAX]; + + if (p_realpath(dir->ptr, buf) != NULL) + error = git_str_sets(dir, buf); + + /* call dirname if this is not a directory */ + if (!error) /* && git_fs_path_isdir(dir->ptr) == false) */ + error = (git_fs_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0; + + if (!error) + error = git_fs_path_to_dir(dir); + + return error; +} + +int git_fs_path_resolve_relative(git_str *path, size_t ceiling) +{ + char *base, *to, *from, *next; + size_t len; + + GIT_ERROR_CHECK_ALLOC_STR(path); + + if (ceiling > path->size) + ceiling = path->size; + + /* recognize drive prefixes, etc. that should not be backed over */ + if (ceiling == 0) + ceiling = git_fs_path_root(path->ptr) + 1; + + /* recognize URL prefixes that should not be backed over */ + if (ceiling == 0) { + for (next = path->ptr; *next && git__isalpha(*next); ++next); + if (next[0] == ':' && next[1] == '/' && next[2] == '/') + ceiling = (next + 3) - path->ptr; + } + + base = to = from = path->ptr + ceiling; + + while (*from) { + for (next = from; *next && *next != '/'; ++next); + + len = next - from; + + if (len == 1 && from[0] == '.') + /* do nothing with singleton dot */; + + else if (len == 2 && from[0] == '.' && from[1] == '.') { + /* error out if trying to up one from a hard base */ + if (to == base && ceiling != 0) { + git_error_set(GIT_ERROR_INVALID, + "cannot strip root component off url"); + return -1; + } + + /* no more path segments to strip, + * use '../' as a new base path */ + if (to == base) { + if (*next == '/') + len++; + + if (to != from) + memmove(to, from, len); + + to += len; + /* this is now the base, can't back up from a + * relative prefix */ + base = to; + } else { + /* back up a path segment */ + while (to > base && to[-1] == '/') to--; + while (to > base && to[-1] != '/') to--; + } + } else { + if (*next == '/' && *from != '/') + len++; + + if (to != from) + memmove(to, from, len); + + to += len; + } + + from += len; + + while (*from == '/') from++; + } + + *to = '\0'; + + path->size = to - path->ptr; + + return 0; +} + +int git_fs_path_apply_relative(git_str *target, const char *relpath) +{ + return git_str_joinpath(target, git_str_cstr(target), relpath) || + git_fs_path_resolve_relative(target, 0); +} + +int git_fs_path_cmp( + const char *name1, size_t len1, int isdir1, + const char *name2, size_t len2, int isdir2, + int (*compare)(const char *, const char *, size_t)) +{ + unsigned char c1, c2; + size_t len = len1 < len2 ? len1 : len2; + int cmp; + + cmp = compare(name1, name2, len); + if (cmp) + return cmp; + + c1 = name1[len]; + c2 = name2[len]; + + if (c1 == '\0' && isdir1) + c1 = '/'; + + if (c2 == '\0' && isdir2) + c2 = '/'; + + return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; +} + +size_t git_fs_path_common_dirlen(const char *one, const char *two) +{ + const char *p, *q, *dirsep = NULL; + + for (p = one, q = two; *p && *q; p++, q++) { + if (*p == '/' && *q == '/') + dirsep = p; + else if (*p != *q) + break; + } + + return dirsep ? (dirsep - one) + 1 : 0; +} + +int git_fs_path_make_relative(git_str *path, const char *parent) +{ + const char *p, *q, *p_dirsep, *q_dirsep; + size_t plen = path->size, newlen, alloclen, depth = 1, i, offset; + + for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) { + if (*p == '/' && *q == '/') { + p_dirsep = p; + q_dirsep = q; + } + else if (*p != *q) + break; + } + + /* need at least 1 common path segment */ + if ((p_dirsep == path->ptr || q_dirsep == parent) && + (*p_dirsep != '/' || *q_dirsep != '/')) { + git_error_set(GIT_ERROR_INVALID, + "%s is not a parent of %s", parent, path->ptr); + return GIT_ENOTFOUND; + } + + if (*p == '/' && !*q) + p++; + else if (!*p && *q == '/') + q++; + else if (!*p && !*q) + return git_str_clear(path), 0; + else { + p = p_dirsep + 1; + q = q_dirsep + 1; + } + + plen -= (p - path->ptr); + + if (!*q) + return git_str_set(path, p, plen); + + for (; (q = strchr(q, '/')) && *(q + 1); q++) + depth++; + + GIT_ERROR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3); + GIT_ERROR_CHECK_ALLOC_ADD(&newlen, newlen, plen); + + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, newlen, 1); + + /* save the offset as we might realllocate the pointer */ + offset = p - path->ptr; + if (git_str_try_grow(path, alloclen, 1) < 0) + return -1; + p = path->ptr + offset; + + memmove(path->ptr + (depth * 3), p, plen + 1); + + for (i = 0; i < depth; i++) + memcpy(path->ptr + (i * 3), "../", 3); + + path->size = newlen; + return 0; +} + +bool git_fs_path_has_non_ascii(const char *path, size_t pathlen) +{ + const uint8_t *scan = (const uint8_t *)path, *end; + + for (end = scan + pathlen; scan < end; ++scan) + if (*scan & 0x80) + return true; + + return false; +} + +#ifdef GIT_USE_ICONV + +int git_fs_path_iconv_init_precompose(git_fs_path_iconv_t *ic) +{ + git_str_init(&ic->buf, 0); + ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); + return 0; +} + +void git_fs_path_iconv_clear(git_fs_path_iconv_t *ic) +{ + if (ic) { + if (ic->map != (iconv_t)-1) + iconv_close(ic->map); + git_str_dispose(&ic->buf); + } +} + +int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen) +{ + char *nfd = (char*)*in, *nfc; + size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv; + int retry = 1; + + if (!ic || ic->map == (iconv_t)-1 || + !git_fs_path_has_non_ascii(*in, *inlen)) + return 0; + + git_str_clear(&ic->buf); + + while (1) { + GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1); + if (git_str_grow(&ic->buf, alloclen) < 0) + return -1; + + nfc = ic->buf.ptr + ic->buf.size; + nfclen = ic->buf.asize - ic->buf.size; + + rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen); + + ic->buf.size = (nfc - ic->buf.ptr); + + if (rv != (size_t)-1) + break; + + /* if we cannot convert the data (probably because iconv thinks + * it is not valid UTF-8 source data), then use original data + */ + if (errno != E2BIG) + return 0; + + /* make space for 2x the remaining data to be converted + * (with per retry overhead to avoid infinite loops) + */ + wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4); + + if (retry++ > 4) + goto fail; + } + + ic->buf.ptr[ic->buf.size] = '\0'; + + *in = ic->buf.ptr; + *inlen = ic->buf.size; + + return 0; + +fail: + git_error_set(GIT_ERROR_OS, "unable to convert unicode path data"); + return -1; +} + +static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX"; +static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; + +/* Check if the platform is decomposing unicode data for us. We will + * emulate core Git and prefer to use precomposed unicode data internally + * on these platforms, composing the decomposed unicode on the fly. + * + * This mainly happens on the Mac where HDFS stores filenames as + * decomposed unicode. Even on VFAT and SAMBA file systems, the Mac will + * return decomposed unicode from readdir() even when the actual + * filesystem is storing precomposed unicode. + */ +bool git_fs_path_does_decompose_unicode(const char *root) +{ + git_str path = GIT_STR_INIT; + int fd; + bool found_decomposed = false; + char tmp[6]; + + /* Create a file using a precomposed path and then try to find it + * using the decomposed name. If the lookup fails, then we will mark + * that we should precompose unicode for this repository. + */ + if (git_str_joinpath(&path, root, nfc_file) < 0 || + (fd = p_mkstemp(path.ptr)) < 0) + goto done; + p_close(fd); + + /* record trailing digits generated by mkstemp */ + memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); + + /* try to look up as NFD path */ + if (git_str_joinpath(&path, root, nfd_file) < 0) + goto done; + memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); + + found_decomposed = git_fs_path_exists(path.ptr); + + /* remove temporary file (using original precomposed path) */ + if (git_str_joinpath(&path, root, nfc_file) < 0) + goto done; + memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); + + (void)p_unlink(path.ptr); + +done: + git_str_dispose(&path); + return found_decomposed; +} + +#else + +bool git_fs_path_does_decompose_unicode(const char *root) +{ + GIT_UNUSED(root); + return false; +} + +#endif + +#if defined(__sun) || defined(__GNU__) +typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1]; +#else +typedef struct dirent path_dirent_data; +#endif + +int git_fs_path_direach( + git_str *path, + uint32_t flags, + int (*fn)(void *, git_str *), + void *arg) +{ + int error = 0; + ssize_t wd_len; + DIR *dir; + struct dirent *de; + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_t ic = GIT_PATH_ICONV_INIT; +#endif + + GIT_UNUSED(flags); + + if (git_fs_path_to_dir(path) < 0) + return -1; + + wd_len = git_str_len(path); + + if ((dir = opendir(path->ptr)) == NULL) { + git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr); + if (errno == ENOENT) + return GIT_ENOTFOUND; + + return -1; + } + +#ifdef GIT_USE_ICONV + if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0) + (void)git_fs_path_iconv_init_precompose(&ic); +#endif + + while ((de = readdir(dir)) != NULL) { + const char *de_path = de->d_name; + size_t de_len = strlen(de_path); + + if (git_fs_path_is_dot_or_dotdot(de_path)) + continue; + +#ifdef GIT_USE_ICONV + if ((error = git_fs_path_iconv(&ic, &de_path, &de_len)) < 0) + break; +#endif + + if ((error = git_str_put(path, de_path, de_len)) < 0) + break; + + git_error_clear(); + error = fn(arg, path); + + git_str_truncate(path, wd_len); /* restore path */ + + /* Only set our own error if the callback did not set one already */ + if (error != 0) { + if (!git_error_last()) + git_error_set_after_callback(error); + + break; + } + } + + closedir(dir); + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_clear(&ic); +#endif + + return error; +} + +#if defined(GIT_WIN32) && !defined(__MINGW32__) + +/* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7 + * and better. + */ +#ifndef FIND_FIRST_EX_LARGE_FETCH +# define FIND_FIRST_EX_LARGE_FETCH 2 +#endif + +int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags) +{ + git_win32_path path_filter; + + static int is_win7_or_later = -1; + if (is_win7_or_later < 0) + is_win7_or_later = git_has_win32_version(6, 1, 0); + + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); + + memset(diriter, 0, sizeof(git_fs_path_diriter)); + diriter->handle = INVALID_HANDLE_VALUE; + + if (git_str_puts(&diriter->path_utf8, path) < 0) + return -1; + + path_trim_slashes(&diriter->path_utf8); + + if (diriter->path_utf8.size == 0) { + git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); + return -1; + } + + if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 || + !git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) { + git_error_set(GIT_ERROR_OS, "could not parse the directory path '%s'", path); + return -1; + } + + diriter->handle = FindFirstFileExW( + path_filter, + is_win7_or_later ? FindExInfoBasic : FindExInfoStandard, + &diriter->current, + FindExSearchNameMatch, + NULL, + is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0); + + if (diriter->handle == INVALID_HANDLE_VALUE) { + git_error_set(GIT_ERROR_OS, "could not open directory '%s'", path); + return -1; + } + + diriter->parent_utf8_len = diriter->path_utf8.size; + diriter->flags = flags; + return 0; +} + +static int diriter_update_paths(git_fs_path_diriter *diriter) +{ + size_t filename_len, path_len; + + filename_len = wcslen(diriter->current.cFileName); + + if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) || + GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2)) + return -1; + + if (path_len > GIT_WIN_PATH_UTF16) { + git_error_set(GIT_ERROR_FILESYSTEM, + "invalid path '%.*ls\\%ls' (path too long)", + diriter->parent_len, diriter->path, diriter->current.cFileName); + return -1; + } + + diriter->path[diriter->parent_len] = L'\\'; + memcpy(&diriter->path[diriter->parent_len+1], + diriter->current.cFileName, filename_len * sizeof(wchar_t)); + diriter->path[path_len-1] = L'\0'; + + git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len); + + if (diriter->parent_utf8_len > 0 && + diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/') + git_str_putc(&diriter->path_utf8, '/'); + + git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); + + if (git_str_oom(&diriter->path_utf8)) + return -1; + + return 0; +} + +int git_fs_path_diriter_next(git_fs_path_diriter *diriter) +{ + bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); + + do { + /* Our first time through, we already have the data from + * FindFirstFileW. Use it, otherwise get the next file. + */ + if (!diriter->needs_next) + diriter->needs_next = 1; + else if (!FindNextFileW(diriter->handle, &diriter->current)) + return GIT_ITEROVER; + } while (skip_dot && git_fs_path_is_dot_or_dotdotW(diriter->current.cFileName)); + + if (diriter_update_paths(diriter) < 0) + return -1; + + return 0; +} + +int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path_utf8.size > diriter->parent_utf8_len); + + *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1]; + *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1; + return 0; +} + +int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + + *out = diriter->path_utf8.ptr; + *out_len = diriter->path_utf8.size; + return 0; +} + +int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); + + return git_win32__file_attribute_to_stat(out, + (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current, + diriter->path); +} + +void git_fs_path_diriter_free(git_fs_path_diriter *diriter) +{ + if (diriter == NULL) + return; + + git_str_dispose(&diriter->path_utf8); + + if (diriter->handle != INVALID_HANDLE_VALUE) { + FindClose(diriter->handle); + diriter->handle = INVALID_HANDLE_VALUE; + } +} + +#else + +int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags) +{ + GIT_ASSERT_ARG(diriter); + GIT_ASSERT_ARG(path); + + memset(diriter, 0, sizeof(git_fs_path_diriter)); + + if (git_str_puts(&diriter->path, path) < 0) + return -1; + + path_trim_slashes(&diriter->path); + + if (diriter->path.size == 0) { + git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); + return -1; + } + + if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) { + git_str_dispose(&diriter->path); + + git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path); + return -1; + } + +#ifdef GIT_USE_ICONV + if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0) + (void)git_fs_path_iconv_init_precompose(&diriter->ic); +#endif + + diriter->parent_len = diriter->path.size; + diriter->flags = flags; + + return 0; +} + +int git_fs_path_diriter_next(git_fs_path_diriter *diriter) +{ + struct dirent *de; + const char *filename; + size_t filename_len; + bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); + int error = 0; + + GIT_ASSERT_ARG(diriter); + + errno = 0; + + do { + if ((de = readdir(diriter->dir)) == NULL) { + if (!errno) + return GIT_ITEROVER; + + git_error_set(GIT_ERROR_OS, + "could not read directory '%s'", diriter->path.ptr); + return -1; + } + } while (skip_dot && git_fs_path_is_dot_or_dotdot(de->d_name)); + + filename = de->d_name; + filename_len = strlen(filename); + +#ifdef GIT_USE_ICONV + if ((diriter->flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0 && + (error = git_fs_path_iconv(&diriter->ic, &filename, &filename_len)) < 0) + return error; +#endif + + git_str_truncate(&diriter->path, diriter->parent_len); + + if (diriter->parent_len > 0 && + diriter->path.ptr[diriter->parent_len-1] != '/') + git_str_putc(&diriter->path, '/'); + + git_str_put(&diriter->path, filename, filename_len); + + if (git_str_oom(&diriter->path)) + return -1; + + return error; +} + +int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + GIT_ASSERT(diriter->path.size > diriter->parent_len); + + *out = &diriter->path.ptr[diriter->parent_len+1]; + *out_len = diriter->path.size - diriter->parent_len - 1; + return 0; +} + +int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(out_len); + GIT_ASSERT_ARG(diriter); + + *out = diriter->path.ptr; + *out_len = diriter->path.size; + return 0; +} + +int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter) +{ + GIT_ASSERT_ARG(out); + GIT_ASSERT_ARG(diriter); + + return git_fs_path_lstat(diriter->path.ptr, out); +} + +void git_fs_path_diriter_free(git_fs_path_diriter *diriter) +{ + if (diriter == NULL) + return; + + if (diriter->dir) { + closedir(diriter->dir); + diriter->dir = NULL; + } + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_clear(&diriter->ic); +#endif + + git_str_dispose(&diriter->path); +} + +#endif + +int git_fs_path_dirload( + git_vector *contents, + const char *path, + size_t prefix_len, + uint32_t flags) +{ + git_fs_path_diriter iter = GIT_FS_PATH_DIRITER_INIT; + const char *name; + size_t name_len; + char *dup; + int error; + + GIT_ASSERT_ARG(contents); + GIT_ASSERT_ARG(path); + + if ((error = git_fs_path_diriter_init(&iter, path, flags)) < 0) + return error; + + while ((error = git_fs_path_diriter_next(&iter)) == 0) { + if ((error = git_fs_path_diriter_fullpath(&name, &name_len, &iter)) < 0) + break; + + GIT_ASSERT(name_len > prefix_len); + + dup = git__strndup(name + prefix_len, name_len - prefix_len); + GIT_ERROR_CHECK_ALLOC(dup); + + if ((error = git_vector_insert(contents, dup)) < 0) + break; + } + + if (error == GIT_ITEROVER) + error = 0; + + git_fs_path_diriter_free(&iter); + return error; +} + +int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path) +{ + if (git_fs_path_is_local_file_url(url_or_path)) + return git_fs_path_fromurl(local_path_out, url_or_path); + else + return git_str_sets(local_path_out, url_or_path); +} + +/* Reject paths like AUX or COM1, or those versions that end in a dot or + * colon. ("AUX." or "AUX:") + */ +GIT_INLINE(bool) validate_dospath( + const char *component, + size_t len, + const char dospath[3], + bool trailing_num) +{ + size_t last = trailing_num ? 4 : 3; + + if (len < last || git__strncasecmp(component, dospath, 3) != 0) + return true; + + if (trailing_num && (component[3] < '1' || component[3] > '9')) + return true; + + return (len > last && + component[last] != '.' && + component[last] != ':'); +} + +GIT_INLINE(bool) validate_char(unsigned char c, unsigned int flags) +{ + if ((flags & GIT_FS_PATH_REJECT_BACKSLASH) && c == '\\') + return false; + + if ((flags & GIT_FS_PATH_REJECT_SLASH) && c == '/') + return false; + + if (flags & GIT_FS_PATH_REJECT_NT_CHARS) { + if (c < 32) + return false; + + switch (c) { + case '<': + case '>': + case ':': + case '"': + case '|': + case '?': + case '*': + return false; + } + } + + return true; +} + +/* + * We fundamentally don't like some paths when dealing with user-inputted + * strings (to avoid escaping a sandbox): we don't want dot or dot-dot + * anywhere, we want to avoid writing weird paths on Windows that can't + * be handled by tools that use the non-\\?\ APIs, we don't want slashes + * or double slashes at the end of paths that can make them ambiguous. + * + * For checkout, we don't want to recurse into ".git" either. + */ +static bool validate_component( + const char *component, + size_t len, + unsigned int flags) +{ + if (len == 0) + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && + len == 1 && component[0] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && + len == 2 && component[0] == '.' && component[1] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_DOT) && + component[len - 1] == '.') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_SPACE) && + component[len - 1] == ' ') + return false; + + if ((flags & GIT_FS_PATH_REJECT_TRAILING_COLON) && + component[len - 1] == ':') + return false; + + if (flags & GIT_FS_PATH_REJECT_DOS_PATHS) { + if (!validate_dospath(component, len, "CON", false) || + !validate_dospath(component, len, "PRN", false) || + !validate_dospath(component, len, "AUX", false) || + !validate_dospath(component, len, "NUL", false) || + !validate_dospath(component, len, "COM", true) || + !validate_dospath(component, len, "LPT", true)) + return false; + } + + return true; +} + +bool git_fs_path_validate_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload) +{ + const char *start, *c; + + for (start = c = path; *c; c++) { + if (!validate_char(*c, flags)) + return false; + + if (validate_char_cb && !validate_char_cb(*c, payload)) + return false; + + if (*c != '/') + continue; + + if (!validate_component(start, (c - start), flags)) + return false; + + if (validate_component_cb && + !validate_component_cb(start, (c - start), payload)) + return false; + + start = c + 1; + } + + if (!validate_component(start, (c - start), flags)) + return false; + + if (validate_component_cb && + !validate_component_cb(start, (c - start), payload)) + return false; + + return true; +} + +bool git_fs_path_validate(const char *path, unsigned int flags) +{ + return git_fs_path_validate_ext(path, flags, NULL, NULL, NULL); +} + +#ifdef GIT_WIN32 +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + int longpaths = 0; + + if (repo && + git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) + longpaths = 0; + + return (longpaths == 0); +} + +#else + +GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) +{ + GIT_UNUSED(repo); + + return false; +} +#endif + +int git_fs_path_validate_workdir(git_repository *repo, const char *path) +{ + if (should_validate_longpaths(repo)) + return git_fs_path_validate_filesystem(path, strlen(path)); + + return 0; +} + +int git_fs_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len) +{ + if (should_validate_longpaths(repo)) + return git_fs_path_validate_filesystem(path, path_len); + + return 0; +} + +int git_fs_path_validate_workdir_buf(git_repository *repo, git_str *path) +{ + return git_fs_path_validate_workdir_with_len(repo, path->ptr, path->size); +} + +int git_fs_path_normalize_slashes(git_str *out, const char *path) +{ + int error; + char *p; + + if ((error = git_str_puts(out, path)) < 0) + return error; + + for (p = out->ptr; *p; p++) { + if (*p == '\\') + *p = '/'; + } + + return 0; +} + +bool git_fs_path_supports_symlinks(const char *dir) +{ + git_str path = GIT_STR_INIT; + bool supported = false; + struct stat st; + int fd; + + if ((fd = git_futils_mktmp(&path, dir, 0666)) < 0 || + p_close(fd) < 0 || + p_unlink(path.ptr) < 0 || + p_symlink("testing", path.ptr) < 0 || + p_lstat(path.ptr, &st) < 0) + goto done; + + supported = (S_ISLNK(st.st_mode) != 0); +done: + if (path.size) + (void)p_unlink(path.ptr); + git_str_dispose(&path); + return supported; +} + +int git_fs_path_validate_system_file_ownership(const char *path) +{ +#ifndef GIT_WIN32 + GIT_UNUSED(path); + return GIT_OK; +#else + git_win32_path buf; + PSID owner_sid; + PSECURITY_DESCRIPTOR descriptor = NULL; + HANDLE token; + TOKEN_USER *info = NULL; + DWORD err, len; + int ret; + + if (git_win32_path_from_utf8(buf, path) < 0) + return -1; + + err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION, + &owner_sid, NULL, NULL, NULL, &descriptor); + + if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { + ret = GIT_ENOTFOUND; + goto cleanup; + } + + if (err != ERROR_SUCCESS) { + git_error_set(GIT_ERROR_OS, "failed to get security information"); + ret = GIT_ERROR; + goto cleanup; + } + + if (!IsValidSid(owner_sid)) { + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown"); + ret = GIT_ERROR; + goto cleanup; + } + + if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) || + IsWellKnownSid(owner_sid, WinLocalSystemSid)) { + ret = GIT_OK; + goto cleanup; + } + + /* Obtain current user's SID */ + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) && + !GetTokenInformation(token, TokenUser, NULL, 0, &len)) { + info = git__malloc(len); + GIT_ERROR_CHECK_ALLOC(info); + if (!GetTokenInformation(token, TokenUser, info, len, &len)) { + git__free(info); + info = NULL; + } + } + + /* + * If the file is owned by the same account that is running the current + * process, it's okay to read from that file. + */ + if (info && EqualSid(owner_sid, info->User.Sid)) + ret = GIT_OK; + else { + git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid"); + ret = GIT_ERROR; + } + git__free(info); + +cleanup: + if (descriptor) + LocalFree(descriptor); + + return ret; +#endif +} diff --git a/src/fs_path.h b/src/fs_path.h new file mode 100644 index 000000000..a60a37d98 --- /dev/null +++ b/src/fs_path.h @@ -0,0 +1,728 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_fs_path_h__ +#define INCLUDE_fs_path_h__ + +#include "common.h" + +#include "posix.h" +#include "str.h" +#include "vector.h" + +#include "git2/sys/path.h" + +/** + * Path manipulation utils + * + * These are path utilities that munge paths without actually + * looking at the real filesystem. + */ + +/* + * The dirname() function shall take a pointer to a character string + * that contains a pathname, and return a pointer to a string that is a + * pathname of the parent directory of that file. Trailing '/' characters + * in the path are not counted as part of the path. + * + * If path does not contain a '/', then dirname() shall return a pointer to + * the string ".". If path is a null pointer or points to an empty string, + * dirname() shall return a pointer to the string "." . + * + * The `git_fs_path_dirname` implementation is thread safe. The returned + * string must be manually free'd. + * + * The `git_fs_path_dirname_r` implementation writes the dirname to a `git_str` + * if the buffer pointer is not NULL. + * It returns an error code < 0 if there is an allocation error, otherwise + * the length of the dirname (which will be > 0). + */ +extern char *git_fs_path_dirname(const char *path); +extern int git_fs_path_dirname_r(git_str *buffer, const char *path); + +/* + * This function returns the basename of the file, which is the last + * part of its full name given by fname, with the drive letter and + * leading directories stripped off. For example, the basename of + * c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo. + * + * Trailing slashes and backslashes are significant: the basename of + * c:/foo/bar/ is an empty string after the rightmost slash. + * + * The `git_fs_path_basename` implementation is thread safe. The returned + * string must be manually free'd. + * + * The `git_fs_path_basename_r` implementation writes the basename to a `git_str`. + * It returns an error code < 0 if there is an allocation error, otherwise + * the length of the basename (which will be >= 0). + */ +extern char *git_fs_path_basename(const char *path); +extern int git_fs_path_basename_r(git_str *buffer, const char *path); + +/* Return the offset of the start of the basename. Unlike the other + * basename functions, this returns 0 if the path is empty. + */ +extern size_t git_fs_path_basename_offset(git_str *buffer); + +/** + * Find offset to root of path if path has one. + * + * This will return a number >= 0 which is the offset to the start of the + * path, if the path is rooted (i.e. "/rooted/path" returns 0 and + * "c:/windows/rooted/path" returns 2). If the path is not rooted, this + * returns -1. + */ +extern int git_fs_path_root(const char *path); + +/** + * Ensure path has a trailing '/'. + */ +extern int git_fs_path_to_dir(git_str *path); + +/** + * Ensure string has a trailing '/' if there is space for it. + */ +extern void git_fs_path_string_to_dir(char *path, size_t size); + +/** + * Taken from git.git; returns nonzero if the given path is "." or "..". + */ +GIT_INLINE(int) git_fs_path_is_dot_or_dotdot(const char *name) +{ + return (name[0] == '.' && + (name[1] == '\0' || + (name[1] == '.' && name[2] == '\0'))); +} + +#ifdef GIT_WIN32 +GIT_INLINE(int) git_fs_path_is_dot_or_dotdotW(const wchar_t *name) +{ + return (name[0] == L'.' && + (name[1] == L'\0' || + (name[1] == L'.' && name[2] == L'\0'))); +} + +#define git_fs_path_is_absolute(p) \ + (git__isalpha((p)[0]) && (p)[1] == ':' && ((p)[2] == '\\' || (p)[2] == '/')) + +#define git_fs_path_is_dirsep(p) \ + ((p) == '/' || (p) == '\\') + +/** + * Convert backslashes in path to forward slashes. + */ +GIT_INLINE(void) git_fs_path_mkposix(char *path) +{ + while (*path) { + if (*path == '\\') + *path = '/'; + + path++; + } +} +#else +# define git_fs_path_mkposix(p) /* blank */ + +#define git_fs_path_is_absolute(p) \ + ((p)[0] == '/') + +#define git_fs_path_is_dirsep(p) \ + ((p) == '/') + +#endif + +/** + * Check if string is a relative path (i.e. starts with "./" or "../") + */ +GIT_INLINE(int) git_fs_path_is_relative(const char *p) +{ + return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); +} + +/** + * Check if string is at end of path segment (i.e. looking at '/' or '\0') + */ +GIT_INLINE(int) git_fs_path_at_end_of_segment(const char *p) +{ + return !*p || *p == '/'; +} + +extern int git__percent_decode(git_str *decoded_out, const char *input); + +/** + * Extract path from file:// URL. + */ +extern int git_fs_path_fromurl(git_str *local_path_out, const char *file_url); + + +/** + * Path filesystem utils + * + * These are path utilities that actually access the filesystem. + */ + +/** + * Check if a file exists and can be accessed. + * @return true or false + */ +extern bool git_fs_path_exists(const char *path); + +/** + * Check if the given path points to a directory. + * @return true or false + */ +extern bool git_fs_path_isdir(const char *path); + +/** + * Check if the given path points to a regular file. + * @return true or false + */ +extern bool git_fs_path_isfile(const char *path); + +/** + * Check if the given path points to a symbolic link. + * @return true or false + */ +extern bool git_fs_path_islink(const char *path); + +/** + * Check if the given path is a directory, and is empty. + */ +extern bool git_fs_path_is_empty_dir(const char *path); + +/** + * Stat a file and/or link and set error if needed. + */ +extern int git_fs_path_lstat(const char *path, struct stat *st); + +/** + * Check if the parent directory contains the item. + * + * @param dir Directory to check. + * @param item Item that might be in the directory. + * @return 0 if item exists in directory, <0 otherwise. + */ +extern bool git_fs_path_contains(git_str *dir, const char *item); + +/** + * Check if the given path contains the given subdirectory. + * + * @param parent Directory path that might contain subdir + * @param subdir Subdirectory name to look for in parent + * @return true if subdirectory exists, false otherwise. + */ +extern bool git_fs_path_contains_dir(git_str *parent, const char *subdir); + +/** + * Determine the common directory length between two paths, including + * the final path separator. For example, given paths 'a/b/c/1.txt + * and 'a/b/c/d/2.txt', the common directory is 'a/b/c/', and this + * will return the length of the string 'a/b/c/', which is 6. + * + * @param one The first path + * @param two The second path + * @return The length of the common directory + */ +extern size_t git_fs_path_common_dirlen(const char *one, const char *two); + +/** + * Make the path relative to the given parent path. + * + * @param path The path to make relative + * @param parent The parent path to make path relative to + * @return 0 if path was made relative, GIT_ENOTFOUND + * if there was not common root between the paths, + * or <0. + */ +extern int git_fs_path_make_relative(git_str *path, const char *parent); + +/** + * Check if the given path contains the given file. + * + * @param dir Directory path that might contain file + * @param file File name to look for in parent + * @return true if file exists, false otherwise. + */ +extern bool git_fs_path_contains_file(git_str *dir, const char *file); + +/** + * Prepend base to unrooted path or just copy path over. + * + * This will optionally return the index into the path where the "root" + * is, either the end of the base directory prefix or the path root. + */ +extern int git_fs_path_join_unrooted( + git_str *path_out, const char *path, const char *base, ssize_t *root_at); + +/** + * Removes multiple occurrences of '/' in a row, squashing them into a + * single '/'. + */ +extern void git_fs_path_squash_slashes(git_str *path); + +/** + * Clean up path, prepending base if it is not already rooted. + */ +extern int git_fs_path_prettify(git_str *path_out, const char *path, const char *base); + +/** + * Clean up path, prepending base if it is not already rooted and + * appending a slash. + */ +extern int git_fs_path_prettify_dir(git_str *path_out, const char *path, const char *base); + +/** + * Get a directory from a path. + * + * If path is a directory, this acts like `git_fs_path_prettify_dir` + * (cleaning up path and appending a '/'). If path is a normal file, + * this prettifies it, then removed the filename a la dirname and + * appends the trailing '/'. If the path does not exist, it is + * treated like a regular filename. + */ +extern int git_fs_path_find_dir(git_str *dir); + +/** + * Resolve relative references within a path. + * + * This eliminates "./" and "../" relative references inside a path, + * as well as condensing multiple slashes into single ones. It will + * not touch the path before the "ceiling" length. + * + * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL + * prefix and not touch that part of the path. + */ +extern int git_fs_path_resolve_relative(git_str *path, size_t ceiling); + +/** + * Apply a relative path to base path. + * + * Note that the base path could be a filename or a URL and this + * should still work. The relative path is walked segment by segment + * with three rules: series of slashes will be condensed to a single + * slash, "." will be eaten with no change, and ".." will remove a + * segment from the base path. + */ +extern int git_fs_path_apply_relative(git_str *target, const char *relpath); + +enum { + GIT_FS_PATH_DIR_IGNORE_CASE = (1u << 0), + GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1), + GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT = (1u << 2), +}; + +/** + * Walk each directory entry, except '.' and '..', calling fn(state). + * + * @param pathbuf Buffer the function reads the initial directory + * path from, and updates with each successive entry's name. + * @param flags Combination of GIT_FS_PATH_DIR flags. + * @param callback Callback for each entry. Passed the `payload` and each + * successive path inside the directory as a full path. This may + * safely append text to the pathbuf if needed. Return non-zero to + * cancel iteration (and return value will be propagated back). + * @param payload Passed to callback as first argument. + * @return 0 on success or error code from OS error or from callback + */ +extern int git_fs_path_direach( + git_str *pathbuf, + uint32_t flags, + int (*callback)(void *payload, git_str *path), + void *payload); + +/** + * Sort function to order two paths + */ +extern int git_fs_path_cmp( + const char *name1, size_t len1, int isdir1, + const char *name2, size_t len2, int isdir2, + int (*compare)(const char *, const char *, size_t)); + +/** + * Invoke callback up path directory by directory until the ceiling is + * reached (inclusive of a final call at the root_path). + * + * Returning anything other than 0 from the callback function + * will stop the iteration and propagate the error to the caller. + * + * @param pathbuf Buffer the function reads the directory from and + * and updates with each successive name. + * @param ceiling Prefix of path at which to stop walking up. If NULL, + * this will walk all the way up to the root. If not a prefix of + * pathbuf, the callback will be invoked a single time on the + * original input path. + * @param callback Function to invoke on each path. Passed the `payload` + * and the buffer containing the current path. The path should not + * be modified in any way. Return non-zero to stop iteration. + * @param payload Passed to fn as the first ath. + */ +extern int git_fs_path_walk_up( + git_str *pathbuf, + const char *ceiling, + int (*callback)(void *payload, const char *path), + void *payload); + + +enum { + GIT_FS_PATH_NOTEQUAL = 0, + GIT_FS_PATH_EQUAL = 1, + GIT_FS_PATH_PREFIX = 2 +}; + +/* + * Determines if a path is equal to or potentially a child of another. + * @param parent The possible parent + * @param child The possible child + */ +GIT_INLINE(int) git_fs_path_equal_or_prefixed( + const char *parent, + const char *child, + ssize_t *prefixlen) +{ + const char *p = parent, *c = child; + int lastslash = 0; + + while (*p && *c) { + lastslash = (*p == '/'); + + if (*p++ != *c++) + return GIT_FS_PATH_NOTEQUAL; + } + + if (*p != '\0') + return GIT_FS_PATH_NOTEQUAL; + + if (*c == '\0') { + if (prefixlen) + *prefixlen = p - parent; + + return GIT_FS_PATH_EQUAL; + } + + if (*c == '/' || lastslash) { + if (prefixlen) + *prefixlen = (p - parent) - lastslash; + + return GIT_FS_PATH_PREFIX; + } + + return GIT_FS_PATH_NOTEQUAL; +} + +/* translate errno to libgit2 error code and set error message */ +extern int git_fs_path_set_error( + int errno_value, const char *path, const char *action); + +/* check if non-ascii characters are present in filename */ +extern bool git_fs_path_has_non_ascii(const char *path, size_t pathlen); + +#define GIT_PATH_REPO_ENCODING "UTF-8" + +#ifdef __APPLE__ +#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC" +#else +#define GIT_PATH_NATIVE_ENCODING "UTF-8" +#endif + +#ifdef GIT_USE_ICONV + +#include + +typedef struct { + iconv_t map; + git_str buf; +} git_fs_path_iconv_t; + +#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_STR_INIT } + +/* Init iconv data for converting decomposed UTF-8 to precomposed */ +extern int git_fs_path_iconv_init_precompose(git_fs_path_iconv_t *ic); + +/* Clear allocated iconv data */ +extern void git_fs_path_iconv_clear(git_fs_path_iconv_t *ic); + +/* + * Rewrite `in` buffer using iconv map if necessary, replacing `in` + * pointer internal iconv buffer if rewrite happened. The `in` pointer + * will be left unchanged if no rewrite was needed. + */ +extern int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen); + +#endif /* GIT_USE_ICONV */ + +extern bool git_fs_path_does_decompose_unicode(const char *root); + + +typedef struct git_fs_path_diriter git_fs_path_diriter; + +#if defined(GIT_WIN32) && !defined(__MINGW32__) + +struct git_fs_path_diriter +{ + git_win32_path path; + size_t parent_len; + + git_str path_utf8; + size_t parent_utf8_len; + + HANDLE handle; + + unsigned int flags; + + WIN32_FIND_DATAW current; + unsigned int needs_next; +}; + +#define GIT_FS_PATH_DIRITER_INIT { {0}, 0, GIT_STR_INIT, 0, INVALID_HANDLE_VALUE } + +#else + +struct git_fs_path_diriter +{ + git_str path; + size_t parent_len; + + unsigned int flags; + + DIR *dir; + +#ifdef GIT_USE_ICONV + git_fs_path_iconv_t ic; +#endif +}; + +#define GIT_FS_PATH_DIRITER_INIT { GIT_STR_INIT } + +#endif + +/** + * Initialize a directory iterator. + * + * @param diriter Pointer to a diriter structure that will be setup. + * @param path The path that will be iterated over + * @param flags Directory reader flags + * @return 0 or an error code + */ +extern int git_fs_path_diriter_init( + git_fs_path_diriter *diriter, + const char *path, + unsigned int flags); + +/** + * Advance the directory iterator. Will return GIT_ITEROVER when + * the iteration has completed successfully. + * + * @param diriter The directory iterator + * @return 0, GIT_ITEROVER, or an error code + */ +extern int git_fs_path_diriter_next(git_fs_path_diriter *diriter); + +/** + * Returns the file name of the current item in the iterator. + * + * @param out Pointer to store the path in + * @param out_len Pointer to store the length of the path in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_filename( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter); + +/** + * Returns the full path of the current item in the iterator; that + * is the current filename plus the path of the directory that the + * iterator was constructed with. + * + * @param out Pointer to store the path in + * @param out_len Pointer to store the length of the path in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_fullpath( + const char **out, + size_t *out_len, + git_fs_path_diriter *diriter); + +/** + * Performs an `lstat` on the current item in the iterator. + * + * @param out Pointer to store the stat data in + * @param diriter The directory iterator + * @return 0 or an error code + */ +extern int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter); + +/** + * Closes the directory iterator. + * + * @param diriter The directory iterator + */ +extern void git_fs_path_diriter_free(git_fs_path_diriter *diriter); + +/** + * Load all directory entries (except '.' and '..') into a vector. + * + * For cases where `git_fs_path_direach()` is not appropriate, this + * allows you to load the filenames in a directory into a vector + * of strings. That vector can then be sorted, iterated, or whatever. + * Remember to free alloc of the allocated strings when you are done. + * + * @param contents Vector to fill with directory entry names. + * @param path The directory to read from. + * @param prefix_len When inserting entries, the trailing part of path + * will be prefixed after this length. I.e. given path "/a/b" and + * prefix_len 3, the entries will look like "b/e1", "b/e2", etc. + * @param flags Combination of GIT_FS_PATH_DIR flags. + */ +extern int git_fs_path_dirload( + git_vector *contents, + const char *path, + size_t prefix_len, + uint32_t flags); + + +/* Used for paths to repositories on the filesystem */ +extern bool git_fs_path_is_local_file_url(const char *file_url); +extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); + +/* Flags to determine path validity in `git_fs_path_isvalid` */ +#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0) +#define GIT_FS_PATH_REJECT_SLASH (1 << 2) +#define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) +#define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) +#define GIT_FS_PATH_REJECT_TRAILING_SPACE (1 << 5) +#define GIT_FS_PATH_REJECT_TRAILING_COLON (1 << 6) +#define GIT_FS_PATH_REJECT_DOS_PATHS (1 << 7) +#define GIT_FS_PATH_REJECT_NT_CHARS (1 << 8) + +#define GIT_FS_PATH_REJECT_MAX (1 << 8) + +/* Default path safety for writing files to disk: since we use the + * Win32 "File Namespace" APIs ("\\?\") we need to protect from + * paths that the normal Win32 APIs would not write. + */ +#ifdef GIT_WIN32 +# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_TRAVERSAL | \ + GIT_FS_PATH_REJECT_BACKSLASH | \ + GIT_FS_PATH_REJECT_TRAILING_DOT | \ + GIT_FS_PATH_REJECT_TRAILING_SPACE | \ + GIT_FS_PATH_REJECT_TRAILING_COLON | \ + GIT_FS_PATH_REJECT_DOS_PATHS | \ + GIT_FS_PATH_REJECT_NT_CHARS +#else +# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_TRAVERSAL +#endif + +/** + * Validate a filesystem path. This ensures that the given path is legal + * and does not contain any "unsafe" components like path traversal ('.' + * or '..'), characters that are inappropriate for lesser filesystems + * (trailing ' ' or ':' characters), or filenames ("component names") + * that are not supported ('AUX', 'COM1"). + */ +extern bool git_fs_path_validate(const char *path, unsigned int flags); + +/** + * Validate a filesystem path; with custom callbacks per-character and + * per-path component. + */ +extern bool git_fs_path_validate_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload); + +/** + * Validate an on-disk path, taking into account that it will have a + * suffix appended (eg, `.lock`). + */ +GIT_INLINE(int) git_fs_path_validate_filesystem_with_suffix( + const char *path, + size_t path_len, + size_t suffix_len) +{ +#ifdef GIT_WIN32 + size_t path_chars, total_chars; + + path_chars = git_utf8_char_length(path, path_len); + + if (GIT_ADD_SIZET_OVERFLOW(&total_chars, path_chars, suffix_len) || + total_chars > MAX_PATH) { + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path); + return -1; + } + return 0; +#else + GIT_UNUSED(path); + GIT_UNUSED(path_len); + GIT_UNUSED(suffix_len); + return 0; +#endif +} + +/** + * Validate an path on the filesystem. This ensures that the given + * path is valid for the operating system/platform; for example, this + * will ensure that the given absolute path is smaller than MAX_PATH on + * Windows. + * + * For paths within the working directory, you should use ensure that + * `core.longpaths` is obeyed. Use `git_fs_path_validate_workdir`. + */ +GIT_INLINE(int) git_fs_path_validate_filesystem( + const char *path, + size_t path_len) +{ + return git_fs_path_validate_filesystem_with_suffix(path, path_len, 0); +} + +/** + * Validate a path relative to the repo's worktree. This ensures that + * the given working tree path is valid for the operating system/platform. + * This will ensure that an absolute path is smaller than MAX_PATH on + * Windows, while keeping `core.longpaths` configuration settings in mind. + * + * This should be checked by mechamisms like `git_checkout` after + * contructing on-disk paths and before trying to write them. + * + * If the repository is null, no repository configuration is applied. + */ +extern int git_fs_path_validate_workdir( + git_repository *repo, + const char *path); +extern int git_fs_path_validate_workdir_with_len( + git_repository *repo, + const char *path, + size_t path_len); +extern int git_fs_path_validate_workdir_buf( + git_repository *repo, + git_str *buf); + +/** + * Convert any backslashes into slashes + */ +int git_fs_path_normalize_slashes(git_str *out, const char *path); + +bool git_fs_path_supports_symlinks(const char *dir); + +/** + * Validate a system file's ownership + * + * Verify that the file in question is owned by an administrator or system + * account, or at least by the current user. + * + * This function returns 0 if successful. If the file is not owned by any of + * these, or any other if there have been problems determining the file + * ownership, it returns -1. + */ +int git_fs_path_validate_system_file_ownership(const char *path); + +#endif diff --git a/src/futils.c b/src/futils.c index 9a15ceeb9..7ec1009bd 100644 --- a/src/futils.c +++ b/src/futils.c @@ -99,7 +99,7 @@ int git_futils_open_ro(const char *path) { int fd = p_open(path, O_RDONLY); if (fd < 0) - return git_path_set_error(errno, path, "open"); + return git_fs_path_set_error(errno, path, "open"); return fd; } @@ -107,7 +107,7 @@ int git_futils_truncate(const char *path, int mode) { int fd = p_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); if (fd < 0) - return git_path_set_error(errno, path, "open"); + return git_fs_path_set_error(errno, path, "open"); close(fd); return 0; @@ -195,7 +195,7 @@ int git_futils_readbuffer_updated( *updated = 0; if (p_stat(path, &st) < 0) - return git_path_set_error(errno, path, "stat"); + return git_fs_path_set_error(errno, path, "stat"); if (S_ISDIR(st.st_mode)) { @@ -429,7 +429,7 @@ GIT_INLINE(int) mkdir_canonicalize( } /* Trim trailing slashes (except the root) */ - if ((root_len = git_path_root(path->ptr)) < 0) + if ((root_len = git_fs_path_root(path->ptr)) < 0) root_len = 0; else root_len++; @@ -439,11 +439,11 @@ GIT_INLINE(int) mkdir_canonicalize( /* if we are not supposed to made the last element, truncate it */ if ((flags & GIT_MKDIR_SKIP_LAST2) != 0) { - git_path_dirname_r(path, path->ptr); + git_fs_path_dirname_r(path, path->ptr); flags |= GIT_MKDIR_SKIP_LAST; } if ((flags & GIT_MKDIR_SKIP_LAST) != 0) { - git_path_dirname_r(path, path->ptr); + git_fs_path_dirname_r(path, path->ptr); } /* We were either given the root path (or trimmed it to @@ -473,7 +473,7 @@ int git_futils_mkdir( make_path.size == 0) goto done; - root_len = git_path_root(make_path.ptr); + root_len = git_fs_path_root(make_path.ptr); /* find the first parent directory that exists. this will be used * as the base to dirname_relative. @@ -492,7 +492,7 @@ int git_futils_mkdir( depth++; /* examine the parent of the current path */ - if ((len = git_path_dirname_r(&parent_path, parent_path.ptr)) < 0) { + if ((len = git_fs_path_dirname_r(&parent_path, parent_path.ptr)) < 0) { error = len; goto done; } @@ -569,7 +569,7 @@ int git_futils_mkdir_relative( opts = &empty_opts; /* build path and find "root" where we should start calling mkdir */ - if (git_path_join_unrooted(&make_path, relative_path, base, &root) < 0) + if (git_fs_path_join_unrooted(&make_path, relative_path, base, &root) < 0) return -1; if ((error = mkdir_canonicalize(&make_path, flags)) < 0 || @@ -581,7 +581,7 @@ int git_futils_mkdir_relative( root = git_str_rfind(&make_path, '/'); /* advance root past drive name or network mount prefix */ - min_root_len = git_path_root(make_path.ptr); + min_root_len = git_fs_path_root(make_path.ptr); if (root < min_root_len) root = min_root_len; while (root >= 0 && make_path.ptr[root] == '/') @@ -744,13 +744,13 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_str *path) path->ptr, "parent is not directory"); } else - error = git_path_set_error(errno, path->ptr, "rmdir"); + error = git_fs_path_set_error(errno, path->ptr, "rmdir"); } else if (S_ISDIR(st.st_mode)) { data->depth++; - error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data); + error = git_fs_path_direach(path, 0, futils__rmdir_recurs_foreach, data); data->depth--; @@ -765,13 +765,13 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_str *path) (errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY)) error = 0; else - error = git_path_set_error(errno, path->ptr, "rmdir"); + error = git_fs_path_set_error(errno, path->ptr, "rmdir"); } } else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) { if (p_unlink(path->ptr) < 0) - error = git_path_set_error(errno, path->ptr, "remove"); + error = git_fs_path_set_error(errno, path->ptr, "remove"); } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0) @@ -795,11 +795,11 @@ static int futils__rmdir_empty_parent(void *opaque, const char *path) /* do nothing */ } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0 && en == EBUSY) { - error = git_path_set_error(errno, path, "rmdir"); + error = git_fs_path_set_error(errno, path, "rmdir"); } else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) { error = GIT_ITEROVER; } else { - error = git_path_set_error(errno, path, "rmdir"); + error = git_fs_path_set_error(errno, path, "rmdir"); } } @@ -814,7 +814,7 @@ int git_futils_rmdir_r( futils__rmdir_data data; /* build path and find "root" where we should start calling mkdir */ - if (git_path_join_unrooted(&fullpath, path, base, NULL) < 0) + if (git_fs_path_join_unrooted(&fullpath, path, base, NULL) < 0) return -1; memset(&data, 0, sizeof(data)); @@ -826,7 +826,7 @@ int git_futils_rmdir_r( /* remove now-empty parents if requested */ if (!error && (flags & GIT_RMDIR_EMPTY_PARENTS) != 0) - error = git_path_walk_up( + error = git_fs_path_walk_up( &fullpath, base, futils__rmdir_empty_parent, &data); if (error == GIT_ITEROVER) { @@ -887,7 +887,7 @@ int git_futils_cp(const char *from, const char *to, mode_t filemode) if ((ofd = p_open(to, O_WRONLY | O_CREAT | O_EXCL, filemode)) < 0) { p_close(ifd); - return git_path_set_error(errno, to, "open for writing"); + return git_fs_path_set_error(errno, to, "open for writing"); } return cp_by_fd(ifd, ofd, true); @@ -903,7 +903,7 @@ int git_futils_touch(const char *path, time_t *when) ret = p_utimes(path, times); - return (ret < 0) ? git_path_set_error(errno, path, "touch") : 0; + return (ret < 0) ? git_fs_path_set_error(errno, path, "touch") : 0; } static int cp_link(const char *from, const char *to, size_t link_size) @@ -977,14 +977,14 @@ static int _cp_r_callback(void *ref, git_str *from) bool exists = false; if ((info->flags & GIT_CPDIR_COPY_DOTFILES) == 0 && - from->ptr[git_path_basename_offset(from)] == '.') + from->ptr[git_fs_path_basename_offset(from)] == '.') return 0; if ((error = git_str_joinpath( &info->to, info->to_root, from->ptr + info->from_prefix)) < 0) return error; - if (!(error = git_path_lstat(info->to.ptr, &to_st))) + if (!(error = git_fs_path_lstat(info->to.ptr, &to_st))) exists = true; else if (error != GIT_ENOTFOUND) return error; @@ -993,7 +993,7 @@ static int _cp_r_callback(void *ref, git_str *from) error = 0; } - if ((error = git_path_lstat(from->ptr, &from_st)) < 0) + if ((error = git_fs_path_lstat(from->ptr, &from_st)) < 0) return error; if (S_ISDIR(from_st.st_mode)) { @@ -1009,7 +1009,7 @@ static int _cp_r_callback(void *ref, git_str *from) /* recurse onto target directory */ if (!error && (!exists || S_ISDIR(to_st.st_mode))) - error = git_path_direach(from, 0, _cp_r_callback, info); + error = git_fs_path_direach(from, 0, _cp_r_callback, info); if (oldmode != 0) info->dirmode = oldmode; @@ -1182,7 +1182,7 @@ int git_futils_fsync_parent(const char *path) char *parent; int error; - if ((parent = git_path_dirname(path)) == NULL) + if ((parent = git_fs_path_dirname(path)) == NULL) return -1; error = git_futils_fsync_dir(parent); diff --git a/src/futils.h b/src/futils.h index eea69adde..22098addf 100644 --- a/src/futils.h +++ b/src/futils.h @@ -11,7 +11,7 @@ #include "map.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "pool.h" #include "strmap.h" #include "hash.h" diff --git a/src/ignore.c b/src/ignore.c index eb9fd8a9e..e7d8b799f 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -10,7 +10,7 @@ #include "git2/ignore.h" #include "common.h" #include "attrcache.h" -#include "path.h" +#include "fs_path.h" #include "config.h" #include "wildmatch.h" @@ -181,7 +181,7 @@ static int parse_ignore_file( /* if subdir file path, convert context for file paths */ if (attrs->entry && - git_path_root(attrs->entry->path) < 0 && + git_fs_path_root(attrs->entry->path) < 0 && !git__suffixcmp(attrs->entry->path, "/" GIT_IGNORE_FILE)) context = attrs->entry->path; @@ -313,21 +313,21 @@ int git_ignore__for_path( goto cleanup; /* given a unrooted path in a non-bare repo, resolve it */ - if (workdir && git_path_root(path) < 0) { + if (workdir && git_fs_path_root(path) < 0) { git_str local = GIT_STR_INIT; - if ((error = git_path_dirname_r(&local, path)) < 0 || - (error = git_path_resolve_relative(&local, 0)) < 0 || - (error = git_path_to_dir(&local)) < 0 || + if ((error = git_fs_path_dirname_r(&local, path)) < 0 || + (error = git_fs_path_resolve_relative(&local, 0)) < 0 || + (error = git_fs_path_to_dir(&local)) < 0 || (error = git_str_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || - (error = git_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { + (error = git_fs_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { /* Nothing, we just want to stop on the first error */ } git_str_dispose(&local); } else { if (!(error = git_str_joinpath(&ignores->dir, path, ""))) - error = git_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); + error = git_fs_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); } if (error < 0) @@ -342,7 +342,7 @@ int git_ignore__for_path( /* load .gitignore up the path */ if (workdir != NULL) { - error = git_path_walk_up( + error = git_fs_path_walk_up( &ignores->dir, workdir, push_one_ignore, ignores); if (error < 0) goto cleanup; @@ -410,7 +410,7 @@ int git_ignore__pop_dir(git_ignores *ign) if (--ign->depth > 0) { git_str_rtruncate_at_char(&ign->dir, '/'); - git_path_to_dir(&ign->dir); + git_fs_path_to_dir(&ign->dir); } return 0; @@ -629,7 +629,7 @@ int git_ignore__check_pathspec_for_exact_ignores( break; /* is there a file on disk that matches this exactly? */ - if (!git_path_isfile(path.ptr)) + if (!git_fs_path_isfile(path.ptr)) continue; /* is that file ignored? */ diff --git a/src/index.c b/src/index.c index b8aa310d3..448852f29 100644 --- a/src/index.c +++ b/src/index.c @@ -20,6 +20,7 @@ #include "idxmap.h" #include "diff.h" #include "varint.h" +#include "path.h" #include "git2/odb.h" #include "git2/oid.h" @@ -420,7 +421,7 @@ int git_index_open(git_index **index_out, const char *index_path) goto fail; /* Check if index file is stored on disk already */ - if (git_path_exists(index->index_file_path) == true) + if (git_fs_path_exists(index->index_file_path) == true) index->on_disk = 1; } @@ -648,7 +649,7 @@ int git_index_read(git_index *index, int force) return create_index_error(-1, "failed to read index: The index is in-memory only"); - index->on_disk = git_path_exists(index->index_file_path); + index->on_disk = git_fs_path_exists(index->index_file_path); if (!index->on_disk) { if (force && (error = git_index_clear(index)) < 0) @@ -991,7 +992,7 @@ static int index_entry_init( if (git_repository_workdir_path(&path, repo, rel_path) < 0) return -1; - error = git_path_lstat(path.ptr, &st); + error = git_fs_path_lstat(path.ptr, &st); git_str_dispose(&path); if (error < 0) @@ -1728,7 +1729,7 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) git_index_entry *entry; if (!(error = git_str_sets(&pfx, dir)) && - !(error = git_path_to_dir(&pfx))) + !(error = git_fs_path_to_dir(&pfx))) index_find(&pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY); while (!error) { diff --git a/src/iterator.c b/src/iterator.c index 5549c636a..a627e0f88 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -472,7 +472,7 @@ GIT_INLINE(tree_iterator_frame *) tree_iterator_current_frame( GIT_INLINE(int) tree_entry_cmp( const git_tree_entry *a, const git_tree_entry *b, bool icase) { - return git_path_cmp( + return git_fs_path_cmp( a->filename, a->filename_len, a->attr == GIT_FILEMODE_TREE, b->filename, b->filename_len, b->attr == GIT_FILEMODE_TREE, icase ? git__strncasecmp : git__strncmp); @@ -1279,7 +1279,7 @@ static int filesystem_iterator_entry_hash( iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && - !(error = git_path_validate_workdir_buf(iter->base.repo, &fullpath))) + !(error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); git_str_dispose(&fullpath); @@ -1336,7 +1336,7 @@ static int filesystem_iterator_frame_push( filesystem_iterator_entry *frame_entry) { filesystem_iterator_frame *new_frame = NULL; - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; git_str root = GIT_STR_INIT; const char *path; filesystem_iterator_entry *entry; @@ -1361,7 +1361,7 @@ static int filesystem_iterator_frame_push( git_str_puts(&root, iter->root); if (git_str_oom(&root) || - git_path_validate_workdir_buf(iter->base.repo, &root) < 0) { + git_fs_path_validate_workdir_buf(iter->base.repo, &root) < 0) { error = -1; goto done; } @@ -1369,7 +1369,7 @@ static int filesystem_iterator_frame_push( new_frame->path_len = frame_entry ? frame_entry->path_len : 0; /* Any error here is equivalent to the dir not existing, skip over it */ - if ((error = git_path_diriter_init( + if ((error = git_fs_path_diriter_init( &diriter, root.ptr, iter->dirload_flags)) < 0) { error = GIT_ENOTFOUND; goto done; @@ -1387,12 +1387,12 @@ static int filesystem_iterator_frame_push( /* check if this directory is ignored */ filesystem_iterator_frame_push_ignores(iter, frame_entry, new_frame); - while ((error = git_path_diriter_next(&diriter)) == 0) { + while ((error = git_fs_path_diriter_next(&diriter)) == 0) { iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL; bool dir_expected = false; - if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || - (error = git_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) + if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || + (error = git_fs_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) goto done; GIT_ASSERT(path_len > iter->root_len); @@ -1414,7 +1414,7 @@ static int filesystem_iterator_frame_push( * we have an index, we can just copy the data out of it. */ - if ((error = git_path_diriter_stat(&statbuf, &diriter)) < 0) { + if ((error = git_fs_path_diriter_stat(&statbuf, &diriter)) < 0) { /* file was removed between readdir and lstat */ if (error == GIT_ENOTFOUND) continue; @@ -1472,7 +1472,7 @@ done: git_array_pop(iter->frames); git_str_dispose(&root); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); return error; } @@ -1565,7 +1565,7 @@ static int filesystem_iterator_is_dir( } if ((error = git_str_joinpath(&fullpath, iter->root, entry->path)) < 0 || - (error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || + (error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || (error = p_stat(fullpath.ptr, &st)) < 0) goto done; @@ -1961,9 +1961,10 @@ static int iterator_for_filesystem( iter->index = index; iter->dirload_flags = - (iterator__ignore_case(&iter->base) ? GIT_PATH_DIR_IGNORE_CASE : 0) | + (iterator__ignore_case(&iter->base) ? + GIT_FS_PATH_DIR_IGNORE_CASE : 0) | (iterator__flag(&iter->base, PRECOMPOSE_UNICODE) ? - GIT_PATH_DIR_PRECOMPOSE_UNICODE : 0); + GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE : 0); if ((error = filesystem_iterator_init(iter)) < 0) goto on_error; @@ -2058,7 +2059,7 @@ static bool index_iterator_create_pseudotree( prev_path = iter->entry ? iter->entry->path : ""; /* determine if the new path is in a different directory from the old */ - common_len = git_path_common_dirlen(prev_path, path); + common_len = git_fs_path_common_dirlen(prev_path, path); relative_path = path + common_len; if ((dirsep = strchr(relative_path, '/')) == NULL) diff --git a/src/mailmap.c b/src/mailmap.c index 38ae01645..4fbb1ae77 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -9,7 +9,7 @@ #include "common.h" #include "config.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "signature.h" #include "git2/config.h" @@ -327,11 +327,11 @@ static int mailmap_add_file_ondisk( git_str content = GIT_STR_INIT; int error; - error = git_path_join_unrooted(&fullpath, path, base, NULL); + error = git_fs_path_join_unrooted(&fullpath, path, base, NULL); if (error < 0) goto cleanup; - error = git_path_validate_workdir_buf(repo, &fullpath); + error = git_fs_path_validate_workdir_buf(repo, &fullpath); if (error < 0) goto cleanup; diff --git a/src/merge.c b/src/merge.c index ae1d453ec..ec7e5bfd1 100644 --- a/src/merge.c +++ b/src/merge.c @@ -12,7 +12,7 @@ #include "repository.h" #include "revwalk.h" #include "commit_list.h" -#include "path.h" +#include "fs_path.h" #include "refs.h" #include "object.h" #include "iterator.h" diff --git a/src/midx.c b/src/midx.c index b8da98986..d4f9bd5a0 100644 --- a/src/midx.c +++ b/src/midx.c @@ -14,7 +14,7 @@ #include "hash.h" #include "odb.h" #include "pack.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "str.h" @@ -502,7 +502,7 @@ int git_midx_writer_new( git__free(w); return -1; } - git_path_squash_slashes(&w->pack_dir); + git_fs_path_squash_slashes(&w->pack_dir); if (git_vector_init(&w->packs, 0, packfile__cmp) < 0) { git_str_dispose(&w->pack_dir); @@ -537,7 +537,7 @@ int git_midx_writer_add( int error; struct git_pack_file *p; - error = git_path_prettify(&idx_path_buf, idx_path, git_str_cstr(&w->pack_dir)); + error = git_fs_path_prettify(&idx_path_buf, idx_path, git_str_cstr(&w->pack_dir)); if (error < 0) return error; @@ -687,7 +687,7 @@ static int midx_write( error = git_str_sets(&relative_index, p->pack_name); if (error < 0) goto cleanup; - error = git_path_make_relative(&relative_index, git_str_cstr(&w->pack_dir)); + error = git_fs_path_make_relative(&relative_index, git_str_cstr(&w->pack_dir)); if (error < 0) { git_str_dispose(&relative_index); goto cleanup; diff --git a/src/odb.c b/src/odb.c index 7bf575474..5bc69c3f6 100644 --- a/src/odb.c +++ b/src/odb.c @@ -277,7 +277,7 @@ int git_odb__hashlink(git_oid *out, const char *path) int size; int result; - if (git_path_lstat(path, &st) < 0) + if (git_fs_path_lstat(path, &st) < 0) return -1; if (!git__is_int(st.st_size) || (int)st.st_size < 0) { @@ -649,7 +649,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ if (git_str_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0) return -1; - if (git_path_exists(alternates_path.ptr) == false) { + if (git_fs_path_exists(alternates_path.ptr) == false) { git_str_dispose(&alternates_path); return 0; } diff --git a/src/odb_loose.c b/src/odb_loose.c index f0c3ac2c8..463e24fa5 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -87,7 +87,7 @@ static int object_file_name( return -1; git_str_set(name, be->objects_dir, be->objects_dirlen); - git_path_to_dir(name); + git_fs_path_to_dir(name); /* loose object filename: aa/aaa... (41 bytes) */ git_oid_pathfmt(name->ptr + name->size, id); @@ -452,7 +452,7 @@ static int locate_object( { int error = object_file_name(object_location, backend, oid); - if (!error && !git_path_exists(object_location->ptr)) + if (!error && !git_fs_path_exists(object_location->ptr)) return GIT_ENOTFOUND; return error; @@ -467,7 +467,7 @@ static int fn_locate_object_short_oid(void *state, git_str *pathbuf) { return 0; } - if (git_path_isdir(pathbuf->ptr) == false) { + if (git_fs_path_isdir(pathbuf->ptr) == false) { /* We are already in the directory matching the 2 first hex characters, * compare the first ncmp characters of the oids */ if (!memcmp(sstate->short_oid + 2, @@ -509,7 +509,7 @@ static int locate_object_short_oid( return -1; git_str_set(object_location, objects_dir, dir_len); - git_path_to_dir(object_location); + git_fs_path_to_dir(object_location); /* save adjusted position at end of dir so it can be restored later */ dir_len = git_str_len(object_location); @@ -523,7 +523,7 @@ static int locate_object_short_oid( object_location->ptr[object_location->size - 1] = '/'; /* Check that directory exists */ - if (git_path_isdir(object_location->ptr) == false) + if (git_fs_path_isdir(object_location->ptr) == false) return git_odb__error_notfound("no matching loose object for prefix", short_oid, len); @@ -532,7 +532,7 @@ static int locate_object_short_oid( state.found = 0; /* Explore directory to find a unique object matching short_oid */ - error = git_path_direach( + error = git_fs_path_direach( object_location, 0, fn_locate_object_short_oid, &state); if (error < 0 && error != GIT_EAMBIGUOUS) return error; @@ -753,10 +753,10 @@ static int foreach_cb(void *_state, git_str *path) struct foreach_state *state = (struct foreach_state *) _state; /* non-dir is some stray file, ignore it */ - if (!git_path_isdir(git_str_cstr(path))) + if (!git_fs_path_isdir(git_str_cstr(path))) return 0; - return git_path_direach(path, 0, foreach_object_dir_cb, state); + return git_fs_path_direach(path, 0, foreach_object_dir_cb, state); } static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data) @@ -773,7 +773,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb objects_dir = backend->objects_dir; git_str_sets(&buf, objects_dir); - git_path_to_dir(&buf); + git_fs_path_to_dir(&buf); if (git_str_oom(&buf)) return -1; @@ -782,7 +782,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb state.data = data; state.dir_len = git_str_len(&buf); - error = git_path_direach(&buf, 0, foreach_cb, &state); + error = git_fs_path_direach(&buf, 0, foreach_cb, &state); git_str_dispose(&buf); diff --git a/src/odb_pack.c b/src/odb_pack.c index f2c47adbe..5b7521029 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -524,7 +524,7 @@ static int pack_backend__refresh(git_odb_backend *backend_) /* reload all packs */ git_str_sets(&path, backend->pack_folder); - error = git_path_direach(&path, 0, packfile_load__cb, backend); + error = git_fs_path_direach(&path, 0, packfile_load__cb, backend); git_str_dispose(&path); git_vector_sort(&backend->packs); @@ -750,7 +750,7 @@ static int get_idx_path( size_t path_len; int error; - error = git_path_prettify(idx_path, p->pack_name, backend->pack_folder); + error = git_fs_path_prettify(idx_path, p->pack_name, backend->pack_folder); if (error < 0) return error; path_len = git_str_len(idx_path); @@ -902,7 +902,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) return -1; if (!(error = git_str_joinpath(&path, objects_dir, "pack")) && - git_path_isdir(git_str_cstr(&path))) + git_fs_path_isdir(git_str_cstr(&path))) { backend->pack_folder = git_str_detach(&path); error = pack_backend__refresh((git_odb_backend *)backend); diff --git a/src/pack.c b/src/pack.c index e17d20f8c..5c0cba7e8 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1198,7 +1198,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) if (!git_disable_pack_keep_file_checks) { memcpy(p->pack_name + root_len, ".keep", sizeof(".keep")); - if (git_path_exists(p->pack_name) == true) + if (git_fs_path_exists(p->pack_name) == true) p->pack_keep = 1; } diff --git a/src/patch_parse.c b/src/patch_parse.c index fce4bc9e4..891cf79a3 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -10,7 +10,7 @@ #include "git2/patch.h" #include "patch.h" #include "diff_parse.h" -#include "path.h" +#include "fs_path.h" typedef struct { git_patch base; @@ -80,7 +80,7 @@ static int parse_header_path_buf(git_str *path, git_patch_parse_ctx *ctx, size_t (error = git_str_unquote(path)) < 0) return error; - git_path_squash_slashes(path); + git_fs_path_squash_slashes(path); if (!path->size) return git_parse_err("patch contains empty path at line %"PRIuZ, diff --git a/src/path.c b/src/path.c index d8d33a141..d34125128 100644 --- a/src/path.c +++ b/src/path.c @@ -7,1555 +7,14 @@ #include "path.h" -#include "posix.h" #include "repository.h" -#ifdef GIT_WIN32 -#include "win32/posix.h" -#include "win32/w32_buffer.h" -#include "win32/w32_util.h" -#include "win32/version.h" -#include -#else -#include -#endif -#include -#include - -static int dos_drive_prefix_length(const char *path) -{ - int i; - - /* - * Does it start with an ASCII letter (i.e. highest bit not set), - * followed by a colon? - */ - if (!(0x80 & (unsigned char)*path)) - return *path && path[1] == ':' ? 2 : 0; - - /* - * While drive letters must be letters of the English alphabet, it is - * possible to assign virtually _any_ Unicode character via `subst` as - * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff - * like this: - * - * subst ֍: %USERPROFILE%\Desktop - */ - for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++) - ; /* skip first UTF-8 character */ - return path[i] == ':' ? i + 1 : 0; -} - -#ifdef GIT_WIN32 -static bool looks_like_network_computer_name(const char *path, int pos) -{ - if (pos < 3) - return false; - - if (path[0] != '/' || path[1] != '/') - return false; - - while (pos-- > 2) { - if (path[pos] == '/') - return false; - } - - return true; -} -#endif - -/* - * Based on the Android implementation, BSD licensed. - * http://android.git.kernel.org/ - * - * Copyright (C) 2008 The Android Open Source Project - * 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. - * - * 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. - */ -int git_path_basename_r(git_str *buffer, const char *path) -{ - const char *endp, *startp; - int len, result; - - /* Empty or NULL string gets treated as "." */ - if (path == NULL || *path == '\0') { - startp = "."; - len = 1; - goto Exit; - } - - /* Strip trailing slashes */ - endp = path + strlen(path) - 1; - while (endp > path && *endp == '/') - endp--; - - /* All slashes becomes "/" */ - if (endp == path && *endp == '/') { - startp = "/"; - len = 1; - goto Exit; - } - - /* Find the start of the base */ - startp = endp; - while (startp > path && *(startp - 1) != '/') - startp--; - - /* Cast is safe because max path < max int */ - len = (int)(endp - startp + 1); - -Exit: - result = len; - - if (buffer != NULL && git_str_set(buffer, startp, len) < 0) - return -1; - - return result; -} - -/* - * Determine if the path is a Windows prefix and, if so, returns - * its actual lentgh. If it is not a prefix, returns -1. - */ -static int win32_prefix_length(const char *path, int len) -{ -#ifndef GIT_WIN32 - GIT_UNUSED(path); - GIT_UNUSED(len); -#else - /* - * Mimic unix behavior where '/.git' returns '/': 'C:/.git' - * will return 'C:/' here - */ - if (dos_drive_prefix_length(path) == len) - return len; - - /* - * Similarly checks if we're dealing with a network computer name - * '//computername/.git' will return '//computername/' - */ - if (looks_like_network_computer_name(path, len)) - return len; -#endif - - return -1; -} - -/* - * Based on the Android implementation, BSD licensed. - * Check http://android.git.kernel.org/ - */ -int git_path_dirname_r(git_str *buffer, const char *path) -{ - const char *endp; - int is_prefix = 0, len; - - /* Empty or NULL string gets treated as "." */ - if (path == NULL || *path == '\0') { - path = "."; - len = 1; - goto Exit; - } - - /* Strip trailing slashes */ - endp = path + strlen(path) - 1; - while (endp > path && *endp == '/') - endp--; - - if (endp - path + 1 > INT_MAX) { - git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; - } - - if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { - is_prefix = 1; - goto Exit; - } - - /* Find the start of the dir */ - while (endp > path && *endp != '/') - endp--; - - /* Either the dir is "/" or there are no slashes */ - if (endp == path) { - path = (*endp == '/') ? "/" : "."; - len = 1; - goto Exit; - } - - do { - endp--; - } while (endp > path && *endp == '/'); - - if (endp - path + 1 > INT_MAX) { - git_error_set(GIT_ERROR_INVALID, "path too long"); - len = -1; - goto Exit; - } - - if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) { - is_prefix = 1; - goto Exit; - } - - /* Cast is safe because max path < max int */ - len = (int)(endp - path + 1); - -Exit: - if (buffer) { - if (git_str_set(buffer, path, len) < 0) - return -1; - if (is_prefix && git_str_putc(buffer, '/') < 0) - return -1; - } - - return len; -} - - -char *git_path_dirname(const char *path) -{ - git_str buf = GIT_STR_INIT; - char *dirname; - - git_path_dirname_r(&buf, path); - dirname = git_str_detach(&buf); - git_str_dispose(&buf); /* avoid memleak if error occurs */ - - return dirname; -} - -char *git_path_basename(const char *path) -{ - git_str buf = GIT_STR_INIT; - char *basename; - - git_path_basename_r(&buf, path); - basename = git_str_detach(&buf); - git_str_dispose(&buf); /* avoid memleak if error occurs */ - - return basename; -} - -size_t git_path_basename_offset(git_str *buffer) -{ - ssize_t slash; - - if (!buffer || buffer->size <= 0) - return 0; - - slash = git_str_rfind_next(buffer, '/'); - - if (slash >= 0 && buffer->ptr[slash] == '/') - return (size_t)(slash + 1); - - return 0; -} - -int git_path_root(const char *path) -{ - int offset = 0, prefix_len; - - /* Does the root of the path look like a windows drive ? */ - if ((prefix_len = dos_drive_prefix_length(path))) - offset += prefix_len; - -#ifdef GIT_WIN32 - /* Are we dealing with a windows network path? */ - else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') || - (path[0] == '\\' && path[1] == '\\' && path[2] != '\\')) - { - offset += 2; - - /* Skip the computer name segment */ - while (path[offset] && path[offset] != '/' && path[offset] != '\\') - offset++; - } - - if (path[offset] == '\\') - return offset; -#endif - - if (path[offset] == '/') - return offset; - - return -1; /* Not a real error - signals that path is not rooted */ -} - -static void path_trim_slashes(git_str *path) -{ - int ceiling = git_path_root(path->ptr) + 1; - - if (ceiling < 0) - return; - - while (path->size > (size_t)ceiling) { - if (path->ptr[path->size-1] != '/') - break; - - path->ptr[path->size-1] = '\0'; - path->size--; - } -} - -int git_path_join_unrooted( - git_str *path_out, const char *path, const char *base, ssize_t *root_at) -{ - ssize_t root; - - GIT_ASSERT_ARG(path_out); - GIT_ASSERT_ARG(path); - - root = (ssize_t)git_path_root(path); - - if (base != NULL && root < 0) { - if (git_str_joinpath(path_out, base, path) < 0) - return -1; - - root = (ssize_t)strlen(base); - } else { - if (git_str_sets(path_out, path) < 0) - return -1; - - if (root < 0) - root = 0; - else if (base) - git_path_equal_or_prefixed(base, path, &root); - } - - if (root_at) - *root_at = root; - - return 0; -} - -void git_path_squash_slashes(git_str *path) -{ - char *p, *q; - - if (path->size == 0) - return; - - for (p = path->ptr, q = path->ptr; *q; p++, q++) { - *p = *q; - - while (*q == '/' && *(q+1) == '/') { - path->size--; - q++; - } - } - - *p = '\0'; -} - -int git_path_prettify(git_str *path_out, const char *path, const char *base) -{ - char buf[GIT_PATH_MAX]; - - GIT_ASSERT_ARG(path_out); - GIT_ASSERT_ARG(path); - - /* construct path if needed */ - if (base != NULL && git_path_root(path) < 0) { - if (git_str_joinpath(path_out, base, path) < 0) - return -1; - path = path_out->ptr; - } - - if (p_realpath(path, buf) == NULL) { - /* git_error_set resets the errno when dealing with a GIT_ERROR_OS kind of error */ - int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1; - git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path); - - git_str_clear(path_out); - - return error; - } - - return git_str_sets(path_out, buf); -} - -int git_path_prettify_dir(git_str *path_out, const char *path, const char *base) -{ - int error = git_path_prettify(path_out, path, base); - return (error < 0) ? error : git_path_to_dir(path_out); -} - -int git_path_to_dir(git_str *path) -{ - if (path->asize > 0 && - git_str_len(path) > 0 && - path->ptr[git_str_len(path) - 1] != '/') - git_str_putc(path, '/'); - - return git_str_oom(path) ? -1 : 0; -} - -void git_path_string_to_dir(char *path, size_t size) -{ - size_t end = strlen(path); - - if (end && path[end - 1] != '/' && end < size) { - path[end] = '/'; - path[end + 1] = '\0'; - } -} - -int git__percent_decode(git_str *decoded_out, const char *input) -{ - int len, hi, lo, i; - - GIT_ASSERT_ARG(decoded_out); - GIT_ASSERT_ARG(input); - - len = (int)strlen(input); - git_str_clear(decoded_out); - - for(i = 0; i < len; i++) - { - char c = input[i]; - - if (c != '%') - goto append; - - if (i >= len - 2) - goto append; - - hi = git__fromhex(input[i + 1]); - lo = git__fromhex(input[i + 2]); - - if (hi < 0 || lo < 0) - goto append; - - c = (char)(hi << 4 | lo); - i += 2; - -append: - if (git_str_putc(decoded_out, c) < 0) - return -1; - } - - return 0; -} - -static int error_invalid_local_file_uri(const char *uri) -{ - git_error_set(GIT_ERROR_CONFIG, "'%s' is not a valid local file URI", uri); - return -1; -} - -static int local_file_url_prefixlen(const char *file_url) -{ - int len = -1; - - if (git__prefixcmp(file_url, "file://") == 0) { - if (file_url[7] == '/') - len = 8; - else if (git__prefixcmp(file_url + 7, "localhost/") == 0) - len = 17; - } - - return len; -} - -bool git_path_is_local_file_url(const char *file_url) -{ - return (local_file_url_prefixlen(file_url) > 0); -} - -int git_path_fromurl(git_str *local_path_out, const char *file_url) -{ - int offset; - - GIT_ASSERT_ARG(local_path_out); - GIT_ASSERT_ARG(file_url); - - if ((offset = local_file_url_prefixlen(file_url)) < 0 || - file_url[offset] == '\0' || file_url[offset] == '/') - return error_invalid_local_file_uri(file_url); - -#ifndef GIT_WIN32 - offset--; /* A *nix absolute path starts with a forward slash */ -#endif - - git_str_clear(local_path_out); - return git__percent_decode(local_path_out, file_url + offset); -} - -int git_path_walk_up( - git_str *path, - const char *ceiling, - int (*cb)(void *data, const char *), - void *data) -{ - int error = 0; - git_str iter; - ssize_t stop = 0, scan; - char oldc = '\0'; - - GIT_ASSERT_ARG(path); - GIT_ASSERT_ARG(cb); - - if (ceiling != NULL) { - if (git__prefixcmp(path->ptr, ceiling) == 0) - stop = (ssize_t)strlen(ceiling); - else - stop = git_str_len(path); - } - scan = git_str_len(path); - - /* empty path: yield only once */ - if (!scan) { - error = cb(data, ""); - if (error) - git_error_set_after_callback(error); - return error; - } - - iter.ptr = path->ptr; - iter.size = git_str_len(path); - iter.asize = path->asize; - - while (scan >= stop) { - error = cb(data, iter.ptr); - iter.ptr[scan] = oldc; - - if (error) { - git_error_set_after_callback(error); - break; - } - - scan = git_str_rfind_next(&iter, '/'); - if (scan >= 0) { - scan++; - oldc = iter.ptr[scan]; - iter.size = scan; - iter.ptr[scan] = '\0'; - } - } - - if (scan >= 0) - iter.ptr[scan] = oldc; - - /* relative path: yield for the last component */ - if (!error && stop == 0 && iter.ptr[0] != '/') { - error = cb(data, ""); - if (error) - git_error_set_after_callback(error); - } - - return error; -} - -bool git_path_exists(const char *path) -{ - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - return p_access(path, F_OK) == 0; -} - -bool git_path_isdir(const char *path) -{ - struct stat st; - if (p_stat(path, &st) < 0) - return false; - - return S_ISDIR(st.st_mode) != 0; -} - -bool git_path_isfile(const char *path) -{ - struct stat st; - - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - if (p_stat(path, &st) < 0) - return false; - - return S_ISREG(st.st_mode) != 0; -} - -bool git_path_islink(const char *path) -{ - struct stat st; - - GIT_ASSERT_ARG_WITH_RETVAL(path, false); - if (p_lstat(path, &st) < 0) - return false; - - return S_ISLNK(st.st_mode) != 0; -} - -#ifdef GIT_WIN32 - -bool git_path_is_empty_dir(const char *path) -{ - git_win32_path filter_w; - bool empty = false; - - if (git_win32__findfirstfile_filter(filter_w, path)) { - WIN32_FIND_DATAW findData; - HANDLE hFind = FindFirstFileW(filter_w, &findData); - - /* FindFirstFile will fail if there are no children to the given - * path, which can happen if the given path is a file (and obviously - * has no children) or if the given path is an empty mount point. - * (Most directories have at least directory entries '.' and '..', - * but ridiculously another volume mounted in another drive letter's - * path space do not, and thus have nothing to enumerate.) If - * FindFirstFile fails, check if this is a directory-like thing - * (a mount point). - */ - if (hFind == INVALID_HANDLE_VALUE) - return git_path_isdir(path); - - /* If the find handle was created successfully, then it's a directory */ - empty = true; - - do { - /* Allow the enumeration to return . and .. and still be considered - * empty. In the special case of drive roots (i.e. C:\) where . and - * .. do not occur, we can still consider the path to be an empty - * directory if there's nothing there. */ - if (!git_path_is_dot_or_dotdotW(findData.cFileName)) { - empty = false; - break; - } - } while (FindNextFileW(hFind, &findData)); - - FindClose(hFind); - } - - return empty; -} - -#else - -static int path_found_entry(void *payload, git_str *path) -{ - GIT_UNUSED(payload); - return !git_path_is_dot_or_dotdot(path->ptr); -} - -bool git_path_is_empty_dir(const char *path) -{ - int error; - git_str dir = GIT_STR_INIT; - - if (!git_path_isdir(path)) - return false; - - if ((error = git_str_sets(&dir, path)) != 0) - git_error_clear(); - else - error = git_path_direach(&dir, 0, path_found_entry, NULL); - - git_str_dispose(&dir); - - return !error; -} - -#endif - -int git_path_set_error(int errno_value, const char *path, const char *action) -{ - switch (errno_value) { - case ENOENT: - case ENOTDIR: - git_error_set(GIT_ERROR_OS, "could not find '%s' to %s", path, action); - return GIT_ENOTFOUND; - - case EINVAL: - case ENAMETOOLONG: - git_error_set(GIT_ERROR_OS, "invalid path for filesystem '%s'", path); - return GIT_EINVALIDSPEC; - - case EEXIST: - git_error_set(GIT_ERROR_OS, "failed %s - '%s' already exists", action, path); - return GIT_EEXISTS; - - case EACCES: - git_error_set(GIT_ERROR_OS, "failed %s - '%s' is locked", action, path); - return GIT_ELOCKED; - - default: - git_error_set(GIT_ERROR_OS, "could not %s '%s'", action, path); - return -1; - } -} - -int git_path_lstat(const char *path, struct stat *st) -{ - if (p_lstat(path, st) == 0) - return 0; - - return git_path_set_error(errno, path, "stat"); -} - -static bool _check_dir_contents( - git_str *dir, - const char *sub, - bool (*predicate)(const char *)) -{ - bool result; - size_t dir_size = git_str_len(dir); - size_t sub_size = strlen(sub); - size_t alloc_size; - - /* leave base valid even if we could not make space for subdir */ - if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) || - GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) || - git_str_try_grow(dir, alloc_size, false) < 0) - return false; - - /* save excursion */ - if (git_str_joinpath(dir, dir->ptr, sub) < 0) - return false; - - result = predicate(dir->ptr); - - /* restore path */ - git_str_truncate(dir, dir_size); - return result; -} - -bool git_path_contains(git_str *dir, const char *item) -{ - return _check_dir_contents(dir, item, &git_path_exists); -} - -bool git_path_contains_dir(git_str *base, const char *subdir) -{ - return _check_dir_contents(base, subdir, &git_path_isdir); -} - -bool git_path_contains_file(git_str *base, const char *file) -{ - return _check_dir_contents(base, file, &git_path_isfile); -} - -int git_path_find_dir(git_str *dir) -{ - int error = 0; - char buf[GIT_PATH_MAX]; - - if (p_realpath(dir->ptr, buf) != NULL) - error = git_str_sets(dir, buf); - - /* call dirname if this is not a directory */ - if (!error) /* && git_path_isdir(dir->ptr) == false) */ - error = (git_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0; - - if (!error) - error = git_path_to_dir(dir); - - return error; -} - -int git_path_resolve_relative(git_str *path, size_t ceiling) -{ - char *base, *to, *from, *next; - size_t len; - - GIT_ERROR_CHECK_ALLOC_STR(path); - - if (ceiling > path->size) - ceiling = path->size; - - /* recognize drive prefixes, etc. that should not be backed over */ - if (ceiling == 0) - ceiling = git_path_root(path->ptr) + 1; - - /* recognize URL prefixes that should not be backed over */ - if (ceiling == 0) { - for (next = path->ptr; *next && git__isalpha(*next); ++next); - if (next[0] == ':' && next[1] == '/' && next[2] == '/') - ceiling = (next + 3) - path->ptr; - } - - base = to = from = path->ptr + ceiling; - - while (*from) { - for (next = from; *next && *next != '/'; ++next); - - len = next - from; - - if (len == 1 && from[0] == '.') - /* do nothing with singleton dot */; - - else if (len == 2 && from[0] == '.' && from[1] == '.') { - /* error out if trying to up one from a hard base */ - if (to == base && ceiling != 0) { - git_error_set(GIT_ERROR_INVALID, - "cannot strip root component off url"); - return -1; - } - - /* no more path segments to strip, - * use '../' as a new base path */ - if (to == base) { - if (*next == '/') - len++; - - if (to != from) - memmove(to, from, len); - - to += len; - /* this is now the base, can't back up from a - * relative prefix */ - base = to; - } else { - /* back up a path segment */ - while (to > base && to[-1] == '/') to--; - while (to > base && to[-1] != '/') to--; - } - } else { - if (*next == '/' && *from != '/') - len++; - - if (to != from) - memmove(to, from, len); - - to += len; - } - - from += len; - - while (*from == '/') from++; - } - - *to = '\0'; - - path->size = to - path->ptr; - - return 0; -} - -int git_path_apply_relative(git_str *target, const char *relpath) -{ - return git_str_joinpath(target, git_str_cstr(target), relpath) || - git_path_resolve_relative(target, 0); -} - -int git_path_cmp( - const char *name1, size_t len1, int isdir1, - const char *name2, size_t len2, int isdir2, - int (*compare)(const char *, const char *, size_t)) -{ - unsigned char c1, c2; - size_t len = len1 < len2 ? len1 : len2; - int cmp; - - cmp = compare(name1, name2, len); - if (cmp) - return cmp; - - c1 = name1[len]; - c2 = name2[len]; - - if (c1 == '\0' && isdir1) - c1 = '/'; - - if (c2 == '\0' && isdir2) - c2 = '/'; - - return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0; -} - -size_t git_path_common_dirlen(const char *one, const char *two) -{ - const char *p, *q, *dirsep = NULL; - - for (p = one, q = two; *p && *q; p++, q++) { - if (*p == '/' && *q == '/') - dirsep = p; - else if (*p != *q) - break; - } - - return dirsep ? (dirsep - one) + 1 : 0; -} - -int git_path_make_relative(git_str *path, const char *parent) -{ - const char *p, *q, *p_dirsep, *q_dirsep; - size_t plen = path->size, newlen, alloclen, depth = 1, i, offset; - - for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) { - if (*p == '/' && *q == '/') { - p_dirsep = p; - q_dirsep = q; - } - else if (*p != *q) - break; - } - - /* need at least 1 common path segment */ - if ((p_dirsep == path->ptr || q_dirsep == parent) && - (*p_dirsep != '/' || *q_dirsep != '/')) { - git_error_set(GIT_ERROR_INVALID, - "%s is not a parent of %s", parent, path->ptr); - return GIT_ENOTFOUND; - } - - if (*p == '/' && !*q) - p++; - else if (!*p && *q == '/') - q++; - else if (!*p && !*q) - return git_str_clear(path), 0; - else { - p = p_dirsep + 1; - q = q_dirsep + 1; - } - - plen -= (p - path->ptr); - - if (!*q) - return git_str_set(path, p, plen); - - for (; (q = strchr(q, '/')) && *(q + 1); q++) - depth++; - - GIT_ERROR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3); - GIT_ERROR_CHECK_ALLOC_ADD(&newlen, newlen, plen); - - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, newlen, 1); - - /* save the offset as we might realllocate the pointer */ - offset = p - path->ptr; - if (git_str_try_grow(path, alloclen, 1) < 0) - return -1; - p = path->ptr + offset; - - memmove(path->ptr + (depth * 3), p, plen + 1); - - for (i = 0; i < depth; i++) - memcpy(path->ptr + (i * 3), "../", 3); - - path->size = newlen; - return 0; -} - -bool git_path_has_non_ascii(const char *path, size_t pathlen) -{ - const uint8_t *scan = (const uint8_t *)path, *end; - - for (end = scan + pathlen; scan < end; ++scan) - if (*scan & 0x80) - return true; - - return false; -} - -#ifdef GIT_USE_ICONV - -int git_path_iconv_init_precompose(git_path_iconv_t *ic) -{ - git_str_init(&ic->buf, 0); - ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); - return 0; -} - -void git_path_iconv_clear(git_path_iconv_t *ic) -{ - if (ic) { - if (ic->map != (iconv_t)-1) - iconv_close(ic->map); - git_str_dispose(&ic->buf); - } -} - -int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen) -{ - char *nfd = (char*)*in, *nfc; - size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv; - int retry = 1; - - if (!ic || ic->map == (iconv_t)-1 || - !git_path_has_non_ascii(*in, *inlen)) - return 0; - - git_str_clear(&ic->buf); - - while (1) { - GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1); - if (git_str_grow(&ic->buf, alloclen) < 0) - return -1; - - nfc = ic->buf.ptr + ic->buf.size; - nfclen = ic->buf.asize - ic->buf.size; - - rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen); - - ic->buf.size = (nfc - ic->buf.ptr); - - if (rv != (size_t)-1) - break; - - /* if we cannot convert the data (probably because iconv thinks - * it is not valid UTF-8 source data), then use original data - */ - if (errno != E2BIG) - return 0; - - /* make space for 2x the remaining data to be converted - * (with per retry overhead to avoid infinite loops) - */ - wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4); - - if (retry++ > 4) - goto fail; - } - - ic->buf.ptr[ic->buf.size] = '\0'; - - *in = ic->buf.ptr; - *inlen = ic->buf.size; - - return 0; - -fail: - git_error_set(GIT_ERROR_OS, "unable to convert unicode path data"); - return -1; -} - -static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX"; -static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX"; - -/* Check if the platform is decomposing unicode data for us. We will - * emulate core Git and prefer to use precomposed unicode data internally - * on these platforms, composing the decomposed unicode on the fly. - * - * This mainly happens on the Mac where HDFS stores filenames as - * decomposed unicode. Even on VFAT and SAMBA file systems, the Mac will - * return decomposed unicode from readdir() even when the actual - * filesystem is storing precomposed unicode. - */ -bool git_path_does_fs_decompose_unicode(const char *root) -{ - git_str path = GIT_STR_INIT; - int fd; - bool found_decomposed = false; - char tmp[6]; - - /* Create a file using a precomposed path and then try to find it - * using the decomposed name. If the lookup fails, then we will mark - * that we should precompose unicode for this repository. - */ - if (git_str_joinpath(&path, root, nfc_file) < 0 || - (fd = p_mkstemp(path.ptr)) < 0) - goto done; - p_close(fd); - - /* record trailing digits generated by mkstemp */ - memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp)); - - /* try to look up as NFD path */ - if (git_str_joinpath(&path, root, nfd_file) < 0) - goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - - found_decomposed = git_path_exists(path.ptr); - - /* remove temporary file (using original precomposed path) */ - if (git_str_joinpath(&path, root, nfc_file) < 0) - goto done; - memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp)); - - (void)p_unlink(path.ptr); - -done: - git_str_dispose(&path); - return found_decomposed; -} - -#else - -bool git_path_does_fs_decompose_unicode(const char *root) -{ - GIT_UNUSED(root); - return false; -} - -#endif - -#if defined(__sun) || defined(__GNU__) -typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1]; -#else -typedef struct dirent path_dirent_data; -#endif - -int git_path_direach( - git_str *path, - uint32_t flags, - int (*fn)(void *, git_str *), - void *arg) -{ - int error = 0; - ssize_t wd_len; - DIR *dir; - struct dirent *de; - -#ifdef GIT_USE_ICONV - git_path_iconv_t ic = GIT_PATH_ICONV_INIT; -#endif - - GIT_UNUSED(flags); - - if (git_path_to_dir(path) < 0) - return -1; - - wd_len = git_str_len(path); - - if ((dir = opendir(path->ptr)) == NULL) { - git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr); - if (errno == ENOENT) - return GIT_ENOTFOUND; - - return -1; - } - -#ifdef GIT_USE_ICONV - if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) - (void)git_path_iconv_init_precompose(&ic); -#endif - - while ((de = readdir(dir)) != NULL) { - const char *de_path = de->d_name; - size_t de_len = strlen(de_path); - - if (git_path_is_dot_or_dotdot(de_path)) - continue; - -#ifdef GIT_USE_ICONV - if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0) - break; -#endif - - if ((error = git_str_put(path, de_path, de_len)) < 0) - break; - - git_error_clear(); - error = fn(arg, path); - - git_str_truncate(path, wd_len); /* restore path */ - - /* Only set our own error if the callback did not set one already */ - if (error != 0) { - if (!git_error_last()) - git_error_set_after_callback(error); - - break; - } - } - - closedir(dir); - -#ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); -#endif - - return error; -} - -#if defined(GIT_WIN32) && !defined(__MINGW32__) - -/* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7 - * and better. - */ -#ifndef FIND_FIRST_EX_LARGE_FETCH -# define FIND_FIRST_EX_LARGE_FETCH 2 -#endif - -int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags) -{ - git_win32_path path_filter; +#include "fs_path.h" - static int is_win7_or_later = -1; - if (is_win7_or_later < 0) - is_win7_or_later = git_has_win32_version(6, 1, 0); - - GIT_ASSERT_ARG(diriter); - GIT_ASSERT_ARG(path); - - memset(diriter, 0, sizeof(git_path_diriter)); - diriter->handle = INVALID_HANDLE_VALUE; - - if (git_str_puts(&diriter->path_utf8, path) < 0) - return -1; - - path_trim_slashes(&diriter->path_utf8); - - if (diriter->path_utf8.size == 0) { - git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); - return -1; - } - - if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 || - !git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) { - git_error_set(GIT_ERROR_OS, "could not parse the directory path '%s'", path); - return -1; - } - - diriter->handle = FindFirstFileExW( - path_filter, - is_win7_or_later ? FindExInfoBasic : FindExInfoStandard, - &diriter->current, - FindExSearchNameMatch, - NULL, - is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0); - - if (diriter->handle == INVALID_HANDLE_VALUE) { - git_error_set(GIT_ERROR_OS, "could not open directory '%s'", path); - return -1; - } - - diriter->parent_utf8_len = diriter->path_utf8.size; - diriter->flags = flags; - return 0; -} - -static int diriter_update_paths(git_path_diriter *diriter) -{ - size_t filename_len, path_len; - - filename_len = wcslen(diriter->current.cFileName); - - if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) || - GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2)) - return -1; - - if (path_len > GIT_WIN_PATH_UTF16) { - git_error_set(GIT_ERROR_FILESYSTEM, - "invalid path '%.*ls\\%ls' (path too long)", - diriter->parent_len, diriter->path, diriter->current.cFileName); - return -1; - } - - diriter->path[diriter->parent_len] = L'\\'; - memcpy(&diriter->path[diriter->parent_len+1], - diriter->current.cFileName, filename_len * sizeof(wchar_t)); - diriter->path[path_len-1] = L'\0'; - - git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len); - - if (diriter->parent_utf8_len > 0 && - diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/') - git_str_putc(&diriter->path_utf8, '/'); - - git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len); - - if (git_str_oom(&diriter->path_utf8)) - return -1; - - return 0; -} - -int git_path_diriter_next(git_path_diriter *diriter) -{ - bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); - - do { - /* Our first time through, we already have the data from - * FindFirstFileW. Use it, otherwise get the next file. - */ - if (!diriter->needs_next) - diriter->needs_next = 1; - else if (!FindNextFileW(diriter->handle, &diriter->current)) - return GIT_ITEROVER; - } while (skip_dot && git_path_is_dot_or_dotdotW(diriter->current.cFileName)); - - if (diriter_update_paths(diriter) < 0) - return -1; - - return 0; -} - -int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - GIT_ASSERT(diriter->path_utf8.size > diriter->parent_utf8_len); - - *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1]; - *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1; - return 0; -} - -int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - - *out = diriter->path_utf8.ptr; - *out_len = diriter->path_utf8.size; - return 0; -} - -int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(diriter); - - return git_win32__file_attribute_to_stat(out, - (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current, - diriter->path); -} - -void git_path_diriter_free(git_path_diriter *diriter) -{ - if (diriter == NULL) - return; - - git_str_dispose(&diriter->path_utf8); - - if (diriter->handle != INVALID_HANDLE_VALUE) { - FindClose(diriter->handle); - diriter->handle = INVALID_HANDLE_VALUE; - } -} - -#else - -int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags) -{ - GIT_ASSERT_ARG(diriter); - GIT_ASSERT_ARG(path); - - memset(diriter, 0, sizeof(git_path_diriter)); - - if (git_str_puts(&diriter->path, path) < 0) - return -1; - - path_trim_slashes(&diriter->path); - - if (diriter->path.size == 0) { - git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path); - return -1; - } - - if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) { - git_str_dispose(&diriter->path); - - git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path); - return -1; - } - -#ifdef GIT_USE_ICONV - if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) - (void)git_path_iconv_init_precompose(&diriter->ic); -#endif - - diriter->parent_len = diriter->path.size; - diriter->flags = flags; - - return 0; -} - -int git_path_diriter_next(git_path_diriter *diriter) -{ - struct dirent *de; - const char *filename; - size_t filename_len; - bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT); - int error = 0; - - GIT_ASSERT_ARG(diriter); - - errno = 0; - - do { - if ((de = readdir(diriter->dir)) == NULL) { - if (!errno) - return GIT_ITEROVER; - - git_error_set(GIT_ERROR_OS, - "could not read directory '%s'", diriter->path.ptr); - return -1; - } - } while (skip_dot && git_path_is_dot_or_dotdot(de->d_name)); - - filename = de->d_name; - filename_len = strlen(filename); - -#ifdef GIT_USE_ICONV - if ((diriter->flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0 && - (error = git_path_iconv(&diriter->ic, &filename, &filename_len)) < 0) - return error; -#endif - - git_str_truncate(&diriter->path, diriter->parent_len); - - if (diriter->parent_len > 0 && - diriter->path.ptr[diriter->parent_len-1] != '/') - git_str_putc(&diriter->path, '/'); - - git_str_put(&diriter->path, filename, filename_len); - - if (git_str_oom(&diriter->path)) - return -1; - - return error; -} - -int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - GIT_ASSERT(diriter->path.size > diriter->parent_len); - - *out = &diriter->path.ptr[diriter->parent_len+1]; - *out_len = diriter->path.size - diriter->parent_len - 1; - return 0; -} - -int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(out_len); - GIT_ASSERT_ARG(diriter); - - *out = diriter->path.ptr; - *out_len = diriter->path.size; - return 0; -} - -int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter) -{ - GIT_ASSERT_ARG(out); - GIT_ASSERT_ARG(diriter); - - return git_path_lstat(diriter->path.ptr, out); -} - -void git_path_diriter_free(git_path_diriter *diriter) -{ - if (diriter == NULL) - return; - - if (diriter->dir) { - closedir(diriter->dir); - diriter->dir = NULL; - } - -#ifdef GIT_USE_ICONV - git_path_iconv_clear(&diriter->ic); -#endif - - git_str_dispose(&diriter->path); -} - -#endif - -int git_path_dirload( - git_vector *contents, - const char *path, - size_t prefix_len, - uint32_t flags) -{ - git_path_diriter iter = GIT_PATH_DIRITER_INIT; - const char *name; - size_t name_len; - char *dup; - int error; - - GIT_ASSERT_ARG(contents); - GIT_ASSERT_ARG(path); - - if ((error = git_path_diriter_init(&iter, path, flags)) < 0) - return error; - - while ((error = git_path_diriter_next(&iter)) == 0) { - if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0) - break; - - GIT_ASSERT(name_len > prefix_len); - - dup = git__strndup(name + prefix_len, name_len - prefix_len); - GIT_ERROR_CHECK_ALLOC(dup); - - if ((error = git_vector_insert(contents, dup)) < 0) - break; - } - - if (error == GIT_ITEROVER) - error = 0; - - git_path_diriter_free(&iter); - return error; -} - -int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path) -{ - if (git_path_is_local_file_url(url_or_path)) - return git_path_fromurl(local_path_out, url_or_path); - else - return git_str_sets(local_path_out, url_or_path); -} - -/* Reject paths like AUX or COM1, or those versions that end in a dot or - * colon. ("AUX." or "AUX:") - */ -GIT_INLINE(bool) verify_dospath( - const char *component, - size_t len, - const char dospath[3], - bool trailing_num) -{ - size_t last = trailing_num ? 4 : 3; - - if (len < last || git__strncasecmp(component, dospath, 3) != 0) - return true; - - if (trailing_num && (component[3] < '1' || component[3] > '9')) - return true; - - return (len > last && - component[last] != '.' && - component[last] != ':'); -} +typedef struct { + git_repository *repo; + uint16_t file_mode; + unsigned int flags; +} repository_path_validate_data; static int32_t next_hfs_char(const char **in, size_t *len) { @@ -1598,7 +57,11 @@ static int32_t next_hfs_char(const char **in, size_t *len) return 0; /* NULL byte -- end of string */ } -static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len) +static bool validate_dotgit_hfs_generic( + const char *path, + size_t len, + const char *needle, + size_t needle_len) { size_t i; char c; @@ -1618,12 +81,15 @@ static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char * return false; } -static bool verify_dotgit_hfs(const char *path, size_t len) +static bool validate_dotgit_hfs(const char *path, size_t len) { - return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git")); + return validate_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_INLINE(bool) validate_dotgit_ntfs( + git_repository *repo, + const char *path, + size_t len) { git_str *reserved = git_repository__reserved_names_win32; size_t reserved_len = git_repository__reserved_names_win32_len; @@ -1685,7 +151,12 @@ GIT_INLINE(bool) ntfs_end_of_filename(const char *path) 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) +GIT_INLINE(bool) validate_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; @@ -1722,33 +193,6 @@ GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const return !ntfs_end_of_filename(name + i); } -GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags) -{ - if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\') - return false; - - if ((flags & GIT_PATH_REJECT_SLASH) && c == '/') - return false; - - if (flags & GIT_PATH_REJECT_NT_CHARS) { - if (c < 32) - return false; - - switch (c) { - case '<': - case '>': - case ':': - case '"': - case '|': - case '?': - case '*': - return false; - } - } - - return true; -} - /* * Return the length of the common prefix between str and prefix, comparing them * case-insensitively (must be ASCII to match). @@ -1757,7 +201,7 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char * { size_t count = 0; - while (len >0 && tolower(*str) == tolower(*prefix)) { + while (len > 0 && tolower(*str) == tolower(*prefix)) { count++; str++; prefix++; @@ -1767,72 +211,37 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char * 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 - * be handled by tools that use the non-\\?\ APIs, we don't want slashes - * or double slashes at the end of paths that can make them ambiguous. - * - * For checkout, we don't want to recurse into ".git" either. - */ -static bool verify_component( - git_repository *repo, +static bool validate_repo_component( const char *component, size_t len, - uint16_t mode, - unsigned int flags) + void *payload) { - if (len == 0) - return false; - - if ((flags & GIT_PATH_REJECT_TRAVERSAL) && - len == 1 && component[0] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAVERSAL) && - len == 2 && component[0] == '.' && component[1] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_DOT) && component[len-1] == '.') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_SPACE) && component[len-1] == ' ') - return false; - - if ((flags & GIT_PATH_REJECT_TRAILING_COLON) && component[len-1] == ':') - return false; + repository_path_validate_data *data = (repository_path_validate_data *)payload; - if (flags & GIT_PATH_REJECT_DOS_PATHS) { - if (!verify_dospath(component, len, "CON", false) || - !verify_dospath(component, len, "PRN", false) || - !verify_dospath(component, len, "AUX", false) || - !verify_dospath(component, len, "NUL", false) || - !verify_dospath(component, len, "COM", true) || - !verify_dospath(component, len, "LPT", true)) + if (data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) { + if (!validate_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_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)) + if (S_ISLNK(data->file_mode) && + git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)) return false; } - if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) { - if (!verify_dotgit_ntfs(repo, component, len)) + if (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) { + if (!validate_dotgit_ntfs(data->repo, component, len)) return false; - if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS)) + + if (S_ISLNK(data->file_mode) && + git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS)) 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)) { + if ((data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 && + (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 && + (data->flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) { if (len >= 4 && component[0] == '.' && (component[1] == 'g' || component[1] == 'G') && @@ -1841,10 +250,11 @@ static bool verify_component( if (len == 4) return false; - if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len) + if (S_ISLNK(data->file_mode) && + common_prefix_icase(component, len, ".gitmodules") == len) return false; } - } + } return true; } @@ -1878,90 +288,20 @@ GIT_INLINE(unsigned int) dotgit_flags( bool git_path_validate( git_repository *repo, const char *path, - uint16_t mode, + uint16_t file_mode, unsigned int flags) { - const char *start, *c; + repository_path_validate_data data = {0}; /* Upgrade the ".git" checks based on platform */ if ((flags & GIT_PATH_REJECT_DOT_GIT)) flags = dotgit_flags(repo, flags); - for (start = c = path; *c; c++) { - if (!verify_char(*c, flags)) - return false; - - if (*c == '/') { - if (!verify_component(repo, start, (c - start), mode, flags)) - return false; - - start = c+1; - } - } - - return verify_component(repo, start, (c - start), mode, flags); -} - -#ifdef GIT_WIN32 -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - int longpaths = 0; - - if (repo && - git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) - longpaths = 0; - - return (longpaths == 0); -} - -#else - -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - GIT_UNUSED(repo); - - return false; -} -#endif - -int git_path_validate_workdir(git_repository *repo, const char *path) -{ - if (should_validate_longpaths(repo)) - return git_path_validate_filesystem(path, strlen(path)); - - return 0; -} - -int git_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len) -{ - if (should_validate_longpaths(repo)) - return git_path_validate_filesystem(path, path_len); - - return 0; -} - -int git_path_validate_workdir_buf(git_repository *repo, git_str *path) -{ - return git_path_validate_workdir_with_len(repo, path->ptr, path->size); -} - -int git_path_normalize_slashes(git_str *out, const char *path) -{ - int error; - char *p; - - if ((error = git_str_puts(out, path)) < 0) - return error; - - for (p = out->ptr; *p; p++) { - if (*p == '\\') - *p = '/'; - } + data.repo = repo; + data.file_mode = file_mode; + data.flags = flags; - return 0; + return git_fs_path_validate_ext(path, flags, NULL, validate_repo_component, &data); } static const struct { @@ -1974,7 +314,11 @@ static const struct { { "gitattributes", "gi7d29", CONST_STRLEN("gitattributes") } }; -extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs) +extern int git_path_is_gitfile( + const char *path, + size_t pathlen, + git_path_gitfile gitfile, + git_path_fs fs) { const char *file, *hash; size_t filelen; @@ -1990,112 +334,15 @@ extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfil switch (fs) { case GIT_PATH_FS_GENERIC: - return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) || - !verify_dotgit_hfs_generic(path, pathlen, file, filelen); + return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) || + !validate_dotgit_hfs_generic(path, pathlen, file, filelen); case GIT_PATH_FS_NTFS: - return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash); + return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash); case GIT_PATH_FS_HFS: - return !verify_dotgit_hfs_generic(path, pathlen, file, filelen); + return !validate_dotgit_hfs_generic(path, pathlen, file, filelen); default: git_error_set(GIT_ERROR_OS, "invalid filesystem for path validation"); return -1; } } -bool git_path_supports_symlinks(const char *dir) -{ - git_str path = GIT_STR_INIT; - bool supported = false; - struct stat st; - int fd; - - if ((fd = git_futils_mktmp(&path, dir, 0666)) < 0 || - p_close(fd) < 0 || - p_unlink(path.ptr) < 0 || - p_symlink("testing", path.ptr) < 0 || - p_lstat(path.ptr, &st) < 0) - goto done; - - supported = (S_ISLNK(st.st_mode) != 0); -done: - if (path.size) - (void)p_unlink(path.ptr); - git_str_dispose(&path); - return supported; -} - -int git_path_validate_system_file_ownership(const char *path) -{ -#ifndef GIT_WIN32 - GIT_UNUSED(path); - return GIT_OK; -#else - git_win32_path buf; - PSID owner_sid; - PSECURITY_DESCRIPTOR descriptor = NULL; - HANDLE token; - TOKEN_USER *info = NULL; - DWORD err, len; - int ret; - - if (git_win32_path_from_utf8(buf, path) < 0) - return -1; - - err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT, - OWNER_SECURITY_INFORMATION | - DACL_SECURITY_INFORMATION, - &owner_sid, NULL, NULL, NULL, &descriptor); - - if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { - ret = GIT_ENOTFOUND; - goto cleanup; - } - - if (err != ERROR_SUCCESS) { - git_error_set(GIT_ERROR_OS, "failed to get security information"); - ret = GIT_ERROR; - goto cleanup; - } - - if (!IsValidSid(owner_sid)) { - git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown"); - ret = GIT_ERROR; - goto cleanup; - } - - if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) || - IsWellKnownSid(owner_sid, WinLocalSystemSid)) { - ret = GIT_OK; - goto cleanup; - } - - /* Obtain current user's SID */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) && - !GetTokenInformation(token, TokenUser, NULL, 0, &len)) { - info = git__malloc(len); - GIT_ERROR_CHECK_ALLOC(info); - if (!GetTokenInformation(token, TokenUser, info, len, &len)) { - git__free(info); - info = NULL; - } - } - - /* - * If the file is owned by the same account that is running the current - * process, it's okay to read from that file. - */ - if (info && EqualSid(owner_sid, info->User.Sid)) - ret = GIT_OK; - else { - git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid"); - ret = GIT_ERROR; - } - git__free(info); - -cleanup: - if (descriptor) - LocalFree(descriptor); - - return ret; -#endif -} diff --git a/src/path.h b/src/path.h index 4074c3425..ca220d121 100644 --- a/src/path.h +++ b/src/path.h @@ -9,729 +9,26 @@ #include "common.h" -#include "posix.h" -#include "str.h" -#include "vector.h" +#include "fs_path.h" +#include -#include "git2/sys/path.h" +#define GIT_PATH_REJECT_DOT_GIT (GIT_FS_PATH_REJECT_MAX << 1) +#define GIT_PATH_REJECT_DOT_GIT_LITERAL (GIT_FS_PATH_REJECT_MAX << 2) +#define GIT_PATH_REJECT_DOT_GIT_HFS (GIT_FS_PATH_REJECT_MAX << 3) +#define GIT_PATH_REJECT_DOT_GIT_NTFS (GIT_FS_PATH_REJECT_MAX << 4) -/** - * Path manipulation utils - * - * These are path utilities that munge paths without actually - * looking at the real filesystem. - */ - -/* - * The dirname() function shall take a pointer to a character string - * that contains a pathname, and return a pointer to a string that is a - * pathname of the parent directory of that file. Trailing '/' characters - * in the path are not counted as part of the path. - * - * If path does not contain a '/', then dirname() shall return a pointer to - * the string ".". If path is a null pointer or points to an empty string, - * dirname() shall return a pointer to the string "." . - * - * The `git_path_dirname` implementation is thread safe. The returned - * string must be manually free'd. - * - * The `git_path_dirname_r` implementation writes the dirname to a `git_str` - * if the buffer pointer is not NULL. - * It returns an error code < 0 if there is an allocation error, otherwise - * the length of the dirname (which will be > 0). - */ -extern char *git_path_dirname(const char *path); -extern int git_path_dirname_r(git_str *buffer, const char *path); - -/* - * This function returns the basename of the file, which is the last - * part of its full name given by fname, with the drive letter and - * leading directories stripped off. For example, the basename of - * c:/foo/bar/file.ext is file.ext, and the basename of a:foo is foo. - * - * Trailing slashes and backslashes are significant: the basename of - * c:/foo/bar/ is an empty string after the rightmost slash. - * - * The `git_path_basename` implementation is thread safe. The returned - * string must be manually free'd. - * - * The `git_path_basename_r` implementation writes the basename to a `git_str`. - * It returns an error code < 0 if there is an allocation error, otherwise - * the length of the basename (which will be >= 0). - */ -extern char *git_path_basename(const char *path); -extern int git_path_basename_r(git_str *buffer, const char *path); - -/* Return the offset of the start of the basename. Unlike the other - * basename functions, this returns 0 if the path is empty. - */ -extern size_t git_path_basename_offset(git_str *buffer); - -/** - * Find offset to root of path if path has one. - * - * This will return a number >= 0 which is the offset to the start of the - * path, if the path is rooted (i.e. "/rooted/path" returns 0 and - * "c:/windows/rooted/path" returns 2). If the path is not rooted, this - * returns -1. - */ -extern int git_path_root(const char *path); - -/** - * Ensure path has a trailing '/'. - */ -extern int git_path_to_dir(git_str *path); - -/** - * Ensure string has a trailing '/' if there is space for it. - */ -extern void git_path_string_to_dir(char *path, size_t size); - -/** - * Taken from git.git; returns nonzero if the given path is "." or "..". - */ -GIT_INLINE(int) git_path_is_dot_or_dotdot(const char *name) -{ - return (name[0] == '.' && - (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0'))); -} - -#ifdef GIT_WIN32 -GIT_INLINE(int) git_path_is_dot_or_dotdotW(const wchar_t *name) -{ - return (name[0] == L'.' && - (name[1] == L'\0' || - (name[1] == L'.' && name[2] == L'\0'))); -} - -#define git_path_is_absolute(p) \ - (git__isalpha((p)[0]) && (p)[1] == ':' && ((p)[2] == '\\' || (p)[2] == '/')) - -#define git_path_is_dirsep(p) \ - ((p) == '/' || (p) == '\\') - -/** - * Convert backslashes in path to forward slashes. - */ -GIT_INLINE(void) git_path_mkposix(char *path) -{ - while (*path) { - if (*path == '\\') - *path = '/'; - - path++; - } -} -#else -# define git_path_mkposix(p) /* blank */ - -#define git_path_is_absolute(p) \ - ((p)[0] == '/') - -#define git_path_is_dirsep(p) \ - ((p) == '/') - -#endif - -/** - * Check if string is a relative path (i.e. starts with "./" or "../") - */ -GIT_INLINE(int) git_path_is_relative(const char *p) -{ - return (p[0] == '.' && (p[1] == '/' || (p[1] == '.' && p[2] == '/'))); -} - -/** - * Check if string is at end of path segment (i.e. looking at '/' or '\0') - */ -GIT_INLINE(int) git_path_at_end_of_segment(const char *p) -{ - return !*p || *p == '/'; -} - -extern int git__percent_decode(git_str *decoded_out, const char *input); - -/** - * Extract path from file:// URL. - */ -extern int git_path_fromurl(git_str *local_path_out, const char *file_url); - - -/** - * Path filesystem utils - * - * These are path utilities that actually access the filesystem. - */ - -/** - * Check if a file exists and can be accessed. - * @return true or false - */ -extern bool git_path_exists(const char *path); - -/** - * Check if the given path points to a directory. - * @return true or false - */ -extern bool git_path_isdir(const char *path); - -/** - * Check if the given path points to a regular file. - * @return true or false - */ -extern bool git_path_isfile(const char *path); - -/** - * Check if the given path points to a symbolic link. - * @return true or false - */ -extern bool git_path_islink(const char *path); - -/** - * Check if the given path is a directory, and is empty. - */ -extern bool git_path_is_empty_dir(const char *path); - -/** - * Stat a file and/or link and set error if needed. - */ -extern int git_path_lstat(const char *path, struct stat *st); - -/** - * Check if the parent directory contains the item. - * - * @param dir Directory to check. - * @param item Item that might be in the directory. - * @return 0 if item exists in directory, <0 otherwise. - */ -extern bool git_path_contains(git_str *dir, const char *item); - -/** - * Check if the given path contains the given subdirectory. - * - * @param parent Directory path that might contain subdir - * @param subdir Subdirectory name to look for in parent - * @return true if subdirectory exists, false otherwise. - */ -extern bool git_path_contains_dir(git_str *parent, const char *subdir); - -/** - * Determine the common directory length between two paths, including - * the final path separator. For example, given paths 'a/b/c/1.txt - * and 'a/b/c/d/2.txt', the common directory is 'a/b/c/', and this - * will return the length of the string 'a/b/c/', which is 6. - * - * @param one The first path - * @param two The second path - * @return The length of the common directory - */ -extern size_t git_path_common_dirlen(const char *one, const char *two); - -/** - * Make the path relative to the given parent path. - * - * @param path The path to make relative - * @param parent The parent path to make path relative to - * @return 0 if path was made relative, GIT_ENOTFOUND - * if there was not common root between the paths, - * or <0. - */ -extern int git_path_make_relative(git_str *path, const char *parent); - -/** - * Check if the given path contains the given file. - * - * @param dir Directory path that might contain file - * @param file File name to look for in parent - * @return true if file exists, false otherwise. - */ -extern bool git_path_contains_file(git_str *dir, const char *file); - -/** - * Prepend base to unrooted path or just copy path over. - * - * This will optionally return the index into the path where the "root" - * is, either the end of the base directory prefix or the path root. - */ -extern int git_path_join_unrooted( - git_str *path_out, const char *path, const char *base, ssize_t *root_at); - -/** - * Removes multiple occurrences of '/' in a row, squashing them into a - * single '/'. - */ -extern void git_path_squash_slashes(git_str *path); - -/** - * Clean up path, prepending base if it is not already rooted. - */ -extern int git_path_prettify(git_str *path_out, const char *path, const char *base); - -/** - * Clean up path, prepending base if it is not already rooted and - * appending a slash. - */ -extern int git_path_prettify_dir(git_str *path_out, const char *path, const char *base); - -/** - * Get a directory from a path. - * - * If path is a directory, this acts like `git_path_prettify_dir` - * (cleaning up path and appending a '/'). If path is a normal file, - * this prettifies it, then removed the filename a la dirname and - * appends the trailing '/'. If the path does not exist, it is - * treated like a regular filename. - */ -extern int git_path_find_dir(git_str *dir); - -/** - * Resolve relative references within a path. - * - * This eliminates "./" and "../" relative references inside a path, - * as well as condensing multiple slashes into single ones. It will - * not touch the path before the "ceiling" length. - * - * Additionally, this will recognize an "c:/" drive prefix or a "xyz://" URL - * prefix and not touch that part of the path. - */ -extern int git_path_resolve_relative(git_str *path, size_t ceiling); - -/** - * Apply a relative path to base path. - * - * Note that the base path could be a filename or a URL and this - * should still work. The relative path is walked segment by segment - * with three rules: series of slashes will be condensed to a single - * slash, "." will be eaten with no change, and ".." will remove a - * segment from the base path. - */ -extern int git_path_apply_relative(git_str *target, const char *relpath); - -enum { - GIT_PATH_DIR_IGNORE_CASE = (1u << 0), - GIT_PATH_DIR_PRECOMPOSE_UNICODE = (1u << 1), - GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT = (1u << 2), -}; - -/** - * Walk each directory entry, except '.' and '..', calling fn(state). - * - * @param pathbuf Buffer the function reads the initial directory - * path from, and updates with each successive entry's name. - * @param flags Combination of GIT_PATH_DIR flags. - * @param callback Callback for each entry. Passed the `payload` and each - * successive path inside the directory as a full path. This may - * safely append text to the pathbuf if needed. Return non-zero to - * cancel iteration (and return value will be propagated back). - * @param payload Passed to callback as first argument. - * @return 0 on success or error code from OS error or from callback - */ -extern int git_path_direach( - git_str *pathbuf, - uint32_t flags, - int (*callback)(void *payload, git_str *path), - void *payload); - -/** - * Sort function to order two paths - */ -extern int git_path_cmp( - const char *name1, size_t len1, int isdir1, - const char *name2, size_t len2, int isdir2, - int (*compare)(const char *, const char *, size_t)); - -/** - * Invoke callback up path directory by directory until the ceiling is - * reached (inclusive of a final call at the root_path). - * - * Returning anything other than 0 from the callback function - * will stop the iteration and propagate the error to the caller. - * - * @param pathbuf Buffer the function reads the directory from and - * and updates with each successive name. - * @param ceiling Prefix of path at which to stop walking up. If NULL, - * this will walk all the way up to the root. If not a prefix of - * pathbuf, the callback will be invoked a single time on the - * original input path. - * @param callback Function to invoke on each path. Passed the `payload` - * and the buffer containing the current path. The path should not - * be modified in any way. Return non-zero to stop iteration. - * @param payload Passed to fn as the first ath. - */ -extern int git_path_walk_up( - git_str *pathbuf, - const char *ceiling, - int (*callback)(void *payload, const char *path), - void *payload); - - -enum { GIT_PATH_NOTEQUAL = 0, GIT_PATH_EQUAL = 1, GIT_PATH_PREFIX = 2 }; - -/* - * Determines if a path is equal to or potentially a child of another. - * @param parent The possible parent - * @param child The possible child - */ -GIT_INLINE(int) git_path_equal_or_prefixed( - const char *parent, - const char *child, - ssize_t *prefixlen) -{ - const char *p = parent, *c = child; - int lastslash = 0; - - while (*p && *c) { - lastslash = (*p == '/'); - - if (*p++ != *c++) - return GIT_PATH_NOTEQUAL; - } - - if (*p != '\0') - return GIT_PATH_NOTEQUAL; - - if (*c == '\0') { - if (prefixlen) - *prefixlen = p - parent; - - return GIT_PATH_EQUAL; - } - - if (*c == '/' || lastslash) { - if (prefixlen) - *prefixlen = (p - parent) - lastslash; - - return GIT_PATH_PREFIX; - } - - return GIT_PATH_NOTEQUAL; -} - -/* translate errno to libgit2 error code and set error message */ -extern int git_path_set_error( - int errno_value, const char *path, const char *action); - -/* check if non-ascii characters are present in filename */ -extern bool git_path_has_non_ascii(const char *path, size_t pathlen); - -#define GIT_PATH_REPO_ENCODING "UTF-8" - -#ifdef __APPLE__ -#define GIT_PATH_NATIVE_ENCODING "UTF-8-MAC" -#else -#define GIT_PATH_NATIVE_ENCODING "UTF-8" -#endif - -#ifdef GIT_USE_ICONV - -#include - -typedef struct { - iconv_t map; - git_str buf; -} git_path_iconv_t; - -#define GIT_PATH_ICONV_INIT { (iconv_t)-1, GIT_STR_INIT } - -/* Init iconv data for converting decomposed UTF-8 to precomposed */ -extern int git_path_iconv_init_precompose(git_path_iconv_t *ic); - -/* Clear allocated iconv data */ -extern void git_path_iconv_clear(git_path_iconv_t *ic); - -/* - * Rewrite `in` buffer using iconv map if necessary, replacing `in` - * pointer internal iconv buffer if rewrite happened. The `in` pointer - * will be left unchanged if no rewrite was needed. - */ -extern int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen); - -#endif /* GIT_USE_ICONV */ - -extern bool git_path_does_fs_decompose_unicode(const char *root); - - -typedef struct git_path_diriter git_path_diriter; - -#if defined(GIT_WIN32) && !defined(__MINGW32__) - -struct git_path_diriter -{ - git_win32_path path; - size_t parent_len; - - git_str path_utf8; - size_t parent_utf8_len; - - HANDLE handle; - - unsigned int flags; - - WIN32_FIND_DATAW current; - unsigned int needs_next; -}; - -#define GIT_PATH_DIRITER_INIT { {0}, 0, GIT_STR_INIT, 0, INVALID_HANDLE_VALUE } - -#else - -struct git_path_diriter -{ - git_str path; - size_t parent_len; - - unsigned int flags; - - DIR *dir; - -#ifdef GIT_USE_ICONV - git_path_iconv_t ic; -#endif -}; - -#define GIT_PATH_DIRITER_INIT { GIT_STR_INIT } - -#endif - -/** - * Initialize a directory iterator. - * - * @param diriter Pointer to a diriter structure that will be setup. - * @param path The path that will be iterated over - * @param flags Directory reader flags - * @return 0 or an error code - */ -extern int git_path_diriter_init( - git_path_diriter *diriter, - const char *path, - unsigned int flags); - -/** - * Advance the directory iterator. Will return GIT_ITEROVER when - * the iteration has completed successfully. - * - * @param diriter The directory iterator - * @return 0, GIT_ITEROVER, or an error code - */ -extern int git_path_diriter_next(git_path_diriter *diriter); - -/** - * Returns the file name of the current item in the iterator. - * - * @param out Pointer to store the path in - * @param out_len Pointer to store the length of the path in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_filename( - const char **out, - size_t *out_len, - git_path_diriter *diriter); - -/** - * Returns the full path of the current item in the iterator; that - * is the current filename plus the path of the directory that the - * iterator was constructed with. - * - * @param out Pointer to store the path in - * @param out_len Pointer to store the length of the path in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_fullpath( - const char **out, - size_t *out_len, - git_path_diriter *diriter); - -/** - * Performs an `lstat` on the current item in the iterator. - * - * @param out Pointer to store the stat data in - * @param diriter The directory iterator - * @return 0 or an error code - */ -extern int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter); - -/** - * Closes the directory iterator. - * - * @param diriter The directory iterator - */ -extern void git_path_diriter_free(git_path_diriter *diriter); - -/** - * Load all directory entries (except '.' and '..') into a vector. - * - * For cases where `git_path_direach()` is not appropriate, this - * allows you to load the filenames in a directory into a vector - * of strings. That vector can then be sorted, iterated, or whatever. - * Remember to free alloc of the allocated strings when you are done. - * - * @param contents Vector to fill with directory entry names. - * @param path The directory to read from. - * @param prefix_len When inserting entries, the trailing part of path - * will be prefixed after this length. I.e. given path "/a/b" and - * prefix_len 3, the entries will look like "b/e1", "b/e2", etc. - * @param flags Combination of GIT_PATH_DIR flags. - */ -extern int git_path_dirload( - git_vector *contents, - const char *path, - size_t prefix_len, - uint32_t flags); - - -/* Used for paths to repositories on the filesystem */ -extern bool git_path_is_local_file_url(const char *file_url); -extern int git_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); - -/* Flags to determine path validity in `git_path_isvalid` */ -#define GIT_PATH_REJECT_TRAVERSAL (1 << 0) -#define GIT_PATH_REJECT_DOT_GIT (1 << 1) -#define GIT_PATH_REJECT_SLASH (1 << 2) -#define GIT_PATH_REJECT_BACKSLASH (1 << 3) -#define GIT_PATH_REJECT_TRAILING_DOT (1 << 4) -#define GIT_PATH_REJECT_TRAILING_SPACE (1 << 5) -#define GIT_PATH_REJECT_TRAILING_COLON (1 << 6) -#define GIT_PATH_REJECT_DOS_PATHS (1 << 7) -#define GIT_PATH_REJECT_NT_CHARS (1 << 8) -#define GIT_PATH_REJECT_DOT_GIT_LITERAL (1 << 9) -#define GIT_PATH_REJECT_DOT_GIT_HFS (1 << 10) -#define GIT_PATH_REJECT_DOT_GIT_NTFS (1 << 11) - -/* Default path safety for writing files to disk: since we use the - * Win32 "File Namespace" APIs ("\\?\") we need to protect from - * paths that the normal Win32 APIs would not write. - */ -#ifdef GIT_WIN32 -# define GIT_PATH_REJECT_FILESYSTEM_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL | \ - GIT_PATH_REJECT_BACKSLASH | \ - GIT_PATH_REJECT_TRAILING_DOT | \ - GIT_PATH_REJECT_TRAILING_SPACE | \ - GIT_PATH_REJECT_TRAILING_COLON | \ - GIT_PATH_REJECT_DOS_PATHS | \ - GIT_PATH_REJECT_NT_CHARS -#else -# define GIT_PATH_REJECT_FILESYSTEM_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL -#endif - - /* Paths that should never be written into the working directory. */ +/* Paths that should never be written into the working directory. */ #define GIT_PATH_REJECT_WORKDIR_DEFAULTS \ - GIT_PATH_REJECT_FILESYSTEM_DEFAULTS | GIT_PATH_REJECT_DOT_GIT + GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS | GIT_PATH_REJECT_DOT_GIT /* Paths that should never be written to the index. */ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ - GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT + GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -/** - * Validate a "bare" git path. This ensures that the given path is legal - * to place in the index or a tree. This should be checked by mechanisms - * like `git_index_add` and `git_treebuilder_insert` when taking user - * data, and by `git_checkout` before constructing on-disk paths. - * - * This will ensure that a git path does not contain any "unsafe" components, - * a '.' or '..' component, or a component that is ".git" (in any case). - * - * (Note: if you take or construct an on-disk path -- a workdir path, - * a path to a git repository or a reference name that could be a loose - * ref -- you should _also_ validate that with `git_path_validate_workdir`.) - * - * `repo` is optional. If specified, it will be used to determine the short - * path name to reject (if `GIT_PATH_REJECT_DOS_SHORTNAME` is specified), - * in addition to the default of "git~1". - */ extern bool git_path_validate( git_repository *repo, const char *path, - uint16_t mode, + uint16_t file_mode, unsigned int flags); -/** - * Validate an on-disk path, taking into account that it will have a - * suffix appended (eg, `.lock`). - */ -GIT_INLINE(int) git_path_validate_filesystem_with_suffix( - const char *path, - size_t path_len, - size_t suffix_len) -{ -#ifdef GIT_WIN32 - size_t path_chars, total_chars; - - path_chars = git_utf8_char_length(path, path_len); - - if (GIT_ADD_SIZET_OVERFLOW(&total_chars, path_chars, suffix_len) || - total_chars > MAX_PATH) { - git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path); - return -1; - } - return 0; -#else - GIT_UNUSED(path); - GIT_UNUSED(path_len); - GIT_UNUSED(suffix_len); - return 0; -#endif -} - -/** - * Validate an path on the filesystem. This ensures that the given - * path is valid for the operating system/platform; for example, this - * will ensure that the given absolute path is smaller than MAX_PATH on - * Windows. - * - * For paths within the working directory, you should use ensure that - * `core.longpaths` is obeyed. Use `git_path_validate_workdir`. - */ -GIT_INLINE(int) git_path_validate_filesystem( - const char *path, - size_t path_len) -{ - return git_path_validate_filesystem_with_suffix(path, path_len, 0); -} - -/** - * Validate a path relative to the repo's worktree. This ensures that - * the given working tree path is valid for the operating system/platform. - * This will ensure that an absolute path is smaller than MAX_PATH on - * Windows, while keeping `core.longpaths` configuration settings in mind. - * - * This should be checked by mechamisms like `git_checkout` after - * contructing on-disk paths and before trying to write them. - * - * If the repository is null, no repository configuration is applied. - */ -extern int git_path_validate_workdir( - git_repository *repo, - const char *path); -extern int git_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len); -extern int git_path_validate_workdir_buf( - git_repository *repo, - git_str *buf); - -/** - * Convert any backslashes into slashes - */ -int git_path_normalize_slashes(git_str *out, const char *path); - -bool git_path_supports_symlinks(const char *dir); - -/** - * Validate a system file's ownership - * - * Verify that the file in question is owned by an administrator or system - * account, or at least by the current user. - * - * This function returns 0 if successful. If the file is not owned by any of - * these, or any other if there have been problems determining the file - * ownership, it returns -1. - */ -int git_path_validate_system_file_ownership(const char *path); - #endif diff --git a/src/posix.c b/src/posix.c index c40134824..b1f85dc94 100644 --- a/src/posix.c +++ b/src/posix.c @@ -7,7 +7,7 @@ #include "posix.h" -#include "path.h" +#include "fs_path.h" #include #include @@ -144,8 +144,8 @@ int p_getcwd(char *buffer_out, size_t size) if (cwd_buffer == NULL) return -1; - git_path_mkposix(buffer_out); - git_path_string_to_dir(buffer_out, size); /* append trailing slash */ + git_fs_path_mkposix(buffer_out); + git_fs_path_string_to_dir(buffer_out, size); /* append trailing slash */ return 0; } diff --git a/src/rebase.c b/src/rebase.c index 302fc81fc..26b03b38c 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -97,7 +97,7 @@ static int rebase_state_type( if (git_str_joinpath(&path, repo->gitdir, REBASE_APPLY_DIR) < 0) return -1; - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_APPLY; goto done; } @@ -106,7 +106,7 @@ static int rebase_state_type( if (git_str_joinpath(&path, repo->gitdir, REBASE_MERGE_DIR) < 0) return -1; - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { type = GIT_REBASE_MERGE; goto done; } @@ -340,7 +340,7 @@ int git_rebase_open( if ((error = git_str_joinpath(&path, path.ptr, ORIG_HEAD_FILE)) < 0) goto done; - if (!git_path_isfile(path.ptr)) { + if (!git_fs_path_isfile(path.ptr)) { /* Previous versions of git.git used 'head' here; support that. */ git_str_truncate(&path, state_path_len); @@ -404,7 +404,7 @@ static int rebase_cleanup(git_rebase *rebase) if (!rebase || rebase->inmemory) return 0; - return git_path_isdir(rebase->state_path) ? + return git_fs_path_isdir(rebase->state_path) ? git_futils_rmdir_r(rebase->state_path, NULL, GIT_RMDIR_REMOVE_FILES) : 0; } diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 37eb85ecc..39dc16e9d 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -18,6 +18,7 @@ #include "sortedcache.h" #include "signature.h" #include "wildmatch.h" +#include "path.h" #include #include @@ -76,7 +77,7 @@ GIT_INLINE(int) loose_path( if (git_str_joinpath(out, base, refname) < 0) return -1; - return git_path_validate_filesystem_with_suffix(out->ptr, out->size, + return git_fs_path_validate_filesystem_with_suffix(out->ptr, out->size, CONST_STRLEN(".lock")); } @@ -307,8 +308,8 @@ static int _dirent_loose_load(void *payload, git_str *full_path) if (git__suffixcmp(full_path->ptr, ".lock") == 0) return 0; - if (git_path_isdir(full_path->ptr)) { - int error = git_path_direach( + if (git_fs_path_isdir(full_path->ptr)) { + int error = git_fs_path_direach( full_path, backend->direach_flags, _dirent_loose_load, backend); /* Race with the filesystem, ignore it */ if (error == GIT_ENOTFOUND) { @@ -343,7 +344,7 @@ static int packed_loadloose(refdb_fs_backend *backend) * This will overwrite any old packed entries with their * updated loose versions */ - error = git_path_direach( + error = git_fs_path_direach( &refs_path, backend->direach_flags, _dirent_loose_load, backend); git_str_dispose(&refs_path); @@ -367,7 +368,7 @@ static int refdb_fs_backend__exists( if ((error = loose_path(&ref_path, backend->gitpath, ref_name)) < 0) goto out; - if (git_path_isfile(ref_path.ptr)) { + if (git_fs_path_isfile(ref_path.ptr)) { *exists = 1; goto out; } @@ -817,7 +818,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(name); - if (!git_path_validate(backend->repo, name, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); return GIT_EINVALIDSPEC; } @@ -1344,10 +1345,10 @@ static int refdb_fs_backend__prune_refs( if ((error = git_str_sets(&relative_path, ref_name)) < 0) goto cleanup; - git_path_squash_slashes(&relative_path); - if ((commonlen = git_path_common_dirlen("refs/heads/", git_str_cstr(&relative_path))) == strlen("refs/heads/") || - (commonlen = git_path_common_dirlen("refs/tags/", git_str_cstr(&relative_path))) == strlen("refs/tags/") || - (commonlen = git_path_common_dirlen("refs/remotes/", git_str_cstr(&relative_path))) == strlen("refs/remotes/")) { + git_fs_path_squash_slashes(&relative_path); + if ((commonlen = git_fs_path_common_dirlen("refs/heads/", git_str_cstr(&relative_path))) == strlen("refs/heads/") || + (commonlen = git_fs_path_common_dirlen("refs/tags/", git_str_cstr(&relative_path))) == strlen("refs/tags/") || + (commonlen = git_fs_path_common_dirlen("refs/remotes/", git_str_cstr(&relative_path))) == strlen("refs/remotes/")) { git_str_truncate(&relative_path, commonlen); @@ -1361,7 +1362,7 @@ static int refdb_fs_backend__prune_refs( git_str_cstr(&relative_path)); if (!error) - error = git_path_validate_filesystem(base_path.ptr, base_path.size); + error = git_fs_path_validate_filesystem(base_path.ptr, base_path.size); if (error < 0) goto cleanup; @@ -1741,7 +1742,7 @@ static int has_reflog(git_repository *repo, const char *name) if (reflog_path(&path, repo, name) < 0) goto cleanup; - ret = git_path_isfile(git_str_cstr(&path)); + ret = git_fs_path_isfile(git_str_cstr(&path)); cleanup: git_str_dispose(&path); @@ -1856,7 +1857,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char repo = backend->repo; - if (!git_path_validate(backend->repo, refname, 0, GIT_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_validate(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", refname); return GIT_EINVALIDSPEC; } @@ -1864,7 +1865,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char if (reflog_path(&log_path, repo, refname) < 0) return -1; - if (!git_path_isfile(git_str_cstr(&log_path))) { + if (!git_fs_path_isfile(git_str_cstr(&log_path))) { git_error_set(GIT_ERROR_INVALID, "log file for reference '%s' doesn't exist", refname); error = -1; @@ -1973,11 +1974,11 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co /* If the new branch matches part of the namespace of a previously deleted branch, * there maybe an obsolete/unused directory (or directory hierarchy) in the way. */ - if (git_path_isdir(git_str_cstr(&path))) { + if (git_fs_path_isdir(git_str_cstr(&path))) { if ((error = git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_SKIP_NONEMPTY)) < 0) { if (error == GIT_ENOTFOUND) error = 0; - } else if (git_path_isdir(git_str_cstr(&path))) { + } else if (git_fs_path_isdir(git_str_cstr(&path))) { git_error_set(GIT_ERROR_REFERENCE, "cannot create reflog at '%s', there are reflogs beneath that folder", ref->name); error = GIT_EDIRECTORY; @@ -2031,7 +2032,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ if ((error = loose_path(&new_path, git_str_cstr(&temp_path), git_str_cstr(&normalized))) < 0) return error; - if (!git_path_exists(git_str_cstr(&old_path))) { + if (!git_fs_path_exists(git_str_cstr(&old_path))) { error = GIT_ENOTFOUND; goto cleanup; } @@ -2059,7 +2060,7 @@ static int refdb_reflog_fs__rename(git_refdb_backend *_backend, const char *old_ goto cleanup; } - if (git_path_isdir(git_str_cstr(&new_path)) && + if (git_fs_path_isdir(git_str_cstr(&new_path)) && (git_futils_rmdir_r(git_str_cstr(&new_path), NULL, GIT_RMDIR_SKIP_NONEMPTY) < 0)) { error = -1; goto cleanup; @@ -2096,7 +2097,7 @@ static int refdb_reflog_fs__delete(git_refdb_backend *_backend, const char *name if ((error = reflog_path(&path, backend->repo, name)) < 0) goto out; - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) goto out; if ((error = p_unlink(path.ptr)) < 0) @@ -2150,11 +2151,11 @@ int git_refdb_backend_fs( if (!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_IGNORECASE) && t) { backend->iterator_flags |= GIT_ITERATOR_IGNORE_CASE; - backend->direach_flags |= GIT_PATH_DIR_IGNORE_CASE; + backend->direach_flags |= GIT_FS_PATH_DIR_IGNORE_CASE; } if (!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_PRECOMPOSE) && t) { backend->iterator_flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE; - backend->direach_flags |= GIT_PATH_DIR_PRECOMPOSE_UNICODE; + backend->direach_flags |= GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE; } if ((!git_repository__configmap_lookup(&t, backend->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t) || git_repository__fsync_gitdir) diff --git a/src/refs.c b/src/refs.c index 0ac455d24..5c875b95b 100644 --- a/src/refs.c +++ b/src/refs.c @@ -902,7 +902,7 @@ int git_reference__normalize_name( bool validate = (flags & GIT_REFERENCE_FORMAT__VALIDATION_DISABLE) == 0; #ifdef GIT_USE_ICONV - git_path_iconv_t ic = GIT_PATH_ICONV_INIT; + git_fs_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif GIT_ASSERT_ARG(name); @@ -919,8 +919,8 @@ int git_reference__normalize_name( #ifdef GIT_USE_ICONV if ((flags & GIT_REFERENCE_FORMAT__PRECOMPOSE_UNICODE) != 0) { size_t namelen = strlen(current); - if ((error = git_path_iconv_init_precompose(&ic)) < 0 || - (error = git_path_iconv(&ic, ¤t, &namelen)) < 0) + if ((error = git_fs_path_iconv_init_precompose(&ic)) < 0 || + (error = git_fs_path_iconv(&ic, ¤t, &namelen)) < 0) goto cleanup; error = GIT_EINVALIDSPEC; } @@ -1011,7 +1011,7 @@ cleanup: git_str_dispose(buf); #ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); + git_fs_path_iconv_clear(&ic); #endif return error; diff --git a/src/repository.c b/src/repository.c index 29684e463..2f7ae9b3d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -197,9 +197,9 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit * If there's no commondir file, the repository path is the * common path, but it needs a trailing slash. */ - if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { + if (!git_fs_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) { if ((error = git_str_set(commondir, repository_path->ptr, repository_path->size)) == 0) - error = git_path_to_dir(commondir); + error = git_fs_path_to_dir(commondir); *separate = false; goto done; @@ -212,7 +212,7 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit goto done; git_str_rtrim(&common_link); - if (git_path_is_relative(common_link.ptr)) { + if (git_fs_path_is_relative(common_link.ptr)) { if ((error = git_str_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0) goto done; } else { @@ -222,7 +222,7 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit git_str_dispose(&common_link); /* Make sure the commondir path always has a trailing slash */ - error = git_path_prettify_dir(commondir, commondir->ptr, NULL); + error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL); done: return error; @@ -240,7 +240,7 @@ GIT_INLINE(int) validate_repo_path(git_str *path) CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; - return git_path_validate_filesystem_with_suffix( + return git_fs_path_validate_filesystem_with_suffix( path->ptr, path->size, suffix_len); } @@ -260,13 +260,13 @@ static int is_valid_repository_path(bool *out, git_str *repository_path, git_str return error; /* Ensure HEAD file exists */ - if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false) + if (git_fs_path_contains_file(repository_path, GIT_HEAD_FILE) == false) return 0; /* Check files in common dir */ - if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false) + if (git_fs_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false) return 0; - if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false) + if (git_fs_path_contains_dir(common_path, GIT_REFS_DIR) == false) return 0; /* Ensure the repo (and commondir) are valid paths */ @@ -357,8 +357,8 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren git_str_attach(&worktree, gitlink, 0); - if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 || - git_path_to_dir(&worktree) < 0) { + if ((git_fs_path_dirname_r(&worktree, worktree.ptr)) < 0 || + git_fs_path_to_dir(&worktree) < 0) { error = -1; goto cleanup; } @@ -366,17 +366,17 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren repo->workdir = git_str_detach(&worktree); } else if (ce && ce->value) { - if ((error = git_path_prettify_dir( + if ((error = git_fs_path_prettify_dir( &worktree, ce->value, repo->gitdir)) < 0) goto cleanup; repo->workdir = git_str_detach(&worktree); } - else if (parent_path && git_path_isdir(parent_path->ptr)) + else if (parent_path && git_fs_path_isdir(parent_path->ptr)) repo->workdir = git_str_detach(parent_path); else { - if (git_path_dirname_r(&worktree, repo->gitdir) < 0 || - git_path_to_dir(&worktree) < 0) { + if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 || + git_fs_path_to_dir(&worktree) < 0) { error = -1; goto cleanup; } @@ -410,7 +410,7 @@ static size_t find_ceiling_dir_offset( GIT_ASSERT_ARG(path); - min_len = (size_t)(git_path_root(path) + 1); + min_len = (size_t)(git_fs_path_root(path) + 1); if (ceiling_directories == NULL || min_len == 0) return min_len; @@ -419,7 +419,7 @@ static size_t find_ceiling_dir_offset( for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++); len = sep - ceil; - if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1) + if (len == 0 || len >= sizeof(buf) || git_fs_path_root(ceil) == -1) continue; strncpy(buf, ceil, len); @@ -462,7 +462,7 @@ static int read_gitfile(git_str *path_out, const char *file_path) git_str_rtrim(&file); /* apparently on Windows, some people use backslashes in paths */ - git_path_mkposix(file.ptr); + git_fs_path_mkposix(file.ptr); if (git_str_len(&file) <= prefix_len || memcmp(git_str_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0) @@ -471,11 +471,11 @@ static int read_gitfile(git_str *path_out, const char *file_path) "the `.git` file at '%s' is malformed", file_path); error = -1; } - else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) { + else if ((error = git_fs_path_dirname_r(path_out, file_path)) >= 0) { const char *gitlink = git_str_cstr(&file) + prefix_len; while (*gitlink && git__isspace(*gitlink)) gitlink++; - error = git_path_prettify_dir( + error = git_fs_path_prettify_dir( path_out, gitlink, git_str_cstr(path_out)); } @@ -504,7 +504,7 @@ static int find_repo( git_str_clear(gitdir_path); - error = git_path_prettify(&path, start_path, NULL); + error = git_fs_path_prettify(&path, start_path, NULL); if (error < 0) return error; @@ -545,7 +545,7 @@ static int find_repo( goto out; if (is_valid) { - if ((error = git_path_to_dir(&path)) < 0 || + if ((error = git_fs_path_to_dir(&path)) < 0 || (error = git_str_set(gitdir_path, path.ptr, path.size)) < 0) goto out; @@ -578,7 +578,7 @@ static int find_repo( /* Move up one directory. If we're in_dot_git, we'll search the * parent itself next. If we're !in_dot_git, we'll search .git * in the parent directory next (added at the top of the loop). */ - if ((error = git_path_dirname_r(&path, path.ptr)) < 0) + if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0) goto out; /* Once we've checked the directory (and .git if applicable), @@ -595,8 +595,8 @@ static int find_repo( if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) { if (!git_str_len(gitdir_path)) git_str_clear(workdir_path); - else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 || - (error = git_path_to_dir(workdir_path)) < 0) + else if ((error = git_fs_path_dirname_r(workdir_path, path.ptr)) < 0 || + (error = git_fs_path_to_dir(workdir_path)) < 0) goto out; } @@ -624,7 +624,7 @@ int git_repository_open_bare( bool is_valid; int error; - if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0 || + if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 || (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0) return error; @@ -838,7 +838,7 @@ static int repo_is_worktree(unsigned *out, const git_repository *repo) /* A 'gitdir' file inside a git directory is currently * only used when the repository is a working tree. */ - *out = !!git_path_exists(gitdir_link.ptr); + *out = !!git_fs_path_exists(gitdir_link.ptr); git_str_dispose(&gitdir_link); return error; @@ -1600,7 +1600,7 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path) int is_insensitive = -1; if (!git_str_joinpath(&path, gitdir_path, "CoNfIg")) - is_insensitive = git_path_exists(git_str_cstr(&path)); + is_insensitive = git_fs_path_exists(git_str_cstr(&path)); git_str_dispose(&path); return is_insensitive; @@ -1639,7 +1639,7 @@ static bool are_symlinks_supported(const char *wd_path) goto done; #endif - if (!(symlinks = git_path_supports_symlinks(wd_path))) + if (!(symlinks = git_fs_path_supports_symlinks(wd_path))) goto done; done: @@ -1683,7 +1683,7 @@ static int repo_local_config( cfg_path = git_str_cstr(config_dir); /* make LOCAL config if missing */ - if (!git_path_isfile(cfg_path) && + if (!git_fs_path_isfile(cfg_path) && (error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0) return error; @@ -1741,7 +1741,7 @@ static int repo_init_fs_configs( #ifdef GIT_USE_ICONV if ((error = git_config_set_bool( cfg, "core.precomposeunicode", - git_path_does_fs_decompose_unicode(work_dir))) < 0) + git_fs_path_does_decompose_unicode(work_dir))) < 0) return error; /* on non-iconv platforms, don't even set core.precomposeunicode */ #endif @@ -1790,7 +1790,7 @@ static int repo_init_config( goto cleanup; if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK)) - if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0) + if ((error = git_fs_path_make_relative(&worktree_path, repo_dir)) < 0) goto cleanup; SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr); @@ -1907,8 +1907,8 @@ static int repo_write_gitlink( git_str path_to_repo = GIT_STR_INIT; struct stat st; - git_path_dirname_r(&buf, to_repo); - git_path_to_dir(&buf); + git_fs_path_dirname_r(&buf, to_repo); + git_fs_path_to_dir(&buf); if (git_str_oom(&buf)) return -1; @@ -1935,7 +1935,7 @@ static int repo_write_gitlink( error = git_str_sets(&path_to_repo, to_repo); if (!error && use_relative_path) - error = git_path_make_relative(&path_to_repo, in_dir); + error = git_fs_path_make_relative(&path_to_repo, in_dir); if (!error) error = git_str_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr); @@ -2132,11 +2132,11 @@ static int repo_init_directories( if (!is_bare) { if (opts->workdir_path) { - if (git_path_join_unrooted( + if (git_fs_path_join_unrooted( wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0) return -1; } else if (has_dotgit) { - if (git_path_dirname_r(wd_path, repo_path->ptr) < 0) + if (git_fs_path_dirname_r(wd_path, repo_path->ptr) < 0) return -1; } else { git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory" @@ -2144,7 +2144,7 @@ static int repo_init_directories( return -1; } - if (git_path_to_dir(wd_path) < 0) + if (git_fs_path_to_dir(wd_path) < 0) return -1; } else { git_str_clear(wd_path); @@ -2204,10 +2204,10 @@ static int repo_init_directories( /* prettify both directories now that they are created */ if (!error) { - error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL); + error = git_fs_path_prettify_dir(repo_path, repo_path->ptr, NULL); if (!error && wd_path->size > 0) - error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL); + error = git_fs_path_prettify_dir(wd_path, wd_path->ptr, NULL); } return error; @@ -2227,7 +2227,7 @@ static int repo_init_head(const char *repo_dir, const char *given) * A template may have set a HEAD; use that unless it's been * overridden by the caller's given initial head setting. */ - if (git_path_exists(head_path.ptr) && !given) + if (git_fs_path_exists(head_path.ptr) && !given) goto out; if (given) { @@ -2628,7 +2628,7 @@ int git_repository__item_path( } if (items[item].directory) { - if (git_path_to_dir(out) < 0) + if (git_fs_path_to_dir(out) < 0) return -1; } @@ -2662,7 +2662,7 @@ int git_repository_workdir_path( } if (!(error = git_str_joinpath(out, repo->workdir, path))) - error = git_path_validate_workdir_buf(repo, out); + error = git_fs_path_validate_workdir_buf(repo, out); return error; } @@ -2682,7 +2682,7 @@ int git_repository_set_workdir( GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(workdir); - if (git_path_prettify_dir(&path, workdir, NULL) < 0) + if (git_fs_path_prettify_dir(&path, workdir, NULL) < 0) return -1; if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0) @@ -2857,8 +2857,8 @@ int git_repository_hashfile( GIT_ASSERT_ARG(path); GIT_ASSERT_ARG(repo); - if ((error = git_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || - (error = git_path_validate_workdir_buf(repo, &full_path)) < 0) + if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || + (error = git_fs_path_validate_workdir_buf(repo, &full_path)) < 0) return error; /* @@ -3084,29 +3084,29 @@ int git_repository_state(git_repository *repo) if (git_str_puts(&repo_path, repo->gitdir) < 0) return -1; - if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE)) + if (git_fs_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE)) state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE; - else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR)) + else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR)) state = GIT_REPOSITORY_STATE_REBASE_MERGE; - else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE)) state = GIT_REPOSITORY_STATE_REBASE; - else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE)) state = GIT_REPOSITORY_STATE_APPLY_MAILBOX; - else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR)) + else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR)) state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE; - else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE)) + else if (git_fs_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE)) state = GIT_REPOSITORY_STATE_MERGE; - else if (git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) { + else if (git_fs_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) { state = GIT_REPOSITORY_STATE_REVERT; - if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { + if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE; } - } else if (git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) { + } else if (git_fs_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) { state = GIT_REPOSITORY_STATE_CHERRYPICK; - if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { + if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) { state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE; } - } else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE)) + } else if (git_fs_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE)) state = GIT_REPOSITORY_STATE_BISECT; git_str_dispose(&repo_path); @@ -3128,9 +3128,9 @@ int git_repository__cleanup_files( path = git_str_cstr(&buf); - if (git_path_isfile(path)) { + if (git_fs_path_isfile(path)) { error = p_unlink(path); - } else if (git_path_isdir(path)) { + } else if (git_fs_path_isdir(path)) { error = git_futils_rmdir_r(path, NULL, GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS); } @@ -3170,7 +3170,7 @@ int git_repository_is_shallow(git_repository *repo) if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0) return error; - error = git_path_lstat(path.ptr, &st); + error = git_fs_path_lstat(path.ptr, &st); git_str_dispose(&path); if (error == GIT_ENOTFOUND) { diff --git a/src/submodule.c b/src/submodule.c index b0f7294be..727b6c6e4 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -16,11 +16,12 @@ #include "repository.h" #include "tree.h" #include "iterator.h" -#include "path.h" +#include "fs_path.h" #include "str.h" #include "index.h" #include "worktree.h" #include "clone.h" +#include "path.h" #include "git2/config.h" #include "git2/sys/config.h" @@ -149,7 +150,7 @@ static int is_path_occupied(bool *occupied, git_repository *repo, const char *pa if ((error = git_str_sets(&dir, path)) < 0) goto out; - if ((error = git_path_to_dir(&dir)) < 0) + if ((error = git_fs_path_to_dir(&dir)) < 0) goto out; if ((error = git_index_find_prefix(NULL, index, dir.ptr)) != GIT_ENOTFOUND) { @@ -385,10 +386,10 @@ int git_submodule__lookup_with_cache( if (git_str_join3(&path, '/', git_repository_workdir(repo), name, DOT_GIT) < 0 || - git_path_validate_workdir_buf(NULL, &path) < 0) + git_fs_path_validate_workdir_buf(NULL, &path) < 0) return -1; - if (git_path_exists(path.ptr)) + if (git_fs_path_exists(path.ptr)) error = GIT_EEXISTS; git_str_dispose(&path); @@ -412,17 +413,17 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag int error, isvalid; if (flags == 0) - flags = GIT_PATH_REJECT_FILESYSTEM_DEFAULTS; + flags = GIT_FS_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) + if ((error = git_fs_path_normalize_slashes(&buf, name)) < 0) return error; } else { git_str_attach_notowned(&buf, name, strlen(name)); } - isvalid = git_path_validate(repo, buf.ptr, 0, flags); + isvalid = git_path_validate(repo, buf.ptr, 0, flags); git_str_dispose(&buf); return isvalid; @@ -743,16 +744,16 @@ static int git_submodule__resolve_url( /* We do this in all platforms in case someone on Windows created the .gitmodules */ if (strchr(url, '\\')) { - if ((error = git_path_normalize_slashes(&normalized, url)) < 0) + if ((error = git_fs_path_normalize_slashes(&normalized, url)) < 0) return error; url = normalized.ptr; } - if (git_path_is_relative(url)) { + if (git_fs_path_is_relative(url)) { if (!(error = get_url_base(out, repo))) - error = git_path_apply_relative(out, url); + error = git_fs_path_apply_relative(out, url); } else if (strchr(url, ':') != NULL || url[0] == '/') { error = git_str_sets(out, url); } else { @@ -805,7 +806,7 @@ int git_submodule_add_setup( if (git__prefixcmp(path, git_repository_workdir(repo)) == 0) path += strlen(git_repository_workdir(repo)); - if (git_path_root(path) >= 0) { + if (git_fs_path_root(path) >= 0) { git_error_set(GIT_ERROR_SUBMODULE, "submodule path must be a relative path"); error = -1; goto cleanup; @@ -846,8 +847,8 @@ int git_submodule_add_setup( /* if the repo does not already exist, then init a new repo and add it. * Otherwise, just add the existing repo. */ - if (!(git_path_exists(name.ptr) && - git_path_contains(&name, DOT_GIT))) { + if (!(git_fs_path_exists(name.ptr) && + git_fs_path_contains(&name, DOT_GIT))) { /* resolve the actual URL to use */ if ((error = git_submodule__resolve_url(&real_url, repo, url)) < 0) @@ -1568,13 +1569,13 @@ static int git_submodule__open( sm->flags |= GIT_SUBMODULE_STATUS__WD_OID_VALID; else git_error_clear(); - } else if (git_path_exists(path.ptr)) { + } else if (git_fs_path_exists(path.ptr)) { sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED | GIT_SUBMODULE_STATUS_IN_WD; } else { git_str_rtruncate_at_char(&path, '/'); /* remove "/.git" */ - if (git_path_isdir(path.ptr)) + if (git_fs_path_isdir(path.ptr)) sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; } @@ -2105,10 +2106,10 @@ static int submodule_load_from_wd_lite(git_submodule *sm) if (git_repository_workdir_path(&path, sm->repo, sm->path) < 0) return -1; - if (git_path_isdir(path.ptr)) + if (git_fs_path_isdir(path.ptr)) sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; - if (git_path_contains(&path, DOT_GIT)) + if (git_fs_path_contains(&path, DOT_GIT)) sm->flags |= GIT_SUBMODULE_STATUS_IN_WD; git_str_dispose(&path); @@ -2160,7 +2161,7 @@ static git_config_backend *open_gitmodules( if (git_repository_workdir_path(&path, repo, GIT_MODULES_FILE) != 0) return NULL; - if (okay_to_create || git_path_isfile(path.ptr)) { + if (okay_to_create || git_fs_path_isfile(path.ptr)) { /* git_config_backend_from_file should only fail if OOM */ if (git_config_backend_from_file(&mods, path.ptr) < 0) mods = NULL; diff --git a/src/sysdir.c b/src/sysdir.c index 457d7f8a8..84d212e01 100644 --- a/src/sysdir.c +++ b/src/sysdir.c @@ -9,7 +9,7 @@ #include "runtime.h" #include "str.h" -#include "path.h" +#include "fs_path.h" #include #if GIT_WIN32 #include "win32/findfile.h" @@ -291,7 +291,7 @@ static int git_sysdir_find_in_dirlist( if (name) GIT_ERROR_CHECK_ERROR(git_str_joinpath(path, path->ptr, name)); - if (git_path_exists(path->ptr)) + if (git_fs_path_exists(path->ptr)) return 0; } diff --git a/src/transport.c b/src/transport.c index fa1d35fce..640ccacae 100644 --- a/src/transport.c +++ b/src/transport.c @@ -12,7 +12,7 @@ #include "git2/net.h" #include "git2/transport.h" #include "git2/sys/transport.h" -#include "path.h" +#include "fs_path.h" typedef struct transport_definition { char *prefix; @@ -82,7 +82,7 @@ static int transport_find_fn( * to a directory and if so assume local path, else assume SSH */ /* Check to see if the path points to a file on the local file system */ - if (!definition && git_path_exists(url) && git_path_isdir(url)) + if (!definition && git_fs_path_exists(url) && git_fs_path_isdir(url)) definition = &local_transport_definition; #endif @@ -98,7 +98,7 @@ static int transport_find_fn( #ifndef GIT_WIN32 /* Check to see if the path points to a file on the local file system */ - if (!definition && git_path_exists(url) && git_path_isdir(url)) + if (!definition && git_fs_path_exists(url) && git_fs_path_isdir(url)) definition = &local_transport_definition; #endif diff --git a/src/transports/local.c b/src/transports/local.c index 0656ea592..0983914b1 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -10,7 +10,7 @@ #include "pack-objects.h" #include "refs.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "repository.h" #include "odb.h" #include "push.h" @@ -226,7 +226,7 @@ static int local_connect( t->flags = flags; /* 'url' may be a url or path; convert to a path */ - if ((error = git_path_from_url_or_path(&buf, url)) < 0) { + if ((error = git_fs_path_from_url_or_path(&buf, url)) < 0) { git_str_dispose(&buf); return error; } @@ -352,7 +352,7 @@ static int local_push( GIT_UNUSED(cbs); /* 'push->remote->url' may be a url or path; convert to a path */ - if ((error = git_path_from_url_or_path(&buf, push->remote->url)) < 0) { + if ((error = git_fs_path_from_url_or_path(&buf, push->remote->url)) < 0) { git_str_dispose(&buf); return error; } diff --git a/src/tree.c b/src/tree.c index c1e39158d..256e72080 100644 --- a/src/tree.c +++ b/src/tree.c @@ -13,6 +13,7 @@ #include "futils.h" #include "tree-cache.h" #include "index.h" +#include "path.h" #define DEFAULT_TREE_SIZE 16 #define MAX_FILEMODE_BYTES 6 @@ -55,7 +56,7 @@ static int valid_entry_name(git_repository *repo, const char *filename) { return *filename != '\0' && git_path_validate(repo, filename, 0, - GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH); + GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_FS_PATH_REJECT_SLASH); } static int entry_sort_cmp(const void *a, const void *b) @@ -63,7 +64,7 @@ static int entry_sort_cmp(const void *a, const void *b) const git_tree_entry *e1 = (const git_tree_entry *)a; const git_tree_entry *e2 = (const git_tree_entry *)b; - return git_path_cmp( + return git_fs_path_cmp( e1->filename, e1->filename_len, git_tree_entry__is_tree(e1), e2->filename, e2->filename_len, git_tree_entry__is_tree(e2), git__strncmp); @@ -1171,7 +1172,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli /* Figure out how much we need to change from the previous tree */ if (last_update) - common_prefix = git_path_common_dirlen(last_update->path, update->path); + common_prefix = git_fs_path_common_dirlen(last_update->path, update->path); /* * The entries are sorted, so when we find we're no @@ -1233,7 +1234,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli { /* Make sure we're replacing something of the same type */ tree_stack_entry *last = git_array_last(stack); - char *basename = git_path_basename(update->path); + char *basename = git_fs_path_basename(update->path); const git_tree_entry *e = git_treebuilder_get(last->bld, basename); if (e && git_tree_entry_type(e) != git_object__type_from_filemode(update->filemode)) { git__free(basename); @@ -1252,7 +1253,7 @@ int git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseli case GIT_TREE_UPDATE_REMOVE: { tree_stack_entry *last = git_array_last(stack); - char *basename = git_path_basename(update->path); + char *basename = git_fs_path_basename(update->path); error = git_treebuilder_remove(last->bld, basename); git__free(basename); break; diff --git a/src/win32/findfile.c b/src/win32/findfile.c index caa79398a..7578d960e 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -44,7 +44,7 @@ static int win32_path_to_8(git_str *dest, const wchar_t *src) } /* Convert backslashes to forward slashes */ - git_path_mkposix(utf8_path); + git_fs_path_mkposix(utf8_path); return git_str_sets(dest, utf8_path); } diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index e6640c85e..1f765f1de 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -57,7 +57,7 @@ static wchar_t *path__skip_server(wchar_t *path) wchar_t *c; for (c = path; *c; c++) { - if (git_path_is_dirsep(*c)) + if (git_fs_path_is_dirsep(*c)) return c + 1; } @@ -71,9 +71,9 @@ static wchar_t *path__skip_prefix(wchar_t *path) if (wcsncmp(path, L"UNC\\", 4) == 0) path = path__skip_server(path + 4); - else if (git_path_is_absolute(path)) + else if (git_fs_path_is_absolute(path)) path += PATH__ABSOLUTE_LEN; - } else if (git_path_is_absolute(path)) { + } else if (git_fs_path_is_absolute(path)) { path += PATH__ABSOLUTE_LEN; } else if (path__is_unc(path)) { path = path__skip_server(path + 2); @@ -204,7 +204,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) dest += PATH__NT_NAMESPACE_LEN; /* See if this is an absolute path (beginning with a drive letter) */ - if (git_path_is_absolute(src)) { + if (git_fs_path_is_absolute(src)) { if (git__utf8_to_16(dest, GIT_WIN_PATH_MAX, src) < 0) goto on_error; } @@ -228,7 +228,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) if (path__cwd(dest, GIT_WIN_PATH_MAX) < 0) goto on_error; - if (!git_path_is_absolute(dest)) { + if (!git_fs_path_is_absolute(dest)) { errno = ENOENT; goto on_error; } @@ -266,7 +266,7 @@ int git_win32_path_relative_from_utf8(git_win32_path out, const char *src) int len; /* Handle absolute paths */ - if (git_path_is_absolute(src) || + if (git_fs_path_is_absolute(src) || path__is_nt_namespace(src) || path__is_unc(src) || path__startswith_slash(src)) { @@ -305,7 +305,7 @@ int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src) if ((len = git__utf16_to_8(out, GIT_WIN_PATH_UTF8, src)) < 0) return len; - git_path_mkposix(dest); + git_fs_path_mkposix(dest); return len; } diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index f26983d97..398287f9e 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -418,10 +418,10 @@ static bool target_is_dir(const char *target, const char *path) git_win32_path resolved_w; bool isdir = true; - if (git_path_is_absolute(target)) + if (git_fs_path_is_absolute(target)) git_win32_path_from_utf8(resolved_w, target); - else if (git_path_dirname_r(&resolved, path) < 0 || - git_path_apply_relative(&resolved, target) < 0 || + else if (git_fs_path_dirname_r(&resolved, path) < 0 || + git_fs_path_apply_relative(&resolved, target) < 0 || git_win32_path_from_utf8(resolved_w, resolved.ptr) < 0) goto out; @@ -661,7 +661,7 @@ int p_getcwd(char *buffer_out, size_t size) return -1; } - git_path_mkposix(buffer_out); + git_fs_path_mkposix(buffer_out); return 0; } @@ -821,7 +821,7 @@ char *p_realpath(const char *orig_path, char *buffer) if (git_win32_path_to_utf8(buffer, buffer_w) < 0) return NULL; - git_path_mkposix(buffer); + git_fs_path_mkposix(buffer); return buffer; } diff --git a/src/worktree.c b/src/worktree.c index 92a0900b0..f0fc6d752 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -22,9 +22,9 @@ static bool is_worktree_dir(const char *dir) if (git_str_sets(&buf, dir) < 0) return -1; - error = git_path_contains_file(&buf, "commondir") - && git_path_contains_file(&buf, "gitdir") - && git_path_contains_file(&buf, "HEAD"); + error = git_fs_path_contains_file(&buf, "commondir") + && git_fs_path_contains_file(&buf, "gitdir") + && git_fs_path_contains_file(&buf, "HEAD"); git_str_dispose(&buf); return error; @@ -46,9 +46,9 @@ int git_worktree_list(git_strarray *wts, git_repository *repo) if ((error = git_str_joinpath(&path, repo->commondir, "worktrees/")) < 0) goto exit; - if (!git_path_exists(path.ptr) || git_path_is_empty_dir(path.ptr)) + if (!git_fs_path_exists(path.ptr) || git_fs_path_is_empty_dir(path.ptr)) goto exit; - if ((error = git_path_dirload(&worktrees, path.ptr, path.size, 0x0)) < 0) + if ((error = git_fs_path_dirload(&worktrees, path.ptr, path.size, 0x0)) < 0) goto exit; len = path.size; @@ -86,12 +86,12 @@ char *git_worktree__read_link(const char *base, const char *file) git_str_rtrim(&buf); - if (!git_path_is_relative(buf.ptr)) + if (!git_fs_path_is_relative(buf.ptr)) return git_str_detach(&buf); if (git_str_sets(&path, base) < 0) goto err; - if (git_path_apply_relative(&path, buf.ptr) < 0) + if (git_fs_path_apply_relative(&path, buf.ptr) < 0) goto err; git_str_dispose(&buf); @@ -136,7 +136,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char goto out; } - if ((error = git_path_validate_workdir(NULL, dir)) < 0) + if ((error = git_fs_path_validate_workdir(NULL, dir)) < 0) goto out; if ((wt = git__calloc(1, sizeof(*wt))) == NULL) { @@ -148,12 +148,12 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL || (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL || (parent && (wt->parent_path = git__strdup(parent)) == NULL) || - (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) { + (wt->worktree_path = git_fs_path_dirname(wt->gitlink_path)) == NULL) { error = -1; goto out; } - if ((error = git_path_prettify_dir(&gitdir, dir, NULL)) < 0) + if ((error = git_fs_path_prettify_dir(&gitdir, dir, NULL)) < 0) goto out; wt->gitdir_path = git_str_detach(&gitdir); @@ -214,11 +214,11 @@ int git_worktree_open_from_repository(git_worktree **out, git_repository *repo) gitdir = git_repository_path(repo); commondir = git_repository_commondir(repo); - if ((error = git_path_prettify_dir(&parent, "..", commondir)) < 0) + if ((error = git_fs_path_prettify_dir(&parent, "..", commondir)) < 0) goto out; /* The name is defined by the last component in '.git/worktree/%s' */ - name = git_path_basename(gitdir); + name = git_fs_path_basename(gitdir); if ((error = open_worktree_dir(out, parent.ptr, gitdir, name)) < 0) goto out; @@ -255,21 +255,21 @@ int git_worktree_validate(const git_worktree *wt) return GIT_ERROR; } - if (wt->parent_path && !git_path_exists(wt->parent_path)) { + if (wt->parent_path && !git_fs_path_exists(wt->parent_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree parent directory ('%s') does not exist ", wt->parent_path); return GIT_ERROR; } - if (!git_path_exists(wt->commondir_path)) { + if (!git_fs_path_exists(wt->commondir_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree common directory ('%s') does not exist ", wt->commondir_path); return GIT_ERROR; } - if (!git_path_exists(wt->worktree_path)) { + if (!git_fs_path_exists(wt->worktree_path)) { git_error_set(GIT_ERROR_WORKTREE, "worktree directory '%s' does not exist", wt->worktree_path); @@ -337,20 +337,20 @@ int git_worktree_add(git_worktree **out, git_repository *repo, /* Create gitdir directory ".git/worktrees/" */ if ((err = git_str_joinpath(&gitdir, repo->commondir, "worktrees")) < 0) goto out; - if (!git_path_exists(gitdir.ptr)) + if (!git_fs_path_exists(gitdir.ptr)) if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; if ((err = git_str_joinpath(&gitdir, gitdir.ptr, name)) < 0) goto out; if ((err = git_futils_mkdir(gitdir.ptr, 0755, GIT_MKDIR_EXCL)) < 0) goto out; - if ((err = git_path_prettify_dir(&gitdir, gitdir.ptr, NULL)) < 0) + if ((err = git_fs_path_prettify_dir(&gitdir, gitdir.ptr, NULL)) < 0) goto out; /* Create worktree work dir */ if ((err = git_futils_mkdir(worktree, 0755, GIT_MKDIR_EXCL)) < 0) goto out; - if ((err = git_path_prettify_dir(&wddir, worktree, NULL)) < 0) + if ((err = git_fs_path_prettify_dir(&wddir, worktree, NULL)) < 0) goto out; if (wtopts.lock) { @@ -375,7 +375,7 @@ int git_worktree_add(git_worktree **out, git_repository *repo, goto out; /* Create gitdir files */ - if ((err = git_path_prettify_dir(&buf, repo->commondir, NULL) < 0) + if ((err = git_fs_path_prettify_dir(&buf, repo->commondir, NULL) < 0) || (err = git_str_putc(&buf, '\n')) < 0 || (err = write_wtfile(gitdir.ptr, "commondir", &buf)) < 0) goto out; @@ -494,7 +494,7 @@ static int git_worktree__is_locked(git_str *reason, const git_worktree *wt) if ((error = git_str_joinpath(&path, wt->gitdir_path, "locked")) < 0) goto out; - locked = git_path_exists(path.ptr); + locked = git_fs_path_exists(path.ptr); if (locked && reason && (error = git_futils_readbuffer(reason, path.ptr)) < 0) goto out; @@ -614,7 +614,7 @@ int git_worktree_prune(git_worktree *wt, /* Delete gitdir in parent repository */ if ((err = git_str_join3(&path, '/', wt->commondir_path, "worktrees", wt->name)) < 0) goto out; - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) { git_error_set(GIT_ERROR_WORKTREE, "worktree gitdir '%s' does not exist", path.ptr); err = -1; @@ -626,15 +626,15 @@ int git_worktree_prune(git_worktree *wt, /* Skip deletion of the actual working tree if it does * not exist or deletion was not requested */ if ((popts.flags & GIT_WORKTREE_PRUNE_WORKING_TREE) == 0 || - !git_path_exists(wt->gitlink_path)) + !git_fs_path_exists(wt->gitlink_path)) { goto out; } - if ((wtpath = git_path_dirname(wt->gitlink_path)) == NULL) + if ((wtpath = git_fs_path_dirname(wt->gitlink_path)) == NULL) goto out; git_str_attach(&path, wtpath, 0); - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) { git_error_set(GIT_ERROR_WORKTREE, "working tree '%s' does not exist", path.ptr); err = -1; diff --git a/tests/attr/repo.c b/tests/attr/repo.c index e7b975290..abd238154 100644 --- a/tests/attr/repo.c +++ b/tests/attr/repo.c @@ -283,7 +283,7 @@ void test_attr_repo__bare_repo_with_index(void) git_index_free(index); cl_must_pass(p_unlink("attr/.gitattributes")); - cl_assert(!git_path_exists("attr/.gitattributes")); + cl_assert(!git_fs_path_exists("attr/.gitattributes")); cl_git_pass(git_repository_set_bare(g_repo)); diff --git a/tests/checkout/conflict.c b/tests/checkout/conflict.c index 3f5e7162d..4a9e4b9fa 100644 --- a/tests/checkout/conflict.c +++ b/tests/checkout/conflict.c @@ -227,7 +227,7 @@ void test_checkout_conflict__ignored(void) cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/conflicting.txt")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/conflicting.txt")); } void test_checkout_conflict__ours(void) @@ -1030,15 +1030,15 @@ void test_checkout_conflict__update_only(void) ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE); ensure_workdir("directory_file-two/file", 0100644, CONFLICTING_OURS_OID); - cl_assert(!git_path_exists("merge-resolve/modify-delete")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one-side-one.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one-side-two.txt")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt~ours")); - cl_assert(!git_path_exists("merge-resolve/test-one.txt~theirs")); - cl_assert(!git_path_exists("merge-resolve/directory_file-one/file")); - cl_assert(!git_path_exists("merge-resolve/directory_file-one~ours")); - cl_assert(!git_path_exists("merge-resolve/directory_file-two~theirs")); + cl_assert(!git_fs_path_exists("merge-resolve/modify-delete")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-one.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-two.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~ours")); + cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~theirs")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one/file")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one~ours")); + cl_assert(!git_fs_path_exists("merge-resolve/directory_file-two~theirs")); } void test_checkout_conflict__path_filters(void) @@ -1076,9 +1076,9 @@ void test_checkout_conflict__path_filters(void) cl_git_pass(git_checkout_index(g_repo, g_index, &opts)); ensure_workdir_contents("conflicting-1.txt", CONFLICTING_DIFF3_FILE); - cl_assert(!git_path_exists("merge-resolve/conflicting-2.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/conflicting-2.txt")); ensure_workdir_contents("conflicting-3.txt", AUTOMERGEABLE_MERGED_FILE); - cl_assert(!git_path_exists("merge-resolve/conflicting-4.txt")); + cl_assert(!git_fs_path_exists("merge-resolve/conflicting-4.txt")); } static void collect_progress( diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index eb4c61f39..8fd16a004 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -17,7 +17,7 @@ static int unlink_file(void *payload, git_str *path) { char *fn; - cl_assert(fn = git_path_basename(path->ptr)); + cl_assert(fn = git_fs_path_basename(path->ptr)); GIT_UNUSED(payload); @@ -39,7 +39,7 @@ void test_checkout_crlf__initialize(void) * check out over it. */ cl_git_pass(git_str_puts(&reponame, "crlf")); - cl_git_pass(git_path_direach(&reponame, 0, unlink_file, NULL)); + cl_git_pass(git_fs_path_direach(&reponame, 0, unlink_file, NULL)); if (GIT_EOL_NATIVE == GIT_EOL_CRLF) systype = "windows"; @@ -76,7 +76,7 @@ static int compare_file(void *payload, git_str *actual_path) int cmp_git, cmp_gitattributes; char *basename; - basename = git_path_basename(actual_path->ptr); + basename = git_fs_path_basename(actual_path->ptr); cmp_git = strcmp(basename, ".git"); cmp_gitattributes = strcmp(basename, ".gitattributes"); @@ -87,8 +87,8 @@ static int compare_file(void *payload, git_str *actual_path) cl_git_pass(git_str_joinpath(&expected_path, cd->dirname, basename)); - if (!git_path_isfile(expected_path.ptr) || - !git_path_isfile(actual_path->ptr)) + if (!git_fs_path_isfile(expected_path.ptr) || + !git_fs_path_isfile(actual_path->ptr)) goto done; if (git_futils_readbuffer(&actual_contents, actual_path->ptr) < 0 || @@ -107,7 +107,7 @@ done: if (failed) { git_str details = GIT_STR_INIT; git_str_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}", - git_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs); + git_fs_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs); clar__fail(__FILE__, __func__, __LINE__, "checked out contents did not match expected", details.ptr, 0); git_str_dispose(&details); @@ -166,7 +166,7 @@ static void test_checkout(const char *autocrlf, const char *attrs) cl_git_pass(git_checkout_head(g_repo, &opts)); compare_data.dirname = sandboxname.ptr; - cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data)); + cl_git_pass(git_fs_path_direach(&reponame, 0, compare_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); git_str_dispose(&expected_fixture); @@ -187,9 +187,9 @@ static void empty_workdir(const char *name) size_t i; const char *fn; - cl_git_pass(git_path_dirload(&contents, name, 0, 0)); + cl_git_pass(git_fs_path_dirload(&contents, name, 0, 0)); git_vector_foreach(&contents, i, fn) { - cl_assert(basename = git_path_basename(fn)); + cl_assert(basename = git_fs_path_basename(fn)); cmp = strncasecmp(basename, ".git", 4); git__free(basename); diff --git a/tests/checkout/head.c b/tests/checkout/head.c index 5b3a034e7..3b0bf4729 100644 --- a/tests/checkout/head.c +++ b/tests/checkout/head.c @@ -43,7 +43,7 @@ void test_checkout_head__with_index_only_tree(void) cl_git_pass(git_index_add_bypath(index, "newdir/newfile.txt")); cl_git_pass(git_index_write(index)); - cl_assert(git_path_isfile("testrepo/newdir/newfile.txt")); + cl_assert(git_fs_path_isfile("testrepo/newdir/newfile.txt")); cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) != NULL); git_index_free(index); @@ -55,7 +55,7 @@ void test_checkout_head__with_index_only_tree(void) cl_git_pass(git_repository_index(&index, g_repo)); - cl_assert(!git_path_isfile("testrepo/newdir/newfile.txt")); + cl_assert(!git_fs_path_isfile("testrepo/newdir/newfile.txt")); cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) == NULL); git_index_free(index); @@ -79,8 +79,8 @@ void test_checkout_head__do_not_remove_untracked_file(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/tracked/tracked")); - cl_assert(git_path_isfile("testrepo/tracked/untracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/untracked")); } void test_checkout_head__do_not_remove_untracked_file_in_subdir(void) @@ -104,9 +104,9 @@ void test_checkout_head__do_not_remove_untracked_file_in_subdir(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/tracked/tracked")); - cl_assert(!git_path_isfile("testrepo/tracked/subdir/tracked")); - cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/subdir/tracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/subdir/untracked")); } void test_checkout_head__do_remove_untracked_paths(void) @@ -131,8 +131,8 @@ void test_checkout_head__do_remove_untracked_paths(void) opts.paths.count = 1; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(git_path_isfile("testrepo/tracked/tracked")); - cl_assert(!git_path_isfile("testrepo/tracked/untracked")); + cl_assert(git_fs_path_isfile("testrepo/tracked/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/tracked/untracked")); } void test_checkout_head__do_remove_tracked_subdir(void) @@ -158,9 +158,9 @@ void test_checkout_head__do_remove_tracked_subdir(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/subdir/tracked")); - cl_assert(!git_path_isfile("testrepo/subdir/tracked-file")); - cl_assert(git_path_isfile("testrepo/subdir/untracked-file")); + cl_assert(!git_fs_path_isdir("testrepo/subdir/tracked")); + cl_assert(!git_fs_path_isfile("testrepo/subdir/tracked-file")); + cl_assert(git_fs_path_isfile("testrepo/subdir/untracked-file")); } void test_checkout_head__typechange_workdir(void) diff --git a/tests/checkout/icase.c b/tests/checkout/icase.c index 6c30765a3..d77c7abd5 100644 --- a/tests/checkout/icase.c +++ b/tests/checkout/icase.c @@ -50,8 +50,8 @@ static char *get_filename(const char *in) DIR *dir; struct dirent *de; - cl_assert(search_dirname = git_path_dirname(in)); - cl_assert(search_filename = git_path_basename(in)); + cl_assert(search_dirname = git_fs_path_dirname(in)); + cl_assert(search_filename = git_fs_path_basename(in)); cl_assert(dir = opendir(search_dirname)); @@ -134,7 +134,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_files(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("tmp")); + cl_assert(!git_fs_path_exists("tmp")); assert_name_is("testrepo/BRANCH_FILE.txt"); } @@ -146,7 +146,7 @@ void test_checkout_icase__overwrites_links_for_files_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("tmp")); + cl_assert(!git_fs_path_exists("tmp")); assert_name_is("testrepo/new.txt"); } @@ -159,7 +159,7 @@ void test_checkout_icase__overwrites_empty_folders_for_files(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/new.txt"); - cl_assert(!git_path_isdir("testrepo/new.txt")); + cl_assert(!git_fs_path_isdir("testrepo/new.txt")); } void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void) @@ -173,7 +173,7 @@ void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/BRANCH_FILE.txt"); - cl_assert(git_path_isdir("testrepo/BRANCH_FILE.txt")); + cl_assert(git_fs_path_isdir("testrepo/BRANCH_FILE.txt")); } void test_checkout_icase__overwrites_folders_for_files_when_forced(void) @@ -187,7 +187,7 @@ void test_checkout_icase__overwrites_folders_for_files_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/new.txt"); - cl_assert(!git_path_isdir("testrepo/new.txt")); + cl_assert(!git_fs_path_isdir("testrepo/new.txt")); } void test_checkout_icase__refuses_to_overwrite_files_for_folders(void) @@ -199,7 +199,7 @@ void test_checkout_icase__refuses_to_overwrite_files_for_folders(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/A"); - cl_assert(!git_path_isdir("testrepo/A")); + cl_assert(!git_fs_path_isdir("testrepo/A")); } void test_checkout_icase__overwrites_files_for_folders_when_forced(void) @@ -211,7 +211,7 @@ void test_checkout_icase__overwrites_files_for_folders_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); assert_name_is("testrepo/a"); - cl_assert(git_path_isdir("testrepo/a")); + cl_assert(git_fs_path_isdir("testrepo/a")); } void test_checkout_icase__refuses_to_overwrite_links_for_folders(void) @@ -222,7 +222,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_folders(void) cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("b.txt")); + cl_assert(!git_fs_path_exists("b.txt")); assert_name_is("testrepo/A"); } @@ -234,7 +234,7 @@ void test_checkout_icase__overwrites_links_for_folders_when_forced(void) cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts)); - cl_assert(!git_path_exists("b.txt")); + cl_assert(!git_fs_path_exists("b.txt")); assert_name_is("testrepo/a"); } diff --git a/tests/checkout/index.c b/tests/checkout/index.c index 13eecc984..6a80d22c5 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -56,9 +56,9 @@ void test_checkout_index__can_create_missing_files(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; @@ -77,7 +77,7 @@ void test_checkout_index__can_remove_untracked_files(void) cl_git_mkfile("./testrepo/dir/one", "one\n"); cl_git_mkfile("./testrepo/dir/subdir/two", "two\n"); - cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir")); + cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/dir/subdir/subsubdir")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | @@ -86,7 +86,7 @@ void test_checkout_index__can_remove_untracked_files(void) cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/dir")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/dir")); } void test_checkout_index__can_disable_pathspec_match(void) @@ -152,15 +152,15 @@ void test_checkout_index__honor_the_specified_pathspecs(void) opts.paths.strings = entries; opts.paths.count = 1; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n"); check_file_contents("./testrepo/new.txt", "my new file\n"); } @@ -236,7 +236,7 @@ void test_checkout_index__honor_coresymlinks_default_true(void) cl_must_pass(p_mkdir("symlink", 0777)); - if (!git_path_supports_symlinks("symlink/test")) + if (!git_fs_path_supports_symlinks("symlink/test")) cl_skip(); #ifdef GIT_WIN32 @@ -269,7 +269,7 @@ void test_checkout_index__honor_coresymlinks_default_false(void) * supports symlinks. Bail entirely on POSIX platforms that * do support symlinks. */ - if (git_path_supports_symlinks("symlink/test")) + if (git_fs_path_supports_symlinks("symlink/test")) cl_skip(); #endif @@ -281,7 +281,7 @@ void test_checkout_index__coresymlinks_set_to_true_fails_when_unsupported(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - if (git_path_supports_symlinks("testrepo/test")) { + if (git_fs_path_supports_symlinks("testrepo/test")) { cl_skip(); } @@ -297,7 +297,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void) char link_data[GIT_PATH_MAX]; size_t link_size = GIT_PATH_MAX; - if (!git_path_supports_symlinks("testrepo/test")) { + if (!git_fs_path_supports_symlinks("testrepo/test")) { cl_skip(); } @@ -578,8 +578,8 @@ void test_checkout_index__can_overcome_name_clashes(void) cl_git_pass(p_mkdir("./testrepo/path0", 0777)); cl_git_mkfile("./testrepo/path0/file0", "content\r\n"); - cl_assert(git_path_isfile("./testrepo/path1")); - cl_assert(git_path_isfile("./testrepo/path0/file0")); + cl_assert(git_fs_path_isfile("./testrepo/path1")); + cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | @@ -587,14 +587,14 @@ void test_checkout_index__can_overcome_name_clashes(void) GIT_CHECKOUT_ALLOW_CONFLICTS; cl_git_pass(git_checkout_index(g_repo, index, &opts)); - cl_assert(git_path_isfile("./testrepo/path1")); - cl_assert(git_path_isfile("./testrepo/path0/file0")); + cl_assert(git_fs_path_isfile("./testrepo/path1")); + cl_assert(git_fs_path_isfile("./testrepo/path0/file0")); opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_index(g_repo, index, &opts)); - cl_assert(git_path_isfile("./testrepo/path0")); - cl_assert(git_path_isfile("./testrepo/path1/file1")); + cl_assert(git_fs_path_isfile("./testrepo/path0")); + cl_assert(git_fs_path_isfile("./testrepo/path1/file1")); git_index_free(index); } @@ -622,9 +622,9 @@ void test_checkout_index__can_update_prefixed_files(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); cl_git_mkfile("./testrepo/READ", "content\n"); cl_git_mkfile("./testrepo/README.after", "content\n"); @@ -647,10 +647,10 @@ void test_checkout_index__can_update_prefixed_files(void) check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n"); check_file_contents_nocr("./testrepo/new.txt", "my new file\n"); - cl_assert(!git_path_exists("testrepo/READ")); - cl_assert(!git_path_exists("testrepo/README.after")); - cl_assert(!git_path_exists("testrepo/branch_file")); - cl_assert(!git_path_exists("testrepo/branch_file.txt.after")); + cl_assert(!git_fs_path_exists("testrepo/READ")); + cl_assert(!git_fs_path_exists("testrepo/README.after")); + cl_assert(!git_fs_path_exists("testrepo/branch_file")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt.after")); } void test_checkout_index__can_checkout_a_newly_initialized_repository(void) @@ -688,7 +688,7 @@ void test_checkout_index__target_directory(void) opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL; opts.notify_cb = checkout_count_callback; @@ -741,7 +741,7 @@ void test_checkout_index__target_directory_from_bare(void) cl_git_fail(git_checkout_index(g_repo, NULL, &opts)); opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); @@ -765,9 +765,9 @@ void test_checkout_index__can_get_repo_from_index(void) git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; - cl_assert_equal_i(false, git_path_isfile("./testrepo/README")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt")); - cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt")); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; diff --git a/tests/checkout/nasty.c b/tests/checkout/nasty.c index a1b3164be..732f1d5e8 100644 --- a/tests/checkout/nasty.c +++ b/tests/checkout/nasty.c @@ -38,7 +38,7 @@ static void test_checkout_passes(const char *refname, const char *filename) GIT_CHECKOUT_DONT_UPDATE_INDEX; cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); git_commit_free(commit); git_str_dispose(&path); @@ -59,7 +59,7 @@ static void test_checkout_fails(const char *refname, const char *filename) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_fail(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); git_commit_free(commit); git_str_dispose(&path); @@ -246,7 +246,7 @@ void test_checkout_nasty__only_looks_like_a_git_shortname(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts)); - cl_assert(git_path_exists("nasty/git~3/foobar")); + cl_assert(git_fs_path_exists("nasty/git~3/foobar")); git_commit_free(commit); #endif diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index cdfb456b7..2f54f4e3e 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -34,7 +34,7 @@ void test_checkout_tree__cleanup(void) cl_git_sandbox_cleanup(); - if (git_path_isdir("alternative")) + if (git_fs_path_isdir("alternative")) git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES); } @@ -54,17 +54,17 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_commit(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt")); } void test_checkout_tree__can_checkout_and_remove_directory(void) { - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); /* Checkout brach "subtrees" and update HEAD, so that HEAD matches the * current working tree @@ -74,9 +74,9 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt")); git_object_free(g_object); g_object = NULL; @@ -90,7 +90,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); /* This directory should no longer exist */ - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); } void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void) @@ -102,12 +102,12 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void) cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees:ab")); - cl_assert_equal_i(false, git_path_isdir("./testrepo/de/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/de/")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/de/2.txt")); - cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/fgh/1.txt")); } static void progress(const char *path, size_t cur, size_t tot, void *payload) @@ -149,7 +149,7 @@ void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void) */ opts.checkout_strategy = GIT_CHECKOUT_NONE; git_checkout_tree(g_repo, (git_object*)p_chomped_commit, &opts); - cl_assert_equal_i(false, git_path_isfile("testrepo/readme.txt")); + cl_assert_equal_i(false, git_fs_path_isfile("testrepo/readme.txt")); git_commit_free(p_master_commit); git_commit_free(p_chomped_commit); @@ -174,12 +174,12 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); - cl_assert(!git_path_isdir("testrepo/ab")); + cl_assert(!git_fs_path_isdir("testrepo/ab")); assert_on_branch(g_repo, "dir"); @@ -194,15 +194,15 @@ void test_checkout_tree__can_switch_branches(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); - cl_assert(git_path_isfile("testrepo/ab/c/3.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/2.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt")); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); assert_on_branch(g_repo, "subtrees"); @@ -216,11 +216,11 @@ void test_checkout_tree__can_remove_untracked(void) opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_UNTRACKED; cl_git_mkfile("testrepo/untracked_file", "as you wish"); - cl_assert(git_path_isfile("testrepo/untracked_file")); + cl_assert(git_fs_path_isfile("testrepo/untracked_file")); cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/untracked_file")); + cl_assert(!git_fs_path_isfile("testrepo/untracked_file")); } void test_checkout_tree__can_remove_ignored(void) @@ -237,11 +237,11 @@ void test_checkout_tree__can_remove_ignored(void) cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ignored_file")); cl_assert_equal_i(1, ignored); - cl_assert(git_path_isfile("testrepo/ignored_file")); + cl_assert(git_fs_path_isfile("testrepo/ignored_file")); cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isfile("testrepo/ignored_file")); + cl_assert(!git_fs_path_isfile("testrepo/ignored_file")); } static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) @@ -264,12 +264,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); - cl_assert(!git_path_isdir("testrepo/ab")); + cl_assert(!git_fs_path_isdir("testrepo/ab")); assert_on_branch(g_repo, "dir"); @@ -285,12 +285,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir) cl_git_mkfile("testrepo/ab/4.txt/file2.txt", "foo bar foo"); cl_git_mkfile("testrepo/ab/4.txt/file3.txt", "inky blinky pinky clyde"); - cl_assert(git_path_isdir("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isdir("testrepo/ab/4.txt")); } else { cl_must_pass(p_mkdir("testrepo/ab", 0777)); cl_git_mkfile("testrepo/ab/4.txt", "as you wish"); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); } cl_git_pass(git_ignore_add_rule(g_repo, "ab/4.txt\n")); @@ -324,7 +324,7 @@ void test_checkout_tree__can_overwrite_ignored_by_default(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); assert_on_branch(g_repo, "subtrees"); } @@ -345,7 +345,7 @@ void test_checkout_tree__can_overwrite_ignored_folder_by_default(void) cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); assert_on_branch(g_repo, "subtrees"); @@ -364,7 +364,7 @@ void test_checkout_tree__can_update_only(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); @@ -384,7 +384,7 @@ void test_checkout_tree__can_update_only(void) * the test_checkout_tree__can_switch_branches test), but with * UPDATE_ONLY it will not have been created. */ - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); /* but this file still should have been updated */ check_file_contents_nocr("testrepo/branch_file.txt", "hi\n"); @@ -410,10 +410,10 @@ void test_checkout_tree__can_checkout_with_pattern(void) git_object_free(g_object); g_object = NULL; - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(!git_path_exists("testrepo/link_to_new.txt")); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); /* now to a narrow patterned checkout */ @@ -425,10 +425,10 @@ void test_checkout_tree__can_checkout_with_pattern(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); } void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) @@ -445,10 +445,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master")); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(git_path_exists("testrepo/branch_file.txt")); - cl_assert(git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); git_object_free(g_object); cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479")); @@ -460,10 +460,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_exists("testrepo/README")); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); - cl_assert(!git_path_exists("testrepo/link_to_new.txt")); - cl_assert(git_path_exists("testrepo/new.txt")); + cl_assert(git_fs_path_exists("testrepo/README")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt")); + cl_assert(git_fs_path_exists("testrepo/new.txt")); } void test_checkout_tree__can_disable_pattern_match(void) @@ -484,7 +484,7 @@ void test_checkout_tree__can_disable_pattern_match(void) git_object_free(g_object); g_object = NULL; - cl_assert(!git_path_isfile("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt")); /* now to a narrow patterned checkout, but disable pattern */ @@ -498,7 +498,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(!git_path_isfile("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt")); /* let's try that again, but allow the pattern match */ @@ -506,7 +506,7 @@ void test_checkout_tree__can_disable_pattern_match(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); } void assert_conflict( @@ -623,7 +623,7 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void) cl_git_pass(git_index_remove_bypath(index ,"branch_file.txt")); cl_git_pass(git_index_write(index)); - cl_assert(!git_path_exists("testrepo/branch_file.txt")); + cl_assert(!git_fs_path_exists("testrepo/branch_file.txt")); cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff")); cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id)); @@ -686,16 +686,16 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) opts.notify_payload = &ca; opts.checkout_strategy = GIT_CHECKOUT_FORCE; - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), -5555); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); /* on case-insensitive FS = a/b.txt, branch_file.txt, new.txt */ /* on case-sensitive FS = README, then above */ - if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ + if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ cl_assert_equal_i(3, ca.count); else cl_assert_equal_i(4, ca.count); @@ -707,9 +707,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), 123); - cl_assert(!git_path_exists("testrepo/new.txt")); + cl_assert(!git_fs_path_exists("testrepo/new.txt")); - if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ + if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */ cl_assert_equal_i(4, ca.count); else cl_assert_equal_i(1, ca.count); @@ -799,7 +799,7 @@ void test_checkout_tree__can_write_to_empty_dirs(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); } @@ -818,7 +818,7 @@ void test_checkout_tree__fails_when_dir_in_use(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); @@ -831,7 +831,7 @@ void test_checkout_tree__fails_when_dir_in_use(void) cl_git_pass(p_chdir("../..")); - cl_assert(git_path_is_empty_dir("testrepo/a")); + cl_assert(git_fs_path_is_empty_dir("testrepo/a")); git_object_free(obj); #endif @@ -852,7 +852,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); - cl_assert(git_path_isfile("testrepo/a/b.txt")); + cl_assert(git_fs_path_isfile("testrepo/a/b.txt")); git_object_free(obj); @@ -865,7 +865,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void) cl_git_pass(p_chdir("../..")); - cl_assert(git_path_is_empty_dir("testrepo/a")); + cl_assert(git_fs_path_is_empty_dir("testrepo/a")); git_object_free(obj); #endif @@ -896,7 +896,7 @@ void test_checkout_tree__target_directory_from_bare(void) cl_git_fail(git_checkout_tree(g_repo, g_object, &opts)); opts.target_directory = "alternative"; - cl_assert(!git_path_isdir("alternative")); + cl_assert(!git_fs_path_isdir("alternative")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); @@ -923,12 +923,12 @@ void test_checkout_tree__extremely_long_file_name(void) cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); sprintf(path, "testrepo/%s.txt", longname); - cl_assert(git_path_exists(path)); + cl_assert(git_fs_path_exists(path)); git_object_free(g_object); cl_git_pass(git_revparse_single(&g_object, g_repo, "master")); cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts)); - cl_assert(!git_path_exists(path)); + cl_assert(!git_fs_path_exists(path)); } static void create_conflict(const char *path) @@ -1138,7 +1138,7 @@ void test_checkout_tree__removes_conflicts(void) cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 2)); cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 3)); - cl_assert(!git_path_exists("testrepo/other.txt")); + cl_assert(!git_fs_path_exists("testrepo/other.txt")); git_commit_free(commit); git_index_free(index); @@ -1183,7 +1183,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void) cl_assert(git_index_get_bypath(index, "other.txt", 2) != NULL); cl_assert(git_index_get_bypath(index, "other.txt", 3) != NULL); - cl_assert(git_path_exists("testrepo/other.txt")); + cl_assert(git_fs_path_exists("testrepo/other.txt")); git_commit_free(commit); git_index_free(index); @@ -1214,8 +1214,8 @@ void test_checkout_tree__case_changing_rename(void) cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir")); - cl_assert(git_path_isfile("testrepo/README")); - case_sensitive = !git_path_isfile("testrepo/readme"); + cl_assert(git_fs_path_isfile("testrepo/README")); + case_sensitive = !git_fs_path_isfile("testrepo/readme"); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); @@ -1235,9 +1235,9 @@ void test_checkout_tree__case_changing_rename(void) cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit)); - cl_assert(git_path_isfile("testrepo/readme")); + cl_assert(git_fs_path_isfile("testrepo/readme")); if (case_sensitive) - cl_assert(!git_path_isfile("testrepo/README")); + cl_assert(!git_fs_path_isfile("testrepo/README")); cl_assert(index_entry = git_index_get_bypath(index, "readme", 0)); cl_assert_equal_s("readme", index_entry->path); @@ -1253,9 +1253,9 @@ void test_checkout_tree__case_changing_rename(void) assert_on_branch(g_repo, "master"); - cl_assert(git_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/README")); if (case_sensitive) - cl_assert(!git_path_isfile("testrepo/readme")); + cl_assert(!git_fs_path_isfile("testrepo/readme")); cl_assert(index_entry = git_index_get_bypath(index, "README", 0)); cl_assert_equal_s("README", index_entry->path); @@ -1366,13 +1366,13 @@ void test_checkout_tree__can_not_update_index(void) cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_WT_NEW, status); @@ -1403,13 +1403,13 @@ void test_checkout_tree__can_update_but_not_write_index(void) cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts)); - cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/")); + cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/")); cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees")); cl_git_pass(git_checkout_tree(g_repo, g_object, &opts)); - cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt")); + cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt")); cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt")); cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status); @@ -1450,15 +1450,15 @@ void test_checkout_tree__safe_proceeds_if_no_index(void) cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees")); - cl_assert(git_path_isfile("testrepo/README")); - cl_assert(git_path_isfile("testrepo/branch_file.txt")); - cl_assert(git_path_isfile("testrepo/new.txt")); - cl_assert(git_path_isfile("testrepo/ab/4.txt")); - cl_assert(git_path_isfile("testrepo/ab/c/3.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/2.txt")); - cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt")); + cl_assert(git_fs_path_isfile("testrepo/README")); + cl_assert(git_fs_path_isfile("testrepo/branch_file.txt")); + cl_assert(git_fs_path_isfile("testrepo/new.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/4.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt")); + cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt")); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); assert_on_branch(g_repo, "subtrees"); @@ -1650,7 +1650,7 @@ void test_checkout_tree__dry_run(void) opts.checkout_strategy = GIT_CHECKOUT_FORCE; cl_git_pass(git_checkout_head(g_repo, &opts)); - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); @@ -1673,7 +1673,7 @@ void test_checkout_tree__dry_run(void) /* these normally would have been created and updated, but with * DRY_RUN they will be unchanged. */ - cl_assert(!git_path_isdir("testrepo/a")); + cl_assert(!git_fs_path_isdir("testrepo/a")); check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n"); /* check that notify callback was invoked */ diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index 205ce657f..b888843f0 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -76,12 +76,12 @@ void test_checkout_typechange__cleanup(void) static void assert_file_exists(const char *path) { - cl_assert_(git_path_isfile(path), path); + cl_assert_(git_fs_path_isfile(path), path); } static void assert_dir_exists(const char *path) { - cl_assert_(git_path_isdir(path), path); + cl_assert_(git_fs_path_isdir(path), path); } static void assert_workdir_matches_tree( @@ -126,7 +126,7 @@ static void assert_workdir_matches_tree( /* because of cross-platform, don't confirm exec bit yet */ break; case GIT_FILEMODE_LINK: - cl_assert_(git_path_exists(path.ptr), path.ptr); + cl_assert_(git_fs_path_exists(path.ptr), path.ptr); /* because of cross-platform, don't confirm link yet */ break; default: @@ -163,19 +163,19 @@ void test_checkout_typechange__checkout_typechanges_safe(void) git_object_free(obj); if (!g_typechange_empty[i]) { - cl_assert(git_path_isdir("typechanges")); - cl_assert(git_path_exists("typechanges/a")); - cl_assert(git_path_exists("typechanges/b")); - cl_assert(git_path_exists("typechanges/c")); - cl_assert(git_path_exists("typechanges/d")); - cl_assert(git_path_exists("typechanges/e")); + cl_assert(git_fs_path_isdir("typechanges")); + cl_assert(git_fs_path_exists("typechanges/a")); + cl_assert(git_fs_path_exists("typechanges/b")); + cl_assert(git_fs_path_exists("typechanges/c")); + cl_assert(git_fs_path_exists("typechanges/d")); + cl_assert(git_fs_path_exists("typechanges/e")); } else { - cl_assert(git_path_isdir("typechanges")); - cl_assert(!git_path_exists("typechanges/a")); - cl_assert(!git_path_exists("typechanges/b")); - cl_assert(!git_path_exists("typechanges/c")); - cl_assert(!git_path_exists("typechanges/d")); - cl_assert(!git_path_exists("typechanges/e")); + cl_assert(git_fs_path_isdir("typechanges")); + cl_assert(!git_fs_path_exists("typechanges/a")); + cl_assert(!git_fs_path_exists("typechanges/b")); + cl_assert(!git_fs_path_exists("typechanges/c")); + cl_assert(!git_fs_path_exists("typechanges/d")); + cl_assert(!git_fs_path_exists("typechanges/e")); } } } @@ -293,12 +293,12 @@ void test_checkout_typechange__checkout_with_conflicts(void) GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED; memset(&cts, 0, sizeof(cts)); - cl_assert(git_path_exists("typechanges/untracked")); + cl_assert(git_fs_path_exists("typechanges/untracked")); cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_assert_equal_i(0, cts.conflicts); - cl_assert(!git_path_exists("typechanges/untracked")); + cl_assert(!git_fs_path_exists("typechanges/untracked")); cl_git_pass( git_repository_set_head_detached(g_repo, git_object_id(obj))); diff --git a/tests/cherrypick/workdir.c b/tests/cherrypick/workdir.c index f7765f2c2..868b9d5ff 100644 --- a/tests/cherrypick/workdir.c +++ b/tests/cherrypick/workdir.c @@ -71,8 +71,8 @@ void test_cherrypick_workdir__automerge(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_git_pass(git_index_write_tree(&cherrypicked_tree_oid, repo_index)); cl_git_pass(git_tree_lookup(&cherrypicked_tree, repo, &cherrypicked_tree_oid)); @@ -114,7 +114,7 @@ void test_cherrypick_workdir__empty_result(void) /* Create an untracked file that should not conflict */ cl_git_mkfile(TEST_REPO_PATH "/file4.txt", ""); - cl_assert(git_path_exists(TEST_REPO_PATH "/file4.txt")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/file4.txt")); cl_git_pass(git_commit_lookup(&head, repo, &head_oid)); cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); @@ -160,8 +160,8 @@ void test_cherrypick_workdir__conflicts(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_git_pass(git_cherrypick(repo, commit, NULL)); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_assert(merge_test_index(repo_index, merge_index_entries, 7)); @@ -373,8 +373,8 @@ void test_cherrypick_workdir__nonmerge_fails_mainline_specified(void) opts.mainline = 1; cl_must_fail(git_cherrypick(repo, commit, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); git_reference_free(head); git_commit_free(commit); @@ -396,8 +396,8 @@ void test_cherrypick_workdir__merge_fails_without_mainline_specified(void) cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid)); cl_must_fail(git_cherrypick(repo, commit, NULL)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); git_commit_free(commit); git_commit_free(head); diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c index adea597e3..55a09d111 100644 --- a/tests/clar_libgit2.c +++ b/tests/clar_libgit2.c @@ -1,6 +1,6 @@ #include "clar_libgit2.h" #include "posix.h" -#include "path.h" +#include "fs_path.h" #include "git2/sys/repository.h" void cl_git_report_failure( @@ -281,7 +281,7 @@ const char* cl_git_path_url(const char *path) git_str path_buf = GIT_STR_INIT; git_str url_buf = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path_buf, path, NULL)); cl_git_pass(git_str_puts(&url_buf, "file://")); #ifdef GIT_WIN32 @@ -336,9 +336,9 @@ const char *cl_git_sandbox_path(int is_dir, ...) } va_end(arg); - cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL)); + cl_git_pass(git_fs_path_prettify(&buf, buf.ptr, NULL)); if (is_dir) - git_path_to_dir(&buf); + git_fs_path_to_dir(&buf); /* make sure we won't truncate */ cl_assert(git_str_len(&buf) < sizeof(_temp)); @@ -359,8 +359,8 @@ static int remove_placeholders_recurs(void *_data, git_str *path) remove_data *data = (remove_data *)_data; size_t pathlen; - if (git_path_isdir(path->ptr) == true) - return git_path_direach(path, 0, remove_placeholders_recurs, data); + if (git_fs_path_isdir(path->ptr) == true) + return git_fs_path_direach(path, 0, remove_placeholders_recurs, data); pathlen = path->size; @@ -382,7 +382,7 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename) remove_data data; git_str buffer = GIT_STR_INIT; - if (git_path_isdir(directory_path) == false) + if (git_fs_path_isdir(directory_path) == false) return -1; if (git_str_sets(&buffer, directory_path) < 0) @@ -570,9 +570,9 @@ void cl_fake_home(void) cl_set_cleanup(cl_fake_home_cleanup, NULL); - if (!git_path_exists("home")) + if (!git_fs_path_exists("home")) cl_must_pass(p_mkdir("home", 0777)); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); git_str_dispose(&path); @@ -584,7 +584,7 @@ void cl_sandbox_set_search_path_defaults(void) git_str_joinpath(&path, clar_sandbox_path(), "__config"); - if (!git_path_exists(path.ptr)) + if (!git_fs_path_exists(path.ptr)) cl_must_pass(p_mkdir(path.ptr, 0777)); git_libgit2_opts( diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c index 7625a2183..c3515b53f 100644 --- a/tests/clone/nonetwork.c +++ b/tests/clone/nonetwork.c @@ -51,10 +51,10 @@ void test_clone_nonetwork__bad_urls(void) { /* Clone should clean up the mess if the URL isn't a git repository */ cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(!git_path_exists("./foo")); + cl_assert(!git_fs_path_exists("./foo")); g_options.bare = true; cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(!git_path_exists("./foo")); + cl_assert(!git_fs_path_exists("./foo")); cl_git_fail(git_clone(&g_repo, "git://example.com:asdf", "./foo", &g_options)); cl_git_fail(git_clone(&g_repo, "https://example.com:asdf/foo", "./foo", &g_options)); @@ -70,12 +70,12 @@ void test_clone_nonetwork__do_not_clean_existing_directory(void) * Should clean up entries it creates. */ p_mkdir("./foo", GIT_DIR_MODE); cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(git_path_is_empty_dir("./foo")); + cl_assert(git_fs_path_is_empty_dir("./foo")); /* Try again with a bare repository. */ g_options.bare = true; cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options)); - cl_assert(git_path_is_empty_dir("./foo")); + cl_assert(git_fs_path_is_empty_dir("./foo")); } void test_clone_nonetwork__local(void) @@ -151,7 +151,7 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void) cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&path))); git_str_dispose(&path); } @@ -168,7 +168,7 @@ void test_clone_nonetwork__can_checkout_given_branch(void) cl_git_pass(git_repository_head(&g_ref, g_repo)); cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test"); - cl_assert(git_path_exists("foo/readme.txt")); + cl_assert(git_fs_path_exists("foo/readme.txt")); cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD")); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head)); @@ -196,7 +196,7 @@ void test_clone_nonetwork__can_cancel_clone_in_fetch(void) -54321); cl_assert(!g_repo); - cl_assert(!git_path_exists("foo/readme.txt")); + cl_assert(!git_fs_path_exists("foo/readme.txt")); } static int clone_cancel_checkout_cb( @@ -227,7 +227,7 @@ void test_clone_nonetwork__can_cancel_clone_in_checkout(void) -12345); cl_assert(!g_repo); - cl_assert(!git_path_exists("foo/readme.txt")); + cl_assert(!git_fs_path_exists("foo/readme.txt")); } void test_clone_nonetwork__can_detached_head(void) diff --git a/tests/config/global.c b/tests/config/global.c index d59c39fa2..5aba4eec6 100644 --- a/tests/config/global.c +++ b/tests/config/global.c @@ -6,17 +6,17 @@ void test_config_global__initialize(void) git_str path = GIT_STR_INIT; cl_git_pass(git_futils_mkdir_r("home", 0777)); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_futils_mkdir_r("xdg/git", 0777)); - cl_git_pass(git_path_prettify(&path, "xdg/git", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "xdg/git", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr)); cl_git_pass(git_futils_mkdir_r("etc", 0777)); - cl_git_pass(git_path_prettify(&path, "etc", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "etc", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr)); @@ -141,7 +141,7 @@ void test_config_global__open_programdata(void) cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_PROGRAMDATA, &dir_path)); - if (!git_path_isdir(dir_path.ptr)) + if (!git_fs_path_isdir(dir_path.ptr)) cl_git_pass(p_mkdir(dir_path.ptr, 0777)); cl_git_pass(git_str_joinpath(&config_path, dir_path.ptr, "config")); diff --git a/tests/config/read.c b/tests/config/read.c index 77f8a1262..3c96f8519 100644 --- a/tests/config/read.c +++ b/tests/config/read.c @@ -1,5 +1,5 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" static git_buf buf = GIT_BUF_INIT; @@ -705,11 +705,11 @@ void test_config_read__path(void) git_str expected_path = GIT_STR_INIT; cl_git_pass(p_mkdir("fakehome", 0777)); - cl_git_pass(git_path_prettify(&home_path, "fakehome", NULL)); + cl_git_pass(git_fs_path_prettify(&home_path, "fakehome", NULL)); cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &old_path)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, home_path.ptr)); cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile"); - cl_git_pass(git_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL)); + cl_git_pass(git_fs_path_join_unrooted(&expected_path, "somefile", home_path.ptr, NULL)); cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig")); cl_git_pass(git_config_get_path(&path, cfg, "some.path")); @@ -717,7 +717,7 @@ void test_config_read__path(void) git_buf_dispose(&path); cl_git_mkfile("./testconfig", "[some]\n path = ~/"); - cl_git_pass(git_path_join_unrooted(&expected_path, "", home_path.ptr, NULL)); + cl_git_pass(git_fs_path_join_unrooted(&expected_path, "", home_path.ptr, NULL)); cl_git_pass(git_config_get_path(&path, cfg, "some.path")); cl_assert_equal_s(expected_path.ptr, path.ptr); diff --git a/tests/config/readonly.c b/tests/config/readonly.c index 5d544b8cb..a8901e394 100644 --- a/tests/config/readonly.c +++ b/tests/config/readonly.c @@ -25,7 +25,7 @@ void test_config_readonly__writing_to_readonly_fails(void) cl_git_pass(git_config_add_backend(cfg, backend, GIT_CONFIG_LEVEL_GLOBAL, NULL, 0)); cl_git_fail_with(GIT_ENOTFOUND, git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(!git_path_exists("global")); + cl_assert(!git_fs_path_exists("global")); } void test_config_readonly__writing_to_cfg_with_rw_precedence_succeeds(void) @@ -41,8 +41,8 @@ void test_config_readonly__writing_to_cfg_with_rw_precedence_succeeds(void) cl_git_pass(git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(git_path_exists("local")); - cl_assert(!git_path_exists("global")); + cl_assert(git_fs_path_exists("local")); + cl_assert(!git_fs_path_exists("global")); cl_git_pass(p_unlink("local")); } @@ -59,7 +59,7 @@ void test_config_readonly__writing_to_cfg_with_ro_precedence_succeeds(void) cl_git_pass(git_config_set_string(cfg, "foo.bar", "baz")); - cl_assert(!git_path_exists("local")); - cl_assert(git_path_exists("global")); + cl_assert(!git_fs_path_exists("local")); + cl_assert(git_fs_path_exists("global")); cl_git_pass(p_unlink("global")); } diff --git a/tests/config/stress.c b/tests/config/stress.c index 7ec274b18..c823284ff 100644 --- a/tests/config/stress.c +++ b/tests/config/stress.c @@ -30,7 +30,7 @@ void test_config_stress__dont_break_on_invalid_input(void) { git_config *config; - cl_assert(git_path_exists(TEST_CONFIG)); + cl_assert(git_fs_path_exists(TEST_CONFIG)); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_get_string_buf(&buf, config, "color.ui")); @@ -72,7 +72,7 @@ void test_config_stress__escape_subsection_names(void) { git_config *config; - cl_assert(git_path_exists("git-test-config")); + cl_assert(git_fs_path_exists("git-test-config")); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "some.sec\\tion.other", "foo")); @@ -90,7 +90,7 @@ void test_config_stress__trailing_backslash(void) git_config *config; const char *path = "C:\\iam\\some\\windows\\path\\"; - cl_assert(git_path_exists("git-test-config")); + cl_assert(git_fs_path_exists("git-test-config")); cl_git_pass(git_config_open_ondisk(&config, TEST_CONFIG)); cl_git_pass(git_config_set_string(config, "windows.path", path)); git_config_free(config); diff --git a/tests/core/copy.c b/tests/core/copy.c index d31274808..2b90fb6bf 100644 --- a/tests/core/copy.c +++ b/tests/core/copy.c @@ -12,7 +12,7 @@ void test_core_copy__file(void) cl_git_pass(git_futils_cp("copy_me", "copy_me_two", 0664)); - cl_git_pass(git_path_lstat("copy_me_two", &st)); + cl_git_pass(git_fs_path_lstat("copy_me_two", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); @@ -27,7 +27,7 @@ void test_core_copy__file_in_dir(void) cl_git_pass(git_futils_mkdir("an_dir/in_a_dir", 0775, GIT_MKDIR_PATH)); cl_git_mkfile("an_dir/in_a_dir/copy_me", content); - cl_assert(git_path_isdir("an_dir")); + cl_assert(git_fs_path_isdir("an_dir")); cl_git_pass(git_futils_mkpath2file ("an_dir/second_dir/and_more/copy_me_two", 0775)); @@ -37,12 +37,12 @@ void test_core_copy__file_in_dir(void) "an_dir/second_dir/and_more/copy_me_two", 0664)); - cl_git_pass(git_path_lstat("an_dir/second_dir/and_more/copy_me_two", &st)); + cl_git_pass(git_fs_path_lstat("an_dir/second_dir/and_more/copy_me_two", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); cl_git_pass(git_futils_rmdir_r("an_dir", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("an_dir")); + cl_assert(!git_fs_path_isdir("an_dir")); } void assert_hard_link(const char *path) @@ -50,7 +50,7 @@ void assert_hard_link(const char *path) /* we assert this by checking that there's more than one link to the file */ struct stat st; - cl_assert(git_path_isfile(path)); + cl_assert(git_fs_path_isfile(path)); cl_git_pass(p_stat(path, &st)); cl_assert(st.st_nlink > 1); } @@ -74,73 +74,73 @@ void test_core_copy__tree(void) cl_assert(p_symlink("../../b/f2", "src/c/d/l1") == 0); #endif - cl_assert(git_path_isdir("src")); - cl_assert(git_path_isdir("src/b")); - cl_assert(git_path_isdir("src/c/d")); - cl_assert(git_path_isfile("src/c/d/f4")); + cl_assert(git_fs_path_isdir("src")); + cl_assert(git_fs_path_isdir("src/b")); + cl_assert(git_fs_path_isdir("src/c/d")); + cl_assert(git_fs_path_isfile("src/c/d/f4")); /* copy with no empty dirs, yes links, no dotfiles, no overwrite */ cl_git_pass( git_futils_cp_r("src", "t1", GIT_CPDIR_COPY_SYMLINKS, 0) ); - cl_assert(git_path_isdir("t1")); - cl_assert(git_path_isdir("t1/b")); - cl_assert(git_path_isdir("t1/c")); - cl_assert(git_path_isdir("t1/c/d")); - cl_assert(!git_path_isdir("t1/c/e")); + cl_assert(git_fs_path_isdir("t1")); + cl_assert(git_fs_path_isdir("t1/b")); + cl_assert(git_fs_path_isdir("t1/c")); + cl_assert(git_fs_path_isdir("t1/c/d")); + cl_assert(!git_fs_path_isdir("t1/c/e")); - cl_assert(git_path_isfile("t1/f1")); - cl_assert(git_path_isfile("t1/b/f2")); - cl_assert(git_path_isfile("t1/c/f3")); - cl_assert(git_path_isfile("t1/c/d/f4")); - cl_assert(!git_path_isfile("t1/c/d/.f5")); + cl_assert(git_fs_path_isfile("t1/f1")); + cl_assert(git_fs_path_isfile("t1/b/f2")); + cl_assert(git_fs_path_isfile("t1/c/f3")); + cl_assert(git_fs_path_isfile("t1/c/d/f4")); + cl_assert(!git_fs_path_isfile("t1/c/d/.f5")); - cl_git_pass(git_path_lstat("t1/c/f3", &st)); + cl_git_pass(git_fs_path_lstat("t1/c/f3", &st)); cl_assert(S_ISREG(st.st_mode)); cl_assert(strlen(content) == (size_t)st.st_size); #ifndef GIT_WIN32 - cl_git_pass(git_path_lstat("t1/c/d/l1", &st)); + cl_git_pass(git_fs_path_lstat("t1/c/d/l1", &st)); cl_assert(S_ISLNK(st.st_mode)); #endif cl_git_pass(git_futils_rmdir_r("t1", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("t1")); + cl_assert(!git_fs_path_isdir("t1")); /* copy with empty dirs, no links, yes dotfiles, no overwrite */ cl_git_pass( git_futils_cp_r("src", "t2", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_COPY_DOTFILES, 0) ); - cl_assert(git_path_isdir("t2")); - cl_assert(git_path_isdir("t2/b")); - cl_assert(git_path_isdir("t2/c")); - cl_assert(git_path_isdir("t2/c/d")); - cl_assert(git_path_isdir("t2/c/e")); + cl_assert(git_fs_path_isdir("t2")); + cl_assert(git_fs_path_isdir("t2/b")); + cl_assert(git_fs_path_isdir("t2/c")); + cl_assert(git_fs_path_isdir("t2/c/d")); + cl_assert(git_fs_path_isdir("t2/c/e")); - cl_assert(git_path_isfile("t2/f1")); - cl_assert(git_path_isfile("t2/b/f2")); - cl_assert(git_path_isfile("t2/c/f3")); - cl_assert(git_path_isfile("t2/c/d/f4")); - cl_assert(git_path_isfile("t2/c/d/.f5")); + cl_assert(git_fs_path_isfile("t2/f1")); + cl_assert(git_fs_path_isfile("t2/b/f2")); + cl_assert(git_fs_path_isfile("t2/c/f3")); + cl_assert(git_fs_path_isfile("t2/c/d/f4")); + cl_assert(git_fs_path_isfile("t2/c/d/.f5")); #ifndef GIT_WIN32 - cl_git_fail(git_path_lstat("t2/c/d/l1", &st)); + cl_git_fail(git_fs_path_lstat("t2/c/d/l1", &st)); #endif cl_git_pass(git_futils_rmdir_r("t2", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("t2")); + cl_assert(!git_fs_path_isdir("t2")); #ifndef GIT_WIN32 cl_git_pass(git_futils_cp_r("src", "t3", GIT_CPDIR_CREATE_EMPTY_DIRS | GIT_CPDIR_LINK_FILES, 0)); - cl_assert(git_path_isdir("t3")); + cl_assert(git_fs_path_isdir("t3")); - cl_assert(git_path_isdir("t3")); - cl_assert(git_path_isdir("t3/b")); - cl_assert(git_path_isdir("t3/c")); - cl_assert(git_path_isdir("t3/c/d")); - cl_assert(git_path_isdir("t3/c/e")); + cl_assert(git_fs_path_isdir("t3")); + cl_assert(git_fs_path_isdir("t3/b")); + cl_assert(git_fs_path_isdir("t3/c")); + cl_assert(git_fs_path_isdir("t3/c/d")); + cl_assert(git_fs_path_isdir("t3/c/e")); assert_hard_link("t3/f1"); assert_hard_link("t3/b/f2"); diff --git a/tests/core/dirent.c b/tests/core/dirent.c index ce93e0358..2419ec7ab 100644 --- a/tests/core/dirent.c +++ b/tests/core/dirent.c @@ -113,7 +113,7 @@ void test_core_dirent__dont_traverse_dot(void) cl_set_cleanup(&dirent_cleanup__cb, &dot); setup(&dot); - cl_git_pass(git_path_direach(&dot.path, 0, one_entry, &dot)); + cl_git_pass(git_fs_path_direach(&dot.path, 0, one_entry, &dot)); check_counts(&dot); } @@ -137,7 +137,7 @@ void test_core_dirent__traverse_subfolder(void) cl_set_cleanup(&dirent_cleanup__cb, &sub); setup(&sub); - cl_git_pass(git_path_direach(&sub.path, 0, one_entry, &sub)); + cl_git_pass(git_fs_path_direach(&sub.path, 0, one_entry, &sub)); check_counts(&sub); } @@ -155,7 +155,7 @@ void test_core_dirent__traverse_slash_terminated_folder(void) cl_set_cleanup(&dirent_cleanup__cb, &sub_slash); setup(&sub_slash); - cl_git_pass(git_path_direach(&sub_slash.path, 0, one_entry, &sub_slash)); + cl_git_pass(git_fs_path_direach(&sub_slash.path, 0, one_entry, &sub_slash)); check_counts(&sub_slash); } @@ -176,12 +176,12 @@ void test_core_dirent__dont_traverse_empty_folders(void) cl_set_cleanup(&dirent_cleanup__cb, &empty); setup(&empty); - cl_git_pass(git_path_direach(&empty.path, 0, one_entry, &empty)); + cl_git_pass(git_fs_path_direach(&empty.path, 0, one_entry, &empty)); check_counts(&empty); /* make sure callback not called */ - cl_assert(git_path_is_empty_dir(empty.path.ptr)); + cl_assert(git_fs_path_is_empty_dir(empty.path.ptr)); } static name_data odd_names[] = { @@ -204,7 +204,7 @@ void test_core_dirent__traverse_weird_filenames(void) cl_set_cleanup(&dirent_cleanup__cb, &odd); setup(&odd); - cl_git_pass(git_path_direach(&odd.path, 0, one_entry, &odd)); + cl_git_pass(git_fs_path_direach(&odd.path, 0, one_entry, &odd)); check_counts(&odd); } @@ -224,30 +224,30 @@ void test_core_dirent__length_limits(void) void test_core_dirent__empty_dir(void) { cl_must_pass(p_mkdir("empty_dir", 0777)); - cl_assert(git_path_is_empty_dir("empty_dir")); + cl_assert(git_fs_path_is_empty_dir("empty_dir")); cl_git_mkfile("empty_dir/content", "whatever\n"); - cl_assert(!git_path_is_empty_dir("empty_dir")); - cl_assert(!git_path_is_empty_dir("empty_dir/content")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir/content")); cl_must_pass(p_unlink("empty_dir/content")); cl_must_pass(p_mkdir("empty_dir/content", 0777)); - cl_assert(!git_path_is_empty_dir("empty_dir")); - cl_assert(git_path_is_empty_dir("empty_dir/content")); + cl_assert(!git_fs_path_is_empty_dir("empty_dir")); + cl_assert(git_fs_path_is_empty_dir("empty_dir/content")); cl_must_pass(p_rmdir("empty_dir/content")); cl_must_pass(p_rmdir("empty_dir")); } -static void handle_next(git_path_diriter *diriter, walk_data *walk) +static void handle_next(git_fs_path_diriter *diriter, walk_data *walk) { const char *fullpath, *filename; size_t fullpath_len, filename_len; - cl_git_pass(git_path_diriter_fullpath(&fullpath, &fullpath_len, diriter)); - cl_git_pass(git_path_diriter_filename(&filename, &filename_len, diriter)); + cl_git_pass(git_fs_path_diriter_fullpath(&fullpath, &fullpath_len, diriter)); + cl_git_pass(git_fs_path_diriter_filename(&filename, &filename_len, diriter)); cl_assert_equal_strn(fullpath, "sub/", 4); cl_assert_equal_s(fullpath+4, filename); @@ -258,42 +258,42 @@ static void handle_next(git_path_diriter *diriter, walk_data *walk) /* test directory iterator */ void test_core_dirent__diriter_with_fullname(void) { - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; int error; cl_set_cleanup(&dirent_cleanup__cb, &sub); setup(&sub); - cl_git_pass(git_path_diriter_init(&diriter, sub.path.ptr, 0)); + cl_git_pass(git_fs_path_diriter_init(&diriter, sub.path.ptr, 0)); - while ((error = git_path_diriter_next(&diriter)) == 0) + while ((error = git_fs_path_diriter_next(&diriter)) == 0) handle_next(&diriter, &sub); cl_assert_equal_i(error, GIT_ITEROVER); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); check_counts(&sub); } void test_core_dirent__diriter_at_directory_root(void) { - git_path_diriter diriter = GIT_PATH_DIRITER_INIT; + git_fs_path_diriter diriter = GIT_FS_PATH_DIRITER_INIT; const char *sandbox_path, *path; char *root_path; size_t path_len; int root_offset, error; sandbox_path = clar_sandbox_path(); - cl_assert((root_offset = git_path_root(sandbox_path)) >= 0); + cl_assert((root_offset = git_fs_path_root(sandbox_path)) >= 0); cl_assert(root_path = git__calloc(1, root_offset + 2)); strncpy(root_path, sandbox_path, root_offset + 1); - cl_git_pass(git_path_diriter_init(&diriter, root_path, 0)); + cl_git_pass(git_fs_path_diriter_init(&diriter, root_path, 0)); - while ((error = git_path_diriter_next(&diriter)) == 0) { - cl_git_pass(git_path_diriter_fullpath(&path, &path_len, &diriter)); + while ((error = git_fs_path_diriter_next(&diriter)) == 0) { + cl_git_pass(git_fs_path_diriter_fullpath(&path, &path_len, &diriter)); cl_assert(path_len > (size_t)(root_offset + 1)); cl_assert(path[root_offset+1] != '/'); @@ -301,6 +301,6 @@ void test_core_dirent__diriter_at_directory_root(void) cl_assert_equal_i(error, GIT_ITEROVER); - git_path_diriter_free(&diriter); + git_fs_path_diriter_free(&diriter); git__free(root_path); } diff --git a/tests/core/env.c b/tests/core/env.c index 9a3f0ae76..88c5c6aa3 100644 --- a/tests/core/env.c +++ b/tests/core/env.c @@ -103,7 +103,7 @@ void test_core_env__0(void) continue; } - cl_git_pass(git_path_prettify(&path, *val, NULL)); + cl_git_pass(git_fs_path_prettify(&path, *val, NULL)); /* vary testfile name in each directory so accidentally leaving * an environment variable set from a previous iteration won't @@ -137,7 +137,7 @@ void test_core_env__0(void) cl_git_pass(git_sysdir_find_global_file(&found, testfile)); { - int root = git_path_root(path.ptr); + int root = git_fs_path_root(path.ptr); char old; if (root >= 0) { @@ -270,7 +270,7 @@ void test_core_env__2(void) continue; } - cl_git_pass(git_path_prettify(&path, *val, NULL)); + cl_git_pass(git_fs_path_prettify(&path, *val, NULL)); /* vary testfile name so any sloppiness is resetting variables or * deleting files won't accidentally make a test pass. diff --git a/tests/core/filebuf.c b/tests/core/filebuf.c index 6f654f523..6f40c2456 100644 --- a/tests/core/filebuf.c +++ b/tests/core/filebuf.c @@ -14,7 +14,7 @@ void test_core_filebuf__0(void) cl_must_pass(p_close(fd)); cl_git_fail(git_filebuf_open(&file, test, 0, 0666)); - cl_assert(git_path_exists(testlock)); + cl_assert(git_fs_path_exists(testlock)); cl_must_pass(p_unlink(testlock)); } @@ -142,14 +142,14 @@ void test_core_filebuf__rename_error(void) cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists(test_lock)); + cl_assert_equal_i(true, git_fs_path_exists(test_lock)); cl_git_fail(git_filebuf_commit(&file)); p_close(fd); git_filebuf_cleanup(&file); - cl_assert_equal_i(false, git_path_exists(test_lock)); + cl_assert_equal_i(false, git_fs_path_exists(test_lock)); } void test_core_filebuf__symlink_follow(void) @@ -157,7 +157,7 @@ void test_core_filebuf__symlink_follow(void) git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(p_mkdir(dir, 0777)); @@ -166,10 +166,10 @@ void test_core_filebuf__symlink_follow(void) cl_git_pass(git_filebuf_open(&file, source, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); @@ -177,10 +177,10 @@ void test_core_filebuf__symlink_follow(void) cl_git_pass(git_filebuf_open(&file, source, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); cl_git_pass(git_futils_rmdir_r(dir, NULL, GIT_RMDIR_REMOVE_FILES)); @@ -191,7 +191,7 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) git_filebuf file = GIT_FILEBUF_INIT; git_str source = GIT_STR_INIT, target = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(git_str_joinpath(&source, clar_sandbox_path(), "linkdir/link")); @@ -202,10 +202,10 @@ void test_core_filebuf__symlink_follow_absolute_paths(void) cl_git_pass(git_filebuf_open(&file, source.ptr, 0, 0666)); cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); - cl_assert_equal_i(true, git_path_exists("linkdir/target.lock")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target.lock")); cl_git_pass(git_filebuf_commit(&file)); - cl_assert_equal_i(true, git_path_exists("linkdir/target")); + cl_assert_equal_i(true, git_fs_path_exists("linkdir/target")); git_filebuf_cleanup(&file); git_str_dispose(&source); @@ -219,7 +219,7 @@ void test_core_filebuf__symlink_depth(void) git_filebuf file = GIT_FILEBUF_INIT; const char *dir = "linkdir", *source = "linkdir/link"; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(p_mkdir(dir, 0777)); diff --git a/tests/core/futils.c b/tests/core/futils.c index d08043b6e..b87ea183b 100644 --- a/tests/core/futils.c +++ b/tests/core/futils.c @@ -68,7 +68,7 @@ void test_core_futils__write_hidden_file(void) void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) { - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) cl_skip(); cl_git_pass(git_futils_mkdir_r("a/b", 0777)); @@ -80,8 +80,8 @@ void test_core_futils__recursive_rmdir_keeps_symlink_targets(void) cl_git_pass(git_futils_rmdir_r("a", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(git_path_exists("dir-target")); - cl_assert(git_path_exists("file-target")); + cl_assert(git_fs_path_exists("dir-target")); + cl_assert(git_fs_path_exists("file-target")); cl_must_pass(p_unlink("dir-target/file")); cl_must_pass(p_rmdir("dir-target")); diff --git a/tests/core/iconv.c b/tests/core/iconv.c index 498094bdb..af1b4eabf 100644 --- a/tests/core/iconv.c +++ b/tests/core/iconv.c @@ -1,8 +1,8 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" #ifdef GIT_USE_ICONV -static git_path_iconv_t ic; +static git_fs_path_iconv_t ic; static char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; #endif @@ -10,14 +10,14 @@ static char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; void test_core_iconv__initialize(void) { #ifdef GIT_USE_ICONV - cl_git_pass(git_path_iconv_init_precompose(&ic)); + cl_git_pass(git_fs_path_iconv_init_precompose(&ic)); #endif } void test_core_iconv__cleanup(void) { #ifdef GIT_USE_ICONV - git_path_iconv_clear(&ic); + git_fs_path_iconv_clear(&ic); #endif } @@ -27,7 +27,7 @@ void test_core_iconv__unchanged(void) const char *data = "Ascii data", *original = data; size_t datalen = strlen(data); - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* There are no high bits set, so this should leave data untouched */ @@ -42,7 +42,7 @@ void test_core_iconv__decomposed_to_precomposed(void) size_t datalen, nfdlen = strlen(nfd); datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* The decomposed nfd string should be transformed to the nfc form @@ -50,13 +50,13 @@ void test_core_iconv__decomposed_to_precomposed(void) */ cl_assert_equal_s(nfc, data); - /* should be able to do it multiple times with the same git_path_iconv_t */ + /* should be able to do it multiple times with the same git_fs_path_iconv_t */ data = nfd; datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); cl_assert_equal_s(nfc, data); data = nfd; datalen = nfdlen; - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); cl_assert_equal_s(nfc, data); #endif } @@ -67,7 +67,7 @@ void test_core_iconv__precomposed_is_unmodified(void) const char *data = nfc; size_t datalen = strlen(nfc); - cl_git_pass(git_path_iconv(&ic, &data, &datalen)); + cl_git_pass(git_fs_path_iconv(&ic, &data, &datalen)); GIT_UNUSED(datalen); /* data is already in precomposed form, so even though some bytes have diff --git a/tests/core/mkdir.c b/tests/core/mkdir.c index f0461ac1f..8d4b9afd6 100644 --- a/tests/core/mkdir.c +++ b/tests/core/mkdir.c @@ -22,32 +22,32 @@ void test_core_mkdir__absolute(void) git_str_joinpath(&path, clar_sandbox_path(), "d0"); /* make a directory */ - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); git_str_joinpath(&path, path.ptr, "subdir"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure mkdir_r works for a single subdir */ git_str_joinpath(&path, path.ptr, "another"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure mkdir_r works */ git_str_joinpath(&path, clar_sandbox_path(), "d1/foo/bar/asdf"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_pass(git_futils_mkdir_r(path.ptr, 0755)); - cl_assert(git_path_isdir(path.ptr)); + cl_assert(git_fs_path_isdir(path.ptr)); /* ensure we don't imply recursive */ git_str_joinpath(&path, clar_sandbox_path(), "d2/foo/bar/asdf"); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); cl_git_fail(git_futils_mkdir(path.ptr, 0755, 0)); - cl_assert(!git_path_isdir(path.ptr)); + cl_assert(!git_fs_path_isdir(path.ptr)); git_str_dispose(&path); } @@ -57,39 +57,39 @@ void test_core_mkdir__basic(void) cl_set_cleanup(cleanup_basic_dirs, NULL); /* make a directory */ - cl_assert(!git_path_isdir("d0")); + cl_assert(!git_fs_path_isdir("d0")); cl_git_pass(git_futils_mkdir("d0", 0755, 0)); - cl_assert(git_path_isdir("d0")); + cl_assert(git_fs_path_isdir("d0")); /* make a path */ - cl_assert(!git_path_isdir("d1")); + cl_assert(!git_fs_path_isdir("d1")); cl_git_pass(git_futils_mkdir("d1/d1.1/d1.2", 0755, GIT_MKDIR_PATH)); - cl_assert(git_path_isdir("d1")); - cl_assert(git_path_isdir("d1/d1.1")); - cl_assert(git_path_isdir("d1/d1.1/d1.2")); + cl_assert(git_fs_path_isdir("d1")); + cl_assert(git_fs_path_isdir("d1/d1.1")); + cl_assert(git_fs_path_isdir("d1/d1.1/d1.2")); /* make a dir exclusively */ - cl_assert(!git_path_isdir("d2")); + cl_assert(!git_fs_path_isdir("d2")); cl_git_pass(git_futils_mkdir("d2", 0755, GIT_MKDIR_EXCL)); - cl_assert(git_path_isdir("d2")); + cl_assert(git_fs_path_isdir("d2")); /* make exclusive failure */ cl_git_fail(git_futils_mkdir("d2", 0755, GIT_MKDIR_EXCL)); /* make a path exclusively */ - cl_assert(!git_path_isdir("d3")); + cl_assert(!git_fs_path_isdir("d3")); cl_git_pass(git_futils_mkdir("d3/d3.1/d3.2", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL)); - cl_assert(git_path_isdir("d3")); - cl_assert(git_path_isdir("d3/d3.1/d3.2")); + cl_assert(git_fs_path_isdir("d3")); + cl_assert(git_fs_path_isdir("d3/d3.1/d3.2")); /* make exclusive path failure */ cl_git_fail(git_futils_mkdir("d3/d3.1/d3.2", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL)); /* ??? Should EXCL only apply to the last item in the path? */ /* path with trailing slash? */ - cl_assert(!git_path_isdir("d4")); + cl_assert(!git_fs_path_isdir("d4")); cl_git_pass(git_futils_mkdir("d4/d4.1/", 0755, GIT_MKDIR_PATH)); - cl_assert(git_path_isdir("d4/d4.1")); + cl_assert(git_fs_path_isdir("d4/d4.1")); } static void cleanup_basedir(void *ref) @@ -107,10 +107,10 @@ void test_core_mkdir__with_base(void) cl_git_pass(git_futils_mkdir(BASEDIR, 0755, GIT_MKDIR_PATH)); cl_git_pass(git_futils_mkdir_relative("a", BASEDIR, 0755, 0, NULL)); - cl_assert(git_path_isdir(BASEDIR "/a")); + cl_assert(git_fs_path_isdir(BASEDIR "/a")); cl_git_pass(git_futils_mkdir_relative("b/b1/b2", BASEDIR, 0755, GIT_MKDIR_PATH, NULL)); - cl_assert(git_path_isdir(BASEDIR "/b/b1/b2")); + cl_assert(git_fs_path_isdir(BASEDIR "/b/b1/b2")); /* exclusive with existing base */ cl_git_pass(git_futils_mkdir_relative("c/c1/c2", BASEDIR, 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL, NULL)); @@ -126,7 +126,7 @@ void test_core_mkdir__with_base(void) /* path with shorter base and existing dirs */ cl_git_pass(git_futils_mkdir_relative("dir/here/d/", "base", 0755, GIT_MKDIR_PATH, NULL)); - cl_assert(git_path_isdir("base/dir/here/d")); + cl_assert(git_fs_path_isdir("base/dir/here/d")); /* fail: path with shorter base and existing dirs */ cl_git_fail(git_futils_mkdir_relative("dir/here/e/", "base", 0755, GIT_MKDIR_PATH | GIT_MKDIR_EXCL, NULL)); @@ -179,51 +179,51 @@ void test_core_mkdir__chmods(void) cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is/important", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/important", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_futils_mkdir_relative("mode2/is2/important2", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD, NULL)); - cl_git_pass(git_path_lstat("r/mode2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2/important2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2/important2", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_futils_mkdir_relative("mode3/is3/important3", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode3/is3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3/is3", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode3/is3/important3", &st)); + cl_git_pass(git_fs_path_lstat("r/mode3/is3/important3", &st)); check_mode(0777, st.st_mode); /* test that we chmod existing dir */ cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); - cl_git_pass(git_path_lstat("r/mode/is/important", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/important", &st)); check_mode(0777, st.st_mode); /* test that we chmod even existing dirs if CHMOD_PATH is set */ cl_git_pass(git_futils_mkdir_relative("mode2/is2/important2.1", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2", &st)); check_mode(0777, st.st_mode); - cl_git_pass(git_path_lstat("r/mode2/is2/important2.1", &st)); + cl_git_pass(git_fs_path_lstat("r/mode2/is2/important2.1", &st)); check_mode(0777, st.st_mode); } @@ -235,27 +235,27 @@ void test_core_mkdir__keeps_parent_symlinks(void) cl_set_cleanup(cleanup_basic_dirs, NULL); /* make a directory */ - cl_assert(!git_path_isdir("d0")); + cl_assert(!git_fs_path_isdir("d0")); cl_git_pass(git_futils_mkdir("d0", 0755, 0)); - cl_assert(git_path_isdir("d0")); + cl_assert(git_fs_path_isdir("d0")); cl_must_pass(symlink("d0", "d1")); - cl_assert(git_path_islink("d1")); + cl_assert(git_fs_path_islink("d1")); cl_git_pass(git_futils_mkdir("d1/foo/bar", 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS)); - cl_assert(git_path_islink("d1")); - cl_assert(git_path_isdir("d1/foo/bar")); - cl_assert(git_path_isdir("d0/foo/bar")); + cl_assert(git_fs_path_islink("d1")); + cl_assert(git_fs_path_isdir("d1/foo/bar")); + cl_assert(git_fs_path_isdir("d0/foo/bar")); cl_must_pass(symlink("d0", "d2")); - cl_assert(git_path_islink("d2")); + cl_assert(git_fs_path_islink("d2")); git_str_joinpath(&path, clar_sandbox_path(), "d2/other/dir"); cl_git_pass(git_futils_mkdir(path.ptr, 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS)); - cl_assert(git_path_islink("d2")); - cl_assert(git_path_isdir("d2/other/dir")); - cl_assert(git_path_isdir("d0/other/dir")); + cl_assert(git_fs_path_islink("d2")); + cl_assert(git_fs_path_isdir("d2/other/dir")); + cl_assert(git_fs_path_isdir("d0/other/dir")); git_str_dispose(&path); #endif @@ -276,16 +276,16 @@ void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void) cl_git_pass(git_futils_mkdir("r", 0777, 0)); cl_git_pass(git_futils_mkdir_relative("mode/is/important", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); cl_must_pass(p_chmod("r/mode", 0111)); - cl_git_pass(git_path_lstat("r/mode", &st)); + cl_git_pass(git_fs_path_lstat("r/mode", &st)); check_mode(0111, st.st_mode); cl_git_pass( git_futils_mkdir_relative("mode/is/okay/inside", "r", 0777, GIT_MKDIR_PATH, NULL)); - cl_git_pass(git_path_lstat("r/mode/is/okay/inside", &st)); + cl_git_pass(git_fs_path_lstat("r/mode/is/okay/inside", &st)); check_mode(0755, st.st_mode); cl_must_pass(p_chmod("r/mode", 0777)); diff --git a/tests/core/path.c b/tests/core/path.c index 6decf23ea..563dcd2a3 100644 --- a/tests/core/path.c +++ b/tests/core/path.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "futils.h" +#include "fs_path.h" static void check_dirname(const char *A, const char *B) @@ -7,11 +8,11 @@ check_dirname(const char *A, const char *B) git_str dir = GIT_STR_INIT; char *dir2; - cl_assert(git_path_dirname_r(&dir, A) >= 0); + cl_assert(git_fs_path_dirname_r(&dir, A) >= 0); cl_assert_equal_s(B, dir.ptr); git_str_dispose(&dir); - cl_assert((dir2 = git_path_dirname(A)) != NULL); + cl_assert((dir2 = git_fs_path_dirname(A)) != NULL); cl_assert_equal_s(B, dir2); git__free(dir2); } @@ -22,11 +23,11 @@ check_basename(const char *A, const char *B) git_str base = GIT_STR_INIT; char *base2; - cl_assert(git_path_basename_r(&base, A) >= 0); + cl_assert(git_fs_path_basename_r(&base, A) >= 0); cl_assert_equal_s(B, base.ptr); git_str_dispose(&base); - cl_assert((base2 = git_path_basename(A)) != NULL); + cl_assert((base2 = git_fs_path_basename(A)) != NULL); cl_assert_equal_s(B, base2); git__free(base2); } @@ -175,7 +176,7 @@ check_path_to_dir( git_str tgt = GIT_STR_INIT; git_str_sets(&tgt, path); - cl_git_pass(git_path_to_dir(&tgt)); + cl_git_pass(git_fs_path_to_dir(&tgt)); cl_assert_equal_s(expected, tgt.ptr); git_str_dispose(&tgt); @@ -193,7 +194,7 @@ check_string_to_dir( strncpy(buf, path, len + 2); - git_path_string_to_dir(buf, maxlen); + git_fs_path_string_to_dir(buf, maxlen); cl_assert_equal_s(expected, buf); @@ -294,10 +295,10 @@ static void check_fromurl(const char *expected_result, const char *input, int sh assert(should_fail || expected_result); if (!should_fail) { - cl_git_pass(git_path_fromurl(&buf, input)); + cl_git_pass(git_fs_path_fromurl(&buf, input)); cl_assert_equal_s(expected_result, git_str_cstr(&buf)); } else - cl_git_fail(git_path_fromurl(&buf, input)); + cl_git_fail(git_fs_path_fromurl(&buf, input)); git_str_dispose(&buf); } @@ -402,7 +403,7 @@ void test_core_path__11_walkup(void) info.expect_idx = i; cl_git_pass( - git_path_walk_up(&p, root[j], check_one_walkup_step, &info) + git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) ); cl_assert_equal_s(p.ptr, expect[i]); @@ -439,7 +440,7 @@ void test_core_path__11a_walkup_cancel(void) cl_assert_equal_i( CANCEL_VALUE, - git_path_walk_up(&p, root[j], check_one_walkup_step, &info) + git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info) ); /* skip to next run of expectations */ @@ -451,16 +452,16 @@ void test_core_path__11a_walkup_cancel(void) void test_core_path__12_offset_to_path_root(void) { - cl_assert(git_path_root("non/rooted/path") == -1); - cl_assert(git_path_root("/rooted/path") == 0); + cl_assert(git_fs_path_root("non/rooted/path") == -1); + cl_assert(git_fs_path_root("/rooted/path") == 0); #ifdef GIT_WIN32 /* Windows specific tests */ - cl_assert(git_path_root("C:non/rooted/path") == -1); - cl_assert(git_path_root("C:/rooted/path") == 2); - cl_assert(git_path_root("//computername/sharefolder/resource") == 14); - cl_assert(git_path_root("//computername/sharefolder") == 14); - cl_assert(git_path_root("//computername") == -1); + cl_assert(git_fs_path_root("C:non/rooted/path") == -1); + cl_assert(git_fs_path_root("C:/rooted/path") == 2); + cl_assert(git_fs_path_root("//computername/sharefolder/resource") == 14); + cl_assert(git_fs_path_root("//computername/sharefolder") == 14); + cl_assert(git_fs_path_root("//computername") == -1); #endif } @@ -470,9 +471,9 @@ void test_core_path__13_cannot_prettify_a_non_existing_file(void) { git_str p = GIT_STR_INIT; - cl_assert_equal_b(git_path_exists(NON_EXISTING_FILEPATH), false); - cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); - cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); + cl_assert_equal_b(git_fs_path_exists(NON_EXISTING_FILEPATH), false); + cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH, NULL)); + cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL)); git_str_dispose(&p); } @@ -483,57 +484,57 @@ void test_core_path__14_apply_relative(void) cl_git_pass(git_str_sets(&p, "/this/is/a/base")); - cl_git_pass(git_path_apply_relative(&p, "../test")); + cl_git_pass(git_fs_path_apply_relative(&p, "../test")); cl_assert_equal_s("/this/is/a/test", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../the/./end")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../the/./end")); cl_assert_equal_s("/this/is/the/end", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "./of/this/../the/string")); + cl_git_pass(git_fs_path_apply_relative(&p, "./of/this/../the/string")); cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../../../..")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../../../..")); cl_assert_equal_s("/this/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../")); + cl_git_pass(git_fs_path_apply_relative(&p, "../")); cl_assert_equal_s("/", p.ptr); - cl_git_fail(git_path_apply_relative(&p, "../../..")); + cl_git_fail(git_fs_path_apply_relative(&p, "../../..")); cl_git_pass(git_str_sets(&p, "d:/another/test")); - cl_git_pass(git_path_apply_relative(&p, "../..")); + cl_git_pass(git_fs_path_apply_relative(&p, "../..")); cl_assert_equal_s("d:/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "from/here/to/../and/./back/.")); + cl_git_pass(git_fs_path_apply_relative(&p, "from/here/to/../and/./back/.")); cl_assert_equal_s("d:/from/here/and/back/", p.ptr); cl_git_pass(git_str_sets(&p, "https://my.url.com/test.git")); - cl_git_pass(git_path_apply_relative(&p, "../another.git")); + cl_git_pass(git_fs_path_apply_relative(&p, "../another.git")); cl_assert_equal_s("https://my.url.com/another.git", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../full/path/url.patch")); + cl_git_pass(git_fs_path_apply_relative(&p, "../full/path/url.patch")); cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "..")); + cl_git_pass(git_fs_path_apply_relative(&p, "..")); cl_assert_equal_s("https://my.url.com/full/path/", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../")); cl_assert_equal_s("https://", p.ptr); cl_git_pass(git_str_sets(&p, "../../this/is/relative")); - cl_git_pass(git_path_apply_relative(&p, "../../preserves/the/prefix")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../preserves/the/prefix")); cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../../../../that")); + cl_git_pass(git_fs_path_apply_relative(&p, "../../../../that")); cl_assert_equal_s("../../that", p.ptr); - cl_git_pass(git_path_apply_relative(&p, "../there")); + cl_git_pass(git_fs_path_apply_relative(&p, "../there")); cl_assert_equal_s("../../there", p.ptr); git_str_dispose(&p); } @@ -542,7 +543,7 @@ static void assert_resolve_relative( git_str *buf, const char *expected, const char *path) { cl_git_pass(git_str_sets(buf, path)); - cl_git_pass(git_path_resolve_relative(buf, 0)); + cl_git_pass(git_fs_path_resolve_relative(buf, 0)); cl_assert_equal_s(expected, buf->ptr); } @@ -596,22 +597,22 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d"); cl_git_pass(git_str_sets(&buf, "/..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/./..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/.//..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/../.")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "/../.././../a")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); cl_git_pass(git_str_sets(&buf, "////..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); /* things that start with Windows network paths */ #ifdef GIT_WIN32 @@ -620,7 +621,7 @@ void test_core_path__15_resolve_relative(void) assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c"); cl_git_pass(git_str_sets(&buf, "//a/b/../..")); - cl_git_fail(git_path_resolve_relative(&buf, 0)); + cl_git_fail(git_fs_path_resolve_relative(&buf, 0)); #else assert_resolve_relative(&buf, "/a/b/c", "//a/b/c"); assert_resolve_relative(&buf, "/a/", "//a/b/.."); @@ -632,7 +633,7 @@ void test_core_path__15_resolve_relative(void) } #define assert_common_dirlen(i, p, q) \ - cl_assert_equal_i((i), git_path_common_dirlen((p), (q))); + cl_assert_equal_i((i), git_fs_path_common_dirlen((p), (q))); void test_core_path__16_resolve_relative(void) { @@ -650,12 +651,3 @@ void test_core_path__16_resolve_relative(void) assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt"); assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt"); } - -void test_core_path__git_path_is_file(void) -{ - cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)); - cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS)); - cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS)); -} diff --git a/tests/core/posix.c b/tests/core/posix.c index 247bd43f5..cba312913 100644 --- a/tests/core/posix.c +++ b/tests/core/posix.c @@ -147,7 +147,7 @@ void test_core_posix__utimes(void) void test_core_posix__unlink_removes_symlink(void) { - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_git_mkfile("file", "Dummy file."); @@ -159,8 +159,8 @@ void test_core_posix__unlink_removes_symlink(void) cl_must_pass(p_unlink("file-symlink")); cl_must_pass(p_unlink("dir-symlink")); - cl_assert(git_path_exists("file")); - cl_assert(git_path_exists("dir")); + cl_assert(git_fs_path_exists("file")); + cl_assert(git_fs_path_exists("dir")); cl_must_pass(p_unlink("file")); cl_must_pass(p_rmdir("dir")); @@ -170,7 +170,7 @@ void test_core_posix__symlink_resolves_to_correct_type(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_must_pass(git_futils_mkdir("dir", 0777, 0)); @@ -194,7 +194,7 @@ void test_core_posix__relative_symlink(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); cl_must_pass(git_futils_mkdir("dir", 0777, 0)); @@ -214,7 +214,7 @@ void test_core_posix__symlink_to_file_across_dirs(void) { git_str contents = GIT_STR_INIT; - if (!git_path_supports_symlinks(clar_sandbox_path())) + if (!git_fs_path_supports_symlinks(clar_sandbox_path())) clar__skip(); /* diff --git a/tests/core/rmdir.c b/tests/core/rmdir.c index 56ea320be..8e5bd5878 100644 --- a/tests/core/rmdir.c +++ b/tests/core/rmdir.c @@ -29,7 +29,7 @@ void test_core_rmdir__initialize(void) void test_core_rmdir__cleanup(void) { - if (git_path_exists(empty_tmp_dir)) + if (git_fs_path_exists(empty_tmp_dir)) cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); } @@ -38,11 +38,11 @@ void test_core_rmdir__delete_recursive(void) { git_str path = GIT_STR_INIT; cl_git_pass(git_str_joinpath(&path, empty_tmp_dir, "/one")); - cl_assert(git_path_exists(git_str_cstr(&path))); + cl_assert(git_fs_path_exists(git_str_cstr(&path))); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); - cl_assert(!git_path_exists(git_str_cstr(&path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&path))); git_str_dispose(&path); } @@ -61,7 +61,7 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) cl_must_pass(p_unlink(file.ptr)); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY)); - cl_assert(!git_path_exists(empty_tmp_dir)); + cl_assert(!git_fs_path_exists(empty_tmp_dir)); git_str_dispose(&file); } @@ -69,7 +69,7 @@ void test_core_rmdir__fail_to_delete_non_empty_dir(void) void test_core_rmdir__keep_base(void) { cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_ROOT)); - cl_assert(git_path_exists(empty_tmp_dir)); + cl_assert(git_fs_path_exists(empty_tmp_dir)); } void test_core_rmdir__can_skip_non_empty_dir(void) @@ -81,10 +81,10 @@ void test_core_rmdir__can_skip_non_empty_dir(void) cl_git_mkfile(git_str_cstr(&file), "dummy"); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_NONEMPTY)); - cl_assert(git_path_exists(git_str_cstr(&file)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&file)) == true); cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(git_path_exists(empty_tmp_dir) == false); + cl_assert(git_fs_path_exists(empty_tmp_dir) == false); git_str_dispose(&file); } @@ -96,23 +96,23 @@ void test_core_rmdir__can_remove_empty_parents(void) cl_git_pass( git_str_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt")); cl_git_mkfile(git_str_cstr(&file), "dummy"); - cl_assert(git_path_isfile(git_str_cstr(&file))); + cl_assert(git_fs_path_isfile(git_str_cstr(&file))); cl_git_pass(git_futils_rmdir_r("one/two_two/three/file.txt", empty_tmp_dir, GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_EMPTY_PARENTS)); - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */ - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */ - cl_assert(!git_path_exists(git_str_cstr(&file))); + cl_assert(!git_fs_path_exists(git_str_cstr(&file))); git_str_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */ - cl_assert(git_path_exists(git_str_cstr(&file))); + cl_assert(git_fs_path_exists(git_str_cstr(&file))); - cl_assert(git_path_exists(empty_tmp_dir) == true); + cl_assert(git_fs_path_exists(empty_tmp_dir) == true); git_str_dispose(&file); diff --git a/tests/core/stat.c b/tests/core/stat.c index 56d141e98..022380ba6 100644 --- a/tests/core/stat.c +++ b/tests/core/stat.c @@ -102,7 +102,7 @@ void test_core_stat__root(void) int root_len; struct stat st; - root_len = git_path_root(sandbox); + root_len = git_fs_path_root(sandbox); cl_assert(root_len >= 0); git_str_set(&root, sandbox, root_len+1); diff --git a/tests/diff/drivers.c b/tests/diff/drivers.c index ce24e9bc0..304a54b56 100644 --- a/tests/diff/drivers.c +++ b/tests/diff/drivers.c @@ -187,7 +187,7 @@ void test_diff_drivers__builtins(void) g_repo = cl_git_sandbox_init("userdiff"); - cl_git_pass(git_path_dirload(&files, "userdiff/files", 9, 0)); + cl_git_pass(git_fs_path_dirload(&files, "userdiff/files", 9, 0)); opts.interhunk_lines = 1; opts.context_lines = 1; diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index f7c74a294..444fc2f97 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -1252,7 +1252,7 @@ void test_diff_workdir__can_diff_empty_file(void) /* empty contents of file */ cl_git_rewritefile("attr_index/README.txt", ""); - cl_git_pass(git_path_lstat("attr_index/README.txt", &st)); + cl_git_pass(git_fs_path_lstat("attr_index/README.txt", &st)); cl_assert_equal_i(0, (int)st.st_size); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts)); @@ -1265,7 +1265,7 @@ void test_diff_workdir__can_diff_empty_file(void) /* remove a file altogether */ cl_git_pass(p_unlink("attr_index/README.txt")); - cl_assert(!git_path_exists("attr_index/README.txt")); + cl_assert(!git_fs_path_exists("attr_index/README.txt")); cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts)); cl_assert_equal_i(3, (int)git_diff_num_deltas(diff)); @@ -1759,7 +1759,7 @@ static int touch_file(void *payload, git_str *path) struct p_timeval times[2]; GIT_UNUSED(payload); - if (git_path_isdir(path->ptr)) + if (git_fs_path_isdir(path->ptr)) return 0; cl_must_pass(p_stat(path->ptr, &st)); @@ -1805,7 +1805,7 @@ void test_diff_workdir__can_update_index(void) { git_str path = GIT_STR_INIT; cl_git_pass(git_str_sets(&path, "status")); - cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); + cl_git_pass(git_fs_path_direach(&path, 0, touch_file, NULL)); git_str_dispose(&path); } @@ -2040,7 +2040,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void) /* touch all the files so stat times are different */ cl_git_pass(git_str_sets(&path, "status")); - cl_git_pass(git_path_direach(&path, 0, touch_file, NULL)); + cl_git_pass(git_fs_path_direach(&path, 0, touch_file, NULL)); cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts)); git_diff_free(diff); diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c index 0de712be8..334755cc3 100644 --- a/tests/fetchhead/nonetwork.c +++ b/tests/fetchhead/nonetwork.c @@ -446,9 +446,9 @@ void test_fetchhead_nonetwork__create_when_refpecs_given(void) cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); cl_git_pass(git_remote_create(&remote, g_repo, "origin", cl_fixture("testrepo.git"))); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL)); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); cl_git_pass(git_repository_fetchhead_foreach(g_repo, find_master_haacked, NULL)); cl_assert(find_master_haacked_called); @@ -500,9 +500,9 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) cl_git_pass(git_remote_lookup(&remote, g_repo, "origin")); cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), "FETCH_HEAD")); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL)); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); { int i; diff --git a/tests/ignore/path.c b/tests/ignore/path.c index d55bdc5dd..a574d1d79 100644 --- a/tests/ignore/path.c +++ b/tests/ignore/path.c @@ -257,7 +257,7 @@ void test_ignore_path__skip_gitignore_directory(void) { cl_git_rewritefile("attr/.git/info/exclude", "/NewFolder\n/NewFolder/NewFolder"); cl_must_pass(p_unlink("attr/.gitignore")); - cl_assert(!git_path_exists("attr/.gitignore")); + cl_assert(!git_fs_path_exists("attr/.gitignore")); p_mkdir("attr/.gitignore", 0777); cl_git_mkfile("attr/.gitignore/garbage.txt", "new_file\n"); @@ -270,7 +270,7 @@ void test_ignore_path__skip_gitignore_directory(void) void test_ignore_path__subdirectory_gitignore(void) { cl_must_pass(p_unlink("attr/.gitignore")); - cl_assert(!git_path_exists("attr/.gitignore")); + cl_assert(!git_fs_path_exists("attr/.gitignore")); cl_git_mkfile( "attr/.gitignore", "file1\n"); diff --git a/tests/index/crlf.c b/tests/index/crlf.c index 8d2a5fcce..7520c23a3 100644 --- a/tests/index/crlf.c +++ b/tests/index/crlf.c @@ -53,7 +53,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) git_blob *blob; bool failed = true; - basename = git_path_basename(actual_path->ptr); + basename = git_fs_path_basename(actual_path->ptr); if (!strcmp(basename, ".git") || !strcmp(basename, ".gitattributes")) { failed = false; @@ -65,7 +65,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) cl_git_pass(git_str_puts(&expected_path_fail, expected_path.ptr)); cl_git_pass(git_str_puts(&expected_path_fail, ".fail")); - if (git_path_isfile(expected_path.ptr)) { + if (git_fs_path_isfile(expected_path.ptr)) { cl_git_pass(git_index_add_bypath(g_index, basename)); cl_assert(entry = git_index_get_bypath(g_index, basename, 0)); @@ -77,7 +77,7 @@ static int add_and_check_file(void *payload, git_str *actual_path) goto done; git_blob_free(blob); - } else if (git_path_isfile(expected_path_fail.ptr)) { + } else if (git_fs_path_isfile(expected_path_fail.ptr)) { cl_git_pass(git_futils_readbuffer(&expected_contents, expected_path_fail.ptr)); git_str_rtrim(&expected_contents); @@ -161,7 +161,7 @@ static void test_add_index(const char *safecrlf, const char *autocrlf, const cha cl_fixture_sandbox(expected_fixture.ptr); compare_data.dirname = sandboxname.ptr; - cl_git_pass(git_path_direach(&reponame, 0, add_and_check_file, &compare_data)); + cl_git_pass(git_fs_path_direach(&reponame, 0, add_and_check_file, &compare_data)); cl_fixture_cleanup(expected_fixture.ptr); git_str_dispose(&expected_fixture); @@ -179,9 +179,9 @@ static void set_up_workingdir(const char *name) size_t i; const char *fn; - git_path_dirload(&contents, name, 0, 0); + git_fs_path_dirload(&contents, name, 0, 0); git_vector_foreach(&contents, i, fn) { - char *basename = git_path_basename(fn); + char *basename = git_fs_path_basename(fn); bool skip = strncasecmp(basename, ".git", 4) == 0 && strlen(basename) == 4; git__free(basename); @@ -193,9 +193,9 @@ static void set_up_workingdir(const char *name) git_vector_free_deep(&contents); /* copy input files */ - git_path_dirload(&contents, cl_fixture("crlf"), 0, 0); + git_fs_path_dirload(&contents, cl_fixture("crlf"), 0, 0); git_vector_foreach(&contents, i, fn) { - char *basename = git_path_basename(fn); + char *basename = git_fs_path_basename(fn); git_str dest_filename = GIT_STR_INIT; if (strcmp(basename, ".gitted") && diff --git a/tests/index/tests.c b/tests/index/tests.c index 9b28028e6..b6715574e 100644 --- a/tests/index/tests.c +++ b/tests/index/tests.c @@ -571,9 +571,9 @@ void test_index_tests__cannot_add_invalid_filename(void) cl_must_pass(p_mkdir("./invalid/subdir", 0777)); /* cl_git_mkfile() needs the dir to exist */ - if (!git_path_exists("./invalid/.GIT")) + if (!git_fs_path_exists("./invalid/.GIT")) cl_must_pass(p_mkdir("./invalid/.GIT", 0777)); - if (!git_path_exists("./invalid/.GiT")) + if (!git_fs_path_exists("./invalid/.GiT")) cl_must_pass(p_mkdir("./invalid/.GiT", 0777)); assert_add_bypath_fails(repo, ".git/hello"); diff --git a/tests/iterator/index.c b/tests/iterator/index.c index 69b795f5c..7218b4f75 100644 --- a/tests/iterator/index.c +++ b/tests/iterator/index.c @@ -283,7 +283,7 @@ void test_iterator_index__case_folding(void) int fs_is_ci = 0; cl_git_pass(git_str_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg")); - fs_is_ci = git_path_exists(path.ptr); + fs_is_ci = git_fs_path_exists(path.ptr); git_str_dispose(&path); index_iterator_test( diff --git a/tests/iterator/workdir.c b/tests/iterator/workdir.c index 7ca726c24..86b847cab 100644 --- a/tests/iterator/workdir.c +++ b/tests/iterator/workdir.c @@ -1024,7 +1024,7 @@ static void create_paths(const char *root, int depth) int i; cl_git_pass(git_str_puts(&fullpath, root)); - cl_git_pass(git_path_to_dir(&fullpath)); + cl_git_pass(git_fs_path_to_dir(&fullpath)); root_len = fullpath.size; diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c index 1eb423ef7..73a1d852d 100644 --- a/tests/merge/merge_helpers.c +++ b/tests/merge/merge_helpers.c @@ -346,7 +346,7 @@ int merge_test_workdir(git_repository *repo, const struct merge_index_entry expe git_str wd = GIT_STR_INIT; git_str_puts(&wd, repo->workdir); - git_path_direach(&wd, 0, dircount, &actual_len); + git_fs_path_direach(&wd, 0, dircount, &actual_len); if (actual_len != expected_len) return 0; diff --git a/tests/merge/workdir/setup.c b/tests/merge/workdir/setup.c index fe33e21f2..3db2d074f 100644 --- a/tests/merge/workdir/setup.c +++ b/tests/merge/workdir/setup.c @@ -48,15 +48,15 @@ static bool test_file_contents(const char *filename, const char *expected) { git_str file_path_buf = GIT_STR_INIT, file_buf = GIT_STR_INIT; bool equals; - + git_str_joinpath(&file_path_buf, git_repository_path(repo), filename); - + cl_git_pass(git_futils_readbuffer(&file_buf, file_path_buf.ptr)); equals = (strcmp(file_buf.ptr, expected) == 0); git_str_dispose(&file_path_buf); git_str_dispose(&file_buf); - + return equals; } @@ -77,13 +77,13 @@ void test_merge_workdir_setup__one_branch(void) git_oid our_oid; git_reference *octo1_ref; git_annotated_commit *our_head, *their_heads[1]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); @@ -92,7 +92,7 @@ void test_merge_workdir_setup__one_branch(void) cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'\n")); git_reference_free(octo1_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -103,10 +103,10 @@ void test_merge_workdir_setup__one_oid(void) git_oid our_oid; git_oid octo1_oid; git_annotated_commit *our_head, *their_heads[1]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); @@ -128,10 +128,10 @@ void test_merge_workdir_setup__two_branches(void) git_reference *octo1_ref; git_reference *octo2_ref; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -139,15 +139,15 @@ void test_merge_workdir_setup__two_branches(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -161,13 +161,13 @@ void test_merge_workdir_setup__three_branches(void) git_reference *octo2_ref; git_reference *octo3_ref; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); @@ -180,7 +180,7 @@ void test_merge_workdir_setup__three_branches(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); @@ -199,13 +199,13 @@ void test_merge_workdir_setup__three_oids(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); - + cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); @@ -218,7 +218,7 @@ void test_merge_workdir_setup__three_oids(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO2_OID "'; commit '" OCTO3_OID "'\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -232,7 +232,7 @@ void test_merge_workdir_setup__branches_and_oids_1(void) git_reference *octo1_ref; git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -248,7 +248,7 @@ void test_merge_workdir_setup__branches_and_oids_1(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "'; commit '" OCTO2_OID "'\n")); - + git_reference_free(octo1_ref); git_annotated_commit_free(our_head); @@ -271,23 +271,23 @@ void test_merge_workdir_setup__branches_and_oids_2(void) cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_oid_fromstr(&octo2_oid, OCTO2_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo2_oid)); cl_git_pass(git_reference_lookup(&octo3_ref, repo, GIT_REFS_HEADS_DIR OCTO3_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo3_ref)); - + cl_git_pass(git_oid_fromstr(&octo4_oid, OCTO4_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[3], repo, &octo4_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "'; commit '" OCTO2_OID "'; commit '" OCTO4_OID "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo3_ref); @@ -307,7 +307,7 @@ void test_merge_workdir_setup__branches_and_oids_3(void) git_oid octo3_oid; git_reference *octo4_ref; git_annotated_commit *our_head, *their_heads[4]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -319,17 +319,17 @@ void test_merge_workdir_setup__branches_and_oids_3(void) cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); - + cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "'; commit '" OCTO3_OID "'\n")); - + git_reference_free(octo2_ref); git_reference_free(octo4_ref); @@ -350,19 +350,19 @@ void test_merge_workdir_setup__branches_and_oids_4(void) git_reference *octo4_ref; git_reference *octo5_ref; git_annotated_commit *our_head, *their_heads[5]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_oid)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_HEADS_DIR OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); - + cl_git_pass(git_oid_fromstr(&octo3_oid, OCTO3_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo3_oid)); - + cl_git_pass(git_reference_lookup(&octo4_ref, repo, GIT_REFS_HEADS_DIR OCTO4_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); @@ -375,7 +375,7 @@ void test_merge_workdir_setup__branches_and_oids_4(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; branches '" OCTO2_BRANCH "', '" OCTO4_BRANCH "' and '" OCTO5_BRANCH "'; commit '" OCTO3_OID "'\n")); - + git_reference_free(octo2_ref); git_reference_free(octo4_ref); git_reference_free(octo5_ref); @@ -396,30 +396,30 @@ void test_merge_workdir_setup__three_same_branches(void) git_reference *octo1_2_ref; git_reference *octo1_3_ref; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_1_ref)); - + cl_git_pass(git_reference_lookup(&octo1_2_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo1_2_ref)); - + cl_git_pass(git_reference_lookup(&octo1_3_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[2], repo, octo1_3_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO1_BRANCH "' and '" OCTO1_BRANCH "'\n")); - + git_reference_free(octo1_1_ref); git_reference_free(octo1_2_ref); git_reference_free(octo1_3_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -434,26 +434,26 @@ void test_merge_workdir_setup__three_same_oids(void) git_oid octo1_2_oid; git_oid octo1_3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[0], repo, &octo1_1_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_2_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[1], repo, &octo1_2_oid)); - + cl_git_pass(git_oid_fromstr(&octo1_3_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_lookup(&their_heads[2], repo, &octo1_3_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 3)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO1_OID "\n" OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge commit '" OCTO1_OID "'; commit '" OCTO1_OID "'; commit '" OCTO1_OID "'\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -473,7 +473,7 @@ static int create_remote_tracking_branch(const char *branch_name, const char *oi (error = git_str_puts(&remotes_path, GIT_REFS_REMOTES_DIR)) < 0) goto done; - if (!git_path_exists(git_str_cstr(&remotes_path)) && + if (!git_fs_path_exists(git_str_cstr(&remotes_path)) && (error = p_mkdir(git_str_cstr(&remotes_path), 0777)) < 0) goto done; @@ -481,7 +481,7 @@ static int create_remote_tracking_branch(const char *branch_name, const char *oi (error = git_str_puts(&origin_path, "origin")) < 0) goto done; - if (!git_path_exists(git_str_cstr(&origin_path)) && + if (!git_fs_path_exists(git_str_cstr(&origin_path)) && (error = p_mkdir(git_str_cstr(&origin_path), 0777)) < 0) goto done; @@ -514,10 +514,10 @@ void test_merge_workdir_setup__remote_tracking_one_branch(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); @@ -526,7 +526,7 @@ void test_merge_workdir_setup__remote_tracking_one_branch(void) cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n")); git_reference_free(octo1_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -544,7 +544,7 @@ void test_merge_workdir_setup__remote_tracking_two_branches(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -552,15 +552,15 @@ void test_merge_workdir_setup__remote_tracking_two_branches(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "' and 'refs/remotes/origin/" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -578,13 +578,13 @@ void test_merge_workdir_setup__remote_tracking_three_branches(void) cl_git_pass(create_remote_tracking_branch(OCTO1_BRANCH, OCTO1_OID)); cl_git_pass(create_remote_tracking_branch(OCTO2_BRANCH, OCTO2_OID)); cl_git_pass(create_remote_tracking_branch(OCTO3_BRANCH, OCTO3_OID)); - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); - + cl_git_pass(git_reference_lookup(&octo2_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO2_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); @@ -597,7 +597,7 @@ void test_merge_workdir_setup__remote_tracking_three_branches(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge remote-tracking branches 'refs/remotes/origin/" OCTO1_BRANCH "', 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO3_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); @@ -628,15 +628,15 @@ void test_merge_workdir_setup__normal_branch_and_remote_tracking_branch(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO2_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -654,7 +654,7 @@ void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void) cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_REMOTES_DIR "origin/" OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -662,15 +662,15 @@ void test_merge_workdir_setup__remote_tracking_branch_and_normal_branch(void) cl_git_pass(git_annotated_commit_from_ref(&their_heads[1], repo, octo2_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 2)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO2_BRANCH "', remote-tracking branch 'refs/remotes/origin/" OCTO1_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -691,7 +691,7 @@ void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branche cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); - + cl_git_pass(git_reference_lookup(&octo1_ref, repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH)); cl_git_pass(git_annotated_commit_from_ref(&their_heads[0], repo, octo1_ref)); @@ -705,17 +705,17 @@ void test_merge_workdir_setup__two_remote_tracking_branch_and_two_normal_branche cl_git_pass(git_annotated_commit_from_ref(&their_heads[3], repo, octo4_ref)); cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 4)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n" OCTO2_OID "\n" OCTO3_OID "\n" OCTO4_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "', remote-tracking branches 'refs/remotes/origin/" OCTO2_BRANCH "' and 'refs/remotes/origin/" OCTO4_BRANCH "'\n")); - + git_reference_free(octo1_ref); git_reference_free(octo2_ref); git_reference_free(octo3_ref); git_reference_free(octo4_ref); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -735,14 +735,14 @@ void test_merge_workdir_setup__pull_one(void) cl_git_pass(git_oid_fromstr(&octo1_1_oid, OCTO1_OID)); cl_git_pass(git_annotated_commit_from_fetchhead(&their_heads[0], repo, GIT_REFS_HEADS_DIR OCTO1_BRANCH, "http://remote.url/repo.git", &octo1_1_oid)); - + cl_git_pass(git_merge__setup(repo, our_head, (const git_annotated_commit **)their_heads, 1)); - + cl_assert(test_file_contents(GIT_MERGE_HEAD_FILE, OCTO1_OID "\n")); cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch 'octo1' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); } @@ -754,7 +754,7 @@ void test_merge_workdir_setup__pull_two(void) git_oid octo1_oid; git_oid octo2_oid; git_annotated_commit *our_head, *their_heads[2]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -770,7 +770,7 @@ void test_merge_workdir_setup__pull_two(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO2_BRANCH "' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -784,7 +784,7 @@ void test_merge_workdir_setup__pull_three(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -803,7 +803,7 @@ void test_merge_workdir_setup__pull_three(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "', '" OCTO2_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.url/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -817,7 +817,7 @@ void test_merge_workdir_setup__three_remotes(void) git_oid octo2_oid; git_oid octo3_oid; git_annotated_commit *our_head, *their_heads[3]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -836,7 +836,7 @@ void test_merge_workdir_setup__three_remotes(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branch '" OCTO1_BRANCH "' of http://remote.first/repo.git, branch '" OCTO2_BRANCH "' of http://remote.second/repo.git, branch '" OCTO3_BRANCH "' of http://remote.third/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -851,7 +851,7 @@ void test_merge_workdir_setup__two_remotes(void) git_oid octo3_oid; git_oid octo4_oid; git_annotated_commit *our_head, *their_heads[4]; - + cl_git_pass(git_oid_fromstr(&our_oid, ORIG_HEAD)); cl_git_pass(git_annotated_commit_lookup(&our_head, repo, &our_oid)); @@ -873,7 +873,7 @@ void test_merge_workdir_setup__two_remotes(void) cl_assert(test_file_contents(GIT_ORIG_HEAD_FILE, ORIG_HEAD "\n")); cl_assert(test_file_contents(GIT_MERGE_MODE_FILE, "no-ff")); cl_assert(test_file_contents(GIT_MERGE_MSG_FILE, "Merge branches '" OCTO1_BRANCH "' and '" OCTO3_BRANCH "' of http://remote.first/repo.git, branches '" OCTO2_BRANCH "' and '" OCTO4_BRANCH "' of http://remote.second/repo.git\n")); - + git_annotated_commit_free(our_head); git_annotated_commit_free(their_heads[0]); git_annotated_commit_free(their_heads[1]); @@ -1036,9 +1036,9 @@ void test_merge_workdir_setup__removed_after_failure(void) cl_git_fail(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_HEAD_FILE)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MODE_FILE)); - cl_assert(!git_path_exists("merge-resolve/.git/" GIT_MERGE_MSG_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_HEAD_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_MODE_FILE)); + cl_assert(!git_fs_path_exists("merge-resolve/.git/" GIT_MERGE_MSG_FILE)); git_reference_free(octo1_ref); @@ -1061,7 +1061,7 @@ void test_merge_workdir_setup__unlocked_after_success(void) cl_git_pass(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/index.lock")); + cl_assert(!git_fs_path_exists("merge-resolve/.git/index.lock")); git_reference_free(octo1_ref); @@ -1087,7 +1087,7 @@ void test_merge_workdir_setup__unlocked_after_conflict(void) cl_git_fail(git_merge( repo, (const git_annotated_commit **)&their_heads[0], 1, NULL, NULL)); - cl_assert(!git_path_exists("merge-resolve/.git/index.lock")); + cl_assert(!git_fs_path_exists("merge-resolve/.git/index.lock")); git_reference_free(octo1_ref); diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index 6c4cf7e3c..f51ff09a7 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -504,7 +504,7 @@ void test_merge_workdir_simple__checkout_ours(void) cl_assert(merge_test_index(repo_index, merge_index_entries, 8)); cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3)); - cl_assert(git_path_exists(TEST_REPO_PATH "/conflicting.txt")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/conflicting.txt")); } void test_merge_workdir_simple__favor_ours(void) diff --git a/tests/object/blob/write.c b/tests/object/blob/write.c index 802467498..422258d63 100644 --- a/tests/object/blob/write.c +++ b/tests/object/blob/write.c @@ -42,7 +42,7 @@ void test_object_blob_write__can_create_a_blob_in_a_standard_repo_from_a_absolut repo = cl_git_sandbox_init(WORKDIR); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); - cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); + cl_must_pass(git_fs_path_prettify_dir(&full_path, ELSEWHERE, NULL)); cl_must_pass(git_str_puts(&full_path, "test.txt")); assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); @@ -58,7 +58,7 @@ void test_object_blob_write__can_create_a_blob_in_a_bare_repo_from_a_absolute_fi repo = cl_git_sandbox_init(BARE_REPO); cl_must_pass(p_mkdir(ELSEWHERE, 0777)); - cl_must_pass(git_path_prettify_dir(&full_path, ELSEWHERE, NULL)); + cl_must_pass(git_fs_path_prettify_dir(&full_path, ELSEWHERE, NULL)); cl_must_pass(git_str_puts(&full_path, "test.txt")); assert_blob_creation(ELSEWHERE "/test.txt", git_str_cstr(&full_path), &git_blob_create_from_disk); diff --git a/tests/object/raw/write.c b/tests/object/raw/write.c index 9bc127680..40e05f357 100644 --- a/tests/object/raw/write.c +++ b/tests/object/raw/write.c @@ -39,8 +39,8 @@ static void streaming_write(git_oid *oid, git_odb *odb, git_rawobj *raw) static void check_object_files(object_data *d) { - cl_assert(git_path_exists(d->dir)); - cl_assert(git_path_exists(d->file)); + cl_assert(git_fs_path_exists(d->dir)); + cl_assert(git_fs_path_exists(d->file)); } static void cmp_objects(git_rawobj *o1, git_rawobj *o2) diff --git a/tests/odb/alternates.c b/tests/odb/alternates.c index e36010b75..6c00fda2f 100644 --- a/tests/odb/alternates.c +++ b/tests/odb/alternates.c @@ -26,7 +26,7 @@ static void init_linked_repo(const char *path, const char *alternate) git_str_clear(&filepath); cl_git_pass(git_repository_init(&repo, path, 1)); - cl_git_pass(git_path_prettify(&destpath, alternate, NULL)); + cl_git_pass(git_fs_path_prettify(&destpath, alternate, NULL)); cl_git_pass(git_str_joinpath(&destpath, destpath.ptr, "objects")); cl_git_pass(git_str_joinpath(&filepath, git_repository_path(repo), "objects/info")); cl_git_pass(git_futils_mkdir(filepath.ptr, 0755, GIT_MKDIR_PATH)); diff --git a/tests/odb/emptyobjects.c b/tests/odb/emptyobjects.c index 89b22ad4a..e3ec62d3f 100644 --- a/tests/odb/emptyobjects.c +++ b/tests/odb/emptyobjects.c @@ -28,7 +28,7 @@ void test_odb_emptyobjects__blob_notfound(void) cl_git_fail_with(GIT_ENOTFOUND, git_blob_lookup(&blob, g_repo, &id)); cl_git_pass(git_odb_write(&written_id, g_odb, "", 0, GIT_OBJECT_BLOB)); - cl_assert(git_path_exists(TEST_REPO_PATH "/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391")); } void test_odb_emptyobjects__read_tree(void) diff --git a/tests/online/clone.c b/tests/online/clone.c index c55cf9f95..ba88dff9c 100644 --- a/tests/online/clone.c +++ b/tests/online/clone.c @@ -194,7 +194,7 @@ void test_online_clone__can_checkout_a_cloned_repo(void) cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); @@ -930,11 +930,11 @@ void test_online_clone__proxy_cred_callback_after_failed_url_creds(void) void test_online_clone__azurerepos(void) { cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/test", "./foo", &g_options)); - cl_assert(git_path_exists("./foo/master.txt")); + cl_assert(git_fs_path_exists("./foo/master.txt")); } void test_online_clone__path_whitespace(void) { cl_git_pass(git_clone(&g_repo, "https://libgit2@dev.azure.com/libgit2/test/_git/spaces%20in%20the%20name", "./foo", &g_options)); - cl_assert(git_path_exists("./foo/master.txt")); + cl_assert(git_fs_path_exists("./foo/master.txt")); } diff --git a/tests/online/customcert.c b/tests/online/customcert.c index 098212b14..7932a9e68 100644 --- a/tests/online/customcert.c +++ b/tests/online/customcert.c @@ -66,7 +66,7 @@ void test_online_customcert__file(void) { #if (GIT_OPENSSL || GIT_MBEDTLS) cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_ONE_URL, "./cloned", NULL)); - cl_assert(git_path_exists("./cloned/master.txt")); + cl_assert(git_fs_path_exists("./cloned/master.txt")); #endif } @@ -74,6 +74,6 @@ void test_online_customcert__path(void) { #if (GIT_OPENSSL || GIT_MBEDTLS) cl_git_pass(git_clone(&g_repo, CUSTOM_CERT_TWO_URL, "./cloned", NULL)); - cl_assert(git_path_exists("./cloned/master.txt")); + cl_assert(git_fs_path_exists("./cloned/master.txt")); #endif } diff --git a/tests/pack/indexer.c b/tests/pack/indexer.c index 5958bc4ba..954bee953 100644 --- a/tests/pack/indexer.c +++ b/tests/pack/indexer.c @@ -289,7 +289,7 @@ static int find_tmp_file_recurs(void *opaque, git_str *path) return error; if (S_ISDIR(st.st_mode)) - return git_path_direach(path, 0, find_tmp_file_recurs, opaque); + return git_fs_path_direach(path, 0, find_tmp_file_recurs, opaque); /* This is the template that's used in git_futils_mktmp. */ if (strstr(git_str_cstr(path), "_git2_") != NULL) diff --git a/tests/pack/packbuilder.c b/tests/pack/packbuilder.c index b4c655c5e..5b1f7b9e9 100644 --- a/tests/pack/packbuilder.c +++ b/tests/pack/packbuilder.c @@ -156,8 +156,8 @@ void test_pack_packbuilder__write_default_path(void) seed_packbuilder(); cl_git_pass(git_packbuilder_write(_packbuilder, NULL, 0, NULL, NULL)); - cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx")); - cl_assert(git_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack")); + cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.idx")); + cl_assert(git_fs_path_exists("objects/pack/pack-7f5fa362c664d68ba7221259be1cbd187434b2f0.pack")); } static void test_write_pack_permission(mode_t given, mode_t expected) diff --git a/tests/path/core.c b/tests/path/core.c index 1d6066933..8576b471e 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -1,5 +1,5 @@ #include "clar_libgit2.h" -#include "path.h" +#include "fs_path.h" void test_path_core__cleanup(void) { @@ -14,7 +14,7 @@ static void test_make_relative( { git_str buf = GIT_STR_INIT; git_str_puts(&buf, path); - cl_assert_equal_i(expected_status, git_path_make_relative(&buf, parent)); + cl_assert_equal_i(expected_status, git_fs_path_make_relative(&buf, parent)); cl_assert_equal_s(expected_path, buf.ptr); git_str_dispose(&buf); } @@ -59,284 +59,208 @@ void test_path_core__make_relative(void) void test_path_core__isvalid_standard(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.file", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar/file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar/.file", 0)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_path_validate(NULL, "foo//bar", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo//bar", 0)); /* leading slash */ - cl_assert_equal_b(false, git_path_validate(NULL, "/", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "/foo", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "/foo/bar", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("/", 0)); + cl_assert_equal_b(false, git_fs_path_validate("/foo", 0)); + cl_assert_equal_b(false, git_fs_path_validate("/foo/bar", 0)); /* trailing slash */ - cl_assert_equal_b(false, git_path_validate(NULL, "foo/", 0, 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/", 0, 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo/", 0)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar/", 0)); } void test_path_core__isvalid_dot_and_dotdot(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "./foo", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "..", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/..", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "../foo", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - - cl_assert_equal_b(false, git_path_validate(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL)); -} - -void test_path_core__isvalid_dot_git(void) -{ - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate(".", 0)); + cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); + + cl_assert_equal_b(true, git_fs_path_validate("..", 0)); + cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/..", 0)); + cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); + + cl_assert_equal_b(false, git_fs_path_validate(".", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + + cl_assert_equal_b(false, git_fs_path_validate("..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); } void test_path_core__isvalid_backslash(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\file.txt", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar\\", 0, 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\", 0)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); } void test_path_core__isvalid_trailing_dot(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo...", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo./bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(true, git_fs_path_validate("foo.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo...", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo./bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_validate("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); } void test_path_core__isvalid_trailing_space(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, " ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo /bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar ", 0)); + cl_assert_equal_b(true, git_fs_path_validate(" ", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo /bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_validate("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); } void test_path_core__isvalid_trailing_colon(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "foo:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ":", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo:/bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON)); -} - -void test_path_core__isvalid_dotgit_ntfs(void) -{ - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_fs_path_validate("foo:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo/bar:", 0)); + cl_assert_equal_b(true, git_fs_path_validate(":", 0)); + cl_assert_equal_b(true, git_fs_path_validate("foo:/bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_validate("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); } void test_path_core__isvalid_dos_paths(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "aux", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "con", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "prn", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "nul", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("aux", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("con", 0)); + cl_assert_equal_b(true, git_fs_path_validate("prn", 0)); + cl_assert_equal_b(true, git_fs_path_validate("nul", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("con", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_validate("aux1", 0)); + cl_assert_equal_b(true, git_fs_path_validate("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_dos_paths_withnum(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "com1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1:", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1.asdf\\zippy", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1:asdf\\foobar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt1", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_path_validate(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_path_validate(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com1", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1:", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("lpt1", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_validate("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_validate("com0", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com10", 0)); + cl_assert_equal_b(true, git_fs_path_validate("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_validate("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_nt_chars(void) { - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\001foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\037bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdffoo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf:foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf\"bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf|foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf?bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "asdf*bar", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdffoo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_path_validate(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_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_validate(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_validate(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_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\001foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\037bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdffoo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf:foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf\"bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf|foo", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf?bar", 0)); + cl_assert_equal_b(true, git_fs_path_validate("asdf*bar", 0)); + + cl_assert_equal_b(false, git_fs_path_validate("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_validate("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); } void test_path_core__validate_workdir(void) { - cl_must_pass(git_path_validate_workdir(NULL, "/foo/bar")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/foo/bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); #ifdef GIT_WIN32 /* * In the absense of a repo configuration, 259 character paths * succeed. >= 260 character paths fail. */ - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); - cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); /* count characters, not bytes */ - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_fail(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #else - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_pass(git_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #endif } @@ -352,15 +276,15 @@ void test_path_core__validate_workdir_with_core_longpath(void) cl_git_pass(git_repository_config(&config, repo)); /* fail by default */ - cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly on */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); - cl_must_pass(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly off */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); - cl_must_fail(git_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); git_config_free(config); git_repository_free(repo); @@ -376,7 +300,7 @@ static void test_join_unrooted( git_str result = GIT_STR_INIT; ssize_t root_at; - cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at)); + cl_git_pass(git_fs_path_join_unrooted(&result, path, base, &root_at)); cl_assert_equal_s(expected_result, result.ptr); cl_assert_equal_i(expected_rootlen, root_at); diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index 2f9fcae4f..5b3a31137 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -1,4 +1,5 @@ #include "clar_libgit2.h" + #include "path.h" static char *gitmodules_altnames[] = { @@ -118,3 +119,88 @@ void test_path_dotgit__dotgit_modules_symlink(void) cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } + +void test_core_path__git_fs_path_is_file(void) +{ + cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS)); + cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS)); + cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS)); +} + +void test_path_dotgit__isvalid_dot_git(void) +{ + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + + cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); +} + +void test_path_dotgit__isvalid_dotgit_ntfs(void) +{ + cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); + + cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); + cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); + + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + + cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); +} + +void test_path_dotgit__isvalid_dotgit_with_hfs_ignorables(void) +{ + cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(false, git_path_validate(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_validate(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_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); +} diff --git a/tests/refs/branches/create.c b/tests/refs/branches/create.c index 7a49ad548..2fb11668b 100644 --- a/tests/refs/branches/create.c +++ b/tests/refs/branches/create.c @@ -145,7 +145,7 @@ void test_refs_branches_create__can_create_branch_with_unicode(void) const char *expected[] = { nfc, nfd, emoji }; unsigned int i; bool fs_decompose_unicode = - git_path_does_fs_decompose_unicode(git_repository_path(repo)); + git_fs_path_does_decompose_unicode(git_repository_path(repo)); retrieve_known_commit(&target, repo); diff --git a/tests/refs/branches/delete.c b/tests/refs/branches/delete.c index aad5c090f..077882b22 100644 --- a/tests/refs/branches/delete.c +++ b/tests/refs/branches/delete.c @@ -173,13 +173,13 @@ void test_refs_branches_delete__removes_empty_folders(void) cl_git_pass(git_str_joinpath(&ref_folder, commondir, "refs/heads/some/deep")); cl_git_pass(git_str_join3(&reflog_folder, '/', commondir, GIT_REFLOG_DIR, "refs/heads/some/deep")); - cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == true); - cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&ref_folder)) == true); + cl_assert(git_fs_path_exists(git_str_cstr(&reflog_folder)) == true); cl_git_pass(git_branch_delete(branch)); - cl_assert(git_path_exists(git_str_cstr(&ref_folder)) == false); - cl_assert(git_path_exists(git_str_cstr(&reflog_folder)) == false); + cl_assert(git_fs_path_exists(git_str_cstr(&ref_folder)) == false); + cl_assert(git_fs_path_exists(git_str_cstr(&reflog_folder)) == false); git_reference_free(branch); git_str_dispose(&ref_folder); diff --git a/tests/refs/delete.c b/tests/refs/delete.c index c76d126eb..42cc534b5 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -33,7 +33,7 @@ void test_refs_delete__packed_loose(void) /* Ensure the loose reference exists on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Lookup the reference */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name)); @@ -49,7 +49,7 @@ void test_refs_delete__packed_loose(void) cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); /* Ensure the loose reference doesn't exist any longer on the file system */ - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); git_reference_free(another_looked_up_ref); git_str_dispose(&temp_path); diff --git a/tests/refs/pack.c b/tests/refs/pack.c index 125b1adb0..1c1cd51cb 100644 --- a/tests/refs/pack.c +++ b/tests/refs/pack.c @@ -63,7 +63,7 @@ void test_refs_pack__loose(void) /* Ensure the packed-refs file exists */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), GIT_PACKEDREFS_FILE)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Ensure the known ref can still be looked up but is now packed */ cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); @@ -72,7 +72,7 @@ void test_refs_pack__loose(void) /* Ensure the known ref has been removed from the loose folder structure */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), loose_tag_ref_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); git_reference_free(reference); git_str_dispose(&temp_path); diff --git a/tests/refs/ref_helpers.c b/tests/refs/ref_helpers.c index e55364c6e..943d0f551 100644 --- a/tests/refs/ref_helpers.c +++ b/tests/refs/ref_helpers.c @@ -16,7 +16,7 @@ int reference_is_packed(git_reference *ref) git_reference_name(ref)) < 0) return -1; - packed = !git_path_isfile(ref_path.ptr); + packed = !git_fs_path_isfile(ref_path.ptr); git_str_dispose(&ref_path); diff --git a/tests/refs/reflog/reflog.c b/tests/refs/reflog/reflog.c index 5bb6138df..32ce7ffb7 100644 --- a/tests/refs/reflog/reflog.c +++ b/tests/refs/reflog/reflog.c @@ -107,15 +107,15 @@ void test_refs_reflog_reflog__renaming_the_reference_moves_the_reflog(void) git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); git_str_joinpath(&moved_log_path, git_str_cstr(&moved_log_path), "refs/moved"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&moved_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&moved_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&moved_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&moved_log_path))); git_reference_free(new_master); git_str_dispose(&moved_log_path); @@ -130,13 +130,13 @@ void test_refs_reflog_reflog__deleting_the_reference_deletes_the_reflog(void) git_str_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&master_log_path, git_str_cstr(&master_log_path), "refs/heads/master"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&master_log_path))); cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master")); cl_git_pass(git_reference_delete(master)); git_reference_free(master); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&master_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&master_log_path))); git_str_dispose(&master_log_path); } @@ -153,7 +153,7 @@ void test_refs_reflog_reflog__removes_empty_reflog_dir(void) git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); @@ -180,7 +180,7 @@ void test_refs_reflog_reflog__fails_gracefully_on_nonempty_reflog_dir(void) git_str_joinpath(&log_path, git_repository_path(g_repo), GIT_REFLOG_DIR); git_str_joinpath(&log_path, git_str_cstr(&log_path), "refs/heads/new-dir/new-head"); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); /* delete the ref manually, leave the reflog */ cl_must_pass(p_unlink("testrepo.git/refs/heads/new-dir/new-head")); @@ -212,7 +212,7 @@ void test_refs_reflog_reflog__reading_the_reflog_from_a_reference_with_no_log_re git_str subtrees_log_path = GIT_STR_INIT; git_str_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, refname); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&subtrees_log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&subtrees_log_path))); cl_git_pass(git_reflog_read(&reflog, g_repo, refname)); diff --git a/tests/refs/rename.c b/tests/refs/rename.c index fa732234a..f71e65782 100644 --- a/tests/refs/rename.c +++ b/tests/refs/rename.c @@ -41,7 +41,7 @@ void test_refs_rename__loose(void) /* Ensure the ref doesn't exist on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); /* Retrieval of the reference to rename */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, loose_tag_ref_name)); @@ -67,7 +67,7 @@ void test_refs_rename__loose(void) /* ...and the ref can be found in the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), new_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); @@ -83,7 +83,7 @@ void test_refs_rename__packed(void) /* Ensure the ref doesn't exist on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_head_name)); - cl_assert(!git_path_exists(temp_path.ptr)); + cl_assert(!git_fs_path_exists(temp_path.ptr)); /* The reference can however be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_head_name)); @@ -109,7 +109,7 @@ void test_refs_rename__packed(void) /* ...and the ref now happily lives in the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), brand_new_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(new_ref); git_reference_free(another_looked_up_ref); @@ -125,7 +125,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) /* Ensure the other reference exists on the file system */ cl_git_pass(git_str_joinpath(&temp_path, git_repository_path(g_repo), packed_test_head_name)); - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); /* Lookup the other reference */ cl_git_pass(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name)); @@ -151,7 +151,7 @@ void test_refs_rename__packed_doesnt_pack_others(void) cl_assert(reference_is_packed(another_looked_up_ref) == 0); /* Ensure the other ref still exists on the file system */ - cl_assert(git_path_exists(temp_path.ptr)); + cl_assert(git_fs_path_exists(temp_path.ptr)); git_reference_free(renamed_ref); git_reference_free(another_looked_up_ref); diff --git a/tests/refs/revparse.c b/tests/refs/revparse.c index 9c960702a..d02249754 100644 --- a/tests/refs/revparse.c +++ b/tests/refs/revparse.c @@ -329,13 +329,13 @@ static void create_fake_stash_reference_and_reflog(git_repository *repo) git_str_joinpath(&log_path, git_repository_path(repo), "logs/refs/fakestash"); - cl_assert_equal_i(false, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&log_path))); cl_git_pass(git_reference_lookup(&master, repo, "refs/heads/master")); cl_git_pass(git_reference_rename(&new_master, master, "refs/fakestash", 0, NULL)); git_reference_free(master); - cl_assert_equal_i(true, git_path_isfile(git_str_cstr(&log_path))); + cl_assert_equal_i(true, git_fs_path_isfile(git_str_cstr(&log_path))); git_str_dispose(&log_path); git_reference_free(new_master); diff --git a/tests/repo/config.c b/tests/repo/config.c index 0b9daac98..ee7e43dff 100644 --- a/tests/repo/config.c +++ b/tests/repo/config.c @@ -14,7 +14,7 @@ void test_repo_config__initialize(void) git_str_clear(&path); cl_must_pass(p_mkdir("alternate", 0777)); - cl_git_pass(git_path_prettify(&path, "alternate", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "alternate", NULL)); } void test_repo_config__cleanup(void) @@ -25,7 +25,7 @@ void test_repo_config__cleanup(void) cl_git_pass( git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_isdir("alternate")); + cl_assert(!git_fs_path_isdir("alternate")); cl_fixture_cleanup("empty_standard_repo"); @@ -101,7 +101,7 @@ void test_repo_config__read_with_no_configs_at_all(void) /* with none */ cl_must_pass(p_unlink("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); git_repository__configmap_lookup_cache_clear(repo); @@ -177,16 +177,16 @@ void test_repo_config__read_with_no_configs_at_all(void) cl_assert_equal_i(40, val); cl_must_pass(p_unlink("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); cl_must_pass(p_unlink("alternate/1/gitconfig")); - cl_assert(!git_path_isfile("alternate/1/gitconfig")); + cl_assert(!git_fs_path_isfile("alternate/1/gitconfig")); cl_must_pass(p_unlink("alternate/2/config")); - cl_assert(!git_path_isfile("alternate/2/config")); + cl_assert(!git_fs_path_isfile("alternate/2/config")); cl_must_pass(p_unlink("alternate/3/.gitconfig")); - cl_assert(!git_path_isfile("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_isfile("alternate/3/.gitconfig")); git_repository__configmap_lookup_cache_clear(repo); val = -1; @@ -196,8 +196,8 @@ void test_repo_config__read_with_no_configs_at_all(void) /* reopen */ - cl_assert(!git_path_isfile("empty_standard_repo/.git/config")); - cl_assert(!git_path_isfile("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_isfile("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_isfile("alternate/3/.gitconfig")); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); git_repository__configmap_lookup_cache_clear(repo); @@ -206,6 +206,6 @@ void test_repo_config__read_with_no_configs_at_all(void) cl_assert_equal_i(7, val); git_repository_free(repo); - cl_assert(!git_path_exists("empty_standard_repo/.git/config")); - cl_assert(!git_path_exists("alternate/3/.gitconfig")); + cl_assert(!git_fs_path_exists("empty_standard_repo/.git/config")); + cl_assert(!git_fs_path_exists("alternate/3/.gitconfig")); } diff --git a/tests/repo/discover.c b/tests/repo/discover.c index 2a24f1b29..523fdf8e3 100644 --- a/tests/repo/discover.c +++ b/tests/repo/discover.c @@ -33,7 +33,7 @@ static void ensure_repository_discover(const char *start_path, git_str_attach(&resolved, p_realpath(expected_path, NULL), 0); cl_assert(resolved.size > 0); - cl_git_pass(git_path_to_dir(&resolved)); + cl_git_pass(git_fs_path_to_dir(&resolved)); cl_git_pass(git_repository_discover(&found_path, start_path, 1, ceiling_dirs)); cl_assert_equal_s(found_path.ptr, resolved.ptr); @@ -47,7 +47,7 @@ static void write_file(const char *path, const char *content) git_file file; int error; - if (git_path_exists(path)) { + if (git_fs_path_exists(path)) { cl_git_pass(p_unlink(path)); } @@ -65,7 +65,7 @@ static void append_ceiling_dir(git_str *ceiling_dirs, const char *path) git_str pretty_path = GIT_STR_INIT; char ceiling_separator[2] = { GIT_PATH_LIST_SEPARATOR, '\0' }; - cl_git_pass(git_path_prettify_dir(&pretty_path, path, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&pretty_path, path, NULL)); if (ceiling_dirs->size > 0) git_str_puts(ceiling_dirs, ceiling_separator); diff --git a/tests/repo/env.c b/tests/repo/env.c index 4bd45d1a6..e3e522480 100644 --- a/tests/repo/env.c +++ b/tests/repo/env.c @@ -24,11 +24,11 @@ void test_repo_env__cleanup(void) { cl_git_sandbox_cleanup(); - if (git_path_isdir("attr")) + if (git_fs_path_isdir("attr")) git_futils_rmdir_r("attr", NULL, GIT_RMDIR_REMOVE_FILES); - if (git_path_isdir("testrepo.git")) + if (git_fs_path_isdir("testrepo.git")) git_futils_rmdir_r("testrepo.git", NULL, GIT_RMDIR_REMOVE_FILES); - if (git_path_isdir("peeled.git")) + if (git_fs_path_isdir("peeled.git")) git_futils_rmdir_r("peeled.git", NULL, GIT_RMDIR_REMOVE_FILES); clear_git_env(); @@ -81,7 +81,7 @@ static void env_cd_( const char *file, const char *func, int line) { git_str cwd_buf = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&cwd_buf, ".", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&cwd_buf, ".", NULL)); cl_must_pass(p_chdir(path)); passfail_(NULL, file, func, line); cl_must_pass(p_chdir(git_str_cstr(&cwd_buf))); @@ -141,7 +141,7 @@ void test_repo_env__open(void) cl_fixture_sandbox("peeled.git"); cl_git_pass(p_rename("attr/.gitted", "attr/.git")); - cl_git_pass(git_path_prettify_dir(&repo_dir_buf, "attr", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&repo_dir_buf, "attr", NULL)); repo_dir = git_str_cstr(&repo_dir_buf); /* GIT_DIR that doesn't exist */ diff --git a/tests/repo/init.c b/tests/repo/init.c index b41608cca..7cf6742ca 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -47,7 +47,7 @@ static void ensure_repository_init( { const char *workdir; - cl_assert(!git_path_isdir(working_directory)); + cl_assert(!git_fs_path_isdir(working_directory)); cl_git_pass(git_repository_init(&g_repo, working_directory, is_bare)); @@ -103,7 +103,7 @@ void test_repo_init__bare_repo_escaping_current_workdir(void) git_str path_repository = GIT_STR_INIT; git_str path_current_workdir = GIT_STR_INIT; - cl_git_pass(git_path_prettify_dir(&path_current_workdir, ".", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path_current_workdir, ".", NULL)); cl_git_pass(git_str_joinpath(&path_repository, git_str_cstr(&path_current_workdir), "a/b/c")); cl_git_pass(git_futils_mkdir_r(git_str_cstr(&path_repository), GIT_DIR_MODE)); @@ -176,15 +176,15 @@ void test_repo_init__additional_templates(void) cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "description")); - cl_assert(git_path_isfile(git_str_cstr(&path))); + cl_assert(git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "info/exclude")); - cl_assert(git_path_isfile(git_str_cstr(&path))); + cl_assert(git_fs_path_isfile(git_str_cstr(&path))); cl_git_pass( git_str_joinpath(&path, git_repository_path(g_repo), "hooks")); - cl_assert(git_path_isdir(git_str_cstr(&path))); + cl_assert(git_fs_path_isdir(git_str_cstr(&path))); /* won't confirm specific contents of hooks dir since it may vary */ git_str_dispose(&path); @@ -257,7 +257,7 @@ void test_repo_init__symlinks_win32_enabled_by_global_config(void) git_config *config, *repo_config; int val; - if (!git_path_supports_symlinks("link")) + if (!git_fs_path_supports_symlinks("link")) cl_skip(); create_tmp_global_config("tmp_global_config", "core.symlinks", "true"); @@ -303,7 +303,7 @@ void test_repo_init__symlinks_posix_detected(void) cl_skip(); #else assert_config_entry_on_init( - "core.symlinks", git_path_supports_symlinks("link") ? GIT_ENOTFOUND : false); + "core.symlinks", git_fs_path_supports_symlinks("link") ? GIT_ENOTFOUND : false); #endif } @@ -418,12 +418,12 @@ void test_repo_init__extended_1(void) cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/c_wd/")); cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/c.git/")); - cl_assert(git_path_isfile("root/b/c_wd/.git")); + cl_assert(git_fs_path_isfile("root/b/c_wd/.git")); cl_assert(!git_repository_is_bare(g_repo)); /* repo will not be counted as empty because we set head to "development" */ cl_assert(!git_repository_is_empty(g_repo)); - cl_git_pass(git_path_lstat(git_repository_path(g_repo), &st)); + cl_git_pass(git_fs_path_lstat(git_repository_path(g_repo), &st)); cl_assert(S_ISDIR(st.st_mode)); if (cl_is_chmod_supported()) cl_assert((S_ISGID & st.st_mode) == S_ISGID); @@ -482,7 +482,7 @@ void test_repo_init__relative_gitdir_2(void) git_str dot_git_content = GIT_STR_INIT; git_str full_path = GIT_STR_INIT; - cl_git_pass(git_path_prettify(&full_path, ".", NULL)); + cl_git_pass(git_fs_path_prettify(&full_path, ".", NULL)); cl_git_pass(git_str_joinpath(&full_path, full_path.ptr, "root/b/c_wd")); opts.workdir_path = full_path.ptr; @@ -604,16 +604,16 @@ void test_repo_init__at_filesystem_root(void) if (!cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE")) cl_skip(); - root_len = git_path_root(sandbox); + root_len = git_fs_path_root(sandbox); cl_assert(root_len >= 0); git_str_put(&root, sandbox, root_len+1); git_str_joinpath(&root, root.ptr, "libgit2_test_dir"); - cl_assert(!git_path_exists(root.ptr)); + cl_assert(!git_fs_path_exists(root.ptr)); cl_git_pass(git_repository_init(&repo, root.ptr, 0)); - cl_assert(git_path_isdir(root.ptr)); + cl_assert(git_fs_path_isdir(root.ptr)); cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES)); git_str_dispose(&root); diff --git a/tests/repo/open.c b/tests/repo/open.c index 6558805c8..f7ed2c373 100644 --- a/tests/repo/open.c +++ b/tests/repo/open.c @@ -8,7 +8,7 @@ void test_repo_open__cleanup(void) { cl_git_sandbox_cleanup(); - if (git_path_isdir("alternate")) + if (git_fs_path_isdir("alternate")) git_futils_rmdir_r("alternate", NULL, GIT_RMDIR_REMOVE_FILES); } @@ -147,7 +147,7 @@ void test_repo_open__with_symlinked_config(void) cl_git_pass(git_futils_mkdir_r("home", 0777)); cl_git_mkfile("home/.gitconfig.linked", "[global]\ntest = 4567\n"); cl_must_pass(symlink(".gitconfig.linked", "home/.gitconfig")); - cl_git_pass(git_path_prettify(&path, "home", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "home", NULL)); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); @@ -191,7 +191,7 @@ void test_repo_open__from_git_new_workdir(void) for (scan = links; *scan != NULL; scan++) { git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); - if (git_path_exists(link_tgt.ptr)) { + if (git_fs_path_exists(link_tgt.ptr)) { git_str_joinpath(&link_tgt, "../../empty_standard_repo/.git", *scan); git_str_joinpath(&link, "alternate/.git", *scan); if (strchr(*scan, '/')) @@ -201,7 +201,7 @@ void test_repo_open__from_git_new_workdir(void) } for (scan = copies; *scan != NULL; scan++) { git_str_joinpath(&link_tgt, "empty_standard_repo/.git", *scan); - if (git_path_exists(link_tgt.ptr)) { + if (git_fs_path_exists(link_tgt.ptr)) { git_str_joinpath(&link, "alternate/.git", *scan); cl_git_pass(git_futils_readbuffer(&body, link_tgt.ptr)); @@ -381,7 +381,7 @@ void test_repo_open__no_config(void) /* isolate from system level configs */ cl_must_pass(p_mkdir("alternate", 0777)); - cl_git_pass(git_path_prettify(&path, "alternate", NULL)); + cl_git_pass(git_fs_path_prettify(&path, "alternate", NULL)); cl_git_pass(git_libgit2_opts( GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr)); cl_git_pass(git_libgit2_opts( diff --git a/tests/repo/setters.c b/tests/repo/setters.c index 2c33db0db..9a965dec6 100644 --- a/tests/repo/setters.c +++ b/tests/repo/setters.c @@ -50,7 +50,7 @@ void test_repo_setters__setting_a_workdir_creates_a_gitlink(void) cl_git_pass(git_repository_set_workdir(repo, "./new_workdir", true)); - cl_assert(git_path_isfile("./new_workdir/.git")); + cl_assert(git_fs_path_isfile("./new_workdir/.git")); cl_git_pass(git_futils_readbuffer(&content, "./new_workdir/.git")); cl_assert(git__prefixcmp(git_str_cstr(&content), "gitdir: ") == 0); diff --git a/tests/repo/template.c b/tests/repo/template.c index 6f369c6d6..b0af96e36 100644 --- a/tests/repo/template.c +++ b/tests/repo/template.c @@ -56,10 +56,10 @@ static void assert_hooks_match( struct stat expected_st, st; cl_git_pass(git_str_joinpath(&expected, template_dir, hook_path)); - cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); + cl_git_pass(git_fs_path_lstat(expected.ptr, &expected_st)); cl_git_pass(git_str_joinpath(&actual, repo_dir, hook_path)); - cl_git_pass(git_path_lstat(actual.ptr, &st)); + cl_git_pass(git_fs_path_lstat(actual.ptr, &st)); cl_assert(expected_st.st_size == st.st_size); @@ -88,7 +88,7 @@ static void assert_mode_seems_okay( struct stat st; cl_git_pass(git_str_joinpath(&full, base, path)); - cl_git_pass(git_path_lstat(full.ptr, &st)); + cl_git_pass(git_fs_path_lstat(full.ptr, &st)); git_str_dispose(&full); if (!core_filemode) { diff --git a/tests/reset/hard.c b/tests/reset/hard.c index 36e8f1470..9d177c021 100644 --- a/tests/reset/hard.c +++ b/tests/reset/hard.c @@ -79,7 +79,7 @@ void test_reset_hard__resetting_reverts_modified_files(void) cl_git_pass(git_futils_readbuffer(&content, path.ptr)); cl_assert(strequal_ignore_eol(after[i], content.ptr)); } else { - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); } } @@ -154,7 +154,7 @@ void test_reset_hard__resetting_reverts_unmerged(void) cl_git_pass(git_revparse_single(&target, repo, "26a125e")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - cl_assert(git_path_exists("status/conflicting_file") == 0); + cl_assert(git_fs_path_exists("status/conflicting_file") == 0); git_object_free(target); target = NULL; @@ -185,11 +185,11 @@ void test_reset_hard__cleans_up_merge(void) cl_git_pass(git_revparse_single(&target, repo, "0017bd4")); cl_git_pass(git_reset(repo, target, GIT_RESET_HARD, NULL)); - cl_assert(!git_path_exists(git_str_cstr(&merge_head_path))); - cl_assert(!git_path_exists(git_str_cstr(&merge_msg_path))); - cl_assert(!git_path_exists(git_str_cstr(&merge_mode_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_head_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_msg_path))); + cl_assert(!git_fs_path_exists(git_str_cstr(&merge_mode_path))); - cl_assert(git_path_exists(git_str_cstr(&orig_head_path))); + cl_assert(git_fs_path_exists(git_str_cstr(&orig_head_path))); cl_git_pass(p_unlink(git_str_cstr(&orig_head_path))); git_str_dispose(&merge_head_path); diff --git a/tests/revert/workdir.c b/tests/revert/workdir.c index 36824044b..0c9810814 100644 --- a/tests/revert/workdir.c +++ b/tests/revert/workdir.c @@ -111,7 +111,7 @@ void test_revert_workdir__conflicts(void) "File one\n" \ ">>>>>>> parent of 72333f4... automergeable changes\n") == 0); - cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); cl_git_pass(git_futils_readbuffer(&mergemsg_buf, TEST_REPO_PATH "/.git/MERGE_MSG")); cl_assert(strcmp(mergemsg_buf.ptr, @@ -498,8 +498,8 @@ void test_revert_workdir__nonmerge_fails_mainline_specified(void) opts.mainline = 1; cl_must_fail(git_revert(repo, commit, &opts)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); git_reference_free(head); git_commit_free(commit); @@ -517,8 +517,8 @@ void test_revert_workdir__merge_fails_without_mainline_specified(void) cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL)); cl_must_fail(git_revert(repo, head, NULL)); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); - cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG")); + cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/REVERT_HEAD")); git_commit_free(head); } diff --git a/tests/stash/drop.c b/tests/stash/drop.c index 6b0895ba8..709ff0f9e 100644 --- a/tests/stash/drop.c +++ b/tests/stash/drop.c @@ -37,26 +37,26 @@ static void push_three_states(void) cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_add_bypath(index, "zero.txt")); cl_repo_commit_from_index(NULL, repo, signature, 0, "Initial commit"); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); git_index_free(index); cl_git_mkfile("stash/one.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "First", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/one.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/one.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); cl_git_mkfile("stash/two.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "Second", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/two.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/two.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); cl_git_mkfile("stash/three.txt", "content\n"); cl_git_pass(git_stash_save( &oid, repo, signature, "Third", GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/three.txt")); - cl_assert(git_path_exists("stash/zero.txt")); + cl_assert(!git_fs_path_exists("stash/three.txt")); + cl_assert(git_fs_path_exists("stash/zero.txt")); } void test_stash_drop__cannot_drop_a_non_existing_stashed_state(void) diff --git a/tests/stash/save.c b/tests/stash/save.c index 1fbcf0957..f574211d7 100644 --- a/tests/stash/save.c +++ b/tests/stash/save.c @@ -161,16 +161,16 @@ void test_stash_save__untracked_skips_ignored(void) cl_must_pass(p_mkdir("stash/bundle/vendor", 0777)); cl_git_mkfile("stash/bundle/vendor/blah", "contents\n"); - cl_assert(git_path_exists("stash/when")); /* untracked */ - cl_assert(git_path_exists("stash/just.ignore")); /* ignored */ - cl_assert(git_path_exists("stash/bundle/vendor/blah")); /* ignored */ + cl_assert(git_fs_path_exists("stash/when")); /* untracked */ + cl_assert(git_fs_path_exists("stash/just.ignore")); /* ignored */ + cl_assert(git_fs_path_exists("stash/bundle/vendor/blah")); /* ignored */ cl_git_pass(git_stash_save( &stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED)); - cl_assert(!git_path_exists("stash/when")); - cl_assert(git_path_exists("stash/bundle/vendor/blah")); - cl_assert(git_path_exists("stash/just.ignore")); + cl_assert(!git_fs_path_exists("stash/when")); + cl_assert(git_fs_path_exists("stash/bundle/vendor/blah")); + cl_assert(git_fs_path_exists("stash/just.ignore")); } void test_stash_save__can_include_untracked_and_ignored_files(void) @@ -185,7 +185,7 @@ void test_stash_save__can_include_untracked_and_ignored_files(void) assert_blob_oid("refs/stash^3:when", "b6ed15e81e2593d7bb6265eb4a991d29dc3e628b"); assert_blob_oid("refs/stash^3:just.ignore", "78925fb1236b98b37a35e9723033e627f97aa88b"); - cl_assert(!git_path_exists("stash/just.ignore")); + cl_assert(!git_fs_path_exists("stash/just.ignore")); } /* @@ -450,9 +450,9 @@ void test_stash_save__ignored_directory(void) cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_INCLUDE_UNTRACKED | GIT_STASH_INCLUDE_IGNORED)); - cl_assert(!git_path_exists("stash/ignored_directory/sub/some_file")); - cl_assert(!git_path_exists("stash/ignored_directory/sub")); - cl_assert(!git_path_exists("stash/ignored_directory")); + cl_assert(!git_fs_path_exists("stash/ignored_directory/sub/some_file")); + cl_assert(!git_fs_path_exists("stash/ignored_directory/sub")); + cl_assert(!git_fs_path_exists("stash/ignored_directory")); } void test_stash_save__skip_submodules(void) diff --git a/tests/status/submodules.c b/tests/status/submodules.c index 38a39471a..d223657b4 100644 --- a/tests/status/submodules.c +++ b/tests/status/submodules.c @@ -36,9 +36,9 @@ void test_status_submodules__0(void) g_repo = setup_fixture_submodules(); - cl_assert(git_path_isdir("submodules/.git")); - cl_assert(git_path_isdir("submodules/testrepo/.git")); - cl_assert(git_path_isfile("submodules/.gitmodules")); + cl_assert(git_fs_path_isdir("submodules/.git")); + cl_assert(git_fs_path_isdir("submodules/testrepo/.git")); + cl_assert(git_fs_path_isfile("submodules/.gitmodules")); cl_git_pass( git_status_foreach(g_repo, cb_status__count, &counts) @@ -89,9 +89,9 @@ void test_status_submodules__1(void) g_repo = setup_fixture_submodules(); - cl_assert(git_path_isdir("submodules/.git")); - cl_assert(git_path_isdir("submodules/testrepo/.git")); - cl_assert(git_path_isfile("submodules/.gitmodules")); + cl_assert(git_fs_path_isdir("submodules/.git")); + cl_assert(git_fs_path_isdir("submodules/testrepo/.git")); + cl_assert(git_fs_path_isfile("submodules/.gitmodules")); status_counts_init(counts, expected_files, expected_status); diff --git a/tests/status/worktree.c b/tests/status/worktree.c index 4ab04094a..692ea93ef 100644 --- a/tests/status/worktree.c +++ b/tests/status/worktree.c @@ -109,7 +109,7 @@ static int remove_file_cb(void *data, git_str *file) if (git__suffixcmp(filename, ".git") == 0) return 0; - if (git_path_isdir(filename)) + if (git_fs_path_isdir(filename)) cl_git_pass(git_futils_rmdir_r(filename, NULL, GIT_RMDIR_REMOVE_FILES)); else cl_git_pass(p_unlink(git_str_cstr(file))); @@ -126,7 +126,7 @@ void test_status_worktree__purged_worktree(void) /* first purge the contents of the worktree */ cl_git_pass(git_str_sets(&workdir, git_repository_workdir(repo))); - cl_git_pass(git_path_direach(&workdir, 0, remove_file_cb, NULL)); + cl_git_pass(git_fs_path_direach(&workdir, 0, remove_file_cb, NULL)); git_str_dispose(&workdir); /* now get status */ @@ -374,7 +374,7 @@ void test_status_worktree__issue_592(void) repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "l.txt")); cl_git_pass(p_unlink(git_str_cstr(&path))); - cl_assert(!git_path_exists("issue_592/l.txt")); + cl_assert(!git_fs_path_exists("issue_592/l.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt")); @@ -389,7 +389,7 @@ void test_status_worktree__issue_592_2(void) repo = cl_git_sandbox_init("issue_592"); cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c/a.txt")); cl_git_pass(p_unlink(git_str_cstr(&path))); - cl_assert(!git_path_exists("issue_592/c/a.txt")); + cl_assert(!git_fs_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); @@ -405,7 +405,7 @@ void test_status_worktree__issue_592_3(void) cl_git_pass(git_str_joinpath(&path, git_repository_workdir(repo), "c")); cl_git_pass(git_futils_rmdir_r(git_str_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES)); - cl_assert(!git_path_exists("issue_592/c/a.txt")); + cl_assert(!git_fs_path_exists("issue_592/c/a.txt")); cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt")); diff --git a/tests/submodule/add.c b/tests/submodule/add.c index b564123dd..ae5507d7f 100644 --- a/tests/submodule/add.c +++ b/tests/submodule/add.c @@ -46,11 +46,11 @@ void test_submodule_add__url_absolute(void) ); git_submodule_free(sm); - cl_assert(git_path_isfile("submod2/" "sm_libgit2" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2" "/.git")); - cl_assert(git_path_isdir("submod2/.git/modules")); - cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2")); - cl_assert(git_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); + cl_assert(git_fs_path_isdir("submod2/.git/modules")); + cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_libgit2")); + cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD")); assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git"); cl_git_pass(git_repository_open(&repo, "submod2/" "sm_libgit2")); @@ -72,9 +72,9 @@ void test_submodule_add__url_absolute(void) ); git_submodule_free(sm); - cl_assert(git_path_isdir("submod2/" "sm_libgit2b" "/.git")); - cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); - cl_assert(!git_path_exists("submod2/.git/modules/" "sm_libgit2b")); + cl_assert(git_fs_path_isdir("submod2/" "sm_libgit2b" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD")); + cl_assert(!git_fs_path_exists("submod2/.git/modules/" "sm_libgit2b")); assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git"); } @@ -227,7 +227,7 @@ void test_submodule_add__submodule_clone_into_nonempty_dir_succeeds(void) cl_git_pass(git_submodule_clone(NULL, sm, NULL)); cl_git_pass(git_submodule_add_finalize(sm)); - cl_assert(git_path_exists("empty_standard_repo/sm/foobar")); + cl_assert(git_fs_path_exists("empty_standard_repo/sm/foobar")); assert_submodule_exists(g_repo, "sm"); diff --git a/tests/submodule/init.c b/tests/submodule/init.c index bf865a9e8..a8e1291c4 100644 --- a/tests/submodule/init.c +++ b/tests/submodule/init.c @@ -20,7 +20,7 @@ void test_submodule_init__absolute_url(void) g_repo = setup_fixture_submodule_simple(); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); /* write the absolute url to the .gitmodules file*/ @@ -53,7 +53,7 @@ void test_submodule_init__relative_url(void) g_repo = setup_fixture_submodule_simple(); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); @@ -91,7 +91,7 @@ void test_submodule_init__relative_url_detached_head(void) cl_git_pass(git_repository_set_head_detached(g_repo, git_commit_id((git_commit *)head_commit))); - cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); + cl_assert(git_fs_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0); cl_git_pass(git_str_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git")); cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo")); diff --git a/tests/submodule/open.c b/tests/submodule/open.c index 4f31feedf..e6883d208 100644 --- a/tests/submodule/open.c +++ b/tests/submodule/open.c @@ -27,9 +27,9 @@ static void assert_sm_valid(git_repository *parent, git_repository *child, const /* assert working directory */ cl_git_pass(git_str_joinpath(&expected, git_repository_workdir(parent), sm_name)); - cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&expected, expected.ptr, NULL)); cl_git_pass(git_str_sets(&actual, git_repository_workdir(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); git_str_clear(&expected); @@ -38,14 +38,14 @@ static void assert_sm_valid(git_repository *parent, git_repository *child, const /* assert common directory */ cl_git_pass(git_str_joinpath(&expected, git_repository_commondir(parent), "modules")); cl_git_pass(git_str_joinpath(&expected, expected.ptr, sm_name)); - cl_git_pass(git_path_prettify_dir(&expected, expected.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&expected, expected.ptr, NULL)); cl_git_pass(git_str_sets(&actual, git_repository_commondir(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); /* assert git directory */ cl_git_pass(git_str_sets(&actual, git_repository_path(child))); - cl_git_pass(git_path_prettify_dir(&actual, actual.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&actual, actual.ptr, NULL)); cl_assert_equal_s(expected.ptr, actual.ptr); git_str_dispose(&expected); diff --git a/tests/submodule/repository_init.c b/tests/submodule/repository_init.c index 3927afc2e..39b55c403 100644 --- a/tests/submodule/repository_init.c +++ b/tests/submodule/repository_init.c @@ -26,11 +26,11 @@ void test_submodule_repository_init__basic(void) cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_gitmodules_only" "/.git")); cl_assert_equal_s("gitdir: ../.git/modules/sm_gitmodules_only/", dot_git_content.ptr); - cl_assert(git_path_isfile("submod2/" "sm_gitmodules_only" "/.git")); + cl_assert(git_fs_path_isfile("submod2/" "sm_gitmodules_only" "/.git")); - cl_assert(git_path_isdir("submod2/.git/modules")); - cl_assert(git_path_isdir("submod2/.git/modules/" "sm_gitmodules_only")); - cl_assert(git_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD")); + cl_assert(git_fs_path_isdir("submod2/.git/modules")); + cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_gitmodules_only")); + cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_gitmodules_only" "/HEAD")); git_submodule_free(sm); git_repository_free(repo); diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c index 95d20a009..b8fc9f60d 100644 --- a/tests/submodule/submodule_helpers.c +++ b/tests/submodule/submodule_helpers.c @@ -65,7 +65,7 @@ void rewrite_gitmodules(const char *workdir) continue; } - git_path_prettify(&path, path.ptr, NULL); + git_fs_path_prettify(&path, path.ptr, NULL); git_str_putc(&path, '\n'); cl_assert(!git_str_oom(&path)); diff --git a/tests/worktree/merge.c b/tests/worktree/merge.c index 8bb95d1f7..5b7e2a837 100644 --- a/tests/worktree/merge.c +++ b/tests/worktree/merge.c @@ -73,7 +73,7 @@ void test_worktree_merge__merge_setup(void) cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, merge_files[i])); - cl_assert(git_path_exists(path.ptr)); + cl_assert(git_fs_path_exists(path.ptr)); } git_str_dispose(&path); diff --git a/tests/worktree/refs.c b/tests/worktree/refs.c index 5ae17ca19..557726aaf 100644 --- a/tests/worktree/refs.c +++ b/tests/worktree/refs.c @@ -181,14 +181,14 @@ void test_worktree_refs__creating_refs_uses_commondir(void) cl_git_pass(git_str_joinpath(&refpath, git_repository_commondir(fixture.worktree), "refs/heads/testbranch")); - cl_assert(!git_path_exists(refpath.ptr)); + cl_assert(!git_fs_path_exists(refpath.ptr)); cl_git_pass(git_repository_head(&head, fixture.worktree)); cl_git_pass(git_commit_lookup(&commit, fixture.worktree, git_reference_target(head))); cl_git_pass(git_branch_create(&branch, fixture.worktree, "testbranch", commit, 0)); cl_git_pass(git_branch_lookup(&lookup, fixture.worktree, "testbranch", GIT_BRANCH_LOCAL)); cl_assert(git_reference_cmp(branch, lookup) == 0); - cl_assert(git_path_exists(refpath.ptr)); + cl_assert(git_fs_path_exists(refpath.ptr)); git_reference_free(lookup); git_reference_free(branch); diff --git a/tests/worktree/submodule.c b/tests/worktree/submodule.c index 4c6c657d3..6b0c07452 100644 --- a/tests/worktree/submodule.c +++ b/tests/worktree/submodule.c @@ -67,7 +67,7 @@ void test_worktree_submodule__resolve_relative_url(void) git_worktree *wt; cl_git_pass(git_futils_mkdir("subdir", 0755, GIT_MKDIR_PATH)); - cl_git_pass(git_path_prettify_dir(&wt_path, "subdir", NULL)); + cl_git_pass(git_fs_path_prettify_dir(&wt_path, "subdir", NULL)); cl_git_pass(git_str_joinpath(&wt_path, wt_path.ptr, "wt")); /* Open child repository, which is a submodule */ diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c index a9a50fbf1..6f14b17f1 100644 --- a/tests/worktree/worktree.c +++ b/tests/worktree/worktree.c @@ -330,7 +330,7 @@ void test_worktree_worktree__init_existing_path(void) for (i = 0; i < ARRAY_SIZE(wtfiles); i++) { cl_git_pass(git_str_joinpath(&path, fixture.worktree->gitdir, wtfiles[i])); - cl_assert(!git_path_exists(path.ptr)); + cl_assert(!git_fs_path_exists(path.ptr)); } git_str_dispose(&path); @@ -351,9 +351,9 @@ void test_worktree_worktree__init_submodule(void) cl_git_pass(git_worktree_add(&worktree, sm, "repo-worktree", path.ptr, NULL)); cl_git_pass(git_repository_open_from_worktree(&wt, worktree)); - cl_git_pass(git_path_prettify_dir(&path, path.ptr, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path, path.ptr, NULL)); cl_assert_equal_s(path.ptr, wt->workdir); - cl_git_pass(git_path_prettify_dir(&path, sm->commondir, NULL)); + cl_git_pass(git_fs_path_prettify_dir(&path, sm->commondir, NULL)); cl_assert_equal_s(sm->commondir, wt->commondir); cl_git_pass(git_str_joinpath(&path, sm->gitdir, "worktrees/repo-worktree/")); @@ -560,8 +560,8 @@ void test_worktree_worktree__prune_gitdir_only(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_prune(wt, &opts)); - cl_assert(!git_path_exists(wt->gitdir_path)); - cl_assert(git_path_exists(wt->gitlink_path)); + cl_assert(!git_fs_path_exists(wt->gitdir_path)); + cl_assert(git_fs_path_exists(wt->gitlink_path)); git_worktree_free(wt); } @@ -576,8 +576,8 @@ void test_worktree_worktree__prune_worktree(void) cl_git_pass(git_worktree_lookup(&wt, fixture.repo, "testrepo-worktree")); cl_git_pass(git_worktree_prune(wt, &opts)); - cl_assert(!git_path_exists(wt->gitdir_path)); - cl_assert(!git_path_exists(wt->gitlink_path)); + cl_assert(!git_fs_path_exists(wt->gitdir_path)); + cl_assert(!git_fs_path_exists(wt->gitlink_path)); git_worktree_free(wt); } -- cgit v1.2.1 From 434a46107bbb1c4d90832c92d4d0f5c89cb82ead Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 09:31:32 -0400 Subject: fs_path: `validate` -> `is_valid` Since we're returning a boolean about validation, the name is more properly "is valid". --- src/fs_path.c | 6 +- src/fs_path.h | 4 +- src/path.c | 2 +- tests/path/core.c | 266 +++++++++++++++++++++++++++--------------------------- 4 files changed, 139 insertions(+), 139 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index e180d5866..ceba02d62 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,7 +1634,7 @@ static bool validate_component( return true; } -bool git_fs_path_validate_ext( +bool git_fs_path_is_valid_ext( const char *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), @@ -1673,9 +1673,9 @@ bool git_fs_path_validate_ext( return true; } -bool git_fs_path_validate(const char *path, unsigned int flags) +bool git_fs_path_is_valid(const char *path, unsigned int flags) { - return git_fs_path_validate_ext(path, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_ext(path, flags, NULL, NULL, NULL); } #ifdef GIT_WIN32 diff --git a/src/fs_path.h b/src/fs_path.h index a60a37d98..991e7cd83 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -627,13 +627,13 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url * (trailing ' ' or ':' characters), or filenames ("component names") * that are not supported ('AUX', 'COM1"). */ -extern bool git_fs_path_validate(const char *path, unsigned int flags); +extern bool git_fs_path_is_valid(const char *path, unsigned int flags); /** * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_validate_ext( +extern bool git_fs_path_is_valid_ext( const char *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), diff --git a/src/path.c b/src/path.c index d34125128..063009fa1 100644 --- a/src/path.c +++ b/src/path.c @@ -301,7 +301,7 @@ bool git_path_validate( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_validate_ext(path, flags, NULL, validate_repo_component, &data); + return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, &data); } static const struct { diff --git a/tests/path/core.c b/tests/path/core.c index 8576b471e..f48a76957 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -59,180 +59,180 @@ void test_path_core__make_relative(void) void test_path_core__isvalid_standard(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo/bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar/file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar/.file", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/.file", 0)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_fs_path_validate("foo//bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); /* leading slash */ - cl_assert_equal_b(false, git_fs_path_validate("/", 0)); - cl_assert_equal_b(false, git_fs_path_validate("/foo", 0)); - cl_assert_equal_b(false, git_fs_path_validate("/foo/bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0)); /* trailing slash */ - cl_assert_equal_b(false, git_fs_path_validate("foo/", 0)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); } void test_path_core__isvalid_dot_and_dotdot(void) { - cl_assert_equal_b(true, git_fs_path_validate(".", 0)); - cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("./foo", 0)); - - cl_assert_equal_b(true, git_fs_path_validate("..", 0)); - cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/..", 0)); - cl_assert_equal_b(true, git_fs_path_validate("../foo", 0)); - - cl_assert_equal_b(false, git_fs_path_validate(".", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - - cl_assert_equal_b(false, git_fs_path_validate("..", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); - cl_assert_equal_b(false, git_fs_path_validate("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(true, git_fs_path_is_valid(".", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("./foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("./foo", 0)); + + cl_assert_equal_b(true, git_fs_path_is_valid("..", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("../foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/..", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("../foo", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid(".", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/.", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("./foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + + cl_assert_equal_b(false, git_fs_path_is_valid("..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/..", GIT_FS_PATH_REJECT_TRAVERSAL)); + cl_assert_equal_b(false, git_fs_path_is_valid("../foo", GIT_FS_PATH_REJECT_TRAVERSAL)); } void test_path_core__isvalid_backslash(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo\\file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\file.txt", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar\\", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar\\file.txt", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar\\", 0)); - cl_assert_equal_b(false, git_fs_path_validate("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar\\file.txt", GIT_FS_PATH_REJECT_BACKSLASH)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar\\", GIT_FS_PATH_REJECT_BACKSLASH)); } void test_path_core__isvalid_trailing_dot(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo...", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo./bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); - cl_assert_equal_b(false, git_fs_path_validate("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo...", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo./bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo...", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar.", GIT_FS_PATH_REJECT_TRAILING_DOT)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo./bar", GIT_FS_PATH_REJECT_TRAILING_DOT)); } void test_path_core__isvalid_trailing_space(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar ", 0)); - cl_assert_equal_b(true, git_fs_path_validate(" ", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo /bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); - cl_assert_equal_b(false, git_fs_path_validate("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid(" ", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo /bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid(" ", GIT_FS_PATH_REJECT_TRAILING_SPACE)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo /bar", GIT_FS_PATH_REJECT_TRAILING_SPACE)); } void test_path_core__isvalid_trailing_colon(void) { - cl_assert_equal_b(true, git_fs_path_validate("foo:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo/bar:", 0)); - cl_assert_equal_b(true, git_fs_path_validate(":", 0)); - cl_assert_equal_b(true, git_fs_path_validate("foo:/bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); - cl_assert_equal_b(false, git_fs_path_validate("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid(":", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo:/bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("foo:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar:", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid(":", GIT_FS_PATH_REJECT_TRAILING_COLON)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo:/bar", GIT_FS_PATH_REJECT_TRAILING_COLON)); } void test_path_core__isvalid_dos_paths(void) { - cl_assert_equal_b(true, git_fs_path_validate("aux", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.asdf", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux.asdf\\zippy", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux:asdf\\foobar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("con", 0)); - cl_assert_equal_b(true, git_fs_path_validate("prn", 0)); - cl_assert_equal_b(true, git_fs_path_validate("nul", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("con", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_fs_path_validate("aux1", 0)); - cl_assert_equal_b(true, git_fs_path_validate("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("con", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("prn", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("nul", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("aux", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("aux:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("con", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("prn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("nul", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_is_valid("aux1", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("auxn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("aux\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_dos_paths_withnum(void) { - cl_assert_equal_b(true, git_fs_path_validate("com1", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1:", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.asdf", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1.asdf\\zippy", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1:asdf\\foobar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("lpt1", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(false, git_fs_path_validate("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); - - cl_assert_equal_b(true, git_fs_path_validate("com0", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("com10", 0)); - cl_assert_equal_b(true, git_fs_path_validate("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); - cl_assert_equal_b(true, git_fs_path_validate("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1:", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.asdf", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1.asdf\\zippy", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1:asdf\\foobar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1\\foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt1", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("com1", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1:", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.asdf", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1.asdf\\zippy", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1:asdf\\foobar", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("com1/foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(false, git_fs_path_is_valid("lpt1", GIT_FS_PATH_REJECT_DOS_PATHS)); + + cl_assert_equal_b(true, git_fs_path_is_valid("com0", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com10", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("com10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("comn", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("com1\\foo", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt0", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lpt10", GIT_FS_PATH_REJECT_DOS_PATHS)); + cl_assert_equal_b(true, git_fs_path_is_valid("lptn", GIT_FS_PATH_REJECT_DOS_PATHS)); } void test_path_core__isvalid_nt_chars(void) { - cl_assert_equal_b(true, git_fs_path_validate("asdf\001foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf\037bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdffoo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf:foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf\"bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf|foo", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf?bar", 0)); - cl_assert_equal_b(true, git_fs_path_validate("asdf*bar", 0)); - - cl_assert_equal_b(false, git_fs_path_validate("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); - cl_assert_equal_b(false, git_fs_path_validate("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\001foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\037bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdffoo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf:foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf\"bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf|foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf?bar", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("asdf*bar", 0)); + + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\001foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\037bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdffoo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf:foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf\"bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf|foo", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf?bar", GIT_FS_PATH_REJECT_NT_CHARS)); + cl_assert_equal_b(false, git_fs_path_is_valid("asdf*bar", GIT_FS_PATH_REJECT_NT_CHARS)); } void test_path_core__validate_workdir(void) -- cgit v1.2.1 From 63e36c53caa8c3f1581471de64bbef3ca87f3921 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 09:34:32 -0400 Subject: path: `validate` -> `is_valid` Since we're returning a boolean about validation, the name is more properly "is valid". --- src/checkout.c | 4 +- src/index.c | 2 +- src/path.c | 2 +- src/path.h | 2 +- src/refdb_fs.c | 4 +- src/submodule.c | 2 +- src/tree.c | 2 +- tests/path/dotgit.c | 136 ++++++++++++++++++++++++++-------------------------- 8 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 96ba4da38..ad4edddd3 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1281,14 +1281,14 @@ static int checkout_verify_paths( unsigned int flags = GIT_PATH_REJECT_WORKDIR_DEFAULTS; if (action & CHECKOUT_ACTION__REMOVE) { - if (!git_path_validate(repo, delta->old_file.path, delta->old_file.mode, flags)) { + if (!git_path_is_valid(repo, delta->old_file.path, delta->old_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot remove invalid path '%s'", delta->old_file.path); return -1; } } if (action & ~CHECKOUT_ACTION__REMOVE) { - if (!git_path_validate(repo, delta->new_file.path, delta->new_file.mode, flags)) { + if (!git_path_is_valid(repo, delta->new_file.path, delta->new_file.mode, flags)) { git_error_set(GIT_ERROR_CHECKOUT, "cannot checkout to invalid path '%s'", delta->new_file.path); return -1; } diff --git a/src/index.c b/src/index.c index 448852f29..bd6ea8f03 100644 --- a/src/index.c +++ b/src/index.c @@ -945,7 +945,7 @@ static int index_entry_create( if (st) mode = st->st_mode; - if (!git_path_validate(repo, path, mode, path_valid_flags)) { + if (!git_path_is_valid(repo, path, mode, path_valid_flags)) { git_error_set(GIT_ERROR_INDEX, "invalid path: '%s'", path); return -1; } diff --git a/src/path.c b/src/path.c index 063009fa1..d54bc5bfe 100644 --- a/src/path.c +++ b/src/path.c @@ -285,7 +285,7 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } -bool git_path_validate( +bool git_path_is_valid( git_repository *repo, const char *path, uint16_t file_mode, diff --git a/src/path.h b/src/path.h index ca220d121..f874a16be 100644 --- a/src/path.h +++ b/src/path.h @@ -25,7 +25,7 @@ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -extern bool git_path_validate( +extern bool git_path_is_valid( git_repository *repo, const char *path, uint16_t file_mode, diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 39dc16e9d..acd627091 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -818,7 +818,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char * GIT_ASSERT_ARG(backend); GIT_ASSERT_ARG(name); - if (!git_path_validate(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_is_valid(backend->repo, name, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", name); return GIT_EINVALIDSPEC; } @@ -1857,7 +1857,7 @@ static int lock_reflog(git_filebuf *file, refdb_fs_backend *backend, const char repo = backend->repo; - if (!git_path_validate(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { + if (!git_path_is_valid(backend->repo, refname, 0, GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS)) { git_error_set(GIT_ERROR_INVALID, "invalid reference name '%s'", refname); return GIT_EINVALIDSPEC; } diff --git a/src/submodule.c b/src/submodule.c index 727b6c6e4..ffe29ccfb 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -423,7 +423,7 @@ int git_submodule_name_is_valid(git_repository *repo, const char *name, int flag git_str_attach_notowned(&buf, name, strlen(name)); } - isvalid = git_path_validate(repo, buf.ptr, 0, flags); + isvalid = git_path_is_valid(repo, buf.ptr, 0, flags); git_str_dispose(&buf); return isvalid; diff --git a/src/tree.c b/src/tree.c index 256e72080..b8e82d485 100644 --- a/src/tree.c +++ b/src/tree.c @@ -55,7 +55,7 @@ GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode) static int valid_entry_name(git_repository *repo, const char *filename) { return *filename != '\0' && - git_path_validate(repo, filename, 0, + git_path_is_valid(repo, filename, 0, GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_FS_PATH_REJECT_SLASH); } diff --git a/tests/path/dotgit.c b/tests/path/dotgit.c index 5b3a31137..9ac68b0ff 100644 --- a/tests/path/dotgit.c +++ b/tests/path/dotgit.c @@ -114,10 +114,10 @@ void test_path_dotgit__dotgit_modules(void) void test_path_dotgit__dotgit_modules_symlink(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gitmodules", 0, GIT_PATH_REJECT_DOT_GIT_HFS|GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gitmodules . .::$DATA", S_IFLNK, GIT_PATH_REJECT_DOT_GIT_NTFS)); } void test_core_path__git_fs_path_is_file(void) @@ -131,76 +131,76 @@ void test_core_path__git_fs_path_is_file(void) void test_path_dotgit__isvalid_dot_git(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git/foo", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.GIT/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/bar/.Git", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - cl_assert_equal_b(false, git_path_validate(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); - - cl_assert_equal_b(true, git_path_validate(NULL, "!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/!git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "!git/bar", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "foo/.tig", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".tig/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git/foo", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.GIT/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/bar/.Git", 0, 0)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, "!git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/!git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "!git/bar", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "foo/.tig", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".tig/bar", 0, 0)); } void test_path_dotgit__isvalid_dotgit_ntfs(void) { - cl_assert_equal_b(true, git_path_validate(NULL, ".git", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git.. .", 0, 0)); - - cl_assert_equal_b(true, git_path_validate(NULL, "git~1", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1 ", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.", 0, 0)); - cl_assert_equal_b(true, git_path_validate(NULL, "git~1.. .", 0, 0)); - - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - - cl_assert_equal_b(false, git_path_validate(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git ", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git.. .", 0, 0)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1 ", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.", 0, 0)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "git~1.. .", 0, 0)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS)); } void test_path_dotgit__isvalid_dotgit_with_hfs_ignorables(void) { - cl_assert_equal_b(false, git_path_validate(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(false, git_path_validate(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(false, git_path_validate(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_validate(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_validate(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - - cl_assert_equal_b(true, git_path_validate(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); - cl_assert_equal_b(true, git_path_validate(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(false, git_path_is_valid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(false, git_path_is_valid(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_is_valid(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_is_valid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + + cl_assert_equal_b(true, git_path_is_valid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); + cl_assert_equal_b(true, git_path_is_valid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS)); } -- cgit v1.2.1 From bef02d3e638ce8c95c9e63622b46d87a0f8ee2b2 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 10:57:28 -0400 Subject: fs_path: introduce `str_is_valid` Provide a mechanism for users to limit the number of characters that are examined; `git_fs_path_str_is_valid` and friends will only examine up to `str->size` bytes. `git_fs_path_is_valid` delegates to these new functions by passing `SIZE_MAX` (instead of doing a `strlen`), which is a sentinel value meaning "look for a NUL terminator". --- src/fs_path.c | 21 +++++++++++++-------- src/fs_path.h | 52 +++++++++++++++++++++++++++++++++++++++++----------- tests/path/core.c | 27 +++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index ceba02d62..fa27a6e73 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,16 +1634,17 @@ static bool validate_component( return true; } -bool git_fs_path_is_valid_ext( - const char *path, +bool git_fs_path_is_valid_str_ext( + const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), void *payload) { const char *start, *c; + size_t len = 0; - for (start = c = path; *c; c++) { + for (start = c = path->ptr; *c && len < path->size; c++, len++) { if (!validate_char(*c, flags)) return false; @@ -1663,6 +1664,15 @@ bool git_fs_path_is_valid_ext( start = c + 1; } + /* + * We want to support paths specified as either `const char *` + * or `git_str *`; we pass size as `SIZE_MAX` when we use a + * `const char *` to avoid a `strlen`. Ensure that we didn't + * have a NUL in the buffer if there was a non-SIZE_MAX length. + */ + if (path->size != SIZE_MAX && len != path->size) + return false; + if (!validate_component(start, (c - start), flags)) return false; @@ -1673,11 +1683,6 @@ bool git_fs_path_is_valid_ext( return true; } -bool git_fs_path_is_valid(const char *path, unsigned int flags) -{ - return git_fs_path_is_valid_ext(path, flags, NULL, NULL, NULL); -} - #ifdef GIT_WIN32 GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) { diff --git a/src/fs_path.h b/src/fs_path.h index 991e7cd83..2f4bc9f79 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -620,26 +620,56 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url GIT_FS_PATH_REJECT_TRAVERSAL #endif -/** - * Validate a filesystem path. This ensures that the given path is legal - * and does not contain any "unsafe" components like path traversal ('.' - * or '..'), characters that are inappropriate for lesser filesystems - * (trailing ' ' or ':' characters), or filenames ("component names") - * that are not supported ('AUX', 'COM1"). - */ -extern bool git_fs_path_is_valid(const char *path, unsigned int flags); - /** * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_is_valid_ext( - const char *path, +extern bool git_fs_path_is_valid_str_ext( + const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), void *payload); +GIT_INLINE(bool) git_fs_path_is_valid_ext( + const char *path, + unsigned int flags, + bool (*validate_char_cb)(char ch, void *payload), + bool (*validate_component_cb)(const char *component, size_t len, void *payload), + void *payload) +{ + const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_fs_path_is_valid_str_ext( + &str, + flags, + validate_char_cb, + validate_component_cb, + payload); +} + +/** + * Validate a filesystem path. This ensures that the given path is legal + * and does not contain any "unsafe" components like path traversal ('.' + * or '..'), characters that are inappropriate for lesser filesystems + * (trailing ' ' or ':' characters), or filenames ("component names") + * that are not supported ('AUX', 'COM1"). + */ +GIT_INLINE(bool) git_fs_path_is_valid( + const char *path, + unsigned int flags) +{ + const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL); +} + +/** Validate a filesystem path in a `git_str`. */ +GIT_INLINE(bool) git_fs_path_is_valid_str( + const git_str *path, + unsigned int flags) +{ + return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL); +} + /** * Validate an on-disk path, taking into account that it will have a * suffix appended (eg, `.lock`). diff --git a/tests/path/core.c b/tests/path/core.c index f48a76957..6fa0450ca 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -64,6 +64,33 @@ void test_path_core__isvalid_standard(void) cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/.file", 0)); } +/* Ensure that `is_valid_str` only reads str->size bytes */ +void test_path_core__isvalid_standard_str(void) +{ + git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); + + str.size = 0; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = 3; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 4; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = 5; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 7; + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + + str.size = 8; + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + + str.size = strlen(str.ptr); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); +} + void test_path_core__isvalid_empty_dir_component(void) { cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); -- cgit v1.2.1 From dd748dbede1a36f1e929461ecbfcde749eb685bb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 13:04:40 -0400 Subject: fs_path: make empty component validation optional --- src/fs_path.c | 5 ++++- src/fs_path.h | 5 ++++- tests/path/core.c | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index fa27a6e73..483b21c1e 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1599,7 +1599,7 @@ static bool validate_component( unsigned int flags) { if (len == 0) - return false; + return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT); if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && len == 1 && component[0] == '.') @@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext( const char *start, *c; size_t len = 0; + if (!flags) + return true; + for (start = c = path->ptr; *c && len < path->size; c++, len++) { if (!validate_char(*c, flags)) return false; diff --git a/src/fs_path.h b/src/fs_path.h index 2f4bc9f79..275b3d857 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -591,7 +591,8 @@ extern bool git_fs_path_is_local_file_url(const char *file_url); extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); /* Flags to determine path validity in `git_fs_path_isvalid` */ -#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0) +#define GIT_FS_PATH_REJECT_EMPTY_COMPONENT (1 << 0) +#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 1) #define GIT_FS_PATH_REJECT_SLASH (1 << 2) #define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) #define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) @@ -608,6 +609,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url */ #ifdef GIT_WIN32 # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL | \ GIT_FS_PATH_REJECT_BACKSLASH | \ GIT_FS_PATH_REJECT_TRAILING_DOT | \ @@ -617,6 +619,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url GIT_FS_PATH_REJECT_NT_CHARS #else # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL #endif diff --git a/tests/path/core.c b/tests/path/core.c index 6fa0450ca..ccb328b10 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void) void test_path_core__isvalid_standard_str(void) { git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; str.size = 0; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 3; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 4; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 5; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 7; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 8; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = strlen(str.ptr); - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; + + /* empty component */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo//bar", 0)); + + /* leading slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo/bar", 0)); + + /* trailing slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/", 0)); + + + /* empty component */ + cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", flags)); /* leading slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", flags)); /* trailing slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", flags)); } void test_path_core__isvalid_dot_and_dotdot(void) -- cgit v1.2.1 From ebacd24c6039c992ef9122a0d6f7de0ca4ba3bd1 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 13:58:18 -0400 Subject: fs_path: add long path validation on windows --- src/fs_path.c | 29 +++++++++++++++++++++++++++++ src/fs_path.h | 10 +++++++--- src/path.c | 2 +- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 483b21c1e..de3b03957 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1634,11 +1634,25 @@ static bool validate_component( return true; } +#ifdef GIT_WIN32 +GIT_INLINE(bool) validate_length( + const char *path, + size_t len, + size_t utf8_char_len) +{ + GIT_UNUSED(path); + GIT_UNUSED(len); + + return (utf8_char_len <= MAX_PATH); +} +#endif + bool git_fs_path_is_valid_str_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *path, size_t len, size_t utf8_char_len), void *payload) { const char *start, *c; @@ -1683,6 +1697,21 @@ bool git_fs_path_is_valid_str_ext( !validate_component_cb(start, (c - start), payload)) return false; +#ifdef GIT_WIN32 + if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS) != 0) { + size_t utf8_len = git_utf8_char_length(path->ptr, len); + + if (!validate_length(path->ptr, len, utf8_len)) + return false; + + if (validate_length_cb && + !validate_length_cb(path->ptr, len, utf8_len)) + return false; + } +#else + GIT_UNUSED(validate_length_cb); +#endif + return true; } diff --git a/src/fs_path.h b/src/fs_path.h index 275b3d857..40b4342f1 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -600,8 +600,9 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url #define GIT_FS_PATH_REJECT_TRAILING_COLON (1 << 6) #define GIT_FS_PATH_REJECT_DOS_PATHS (1 << 7) #define GIT_FS_PATH_REJECT_NT_CHARS (1 << 8) +#define GIT_FS_PATH_REJECT_LONG_PATHS (1 << 9) -#define GIT_FS_PATH_REJECT_MAX (1 << 8) +#define GIT_FS_PATH_REJECT_MAX (1 << 9) /* Default path safety for writing files to disk: since we use the * Win32 "File Namespace" APIs ("\\?\") we need to protect from @@ -632,6 +633,7 @@ extern bool git_fs_path_is_valid_str_ext( unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len), void *payload); GIT_INLINE(bool) git_fs_path_is_valid_ext( @@ -639,6 +641,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), bool (*validate_component_cb)(const char *component, size_t len, void *payload), + bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len), void *payload) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); @@ -647,6 +650,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( flags, validate_char_cb, validate_component_cb, + validate_length_cb, payload); } @@ -662,7 +666,7 @@ GIT_INLINE(bool) git_fs_path_is_valid( unsigned int flags) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL, NULL); } /** Validate a filesystem path in a `git_str`. */ @@ -670,7 +674,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_str( const git_str *path, unsigned int flags) { - return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL); + return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL, NULL); } /** diff --git a/src/path.c b/src/path.c index d54bc5bfe..a6b396f6d 100644 --- a/src/path.c +++ b/src/path.c @@ -301,7 +301,7 @@ bool git_path_is_valid( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, &data); + return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); } static const struct { -- cgit v1.2.1 From 315a43b2f16fab679126f519a5dce1c9e1e335af Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 17:37:06 -0400 Subject: path: introduce `git_path_str_is_valid` Add a `git_str` based validity check; the existing `git_path_is_valid` defers to it. --- src/fs_path.c | 2 +- src/fs_path.h | 10 +++++----- src/path.c | 6 +++--- src/path.h | 14 ++++++++++++-- tests/path/core.c | 14 +++++++------- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index de3b03957..9079c30c9 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1647,7 +1647,7 @@ GIT_INLINE(bool) validate_length( } #endif -bool git_fs_path_is_valid_str_ext( +bool git_fs_path_str_is_valid_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), diff --git a/src/fs_path.h b/src/fs_path.h index 40b4342f1..947c4ae86 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -628,7 +628,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url * Validate a filesystem path; with custom callbacks per-character and * per-path component. */ -extern bool git_fs_path_is_valid_str_ext( +extern bool git_fs_path_str_is_valid_ext( const git_str *path, unsigned int flags, bool (*validate_char_cb)(char ch, void *payload), @@ -645,7 +645,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext( void *payload) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext( + return git_fs_path_str_is_valid_ext( &str, flags, validate_char_cb, @@ -666,15 +666,15 @@ GIT_INLINE(bool) git_fs_path_is_valid( unsigned int flags) { const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); - return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL, NULL); + return git_fs_path_str_is_valid_ext(&str, flags, NULL, NULL, NULL, NULL); } /** Validate a filesystem path in a `git_str`. */ -GIT_INLINE(bool) git_fs_path_is_valid_str( +GIT_INLINE(bool) git_fs_path_str_is_valid( const git_str *path, unsigned int flags) { - return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL, NULL); + return git_fs_path_str_is_valid_ext(path, flags, NULL, NULL, NULL, NULL); } /** diff --git a/src/path.c b/src/path.c index a6b396f6d..933444de2 100644 --- a/src/path.c +++ b/src/path.c @@ -285,9 +285,9 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } -bool git_path_is_valid( +bool git_path_str_is_valid( git_repository *repo, - const char *path, + const git_str *path, uint16_t file_mode, unsigned int flags) { @@ -301,7 +301,7 @@ bool git_path_is_valid( data.file_mode = file_mode; data.flags = flags; - return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); + return git_fs_path_str_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data); } static const struct { diff --git a/src/path.h b/src/path.h index f874a16be..f2ac8484b 100644 --- a/src/path.h +++ b/src/path.h @@ -25,10 +25,20 @@ #define GIT_PATH_REJECT_INDEX_DEFAULTS \ GIT_FS_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT -extern bool git_path_is_valid( +extern bool git_path_str_is_valid( git_repository *repo, - const char *path, + const git_str *path, uint16_t file_mode, unsigned int flags); +GIT_INLINE(bool) git_path_is_valid( + git_repository *repo, + const char *path, + uint16_t file_mode, + unsigned int flags) +{ + git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_path_str_is_valid(repo, &str, file_mode, flags); +} + #endif diff --git a/tests/path/core.c b/tests/path/core.c index ccb328b10..eb6e5b851 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -71,25 +71,25 @@ void test_path_core__isvalid_standard_str(void) unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; str.size = 0; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = 3; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 4; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = 5; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 7; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(true, git_fs_path_str_is_valid(&str, flags)); str.size = 8; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); str.size = strlen(str.ptr); - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); + cl_assert_equal_b(false, git_fs_path_str_is_valid(&str, flags)); } void test_path_core__isvalid_empty_dir_component(void) -- cgit v1.2.1 From 1728e27c96a2e14328423554d3559166ebd1bab7 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 18:19:56 -0400 Subject: path: length validation respecting core.longpaths Teach `git_path_is_valid` to respect `core.longpaths`. Add helper methods to validate length and set the error message appropriately. --- src/path.c | 26 ++++++++++++++++++++++++++ src/path.h | 24 ++++++++++++++++++++++++ tests/path/core.c | 37 +++++++++++++++++++------------------ 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/path.c b/src/path.c index 933444de2..05a3dc2cf 100644 --- a/src/path.c +++ b/src/path.c @@ -285,6 +285,28 @@ GIT_INLINE(unsigned int) dotgit_flags( return flags; } +GIT_INLINE(unsigned int) length_flags( + git_repository *repo, + unsigned int flags) +{ +#ifdef GIT_WIN32 + int allow = 0; + + if (repo && + git_repository__configmap_lookup(&allow, repo, GIT_CONFIGMAP_LONGPATHS) < 0) + allow = 0; + + if (allow) + flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS; + +#else + GIT_UNUSED(repo); + flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS; +#endif + + return flags; +} + bool git_path_str_is_valid( git_repository *repo, const git_str *path, @@ -297,6 +319,10 @@ bool git_path_str_is_valid( if ((flags & GIT_PATH_REJECT_DOT_GIT)) flags = dotgit_flags(repo, flags); + /* Update the length checks based on platform */ + if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS)) + flags = length_flags(repo, flags); + data.repo = repo; data.file_mode = file_mode; data.flags = flags; diff --git a/src/path.h b/src/path.h index f2ac8484b..c4a2c4250 100644 --- a/src/path.h +++ b/src/path.h @@ -41,4 +41,28 @@ GIT_INLINE(bool) git_path_is_valid( return git_path_str_is_valid(repo, &str, file_mode, flags); } +GIT_INLINE(int) git_path_validate_str_length( + git_repository *repo, + const git_str *path) +{ + if (!git_path_str_is_valid(repo, path, 0, GIT_FS_PATH_REJECT_LONG_PATHS)) { + if (path->size == SIZE_MAX) + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%s'", path->ptr); + else + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'", (int)path->size, path->ptr); + + return -1; + } + + return 0; +} + +GIT_INLINE(int) git_path_validate_length( + git_repository *repo, + const char *path) +{ + git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX); + return git_path_validate_str_length(repo, &str); +} + #endif diff --git a/tests/path/core.c b/tests/path/core.c index eb6e5b851..9421941c0 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "fs_path.h" +#include "path.h" void test_path_core__cleanup(void) { @@ -281,30 +282,30 @@ void test_path_core__isvalid_nt_chars(void) void test_path_core__validate_workdir(void) { - cl_must_pass(git_fs_path_validate_workdir(NULL, "/foo/bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\C:\\Foo\\Bar")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "\\\\?\\UNC\\server\\C$\\folder")); + cl_must_pass(git_path_validate_length(NULL, "/foo/bar")); + cl_must_pass(git_path_validate_length(NULL, "C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\C:\\Foo\\Bar")); + cl_must_pass(git_path_validate_length(NULL, "\\\\?\\UNC\\server\\C$\\folder")); #ifdef GIT_WIN32 /* * In the absense of a repo configuration, 259 character paths * succeed. >= 260 character paths fail. */ - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); - cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\longer_than_260.txt")); /* count characters, not bytes */ - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_fail(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_fail(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #else - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); - cl_must_pass(git_fs_path_validate_workdir(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/ok.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/260.txt")); + cl_must_pass(git_path_validate_length(NULL, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\260.txt")); + cl_must_pass(git_path_validate_length(NULL, "C:\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\aaaaaaaaa\\\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\xc2\xa2\\long.txt")); #endif } @@ -320,15 +321,15 @@ void test_path_core__validate_workdir_with_core_longpath(void) cl_git_pass(git_repository_config(&config, repo)); /* fail by default */ - cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly on */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 1)); - cl_must_pass(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_pass(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); /* set core.longpaths explicitly off */ cl_git_pass(git_config_set_bool(config, "core.longpaths", 0)); - cl_must_fail(git_fs_path_validate_workdir(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); + cl_must_fail(git_path_validate_length(repo, "/c/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/aaaaaaaaa/longer_than_260.txt")); git_config_free(config); git_repository_free(repo); -- cgit v1.2.1 From 91246ee5e0d8be8a15a669844f0893cd0f01c604 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 20:14:34 -0400 Subject: path: use new length validation functions --- src/attrcache.c | 9 +++++++-- src/checkout.c | 6 +++--- src/filter.c | 3 ++- src/ignore.c | 5 +++-- src/iterator.c | 17 ++++++++++++----- src/mailmap.c | 3 ++- src/refdb_fs.c | 2 +- src/repository.c | 6 +++--- src/submodule.c | 2 +- src/worktree.c | 3 ++- 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/attrcache.c b/src/attrcache.c index 15c7fab48..b16d95c3c 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -12,6 +12,7 @@ #include "config.h" #include "sysdir.h" #include "ignore.h" +#include "path.h" GIT_INLINE(int) attr_cache_lock(git_attr_cache *cache) { @@ -43,6 +44,7 @@ int git_attr_cache__alloc_file_entry( const char *path, git_pool *pool) { + git_str fullpath_str = GIT_STR_INIT; size_t baselen = 0, pathlen = strlen(path); size_t cachesize = sizeof(git_attr_file_entry) + pathlen + 1; git_attr_file_entry *ce; @@ -66,7 +68,10 @@ int git_attr_cache__alloc_file_entry( } memcpy(&ce->fullpath[baselen], path, pathlen); - if (git_fs_path_validate_workdir_with_len(repo, ce->fullpath, pathlen + baselen) < 0) + fullpath_str.ptr = ce->fullpath; + fullpath_str.size = pathlen + baselen; + + if (git_path_validate_str_length(repo, &fullpath_str) < 0) return -1; ce->path = &ce->fullpath[baselen]; @@ -173,7 +178,7 @@ static int attr_cache_lookup( git_str *p = attr_session ? &attr_session->tmp : &path; if (git_str_joinpath(p, source->base, source->filename) < 0 || - git_fs_path_validate_workdir_buf(repo, p) < 0) + git_path_validate_str_length(repo, p) < 0) return -1; filename = p->ptr; diff --git a/src/checkout.c b/src/checkout.c index ad4edddd3..5733f4ab5 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -329,7 +329,7 @@ static int checkout_target_fullpath( if (path && git_str_puts(&data->target_path, path) < 0) return -1; - if (git_fs_path_validate_workdir_buf(data->repo, &data->target_path) < 0) + if (git_path_validate_str_length(data->repo, &data->target_path) < 0) return -1; *out = &data->target_path; @@ -2035,7 +2035,7 @@ static int checkout_merge_path( int error = 0; if ((error = git_str_joinpath(out, data->opts.target_directory, result->path)) < 0 || - (error = git_fs_path_validate_workdir_buf(data->repo, out)) < 0) + (error = git_path_validate_str_length(data->repo, out)) < 0) return error; /* Most conflicts simply use the filename in the index */ @@ -2338,7 +2338,7 @@ static int validate_target_directory(checkout_data *data) { int error; - if ((error = git_fs_path_validate_workdir(data->repo, data->opts.target_directory)) < 0) + if ((error = git_path_validate_length(data->repo, data->opts.target_directory)) < 0) return error; if (git_fs_path_isdir(data->opts.target_directory)) diff --git a/src/filter.c b/src/filter.c index 950296033..2712e8c60 100644 --- a/src/filter.c +++ b/src/filter.c @@ -18,6 +18,7 @@ #include "blob.h" #include "attr_file.h" #include "array.h" +#include "path.h" struct git_filter_source { git_repository *repo; @@ -1095,7 +1096,7 @@ int git_filter_list_stream_file( if ((error = stream_list_init( &stream_start, &filter_streams, filters, target)) < 0 || (error = git_fs_path_join_unrooted(&abspath, path, base, NULL)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &abspath)) < 0) + (error = git_path_validate_str_length(repo, &abspath)) < 0) goto done; initialized = 1; diff --git a/src/ignore.c b/src/ignore.c index e7d8b799f..cee58d7f1 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -13,6 +13,7 @@ #include "fs_path.h" #include "config.h" #include "wildmatch.h" +#include "path.h" #define GIT_IGNORE_INTERNAL "[internal]exclude" @@ -320,14 +321,14 @@ int git_ignore__for_path( (error = git_fs_path_resolve_relative(&local, 0)) < 0 || (error = git_fs_path_to_dir(&local)) < 0 || (error = git_str_joinpath(&ignores->dir, workdir, local.ptr)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &ignores->dir)) < 0) { + (error = git_path_validate_str_length(repo, &ignores->dir)) < 0) { /* Nothing, we just want to stop on the first error */ } git_str_dispose(&local); } else { if (!(error = git_str_joinpath(&ignores->dir, path, ""))) - error = git_fs_path_validate_filesystem(ignores->dir.ptr, ignores->dir.size); + error = git_path_validate_str_length(NULL, &ignores->dir); } if (error < 0) diff --git a/src/iterator.c b/src/iterator.c index a627e0f88..a4337bb9a 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -9,6 +9,7 @@ #include "tree.h" #include "index.h" +#include "path.h" #define GIT_ITERATOR_FIRST_ACCESS (1 << 15) #define GIT_ITERATOR_HONOR_IGNORES (1 << 16) @@ -1279,7 +1280,7 @@ static int filesystem_iterator_entry_hash( iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL); if (!(error = git_str_joinpath(&fullpath, iter->root, entry->path)) && - !(error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath))) + !(error = git_path_validate_str_length(iter->base.repo, &fullpath))) error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB); git_str_dispose(&fullpath); @@ -1361,7 +1362,7 @@ static int filesystem_iterator_frame_push( git_str_puts(&root, iter->root); if (git_str_oom(&root) || - git_fs_path_validate_workdir_buf(iter->base.repo, &root) < 0) { + git_path_validate_str_length(iter->base.repo, &root) < 0) { error = -1; goto done; } @@ -1389,10 +1390,16 @@ static int filesystem_iterator_frame_push( while ((error = git_fs_path_diriter_next(&diriter)) == 0) { iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL; + git_str path_str = GIT_STR_INIT; bool dir_expected = false; - if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 || - (error = git_fs_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0) + if ((error = git_fs_path_diriter_fullpath(&path, &path_len, &diriter)) < 0) + goto done; + + path_str.ptr = (char *)path; + path_str.size = path_len; + + if ((error = git_path_validate_str_length(iter->base.repo, &path_str)) < 0) goto done; GIT_ASSERT(path_len > iter->root_len); @@ -1565,7 +1572,7 @@ static int filesystem_iterator_is_dir( } if ((error = git_str_joinpath(&fullpath, iter->root, entry->path)) < 0 || - (error = git_fs_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 || + (error = git_path_validate_str_length(iter->base.repo, &fullpath)) < 0 || (error = p_stat(fullpath.ptr, &st)) < 0) goto done; diff --git a/src/mailmap.c b/src/mailmap.c index 4fbb1ae77..4336fe3e5 100644 --- a/src/mailmap.c +++ b/src/mailmap.c @@ -16,6 +16,7 @@ #include "git2/revparse.h" #include "blob.h" #include "parse.h" +#include "path.h" #define MM_FILE ".mailmap" #define MM_FILE_CONFIG "mailmap.file" @@ -331,7 +332,7 @@ static int mailmap_add_file_ondisk( if (error < 0) goto cleanup; - error = git_fs_path_validate_workdir_buf(repo, &fullpath); + error = git_path_validate_str_length(repo, &fullpath); if (error < 0) goto cleanup; diff --git a/src/refdb_fs.c b/src/refdb_fs.c index acd627091..dc291d0f5 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1362,7 +1362,7 @@ static int refdb_fs_backend__prune_refs( git_str_cstr(&relative_path)); if (!error) - error = git_fs_path_validate_filesystem(base_path.ptr, base_path.size); + error = git_path_validate_str_length(NULL, &base_path); if (error < 0) goto cleanup; diff --git a/src/repository.c b/src/repository.c index 2f7ae9b3d..f564453db 100644 --- a/src/repository.c +++ b/src/repository.c @@ -32,7 +32,7 @@ #include "annotated_commit.h" #include "submodule.h" #include "worktree.h" - +#include "path.h" #include "strmap.h" #ifdef GIT_WIN32 @@ -2662,7 +2662,7 @@ int git_repository_workdir_path( } if (!(error = git_str_joinpath(out, repo->workdir, path))) - error = git_fs_path_validate_workdir_buf(repo, out); + error = git_path_validate_str_length(repo, out); return error; } @@ -2858,7 +2858,7 @@ int git_repository_hashfile( GIT_ASSERT_ARG(repo); if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 || - (error = git_fs_path_validate_workdir_buf(repo, &full_path)) < 0) + (error = git_path_validate_str_length(repo, &full_path)) < 0) return error; /* diff --git a/src/submodule.c b/src/submodule.c index ffe29ccfb..0370ac82b 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -386,7 +386,7 @@ int git_submodule__lookup_with_cache( if (git_str_join3(&path, '/', git_repository_workdir(repo), name, DOT_GIT) < 0 || - git_fs_path_validate_workdir_buf(NULL, &path) < 0) + git_path_validate_str_length(NULL, &path) < 0) return -1; if (git_fs_path_exists(path.ptr)) diff --git a/src/worktree.c b/src/worktree.c index f0fc6d752..e08d6d401 100644 --- a/src/worktree.c +++ b/src/worktree.c @@ -9,6 +9,7 @@ #include "buf.h" #include "repository.h" +#include "path.h" #include "git2/branch.h" #include "git2/commit.h" @@ -136,7 +137,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char goto out; } - if ((error = git_fs_path_validate_workdir(NULL, dir)) < 0) + if ((error = git_path_validate_length(NULL, dir)) < 0) goto out; if ((wt = git__calloc(1, sizeof(*wt))) == NULL) { -- cgit v1.2.1 From 622514095fd1d731d35b0d69608911445ba3b0c4 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 21:09:17 -0400 Subject: fs_path: add length with suffix validation --- src/fs_path.c | 23 +++++++++++++++++++++++ src/fs_path.h | 4 ++++ src/refdb_fs.c | 2 +- src/repository.c | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 9079c30c9..56980148e 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1715,6 +1715,29 @@ bool git_fs_path_str_is_valid_ext( return true; } +int git_fs_path_validate_str_length_with_suffix( + git_str *path, + size_t suffix_len) +{ +#ifdef GIT_WIN32 + size_t utf8_len = git_utf8_char_length(path->ptr, path->size); + size_t total_len; + + if (GIT_ADD_SIZET_OVERFLOW(&total_len, utf8_len, suffix_len) || + total_len > MAX_PATH) { + + git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'", + (int)path->size, path->ptr); + return -1; + } +#else + GIT_UNUSED(path); + GIT_UNUSED(suffix_len); +#endif + + return 0; +} + #ifdef GIT_WIN32 GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) { diff --git a/src/fs_path.h b/src/fs_path.h index 947c4ae86..116e8f912 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -677,6 +677,10 @@ GIT_INLINE(bool) git_fs_path_str_is_valid( return git_fs_path_str_is_valid_ext(path, flags, NULL, NULL, NULL, NULL); } +extern int git_fs_path_validate_str_length_with_suffix( + git_str *path, + size_t suffix_len); + /** * Validate an on-disk path, taking into account that it will have a * suffix appended (eg, `.lock`). diff --git a/src/refdb_fs.c b/src/refdb_fs.c index dc291d0f5..097d2b38e 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -77,7 +77,7 @@ GIT_INLINE(int) loose_path( if (git_str_joinpath(out, base, refname) < 0) return -1; - return git_fs_path_validate_filesystem_with_suffix(out->ptr, out->size, + return git_fs_path_validate_str_length_with_suffix(out, CONST_STRLEN(".lock")); } diff --git a/src/repository.c b/src/repository.c index f564453db..3b3f7ca82 100644 --- a/src/repository.c +++ b/src/repository.c @@ -240,8 +240,8 @@ GIT_INLINE(int) validate_repo_path(git_str *path) CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ; - return git_fs_path_validate_filesystem_with_suffix( - path->ptr, path->size, suffix_len); + return git_fs_path_validate_str_length_with_suffix( + path, suffix_len); } /* -- cgit v1.2.1 From 1217c5b232a2343f711ecf4c4ed38211ee6a268a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 Nov 2021 21:12:23 -0400 Subject: fs_path: remove now-unused validation functions --- src/fs_path.c | 46 ---------------------------------------------- src/fs_path.h | 22 ---------------------- 2 files changed, 68 deletions(-) diff --git a/src/fs_path.c b/src/fs_path.c index 56980148e..957f389cc 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1738,52 +1738,6 @@ int git_fs_path_validate_str_length_with_suffix( return 0; } -#ifdef GIT_WIN32 -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - int longpaths = 0; - - if (repo && - git_repository__configmap_lookup(&longpaths, repo, GIT_CONFIGMAP_LONGPATHS) < 0) - longpaths = 0; - - return (longpaths == 0); -} - -#else - -GIT_INLINE(bool) should_validate_longpaths(git_repository *repo) -{ - GIT_UNUSED(repo); - - return false; -} -#endif - -int git_fs_path_validate_workdir(git_repository *repo, const char *path) -{ - if (should_validate_longpaths(repo)) - return git_fs_path_validate_filesystem(path, strlen(path)); - - return 0; -} - -int git_fs_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len) -{ - if (should_validate_longpaths(repo)) - return git_fs_path_validate_filesystem(path, path_len); - - return 0; -} - -int git_fs_path_validate_workdir_buf(git_repository *repo, git_str *path) -{ - return git_fs_path_validate_workdir_with_len(repo, path->ptr, path->size); -} - int git_fs_path_normalize_slashes(git_str *out, const char *path) { int error; diff --git a/src/fs_path.h b/src/fs_path.h index 116e8f912..dcedd5eb5 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -725,28 +725,6 @@ GIT_INLINE(int) git_fs_path_validate_filesystem( return git_fs_path_validate_filesystem_with_suffix(path, path_len, 0); } -/** - * Validate a path relative to the repo's worktree. This ensures that - * the given working tree path is valid for the operating system/platform. - * This will ensure that an absolute path is smaller than MAX_PATH on - * Windows, while keeping `core.longpaths` configuration settings in mind. - * - * This should be checked by mechamisms like `git_checkout` after - * contructing on-disk paths and before trying to write them. - * - * If the repository is null, no repository configuration is applied. - */ -extern int git_fs_path_validate_workdir( - git_repository *repo, - const char *path); -extern int git_fs_path_validate_workdir_with_len( - git_repository *repo, - const char *path, - size_t path_len); -extern int git_fs_path_validate_workdir_buf( - git_repository *repo, - git_str *buf); - /** * Convert any backslashes into slashes */ -- cgit v1.2.1 From 1a8b2922d953e78bd51fc6d5ef290e1f7e00af3a Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Tue, 9 Nov 2021 14:15:32 +0000 Subject: win32: include correct path header --- src/fs_path.h | 1 + src/win32/findfile.c | 2 +- src/win32/path_w32.c | 2 +- src/win32/posix_w32.c | 3 +-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fs_path.h b/src/fs_path.h index dcedd5eb5..188dcf303 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -12,6 +12,7 @@ #include "posix.h" #include "str.h" #include "vector.h" +#include "utf8.h" #include "git2/sys/path.h" diff --git a/src/win32/findfile.c b/src/win32/findfile.c index 7578d960e..d4afc4acc 100644 --- a/src/win32/findfile.c +++ b/src/win32/findfile.c @@ -9,7 +9,7 @@ #include "path_w32.h" #include "utf-conv.h" -#include "path.h" +#include "fs_path.h" #define REG_MSYSGIT_INSTALL_LOCAL L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Git_is1" diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 1f765f1de..5d7ad11f6 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -7,7 +7,7 @@ #include "path_w32.h" -#include "path.h" +#include "fs_path.h" #include "utf-conv.h" #include "posix.h" #include "reparse.h" diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 398287f9e..ba46b5ea9 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -9,10 +9,9 @@ #include "../posix.h" #include "../futils.h" -#include "path.h" +#include "fs_path.h" #include "path_w32.h" #include "utf-conv.h" -#include "repository.h" #include "reparse.h" #include #include -- cgit v1.2.1