rugged 1.1.1 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (407) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -0
  3. data/README.md +1 -1
  4. data/ext/rugged/extconf.rb +2 -2
  5. data/ext/rugged/rugged.c +7 -4
  6. data/ext/rugged/rugged_config.c +7 -2
  7. data/ext/rugged/rugged_object.c +1 -1
  8. data/ext/rugged/rugged_remote.c +17 -0
  9. data/ext/rugged/rugged_repo.c +3 -3
  10. data/lib/rugged/repository.rb +2 -2
  11. data/lib/rugged/version.rb +1 -1
  12. data/vendor/libgit2/CMakeLists.txt +103 -271
  13. data/vendor/libgit2/COPYING +149 -24
  14. data/vendor/libgit2/cmake/AddCFlagIfSupported.cmake +21 -21
  15. data/vendor/libgit2/cmake/DefaultCFlags.cmake +154 -0
  16. data/vendor/libgit2/cmake/EnableWarnings.cmake +13 -13
  17. data/vendor/libgit2/cmake/FindCoreFoundation.cmake +13 -13
  18. data/vendor/libgit2/cmake/FindGSSAPI.cmake +171 -287
  19. data/vendor/libgit2/cmake/FindGSSFramework.cmake +13 -13
  20. data/vendor/libgit2/cmake/{FindHTTP_Parser.cmake → FindHTTPParser.cmake} +17 -17
  21. data/vendor/libgit2/cmake/FindIconv.cmake +27 -27
  22. data/vendor/libgit2/cmake/FindLibSSH2.cmake +13 -0
  23. data/vendor/libgit2/cmake/FindPCRE.cmake +13 -13
  24. data/vendor/libgit2/cmake/FindPCRE2.cmake +12 -12
  25. data/vendor/libgit2/cmake/FindPkgLibraries.cmake +19 -19
  26. data/vendor/libgit2/cmake/FindSecurity.cmake +14 -14
  27. data/vendor/libgit2/cmake/FindStatNsec.cmake +12 -18
  28. data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
  29. data/vendor/libgit2/cmake/FindmbedTLS.cmake +63 -70
  30. data/vendor/libgit2/cmake/IdeSplitSources.cmake +18 -18
  31. data/vendor/libgit2/cmake/PkgBuildConfig.cmake +60 -60
  32. data/vendor/libgit2/cmake/SanitizeBool.cmake +20 -20
  33. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +37 -37
  34. data/vendor/libgit2/cmake/SelectHTTPParser.cmake +19 -0
  35. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +100 -96
  36. data/vendor/libgit2/cmake/SelectHashes.cmake +39 -48
  37. data/vendor/libgit2/cmake/SelectRegex.cmake +51 -0
  38. data/vendor/libgit2/cmake/SelectSSH.cmake +41 -0
  39. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +17 -0
  40. data/vendor/libgit2/cmake/SelectZlib.cmake +34 -0
  41. data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
  42. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +32 -20
  43. data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
  44. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
  45. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
  46. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
  47. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
  48. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
  49. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
  50. data/vendor/libgit2/deps/ntlmclient/ntlm.c +154 -122
  51. data/vendor/libgit2/deps/ntlmclient/ntlm.h +17 -13
  52. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +17 -4
  53. data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
  54. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
  55. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
  56. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
  57. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
  58. data/vendor/libgit2/deps/pcre/CMakeLists.txt +88 -88
  59. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +14 -16
  60. data/vendor/libgit2/include/git2/apply.h +16 -2
  61. data/vendor/libgit2/include/git2/attr.h +106 -2
  62. data/vendor/libgit2/include/git2/blame.h +97 -43
  63. data/vendor/libgit2/include/git2/blob.h +33 -2
  64. data/vendor/libgit2/include/git2/branch.h +27 -0
  65. data/vendor/libgit2/include/git2/buffer.h +18 -78
  66. data/vendor/libgit2/include/git2/cert.h +43 -6
  67. data/vendor/libgit2/include/git2/checkout.h +32 -13
  68. data/vendor/libgit2/include/git2/clone.h +4 -4
  69. data/vendor/libgit2/include/git2/commit.h +37 -19
  70. data/vendor/libgit2/include/git2/common.h +46 -5
  71. data/vendor/libgit2/include/git2/config.h +19 -3
  72. data/vendor/libgit2/include/git2/credential.h +2 -1
  73. data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
  74. data/vendor/libgit2/include/git2/deprecated.h +326 -6
  75. data/vendor/libgit2/include/git2/describe.h +7 -2
  76. data/vendor/libgit2/include/git2/diff.h +50 -121
  77. data/vendor/libgit2/include/git2/email.h +127 -0
  78. data/vendor/libgit2/include/git2/errors.h +7 -6
  79. data/vendor/libgit2/include/git2/filter.h +69 -18
  80. data/vendor/libgit2/include/git2/graph.h +21 -2
  81. data/vendor/libgit2/include/git2/ignore.h +1 -1
  82. data/vendor/libgit2/include/git2/index.h +13 -7
  83. data/vendor/libgit2/include/git2/indexer.h +19 -0
  84. data/vendor/libgit2/include/git2/merge.h +23 -3
  85. data/vendor/libgit2/include/git2/message.h +2 -0
  86. data/vendor/libgit2/include/git2/notes.h +2 -2
  87. data/vendor/libgit2/include/git2/object.h +23 -0
  88. data/vendor/libgit2/include/git2/odb.h +65 -6
  89. data/vendor/libgit2/include/git2/odb_backend.h +1 -1
  90. data/vendor/libgit2/include/git2/oidarray.h +5 -8
  91. data/vendor/libgit2/include/git2/pack.h +24 -8
  92. data/vendor/libgit2/include/git2/patch.h +16 -0
  93. data/vendor/libgit2/include/git2/pathspec.h +1 -1
  94. data/vendor/libgit2/include/git2/proxy.h +1 -1
  95. data/vendor/libgit2/include/git2/rebase.h +34 -2
  96. data/vendor/libgit2/include/git2/refdb.h +3 -0
  97. data/vendor/libgit2/include/git2/reflog.h +1 -1
  98. data/vendor/libgit2/include/git2/refs.h +8 -4
  99. data/vendor/libgit2/include/git2/remote.h +246 -46
  100. data/vendor/libgit2/include/git2/repository.h +25 -18
  101. data/vendor/libgit2/include/git2/reset.h +2 -2
  102. data/vendor/libgit2/include/git2/revparse.h +5 -5
  103. data/vendor/libgit2/include/git2/revwalk.h +4 -1
  104. data/vendor/libgit2/include/git2/signature.h +1 -1
  105. data/vendor/libgit2/include/git2/stash.h +4 -4
  106. data/vendor/libgit2/include/git2/status.h +124 -62
  107. data/vendor/libgit2/include/git2/stdint.h +3 -3
  108. data/vendor/libgit2/include/git2/submodule.h +16 -2
  109. data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
  110. data/vendor/libgit2/include/git2/sys/email.h +45 -0
  111. data/vendor/libgit2/include/git2/sys/filter.h +49 -28
  112. data/vendor/libgit2/include/git2/sys/midx.h +74 -0
  113. data/vendor/libgit2/include/git2/sys/odb_backend.h +9 -5
  114. data/vendor/libgit2/include/git2/sys/remote.h +31 -0
  115. data/vendor/libgit2/include/git2/sys/stream.h +1 -1
  116. data/vendor/libgit2/include/git2/sys/transport.h +26 -34
  117. data/vendor/libgit2/include/git2/tag.h +13 -0
  118. data/vendor/libgit2/include/git2/tree.h +4 -17
  119. data/vendor/libgit2/include/git2/types.h +16 -7
  120. data/vendor/libgit2/include/git2/version.h +4 -4
  121. data/vendor/libgit2/include/git2/worktree.h +13 -2
  122. data/vendor/libgit2/include/git2.h +1 -0
  123. data/vendor/libgit2/src/CMakeLists.txt +192 -290
  124. data/vendor/libgit2/src/alloc.c +21 -8
  125. data/vendor/libgit2/src/allocators/failalloc.c +92 -0
  126. data/vendor/libgit2/src/allocators/failalloc.h +23 -0
  127. data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
  128. data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
  129. data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
  130. data/vendor/libgit2/src/annotated_commit.c +21 -9
  131. data/vendor/libgit2/src/annotated_commit.h +1 -1
  132. data/vendor/libgit2/src/apply.c +34 -25
  133. data/vendor/libgit2/src/apply.h +2 -2
  134. data/vendor/libgit2/src/array.h +11 -11
  135. data/vendor/libgit2/src/attr.c +204 -82
  136. data/vendor/libgit2/src/attr_file.c +105 -52
  137. data/vendor/libgit2/src/attr_file.h +36 -15
  138. data/vendor/libgit2/src/attrcache.c +55 -45
  139. data/vendor/libgit2/src/attrcache.h +4 -5
  140. data/vendor/libgit2/src/blame.c +15 -9
  141. data/vendor/libgit2/src/blame_git.c +2 -2
  142. data/vendor/libgit2/src/blob.c +76 -52
  143. data/vendor/libgit2/src/blob.h +1 -1
  144. data/vendor/libgit2/src/branch.c +203 -110
  145. data/vendor/libgit2/src/branch.h +15 -3
  146. data/vendor/libgit2/src/buf.c +126 -0
  147. data/vendor/libgit2/src/buf.h +50 -0
  148. data/vendor/libgit2/src/cache.c +2 -2
  149. data/vendor/libgit2/src/cache.h +7 -7
  150. data/vendor/libgit2/src/cc-compat.h +11 -9
  151. data/vendor/libgit2/src/checkout.c +118 -91
  152. data/vendor/libgit2/src/cherrypick.c +16 -12
  153. data/vendor/libgit2/src/clone.c +97 -103
  154. data/vendor/libgit2/src/commit.c +167 -84
  155. data/vendor/libgit2/src/commit.h +24 -1
  156. data/vendor/libgit2/src/commit_graph.c +1224 -0
  157. data/vendor/libgit2/src/commit_graph.h +169 -0
  158. data/vendor/libgit2/src/commit_list.c +48 -3
  159. data/vendor/libgit2/src/commit_list.h +2 -0
  160. data/vendor/libgit2/src/common.h +35 -5
  161. data/vendor/libgit2/src/config.c +119 -64
  162. data/vendor/libgit2/src/config.h +15 -2
  163. data/vendor/libgit2/src/config_cache.c +5 -3
  164. data/vendor/libgit2/src/config_file.c +120 -100
  165. data/vendor/libgit2/src/config_mem.c +9 -9
  166. data/vendor/libgit2/src/config_parse.c +29 -27
  167. data/vendor/libgit2/src/crlf.c +36 -23
  168. data/vendor/libgit2/src/date.c +13 -19
  169. data/vendor/libgit2/src/date.h +33 -0
  170. data/vendor/libgit2/src/delta.c +1 -1
  171. data/vendor/libgit2/src/describe.c +32 -21
  172. data/vendor/libgit2/src/diff.c +71 -183
  173. data/vendor/libgit2/src/diff.h +2 -4
  174. data/vendor/libgit2/src/diff_driver.c +53 -51
  175. data/vendor/libgit2/src/diff_driver.h +3 -3
  176. data/vendor/libgit2/src/diff_file.c +31 -26
  177. data/vendor/libgit2/src/diff_generate.c +76 -23
  178. data/vendor/libgit2/src/diff_generate.h +5 -3
  179. data/vendor/libgit2/src/diff_print.c +120 -95
  180. data/vendor/libgit2/src/diff_stats.c +47 -34
  181. data/vendor/libgit2/src/{message.h → diff_stats.h} +7 -6
  182. data/vendor/libgit2/src/diff_tform.c +18 -16
  183. data/vendor/libgit2/src/diff_xdiff.c +7 -10
  184. data/vendor/libgit2/src/diff_xdiff.h +1 -1
  185. data/vendor/libgit2/src/email.c +315 -0
  186. data/vendor/libgit2/src/email.h +25 -0
  187. data/vendor/libgit2/src/errors.c +37 -32
  188. data/vendor/libgit2/src/features.h.in +11 -2
  189. data/vendor/libgit2/src/fetch.c +77 -26
  190. data/vendor/libgit2/src/fetch.h +1 -1
  191. data/vendor/libgit2/src/fetchhead.c +27 -23
  192. data/vendor/libgit2/src/filebuf.c +36 -34
  193. data/vendor/libgit2/src/filebuf.h +1 -1
  194. data/vendor/libgit2/src/filter.c +278 -132
  195. data/vendor/libgit2/src/filter.h +46 -6
  196. data/vendor/libgit2/src/fs_path.c +2071 -0
  197. data/vendor/libgit2/src/fs_path.h +772 -0
  198. data/vendor/libgit2/src/futils.c +96 -90
  199. data/vendor/libgit2/src/futils.h +27 -15
  200. data/vendor/libgit2/src/graph.c +64 -9
  201. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +5 -5
  202. data/vendor/libgit2/src/hash/sha1/common_crypto.c +5 -5
  203. data/vendor/libgit2/src/hash/sha1/generic.c +2 -2
  204. data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
  205. data/vendor/libgit2/src/hash/sha1/mbedtls.c +13 -13
  206. data/vendor/libgit2/src/hash/sha1/openssl.c +5 -5
  207. data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +9 -11
  208. data/vendor/libgit2/src/hash/sha1/win32.c +21 -17
  209. data/vendor/libgit2/src/hash/sha1.h +3 -1
  210. data/vendor/libgit2/src/hash.c +71 -36
  211. data/vendor/libgit2/src/hash.h +13 -13
  212. data/vendor/libgit2/src/hashsig.c +23 -10
  213. data/vendor/libgit2/src/ident.c +30 -20
  214. data/vendor/libgit2/src/ignore.c +63 -46
  215. data/vendor/libgit2/src/ignore.h +2 -2
  216. data/vendor/libgit2/src/index.c +184 -149
  217. data/vendor/libgit2/src/index.h +7 -4
  218. data/vendor/libgit2/src/indexer.c +143 -89
  219. data/vendor/libgit2/src/integer.h +64 -2
  220. data/vendor/libgit2/src/iterator.c +93 -73
  221. data/vendor/libgit2/src/iterator.h +6 -6
  222. data/vendor/libgit2/src/khash.h +3 -12
  223. data/vendor/libgit2/src/{settings.c → libgit2.c} +165 -56
  224. data/vendor/libgit2/src/libgit2.h +15 -0
  225. data/vendor/libgit2/src/mailmap.c +60 -45
  226. data/vendor/libgit2/src/map.h +3 -3
  227. data/vendor/libgit2/src/merge.c +104 -61
  228. data/vendor/libgit2/src/merge.h +3 -15
  229. data/vendor/libgit2/src/merge_driver.c +21 -15
  230. data/vendor/libgit2/src/merge_file.c +24 -6
  231. data/vendor/libgit2/src/message.c +21 -8
  232. data/vendor/libgit2/src/midx.c +501 -18
  233. data/vendor/libgit2/src/midx.h +29 -2
  234. data/vendor/libgit2/src/mwindow.c +103 -59
  235. data/vendor/libgit2/src/mwindow.h +3 -3
  236. data/vendor/libgit2/src/net.c +405 -71
  237. data/vendor/libgit2/src/net.h +26 -5
  238. data/vendor/libgit2/src/netops.c +7 -5
  239. data/vendor/libgit2/src/netops.h +3 -3
  240. data/vendor/libgit2/src/notes.c +40 -49
  241. data/vendor/libgit2/src/object.c +68 -20
  242. data/vendor/libgit2/src/object.h +1 -1
  243. data/vendor/libgit2/src/odb.c +320 -80
  244. data/vendor/libgit2/src/odb.h +17 -3
  245. data/vendor/libgit2/src/odb_loose.c +96 -86
  246. data/vendor/libgit2/src/odb_mempack.c +19 -6
  247. data/vendor/libgit2/src/odb_pack.c +402 -125
  248. data/vendor/libgit2/src/oid.c +16 -8
  249. data/vendor/libgit2/src/oid.h +15 -0
  250. data/vendor/libgit2/src/oidarray.c +10 -1
  251. data/vendor/libgit2/src/pack-objects.c +90 -69
  252. data/vendor/libgit2/src/pack-objects.h +11 -6
  253. data/vendor/libgit2/src/pack.c +337 -127
  254. data/vendor/libgit2/src/pack.h +25 -7
  255. data/vendor/libgit2/src/patch.c +17 -10
  256. data/vendor/libgit2/src/patch.h +1 -0
  257. data/vendor/libgit2/src/patch_generate.c +29 -13
  258. data/vendor/libgit2/src/patch_generate.h +5 -5
  259. data/vendor/libgit2/src/patch_parse.c +26 -25
  260. data/vendor/libgit2/src/path.c +86 -1768
  261. data/vendor/libgit2/src/path.h +39 -635
  262. data/vendor/libgit2/src/pathspec.c +12 -12
  263. data/vendor/libgit2/src/pathspec.h +2 -2
  264. data/vendor/libgit2/src/pool.c +13 -7
  265. data/vendor/libgit2/src/posix.c +14 -6
  266. data/vendor/libgit2/src/posix.h +1 -0
  267. data/vendor/libgit2/src/pqueue.h +1 -1
  268. data/vendor/libgit2/src/proxy.c +4 -1
  269. data/vendor/libgit2/src/proxy.h +1 -1
  270. data/vendor/libgit2/src/push.c +30 -35
  271. data/vendor/libgit2/src/push.h +4 -16
  272. data/vendor/libgit2/src/rand.c +226 -0
  273. data/vendor/libgit2/src/rand.h +37 -0
  274. data/vendor/libgit2/src/reader.c +18 -14
  275. data/vendor/libgit2/src/reader.h +2 -2
  276. data/vendor/libgit2/src/rebase.c +177 -132
  277. data/vendor/libgit2/src/refdb.c +30 -13
  278. data/vendor/libgit2/src/refdb_fs.c +548 -222
  279. data/vendor/libgit2/src/reflog.c +19 -14
  280. data/vendor/libgit2/src/refs.c +107 -72
  281. data/vendor/libgit2/src/refs.h +2 -2
  282. data/vendor/libgit2/src/refspec.c +53 -38
  283. data/vendor/libgit2/src/refspec.h +5 -2
  284. data/vendor/libgit2/src/regexp.c +1 -1
  285. data/vendor/libgit2/src/remote.c +960 -486
  286. data/vendor/libgit2/src/remote.h +16 -10
  287. data/vendor/libgit2/src/repository.c +702 -422
  288. data/vendor/libgit2/src/repository.h +26 -8
  289. data/vendor/libgit2/src/reset.c +16 -12
  290. data/vendor/libgit2/src/revert.c +16 -12
  291. data/vendor/libgit2/src/revparse.c +66 -48
  292. data/vendor/libgit2/src/revwalk.c +39 -22
  293. data/vendor/libgit2/src/runtime.c +162 -0
  294. data/vendor/libgit2/src/runtime.h +62 -0
  295. data/vendor/libgit2/src/settings.h +11 -0
  296. data/vendor/libgit2/src/signature.c +18 -11
  297. data/vendor/libgit2/src/signature.h +1 -1
  298. data/vendor/libgit2/src/sortedcache.c +1 -1
  299. data/vendor/libgit2/src/sortedcache.h +10 -8
  300. data/vendor/libgit2/src/stash.c +39 -38
  301. data/vendor/libgit2/src/status.c +11 -5
  302. data/vendor/libgit2/src/{buffer.c → str.c} +459 -136
  303. data/vendor/libgit2/src/str.h +357 -0
  304. data/vendor/libgit2/src/strarray.c +2 -1
  305. data/vendor/libgit2/src/streams/mbedtls.c +22 -23
  306. data/vendor/libgit2/src/streams/mbedtls.h +1 -1
  307. data/vendor/libgit2/src/streams/openssl.c +101 -201
  308. data/vendor/libgit2/src/streams/openssl.h +9 -1
  309. data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
  310. data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
  311. data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
  312. data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
  313. data/vendor/libgit2/src/streams/registry.c +5 -6
  314. data/vendor/libgit2/src/streams/socket.c +6 -2
  315. data/vendor/libgit2/src/streams/stransport.c +6 -3
  316. data/vendor/libgit2/src/streams/tls.c +5 -3
  317. data/vendor/libgit2/src/submodule.c +290 -212
  318. data/vendor/libgit2/src/submodule.h +10 -10
  319. data/vendor/libgit2/src/sysdir.c +70 -56
  320. data/vendor/libgit2/src/sysdir.h +15 -10
  321. data/vendor/libgit2/src/tag.c +72 -34
  322. data/vendor/libgit2/src/thread.c +140 -0
  323. data/vendor/libgit2/src/thread.h +479 -0
  324. data/vendor/libgit2/src/threadstate.c +84 -0
  325. data/vendor/libgit2/src/threadstate.h +24 -0
  326. data/vendor/libgit2/src/trace.c +3 -16
  327. data/vendor/libgit2/src/trace.h +17 -30
  328. data/vendor/libgit2/src/trailer.c +2 -2
  329. data/vendor/libgit2/src/transaction.c +20 -9
  330. data/vendor/libgit2/src/transport.c +13 -13
  331. data/vendor/libgit2/src/transports/auth.c +8 -10
  332. data/vendor/libgit2/src/transports/auth.h +2 -3
  333. data/vendor/libgit2/src/transports/auth_negotiate.c +23 -17
  334. data/vendor/libgit2/src/transports/auth_ntlm.c +20 -16
  335. data/vendor/libgit2/src/transports/auth_ntlm.h +0 -1
  336. data/vendor/libgit2/src/transports/credential.c +15 -7
  337. data/vendor/libgit2/src/transports/git.c +10 -14
  338. data/vendor/libgit2/src/transports/http.c +56 -34
  339. data/vendor/libgit2/src/transports/http.h +3 -3
  340. data/vendor/libgit2/src/transports/httpclient.c +106 -79
  341. data/vendor/libgit2/src/transports/httpclient.h +1 -1
  342. data/vendor/libgit2/src/transports/local.c +127 -119
  343. data/vendor/libgit2/src/transports/smart.c +61 -144
  344. data/vendor/libgit2/src/transports/smart.h +26 -32
  345. data/vendor/libgit2/src/transports/smart_pkt.c +33 -33
  346. data/vendor/libgit2/src/transports/smart_protocol.c +68 -44
  347. data/vendor/libgit2/src/transports/ssh.c +100 -131
  348. data/vendor/libgit2/src/transports/winhttp.c +86 -82
  349. data/vendor/libgit2/src/tree-cache.c +5 -5
  350. data/vendor/libgit2/src/tree-cache.h +2 -2
  351. data/vendor/libgit2/src/tree.c +150 -116
  352. data/vendor/libgit2/src/tree.h +1 -0
  353. data/vendor/libgit2/src/tsort.c +0 -2
  354. data/vendor/libgit2/src/unix/map.c +3 -3
  355. data/vendor/libgit2/src/unix/posix.h +1 -4
  356. data/vendor/libgit2/src/unix/pthread.h +2 -1
  357. data/vendor/libgit2/src/unix/realpath.c +0 -2
  358. data/vendor/libgit2/src/utf8.c +150 -0
  359. data/vendor/libgit2/src/utf8.h +52 -0
  360. data/vendor/libgit2/src/util.c +68 -144
  361. data/vendor/libgit2/src/util.h +36 -68
  362. data/vendor/libgit2/src/vector.c +23 -19
  363. data/vendor/libgit2/src/vector.h +5 -3
  364. data/vendor/libgit2/src/win32/findfile.c +172 -114
  365. data/vendor/libgit2/src/win32/findfile.h +7 -4
  366. data/vendor/libgit2/src/win32/map.c +1 -1
  367. data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
  368. data/vendor/libgit2/src/win32/path_w32.c +162 -33
  369. data/vendor/libgit2/src/win32/path_w32.h +2 -1
  370. data/vendor/libgit2/src/win32/posix.h +6 -7
  371. data/vendor/libgit2/src/win32/posix_w32.c +26 -33
  372. data/vendor/libgit2/src/win32/precompiled.h +0 -1
  373. data/vendor/libgit2/src/win32/reparse.h +4 -4
  374. data/vendor/libgit2/src/win32/thread.c +24 -15
  375. data/vendor/libgit2/src/win32/thread.h +1 -1
  376. data/vendor/libgit2/src/win32/w32_buffer.c +5 -6
  377. data/vendor/libgit2/src/win32/w32_buffer.h +2 -3
  378. data/vendor/libgit2/src/win32/w32_common.h +18 -9
  379. data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
  380. data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
  381. data/vendor/libgit2/src/win32/w32_util.h +6 -6
  382. data/vendor/libgit2/src/worktree.c +138 -105
  383. data/vendor/libgit2/src/worktree.h +1 -1
  384. data/vendor/libgit2/src/xdiff/git-xdiff.h +53 -0
  385. data/vendor/libgit2/src/xdiff/xdiff.h +15 -15
  386. data/vendor/libgit2/src/xdiff/xdiffi.c +134 -108
  387. data/vendor/libgit2/src/xdiff/xemit.c +23 -7
  388. data/vendor/libgit2/src/xdiff/xhistogram.c +87 -78
  389. data/vendor/libgit2/src/xdiff/xinclude.h +1 -12
  390. data/vendor/libgit2/src/xdiff/xmerge.c +104 -117
  391. data/vendor/libgit2/src/xdiff/xpatience.c +6 -17
  392. data/vendor/libgit2/src/xdiff/xprepare.c +15 -20
  393. data/vendor/libgit2/src/xdiff/xutils.c +18 -7
  394. data/vendor/libgit2/src/zstream.c +6 -6
  395. data/vendor/libgit2/src/zstream.h +4 -4
  396. metadata +60 -24
  397. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  398. data/vendor/libgit2/src/buf_text.c +0 -316
  399. data/vendor/libgit2/src/buf_text.h +0 -122
  400. data/vendor/libgit2/src/buffer.h +0 -222
  401. data/vendor/libgit2/src/global.c +0 -363
  402. data/vendor/libgit2/src/global.h +0 -41
  403. data/vendor/libgit2/src/thread-utils.c +0 -58
  404. data/vendor/libgit2/src/thread-utils.h +0 -369
  405. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
  406. data/vendor/libgit2/src/win32/w32_stack.c +0 -188
  407. data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -7,1562 +7,20 @@
7
7
 
8
8
  #include "path.h"
9
9
 
10
- #include "posix.h"
11
10
  #include "repository.h"
12
- #ifdef GIT_WIN32
13
- #include "win32/posix.h"
14
- #include "win32/w32_buffer.h"
15
- #include "win32/w32_util.h"
16
- #include "win32/version.h"
17
- #include <aclapi.h>
18
- #else
19
- #include <dirent.h>
20
- #endif
21
- #include <stdio.h>
22
- #include <ctype.h>
23
-
24
- static int dos_drive_prefix_length(const char *path)
25
- {
26
- int i;
27
-
28
- /*
29
- * Does it start with an ASCII letter (i.e. highest bit not set),
30
- * followed by a colon?
31
- */
32
- if (!(0x80 & (unsigned char)*path))
33
- return *path && path[1] == ':' ? 2 : 0;
34
-
35
- /*
36
- * While drive letters must be letters of the English alphabet, it is
37
- * possible to assign virtually _any_ Unicode character via `subst` as
38
- * a drive letter to "virtual drives". Even `1`, or `ä`. Or fun stuff
39
- * like this:
40
- *
41
- * subst ֍: %USERPROFILE%\Desktop
42
- */
43
- for (i = 1; i < 4 && (0x80 & (unsigned char)path[i]); i++)
44
- ; /* skip first UTF-8 character */
45
- return path[i] == ':' ? i + 1 : 0;
46
- }
47
-
48
- #ifdef GIT_WIN32
49
- static bool looks_like_network_computer_name(const char *path, int pos)
50
- {
51
- if (pos < 3)
52
- return false;
53
-
54
- if (path[0] != '/' || path[1] != '/')
55
- return false;
56
-
57
- while (pos-- > 2) {
58
- if (path[pos] == '/')
59
- return false;
60
- }
61
-
62
- return true;
63
- }
64
- #endif
65
-
66
- /*
67
- * Based on the Android implementation, BSD licensed.
68
- * http://android.git.kernel.org/
69
- *
70
- * Copyright (C) 2008 The Android Open Source Project
71
- * All rights reserved.
72
- *
73
- * Redistribution and use in source and binary forms, with or without
74
- * modification, are permitted provided that the following conditions
75
- * are met:
76
- * * Redistributions of source code must retain the above copyright
77
- * notice, this list of conditions and the following disclaimer.
78
- * * Redistributions in binary form must reproduce the above copyright
79
- * notice, this list of conditions and the following disclaimer in
80
- * the documentation and/or other materials provided with the
81
- * distribution.
82
- *
83
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
84
- * AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
85
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
86
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
87
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
88
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
89
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
90
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
91
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
92
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
93
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
94
- * SUCH DAMAGE.
95
- */
96
- int git_path_basename_r(git_buf *buffer, const char *path)
97
- {
98
- const char *endp, *startp;
99
- int len, result;
100
-
101
- /* Empty or NULL string gets treated as "." */
102
- if (path == NULL || *path == '\0') {
103
- startp = ".";
104
- len = 1;
105
- goto Exit;
106
- }
107
-
108
- /* Strip trailing slashes */
109
- endp = path + strlen(path) - 1;
110
- while (endp > path && *endp == '/')
111
- endp--;
112
-
113
- /* All slashes becomes "/" */
114
- if (endp == path && *endp == '/') {
115
- startp = "/";
116
- len = 1;
117
- goto Exit;
118
- }
119
-
120
- /* Find the start of the base */
121
- startp = endp;
122
- while (startp > path && *(startp - 1) != '/')
123
- startp--;
124
-
125
- /* Cast is safe because max path < max int */
126
- len = (int)(endp - startp + 1);
127
-
128
- Exit:
129
- result = len;
130
-
131
- if (buffer != NULL && git_buf_set(buffer, startp, len) < 0)
132
- return -1;
133
-
134
- return result;
135
- }
136
-
137
- /*
138
- * Determine if the path is a Windows prefix and, if so, returns
139
- * its actual lentgh. If it is not a prefix, returns -1.
140
- */
141
- static int win32_prefix_length(const char *path, int len)
142
- {
143
- #ifndef GIT_WIN32
144
- GIT_UNUSED(path);
145
- GIT_UNUSED(len);
146
- #else
147
- /*
148
- * Mimic unix behavior where '/.git' returns '/': 'C:/.git'
149
- * will return 'C:/' here
150
- */
151
- if (dos_drive_prefix_length(path) == len)
152
- return len;
153
-
154
- /*
155
- * Similarly checks if we're dealing with a network computer name
156
- * '//computername/.git' will return '//computername/'
157
- */
158
- if (looks_like_network_computer_name(path, len))
159
- return len;
160
- #endif
161
-
162
- return -1;
163
- }
164
-
165
- /*
166
- * Based on the Android implementation, BSD licensed.
167
- * Check http://android.git.kernel.org/
168
- */
169
- int git_path_dirname_r(git_buf *buffer, const char *path)
170
- {
171
- const char *endp;
172
- int is_prefix = 0, len;
173
-
174
- /* Empty or NULL string gets treated as "." */
175
- if (path == NULL || *path == '\0') {
176
- path = ".";
177
- len = 1;
178
- goto Exit;
179
- }
180
-
181
- /* Strip trailing slashes */
182
- endp = path + strlen(path) - 1;
183
- while (endp > path && *endp == '/')
184
- endp--;
185
-
186
- if (endp - path + 1 > INT_MAX) {
187
- git_error_set(GIT_ERROR_INVALID, "path too long");
188
- len = -1;
189
- goto Exit;
190
- }
191
-
192
- if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) {
193
- is_prefix = 1;
194
- goto Exit;
195
- }
196
-
197
- /* Find the start of the dir */
198
- while (endp > path && *endp != '/')
199
- endp--;
200
-
201
- /* Either the dir is "/" or there are no slashes */
202
- if (endp == path) {
203
- path = (*endp == '/') ? "/" : ".";
204
- len = 1;
205
- goto Exit;
206
- }
207
-
208
- do {
209
- endp--;
210
- } while (endp > path && *endp == '/');
211
-
212
- if (endp - path + 1 > INT_MAX) {
213
- git_error_set(GIT_ERROR_INVALID, "path too long");
214
- len = -1;
215
- goto Exit;
216
- }
217
-
218
- if ((len = win32_prefix_length(path, (int)(endp - path + 1))) > 0) {
219
- is_prefix = 1;
220
- goto Exit;
221
- }
222
-
223
- /* Cast is safe because max path < max int */
224
- len = (int)(endp - path + 1);
225
-
226
- Exit:
227
- if (buffer) {
228
- if (git_buf_set(buffer, path, len) < 0)
229
- return -1;
230
- if (is_prefix && git_buf_putc(buffer, '/') < 0)
231
- return -1;
232
- }
233
-
234
- return len;
235
- }
236
-
237
-
238
- char *git_path_dirname(const char *path)
239
- {
240
- git_buf buf = GIT_BUF_INIT;
241
- char *dirname;
242
-
243
- git_path_dirname_r(&buf, path);
244
- dirname = git_buf_detach(&buf);
245
- git_buf_dispose(&buf); /* avoid memleak if error occurs */
246
-
247
- return dirname;
248
- }
249
-
250
- char *git_path_basename(const char *path)
251
- {
252
- git_buf buf = GIT_BUF_INIT;
253
- char *basename;
254
-
255
- git_path_basename_r(&buf, path);
256
- basename = git_buf_detach(&buf);
257
- git_buf_dispose(&buf); /* avoid memleak if error occurs */
258
-
259
- return basename;
260
- }
261
-
262
- size_t git_path_basename_offset(git_buf *buffer)
263
- {
264
- ssize_t slash;
265
-
266
- if (!buffer || buffer->size <= 0)
267
- return 0;
268
-
269
- slash = git_buf_rfind_next(buffer, '/');
270
-
271
- if (slash >= 0 && buffer->ptr[slash] == '/')
272
- return (size_t)(slash + 1);
273
-
274
- return 0;
275
- }
276
-
277
- const char *git_path_topdir(const char *path)
278
- {
279
- size_t len;
280
- ssize_t i;
281
-
282
- assert(path);
283
- len = strlen(path);
284
-
285
- if (!len || path[len - 1] != '/')
286
- return NULL;
287
-
288
- for (i = (ssize_t)len - 2; i >= 0; --i)
289
- if (path[i] == '/')
290
- break;
291
-
292
- return &path[i + 1];
293
- }
294
-
295
- int git_path_root(const char *path)
296
- {
297
- int offset = 0, prefix_len;
298
-
299
- /* Does the root of the path look like a windows drive ? */
300
- if ((prefix_len = dos_drive_prefix_length(path)))
301
- offset += prefix_len;
302
-
303
- #ifdef GIT_WIN32
304
- /* Are we dealing with a windows network path? */
305
- else if ((path[0] == '/' && path[1] == '/' && path[2] != '/') ||
306
- (path[0] == '\\' && path[1] == '\\' && path[2] != '\\'))
307
- {
308
- offset += 2;
309
-
310
- /* Skip the computer name segment */
311
- while (path[offset] && path[offset] != '/' && path[offset] != '\\')
312
- offset++;
313
- }
314
-
315
- if (path[offset] == '\\')
316
- return offset;
317
- #endif
318
-
319
- if (path[offset] == '/')
320
- return offset;
321
-
322
- return -1; /* Not a real error - signals that path is not rooted */
323
- }
324
-
325
- static void path_trim_slashes(git_buf *path)
326
- {
327
- int ceiling = git_path_root(path->ptr) + 1;
328
- assert(ceiling >= 0);
329
-
330
- while (path->size > (size_t)ceiling) {
331
- if (path->ptr[path->size-1] != '/')
332
- break;
333
-
334
- path->ptr[path->size-1] = '\0';
335
- path->size--;
336
- }
337
- }
338
-
339
- int git_path_join_unrooted(
340
- git_buf *path_out, const char *path, const char *base, ssize_t *root_at)
341
- {
342
- ssize_t root;
343
-
344
- assert(path && path_out);
345
-
346
- root = (ssize_t)git_path_root(path);
347
-
348
- if (base != NULL && root < 0) {
349
- if (git_buf_joinpath(path_out, base, path) < 0)
350
- return -1;
351
-
352
- root = (ssize_t)strlen(base);
353
- } else {
354
- if (git_buf_sets(path_out, path) < 0)
355
- return -1;
356
-
357
- if (root < 0)
358
- root = 0;
359
- else if (base)
360
- git_path_equal_or_prefixed(base, path, &root);
361
- }
362
-
363
- if (root_at)
364
- *root_at = root;
365
-
366
- return 0;
367
- }
368
-
369
- void git_path_squash_slashes(git_buf *path)
370
- {
371
- char *p, *q;
372
-
373
- if (path->size == 0)
374
- return;
375
-
376
- for (p = path->ptr, q = path->ptr; *q; p++, q++) {
377
- *p = *q;
378
-
379
- while (*q == '/' && *(q+1) == '/') {
380
- path->size--;
381
- q++;
382
- }
383
- }
384
-
385
- *p = '\0';
386
- }
387
-
388
- int git_path_prettify(git_buf *path_out, const char *path, const char *base)
389
- {
390
- char buf[GIT_PATH_MAX];
391
-
392
- assert(path && path_out);
393
-
394
- /* construct path if needed */
395
- if (base != NULL && git_path_root(path) < 0) {
396
- if (git_buf_joinpath(path_out, base, path) < 0)
397
- return -1;
398
- path = path_out->ptr;
399
- }
400
-
401
- if (p_realpath(path, buf) == NULL) {
402
- /* git_error_set resets the errno when dealing with a GIT_ERROR_OS kind of error */
403
- int error = (errno == ENOENT || errno == ENOTDIR) ? GIT_ENOTFOUND : -1;
404
- git_error_set(GIT_ERROR_OS, "failed to resolve path '%s'", path);
405
-
406
- git_buf_clear(path_out);
407
-
408
- return error;
409
- }
410
-
411
- return git_buf_sets(path_out, buf);
412
- }
413
-
414
- int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base)
415
- {
416
- int error = git_path_prettify(path_out, path, base);
417
- return (error < 0) ? error : git_path_to_dir(path_out);
418
- }
419
-
420
- int git_path_to_dir(git_buf *path)
421
- {
422
- if (path->asize > 0 &&
423
- git_buf_len(path) > 0 &&
424
- path->ptr[git_buf_len(path) - 1] != '/')
425
- git_buf_putc(path, '/');
426
-
427
- return git_buf_oom(path) ? -1 : 0;
428
- }
429
-
430
- void git_path_string_to_dir(char* path, size_t size)
431
- {
432
- size_t end = strlen(path);
433
-
434
- if (end && path[end - 1] != '/' && end < size) {
435
- path[end] = '/';
436
- path[end + 1] = '\0';
437
- }
438
- }
439
-
440
- int git__percent_decode(git_buf *decoded_out, const char *input)
441
- {
442
- int len, hi, lo, i;
443
- assert(decoded_out && input);
444
-
445
- len = (int)strlen(input);
446
- git_buf_clear(decoded_out);
447
-
448
- for(i = 0; i < len; i++)
449
- {
450
- char c = input[i];
451
-
452
- if (c != '%')
453
- goto append;
454
-
455
- if (i >= len - 2)
456
- goto append;
457
-
458
- hi = git__fromhex(input[i + 1]);
459
- lo = git__fromhex(input[i + 2]);
460
-
461
- if (hi < 0 || lo < 0)
462
- goto append;
463
-
464
- c = (char)(hi << 4 | lo);
465
- i += 2;
466
-
467
- append:
468
- if (git_buf_putc(decoded_out, c) < 0)
469
- return -1;
470
- }
471
-
472
- return 0;
473
- }
474
-
475
- static int error_invalid_local_file_uri(const char *uri)
476
- {
477
- git_error_set(GIT_ERROR_CONFIG, "'%s' is not a valid local file URI", uri);
478
- return -1;
479
- }
480
-
481
- static int local_file_url_prefixlen(const char *file_url)
482
- {
483
- int len = -1;
484
-
485
- if (git__prefixcmp(file_url, "file://") == 0) {
486
- if (file_url[7] == '/')
487
- len = 8;
488
- else if (git__prefixcmp(file_url + 7, "localhost/") == 0)
489
- len = 17;
490
- }
491
-
492
- return len;
493
- }
494
-
495
- bool git_path_is_local_file_url(const char *file_url)
496
- {
497
- return (local_file_url_prefixlen(file_url) > 0);
498
- }
499
-
500
- int git_path_fromurl(git_buf *local_path_out, const char *file_url)
501
- {
502
- int offset;
503
-
504
- assert(local_path_out && file_url);
505
-
506
- if ((offset = local_file_url_prefixlen(file_url)) < 0 ||
507
- file_url[offset] == '\0' || file_url[offset] == '/')
508
- return error_invalid_local_file_uri(file_url);
509
-
510
- #ifndef GIT_WIN32
511
- offset--; /* A *nix absolute path starts with a forward slash */
512
- #endif
513
-
514
- git_buf_clear(local_path_out);
515
- return git__percent_decode(local_path_out, file_url + offset);
516
- }
517
-
518
- int git_path_walk_up(
519
- git_buf *path,
520
- const char *ceiling,
521
- int (*cb)(void *data, const char *),
522
- void *data)
523
- {
524
- int error = 0;
525
- git_buf iter;
526
- ssize_t stop = 0, scan;
527
- char oldc = '\0';
528
-
529
- assert(path && cb);
530
-
531
- if (ceiling != NULL) {
532
- if (git__prefixcmp(path->ptr, ceiling) == 0)
533
- stop = (ssize_t)strlen(ceiling);
534
- else
535
- stop = git_buf_len(path);
536
- }
537
- scan = git_buf_len(path);
538
-
539
- /* empty path: yield only once */
540
- if (!scan) {
541
- error = cb(data, "");
542
- if (error)
543
- git_error_set_after_callback(error);
544
- return error;
545
- }
546
-
547
- iter.ptr = path->ptr;
548
- iter.size = git_buf_len(path);
549
- iter.asize = path->asize;
550
-
551
- while (scan >= stop) {
552
- error = cb(data, iter.ptr);
553
- iter.ptr[scan] = oldc;
554
-
555
- if (error) {
556
- git_error_set_after_callback(error);
557
- break;
558
- }
559
-
560
- scan = git_buf_rfind_next(&iter, '/');
561
- if (scan >= 0) {
562
- scan++;
563
- oldc = iter.ptr[scan];
564
- iter.size = scan;
565
- iter.ptr[scan] = '\0';
566
- }
567
- }
568
-
569
- if (scan >= 0)
570
- iter.ptr[scan] = oldc;
571
-
572
- /* relative path: yield for the last component */
573
- if (!error && stop == 0 && iter.ptr[0] != '/') {
574
- error = cb(data, "");
575
- if (error)
576
- git_error_set_after_callback(error);
577
- }
578
-
579
- return error;
580
- }
581
-
582
- bool git_path_exists(const char *path)
583
- {
584
- assert(path);
585
- return p_access(path, F_OK) == 0;
586
- }
587
-
588
- bool git_path_isdir(const char *path)
589
- {
590
- struct stat st;
591
- if (p_stat(path, &st) < 0)
592
- return false;
593
-
594
- return S_ISDIR(st.st_mode) != 0;
595
- }
596
-
597
- bool git_path_isfile(const char *path)
598
- {
599
- struct stat st;
600
-
601
- assert(path);
602
- if (p_stat(path, &st) < 0)
603
- return false;
604
-
605
- return S_ISREG(st.st_mode) != 0;
606
- }
607
-
608
- bool git_path_islink(const char *path)
609
- {
610
- struct stat st;
611
-
612
- assert(path);
613
- if (p_lstat(path, &st) < 0)
614
- return false;
615
-
616
- return S_ISLNK(st.st_mode) != 0;
617
- }
618
-
619
- #ifdef GIT_WIN32
620
-
621
- bool git_path_is_empty_dir(const char *path)
622
- {
623
- git_win32_path filter_w;
624
- bool empty = false;
625
-
626
- if (git_win32__findfirstfile_filter(filter_w, path)) {
627
- WIN32_FIND_DATAW findData;
628
- HANDLE hFind = FindFirstFileW(filter_w, &findData);
629
-
630
- /* FindFirstFile will fail if there are no children to the given
631
- * path, which can happen if the given path is a file (and obviously
632
- * has no children) or if the given path is an empty mount point.
633
- * (Most directories have at least directory entries '.' and '..',
634
- * but ridiculously another volume mounted in another drive letter's
635
- * path space do not, and thus have nothing to enumerate.) If
636
- * FindFirstFile fails, check if this is a directory-like thing
637
- * (a mount point).
638
- */
639
- if (hFind == INVALID_HANDLE_VALUE)
640
- return git_path_isdir(path);
641
-
642
- /* If the find handle was created successfully, then it's a directory */
643
- empty = true;
644
-
645
- do {
646
- /* Allow the enumeration to return . and .. and still be considered
647
- * empty. In the special case of drive roots (i.e. C:\) where . and
648
- * .. do not occur, we can still consider the path to be an empty
649
- * directory if there's nothing there. */
650
- if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
651
- empty = false;
652
- break;
653
- }
654
- } while (FindNextFileW(hFind, &findData));
655
-
656
- FindClose(hFind);
657
- }
658
-
659
- return empty;
660
- }
661
-
662
- #else
663
-
664
- static int path_found_entry(void *payload, git_buf *path)
665
- {
666
- GIT_UNUSED(payload);
667
- return !git_path_is_dot_or_dotdot(path->ptr);
668
- }
669
-
670
- bool git_path_is_empty_dir(const char *path)
671
- {
672
- int error;
673
- git_buf dir = GIT_BUF_INIT;
674
-
675
- if (!git_path_isdir(path))
676
- return false;
677
-
678
- if ((error = git_buf_sets(&dir, path)) != 0)
679
- git_error_clear();
680
- else
681
- error = git_path_direach(&dir, 0, path_found_entry, NULL);
682
-
683
- git_buf_dispose(&dir);
684
-
685
- return !error;
686
- }
687
-
688
- #endif
689
-
690
- int git_path_set_error(int errno_value, const char *path, const char *action)
691
- {
692
- switch (errno_value) {
693
- case ENOENT:
694
- case ENOTDIR:
695
- git_error_set(GIT_ERROR_OS, "could not find '%s' to %s", path, action);
696
- return GIT_ENOTFOUND;
697
-
698
- case EINVAL:
699
- case ENAMETOOLONG:
700
- git_error_set(GIT_ERROR_OS, "invalid path for filesystem '%s'", path);
701
- return GIT_EINVALIDSPEC;
702
-
703
- case EEXIST:
704
- git_error_set(GIT_ERROR_OS, "failed %s - '%s' already exists", action, path);
705
- return GIT_EEXISTS;
706
-
707
- case EACCES:
708
- git_error_set(GIT_ERROR_OS, "failed %s - '%s' is locked", action, path);
709
- return GIT_ELOCKED;
710
-
711
- default:
712
- git_error_set(GIT_ERROR_OS, "could not %s '%s'", action, path);
713
- return -1;
714
- }
715
- }
716
-
717
- int git_path_lstat(const char *path, struct stat *st)
718
- {
719
- if (p_lstat(path, st) == 0)
720
- return 0;
721
-
722
- return git_path_set_error(errno, path, "stat");
723
- }
724
-
725
- static bool _check_dir_contents(
726
- git_buf *dir,
727
- const char *sub,
728
- bool (*predicate)(const char *))
729
- {
730
- bool result;
731
- size_t dir_size = git_buf_len(dir);
732
- size_t sub_size = strlen(sub);
733
- size_t alloc_size;
734
-
735
- /* leave base valid even if we could not make space for subdir */
736
- if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
737
- GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
738
- git_buf_try_grow(dir, alloc_size, false) < 0)
739
- return false;
740
-
741
- /* save excursion */
742
- if (git_buf_joinpath(dir, dir->ptr, sub) < 0)
743
- return false;
744
-
745
- result = predicate(dir->ptr);
746
-
747
- /* restore path */
748
- git_buf_truncate(dir, dir_size);
749
- return result;
750
- }
751
-
752
- bool git_path_contains(git_buf *dir, const char *item)
753
- {
754
- return _check_dir_contents(dir, item, &git_path_exists);
755
- }
756
-
757
- bool git_path_contains_dir(git_buf *base, const char *subdir)
758
- {
759
- return _check_dir_contents(base, subdir, &git_path_isdir);
760
- }
761
-
762
- bool git_path_contains_file(git_buf *base, const char *file)
763
- {
764
- return _check_dir_contents(base, file, &git_path_isfile);
765
- }
766
-
767
- int git_path_find_dir(git_buf *dir, const char *path, const char *base)
768
- {
769
- int error = git_path_join_unrooted(dir, path, base, NULL);
770
-
771
- if (!error) {
772
- char buf[GIT_PATH_MAX];
773
- if (p_realpath(dir->ptr, buf) != NULL)
774
- error = git_buf_sets(dir, buf);
775
- }
776
-
777
- /* call dirname if this is not a directory */
778
- if (!error) /* && git_path_isdir(dir->ptr) == false) */
779
- error = (git_path_dirname_r(dir, dir->ptr) < 0) ? -1 : 0;
780
-
781
- if (!error)
782
- error = git_path_to_dir(dir);
783
-
784
- return error;
785
- }
786
-
787
- int git_path_resolve_relative(git_buf *path, size_t ceiling)
788
- {
789
- char *base, *to, *from, *next;
790
- size_t len;
791
-
792
- GIT_ERROR_CHECK_ALLOC_BUF(path);
793
-
794
- if (ceiling > path->size)
795
- ceiling = path->size;
796
-
797
- /* recognize drive prefixes, etc. that should not be backed over */
798
- if (ceiling == 0)
799
- ceiling = git_path_root(path->ptr) + 1;
800
-
801
- /* recognize URL prefixes that should not be backed over */
802
- if (ceiling == 0) {
803
- for (next = path->ptr; *next && git__isalpha(*next); ++next);
804
- if (next[0] == ':' && next[1] == '/' && next[2] == '/')
805
- ceiling = (next + 3) - path->ptr;
806
- }
807
-
808
- base = to = from = path->ptr + ceiling;
809
-
810
- while (*from) {
811
- for (next = from; *next && *next != '/'; ++next);
812
-
813
- len = next - from;
814
-
815
- if (len == 1 && from[0] == '.')
816
- /* do nothing with singleton dot */;
817
-
818
- else if (len == 2 && from[0] == '.' && from[1] == '.') {
819
- /* error out if trying to up one from a hard base */
820
- if (to == base && ceiling != 0) {
821
- git_error_set(GIT_ERROR_INVALID,
822
- "cannot strip root component off url");
823
- return -1;
824
- }
825
-
826
- /* no more path segments to strip,
827
- * use '../' as a new base path */
828
- if (to == base) {
829
- if (*next == '/')
830
- len++;
831
-
832
- if (to != from)
833
- memmove(to, from, len);
834
-
835
- to += len;
836
- /* this is now the base, can't back up from a
837
- * relative prefix */
838
- base = to;
839
- } else {
840
- /* back up a path segment */
841
- while (to > base && to[-1] == '/') to--;
842
- while (to > base && to[-1] != '/') to--;
843
- }
844
- } else {
845
- if (*next == '/' && *from != '/')
846
- len++;
847
-
848
- if (to != from)
849
- memmove(to, from, len);
850
-
851
- to += len;
852
- }
853
-
854
- from += len;
855
-
856
- while (*from == '/') from++;
857
- }
858
-
859
- *to = '\0';
860
-
861
- path->size = to - path->ptr;
862
-
863
- return 0;
864
- }
865
-
866
- int git_path_apply_relative(git_buf *target, const char *relpath)
867
- {
868
- return git_buf_joinpath(target, git_buf_cstr(target), relpath) ||
869
- git_path_resolve_relative(target, 0);
870
- }
871
-
872
- int git_path_cmp(
873
- const char *name1, size_t len1, int isdir1,
874
- const char *name2, size_t len2, int isdir2,
875
- int (*compare)(const char *, const char *, size_t))
876
- {
877
- unsigned char c1, c2;
878
- size_t len = len1 < len2 ? len1 : len2;
879
- int cmp;
880
-
881
- cmp = compare(name1, name2, len);
882
- if (cmp)
883
- return cmp;
884
-
885
- c1 = name1[len];
886
- c2 = name2[len];
887
-
888
- if (c1 == '\0' && isdir1)
889
- c1 = '/';
890
-
891
- if (c2 == '\0' && isdir2)
892
- c2 = '/';
893
-
894
- return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
895
- }
896
-
897
- size_t git_path_common_dirlen(const char *one, const char *two)
898
- {
899
- const char *p, *q, *dirsep = NULL;
900
-
901
- for (p = one, q = two; *p && *q; p++, q++) {
902
- if (*p == '/' && *q == '/')
903
- dirsep = p;
904
- else if (*p != *q)
905
- break;
906
- }
907
-
908
- return dirsep ? (dirsep - one) + 1 : 0;
909
- }
910
-
911
- int git_path_make_relative(git_buf *path, const char *parent)
912
- {
913
- const char *p, *q, *p_dirsep, *q_dirsep;
914
- size_t plen = path->size, newlen, alloclen, depth = 1, i, offset;
915
-
916
- for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) {
917
- if (*p == '/' && *q == '/') {
918
- p_dirsep = p;
919
- q_dirsep = q;
920
- }
921
- else if (*p != *q)
922
- break;
923
- }
924
-
925
- /* need at least 1 common path segment */
926
- if ((p_dirsep == path->ptr || q_dirsep == parent) &&
927
- (*p_dirsep != '/' || *q_dirsep != '/')) {
928
- git_error_set(GIT_ERROR_INVALID,
929
- "%s is not a parent of %s", parent, path->ptr);
930
- return GIT_ENOTFOUND;
931
- }
932
-
933
- if (*p == '/' && !*q)
934
- p++;
935
- else if (!*p && *q == '/')
936
- q++;
937
- else if (!*p && !*q)
938
- return git_buf_clear(path), 0;
939
- else {
940
- p = p_dirsep + 1;
941
- q = q_dirsep + 1;
942
- }
943
-
944
- plen -= (p - path->ptr);
945
-
946
- if (!*q)
947
- return git_buf_set(path, p, plen);
948
-
949
- for (; (q = strchr(q, '/')) && *(q + 1); q++)
950
- depth++;
951
-
952
- GIT_ERROR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3);
953
- GIT_ERROR_CHECK_ALLOC_ADD(&newlen, newlen, plen);
954
-
955
- GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, newlen, 1);
956
-
957
- /* save the offset as we might realllocate the pointer */
958
- offset = p - path->ptr;
959
- if (git_buf_try_grow(path, alloclen, 1) < 0)
960
- return -1;
961
- p = path->ptr + offset;
962
-
963
- memmove(path->ptr + (depth * 3), p, plen + 1);
964
-
965
- for (i = 0; i < depth; i++)
966
- memcpy(path->ptr + (i * 3), "../", 3);
967
-
968
- path->size = newlen;
969
- return 0;
970
- }
971
-
972
- bool git_path_has_non_ascii(const char *path, size_t pathlen)
973
- {
974
- const uint8_t *scan = (const uint8_t *)path, *end;
975
-
976
- for (end = scan + pathlen; scan < end; ++scan)
977
- if (*scan & 0x80)
978
- return true;
979
-
980
- return false;
981
- }
982
-
983
- #ifdef GIT_USE_ICONV
984
-
985
- int git_path_iconv_init_precompose(git_path_iconv_t *ic)
986
- {
987
- git_buf_init(&ic->buf, 0);
988
- ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING);
989
- return 0;
990
- }
991
-
992
- void git_path_iconv_clear(git_path_iconv_t *ic)
993
- {
994
- if (ic) {
995
- if (ic->map != (iconv_t)-1)
996
- iconv_close(ic->map);
997
- git_buf_dispose(&ic->buf);
998
- }
999
- }
1000
-
1001
- int git_path_iconv(git_path_iconv_t *ic, const char **in, size_t *inlen)
1002
- {
1003
- char *nfd = (char*)*in, *nfc;
1004
- size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv;
1005
- int retry = 1;
1006
-
1007
- if (!ic || ic->map == (iconv_t)-1 ||
1008
- !git_path_has_non_ascii(*in, *inlen))
1009
- return 0;
1010
-
1011
- git_buf_clear(&ic->buf);
1012
-
1013
- while (1) {
1014
- GIT_ERROR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1);
1015
- if (git_buf_grow(&ic->buf, alloclen) < 0)
1016
- return -1;
1017
-
1018
- nfc = ic->buf.ptr + ic->buf.size;
1019
- nfclen = ic->buf.asize - ic->buf.size;
1020
-
1021
- rv = iconv(ic->map, &nfd, &nfdlen, &nfc, &nfclen);
1022
-
1023
- ic->buf.size = (nfc - ic->buf.ptr);
1024
-
1025
- if (rv != (size_t)-1)
1026
- break;
1027
-
1028
- /* if we cannot convert the data (probably because iconv thinks
1029
- * it is not valid UTF-8 source data), then use original data
1030
- */
1031
- if (errno != E2BIG)
1032
- return 0;
1033
-
1034
- /* make space for 2x the remaining data to be converted
1035
- * (with per retry overhead to avoid infinite loops)
1036
- */
1037
- wantlen = ic->buf.size + max(nfclen, nfdlen) * 2 + (size_t)(retry * 4);
1038
-
1039
- if (retry++ > 4)
1040
- goto fail;
1041
- }
1042
-
1043
- ic->buf.ptr[ic->buf.size] = '\0';
1044
-
1045
- *in = ic->buf.ptr;
1046
- *inlen = ic->buf.size;
1047
-
1048
- return 0;
1049
-
1050
- fail:
1051
- git_error_set(GIT_ERROR_OS, "unable to convert unicode path data");
1052
- return -1;
1053
- }
1054
-
1055
- static const char *nfc_file = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D.XXXXXX";
1056
- static const char *nfd_file = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D.XXXXXX";
1057
-
1058
- /* Check if the platform is decomposing unicode data for us. We will
1059
- * emulate core Git and prefer to use precomposed unicode data internally
1060
- * on these platforms, composing the decomposed unicode on the fly.
1061
- *
1062
- * This mainly happens on the Mac where HDFS stores filenames as
1063
- * decomposed unicode. Even on VFAT and SAMBA file systems, the Mac will
1064
- * return decomposed unicode from readdir() even when the actual
1065
- * filesystem is storing precomposed unicode.
1066
- */
1067
- bool git_path_does_fs_decompose_unicode(const char *root)
1068
- {
1069
- git_buf path = GIT_BUF_INIT;
1070
- int fd;
1071
- bool found_decomposed = false;
1072
- char tmp[6];
1073
-
1074
- /* Create a file using a precomposed path and then try to find it
1075
- * using the decomposed name. If the lookup fails, then we will mark
1076
- * that we should precompose unicode for this repository.
1077
- */
1078
- if (git_buf_joinpath(&path, root, nfc_file) < 0 ||
1079
- (fd = p_mkstemp(path.ptr)) < 0)
1080
- goto done;
1081
- p_close(fd);
1082
-
1083
- /* record trailing digits generated by mkstemp */
1084
- memcpy(tmp, path.ptr + path.size - sizeof(tmp), sizeof(tmp));
1085
-
1086
- /* try to look up as NFD path */
1087
- if (git_buf_joinpath(&path, root, nfd_file) < 0)
1088
- goto done;
1089
- memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
1090
-
1091
- found_decomposed = git_path_exists(path.ptr);
1092
-
1093
- /* remove temporary file (using original precomposed path) */
1094
- if (git_buf_joinpath(&path, root, nfc_file) < 0)
1095
- goto done;
1096
- memcpy(path.ptr + path.size - sizeof(tmp), tmp, sizeof(tmp));
1097
-
1098
- (void)p_unlink(path.ptr);
1099
-
1100
- done:
1101
- git_buf_dispose(&path);
1102
- return found_decomposed;
1103
- }
1104
-
1105
- #else
1106
-
1107
- bool git_path_does_fs_decompose_unicode(const char *root)
1108
- {
1109
- GIT_UNUSED(root);
1110
- return false;
1111
- }
1112
-
1113
- #endif
1114
-
1115
- #if defined(__sun) || defined(__GNU__)
1116
- typedef char path_dirent_data[sizeof(struct dirent) + FILENAME_MAX + 1];
1117
- #else
1118
- typedef struct dirent path_dirent_data;
1119
- #endif
1120
-
1121
- int git_path_direach(
1122
- git_buf *path,
1123
- uint32_t flags,
1124
- int (*fn)(void *, git_buf *),
1125
- void *arg)
1126
- {
1127
- int error = 0;
1128
- ssize_t wd_len;
1129
- DIR *dir;
1130
- struct dirent *de;
1131
-
1132
- #ifdef GIT_USE_ICONV
1133
- git_path_iconv_t ic = GIT_PATH_ICONV_INIT;
1134
- #endif
1135
-
1136
- GIT_UNUSED(flags);
1137
-
1138
- if (git_path_to_dir(path) < 0)
1139
- return -1;
1140
-
1141
- wd_len = git_buf_len(path);
1142
-
1143
- if ((dir = opendir(path->ptr)) == NULL) {
1144
- git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path->ptr);
1145
- if (errno == ENOENT)
1146
- return GIT_ENOTFOUND;
1147
-
1148
- return -1;
1149
- }
1150
-
1151
- #ifdef GIT_USE_ICONV
1152
- if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
1153
- (void)git_path_iconv_init_precompose(&ic);
1154
- #endif
1155
-
1156
- while ((de = readdir(dir)) != NULL) {
1157
- const char *de_path = de->d_name;
1158
- size_t de_len = strlen(de_path);
1159
-
1160
- if (git_path_is_dot_or_dotdot(de_path))
1161
- continue;
1162
-
1163
- #ifdef GIT_USE_ICONV
1164
- if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0)
1165
- break;
1166
- #endif
1167
-
1168
- if ((error = git_buf_put(path, de_path, de_len)) < 0)
1169
- break;
1170
-
1171
- git_error_clear();
1172
- error = fn(arg, path);
1173
-
1174
- git_buf_truncate(path, wd_len); /* restore path */
1175
-
1176
- /* Only set our own error if the callback did not set one already */
1177
- if (error != 0) {
1178
- if (!git_error_last())
1179
- git_error_set_after_callback(error);
1180
-
1181
- break;
1182
- }
1183
- }
1184
-
1185
- closedir(dir);
1186
-
1187
- #ifdef GIT_USE_ICONV
1188
- git_path_iconv_clear(&ic);
1189
- #endif
1190
-
1191
- return error;
1192
- }
1193
-
1194
- #if defined(GIT_WIN32) && !defined(__MINGW32__)
1195
-
1196
- /* Using _FIND_FIRST_EX_LARGE_FETCH may increase performance in Windows 7
1197
- * and better.
1198
- */
1199
- #ifndef FIND_FIRST_EX_LARGE_FETCH
1200
- # define FIND_FIRST_EX_LARGE_FETCH 2
1201
- #endif
1202
-
1203
- int git_path_diriter_init(
1204
- git_path_diriter *diriter,
1205
- const char *path,
1206
- unsigned int flags)
1207
- {
1208
- git_win32_path path_filter;
1209
-
1210
- static int is_win7_or_later = -1;
1211
- if (is_win7_or_later < 0)
1212
- is_win7_or_later = git_has_win32_version(6, 1, 0);
1213
-
1214
- assert(diriter && path);
1215
-
1216
- memset(diriter, 0, sizeof(git_path_diriter));
1217
- diriter->handle = INVALID_HANDLE_VALUE;
1218
-
1219
- if (git_buf_puts(&diriter->path_utf8, path) < 0)
1220
- return -1;
1221
-
1222
- path_trim_slashes(&diriter->path_utf8);
1223
-
1224
- if (diriter->path_utf8.size == 0) {
1225
- git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path);
1226
- return -1;
1227
- }
1228
-
1229
- if ((diriter->parent_len = git_win32_path_from_utf8(diriter->path, diriter->path_utf8.ptr)) < 0 ||
1230
- !git_win32__findfirstfile_filter(path_filter, diriter->path_utf8.ptr)) {
1231
- git_error_set(GIT_ERROR_OS, "could not parse the directory path '%s'", path);
1232
- return -1;
1233
- }
1234
-
1235
- diriter->handle = FindFirstFileExW(
1236
- path_filter,
1237
- is_win7_or_later ? FindExInfoBasic : FindExInfoStandard,
1238
- &diriter->current,
1239
- FindExSearchNameMatch,
1240
- NULL,
1241
- is_win7_or_later ? FIND_FIRST_EX_LARGE_FETCH : 0);
1242
-
1243
- if (diriter->handle == INVALID_HANDLE_VALUE) {
1244
- git_error_set(GIT_ERROR_OS, "could not open directory '%s'", path);
1245
- return -1;
1246
- }
1247
-
1248
- diriter->parent_utf8_len = diriter->path_utf8.size;
1249
- diriter->flags = flags;
1250
- return 0;
1251
- }
1252
-
1253
- static int diriter_update_paths(git_path_diriter *diriter)
1254
- {
1255
- size_t filename_len, path_len;
1256
-
1257
- filename_len = wcslen(diriter->current.cFileName);
1258
-
1259
- if (GIT_ADD_SIZET_OVERFLOW(&path_len, diriter->parent_len, filename_len) ||
1260
- GIT_ADD_SIZET_OVERFLOW(&path_len, path_len, 2))
1261
- return -1;
1262
-
1263
- if (path_len > GIT_WIN_PATH_UTF16) {
1264
- git_error_set(GIT_ERROR_FILESYSTEM,
1265
- "invalid path '%.*ls\\%ls' (path too long)",
1266
- diriter->parent_len, diriter->path, diriter->current.cFileName);
1267
- return -1;
1268
- }
1269
-
1270
- diriter->path[diriter->parent_len] = L'\\';
1271
- memcpy(&diriter->path[diriter->parent_len+1],
1272
- diriter->current.cFileName, filename_len * sizeof(wchar_t));
1273
- diriter->path[path_len-1] = L'\0';
1274
-
1275
- git_buf_truncate(&diriter->path_utf8, diriter->parent_utf8_len);
1276
-
1277
- if (diriter->parent_utf8_len > 0 &&
1278
- diriter->path_utf8.ptr[diriter->parent_utf8_len-1] != '/')
1279
- git_buf_putc(&diriter->path_utf8, '/');
1280
-
1281
- git_buf_put_w(&diriter->path_utf8, diriter->current.cFileName, filename_len);
1282
-
1283
- if (git_buf_oom(&diriter->path_utf8))
1284
- return -1;
1285
-
1286
- return 0;
1287
- }
1288
-
1289
- int git_path_diriter_next(git_path_diriter *diriter)
1290
- {
1291
- bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
1292
-
1293
- do {
1294
- /* Our first time through, we already have the data from
1295
- * FindFirstFileW. Use it, otherwise get the next file.
1296
- */
1297
- if (!diriter->needs_next)
1298
- diriter->needs_next = 1;
1299
- else if (!FindNextFileW(diriter->handle, &diriter->current))
1300
- return GIT_ITEROVER;
1301
- } while (skip_dot && git_path_is_dot_or_dotdotW(diriter->current.cFileName));
1302
-
1303
- if (diriter_update_paths(diriter) < 0)
1304
- return -1;
1305
-
1306
- return 0;
1307
- }
1308
-
1309
- int git_path_diriter_filename(
1310
- const char **out,
1311
- size_t *out_len,
1312
- git_path_diriter *diriter)
1313
- {
1314
- assert(out && out_len && diriter);
1315
-
1316
- assert(diriter->path_utf8.size > diriter->parent_utf8_len);
1317
-
1318
- *out = &diriter->path_utf8.ptr[diriter->parent_utf8_len+1];
1319
- *out_len = diriter->path_utf8.size - diriter->parent_utf8_len - 1;
1320
- return 0;
1321
- }
1322
-
1323
- int git_path_diriter_fullpath(
1324
- const char **out,
1325
- size_t *out_len,
1326
- git_path_diriter *diriter)
1327
- {
1328
- assert(out && out_len && diriter);
1329
-
1330
- *out = diriter->path_utf8.ptr;
1331
- *out_len = diriter->path_utf8.size;
1332
- return 0;
1333
- }
1334
-
1335
- int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter)
1336
- {
1337
- assert(out && diriter);
1338
-
1339
- return git_win32__file_attribute_to_stat(out,
1340
- (WIN32_FILE_ATTRIBUTE_DATA *)&diriter->current,
1341
- diriter->path);
1342
- }
1343
-
1344
- void git_path_diriter_free(git_path_diriter *diriter)
1345
- {
1346
- if (diriter == NULL)
1347
- return;
1348
-
1349
- git_buf_dispose(&diriter->path_utf8);
1350
-
1351
- if (diriter->handle != INVALID_HANDLE_VALUE) {
1352
- FindClose(diriter->handle);
1353
- diriter->handle = INVALID_HANDLE_VALUE;
1354
- }
1355
- }
1356
-
1357
- #else
1358
-
1359
- int git_path_diriter_init(
1360
- git_path_diriter *diriter,
1361
- const char *path,
1362
- unsigned int flags)
1363
- {
1364
- assert(diriter && path);
1365
-
1366
- memset(diriter, 0, sizeof(git_path_diriter));
1367
-
1368
- if (git_buf_puts(&diriter->path, path) < 0)
1369
- return -1;
1370
-
1371
- path_trim_slashes(&diriter->path);
1372
-
1373
- if (diriter->path.size == 0) {
1374
- git_error_set(GIT_ERROR_FILESYSTEM, "could not open directory '%s'", path);
1375
- return -1;
1376
- }
1377
-
1378
- if ((diriter->dir = opendir(diriter->path.ptr)) == NULL) {
1379
- git_buf_dispose(&diriter->path);
1380
-
1381
- git_error_set(GIT_ERROR_OS, "failed to open directory '%s'", path);
1382
- return -1;
1383
- }
1384
-
1385
- #ifdef GIT_USE_ICONV
1386
- if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0)
1387
- (void)git_path_iconv_init_precompose(&diriter->ic);
1388
- #endif
1389
-
1390
- diriter->parent_len = diriter->path.size;
1391
- diriter->flags = flags;
1392
-
1393
- return 0;
1394
- }
1395
-
1396
- int git_path_diriter_next(git_path_diriter *diriter)
1397
- {
1398
- struct dirent *de;
1399
- const char *filename;
1400
- size_t filename_len;
1401
- bool skip_dot = !(diriter->flags & GIT_PATH_DIR_INCLUDE_DOT_AND_DOTDOT);
1402
- int error = 0;
1403
-
1404
- assert(diriter);
1405
-
1406
- errno = 0;
1407
-
1408
- do {
1409
- if ((de = readdir(diriter->dir)) == NULL) {
1410
- if (!errno)
1411
- return GIT_ITEROVER;
1412
-
1413
- git_error_set(GIT_ERROR_OS,
1414
- "could not read directory '%s'", diriter->path.ptr);
1415
- return -1;
1416
- }
1417
- } while (skip_dot && git_path_is_dot_or_dotdot(de->d_name));
1418
-
1419
- filename = de->d_name;
1420
- filename_len = strlen(filename);
1421
-
1422
- #ifdef GIT_USE_ICONV
1423
- if ((diriter->flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0 &&
1424
- (error = git_path_iconv(&diriter->ic, &filename, &filename_len)) < 0)
1425
- return error;
1426
- #endif
1427
-
1428
- git_buf_truncate(&diriter->path, diriter->parent_len);
1429
-
1430
- if (diriter->parent_len > 0 &&
1431
- diriter->path.ptr[diriter->parent_len-1] != '/')
1432
- git_buf_putc(&diriter->path, '/');
1433
-
1434
- git_buf_put(&diriter->path, filename, filename_len);
1435
-
1436
- if (git_buf_oom(&diriter->path))
1437
- return -1;
1438
-
1439
- return error;
1440
- }
1441
-
1442
- int git_path_diriter_filename(
1443
- const char **out,
1444
- size_t *out_len,
1445
- git_path_diriter *diriter)
1446
- {
1447
- assert(out && out_len && diriter);
1448
-
1449
- assert(diriter->path.size > diriter->parent_len);
1450
-
1451
- *out = &diriter->path.ptr[diriter->parent_len+1];
1452
- *out_len = diriter->path.size - diriter->parent_len - 1;
1453
- return 0;
1454
- }
1455
-
1456
- int git_path_diriter_fullpath(
1457
- const char **out,
1458
- size_t *out_len,
1459
- git_path_diriter *diriter)
1460
- {
1461
- assert(out && out_len && diriter);
1462
-
1463
- *out = diriter->path.ptr;
1464
- *out_len = diriter->path.size;
1465
- return 0;
1466
- }
1467
-
1468
- int git_path_diriter_stat(struct stat *out, git_path_diriter *diriter)
1469
- {
1470
- assert(out && diriter);
1471
-
1472
- return git_path_lstat(diriter->path.ptr, out);
1473
- }
1474
-
1475
- void git_path_diriter_free(git_path_diriter *diriter)
1476
- {
1477
- if (diriter == NULL)
1478
- return;
1479
-
1480
- if (diriter->dir) {
1481
- closedir(diriter->dir);
1482
- diriter->dir = NULL;
1483
- }
1484
-
1485
- #ifdef GIT_USE_ICONV
1486
- git_path_iconv_clear(&diriter->ic);
1487
- #endif
1488
-
1489
- git_buf_dispose(&diriter->path);
1490
- }
1491
-
1492
- #endif
1493
-
1494
- int git_path_dirload(
1495
- git_vector *contents,
1496
- const char *path,
1497
- size_t prefix_len,
1498
- uint32_t flags)
1499
- {
1500
- git_path_diriter iter = GIT_PATH_DIRITER_INIT;
1501
- const char *name;
1502
- size_t name_len;
1503
- char *dup;
1504
- int error;
1505
-
1506
- assert(contents && path);
1507
-
1508
- if ((error = git_path_diriter_init(&iter, path, flags)) < 0)
1509
- return error;
1510
-
1511
- while ((error = git_path_diriter_next(&iter)) == 0) {
1512
- if ((error = git_path_diriter_fullpath(&name, &name_len, &iter)) < 0)
1513
- break;
1514
-
1515
- assert(name_len > prefix_len);
1516
-
1517
- dup = git__strndup(name + prefix_len, name_len - prefix_len);
1518
- GIT_ERROR_CHECK_ALLOC(dup);
1519
-
1520
- if ((error = git_vector_insert(contents, dup)) < 0)
1521
- break;
1522
- }
1523
-
1524
- if (error == GIT_ITEROVER)
1525
- error = 0;
1526
-
1527
- git_path_diriter_free(&iter);
1528
- return error;
1529
- }
1530
-
1531
- int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
1532
- {
1533
- if (git_path_is_local_file_url(url_or_path))
1534
- return git_path_fromurl(local_path_out, url_or_path);
1535
- else
1536
- return git_buf_sets(local_path_out, url_or_path);
1537
- }
1538
-
1539
- /* Reject paths like AUX or COM1, or those versions that end in a dot or
1540
- * colon. ("AUX." or "AUX:")
1541
- */
1542
- GIT_INLINE(bool) verify_dospath(
1543
- const char *component,
1544
- size_t len,
1545
- const char dospath[3],
1546
- bool trailing_num)
1547
- {
1548
- size_t last = trailing_num ? 4 : 3;
1549
-
1550
- if (len < last || git__strncasecmp(component, dospath, 3) != 0)
1551
- return true;
11
+ #include "fs_path.h"
1552
12
 
1553
- if (trailing_num && (component[3] < '1' || component[3] > '9'))
1554
- return true;
1555
-
1556
- return (len > last &&
1557
- component[last] != '.' &&
1558
- component[last] != ':');
1559
- }
13
+ typedef struct {
14
+ git_repository *repo;
15
+ uint16_t file_mode;
16
+ unsigned int flags;
17
+ } repository_path_validate_data;
1560
18
 
1561
19
  static int32_t next_hfs_char(const char **in, size_t *len)
1562
20
  {
1563
21
  while (*len) {
1564
- int32_t codepoint;
1565
- int cp_len = git__utf8_iterate((const uint8_t *)(*in), (int)(*len), &codepoint);
22
+ uint32_t codepoint;
23
+ int cp_len = git_utf8_iterate(&codepoint, *in, *len);
1566
24
  if (cp_len < 0)
1567
25
  return -1;
1568
26
 
@@ -1594,12 +52,16 @@ static int32_t next_hfs_char(const char **in, size_t *len)
1594
52
  * the ASCII range, which is perfectly fine, because the
1595
53
  * git folder name can only be composed of ascii characters
1596
54
  */
1597
- return git__tolower(codepoint);
55
+ return git__tolower((int)codepoint);
1598
56
  }
1599
57
  return 0; /* NULL byte -- end of string */
1600
58
  }
1601
59
 
1602
- static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *needle, size_t needle_len)
60
+ static bool validate_dotgit_hfs_generic(
61
+ const char *path,
62
+ size_t len,
63
+ const char *needle,
64
+ size_t needle_len)
1603
65
  {
1604
66
  size_t i;
1605
67
  char c;
@@ -1619,14 +81,17 @@ static bool verify_dotgit_hfs_generic(const char *path, size_t len, const char *
1619
81
  return false;
1620
82
  }
1621
83
 
1622
- static bool verify_dotgit_hfs(const char *path, size_t len)
84
+ static bool validate_dotgit_hfs(const char *path, size_t len)
1623
85
  {
1624
- return verify_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git"));
86
+ return validate_dotgit_hfs_generic(path, len, "git", CONST_STRLEN("git"));
1625
87
  }
1626
88
 
1627
- GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size_t len)
89
+ GIT_INLINE(bool) validate_dotgit_ntfs(
90
+ git_repository *repo,
91
+ const char *path,
92
+ size_t len)
1628
93
  {
1629
- git_buf *reserved = git_repository__reserved_names_win32;
94
+ git_str *reserved = git_repository__reserved_names_win32;
1630
95
  size_t reserved_len = git_repository__reserved_names_win32_len;
1631
96
  size_t start = 0, i;
1632
97
 
@@ -1634,7 +99,7 @@ GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size
1634
99
  git_repository__reserved_names(&reserved, &reserved_len, repo, true);
1635
100
 
1636
101
  for (i = 0; i < reserved_len; i++) {
1637
- git_buf *r = &reserved[i];
102
+ git_str *r = &reserved[i];
1638
103
 
1639
104
  if (len >= r->size &&
1640
105
  strncasecmp(path, r->ptr, r->size) == 0) {
@@ -1686,7 +151,12 @@ GIT_INLINE(bool) ntfs_end_of_filename(const char *path)
1686
151
  return true;
1687
152
  }
1688
153
 
1689
- 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)
154
+ GIT_INLINE(bool) validate_dotgit_ntfs_generic(
155
+ const char *name,
156
+ size_t len,
157
+ const char *dotgit_name,
158
+ size_t dotgit_len,
159
+ const char *shortname_pfix)
1690
160
  {
1691
161
  int i, saw_tilde;
1692
162
 
@@ -1723,33 +193,6 @@ GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, size_t len, const
1723
193
  return !ntfs_end_of_filename(name + i);
1724
194
  }
1725
195
 
1726
- GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
1727
- {
1728
- if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\')
1729
- return false;
1730
-
1731
- if ((flags & GIT_PATH_REJECT_SLASH) && c == '/')
1732
- return false;
1733
-
1734
- if (flags & GIT_PATH_REJECT_NT_CHARS) {
1735
- if (c < 32)
1736
- return false;
1737
-
1738
- switch (c) {
1739
- case '<':
1740
- case '>':
1741
- case ':':
1742
- case '"':
1743
- case '|':
1744
- case '?':
1745
- case '*':
1746
- return false;
1747
- }
1748
- }
1749
-
1750
- return true;
1751
- }
1752
-
1753
196
  /*
1754
197
  * Return the length of the common prefix between str and prefix, comparing them
1755
198
  * case-insensitively (must be ASCII to match).
@@ -1758,7 +201,7 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char *
1758
201
  {
1759
202
  size_t count = 0;
1760
203
 
1761
- while (len >0 && tolower(*str) == tolower(*prefix)) {
204
+ while (len > 0 && tolower(*str) == tolower(*prefix)) {
1762
205
  count++;
1763
206
  str++;
1764
207
  prefix++;
@@ -1768,72 +211,37 @@ GIT_INLINE(size_t) common_prefix_icase(const char *str, size_t len, const char *
1768
211
  return count;
1769
212
  }
1770
213
 
1771
- /*
1772
- * We fundamentally don't like some paths when dealing with user-inputted
1773
- * strings (in checkout or ref names): we don't want dot or dot-dot
1774
- * anywhere, we want to avoid writing weird paths on Windows that can't
1775
- * be handled by tools that use the non-\\?\ APIs, we don't want slashes
1776
- * or double slashes at the end of paths that can make them ambiguous.
1777
- *
1778
- * For checkout, we don't want to recurse into ".git" either.
1779
- */
1780
- static bool verify_component(
1781
- git_repository *repo,
214
+ static bool validate_repo_component(
1782
215
  const char *component,
1783
216
  size_t len,
1784
- uint16_t mode,
1785
- unsigned int flags)
217
+ void *payload)
1786
218
  {
1787
- if (len == 0)
1788
- return false;
219
+ repository_path_validate_data *data = (repository_path_validate_data *)payload;
1789
220
 
1790
- if ((flags & GIT_PATH_REJECT_TRAVERSAL) &&
1791
- len == 1 && component[0] == '.')
1792
- return false;
1793
-
1794
- if ((flags & GIT_PATH_REJECT_TRAVERSAL) &&
1795
- len == 2 && component[0] == '.' && component[1] == '.')
1796
- return false;
1797
-
1798
- if ((flags & GIT_PATH_REJECT_TRAILING_DOT) && component[len-1] == '.')
1799
- return false;
1800
-
1801
- if ((flags & GIT_PATH_REJECT_TRAILING_SPACE) && component[len-1] == ' ')
1802
- return false;
1803
-
1804
- if ((flags & GIT_PATH_REJECT_TRAILING_COLON) && component[len-1] == ':')
1805
- return false;
1806
-
1807
- if (flags & GIT_PATH_REJECT_DOS_PATHS) {
1808
- if (!verify_dospath(component, len, "CON", false) ||
1809
- !verify_dospath(component, len, "PRN", false) ||
1810
- !verify_dospath(component, len, "AUX", false) ||
1811
- !verify_dospath(component, len, "NUL", false) ||
1812
- !verify_dospath(component, len, "COM", true) ||
1813
- !verify_dospath(component, len, "LPT", true))
221
+ if (data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
222
+ if (!validate_dotgit_hfs(component, len))
1814
223
  return false;
1815
- }
1816
224
 
1817
- if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
1818
- if (!verify_dotgit_hfs(component, len))
1819
- return false;
1820
- if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS))
225
+ if (S_ISLNK(data->file_mode) &&
226
+ git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS))
1821
227
  return false;
1822
228
  }
1823
229
 
1824
- if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
1825
- if (!verify_dotgit_ntfs(repo, component, len))
230
+ if (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
231
+ if (!validate_dotgit_ntfs(data->repo, component, len))
1826
232
  return false;
1827
- if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS))
233
+
234
+ if (S_ISLNK(data->file_mode) &&
235
+ git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS))
1828
236
  return false;
1829
237
  }
1830
238
 
1831
239
  /* don't bother rerunning the `.git` test if we ran the HFS or NTFS
1832
240
  * specific tests, they would have already rejected `.git`.
1833
241
  */
1834
- if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
1835
- (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
1836
- (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) {
242
+ if ((data->flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
243
+ (data->flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
244
+ (data->flags & GIT_PATH_REJECT_DOT_GIT_LITERAL)) {
1837
245
  if (len >= 4 &&
1838
246
  component[0] == '.' &&
1839
247
  (component[1] == 'g' || component[1] == 'G') &&
@@ -1842,10 +250,11 @@ static bool verify_component(
1842
250
  if (len == 4)
1843
251
  return false;
1844
252
 
1845
- if (S_ISLNK(mode) && common_prefix_icase(component, len, ".gitmodules") == len)
253
+ if (S_ISLNK(data->file_mode) &&
254
+ common_prefix_icase(component, len, ".gitmodules") == len)
1846
255
  return false;
1847
256
  }
1848
- }
257
+ }
1849
258
 
1850
259
  return true;
1851
260
  }
@@ -1876,47 +285,49 @@ GIT_INLINE(unsigned int) dotgit_flags(
1876
285
  return flags;
1877
286
  }
1878
287
 
1879
- bool git_path_isvalid(
288
+ GIT_INLINE(unsigned int) length_flags(
1880
289
  git_repository *repo,
1881
- const char *path,
1882
- uint16_t mode,
1883
290
  unsigned int flags)
1884
291
  {
1885
- const char *start, *c;
1886
-
1887
- /* Upgrade the ".git" checks based on platform */
1888
- if ((flags & GIT_PATH_REJECT_DOT_GIT))
1889
- flags = dotgit_flags(repo, flags);
292
+ #ifdef GIT_WIN32
293
+ int allow = 0;
1890
294
 
1891
- for (start = c = path; *c; c++) {
1892
- if (!verify_char(*c, flags))
1893
- return false;
295
+ if (repo &&
296
+ git_repository__configmap_lookup(&allow, repo, GIT_CONFIGMAP_LONGPATHS) < 0)
297
+ allow = 0;
1894
298
 
1895
- if (*c == '/') {
1896
- if (!verify_component(repo, start, (c - start), mode, flags))
1897
- return false;
299
+ if (allow)
300
+ flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS;
1898
301
 
1899
- start = c+1;
1900
- }
1901
- }
302
+ #else
303
+ GIT_UNUSED(repo);
304
+ flags &= ~GIT_FS_PATH_REJECT_LONG_PATHS;
305
+ #endif
1902
306
 
1903
- return verify_component(repo, start, (c - start), mode, flags);
307
+ return flags;
1904
308
  }
1905
309
 
1906
- int git_path_normalize_slashes(git_buf *out, const char *path)
310
+ bool git_path_str_is_valid(
311
+ git_repository *repo,
312
+ const git_str *path,
313
+ uint16_t file_mode,
314
+ unsigned int flags)
1907
315
  {
1908
- int error;
1909
- char *p;
316
+ repository_path_validate_data data = {0};
317
+
318
+ /* Upgrade the ".git" checks based on platform */
319
+ if ((flags & GIT_PATH_REJECT_DOT_GIT))
320
+ flags = dotgit_flags(repo, flags);
1910
321
 
1911
- if ((error = git_buf_puts(out, path)) < 0)
1912
- return error;
322
+ /* Update the length checks based on platform */
323
+ if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS))
324
+ flags = length_flags(repo, flags);
1913
325
 
1914
- for (p = out->ptr; *p; p++) {
1915
- if (*p == '\\')
1916
- *p = '/';
1917
- }
326
+ data.repo = repo;
327
+ data.file_mode = file_mode;
328
+ data.flags = flags;
1918
329
 
1919
- return 0;
330
+ return git_fs_path_str_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data);
1920
331
  }
1921
332
 
1922
333
  static const struct {
@@ -1929,7 +340,11 @@ static const struct {
1929
340
  { "gitattributes", "gi7d29", CONST_STRLEN("gitattributes") }
1930
341
  };
1931
342
 
1932
- extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs)
343
+ extern int git_path_is_gitfile(
344
+ const char *path,
345
+ size_t pathlen,
346
+ git_path_gitfile gitfile,
347
+ git_path_fs fs)
1933
348
  {
1934
349
  const char *file, *hash;
1935
350
  size_t filelen;
@@ -1945,112 +360,15 @@ extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfil
1945
360
 
1946
361
  switch (fs) {
1947
362
  case GIT_PATH_FS_GENERIC:
1948
- return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) ||
1949
- !verify_dotgit_hfs_generic(path, pathlen, file, filelen);
363
+ return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) ||
364
+ !validate_dotgit_hfs_generic(path, pathlen, file, filelen);
1950
365
  case GIT_PATH_FS_NTFS:
1951
- return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash);
366
+ return !validate_dotgit_ntfs_generic(path, pathlen, file, filelen, hash);
1952
367
  case GIT_PATH_FS_HFS:
1953
- return !verify_dotgit_hfs_generic(path, pathlen, file, filelen);
368
+ return !validate_dotgit_hfs_generic(path, pathlen, file, filelen);
1954
369
  default:
1955
370
  git_error_set(GIT_ERROR_OS, "invalid filesystem for path validation");
1956
371
  return -1;
1957
372
  }
1958
373
  }
1959
374
 
1960
- bool git_path_supports_symlinks(const char *dir)
1961
- {
1962
- git_buf path = GIT_BUF_INIT;
1963
- bool supported = false;
1964
- struct stat st;
1965
- int fd;
1966
-
1967
- if ((fd = git_futils_mktmp(&path, dir, 0666)) < 0 ||
1968
- p_close(fd) < 0 ||
1969
- p_unlink(path.ptr) < 0 ||
1970
- p_symlink("testing", path.ptr) < 0 ||
1971
- p_lstat(path.ptr, &st) < 0)
1972
- goto done;
1973
-
1974
- supported = (S_ISLNK(st.st_mode) != 0);
1975
- done:
1976
- if (path.size)
1977
- (void)p_unlink(path.ptr);
1978
- git_buf_dispose(&path);
1979
- return supported;
1980
- }
1981
-
1982
- int git_path_validate_system_file_ownership(const char *path)
1983
- {
1984
- #ifndef GIT_WIN32
1985
- GIT_UNUSED(path);
1986
- return GIT_OK;
1987
- #else
1988
- git_win32_path buf;
1989
- PSID owner_sid;
1990
- PSECURITY_DESCRIPTOR descriptor = NULL;
1991
- HANDLE token;
1992
- TOKEN_USER *info = NULL;
1993
- DWORD err, len;
1994
- int ret;
1995
-
1996
- if (git_win32_path_from_utf8(buf, path) < 0)
1997
- return -1;
1998
-
1999
- err = GetNamedSecurityInfoW(buf, SE_FILE_OBJECT,
2000
- OWNER_SECURITY_INFORMATION |
2001
- DACL_SECURITY_INFORMATION,
2002
- &owner_sid, NULL, NULL, NULL, &descriptor);
2003
-
2004
- if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
2005
- ret = GIT_ENOTFOUND;
2006
- goto cleanup;
2007
- }
2008
-
2009
- if (err != ERROR_SUCCESS) {
2010
- git_error_set(GIT_ERROR_OS, "failed to get security information");
2011
- ret = GIT_ERROR;
2012
- goto cleanup;
2013
- }
2014
-
2015
- if (!IsValidSid(owner_sid)) {
2016
- git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is unknown");
2017
- ret = GIT_ERROR;
2018
- goto cleanup;
2019
- }
2020
-
2021
- if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
2022
- IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
2023
- ret = GIT_OK;
2024
- goto cleanup;
2025
- }
2026
-
2027
- /* Obtain current user's SID */
2028
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) &&
2029
- !GetTokenInformation(token, TokenUser, NULL, 0, &len)) {
2030
- info = git__malloc(len);
2031
- GIT_ERROR_CHECK_ALLOC(info);
2032
- if (!GetTokenInformation(token, TokenUser, info, len, &len)) {
2033
- git__free(info);
2034
- info = NULL;
2035
- }
2036
- }
2037
-
2038
- /*
2039
- * If the file is owned by the same account that is running the current
2040
- * process, it's okay to read from that file.
2041
- */
2042
- if (info && EqualSid(owner_sid, info->User.Sid))
2043
- ret = GIT_OK;
2044
- else {
2045
- git_error_set(GIT_ERROR_INVALID, "programdata configuration file owner is not valid");
2046
- ret = GIT_ERROR;
2047
- }
2048
- git__free(info);
2049
-
2050
- cleanup:
2051
- if (descriptor)
2052
- LocalFree(descriptor);
2053
-
2054
- return ret;
2055
- #endif
2056
- }