rugged 1.3.1 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -2
- data/ext/rugged/extconf.rb +6 -3
- data/ext/rugged/rugged.c +16 -0
- data/ext/rugged/rugged.h +4 -0
- data/ext/rugged/rugged_blame.c +2 -0
- data/ext/rugged/rugged_blob.c +3 -0
- data/ext/rugged/rugged_commit.c +1 -0
- data/ext/rugged/rugged_config.c +9 -2
- data/ext/rugged/rugged_diff.c +1 -0
- data/ext/rugged/rugged_index.c +2 -0
- data/ext/rugged/rugged_patch.c +1 -0
- data/ext/rugged/rugged_rebase.c +1 -0
- data/ext/rugged/rugged_reference.c +1 -0
- data/ext/rugged/rugged_remote.c +28 -10
- data/ext/rugged/rugged_repo.c +7 -9
- data/ext/rugged/rugged_revwalk.c +5 -1
- data/ext/rugged/rugged_settings.c +5 -0
- data/ext/rugged/rugged_submodule.c +1 -0
- data/ext/rugged/rugged_tag.c +1 -0
- data/ext/rugged/rugged_tree.c +4 -0
- data/lib/rugged/index.rb +1 -1
- data/lib/rugged/tree.rb +5 -1
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +132 -288
- data/vendor/libgit2/COPYING +106 -19
- data/vendor/libgit2/cmake/AddCFlagIfSupported.cmake +21 -21
- data/vendor/libgit2/cmake/AddClarTest.cmake +7 -0
- data/vendor/libgit2/cmake/DefaultCFlags.cmake +154 -0
- data/vendor/libgit2/cmake/EnableWarnings.cmake +13 -13
- data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
- data/vendor/libgit2/cmake/FindCoreFoundation.cmake +13 -13
- data/vendor/libgit2/cmake/FindGSSAPI.cmake +171 -287
- data/vendor/libgit2/cmake/FindGSSFramework.cmake +13 -13
- data/vendor/libgit2/cmake/{FindHTTP_Parser.cmake → FindHTTPParser.cmake} +17 -17
- data/vendor/libgit2/cmake/FindIconv.cmake +27 -27
- data/vendor/libgit2/cmake/FindLibSSH2.cmake +5 -5
- data/vendor/libgit2/cmake/FindPCRE.cmake +12 -13
- data/vendor/libgit2/cmake/FindPCRE2.cmake +12 -12
- data/vendor/libgit2/cmake/FindPkgLibraries.cmake +19 -19
- data/vendor/libgit2/cmake/FindSecurity.cmake +14 -14
- data/vendor/libgit2/cmake/FindStatNsec.cmake +12 -18
- data/vendor/libgit2/cmake/Findfutimens.cmake +8 -8
- data/vendor/libgit2/cmake/FindmbedTLS.cmake +63 -70
- data/vendor/libgit2/cmake/IdeSplitSources.cmake +18 -18
- data/vendor/libgit2/cmake/PkgBuildConfig.cmake +60 -60
- data/vendor/libgit2/cmake/SanitizeBool.cmake +20 -20
- data/vendor/libgit2/cmake/SelectGSSAPI.cmake +37 -37
- data/vendor/libgit2/cmake/SelectHTTPParser.cmake +19 -0
- data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +100 -100
- data/vendor/libgit2/cmake/SelectHashes.cmake +91 -53
- data/vendor/libgit2/cmake/SelectRegex.cmake +51 -0
- data/vendor/libgit2/cmake/SelectSSH.cmake +41 -0
- data/vendor/libgit2/cmake/SelectWinHTTP.cmake +17 -0
- data/vendor/libgit2/cmake/SelectZlib.cmake +34 -0
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +6 -6
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +33 -31
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +3 -1
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +4 -4
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +4 -4
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +2 -2
- data/vendor/libgit2/deps/pcre/CMakeLists.txt +88 -88
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +14 -16
- data/vendor/libgit2/deps/zlib/adler32.c +7 -0
- data/vendor/libgit2/deps/zlib/crc32.c +975 -288
- data/vendor/libgit2/deps/zlib/crc32.h +9441 -436
- data/vendor/libgit2/deps/zlib/deflate.c +83 -31
- data/vendor/libgit2/deps/zlib/deflate.h +12 -15
- data/vendor/libgit2/deps/zlib/gzguts.h +3 -2
- data/vendor/libgit2/deps/zlib/infback.c +2 -1
- data/vendor/libgit2/deps/zlib/inffast.c +14 -14
- data/vendor/libgit2/deps/zlib/inflate.c +39 -8
- data/vendor/libgit2/deps/zlib/inflate.h +3 -2
- data/vendor/libgit2/deps/zlib/inftrees.c +3 -3
- data/vendor/libgit2/deps/zlib/trees.c +27 -48
- data/vendor/libgit2/deps/zlib/zlib.h +126 -100
- data/vendor/libgit2/deps/zlib/zutil.c +2 -2
- data/vendor/libgit2/deps/zlib/zutil.h +12 -9
- data/vendor/libgit2/include/git2/apply.h +16 -2
- data/vendor/libgit2/include/git2/attr.h +11 -2
- data/vendor/libgit2/include/git2/blame.h +4 -1
- data/vendor/libgit2/include/git2/blob.h +14 -1
- data/vendor/libgit2/include/git2/branch.h +4 -2
- data/vendor/libgit2/include/git2/buffer.h +18 -78
- data/vendor/libgit2/include/git2/cert.h +2 -2
- data/vendor/libgit2/include/git2/checkout.h +5 -2
- data/vendor/libgit2/include/git2/clone.h +3 -3
- data/vendor/libgit2/include/git2/commit.h +2 -0
- data/vendor/libgit2/include/git2/common.h +38 -7
- data/vendor/libgit2/include/git2/config.h +25 -9
- data/vendor/libgit2/include/git2/credential.h +2 -1
- data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
- data/vendor/libgit2/include/git2/deprecated.h +9 -1
- data/vendor/libgit2/include/git2/describe.h +7 -2
- data/vendor/libgit2/include/git2/diff.h +18 -10
- data/vendor/libgit2/include/git2/email.h +1 -1
- data/vendor/libgit2/include/git2/errors.h +18 -3
- data/vendor/libgit2/include/git2/experimental.h +20 -0
- data/vendor/libgit2/include/git2/filter.h +7 -2
- data/vendor/libgit2/include/git2/graph.h +1 -0
- data/vendor/libgit2/include/git2/ignore.h +1 -1
- data/vendor/libgit2/include/git2/index.h +11 -5
- data/vendor/libgit2/include/git2/indexer.h +48 -0
- data/vendor/libgit2/include/git2/merge.h +24 -4
- data/vendor/libgit2/include/git2/message.h +2 -0
- data/vendor/libgit2/include/git2/object.h +49 -0
- data/vendor/libgit2/include/git2/odb.h +94 -13
- data/vendor/libgit2/include/git2/odb_backend.h +107 -19
- data/vendor/libgit2/include/git2/oid.h +115 -15
- data/vendor/libgit2/include/git2/pack.h +24 -8
- data/vendor/libgit2/include/git2/patch.h +8 -0
- data/vendor/libgit2/include/git2/pathspec.h +1 -1
- data/vendor/libgit2/include/git2/proxy.h +1 -1
- data/vendor/libgit2/include/git2/rebase.h +9 -1
- data/vendor/libgit2/include/git2/refdb.h +3 -0
- data/vendor/libgit2/include/git2/reflog.h +1 -1
- data/vendor/libgit2/include/git2/refs.h +2 -2
- data/vendor/libgit2/include/git2/remote.h +184 -37
- data/vendor/libgit2/include/git2/repository.h +34 -10
- data/vendor/libgit2/include/git2/reset.h +2 -2
- data/vendor/libgit2/include/git2/revparse.h +1 -1
- data/vendor/libgit2/include/git2/revwalk.h +4 -1
- data/vendor/libgit2/include/git2/signature.h +1 -1
- data/vendor/libgit2/include/git2/stash.h +61 -7
- data/vendor/libgit2/include/git2/status.h +14 -5
- data/vendor/libgit2/include/git2/strarray.h +0 -13
- data/vendor/libgit2/include/git2/submodule.h +7 -2
- data/vendor/libgit2/include/git2/sys/commit_graph.h +1 -1
- data/vendor/libgit2/include/git2/sys/odb_backend.h +3 -6
- data/vendor/libgit2/include/git2/sys/remote.h +46 -0
- data/vendor/libgit2/include/git2/sys/stream.h +1 -1
- data/vendor/libgit2/include/git2/sys/transport.h +46 -39
- data/vendor/libgit2/include/git2/tag.h +1 -0
- data/vendor/libgit2/include/git2/tree.h +4 -3
- data/vendor/libgit2/include/git2/types.h +7 -7
- data/vendor/libgit2/include/git2/version.h +27 -6
- data/vendor/libgit2/include/git2/worktree.h +12 -2
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +177 -419
- data/vendor/libgit2/src/README.md +12 -0
- data/vendor/libgit2/src/cli/CMakeLists.txt +57 -0
- data/vendor/libgit2/src/cli/README.md +26 -0
- data/vendor/libgit2/src/cli/cli.h +20 -0
- data/vendor/libgit2/src/cli/cmd.c +21 -0
- data/vendor/libgit2/src/cli/cmd.h +33 -0
- data/vendor/libgit2/src/cli/cmd_cat_file.c +204 -0
- data/vendor/libgit2/src/cli/cmd_clone.c +176 -0
- data/vendor/libgit2/src/cli/cmd_hash_object.c +154 -0
- data/vendor/libgit2/src/cli/cmd_help.c +86 -0
- data/vendor/libgit2/src/cli/error.h +51 -0
- data/vendor/libgit2/src/cli/main.c +106 -0
- data/vendor/libgit2/src/cli/opt.c +669 -0
- data/vendor/libgit2/src/cli/opt.h +349 -0
- data/vendor/libgit2/src/cli/opt_usage.c +194 -0
- data/vendor/libgit2/src/cli/opt_usage.h +35 -0
- data/vendor/libgit2/src/cli/progress.c +345 -0
- data/vendor/libgit2/src/cli/progress.h +117 -0
- data/vendor/libgit2/src/cli/sighandler.h +20 -0
- data/vendor/libgit2/src/cli/unix/sighandler.c +36 -0
- data/vendor/libgit2/src/cli/win32/precompiled.h +3 -0
- data/vendor/libgit2/src/cli/win32/sighandler.c +37 -0
- data/vendor/libgit2/src/libgit2/CMakeLists.txt +141 -0
- data/vendor/libgit2/src/{annotated_commit.c → libgit2/annotated_commit.c} +1 -1
- data/vendor/libgit2/src/{annotated_commit.h → libgit2/annotated_commit.h} +2 -2
- data/vendor/libgit2/src/{apply.c → libgit2/apply.c} +18 -18
- data/vendor/libgit2/src/{apply.h → libgit2/apply.h} +2 -2
- data/vendor/libgit2/src/{attr.c → libgit2/attr.c} +18 -18
- data/vendor/libgit2/src/{attr_file.c → libgit2/attr_file.c} +18 -18
- data/vendor/libgit2/src/{attr_file.h → libgit2/attr_file.h} +4 -4
- data/vendor/libgit2/src/{attrcache.c → libgit2/attrcache.c} +18 -13
- data/vendor/libgit2/src/{blame.c → libgit2/blame.c} +2 -0
- data/vendor/libgit2/src/{blame_git.c → libgit2/blame_git.c} +1 -1
- data/vendor/libgit2/src/{blob.c → libgit2/blob.c} +38 -29
- data/vendor/libgit2/src/{blob.h → libgit2/blob.h} +3 -3
- data/vendor/libgit2/src/{branch.c → libgit2/branch.c} +164 -118
- data/vendor/libgit2/src/{branch.h → libgit2/branch.h} +15 -3
- data/vendor/libgit2/src/libgit2/buf.c +126 -0
- data/vendor/libgit2/src/libgit2/buf.h +50 -0
- data/vendor/libgit2/src/{checkout.c → libgit2/checkout.c} +74 -68
- data/vendor/libgit2/src/{cherrypick.c → libgit2/cherrypick.c} +13 -13
- data/vendor/libgit2/src/{clone.c → libgit2/clone.c} +96 -67
- data/vendor/libgit2/src/{commit.c → libgit2/commit.c} +178 -73
- data/vendor/libgit2/src/libgit2/commit.h +87 -0
- data/vendor/libgit2/src/{commit_graph.c → libgit2/commit_graph.c} +122 -89
- data/vendor/libgit2/src/{commit_graph.h → libgit2/commit_graph.h} +14 -4
- data/vendor/libgit2/src/{commit_list.c → libgit2/commit_list.c} +7 -4
- data/vendor/libgit2/src/libgit2/common.h +55 -0
- data/vendor/libgit2/src/{config.c → libgit2/config.c} +107 -71
- data/vendor/libgit2/src/{config.h → libgit2/config.h} +15 -2
- data/vendor/libgit2/src/{config_file.c → libgit2/config_file.c} +105 -93
- data/vendor/libgit2/src/{config_mem.c → libgit2/config_mem.c} +9 -9
- data/vendor/libgit2/src/{config_parse.c → libgit2/config_parse.c} +27 -23
- data/vendor/libgit2/src/{crlf.c → libgit2/crlf.c} +24 -21
- data/vendor/libgit2/src/{describe.c → libgit2/describe.c} +35 -27
- data/vendor/libgit2/src/{diff.c → libgit2/diff.c} +30 -9
- data/vendor/libgit2/src/{diff.h → libgit2/diff.h} +2 -4
- data/vendor/libgit2/src/{diff_driver.c → libgit2/diff_driver.c} +34 -36
- data/vendor/libgit2/src/{diff_driver.h → libgit2/diff_driver.h} +3 -3
- data/vendor/libgit2/src/{diff_file.c → libgit2/diff_file.c} +44 -26
- data/vendor/libgit2/src/{diff_generate.c → libgit2/diff_generate.c} +47 -18
- data/vendor/libgit2/src/{diff_generate.h → libgit2/diff_generate.h} +5 -3
- data/vendor/libgit2/src/{diff_print.c → libgit2/diff_print.c} +112 -100
- data/vendor/libgit2/src/{diff_stats.c → libgit2/diff_stats.c} +40 -29
- data/vendor/libgit2/src/libgit2/diff_stats.h +18 -0
- data/vendor/libgit2/src/{diff_tform.c → libgit2/diff_tform.c} +13 -8
- data/vendor/libgit2/src/{diff_xdiff.c → libgit2/diff_xdiff.c} +4 -8
- data/vendor/libgit2/src/{email.c → libgit2/email.c} +55 -39
- data/vendor/libgit2/src/{email.h → libgit2/email.h} +1 -1
- data/vendor/libgit2/src/{errors.c → libgit2/errors.c} +18 -18
- data/vendor/libgit2/src/{errors.h → libgit2/errors.h} +1 -2
- data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
- data/vendor/libgit2/src/{fetch.c → libgit2/fetch.c} +72 -27
- data/vendor/libgit2/src/{fetch.h → libgit2/fetch.h} +1 -1
- data/vendor/libgit2/src/{fetchhead.c → libgit2/fetchhead.c} +23 -23
- data/vendor/libgit2/src/{filter.c → libgit2/filter.c} +127 -53
- data/vendor/libgit2/src/{filter.h → libgit2/filter.h} +26 -5
- data/vendor/libgit2/src/{ident.c → libgit2/ident.c} +20 -20
- data/vendor/libgit2/src/{ignore.c → libgit2/ignore.c} +35 -34
- data/vendor/libgit2/src/{ignore.h → libgit2/ignore.h} +2 -2
- data/vendor/libgit2/src/{index.c → libgit2/index.c} +91 -90
- data/vendor/libgit2/src/{index.h → libgit2/index.h} +6 -3
- data/vendor/libgit2/src/{indexer.c → libgit2/indexer.c} +173 -92
- data/vendor/libgit2/src/{iterator.c → libgit2/iterator.c} +71 -61
- data/vendor/libgit2/src/{iterator.h → libgit2/iterator.h} +5 -5
- data/vendor/libgit2/src/{libgit2.c → libgit2/libgit2.c} +54 -11
- data/vendor/libgit2/src/{mailmap.c → libgit2/mailmap.c} +38 -36
- data/vendor/libgit2/src/{merge.c → libgit2/merge.c} +30 -30
- data/vendor/libgit2/src/{merge.h → libgit2/merge.h} +1 -14
- data/vendor/libgit2/src/{merge_driver.c → libgit2/merge_driver.c} +2 -2
- data/vendor/libgit2/src/{merge_file.c → libgit2/merge_file.c} +13 -3
- data/vendor/libgit2/src/{message.c → libgit2/message.c} +21 -10
- data/vendor/libgit2/src/{midx.c → libgit2/midx.c} +112 -92
- data/vendor/libgit2/src/{midx.h → libgit2/midx.h} +5 -4
- data/vendor/libgit2/src/{mwindow.c → libgit2/mwindow.c} +15 -12
- data/vendor/libgit2/src/{mwindow.h → libgit2/mwindow.h} +5 -2
- data/vendor/libgit2/src/{netops.c → libgit2/netops.c} +1 -2
- data/vendor/libgit2/src/{netops.h → libgit2/netops.h} +1 -1
- data/vendor/libgit2/src/{notes.c → libgit2/notes.c} +25 -34
- data/vendor/libgit2/src/{object.c → libgit2/object.c} +135 -30
- data/vendor/libgit2/src/{object.h → libgit2/object.h} +12 -3
- data/vendor/libgit2/src/{odb.c → libgit2/odb.c} +228 -81
- data/vendor/libgit2/src/{odb.h → libgit2/odb.h} +44 -5
- data/vendor/libgit2/src/{odb_loose.c → libgit2/odb_loose.c} +192 -134
- data/vendor/libgit2/src/{odb_mempack.c → libgit2/odb_mempack.c} +18 -5
- data/vendor/libgit2/src/{odb_pack.c → libgit2/odb_pack.c} +137 -85
- data/vendor/libgit2/src/{oid.c → libgit2/oid.c} +136 -90
- data/vendor/libgit2/src/libgit2/oid.h +273 -0
- data/vendor/libgit2/src/{oidmap.c → libgit2/oidmap.c} +1 -1
- data/vendor/libgit2/src/{pack-objects.c → libgit2/pack-objects.c} +56 -30
- data/vendor/libgit2/src/{pack-objects.h → libgit2/pack-objects.h} +11 -6
- data/vendor/libgit2/src/{pack.c → libgit2/pack.c} +114 -84
- data/vendor/libgit2/src/{pack.h → libgit2/pack.h} +31 -16
- data/vendor/libgit2/src/{parse.c → libgit2/parse.c} +4 -3
- data/vendor/libgit2/src/{patch.c → libgit2/patch.c} +3 -3
- data/vendor/libgit2/src/{patch.h → libgit2/patch.h} +1 -0
- data/vendor/libgit2/src/{patch_generate.c → libgit2/patch_generate.c} +27 -11
- data/vendor/libgit2/src/{patch_generate.h → libgit2/patch_generate.h} +5 -5
- data/vendor/libgit2/src/{patch_parse.c → libgit2/patch_parse.c} +29 -29
- data/vendor/libgit2/src/libgit2/path.c +375 -0
- data/vendor/libgit2/src/libgit2/path.h +68 -0
- data/vendor/libgit2/src/{pathspec.c → libgit2/pathspec.c} +6 -6
- data/vendor/libgit2/src/{pathspec.h → libgit2/pathspec.h} +2 -2
- data/vendor/libgit2/src/{proxy.c → libgit2/proxy.c} +4 -1
- data/vendor/libgit2/src/{proxy.h → libgit2/proxy.h} +1 -1
- data/vendor/libgit2/src/{push.c → libgit2/push.c} +43 -38
- data/vendor/libgit2/src/{push.h → libgit2/push.h} +4 -16
- data/vendor/libgit2/src/{reader.c → libgit2/reader.c} +9 -9
- data/vendor/libgit2/src/{reader.h → libgit2/reader.h} +2 -2
- data/vendor/libgit2/src/{rebase.c → libgit2/rebase.c} +119 -107
- data/vendor/libgit2/src/{refdb_fs.c → libgit2/refdb_fs.c} +506 -197
- data/vendor/libgit2/src/{reflog.c → libgit2/reflog.c} +7 -5
- data/vendor/libgit2/src/{reflog.h → libgit2/reflog.h} +1 -2
- data/vendor/libgit2/src/{refs.c → libgit2/refs.c} +34 -32
- data/vendor/libgit2/src/{refs.h → libgit2/refs.h} +2 -2
- data/vendor/libgit2/src/{refspec.c → libgit2/refspec.c} +32 -37
- data/vendor/libgit2/src/{refspec.h → libgit2/refspec.h} +5 -2
- data/vendor/libgit2/src/{remote.c → libgit2/remote.c} +718 -420
- data/vendor/libgit2/src/libgit2/remote.h +100 -0
- data/vendor/libgit2/src/{repository.c → libgit2/repository.c} +690 -366
- data/vendor/libgit2/src/{repository.h → libgit2/repository.h} +21 -9
- data/vendor/libgit2/src/{reset.c → libgit2/reset.c} +8 -5
- data/vendor/libgit2/src/{revert.c → libgit2/revert.c} +14 -14
- data/vendor/libgit2/src/{revparse.c → libgit2/revparse.c} +71 -42
- data/vendor/libgit2/src/{revwalk.c → libgit2/revwalk.c} +12 -8
- data/vendor/libgit2/src/{signature.c → libgit2/signature.c} +12 -6
- data/vendor/libgit2/src/{signature.h → libgit2/signature.h} +1 -1
- data/vendor/libgit2/src/{stash.c → libgit2/stash.c} +235 -61
- data/vendor/libgit2/src/{status.c → libgit2/status.c} +4 -1
- data/vendor/libgit2/src/{strarray.c → libgit2/strarray.c} +1 -0
- data/vendor/libgit2/src/libgit2/strarray.h +25 -0
- data/vendor/libgit2/src/{streams → libgit2/streams}/mbedtls.c +8 -6
- data/vendor/libgit2/src/{streams → libgit2/streams}/openssl.c +1 -1
- data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_dynamic.c +7 -3
- data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_dynamic.h +3 -3
- data/vendor/libgit2/src/{streams → libgit2/streams}/socket.c +4 -1
- data/vendor/libgit2/src/{submodule.c → libgit2/submodule.c} +177 -161
- data/vendor/libgit2/src/{submodule.h → libgit2/submodule.h} +1 -1
- data/vendor/libgit2/src/libgit2/sysdir.c +650 -0
- data/vendor/libgit2/src/{sysdir.h → libgit2/sysdir.h} +53 -18
- data/vendor/libgit2/src/{tag.c → libgit2/tag.c} +73 -42
- data/vendor/libgit2/src/{tag.h → libgit2/tag.h} +2 -2
- data/vendor/libgit2/src/{threadstate.c → libgit2/threadstate.c} +3 -3
- data/vendor/libgit2/src/{threadstate.h → libgit2/threadstate.h} +2 -2
- data/vendor/libgit2/src/{trace.c → libgit2/trace.c} +1 -14
- data/vendor/libgit2/src/{trace.h → libgit2/trace.h} +5 -22
- data/vendor/libgit2/src/{trailer.c → libgit2/trailer.c} +1 -1
- data/vendor/libgit2/src/{transaction.c → libgit2/transaction.c} +1 -1
- data/vendor/libgit2/src/{transport.c → libgit2/transport.c} +10 -10
- data/vendor/libgit2/src/{transports → libgit2/transports}/auth.c +7 -9
- data/vendor/libgit2/src/{transports → libgit2/transports}/auth.h +2 -3
- data/vendor/libgit2/src/{transports → libgit2/transports}/auth_negotiate.c +12 -13
- data/vendor/libgit2/src/{transports → libgit2/transports}/auth_ntlm.c +10 -10
- data/vendor/libgit2/src/{transports → libgit2/transports}/auth_ntlm.h +0 -1
- data/vendor/libgit2/src/{transports → libgit2/transports}/git.c +9 -11
- data/vendor/libgit2/src/{transports → libgit2/transports}/http.c +41 -20
- data/vendor/libgit2/src/{transports → libgit2/transports}/http.h +2 -3
- data/vendor/libgit2/src/{transports → libgit2/transports}/httpclient.c +75 -66
- data/vendor/libgit2/src/{transports → libgit2/transports}/httpclient.h +10 -0
- data/vendor/libgit2/src/{transports → libgit2/transports}/local.c +138 -116
- data/vendor/libgit2/src/{transports → libgit2/transports}/smart.c +92 -133
- data/vendor/libgit2/src/{transports → libgit2/transports}/smart.h +35 -32
- data/vendor/libgit2/src/{transports → libgit2/transports}/smart_pkt.c +177 -65
- data/vendor/libgit2/src/{transports → libgit2/transports}/smart_protocol.c +97 -49
- data/vendor/libgit2/src/{transports → libgit2/transports}/ssh.c +365 -198
- data/vendor/libgit2/src/{transports → libgit2/transports}/winhttp.c +58 -59
- data/vendor/libgit2/src/{tree-cache.c → libgit2/tree-cache.c} +8 -8
- data/vendor/libgit2/src/{tree-cache.h → libgit2/tree-cache.h} +2 -2
- data/vendor/libgit2/src/{tree.c → libgit2/tree.c} +93 -83
- data/vendor/libgit2/src/{tree.h → libgit2/tree.h} +4 -4
- data/vendor/libgit2/src/{worktree.c → libgit2/worktree.c} +121 -94
- data/vendor/libgit2/src/{worktree.h → libgit2/worktree.h} +1 -1
- data/vendor/libgit2/src/libgit2/xdiff/git-xdiff.h +53 -0
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xdiff.h +15 -15
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xdiffi.c +134 -108
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xemit.c +23 -7
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xhistogram.c +87 -78
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xinclude.h +1 -12
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xmerge.c +104 -117
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xpatience.c +6 -17
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xprepare.c +15 -20
- data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xutils.c +18 -7
- data/vendor/libgit2/src/util/CMakeLists.txt +80 -0
- data/vendor/libgit2/src/{allocators → util/allocators}/failalloc.h +1 -1
- data/vendor/libgit2/src/{allocators → util/allocators}/stdalloc.h +1 -1
- data/vendor/libgit2/src/{allocators → util/allocators}/win32_leakcheck.h +1 -1
- data/vendor/libgit2/src/{array.h → util/array.h} +1 -1
- data/vendor/libgit2/src/{assert_safe.h → util/assert_safe.h} +16 -0
- data/vendor/libgit2/src/{cc-compat.h → util/cc-compat.h} +1 -1
- data/vendor/libgit2/src/{date.c → util/date.c} +14 -20
- data/vendor/libgit2/src/util/date.h +33 -0
- data/vendor/libgit2/src/{filebuf.c → util/filebuf.c} +29 -29
- data/vendor/libgit2/src/{filebuf.h → util/filebuf.h} +2 -2
- data/vendor/libgit2/src/{path.c → util/fs_path.c} +580 -615
- data/vendor/libgit2/src/{path.h → util/fs_path.h} +234 -181
- data/vendor/libgit2/src/{futils.c → util/futils.c} +135 -90
- data/vendor/libgit2/src/{futils.h → util/futils.h} +28 -15
- data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +15 -1
- data/vendor/libgit2/src/{common.h → util/git2_util.h} +20 -59
- data/vendor/libgit2/src/util/hash/builtin.c +53 -0
- data/vendor/libgit2/src/{hash/sha1/openssl.h → util/hash/builtin.h} +6 -6
- data/vendor/libgit2/src/{hash/sha1 → util/hash}/collisiondetect.c +3 -3
- data/vendor/libgit2/src/{hash/sha1 → util/hash}/collisiondetect.h +3 -3
- data/vendor/libgit2/src/util/hash/common_crypto.c +112 -0
- data/vendor/libgit2/src/{hash/sha1 → util/hash}/common_crypto.h +11 -3
- data/vendor/libgit2/src/util/hash/mbedtls.c +92 -0
- data/vendor/libgit2/src/{hash/sha1 → util/hash}/mbedtls.h +14 -4
- data/vendor/libgit2/src/util/hash/openssl.c +195 -0
- data/vendor/libgit2/src/util/hash/openssl.h +45 -0
- data/vendor/libgit2/src/util/hash/rfc6234/sha.h +243 -0
- data/vendor/libgit2/src/util/hash/rfc6234/sha224-256.c +601 -0
- data/vendor/libgit2/src/util/hash/sha.h +70 -0
- data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/sha1.c +1 -1
- data/vendor/libgit2/src/util/hash/win32.c +549 -0
- data/vendor/libgit2/src/util/hash/win32.h +60 -0
- data/vendor/libgit2/src/util/hash.c +158 -0
- data/vendor/libgit2/src/util/hash.h +61 -0
- data/vendor/libgit2/src/{khash.h → util/khash.h} +1 -1
- data/vendor/libgit2/src/{map.h → util/map.h} +1 -1
- data/vendor/libgit2/src/util/net.c +1003 -0
- data/vendor/libgit2/src/{net.h → util/net.h} +18 -4
- data/vendor/libgit2/src/{pool.h → util/pool.h} +1 -1
- data/vendor/libgit2/src/{posix.c → util/posix.c} +3 -3
- data/vendor/libgit2/src/{posix.h → util/posix.h} +4 -1
- data/vendor/libgit2/src/{pqueue.h → util/pqueue.h} +2 -2
- data/vendor/libgit2/src/util/rand.c +234 -0
- data/vendor/libgit2/src/util/rand.h +37 -0
- data/vendor/libgit2/src/{regexp.c → util/regexp.c} +4 -4
- data/vendor/libgit2/src/{regexp.h → util/regexp.h} +1 -1
- data/vendor/libgit2/src/{runtime.c → util/runtime.c} +1 -1
- data/vendor/libgit2/src/{runtime.h → util/runtime.h} +1 -1
- data/vendor/libgit2/src/{sortedcache.c → util/sortedcache.c} +1 -1
- data/vendor/libgit2/src/{sortedcache.h → util/sortedcache.h} +2 -2
- data/vendor/libgit2/src/{buffer.c → util/str.c} +157 -151
- data/vendor/libgit2/src/util/str.h +357 -0
- data/vendor/libgit2/src/{strmap.h → util/strmap.h} +1 -1
- data/vendor/libgit2/src/{thread.c → util/thread.c} +1 -1
- data/vendor/libgit2/src/{thread.h → util/thread.h} +23 -22
- data/vendor/libgit2/src/{tsort.c → util/tsort.c} +1 -1
- data/vendor/libgit2/src/{unix → util/unix}/map.c +1 -3
- data/vendor/libgit2/src/{unix → util/unix}/posix.h +1 -4
- data/vendor/libgit2/src/{unix → util/unix}/realpath.c +1 -3
- data/vendor/libgit2/src/{utf8.c → util/utf8.c} +1 -1
- data/vendor/libgit2/src/{utf8.h → util/utf8.h} +1 -1
- data/vendor/libgit2/src/{util.c → util/util.c} +15 -15
- data/vendor/libgit2/src/{util.h → util/util.h} +4 -29
- data/vendor/libgit2/src/{varint.h → util/varint.h} +1 -1
- data/vendor/libgit2/src/{vector.h → util/vector.h} +2 -2
- data/vendor/libgit2/src/{wildmatch.h → util/wildmatch.h} +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/dir.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/error.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/map.c +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/path_w32.c +140 -9
- data/vendor/libgit2/src/{win32 → util/win32}/path_w32.h +3 -1
- data/vendor/libgit2/src/{win32 → util/win32}/posix.h +1 -2
- data/vendor/libgit2/src/{win32 → util/win32}/posix_w32.c +12 -28
- data/vendor/libgit2/src/util/win32/precompiled.c +1 -0
- data/vendor/libgit2/src/{win32 → util/win32}/precompiled.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/thread.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/utf-conv.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/w32_buffer.c +2 -3
- data/vendor/libgit2/src/{win32 → util/win32}/w32_buffer.h +3 -4
- data/vendor/libgit2/src/{win32 → util/win32}/w32_leakcheck.c +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/w32_leakcheck.h +1 -1
- data/vendor/libgit2/src/{win32 → util/win32}/w32_util.h +1 -1
- data/vendor/libgit2/src/{zstream.c → util/zstream.c} +5 -5
- data/vendor/libgit2/src/{zstream.h → util/zstream.h} +5 -5
- metadata +402 -356
- data/vendor/libgit2/src/buffer.h +0 -374
- data/vendor/libgit2/src/commit.h +0 -46
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +0 -57
- data/vendor/libgit2/src/hash/sha1/generic.c +0 -300
- data/vendor/libgit2/src/hash/sha1/generic.h +0 -19
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +0 -46
- data/vendor/libgit2/src/hash/sha1/openssl.c +0 -59
- data/vendor/libgit2/src/hash/sha1/win32.c +0 -333
- data/vendor/libgit2/src/hash/sha1/win32.h +0 -128
- data/vendor/libgit2/src/hash/sha1.h +0 -38
- data/vendor/libgit2/src/hash.c +0 -110
- data/vendor/libgit2/src/hash.h +0 -46
- data/vendor/libgit2/src/message.h +0 -17
- data/vendor/libgit2/src/net.c +0 -540
- data/vendor/libgit2/src/oid.h +0 -51
- data/vendor/libgit2/src/remote.h +0 -55
- data/vendor/libgit2/src/sysdir.c +0 -347
- data/vendor/libgit2/src/win32/findfile.c +0 -230
- data/vendor/libgit2/src/win32/findfile.h +0 -19
- /data/vendor/libgit2/src/{win32 → cli/win32}/precompiled.c +0 -0
- /data/vendor/libgit2/src/{attr.h → libgit2/attr.h} +0 -0
- /data/vendor/libgit2/src/{attrcache.h → libgit2/attrcache.h} +0 -0
- /data/vendor/libgit2/src/{blame.h → libgit2/blame.h} +0 -0
- /data/vendor/libgit2/src/{blame_git.h → libgit2/blame_git.h} +0 -0
- /data/vendor/libgit2/src/{cache.c → libgit2/cache.c} +0 -0
- /data/vendor/libgit2/src/{cache.h → libgit2/cache.h} +0 -0
- /data/vendor/libgit2/src/{checkout.h → libgit2/checkout.h} +0 -0
- /data/vendor/libgit2/src/{clone.h → libgit2/clone.h} +0 -0
- /data/vendor/libgit2/src/{commit_list.h → libgit2/commit_list.h} +0 -0
- /data/vendor/libgit2/src/{config_backend.h → libgit2/config_backend.h} +0 -0
- /data/vendor/libgit2/src/{config_cache.c → libgit2/config_cache.c} +0 -0
- /data/vendor/libgit2/src/{config_entries.c → libgit2/config_entries.c} +0 -0
- /data/vendor/libgit2/src/{config_entries.h → libgit2/config_entries.h} +0 -0
- /data/vendor/libgit2/src/{config_parse.h → libgit2/config_parse.h} +0 -0
- /data/vendor/libgit2/src/{config_snapshot.c → libgit2/config_snapshot.c} +0 -0
- /data/vendor/libgit2/src/{delta.c → libgit2/delta.c} +0 -0
- /data/vendor/libgit2/src/{delta.h → libgit2/delta.h} +0 -0
- /data/vendor/libgit2/src/{diff_file.h → libgit2/diff_file.h} +0 -0
- /data/vendor/libgit2/src/{diff_parse.c → libgit2/diff_parse.c} +0 -0
- /data/vendor/libgit2/src/{diff_parse.h → libgit2/diff_parse.h} +0 -0
- /data/vendor/libgit2/src/{diff_tform.h → libgit2/diff_tform.h} +0 -0
- /data/vendor/libgit2/src/{diff_xdiff.h → libgit2/diff_xdiff.h} +0 -0
- /data/vendor/libgit2/src/{fetchhead.h → libgit2/fetchhead.h} +0 -0
- /data/vendor/libgit2/src/{win32 → libgit2}/git2.rc +0 -0
- /data/vendor/libgit2/src/{graph.c → libgit2/graph.c} +0 -0
- /data/vendor/libgit2/src/{hashsig.c → libgit2/hashsig.c} +0 -0
- /data/vendor/libgit2/src/{idxmap.c → libgit2/idxmap.c} +0 -0
- /data/vendor/libgit2/src/{idxmap.h → libgit2/idxmap.h} +0 -0
- /data/vendor/libgit2/src/{indexer.h → libgit2/indexer.h} +0 -0
- /data/vendor/libgit2/src/{libgit2.h → libgit2/libgit2.h} +0 -0
- /data/vendor/libgit2/src/{mailmap.h → libgit2/mailmap.h} +0 -0
- /data/vendor/libgit2/src/{merge_driver.h → libgit2/merge_driver.h} +0 -0
- /data/vendor/libgit2/src/{notes.h → libgit2/notes.h} +0 -0
- /data/vendor/libgit2/src/{object_api.c → libgit2/object_api.c} +0 -0
- /data/vendor/libgit2/src/{offmap.c → libgit2/offmap.c} +0 -0
- /data/vendor/libgit2/src/{offmap.h → libgit2/offmap.h} +0 -0
- /data/vendor/libgit2/src/{oidarray.c → libgit2/oidarray.c} +0 -0
- /data/vendor/libgit2/src/{oidarray.h → libgit2/oidarray.h} +0 -0
- /data/vendor/libgit2/src/{oidmap.h → libgit2/oidmap.h} +0 -0
- /data/vendor/libgit2/src/{parse.h → libgit2/parse.h} +0 -0
- /data/vendor/libgit2/src/{patch_parse.h → libgit2/patch_parse.h} +0 -0
- /data/vendor/libgit2/src/{refdb.c → libgit2/refdb.c} +0 -0
- /data/vendor/libgit2/src/{refdb.h → libgit2/refdb.h} +0 -0
- /data/vendor/libgit2/src/{repo_template.h → libgit2/repo_template.h} +0 -0
- /data/vendor/libgit2/src/{revwalk.h → libgit2/revwalk.h} +0 -0
- /data/vendor/libgit2/src/{settings.h → libgit2/settings.h} +0 -0
- /data/vendor/libgit2/src/{status.h → libgit2/status.h} +0 -0
- /data/vendor/libgit2/src/{stream.h → libgit2/stream.h} +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/mbedtls.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/openssl.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_legacy.c +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_legacy.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/registry.c +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/registry.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/socket.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/stransport.c +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/stransport.h +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/tls.c +0 -0
- /data/vendor/libgit2/src/{streams → libgit2/streams}/tls.h +0 -0
- /data/vendor/libgit2/src/{transaction.h → libgit2/transaction.h} +0 -0
- /data/vendor/libgit2/src/{transports → libgit2/transports}/auth_negotiate.h +0 -0
- /data/vendor/libgit2/src/{transports → libgit2/transports}/credential.c +0 -0
- /data/vendor/libgit2/src/{transports → libgit2/transports}/credential_helpers.c +0 -0
- /data/vendor/libgit2/src/{transports → libgit2/transports}/ssh.h +0 -0
- /data/vendor/libgit2/src/{userdiff.h → libgit2/userdiff.h} +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xdiffi.h +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xemit.h +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xmacros.h +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xprepare.h +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xtypes.h +0 -0
- /data/vendor/libgit2/src/{xdiff → libgit2/xdiff}/xutils.h +0 -0
- /data/vendor/libgit2/src/{alloc.c → util/alloc.c} +0 -0
- /data/vendor/libgit2/src/{alloc.h → util/alloc.h} +0 -0
- /data/vendor/libgit2/src/{allocators → util/allocators}/failalloc.c +0 -0
- /data/vendor/libgit2/src/{allocators → util/allocators}/stdalloc.c +0 -0
- /data/vendor/libgit2/src/{allocators → util/allocators}/win32_leakcheck.c +0 -0
- /data/vendor/libgit2/src/{bitvec.h → util/bitvec.h} +0 -0
- /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/sha1.h +0 -0
- /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/ubc_check.c +0 -0
- /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/ubc_check.h +0 -0
- /data/vendor/libgit2/src/{integer.h → util/integer.h} +0 -0
- /data/vendor/libgit2/src/{pool.c → util/pool.c} +0 -0
- /data/vendor/libgit2/src/{pqueue.c → util/pqueue.c} +0 -0
- /data/vendor/libgit2/src/{strmap.c → util/strmap.c} +0 -0
- /data/vendor/libgit2/src/{strnlen.h → util/strnlen.h} +0 -0
- /data/vendor/libgit2/src/{unix → util/unix}/pthread.h +0 -0
- /data/vendor/libgit2/src/{varint.c → util/varint.c} +0 -0
- /data/vendor/libgit2/src/{vector.c → util/vector.c} +0 -0
- /data/vendor/libgit2/src/{wildmatch.c → util/wildmatch.c} +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/dir.c +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/error.c +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/mingw-compat.h +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/msvc-compat.h +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/reparse.h +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/thread.c +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/utf-conv.c +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/version.h +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/w32_common.h +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/w32_util.c +0 -0
- /data/vendor/libgit2/src/{win32 → util/win32}/win32-compat.h +0 -0
@@ -5,10 +5,11 @@
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
6
6
|
*/
|
7
7
|
|
8
|
-
#include "
|
8
|
+
#include "fs_path.h"
|
9
9
|
|
10
|
+
#include "git2_util.h"
|
11
|
+
#include "futils.h"
|
10
12
|
#include "posix.h"
|
11
|
-
#include "repository.h"
|
12
13
|
#ifdef GIT_WIN32
|
13
14
|
#include "win32/posix.h"
|
14
15
|
#include "win32/w32_buffer.h"
|
@@ -21,6 +22,13 @@
|
|
21
22
|
#include <stdio.h>
|
22
23
|
#include <ctype.h>
|
23
24
|
|
25
|
+
#define ensure_error_set(code) do { \
|
26
|
+
const git_error *e = git_error_last(); \
|
27
|
+
if (!e || !e->message) \
|
28
|
+
git_error_set(e ? e->klass : GIT_ERROR_CALLBACK, \
|
29
|
+
"filesystem callback returned %d", code); \
|
30
|
+
} while(0)
|
31
|
+
|
24
32
|
static int dos_drive_prefix_length(const char *path)
|
25
33
|
{
|
26
34
|
int i;
|
@@ -93,7 +101,7 @@ static bool looks_like_network_computer_name(const char *path, int pos)
|
|
93
101
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
94
102
|
* SUCH DAMAGE.
|
95
103
|
*/
|
96
|
-
int
|
104
|
+
int git_fs_path_basename_r(git_str *buffer, const char *path)
|
97
105
|
{
|
98
106
|
const char *endp, *startp;
|
99
107
|
int len, result;
|
@@ -101,7 +109,7 @@ int git_path_basename_r(git_buf *buffer, const char *path)
|
|
101
109
|
/* Empty or NULL string gets treated as "." */
|
102
110
|
if (path == NULL || *path == '\0') {
|
103
111
|
startp = ".";
|
104
|
-
len
|
112
|
+
len = 1;
|
105
113
|
goto Exit;
|
106
114
|
}
|
107
115
|
|
@@ -113,7 +121,7 @@ int git_path_basename_r(git_buf *buffer, const char *path)
|
|
113
121
|
/* All slashes becomes "/" */
|
114
122
|
if (endp == path && *endp == '/') {
|
115
123
|
startp = "/";
|
116
|
-
len
|
124
|
+
len = 1;
|
117
125
|
goto Exit;
|
118
126
|
}
|
119
127
|
|
@@ -128,7 +136,7 @@ int git_path_basename_r(git_buf *buffer, const char *path)
|
|
128
136
|
Exit:
|
129
137
|
result = len;
|
130
138
|
|
131
|
-
if (buffer != NULL &&
|
139
|
+
if (buffer != NULL && git_str_set(buffer, startp, len) < 0)
|
132
140
|
return -1;
|
133
141
|
|
134
142
|
return result;
|
@@ -136,7 +144,7 @@ Exit:
|
|
136
144
|
|
137
145
|
/*
|
138
146
|
* Determine if the path is a Windows prefix and, if so, returns
|
139
|
-
* its actual
|
147
|
+
* its actual length. If it is not a prefix, returns -1.
|
140
148
|
*/
|
141
149
|
static int win32_prefix_length(const char *path, int len)
|
142
150
|
{
|
@@ -166,7 +174,7 @@ static int win32_prefix_length(const char *path, int len)
|
|
166
174
|
* Based on the Android implementation, BSD licensed.
|
167
175
|
* Check http://android.git.kernel.org/
|
168
176
|
*/
|
169
|
-
int
|
177
|
+
int git_fs_path_dirname_r(git_str *buffer, const char *path)
|
170
178
|
{
|
171
179
|
const char *endp;
|
172
180
|
int is_prefix = 0, len;
|
@@ -185,8 +193,7 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
|
|
185
193
|
|
186
194
|
if (endp - path + 1 > INT_MAX) {
|
187
195
|
git_error_set(GIT_ERROR_INVALID, "path too long");
|
188
|
-
|
189
|
-
goto Exit;
|
196
|
+
return -1;
|
190
197
|
}
|
191
198
|
|
192
199
|
if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) {
|
@@ -211,8 +218,7 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
|
|
211
218
|
|
212
219
|
if (endp - path + 1 > INT_MAX) {
|
213
220
|
git_error_set(GIT_ERROR_INVALID, "path too long");
|
214
|
-
|
215
|
-
goto Exit;
|
221
|
+
return -1;
|
216
222
|
}
|
217
223
|
|
218
224
|
if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) {
|
@@ -225,9 +231,9 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
|
|
225
231
|
|
226
232
|
Exit:
|
227
233
|
if (buffer) {
|
228
|
-
if (
|
234
|
+
if (git_str_set(buffer, path, len) < 0)
|
229
235
|
return -1;
|
230
|
-
if (is_prefix &&
|
236
|
+
if (is_prefix && git_str_putc(buffer, '/') < 0)
|
231
237
|
return -1;
|
232
238
|
}
|
233
239
|
|
@@ -235,38 +241,38 @@ Exit:
|
|
235
241
|
}
|
236
242
|
|
237
243
|
|
238
|
-
char *
|
244
|
+
char *git_fs_path_dirname(const char *path)
|
239
245
|
{
|
240
|
-
|
246
|
+
git_str buf = GIT_STR_INIT;
|
241
247
|
char *dirname;
|
242
248
|
|
243
|
-
|
244
|
-
dirname =
|
245
|
-
|
249
|
+
git_fs_path_dirname_r(&buf, path);
|
250
|
+
dirname = git_str_detach(&buf);
|
251
|
+
git_str_dispose(&buf); /* avoid memleak if error occurs */
|
246
252
|
|
247
253
|
return dirname;
|
248
254
|
}
|
249
255
|
|
250
|
-
char *
|
256
|
+
char *git_fs_path_basename(const char *path)
|
251
257
|
{
|
252
|
-
|
258
|
+
git_str buf = GIT_STR_INIT;
|
253
259
|
char *basename;
|
254
260
|
|
255
|
-
|
256
|
-
basename =
|
257
|
-
|
261
|
+
git_fs_path_basename_r(&buf, path);
|
262
|
+
basename = git_str_detach(&buf);
|
263
|
+
git_str_dispose(&buf); /* avoid memleak if error occurs */
|
258
264
|
|
259
265
|
return basename;
|
260
266
|
}
|
261
267
|
|
262
|
-
size_t
|
268
|
+
size_t git_fs_path_basename_offset(git_str *buffer)
|
263
269
|
{
|
264
270
|
ssize_t slash;
|
265
271
|
|
266
272
|
if (!buffer || buffer->size <= 0)
|
267
273
|
return 0;
|
268
274
|
|
269
|
-
slash =
|
275
|
+
slash = git_str_rfind_next(buffer, '/');
|
270
276
|
|
271
277
|
if (slash >= 0 && buffer->ptr[slash] == '/')
|
272
278
|
return (size_t)(slash + 1);
|
@@ -274,7 +280,7 @@ size_t git_path_basename_offset(git_buf *buffer)
|
|
274
280
|
return 0;
|
275
281
|
}
|
276
282
|
|
277
|
-
int
|
283
|
+
int git_fs_path_root(const char *path)
|
278
284
|
{
|
279
285
|
int offset = 0, prefix_len;
|
280
286
|
|
@@ -304,9 +310,9 @@ int git_path_root(const char *path)
|
|
304
310
|
return -1; /* Not a real error - signals that path is not rooted */
|
305
311
|
}
|
306
312
|
|
307
|
-
static void path_trim_slashes(
|
313
|
+
static void path_trim_slashes(git_str *path)
|
308
314
|
{
|
309
|
-
int ceiling =
|
315
|
+
int ceiling = git_fs_path_root(path->ptr) + 1;
|
310
316
|
|
311
317
|
if (ceiling < 0)
|
312
318
|
return;
|
@@ -320,29 +326,29 @@ static void path_trim_slashes(git_buf *path)
|
|
320
326
|
}
|
321
327
|
}
|
322
328
|
|
323
|
-
int
|
324
|
-
|
329
|
+
int git_fs_path_join_unrooted(
|
330
|
+
git_str *path_out, const char *path, const char *base, ssize_t *root_at)
|
325
331
|
{
|
326
332
|
ssize_t root;
|
327
333
|
|
328
334
|
GIT_ASSERT_ARG(path_out);
|
329
335
|
GIT_ASSERT_ARG(path);
|
330
336
|
|
331
|
-
root = (ssize_t)
|
337
|
+
root = (ssize_t)git_fs_path_root(path);
|
332
338
|
|
333
339
|
if (base != NULL && root < 0) {
|
334
|
-
if (
|
340
|
+
if (git_str_joinpath(path_out, base, path) < 0)
|
335
341
|
return -1;
|
336
342
|
|
337
343
|
root = (ssize_t)strlen(base);
|
338
344
|
} else {
|
339
|
-
if (
|
345
|
+
if (git_str_sets(path_out, path) < 0)
|
340
346
|
return -1;
|
341
347
|
|
342
348
|
if (root < 0)
|
343
349
|
root = 0;
|
344
350
|
else if (base)
|
345
|
-
|
351
|
+
git_fs_path_equal_or_prefixed(base, path, &root);
|
346
352
|
}
|
347
353
|
|
348
354
|
if (root_at)
|
@@ -351,7 +357,7 @@ int git_path_join_unrooted(
|
|
351
357
|
return 0;
|
352
358
|
}
|
353
359
|
|
354
|
-
void
|
360
|
+
void git_fs_path_squash_slashes(git_str *path)
|
355
361
|
{
|
356
362
|
char *p, *q;
|
357
363
|
|
@@ -370,7 +376,7 @@ void git_path_squash_slashes(git_buf *path)
|
|
370
376
|
*p = '\0';
|
371
377
|
}
|
372
378
|
|
373
|
-
int
|
379
|
+
int git_fs_path_prettify(git_str *path_out, const char *path, const char *base)
|
374
380
|
{
|
375
381
|
char buf[GIT_PATH_MAX];
|
376
382
|
|
@@ -378,8 +384,8 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base)
|
|
378
384
|
GIT_ASSERT_ARG(path);
|
379
385
|
|
380
386
|
/* construct path if needed */
|
381
|
-
if (base != NULL &&
|
382
|
-
if (
|
387
|
+
if (base != NULL && git_fs_path_root(path) < 0) {
|
388
|
+
if (git_str_joinpath(path_out, base, path) < 0)
|
383
389
|
return -1;
|
384
390
|
path = path_out->ptr;
|
385
391
|
}
|
@@ -389,31 +395,31 @@ int git_path_prettify(git_buf *path_out, const char *path, const char *base)
|
|
389
395
|
int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1;
|
390
396
|
git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path);
|
391
397
|
|
392
|
-
|
398
|
+
git_str_clear(path_out);
|
393
399
|
|
394
400
|
return error;
|
395
401
|
}
|
396
402
|
|
397
|
-
return
|
403
|
+
return git_str_sets(path_out, buf);
|
398
404
|
}
|
399
405
|
|
400
|
-
int
|
406
|
+
int git_fs_path_prettify_dir(git_str *path_out, const char *path, const char *base)
|
401
407
|
{
|
402
|
-
int error =
|
403
|
-
return (error < 0) ? error :
|
408
|
+
int error = git_fs_path_prettify(path_out, path, base);
|
409
|
+
return (error < 0) ? error : git_fs_path_to_dir(path_out);
|
404
410
|
}
|
405
411
|
|
406
|
-
int
|
412
|
+
int git_fs_path_to_dir(git_str *path)
|
407
413
|
{
|
408
414
|
if (path->asize > 0 &&
|
409
|
-
|
410
|
-
path->ptr[
|
411
|
-
|
415
|
+
git_str_len(path) > 0 &&
|
416
|
+
path->ptr[git_str_len(path) - 1] != '/')
|
417
|
+
git_str_putc(path, '/');
|
412
418
|
|
413
|
-
return
|
419
|
+
return git_str_oom(path) ? -1 : 0;
|
414
420
|
}
|
415
421
|
|
416
|
-
void
|
422
|
+
void git_fs_path_string_to_dir(char *path, size_t size)
|
417
423
|
{
|
418
424
|
size_t end = strlen(path);
|
419
425
|
|
@@ -423,7 +429,7 @@ void git_path_string_to_dir(char *path, size_t size)
|
|
423
429
|
}
|
424
430
|
}
|
425
431
|
|
426
|
-
int git__percent_decode(
|
432
|
+
int git__percent_decode(git_str *decoded_out, const char *input)
|
427
433
|
{
|
428
434
|
int len, hi, lo, i;
|
429
435
|
|
@@ -431,7 +437,7 @@ int git__percent_decode(git_buf *decoded_out, const char *input)
|
|
431
437
|
GIT_ASSERT_ARG(input);
|
432
438
|
|
433
439
|
len = (int)strlen(input);
|
434
|
-
|
440
|
+
git_str_clear(decoded_out);
|
435
441
|
|
436
442
|
for(i = 0; i < len; i++)
|
437
443
|
{
|
@@ -453,7 +459,7 @@ int git__percent_decode(git_buf *decoded_out, const char *input)
|
|
453
459
|
i += 2;
|
454
460
|
|
455
461
|
append:
|
456
|
-
if (
|
462
|
+
if (git_str_putc(decoded_out, c) < 0)
|
457
463
|
return -1;
|
458
464
|
}
|
459
465
|
|
@@ -480,12 +486,12 @@ static int local_file_url_prefixlen(const char *file_url)
|
|
480
486
|
return len;
|
481
487
|
}
|
482
488
|
|
483
|
-
bool
|
489
|
+
bool git_fs_path_is_local_file_url(const char *file_url)
|
484
490
|
{
|
485
491
|
return (local_file_url_prefixlen(file_url) > 0);
|
486
492
|
}
|
487
493
|
|
488
|
-
int
|
494
|
+
int git_fs_path_fromurl(git_str *local_path_out, const char *file_url)
|
489
495
|
{
|
490
496
|
int offset;
|
491
497
|
|
@@ -500,18 +506,18 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
|
|
500
506
|
offset--; /* A *nix absolute path starts with a forward slash */
|
501
507
|
#endif
|
502
508
|
|
503
|
-
|
509
|
+
git_str_clear(local_path_out);
|
504
510
|
return git__percent_decode(local_path_out, file_url + offset);
|
505
511
|
}
|
506
512
|
|
507
|
-
int
|
508
|
-
|
513
|
+
int git_fs_path_walk_up(
|
514
|
+
git_str *path,
|
509
515
|
const char *ceiling,
|
510
516
|
int (*cb)(void *data, const char *),
|
511
517
|
void *data)
|
512
518
|
{
|
513
519
|
int error = 0;
|
514
|
-
|
520
|
+
git_str iter;
|
515
521
|
ssize_t stop = 0, scan;
|
516
522
|
char oldc = '\0';
|
517
523
|
|
@@ -522,20 +528,20 @@ int git_path_walk_up(
|
|
522
528
|
if (git__prefixcmp(path->ptr, ceiling) == 0)
|
523
529
|
stop = (ssize_t)strlen(ceiling);
|
524
530
|
else
|
525
|
-
stop =
|
531
|
+
stop = git_str_len(path);
|
526
532
|
}
|
527
|
-
scan =
|
533
|
+
scan = git_str_len(path);
|
528
534
|
|
529
535
|
/* empty path: yield only once */
|
530
536
|
if (!scan) {
|
531
537
|
error = cb(data, "");
|
532
538
|
if (error)
|
533
|
-
|
539
|
+
ensure_error_set(error);
|
534
540
|
return error;
|
535
541
|
}
|
536
542
|
|
537
543
|
iter.ptr = path->ptr;
|
538
|
-
iter.size =
|
544
|
+
iter.size = git_str_len(path);
|
539
545
|
iter.asize = path->asize;
|
540
546
|
|
541
547
|
while (scan >= stop) {
|
@@ -543,11 +549,11 @@ int git_path_walk_up(
|
|
543
549
|
iter.ptr[scan] = oldc;
|
544
550
|
|
545
551
|
if (error) {
|
546
|
-
|
552
|
+
ensure_error_set(error);
|
547
553
|
break;
|
548
554
|
}
|
549
555
|
|
550
|
-
scan =
|
556
|
+
scan = git_str_rfind_next(&iter, '/');
|
551
557
|
if (scan >= 0) {
|
552
558
|
scan++;
|
553
559
|
oldc = iter.ptr[scan];
|
@@ -563,19 +569,19 @@ int git_path_walk_up(
|
|
563
569
|
if (!error && stop == 0 && iter.ptr[0] != '/') {
|
564
570
|
error = cb(data, "");
|
565
571
|
if (error)
|
566
|
-
|
572
|
+
ensure_error_set(error);
|
567
573
|
}
|
568
574
|
|
569
575
|
return error;
|
570
576
|
}
|
571
577
|
|
572
|
-
bool
|
578
|
+
bool git_fs_path_exists(const char *path)
|
573
579
|
{
|
574
580
|
GIT_ASSERT_ARG_WITH_RETVAL(path, false);
|
575
581
|
return p_access(path, F_OK) == 0;
|
576
582
|
}
|
577
583
|
|
578
|
-
bool
|
584
|
+
bool git_fs_path_isdir(const char *path)
|
579
585
|
{
|
580
586
|
struct stat st;
|
581
587
|
if (p_stat(path, &st) < 0)
|
@@ -584,7 +590,7 @@ bool git_path_isdir(const char *path)
|
|
584
590
|
return S_ISDIR(st.st_mode) != 0;
|
585
591
|
}
|
586
592
|
|
587
|
-
bool
|
593
|
+
bool git_fs_path_isfile(const char *path)
|
588
594
|
{
|
589
595
|
struct stat st;
|
590
596
|
|
@@ -595,7 +601,7 @@ bool git_path_isfile(const char *path)
|
|
595
601
|
return S_ISREG(st.st_mode) != 0;
|
596
602
|
}
|
597
603
|
|
598
|
-
bool
|
604
|
+
bool git_fs_path_islink(const char *path)
|
599
605
|
{
|
600
606
|
struct stat st;
|
601
607
|
|
@@ -608,7 +614,7 @@ bool git_path_islink(const char *path)
|
|
608
614
|
|
609
615
|
#ifdef GIT_WIN32
|
610
616
|
|
611
|
-
bool
|
617
|
+
bool git_fs_path_is_empty_dir(const char *path)
|
612
618
|
{
|
613
619
|
git_win32_path filter_w;
|
614
620
|
bool empty = false;
|
@@ -627,7 +633,7 @@ bool git_path_is_empty_dir(const char *path)
|
|
627
633
|
* (a mount point).
|
628
634
|
*/
|
629
635
|
if (hFind == INVALID_HANDLE_VALUE)
|
630
|
-
return
|
636
|
+
return git_fs_path_isdir(path);
|
631
637
|
|
632
638
|
/* If the find handle was created successfully, then it's a directory */
|
633
639
|
empty = true;
|
@@ -637,7 +643,7 @@ bool git_path_is_empty_dir(const char *path)
|
|
637
643
|
* empty. In the special case of drive roots (i.e. C:\) where . and
|
638
644
|
* .. do not occur, we can still consider the path to be an empty
|
639
645
|
* directory if there's nothing there. */
|
640
|
-
if (!
|
646
|
+
if (!git_fs_path_is_dot_or_dotdotW(findData.cFileName)) {
|
641
647
|
empty = false;
|
642
648
|
break;
|
643
649
|
}
|
@@ -651,33 +657,33 @@ bool git_path_is_empty_dir(const char *path)
|
|
651
657
|
|
652
658
|
#else
|
653
659
|
|
654
|
-
static int path_found_entry(void *payload,
|
660
|
+
static int path_found_entry(void *payload, git_str *path)
|
655
661
|
{
|
656
662
|
GIT_UNUSED(payload);
|
657
|
-
return !
|
663
|
+
return !git_fs_path_is_dot_or_dotdot(path->ptr);
|
658
664
|
}
|
659
665
|
|
660
|
-
bool
|
666
|
+
bool git_fs_path_is_empty_dir(const char *path)
|
661
667
|
{
|
662
668
|
int error;
|
663
|
-
|
669
|
+
git_str dir = GIT_STR_INIT;
|
664
670
|
|
665
|
-
if (!
|
671
|
+
if (!git_fs_path_isdir(path))
|
666
672
|
return false;
|
667
673
|
|
668
|
-
if ((error =
|
674
|
+
if ((error = git_str_sets(&dir, path)) != 0)
|
669
675
|
git_error_clear();
|
670
676
|
else
|
671
|
-
error =
|
677
|
+
error = git_fs_path_direach(&dir, 0, path_found_entry, NULL);
|
672
678
|
|
673
|
-
|
679
|
+
git_str_dispose(&dir);
|
674
680
|
|
675
681
|
return !error;
|
676
682
|
}
|
677
683
|
|
678
684
|
#endif
|
679
685
|
|
680
|
-
int
|
686
|
+
int git_fs_path_set_error(int errno_value, const char *path, const char *action)
|
681
687
|
{
|
682
688
|
switch (errno_value) {
|
683
689
|
case ENOENT:
|
@@ -704,87 +710,87 @@ int git_path_set_error(int errno_value, const char *path, const char *action)
|
|
704
710
|
}
|
705
711
|
}
|
706
712
|
|
707
|
-
int
|
713
|
+
int git_fs_path_lstat(const char *path, struct stat *st)
|
708
714
|
{
|
709
715
|
if (p_lstat(path, st) == 0)
|
710
716
|
return 0;
|
711
717
|
|
712
|
-
return
|
718
|
+
return git_fs_path_set_error(errno, path, "stat");
|
713
719
|
}
|
714
720
|
|
715
721
|
static bool _check_dir_contents(
|
716
|
-
|
722
|
+
git_str *dir,
|
717
723
|
const char *sub,
|
718
724
|
bool (*predicate)(const char *))
|
719
725
|
{
|
720
726
|
bool result;
|
721
|
-
size_t dir_size =
|
727
|
+
size_t dir_size = git_str_len(dir);
|
722
728
|
size_t sub_size = strlen(sub);
|
723
729
|
size_t alloc_size;
|
724
730
|
|
725
731
|
/* leave base valid even if we could not make space for subdir */
|
726
732
|
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
|
727
733
|
GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
|
728
|
-
|
734
|
+
git_str_try_grow(dir, alloc_size, false) < 0)
|
729
735
|
return false;
|
730
736
|
|
731
737
|
/* save excursion */
|
732
|
-
if (
|
738
|
+
if (git_str_joinpath(dir, dir->ptr, sub) < 0)
|
733
739
|
return false;
|
734
740
|
|
735
741
|
result = predicate(dir->ptr);
|
736
742
|
|
737
743
|
/* restore path */
|
738
|
-
|
744
|
+
git_str_truncate(dir, dir_size);
|
739
745
|
return result;
|
740
746
|
}
|
741
747
|
|
742
|
-
bool
|
748
|
+
bool git_fs_path_contains(git_str *dir, const char *item)
|
743
749
|
{
|
744
|
-
return _check_dir_contents(dir, item, &
|
750
|
+
return _check_dir_contents(dir, item, &git_fs_path_exists);
|
745
751
|
}
|
746
752
|
|
747
|
-
bool
|
753
|
+
bool git_fs_path_contains_dir(git_str *base, const char *subdir)
|
748
754
|
{
|
749
|
-
return _check_dir_contents(base, subdir, &
|
755
|
+
return _check_dir_contents(base, subdir, &git_fs_path_isdir);
|
750
756
|
}
|
751
757
|
|
752
|
-
bool
|
758
|
+
bool git_fs_path_contains_file(git_str *base, const char *file)
|
753
759
|
{
|
754
|
-
return _check_dir_contents(base, file, &
|
760
|
+
return _check_dir_contents(base, file, &git_fs_path_isfile);
|
755
761
|
}
|
756
762
|
|
757
|
-
int
|
763
|
+
int git_fs_path_find_dir(git_str *dir)
|
758
764
|
{
|
759
765
|
int error = 0;
|
760
766
|
char buf[GIT_PATH_MAX];
|
761
767
|
|
762
768
|
if (p_realpath(dir->ptr, buf) != NULL)
|
763
|
-
error =
|
769
|
+
error = git_str_sets(dir, buf);
|
764
770
|
|
765
771
|
/* call dirname if this is not a directory */
|
766
|
-
if (!error) /* &&
|
767
|
-
error = (
|
772
|
+
if (!error) /* && git_fs_path_isdir(dir->ptr) == false) */
|
773
|
+
error = (git_fs_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0;
|
768
774
|
|
769
775
|
if (!error)
|
770
|
-
error =
|
776
|
+
error = git_fs_path_to_dir(dir);
|
771
777
|
|
772
778
|
return error;
|
773
779
|
}
|
774
780
|
|
775
|
-
int
|
781
|
+
int git_fs_path_resolve_relative(git_str *path, size_t ceiling)
|
776
782
|
{
|
777
783
|
char *base, *to, *from, *next;
|
778
784
|
size_t len;
|
779
785
|
|
780
|
-
|
786
|
+
GIT_ERROR_CHECK_ALLOC_STR(path);
|
781
787
|
|
782
788
|
if (ceiling > path->size)
|
783
789
|
ceiling = path->size;
|
784
790
|
|
785
791
|
/* recognize drive prefixes, etc. that should not be backed over */
|
786
792
|
if (ceiling == 0)
|
787
|
-
ceiling =
|
793
|
+
ceiling = git_fs_path_root(path->ptr) + 1;
|
788
794
|
|
789
795
|
/* recognize URL prefixes that should not be backed over */
|
790
796
|
if (ceiling == 0) {
|
@@ -851,13 +857,13 @@ int git_path_resolve_relative(git_buf *path, size_t ceiling)
|
|
851
857
|
return 0;
|
852
858
|
}
|
853
859
|
|
854
|
-
int
|
860
|
+
int git_fs_path_apply_relative(git_str *target, const char *relpath)
|
855
861
|
{
|
856
|
-
return
|
857
|
-
|
862
|
+
return git_str_joinpath(target, git_str_cstr(target), relpath) ||
|
863
|
+
git_fs_path_resolve_relative(target, 0);
|
858
864
|
}
|
859
865
|
|
860
|
-
int
|
866
|
+
int git_fs_path_cmp(
|
861
867
|
const char *name1, size_t len1, int isdir1,
|
862
868
|
const char *name2, size_t len2, int isdir2,
|
863
869
|
int (*compare)(const char *, const char *, size_t))
|
@@ -882,7 +888,7 @@ int git_path_cmp(
|
|
882
888
|
return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
|
883
889
|
}
|
884
890
|
|
885
|
-
size_t
|
891
|
+
size_t git_fs_path_common_dirlen(const char *one, const char *two)
|
886
892
|
{
|
887
893
|
const char *p, *q, *dirsep = NULL;
|
888
894
|
|
@@ -896,7 +902,7 @@ size_t git_path_common_dirlen(const char *one, const char *two)
|
|
896
902
|
return dirsep ? (dirsep - one) + 1 : 0;
|
897
903
|
}
|
898
904
|
|
899
|
-
int
|
905
|
+
int git_fs_path_make_relative(git_str *path, const char *parent)
|
900
906
|
{
|
901
907
|
const char *p, *q, *p_dirsep, *q_dirsep;
|
902
908
|
size_t plen = path->size, newlen, alloclen, depth = 1, i, offset;
|
@@ -923,7 +929,7 @@ int git_path_make_relative(git_buf *path, const char *parent)
|
|
923
929
|
else if (!*p && *q == '/')
|
924
930
|
q++;
|
925
931
|
else if (!*p && !*q)
|
926
|
-
return
|
932
|
+
return git_str_clear(path), 0;
|
927
933
|
else {
|
928
934
|
p = p_dirsep + 1;
|
929
935
|
q = q_dirsep + 1;
|
@@ -932,7 +938,7 @@ int git_path_make_relative(git_buf *path, const char *parent)
|
|
932
938
|
plen -= (p - path->ptr);
|
933
939
|
|
934
940
|
if (!*q)
|
935
|
-
return
|
941
|
+
return git_str_set(path, p, plen);
|
936
942
|
|
937
943
|
for (; (q = strchr(q, '/')) && *(q + 1); q++)
|
938
944
|
depth++;
|
@@ -944,7 +950,7 @@ int git_path_make_relative(git_buf *path, const char *parent)
|
|
944
950
|
|
945
951
|
/* save the offset as we might realllocate the pointer */
|
946
952
|
offset = p - path->ptr;
|
947
|
-
if (
|
953
|
+
if (git_str_try_grow(path, alloclen, 1) < 0)
|
948
954
|
return -1;
|
949
955
|
p = path->ptr + offset;
|
950
956
|
|
@@ -957,7 +963,7 @@ int git_path_make_relative(git_buf *path, const char *parent)
|
|
957
963
|
return 0;
|
958
964
|
}
|
959
965
|
|
960
|
-
bool
|
966
|
+
bool git_fs_path_has_non_ascii(const char *path, size_t pathlen)
|
961
967
|
{
|
962
968
|
const uint8_t *scan = (const uint8_t *)path, *end;
|
963
969
|
|
@@ -970,37 +976,37 @@ bool git_path_has_non_ascii(const char *path, size_t pathlen)
|
|
970
976
|
|
971
977
|
#ifdef GIT_USE_ICONV
|
972
978
|
|
973
|
-
int
|
979
|
+
int git_fs_path_iconv_init_precompose(git_fs_path_iconv_t *ic)
|
974
980
|
{
|
975
|
-
|
981
|
+
git_str_init(&ic->buf, 0);
|
976
982
|
ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING);
|
977
983
|
return 0;
|
978
984
|
}
|
979
985
|
|
980
|
-
void
|
986
|
+
void git_fs_path_iconv_clear(git_fs_path_iconv_t *ic)
|
981
987
|
{
|
982
988
|
if (ic) {
|
983
989
|
if (ic->map != (iconv_t)-1)
|
984
990
|
iconv_close(ic->map);
|
985
|
-
|
991
|
+
git_str_dispose(&ic->buf);
|
986
992
|
}
|
987
993
|
}
|
988
994
|
|
989
|
-
int
|
995
|
+
int git_fs_path_iconv(git_fs_path_iconv_t *ic, const char **in, size_t *inlen)
|
990
996
|
{
|
991
997
|
char *nfd = (char*)*in, *nfc;
|
992
998
|
size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv;
|
993
999
|
int retry = 1;
|
994
1000
|
|
995
1001
|
if (!ic || ic->map == (iconv_t)-1 ||
|
996
|
-
!
|
1002
|
+
!git_fs_path_has_non_ascii(*in, *inlen))
|
997
1003
|
return 0;
|
998
1004
|
|
999
|
-
|
1005
|
+
git_str_clear(&ic->buf);
|
1000
1006
|
|
1001
1007
|
while (1) {
|
1002
1008
|
GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1);
|
1003
|
-
if (
|
1009
|
+
if (git_str_grow(&ic->buf, alloclen) < 0)
|
1004
1010
|
return -1;
|
1005
1011
|
|
1006
1012
|
nfc = ic->buf.ptr + ic->buf.size;
|
@@ -1040,8 +1046,8 @@ fail:
|
|
1040
1046
|
return -1;
|
1041
1047
|
}
|
1042
1048
|
|
1043
|
-
static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D
|
1044
|
-
static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D
|
1049
|
+
static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D";
|
1050
|
+
static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D";
|
1045
1051
|
|
1046
1052
|
/* Check if the platform is decomposing unicode data for us. We will
|
1047
1053
|
* emulate core Git and prefer to use precomposed unicode data internally
|
@@ -1052,47 +1058,50 @@ static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX";
|
|
1052
1058
|
* return decomposed unicode from readdir() even when the actual
|
1053
1059
|
* filesystem is storing precomposed unicode.
|
1054
1060
|
*/
|
1055
|
-
bool
|
1061
|
+
bool git_fs_path_does_decompose_unicode(const char *root)
|
1056
1062
|
{
|
1057
|
-
|
1063
|
+
git_str nfc_path = GIT_STR_INIT;
|
1064
|
+
git_str nfd_path = GIT_STR_INIT;
|
1058
1065
|
int fd;
|
1059
1066
|
bool found_decomposed = false;
|
1060
|
-
|
1067
|
+
size_t orig_len;
|
1068
|
+
const char *trailer;
|
1061
1069
|
|
1062
1070
|
/* Create a file using a precomposed path and then try to find it
|
1063
1071
|
* using the decomposed name. If the lookup fails, then we will mark
|
1064
1072
|
* that we should precompose unicode for this repository.
|
1065
1073
|
*/
|
1066
|
-
if (
|
1067
|
-
|
1074
|
+
if (git_str_joinpath(&nfc_path, root, nfc_file) < 0)
|
1075
|
+
goto done;
|
1076
|
+
|
1077
|
+
/* record original path length before trailer */
|
1078
|
+
orig_len = nfc_path.size;
|
1079
|
+
|
1080
|
+
if ((fd = git_futils_mktmp(&nfc_path, nfc_path.ptr, 0666)) < 0)
|
1068
1081
|
goto done;
|
1069
1082
|
p_close(fd);
|
1070
1083
|
|
1071
|
-
|
1072
|
-
memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp));
|
1084
|
+
trailer = nfc_path.ptr + orig_len;
|
1073
1085
|
|
1074
1086
|
/* try to look up as NFD path */
|
1075
|
-
if (
|
1087
|
+
if (git_str_joinpath(&nfd_path, root, nfd_file) < 0 ||
|
1088
|
+
git_str_puts(&nfd_path, trailer) < 0)
|
1076
1089
|
goto done;
|
1077
|
-
memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
|
1078
1090
|
|
1079
|
-
found_decomposed =
|
1091
|
+
found_decomposed = git_fs_path_exists(nfd_path.ptr);
|
1080
1092
|
|
1081
1093
|
/* remove temporary file (using original precomposed path) */
|
1082
|
-
|
1083
|
-
goto done;
|
1084
|
-
memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
|
1085
|
-
|
1086
|
-
(void)p_unlink(path.ptr);
|
1094
|
+
(void)p_unlink(nfc_path.ptr);
|
1087
1095
|
|
1088
1096
|
done:
|
1089
|
-
|
1097
|
+
git_str_dispose(&nfc_path);
|
1098
|
+
git_str_dispose(&nfd_path);
|
1090
1099
|
return found_decomposed;
|
1091
1100
|
}
|
1092
1101
|
|
1093
1102
|
#else
|
1094
1103
|
|
1095
|
-
bool
|
1104
|
+
bool git_fs_path_does_decompose_unicode(const char *root)
|
1096
1105
|
{
|
1097
1106
|
GIT_UNUSED(root);
|
1098
1107
|
return false;
|
@@ -1106,10 +1115,10 @@ typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1];
|
|
1106
1115
|
typedef struct dirent path_dirent_data;
|
1107
1116
|
#endif
|
1108
1117
|
|
1109
|
-
int
|
1110
|
-
|
1118
|
+
int git_fs_path_direach(
|
1119
|
+
git_str *path,
|
1111
1120
|
uint32_t flags,
|
1112
|
-
int (*fn)(void *,
|
1121
|
+
int (*fn)(void *, git_str *),
|
1113
1122
|
void *arg)
|
1114
1123
|
{
|
1115
1124
|
int error = 0;
|
@@ -1118,15 +1127,15 @@ int git_path_direach(
|
|
1118
1127
|
struct dirent *de;
|
1119
1128
|
|
1120
1129
|
#ifdef GIT_USE_ICONV
|
1121
|
-
|
1130
|
+
git_fs_path_iconv_t ic = GIT_PATH_ICONV_INIT;
|
1122
1131
|
#endif
|
1123
1132
|
|
1124
1133
|
GIT_UNUSED(flags);
|
1125
1134
|
|
1126
|
-
if (
|
1135
|
+
if (git_fs_path_to_dir(path) < 0)
|
1127
1136
|
return -1;
|
1128
1137
|
|
1129
|
-
wd_len =
|
1138
|
+
wd_len = git_str_len(path);
|
1130
1139
|
|
1131
1140
|
if ((dir = opendir(path->ptr)) == NULL) {
|
1132
1141
|
git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr);
|
@@ -1137,34 +1146,34 @@ int git_path_direach(
|
|
1137
1146
|
}
|
1138
1147
|
|
1139
1148
|
#ifdef GIT_USE_ICONV
|
1140
|
-
if ((flags &
|
1141
|
-
(void)
|
1149
|
+
if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
|
1150
|
+
(void)git_fs_path_iconv_init_precompose(&ic);
|
1142
1151
|
#endif
|
1143
1152
|
|
1144
1153
|
while ((de = readdir(dir)) != NULL) {
|
1145
1154
|
const char *de_path = de->d_name;
|
1146
1155
|
size_t de_len = strlen(de_path);
|
1147
1156
|
|
1148
|
-
if (
|
1157
|
+
if (git_fs_path_is_dot_or_dotdot(de_path))
|
1149
1158
|
continue;
|
1150
1159
|
|
1151
1160
|
#ifdef GIT_USE_ICONV
|
1152
|
-
if ((error =
|
1161
|
+
if ((error = git_fs_path_iconv(&ic, &de_path, &de_len)) < 0)
|
1153
1162
|
break;
|
1154
1163
|
#endif
|
1155
1164
|
|
1156
|
-
if ((error =
|
1165
|
+
if ((error = git_str_put(path, de_path, de_len)) < 0)
|
1157
1166
|
break;
|
1158
1167
|
|
1159
1168
|
git_error_clear();
|
1160
1169
|
error = fn(arg, path);
|
1161
1170
|
|
1162
|
-
|
1171
|
+
git_str_truncate(path, wd_len); /* restore path */
|
1163
1172
|
|
1164
1173
|
/* Only set our own error if the callback did not set one already */
|
1165
1174
|
if (error != 0) {
|
1166
1175
|
if (!git_error_last())
|
1167
|
-
|
1176
|
+
ensure_error_set(error);
|
1168
1177
|
|
1169
1178
|
break;
|
1170
1179
|
}
|
@@ -1173,7 +1182,7 @@ int git_path_direach(
|
|
1173
1182
|
closedir(dir);
|
1174
1183
|
|
1175
1184
|
#ifdef GIT_USE_ICONV
|
1176
|
-
|
1185
|
+
git_fs_path_iconv_clear(&ic);
|
1177
1186
|
#endif
|
1178
1187
|
|
1179
1188
|
return error;
|
@@ -1188,8 +1197,8 @@ int git_path_direach(
|
|
1188
1197
|
# define FIND_FIRST_EX_LARGE_FETCH 2
|
1189
1198
|
#endif
|
1190
1199
|
|
1191
|
-
int
|
1192
|
-
|
1200
|
+
int git_fs_path_diriter_init(
|
1201
|
+
git_fs_path_diriter *diriter,
|
1193
1202
|
const char *path,
|
1194
1203
|
unsigned int flags)
|
1195
1204
|
{
|
@@ -1202,10 +1211,10 @@ int git_path_diriter_init(
|
|
1202
1211
|
GIT_ASSERT_ARG(diriter);
|
1203
1212
|
GIT_ASSERT_ARG(path);
|
1204
1213
|
|
1205
|
-
memset(diriter, 0, sizeof(
|
1214
|
+
memset(diriter, 0, sizeof(git_fs_path_diriter));
|
1206
1215
|
diriter->handle = INVALID_HANDLE_VALUE;
|
1207
1216
|
|
1208
|
-
if (
|
1217
|
+
if (git_str_puts(&diriter->path_utf8, path) < 0)
|
1209
1218
|
return -1;
|
1210
1219
|
|
1211
1220
|
path_trim_slashes(&diriter->path_utf8);
|
@@ -1239,7 +1248,7 @@ int git_path_diriter_init(
|
|
1239
1248
|
return 0;
|
1240
1249
|
}
|
1241
1250
|
|
1242
|
-
static int diriter_update_paths(
|
1251
|
+
static int diriter_update_paths(git_fs_path_diriter *diriter)
|
1243
1252
|
{
|
1244
1253
|
size_t filename_len, path_len;
|
1245
1254
|
|
@@ -1261,23 +1270,23 @@ static int diriter_update_paths(git_path_diriter *diriter)
|
|
1261
1270
|
diriter->current.cFileName, filename_len * sizeof(wchar_t));
|
1262
1271
|
diriter->path[path_len-1] = L'\0';
|
1263
1272
|
|
1264
|
-
|
1273
|
+
git_str_truncate(&diriter->path_utf8, diriter->parent_utf8_len);
|
1265
1274
|
|
1266
1275
|
if (diriter->parent_utf8_len > 0 &&
|
1267
1276
|
diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/')
|
1268
|
-
|
1277
|
+
git_str_putc(&diriter->path_utf8, '/');
|
1269
1278
|
|
1270
|
-
|
1279
|
+
git_str_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len);
|
1271
1280
|
|
1272
|
-
if (
|
1281
|
+
if (git_str_oom(&diriter->path_utf8))
|
1273
1282
|
return -1;
|
1274
1283
|
|
1275
1284
|
return 0;
|
1276
1285
|
}
|
1277
1286
|
|
1278
|
-
int
|
1287
|
+
int git_fs_path_diriter_next(git_fs_path_diriter *diriter)
|
1279
1288
|
{
|
1280
|
-
bool skip_dot = !(diriter->flags &
|
1289
|
+
bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
|
1281
1290
|
|
1282
1291
|
do {
|
1283
1292
|
/* Our first time through, we already have the data from
|
@@ -1287,7 +1296,7 @@ int git_path_diriter_next(git_path_diriter *diriter)
|
|
1287
1296
|
diriter->needs_next = 1;
|
1288
1297
|
else if (!FindNextFileW(diriter->handle, &diriter->current))
|
1289
1298
|
return GIT_ITEROVER;
|
1290
|
-
} while (skip_dot &&
|
1299
|
+
} while (skip_dot && git_fs_path_is_dot_or_dotdotW(diriter->current.cFileName));
|
1291
1300
|
|
1292
1301
|
if (diriter_update_paths(diriter) < 0)
|
1293
1302
|
return -1;
|
@@ -1295,10 +1304,10 @@ int git_path_diriter_next(git_path_diriter *diriter)
|
|
1295
1304
|
return 0;
|
1296
1305
|
}
|
1297
1306
|
|
1298
|
-
int
|
1307
|
+
int git_fs_path_diriter_filename(
|
1299
1308
|
const char **out,
|
1300
1309
|
size_t *out_len,
|
1301
|
-
|
1310
|
+
git_fs_path_diriter *diriter)
|
1302
1311
|
{
|
1303
1312
|
GIT_ASSERT_ARG(out);
|
1304
1313
|
GIT_ASSERT_ARG(out_len);
|
@@ -1310,10 +1319,10 @@ int git_path_diriter_filename(
|
|
1310
1319
|
return 0;
|
1311
1320
|
}
|
1312
1321
|
|
1313
|
-
int
|
1322
|
+
int git_fs_path_diriter_fullpath(
|
1314
1323
|
const char **out,
|
1315
1324
|
size_t *out_len,
|
1316
|
-
|
1325
|
+
git_fs_path_diriter *diriter)
|
1317
1326
|
{
|
1318
1327
|
GIT_ASSERT_ARG(out);
|
1319
1328
|
GIT_ASSERT_ARG(out_len);
|
@@ -1324,7 +1333,7 @@ int git_path_diriter_fullpath(
|
|
1324
1333
|
return 0;
|
1325
1334
|
}
|
1326
1335
|
|
1327
|
-
int
|
1336
|
+
int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter)
|
1328
1337
|
{
|
1329
1338
|
GIT_ASSERT_ARG(out);
|
1330
1339
|
GIT_ASSERT_ARG(diriter);
|
@@ -1334,12 +1343,12 @@ int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter)
|
|
1334
1343
|
diriter->path);
|
1335
1344
|
}
|
1336
1345
|
|
1337
|
-
void
|
1346
|
+
void git_fs_path_diriter_free(git_fs_path_diriter *diriter)
|
1338
1347
|
{
|
1339
1348
|
if (diriter == NULL)
|
1340
1349
|
return;
|
1341
1350
|
|
1342
|
-
|
1351
|
+
git_str_dispose(&diriter->path_utf8);
|
1343
1352
|
|
1344
1353
|
if (diriter->handle != INVALID_HANDLE_VALUE) {
|
1345
1354
|
FindClose(diriter->handle);
|
@@ -1349,17 +1358,17 @@ void git_path_diriter_free(git_path_diriter *diriter)
|
|
1349
1358
|
|
1350
1359
|
#else
|
1351
1360
|
|
1352
|
-
int
|
1353
|
-
|
1361
|
+
int git_fs_path_diriter_init(
|
1362
|
+
git_fs_path_diriter *diriter,
|
1354
1363
|
const char *path,
|
1355
1364
|
unsigned int flags)
|
1356
1365
|
{
|
1357
1366
|
GIT_ASSERT_ARG(diriter);
|
1358
1367
|
GIT_ASSERT_ARG(path);
|
1359
1368
|
|
1360
|
-
memset(diriter, 0, sizeof(
|
1369
|
+
memset(diriter, 0, sizeof(git_fs_path_diriter));
|
1361
1370
|
|
1362
|
-
if (
|
1371
|
+
if (git_str_puts(&diriter->path, path) < 0)
|
1363
1372
|
return -1;
|
1364
1373
|
|
1365
1374
|
path_trim_slashes(&diriter->path);
|
@@ -1370,15 +1379,15 @@ int git_path_diriter_init(
|
|
1370
1379
|
}
|
1371
1380
|
|
1372
1381
|
if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) {
|
1373
|
-
|
1382
|
+
git_str_dispose(&diriter->path);
|
1374
1383
|
|
1375
1384
|
git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path);
|
1376
1385
|
return -1;
|
1377
1386
|
}
|
1378
1387
|
|
1379
1388
|
#ifdef GIT_USE_ICONV
|
1380
|
-
if ((flags &
|
1381
|
-
(void)
|
1389
|
+
if ((flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
|
1390
|
+
(void)git_fs_path_iconv_init_precompose(&diriter->ic);
|
1382
1391
|
#endif
|
1383
1392
|
|
1384
1393
|
diriter->parent_len = diriter->path.size;
|
@@ -1387,12 +1396,12 @@ int git_path_diriter_init(
|
|
1387
1396
|
return 0;
|
1388
1397
|
}
|
1389
1398
|
|
1390
|
-
int
|
1399
|
+
int git_fs_path_diriter_next(git_fs_path_diriter *diriter)
|
1391
1400
|
{
|
1392
1401
|
struct dirent *de;
|
1393
1402
|
const char *filename;
|
1394
1403
|
size_t filename_len;
|
1395
|
-
bool skip_dot = !(diriter->flags &
|
1404
|
+
bool skip_dot = !(diriter->flags & GIT_FS_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
|
1396
1405
|
int error = 0;
|
1397
1406
|
|
1398
1407
|
GIT_ASSERT_ARG(diriter);
|
@@ -1408,35 +1417,35 @@ int git_path_diriter_next(git_path_diriter *diriter)
|
|
1408
1417
|
"could not read directory '%s'", diriter->path.ptr);
|
1409
1418
|
return -1;
|
1410
1419
|
}
|
1411
|
-
} while (skip_dot &&
|
1420
|
+
} while (skip_dot && git_fs_path_is_dot_or_dotdot(de->d_name));
|
1412
1421
|
|
1413
1422
|
filename = de->d_name;
|
1414
1423
|
filename_len = strlen(filename);
|
1415
1424
|
|
1416
1425
|
#ifdef GIT_USE_ICONV
|
1417
|
-
if ((diriter->flags &
|
1418
|
-
(error =
|
1426
|
+
if ((diriter->flags & GIT_FS_PATH_DIR_PRECOMPOSE_UNICODE) != 0 &&
|
1427
|
+
(error = git_fs_path_iconv(&diriter->ic, &filename, &filename_len)) < 0)
|
1419
1428
|
return error;
|
1420
1429
|
#endif
|
1421
1430
|
|
1422
|
-
|
1431
|
+
git_str_truncate(&diriter->path, diriter->parent_len);
|
1423
1432
|
|
1424
1433
|
if (diriter->parent_len > 0 &&
|
1425
1434
|
diriter->path.ptr[diriter->parent_len-1] != '/')
|
1426
|
-
|
1435
|
+
git_str_putc(&diriter->path, '/');
|
1427
1436
|
|
1428
|
-
|
1437
|
+
git_str_put(&diriter->path, filename, filename_len);
|
1429
1438
|
|
1430
|
-
if (
|
1439
|
+
if (git_str_oom(&diriter->path))
|
1431
1440
|
return -1;
|
1432
1441
|
|
1433
1442
|
return error;
|
1434
1443
|
}
|
1435
1444
|
|
1436
|
-
int
|
1445
|
+
int git_fs_path_diriter_filename(
|
1437
1446
|
const char **out,
|
1438
1447
|
size_t *out_len,
|
1439
|
-
|
1448
|
+
git_fs_path_diriter *diriter)
|
1440
1449
|
{
|
1441
1450
|
GIT_ASSERT_ARG(out);
|
1442
1451
|
GIT_ASSERT_ARG(out_len);
|
@@ -1448,10 +1457,10 @@ int git_path_diriter_filename(
|
|
1448
1457
|
return 0;
|
1449
1458
|
}
|
1450
1459
|
|
1451
|
-
int
|
1460
|
+
int git_fs_path_diriter_fullpath(
|
1452
1461
|
const char **out,
|
1453
1462
|
size_t *out_len,
|
1454
|
-
|
1463
|
+
git_fs_path_diriter *diriter)
|
1455
1464
|
{
|
1456
1465
|
GIT_ASSERT_ARG(out);
|
1457
1466
|
GIT_ASSERT_ARG(out_len);
|
@@ -1462,15 +1471,15 @@ int git_path_diriter_fullpath(
|
|
1462
1471
|
return 0;
|
1463
1472
|
}
|
1464
1473
|
|
1465
|
-
int
|
1474
|
+
int git_fs_path_diriter_stat(struct stat *out, git_fs_path_diriter *diriter)
|
1466
1475
|
{
|
1467
1476
|
GIT_ASSERT_ARG(out);
|
1468
1477
|
GIT_ASSERT_ARG(diriter);
|
1469
1478
|
|
1470
|
-
return
|
1479
|
+
return git_fs_path_lstat(diriter->path.ptr, out);
|
1471
1480
|
}
|
1472
1481
|
|
1473
|
-
void
|
1482
|
+
void git_fs_path_diriter_free(git_fs_path_diriter *diriter)
|
1474
1483
|
{
|
1475
1484
|
if (diriter == NULL)
|
1476
1485
|
return;
|
@@ -1481,21 +1490,21 @@ void git_path_diriter_free(git_path_diriter *diriter)
|
|
1481
1490
|
}
|
1482
1491
|
|
1483
1492
|
#ifdef GIT_USE_ICONV
|
1484
|
-
|
1493
|
+
git_fs_path_iconv_clear(&diriter->ic);
|
1485
1494
|
#endif
|
1486
1495
|
|
1487
|
-
|
1496
|
+
git_str_dispose(&diriter->path);
|
1488
1497
|
}
|
1489
1498
|
|
1490
1499
|
#endif
|
1491
1500
|
|
1492
|
-
int
|
1501
|
+
int git_fs_path_dirload(
|
1493
1502
|
git_vector *contents,
|
1494
1503
|
const char *path,
|
1495
1504
|
size_t prefix_len,
|
1496
1505
|
uint32_t flags)
|
1497
1506
|
{
|
1498
|
-
|
1507
|
+
git_fs_path_diriter iter = GIT_FS_PATH_DIRITER_INIT;
|
1499
1508
|
const char *name;
|
1500
1509
|
size_t name_len;
|
1501
1510
|
char *dup;
|
@@ -1504,11 +1513,11 @@ int git_path_dirload(
|
|
1504
1513
|
GIT_ASSERT_ARG(contents);
|
1505
1514
|
GIT_ASSERT_ARG(path);
|
1506
1515
|
|
1507
|
-
if ((error =
|
1516
|
+
if ((error = git_fs_path_diriter_init(&iter, path, flags)) < 0)
|
1508
1517
|
return error;
|
1509
1518
|
|
1510
|
-
while ((error =
|
1511
|
-
if ((error =
|
1519
|
+
while ((error = git_fs_path_diriter_next(&iter)) == 0) {
|
1520
|
+
if ((error = git_fs_path_diriter_fullpath(&name, &name_len, &iter)) < 0)
|
1512
1521
|
break;
|
1513
1522
|
|
1514
1523
|
GIT_ASSERT(name_len > prefix_len);
|
@@ -1523,22 +1532,22 @@ int git_path_dirload(
|
|
1523
1532
|
if (error == GIT_ITEROVER)
|
1524
1533
|
error = 0;
|
1525
1534
|
|
1526
|
-
|
1535
|
+
git_fs_path_diriter_free(&iter);
|
1527
1536
|
return error;
|
1528
1537
|
}
|
1529
1538
|
|
1530
|
-
int
|
1539
|
+
int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path)
|
1531
1540
|
{
|
1532
|
-
if (
|
1533
|
-
return
|
1541
|
+
if (git_fs_path_is_local_file_url(url_or_path))
|
1542
|
+
return git_fs_path_fromurl(local_path_out, url_or_path);
|
1534
1543
|
else
|
1535
|
-
return
|
1544
|
+
return git_str_sets(local_path_out, url_or_path);
|
1536
1545
|
}
|
1537
1546
|
|
1538
1547
|
/* Reject paths like AUX or COM1, or those versions that end in a dot or
|
1539
1548
|
* colon. ("AUX." or "AUX:")
|
1540
1549
|
*/
|
1541
|
-
GIT_INLINE(bool)
|
1550
|
+
GIT_INLINE(bool) validate_dospath(
|
1542
1551
|
const char *component,
|
1543
1552
|
size_t len,
|
1544
1553
|
const char dospath[3],
|
@@ -1557,180 +1566,15 @@ GIT_INLINE(bool) verify_dospath(
|
|
1557
1566
|
component[last] != ':');
|
1558
1567
|
}
|
1559
1568
|
|
1560
|
-
|
1561
|
-
{
|
1562
|
-
while (*len) {
|
1563
|
-
uint32_t codepoint;
|
1564
|
-
int cp_len = git_utf8_iterate(&codepoint, *in, *len);
|
1565
|
-
if (cp_len < 0)
|
1566
|
-
return -1;
|
1567
|
-
|
1568
|
-
(*in) += cp_len;
|
1569
|
-
(*len) -= cp_len;
|
1570
|
-
|
1571
|
-
/* these code points are ignored completely */
|
1572
|
-
switch (codepoint) {
|
1573
|
-
case 0x200c: /* ZERO WIDTH NON-JOINER */
|
1574
|
-
case 0x200d: /* ZERO WIDTH JOINER */
|
1575
|
-
case 0x200e: /* LEFT-TO-RIGHT MARK */
|
1576
|
-
case 0x200f: /* RIGHT-TO-LEFT MARK */
|
1577
|
-
case 0x202a: /* LEFT-TO-RIGHT EMBEDDING */
|
1578
|
-
case 0x202b: /* RIGHT-TO-LEFT EMBEDDING */
|
1579
|
-
case 0x202c: /* POP DIRECTIONAL FORMATTING */
|
1580
|
-
case 0x202d: /* LEFT-TO-RIGHT OVERRIDE */
|
1581
|
-
case 0x202e: /* RIGHT-TO-LEFT OVERRIDE */
|
1582
|
-
case 0x206a: /* INHIBIT SYMMETRIC SWAPPING */
|
1583
|
-
case 0x206b: /* ACTIVATE SYMMETRIC SWAPPING */
|
1584
|
-
case 0x206c: /* INHIBIT ARABIC FORM SHAPING */
|
1585
|
-
case 0x206d: /* ACTIVATE ARABIC FORM SHAPING */
|
1586
|
-
case 0x206e: /* NATIONAL DIGIT SHAPES */
|
1587
|
-
case 0x206f: /* NOMINAL DIGIT SHAPES */
|
1588
|
-
case 0xfeff: /* ZERO WIDTH NO-BREAK SPACE */
|
1589
|
-
continue;
|
1590
|
-
}
|
1591
|
-
|
1592
|
-
/* fold into lowercase -- this will only fold characters in
|
1593
|
-
* the ASCII range, which is perfectly fine, because the
|
1594
|
-
* git folder name can only be composed of ascii characters
|
1595
|
-
*/
|
1596
|
-
return git__tolower((int)codepoint);
|
1597
|
-
}
|
1598
|
-
return 0; /* NULL byte -- end of string */
|
1599
|
-
}
|
1600
|
-
|
1601
|
-
static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len)
|
1602
|
-
{
|
1603
|
-
size_t i;
|
1604
|
-
char c;
|
1605
|
-
|
1606
|
-
if (next_hfs_char(&path, &len) != '.')
|
1607
|
-
return true;
|
1608
|
-
|
1609
|
-
for (i = 0; i < needle_len; i++) {
|
1610
|
-
c = next_hfs_char(&path, &len);
|
1611
|
-
if (c != needle[i])
|
1612
|
-
return true;
|
1613
|
-
}
|
1614
|
-
|
1615
|
-
if (next_hfs_char(&path, &len) != '\0')
|
1616
|
-
return true;
|
1617
|
-
|
1618
|
-
return false;
|
1619
|
-
}
|
1620
|
-
|
1621
|
-
static bool verify_dotgit_hfs(const char *path, size_t len)
|
1622
|
-
{
|
1623
|
-
return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git"));
|
1624
|
-
}
|
1625
|
-
|
1626
|
-
GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
|
1627
|
-
{
|
1628
|
-
git_buf *reserved = git_repository__reserved_names_win32;
|
1629
|
-
size_t reserved_len = git_repository__reserved_names_win32_len;
|
1630
|
-
size_t start = 0, i;
|
1631
|
-
|
1632
|
-
if (repo)
|
1633
|
-
git_repository__reserved_names(&reserved, &reserved_len, repo, true);
|
1634
|
-
|
1635
|
-
for (i = 0; i < reserved_len; i++) {
|
1636
|
-
git_buf *r = &reserved[i];
|
1637
|
-
|
1638
|
-
if (len >= r->size &&
|
1639
|
-
strncasecmp(path, r->ptr, r->size) == 0) {
|
1640
|
-
start = r->size;
|
1641
|
-
break;
|
1642
|
-
}
|
1643
|
-
}
|
1644
|
-
|
1645
|
-
if (!start)
|
1646
|
-
return true;
|
1647
|
-
|
1648
|
-
/*
|
1649
|
-
* Reject paths that start with Windows-style directory separators
|
1650
|
-
* (".git\") or NTFS alternate streams (".git:") and could be used
|
1651
|
-
* to write to the ".git" directory on Windows platforms.
|
1652
|
-
*/
|
1653
|
-
if (path[start] == '\\' || path[start] == ':')
|
1654
|
-
return false;
|
1655
|
-
|
1656
|
-
/* Reject paths like '.git ' or '.git.' */
|
1657
|
-
for (i = start; i < len; i++) {
|
1658
|
-
if (path[i] != ' ' && path[i] != '.')
|
1659
|
-
return true;
|
1660
|
-
}
|
1661
|
-
|
1662
|
-
return false;
|
1663
|
-
}
|
1664
|
-
|
1665
|
-
/*
|
1666
|
-
* Windows paths that end with spaces and/or dots are elided to the
|
1667
|
-
* path without them for backward compatibility. That is to say
|
1668
|
-
* that opening file "foo ", "foo." or even "foo . . ." will all
|
1669
|
-
* map to a filename of "foo". This function identifies spaces and
|
1670
|
-
* dots at the end of a filename, whether the proper end of the
|
1671
|
-
* filename (end of string) or a colon (which would indicate a
|
1672
|
-
* Windows alternate data stream.)
|
1673
|
-
*/
|
1674
|
-
GIT_INLINE(bool) ntfs_end_of_filename(const char *path)
|
1675
|
-
{
|
1676
|
-
const char *c = path;
|
1677
|
-
|
1678
|
-
for (;; c++) {
|
1679
|
-
if (*c == '\0' || *c == ':')
|
1680
|
-
return true;
|
1681
|
-
if (*c != ' ' && *c != '.')
|
1682
|
-
return false;
|
1683
|
-
}
|
1684
|
-
|
1685
|
-
return true;
|
1686
|
-
}
|
1687
|
-
|
1688
|
-
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)
|
1689
|
-
{
|
1690
|
-
int i, saw_tilde;
|
1691
|
-
|
1692
|
-
if (name[0] == '.' && len >= dotgit_len &&
|
1693
|
-
!strncasecmp(name + 1, dotgit_name, dotgit_len)) {
|
1694
|
-
return !ntfs_end_of_filename(name + dotgit_len + 1);
|
1695
|
-
}
|
1696
|
-
|
1697
|
-
/* Detect the basic NTFS shortname with the first six chars */
|
1698
|
-
if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
|
1699
|
-
name[7] >= '1' && name[7] <= '4')
|
1700
|
-
return !ntfs_end_of_filename(name + 8);
|
1701
|
-
|
1702
|
-
/* Catch fallback names */
|
1703
|
-
for (i = 0, saw_tilde = 0; i < 8; i++) {
|
1704
|
-
if (name[i] == '\0') {
|
1705
|
-
return true;
|
1706
|
-
} else if (saw_tilde) {
|
1707
|
-
if (name[i] < '0' || name[i] > '9')
|
1708
|
-
return true;
|
1709
|
-
} else if (name[i] == '~') {
|
1710
|
-
if (name[i+1] < '1' || name[i+1] > '9')
|
1711
|
-
return true;
|
1712
|
-
saw_tilde = 1;
|
1713
|
-
} else if (i >= 6) {
|
1714
|
-
return true;
|
1715
|
-
} else if ((unsigned char)name[i] > 127) {
|
1716
|
-
return true;
|
1717
|
-
} else if (git__tolower(name[i]) != shortname_pfix[i]) {
|
1718
|
-
return true;
|
1719
|
-
}
|
1720
|
-
}
|
1721
|
-
|
1722
|
-
return !ntfs_end_of_filename(name + i);
|
1723
|
-
}
|
1724
|
-
|
1725
|
-
GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
|
1569
|
+
GIT_INLINE(bool) validate_char(unsigned char c, unsigned int flags)
|
1726
1570
|
{
|
1727
|
-
if ((flags &
|
1571
|
+
if ((flags & GIT_FS_PATH_REJECT_BACKSLASH) && c == '\\')
|
1728
1572
|
return false;
|
1729
1573
|
|
1730
|
-
if ((flags &
|
1574
|
+
if ((flags & GIT_FS_PATH_REJECT_SLASH) && c == '/')
|
1731
1575
|
return false;
|
1732
1576
|
|
1733
|
-
if (flags &
|
1577
|
+
if (flags & GIT_FS_PATH_REJECT_NT_CHARS) {
|
1734
1578
|
if (c < 32)
|
1735
1579
|
return false;
|
1736
1580
|
|
@@ -1749,211 +1593,166 @@ GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
|
|
1749
1593
|
return true;
|
1750
1594
|
}
|
1751
1595
|
|
1752
|
-
/*
|
1753
|
-
* Return the length of the common prefix between str and prefix, comparing them
|
1754
|
-
* case-insensitively (must be ASCII to match).
|
1755
|
-
*/
|
1756
|
-
GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char *prefix)
|
1757
|
-
{
|
1758
|
-
size_t count = 0;
|
1759
|
-
|
1760
|
-
while (len >0 && tolower(*str) == tolower(*prefix)) {
|
1761
|
-
count++;
|
1762
|
-
str++;
|
1763
|
-
prefix++;
|
1764
|
-
len--;
|
1765
|
-
}
|
1766
|
-
|
1767
|
-
return count;
|
1768
|
-
}
|
1769
|
-
|
1770
1596
|
/*
|
1771
1597
|
* We fundamentally don't like some paths when dealing with user-inputted
|
1772
|
-
* strings (
|
1598
|
+
* strings (to avoid escaping a sandbox): we don't want dot or dot-dot
|
1773
1599
|
* anywhere, we want to avoid writing weird paths on Windows that can't
|
1774
1600
|
* be handled by tools that use the non-\\?\ APIs, we don't want slashes
|
1775
1601
|
* or double slashes at the end of paths that can make them ambiguous.
|
1776
1602
|
*
|
1777
1603
|
* For checkout, we don't want to recurse into ".git" either.
|
1778
1604
|
*/
|
1779
|
-
static bool
|
1780
|
-
git_repository *repo,
|
1605
|
+
static bool validate_component(
|
1781
1606
|
const char *component,
|
1782
1607
|
size_t len,
|
1783
|
-
uint16_t mode,
|
1784
1608
|
unsigned int flags)
|
1785
1609
|
{
|
1786
1610
|
if (len == 0)
|
1787
|
-
return
|
1611
|
+
return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT);
|
1788
1612
|
|
1789
|
-
if ((flags &
|
1790
|
-
|
1613
|
+
if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) &&
|
1614
|
+
len == 1 && component[0] == '.')
|
1791
1615
|
return false;
|
1792
1616
|
|
1793
|
-
if ((flags &
|
1794
|
-
|
1617
|
+
if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) &&
|
1618
|
+
len == 2 && component[0] == '.' && component[1] == '.')
|
1795
1619
|
return false;
|
1796
1620
|
|
1797
|
-
if ((flags &
|
1621
|
+
if ((flags & GIT_FS_PATH_REJECT_TRAILING_DOT) &&
|
1622
|
+
component[len - 1] == '.')
|
1798
1623
|
return false;
|
1799
1624
|
|
1800
|
-
if ((flags &
|
1625
|
+
if ((flags & GIT_FS_PATH_REJECT_TRAILING_SPACE) &&
|
1626
|
+
component[len - 1] == ' ')
|
1801
1627
|
return false;
|
1802
1628
|
|
1803
|
-
if ((flags &
|
1629
|
+
if ((flags & GIT_FS_PATH_REJECT_TRAILING_COLON) &&
|
1630
|
+
component[len - 1] == ':')
|
1804
1631
|
return false;
|
1805
1632
|
|
1806
|
-
if (flags &
|
1807
|
-
if (!
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
return false;
|
1814
|
-
}
|
1815
|
-
|
1816
|
-
if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
|
1817
|
-
if (!verify_dotgit_hfs(component, len))
|
1818
|
-
return false;
|
1819
|
-
if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS))
|
1633
|
+
if (flags & GIT_FS_PATH_REJECT_DOS_PATHS) {
|
1634
|
+
if (!validate_dospath(component, len, "CON", false) ||
|
1635
|
+
!validate_dospath(component, len, "PRN", false) ||
|
1636
|
+
!validate_dospath(component, len, "AUX", false) ||
|
1637
|
+
!validate_dospath(component, len, "NUL", false) ||
|
1638
|
+
!validate_dospath(component, len, "COM", true) ||
|
1639
|
+
!validate_dospath(component, len, "LPT", true))
|
1820
1640
|
return false;
|
1821
1641
|
}
|
1822
1642
|
|
1823
|
-
if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
|
1824
|
-
if (!verify_dotgit_ntfs(repo, component, len))
|
1825
|
-
return false;
|
1826
|
-
if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS))
|
1827
|
-
return false;
|
1828
|
-
}
|
1829
|
-
|
1830
|
-
/* don't bother rerunning the `.git` test if we ran the HFS or NTFS
|
1831
|
-
* specific tests, they would have already rejected `.git`.
|
1832
|
-
*/
|
1833
|
-
if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
|
1834
|
-
(flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
|
1835
|
-
(flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) {
|
1836
|
-
if (len >= 4 &&
|
1837
|
-
component[0] == '.' &&
|
1838
|
-
(component[1] == 'g' || component[1] == 'G') &&
|
1839
|
-
(component[2] == 'i' || component[2] == 'I') &&
|
1840
|
-
(component[3] == 't' || component[3] == 'T')) {
|
1841
|
-
if (len == 4)
|
1842
|
-
return false;
|
1843
|
-
|
1844
|
-
if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len)
|
1845
|
-
return false;
|
1846
|
-
}
|
1847
|
-
}
|
1848
|
-
|
1849
1643
|
return true;
|
1850
1644
|
}
|
1851
1645
|
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1646
|
+
#ifdef GIT_WIN32
|
1647
|
+
GIT_INLINE(bool) validate_length(
|
1648
|
+
const char *path,
|
1649
|
+
size_t len,
|
1650
|
+
size_t utf8_char_len)
|
1855
1651
|
{
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
flags |= GIT_PATH_REJECT_DOT_GIT_LITERAL;
|
1652
|
+
GIT_UNUSED(path);
|
1653
|
+
GIT_UNUSED(len);
|
1860
1654
|
|
1861
|
-
|
1862
|
-
|
1655
|
+
return (utf8_char_len <= MAX_PATH);
|
1656
|
+
}
|
1863
1657
|
#endif
|
1864
1658
|
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1659
|
+
bool git_fs_path_str_is_valid_ext(
|
1660
|
+
const git_str *path,
|
1661
|
+
unsigned int flags,
|
1662
|
+
bool (*validate_char_cb)(char ch, void *payload),
|
1663
|
+
bool (*validate_component_cb)(const char *component, size_t len, void *payload),
|
1664
|
+
bool (*validate_length_cb)(const char *path, size_t len, size_t utf8_char_len),
|
1665
|
+
void *payload)
|
1666
|
+
{
|
1667
|
+
const char *start, *c;
|
1668
|
+
size_t len = 0;
|
1869
1669
|
|
1870
|
-
if (
|
1871
|
-
|
1872
|
-
if (!error && protectNTFS)
|
1873
|
-
flags |= GIT_PATH_REJECT_DOT_GIT_NTFS;
|
1670
|
+
if (!flags)
|
1671
|
+
return true;
|
1874
1672
|
|
1875
|
-
|
1876
|
-
|
1673
|
+
for (start = c = path->ptr; *c && len < path->size; c++, len++) {
|
1674
|
+
if (!validate_char(*c, flags))
|
1675
|
+
return false;
|
1877
1676
|
|
1878
|
-
|
1879
|
-
|
1880
|
-
const char *path,
|
1881
|
-
uint16_t mode,
|
1882
|
-
unsigned int flags)
|
1883
|
-
{
|
1884
|
-
const char *start, *c;
|
1677
|
+
if (validate_char_cb && !validate_char_cb(*c, payload))
|
1678
|
+
return false;
|
1885
1679
|
|
1886
|
-
|
1887
|
-
|
1888
|
-
flags = dotgit_flags(repo, flags);
|
1680
|
+
if (*c != '/')
|
1681
|
+
continue;
|
1889
1682
|
|
1890
|
-
|
1891
|
-
if (!verify_char(*c, flags))
|
1683
|
+
if (!validate_component(start, (c - start), flags))
|
1892
1684
|
return false;
|
1893
1685
|
|
1894
|
-
if (
|
1895
|
-
|
1896
|
-
|
1686
|
+
if (validate_component_cb &&
|
1687
|
+
!validate_component_cb(start, (c - start), payload))
|
1688
|
+
return false;
|
1897
1689
|
|
1898
|
-
|
1899
|
-
}
|
1690
|
+
start = c + 1;
|
1900
1691
|
}
|
1901
1692
|
|
1902
|
-
|
1903
|
-
|
1693
|
+
/*
|
1694
|
+
* We want to support paths specified as either `const char *`
|
1695
|
+
* or `git_str *`; we pass size as `SIZE_MAX` when we use a
|
1696
|
+
* `const char *` to avoid a `strlen`. Ensure that we didn't
|
1697
|
+
* have a NUL in the buffer if there was a non-SIZE_MAX length.
|
1698
|
+
*/
|
1699
|
+
if (path->size != SIZE_MAX && len != path->size)
|
1700
|
+
return false;
|
1904
1701
|
|
1905
|
-
|
1906
|
-
|
1907
|
-
{
|
1908
|
-
int longpaths = 0;
|
1702
|
+
if (!validate_component(start, (c - start), flags))
|
1703
|
+
return false;
|
1909
1704
|
|
1910
|
-
if (
|
1911
|
-
|
1912
|
-
|
1705
|
+
if (validate_component_cb &&
|
1706
|
+
!validate_component_cb(start, (c - start), payload))
|
1707
|
+
return false;
|
1913
1708
|
|
1914
|
-
|
1915
|
-
|
1709
|
+
#ifdef GIT_WIN32
|
1710
|
+
if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS) != 0) {
|
1711
|
+
size_t utf8_len = git_utf8_char_length(path->ptr, len);
|
1916
1712
|
|
1917
|
-
|
1713
|
+
if (!validate_length(path->ptr, len, utf8_len))
|
1714
|
+
return false;
|
1918
1715
|
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1716
|
+
if (validate_length_cb &&
|
1717
|
+
!validate_length_cb(path->ptr, len, utf8_len))
|
1718
|
+
return false;
|
1719
|
+
}
|
1720
|
+
#else
|
1721
|
+
GIT_UNUSED(validate_length_cb);
|
1722
|
+
#endif
|
1922
1723
|
|
1923
|
-
return
|
1724
|
+
return true;
|
1924
1725
|
}
|
1925
|
-
#endif
|
1926
1726
|
|
1927
|
-
int
|
1727
|
+
int git_fs_path_validate_str_length_with_suffix(
|
1728
|
+
git_str *path,
|
1729
|
+
size_t suffix_len)
|
1928
1730
|
{
|
1929
|
-
|
1930
|
-
|
1731
|
+
#ifdef GIT_WIN32
|
1732
|
+
size_t utf8_len = git_utf8_char_length(path->ptr, path->size);
|
1733
|
+
size_t total_len;
|
1931
1734
|
|
1932
|
-
|
1933
|
-
|
1735
|
+
if (GIT_ADD_SIZET_OVERFLOW(&total_len, utf8_len, suffix_len) ||
|
1736
|
+
total_len > MAX_PATH) {
|
1934
1737
|
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1738
|
+
git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'",
|
1739
|
+
(int)path->size, path->ptr);
|
1740
|
+
return -1;
|
1741
|
+
}
|
1742
|
+
#else
|
1743
|
+
GIT_UNUSED(path);
|
1744
|
+
GIT_UNUSED(suffix_len);
|
1745
|
+
#endif
|
1942
1746
|
|
1943
1747
|
return 0;
|
1944
1748
|
}
|
1945
1749
|
|
1946
|
-
int
|
1947
|
-
{
|
1948
|
-
return git_path_validate_workdir_with_len(repo, path->ptr, path->size);
|
1949
|
-
}
|
1950
|
-
|
1951
|
-
int git_path_normalize_slashes(git_buf *out, const char *path)
|
1750
|
+
int git_fs_path_normalize_slashes(git_str *out, const char *path)
|
1952
1751
|
{
|
1953
1752
|
int error;
|
1954
1753
|
char *p;
|
1955
1754
|
|
1956
|
-
if ((error =
|
1755
|
+
if ((error = git_str_puts(out, path)) < 0)
|
1957
1756
|
return error;
|
1958
1757
|
|
1959
1758
|
for (p = out->ptr; *p; p++) {
|
@@ -1964,47 +1763,9 @@ int git_path_normalize_slashes(git_buf *out, const char *path)
|
|
1964
1763
|
return 0;
|
1965
1764
|
}
|
1966
1765
|
|
1967
|
-
|
1968
|
-
const char *file;
|
1969
|
-
const char *hash;
|
1970
|
-
size_t filelen;
|
1971
|
-
} gitfiles[] = {
|
1972
|
-
{ "gitignore", "gi250a", CONST_STRLEN("gitignore") },
|
1973
|
-
{ "gitmodules", "gi7eba", CONST_STRLEN("gitmodules") },
|
1974
|
-
{ "gitattributes", "gi7d29", CONST_STRLEN("gitattributes") }
|
1975
|
-
};
|
1976
|
-
|
1977
|
-
extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs)
|
1978
|
-
{
|
1979
|
-
const char *file, *hash;
|
1980
|
-
size_t filelen;
|
1981
|
-
|
1982
|
-
if (!(gitfile >= GIT_PATH_GITFILE_GITIGNORE && gitfile < ARRAY_SIZE(gitfiles))) {
|
1983
|
-
git_error_set(GIT_ERROR_OS, "invalid gitfile for path validation");
|
1984
|
-
return -1;
|
1985
|
-
}
|
1986
|
-
|
1987
|
-
file = gitfiles[gitfile].file;
|
1988
|
-
filelen = gitfiles[gitfile].filelen;
|
1989
|
-
hash = gitfiles[gitfile].hash;
|
1990
|
-
|
1991
|
-
switch (fs) {
|
1992
|
-
case GIT_PATH_FS_GENERIC:
|
1993
|
-
return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) ||
|
1994
|
-
!verify_dotgit_hfs_generic(path, pathlen, file, filelen);
|
1995
|
-
case GIT_PATH_FS_NTFS:
|
1996
|
-
return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash);
|
1997
|
-
case GIT_PATH_FS_HFS:
|
1998
|
-
return !verify_dotgit_hfs_generic(path, pathlen, file, filelen);
|
1999
|
-
default:
|
2000
|
-
git_error_set(GIT_ERROR_OS, "invalid filesystem for path validation");
|
2001
|
-
return -1;
|
2002
|
-
}
|
2003
|
-
}
|
2004
|
-
|
2005
|
-
bool git_path_supports_symlinks(const char *dir)
|
1766
|
+
bool git_fs_path_supports_symlinks(const char *dir)
|
2006
1767
|
{
|
2007
|
-
|
1768
|
+
git_str path = GIT_STR_INIT;
|
2008
1769
|
bool supported = false;
|
2009
1770
|
struct stat st;
|
2010
1771
|
int fd;
|
@@ -2020,82 +1781,286 @@ bool git_path_supports_symlinks(const char *dir)
|
|
2020
1781
|
done:
|
2021
1782
|
if (path.size)
|
2022
1783
|
(void)p_unlink(path.ptr);
|
2023
|
-
|
1784
|
+
git_str_dispose(&path);
|
2024
1785
|
return supported;
|
2025
1786
|
}
|
2026
1787
|
|
2027
|
-
|
1788
|
+
static git_fs_path_owner_t mock_owner = GIT_FS_PATH_OWNER_NONE;
|
1789
|
+
|
1790
|
+
void git_fs_path__set_owner(git_fs_path_owner_t owner)
|
1791
|
+
{
|
1792
|
+
mock_owner = owner;
|
1793
|
+
}
|
1794
|
+
|
1795
|
+
#ifdef GIT_WIN32
|
1796
|
+
static PSID *sid_dup(PSID sid)
|
1797
|
+
{
|
1798
|
+
DWORD len;
|
1799
|
+
PSID dup;
|
1800
|
+
|
1801
|
+
len = GetLengthSid(sid);
|
1802
|
+
|
1803
|
+
if ((dup = git__malloc(len)) == NULL)
|
1804
|
+
return NULL;
|
1805
|
+
|
1806
|
+
if (!CopySid(len, dup, sid)) {
|
1807
|
+
git_error_set(GIT_ERROR_OS, "could not duplicate sid");
|
1808
|
+
git__free(dup);
|
1809
|
+
return NULL;
|
1810
|
+
}
|
1811
|
+
|
1812
|
+
return dup;
|
1813
|
+
}
|
1814
|
+
|
1815
|
+
static int current_user_sid(PSID *out)
|
2028
1816
|
{
|
2029
|
-
#ifndef GIT_WIN32
|
2030
|
-
GIT_UNUSED(path);
|
2031
|
-
return GIT_OK;
|
2032
|
-
#else
|
2033
|
-
git_win32_path buf;
|
2034
|
-
PSID owner_sid;
|
2035
|
-
PSECURITY_DESCRIPTOR descriptor = NULL;
|
2036
|
-
HANDLE token;
|
2037
1817
|
TOKEN_USER *info = NULL;
|
2038
|
-
|
2039
|
-
|
1818
|
+
HANDLE token = NULL;
|
1819
|
+
DWORD len = 0;
|
1820
|
+
int error = -1;
|
2040
1821
|
|
2041
|
-
if (
|
2042
|
-
|
1822
|
+
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
1823
|
+
git_error_set(GIT_ERROR_OS, "could not lookup process information");
|
1824
|
+
goto done;
|
1825
|
+
}
|
1826
|
+
|
1827
|
+
if (GetTokenInformation(token, TokenUser, NULL, 0, &len) ||
|
1828
|
+
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
1829
|
+
git_error_set(GIT_ERROR_OS, "could not lookup token metadata");
|
1830
|
+
goto done;
|
1831
|
+
}
|
2043
1832
|
|
2044
|
-
|
2045
|
-
|
2046
|
-
DACL_SECURITY_INFORMATION,
|
2047
|
-
&owner_sid, NULL, NULL, NULL, &descriptor);
|
1833
|
+
info = git__malloc(len);
|
1834
|
+
GIT_ERROR_CHECK_ALLOC(info);
|
2048
1835
|
|
2049
|
-
if (
|
2050
|
-
|
2051
|
-
goto
|
1836
|
+
if (!GetTokenInformation(token, TokenUser, info, len, &len)) {
|
1837
|
+
git_error_set(GIT_ERROR_OS, "could not lookup current user");
|
1838
|
+
goto done;
|
2052
1839
|
}
|
2053
1840
|
|
2054
|
-
if (
|
1841
|
+
if ((*out = sid_dup(info->User.Sid)))
|
1842
|
+
error = 0;
|
1843
|
+
|
1844
|
+
done:
|
1845
|
+
if (token)
|
1846
|
+
CloseHandle(token);
|
1847
|
+
|
1848
|
+
git__free(info);
|
1849
|
+
return error;
|
1850
|
+
}
|
1851
|
+
|
1852
|
+
static int file_owner_sid(PSID *out, const char *path)
|
1853
|
+
{
|
1854
|
+
git_win32_path path_w32;
|
1855
|
+
PSECURITY_DESCRIPTOR descriptor = NULL;
|
1856
|
+
PSID owner_sid;
|
1857
|
+
DWORD ret;
|
1858
|
+
int error = GIT_EINVALID;
|
1859
|
+
|
1860
|
+
if (git_win32_path_from_utf8(path_w32, path) < 0)
|
1861
|
+
return -1;
|
1862
|
+
|
1863
|
+
ret = GetNamedSecurityInfoW(path_w32, SE_FILE_OBJECT,
|
1864
|
+
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
1865
|
+
&owner_sid, NULL, NULL, NULL, &descriptor);
|
1866
|
+
|
1867
|
+
if (ret == ERROR_FILE_NOT_FOUND || ret == ERROR_PATH_NOT_FOUND)
|
1868
|
+
error = GIT_ENOTFOUND;
|
1869
|
+
else if (ret != ERROR_SUCCESS)
|
2055
1870
|
git_error_set(GIT_ERROR_OS, "failed to get security information");
|
2056
|
-
|
2057
|
-
|
1871
|
+
else if (!IsValidSid(owner_sid))
|
1872
|
+
git_error_set(GIT_ERROR_OS, "file owner is not valid");
|
1873
|
+
else if ((*out = sid_dup(owner_sid)))
|
1874
|
+
error = 0;
|
1875
|
+
|
1876
|
+
if (descriptor)
|
1877
|
+
LocalFree(descriptor);
|
1878
|
+
|
1879
|
+
return error;
|
1880
|
+
}
|
1881
|
+
|
1882
|
+
int git_fs_path_owner_is(
|
1883
|
+
bool *out,
|
1884
|
+
const char *path,
|
1885
|
+
git_fs_path_owner_t owner_type)
|
1886
|
+
{
|
1887
|
+
PSID owner_sid = NULL, user_sid = NULL;
|
1888
|
+
BOOL is_admin, admin_owned;
|
1889
|
+
int error;
|
1890
|
+
|
1891
|
+
if (mock_owner) {
|
1892
|
+
*out = ((mock_owner & owner_type) != 0);
|
1893
|
+
return 0;
|
2058
1894
|
}
|
2059
1895
|
|
2060
|
-
if (
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
1896
|
+
if ((error = file_owner_sid(&owner_sid, path)) < 0)
|
1897
|
+
goto done;
|
1898
|
+
|
1899
|
+
if ((owner_type & GIT_FS_PATH_OWNER_CURRENT_USER) != 0) {
|
1900
|
+
if ((error = current_user_sid(&user_sid)) < 0)
|
1901
|
+
goto done;
|
1902
|
+
|
1903
|
+
if (EqualSid(owner_sid, user_sid)) {
|
1904
|
+
*out = true;
|
1905
|
+
goto done;
|
1906
|
+
}
|
2064
1907
|
}
|
2065
1908
|
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
1909
|
+
admin_owned =
|
1910
|
+
IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
|
1911
|
+
IsWellKnownSid(owner_sid, WinLocalSystemSid);
|
1912
|
+
|
1913
|
+
if (admin_owned &&
|
1914
|
+
(owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR) != 0) {
|
1915
|
+
*out = true;
|
1916
|
+
goto done;
|
2070
1917
|
}
|
2071
1918
|
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
git__free(info);
|
2079
|
-
info = NULL;
|
2080
|
-
}
|
1919
|
+
if (admin_owned &&
|
1920
|
+
(owner_type & GIT_FS_PATH_USER_IS_ADMINISTRATOR) != 0 &&
|
1921
|
+
CheckTokenMembership(NULL, owner_sid, &is_admin) &&
|
1922
|
+
is_admin) {
|
1923
|
+
*out = true;
|
1924
|
+
goto done;
|
2081
1925
|
}
|
2082
1926
|
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
1927
|
+
*out = false;
|
1928
|
+
|
1929
|
+
done:
|
1930
|
+
git__free(owner_sid);
|
1931
|
+
git__free(user_sid);
|
1932
|
+
return error;
|
1933
|
+
}
|
1934
|
+
|
1935
|
+
#else
|
1936
|
+
|
1937
|
+
static int sudo_uid_lookup(uid_t *out)
|
1938
|
+
{
|
1939
|
+
git_str uid_str = GIT_STR_INIT;
|
1940
|
+
int64_t uid;
|
1941
|
+
int error;
|
1942
|
+
|
1943
|
+
if ((error = git__getenv(&uid_str, "SUDO_UID")) == 0 &&
|
1944
|
+
(error = git__strntol64(&uid, uid_str.ptr, uid_str.size, NULL, 10)) == 0 &&
|
1945
|
+
uid == (int64_t)((uid_t)uid)) {
|
1946
|
+
*out = (uid_t)uid;
|
2092
1947
|
}
|
2093
|
-
git__free(info);
|
2094
1948
|
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
1949
|
+
git_str_dispose(&uid_str);
|
1950
|
+
return error;
|
1951
|
+
}
|
1952
|
+
|
1953
|
+
int git_fs_path_owner_is(
|
1954
|
+
bool *out,
|
1955
|
+
const char *path,
|
1956
|
+
git_fs_path_owner_t owner_type)
|
1957
|
+
{
|
1958
|
+
struct stat st;
|
1959
|
+
uid_t euid, sudo_uid;
|
1960
|
+
|
1961
|
+
if (mock_owner) {
|
1962
|
+
*out = ((mock_owner & owner_type) != 0);
|
1963
|
+
return 0;
|
1964
|
+
}
|
1965
|
+
|
1966
|
+
euid = geteuid();
|
1967
|
+
|
1968
|
+
if (p_lstat(path, &st) != 0) {
|
1969
|
+
if (errno == ENOENT)
|
1970
|
+
return GIT_ENOTFOUND;
|
1971
|
+
|
1972
|
+
git_error_set(GIT_ERROR_OS, "could not stat '%s'", path);
|
1973
|
+
return -1;
|
1974
|
+
}
|
1975
|
+
|
1976
|
+
if ((owner_type & GIT_FS_PATH_OWNER_CURRENT_USER) != 0 &&
|
1977
|
+
st.st_uid == euid) {
|
1978
|
+
*out = true;
|
1979
|
+
return 0;
|
1980
|
+
}
|
1981
|
+
|
1982
|
+
if ((owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR) != 0 &&
|
1983
|
+
st.st_uid == 0) {
|
1984
|
+
*out = true;
|
1985
|
+
return 0;
|
1986
|
+
}
|
1987
|
+
|
1988
|
+
if ((owner_type & GIT_FS_PATH_OWNER_RUNNING_SUDO) != 0 &&
|
1989
|
+
euid == 0 &&
|
1990
|
+
sudo_uid_lookup(&sudo_uid) == 0 &&
|
1991
|
+
st.st_uid == sudo_uid) {
|
1992
|
+
*out = true;
|
1993
|
+
return 0;
|
1994
|
+
}
|
1995
|
+
|
1996
|
+
*out = false;
|
1997
|
+
return 0;
|
1998
|
+
}
|
1999
|
+
|
2000
|
+
#endif
|
2001
|
+
|
2002
|
+
int git_fs_path_owner_is_current_user(bool *out, const char *path)
|
2003
|
+
{
|
2004
|
+
return git_fs_path_owner_is(out, path, GIT_FS_PATH_OWNER_CURRENT_USER);
|
2005
|
+
}
|
2006
|
+
|
2007
|
+
int git_fs_path_owner_is_system(bool *out, const char *path)
|
2008
|
+
{
|
2009
|
+
return git_fs_path_owner_is(out, path, GIT_FS_PATH_OWNER_ADMINISTRATOR);
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
int git_fs_path_find_executable(git_str *fullpath, const char *executable)
|
2013
|
+
{
|
2014
|
+
#ifdef GIT_WIN32
|
2015
|
+
git_win32_path fullpath_w, executable_w;
|
2016
|
+
int error;
|
2017
|
+
|
2018
|
+
if (git__utf8_to_16(executable_w, GIT_WIN_PATH_MAX, executable) < 0)
|
2019
|
+
return -1;
|
2020
|
+
|
2021
|
+
error = git_win32_path_find_executable(fullpath_w, executable_w);
|
2022
|
+
|
2023
|
+
if (error == 0)
|
2024
|
+
error = git_str_put_w(fullpath, fullpath_w, wcslen(fullpath_w));
|
2025
|
+
|
2026
|
+
return error;
|
2027
|
+
#else
|
2028
|
+
git_str path = GIT_STR_INIT;
|
2029
|
+
const char *current_dir, *term;
|
2030
|
+
bool found = false;
|
2031
|
+
|
2032
|
+
if (git__getenv(&path, "PATH") < 0)
|
2033
|
+
return -1;
|
2034
|
+
|
2035
|
+
current_dir = path.ptr;
|
2036
|
+
|
2037
|
+
while (*current_dir) {
|
2038
|
+
if (! (term = strchr(current_dir, GIT_PATH_LIST_SEPARATOR)))
|
2039
|
+
term = strchr(current_dir, '\0');
|
2040
|
+
|
2041
|
+
git_str_clear(fullpath);
|
2042
|
+
if (git_str_put(fullpath, current_dir, (term - current_dir)) < 0 ||
|
2043
|
+
git_str_putc(fullpath, '/') < 0 ||
|
2044
|
+
git_str_puts(fullpath, executable) < 0)
|
2045
|
+
return -1;
|
2046
|
+
|
2047
|
+
if (git_fs_path_isfile(fullpath->ptr)) {
|
2048
|
+
found = true;
|
2049
|
+
break;
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
current_dir = term;
|
2053
|
+
|
2054
|
+
while (*current_dir == GIT_PATH_LIST_SEPARATOR)
|
2055
|
+
current_dir++;
|
2056
|
+
}
|
2057
|
+
|
2058
|
+
git_str_dispose(&path);
|
2059
|
+
|
2060
|
+
if (found)
|
2061
|
+
return 0;
|
2098
2062
|
|
2099
|
-
|
2063
|
+
git_str_clear(fullpath);
|
2064
|
+
return GIT_ENOTFOUND;
|
2100
2065
|
#endif
|
2101
2066
|
}
|