rugged 0.26.7 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/rugged/rugged_blame.c +6 -3
  4. data/ext/rugged/rugged_branch_collection.c +3 -6
  5. data/ext/rugged/rugged_commit.c +56 -0
  6. data/ext/rugged/rugged_config.c +44 -9
  7. data/ext/rugged/rugged_diff.c +3 -14
  8. data/ext/rugged/rugged_diff_hunk.c +1 -3
  9. data/ext/rugged/rugged_index.c +1 -5
  10. data/ext/rugged/rugged_note.c +1 -4
  11. data/ext/rugged/rugged_patch.c +1 -4
  12. data/ext/rugged/rugged_reference_collection.c +1 -7
  13. data/ext/rugged/rugged_remote.c +5 -8
  14. data/ext/rugged/rugged_remote_collection.c +1 -6
  15. data/ext/rugged/rugged_repo.c +16 -48
  16. data/ext/rugged/rugged_revwalk.c +7 -16
  17. data/ext/rugged/rugged_settings.c +28 -0
  18. data/ext/rugged/rugged_submodule_collection.c +3 -4
  19. data/ext/rugged/rugged_tag_collection.c +1 -5
  20. data/ext/rugged/rugged_tree.c +2 -3
  21. data/lib/rugged/repository.rb +43 -0
  22. data/lib/rugged/version.rb +1 -1
  23. data/vendor/libgit2/AUTHORS +1 -0
  24. data/vendor/libgit2/CMakeLists.txt +61 -510
  25. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +14 -0
  26. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +25 -8
  27. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +27 -8
  28. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
  29. data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
  30. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +3 -0
  31. data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
  32. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
  33. data/vendor/libgit2/deps/zlib/CMakeLists.txt +4 -0
  34. data/vendor/libgit2/include/git2/config.h +29 -2
  35. data/vendor/libgit2/include/git2/describe.h +1 -1
  36. data/vendor/libgit2/include/git2/diff.h +59 -8
  37. data/vendor/libgit2/include/git2/graph.h +3 -0
  38. data/vendor/libgit2/include/git2/merge.h +6 -0
  39. data/vendor/libgit2/include/git2/message.h +43 -3
  40. data/vendor/libgit2/include/git2/notes.h +89 -0
  41. data/vendor/libgit2/include/git2/odb.h +8 -1
  42. data/vendor/libgit2/include/git2/patch.h +2 -2
  43. data/vendor/libgit2/include/git2/pathspec.h +35 -18
  44. data/vendor/libgit2/include/git2/refs.h +3 -0
  45. data/vendor/libgit2/include/git2/remote.h +34 -4
  46. data/vendor/libgit2/include/git2/repository.h +6 -6
  47. data/vendor/libgit2/include/git2/reset.h +4 -4
  48. data/vendor/libgit2/include/git2/status.h +4 -0
  49. data/vendor/libgit2/include/git2/sys/config.h +4 -1
  50. data/vendor/libgit2/include/git2/sys/odb_backend.h +2 -1
  51. data/vendor/libgit2/include/git2/tree.h +4 -3
  52. data/vendor/libgit2/include/git2/types.h +1 -0
  53. data/vendor/libgit2/include/git2/version.h +4 -4
  54. data/vendor/libgit2/include/git2/worktree.h +1 -1
  55. data/vendor/libgit2/src/CMakeLists.txt +463 -0
  56. data/vendor/libgit2/src/annotated_commit.c +1 -1
  57. data/vendor/libgit2/src/annotated_commit.h +2 -0
  58. data/vendor/libgit2/src/apply.c +2 -1
  59. data/vendor/libgit2/src/apply.h +2 -0
  60. data/vendor/libgit2/src/attr.c +24 -4
  61. data/vendor/libgit2/src/attr.h +2 -0
  62. data/vendor/libgit2/src/attr_file.c +9 -2
  63. data/vendor/libgit2/src/attr_file.h +2 -0
  64. data/vendor/libgit2/src/attrcache.c +9 -1
  65. data/vendor/libgit2/src/attrcache.h +2 -0
  66. data/vendor/libgit2/src/blame.c +1 -0
  67. data/vendor/libgit2/src/blame.h +2 -1
  68. data/vendor/libgit2/src/blame_git.c +1 -0
  69. data/vendor/libgit2/src/blame_git.h +2 -0
  70. data/vendor/libgit2/src/blob.c +2 -2
  71. data/vendor/libgit2/src/blob.h +2 -0
  72. data/vendor/libgit2/src/branch.c +8 -1
  73. data/vendor/libgit2/src/branch.h +2 -0
  74. data/vendor/libgit2/src/buf_text.c +7 -7
  75. data/vendor/libgit2/src/buf_text.h +3 -3
  76. data/vendor/libgit2/src/buffer.c +31 -1
  77. data/vendor/libgit2/src/buffer.h +3 -0
  78. data/vendor/libgit2/src/cache.c +2 -2
  79. data/vendor/libgit2/src/cache.h +2 -0
  80. data/vendor/libgit2/src/cc-compat.h +3 -3
  81. data/vendor/libgit2/src/checkout.c +30 -19
  82. data/vendor/libgit2/src/checkout.h +2 -0
  83. data/vendor/libgit2/src/cherrypick.c +1 -0
  84. data/vendor/libgit2/src/clone.c +2 -1
  85. data/vendor/libgit2/src/clone.h +4 -0
  86. data/vendor/libgit2/src/commit.c +2 -1
  87. data/vendor/libgit2/src/commit.h +2 -0
  88. data/vendor/libgit2/src/commit_list.c +1 -1
  89. data/vendor/libgit2/src/commit_list.h +2 -0
  90. data/vendor/libgit2/src/common.h +11 -5
  91. data/vendor/libgit2/src/config.c +12 -10
  92. data/vendor/libgit2/src/config.h +2 -0
  93. data/vendor/libgit2/src/config_cache.c +1 -0
  94. data/vendor/libgit2/src/config_file.c +287 -786
  95. data/vendor/libgit2/src/config_file.h +4 -3
  96. data/vendor/libgit2/src/config_parse.c +525 -0
  97. data/vendor/libgit2/src/config_parse.h +64 -0
  98. data/vendor/libgit2/src/crlf.c +2 -1
  99. data/vendor/libgit2/src/delta.c +28 -30
  100. data/vendor/libgit2/src/delta.h +1 -0
  101. data/vendor/libgit2/src/describe.c +3 -1
  102. data/vendor/libgit2/src/diff.c +148 -2
  103. data/vendor/libgit2/src/diff.h +3 -1
  104. data/vendor/libgit2/src/diff_driver.c +12 -9
  105. data/vendor/libgit2/src/diff_driver.h +4 -1
  106. data/vendor/libgit2/src/diff_file.c +7 -4
  107. data/vendor/libgit2/src/diff_file.h +1 -0
  108. data/vendor/libgit2/src/diff_generate.c +6 -3
  109. data/vendor/libgit2/src/diff_generate.h +6 -1
  110. data/vendor/libgit2/src/diff_parse.c +5 -4
  111. data/vendor/libgit2/src/diff_parse.h +2 -0
  112. data/vendor/libgit2/src/diff_print.c +2 -0
  113. data/vendor/libgit2/src/diff_stats.c +2 -0
  114. data/vendor/libgit2/src/diff_tform.c +2 -1
  115. data/vendor/libgit2/src/diff_tform.h +4 -1
  116. data/vendor/libgit2/src/diff_xdiff.c +5 -2
  117. data/vendor/libgit2/src/diff_xdiff.h +2 -0
  118. data/vendor/libgit2/src/errors.c +2 -0
  119. data/vendor/libgit2/src/features.h.in +36 -0
  120. data/vendor/libgit2/src/fetch.c +2 -2
  121. data/vendor/libgit2/src/fetch.h +4 -0
  122. data/vendor/libgit2/src/fetchhead.c +3 -3
  123. data/vendor/libgit2/src/fetchhead.h +3 -0
  124. data/vendor/libgit2/src/filebuf.c +2 -1
  125. data/vendor/libgit2/src/filebuf.h +2 -0
  126. data/vendor/libgit2/src/fileops.c +12 -1
  127. data/vendor/libgit2/src/fileops.h +7 -1
  128. data/vendor/libgit2/src/filter.c +2 -1
  129. data/vendor/libgit2/src/filter.h +1 -0
  130. data/vendor/libgit2/src/fnmatch.c +2 -2
  131. data/vendor/libgit2/src/fnmatch.h +3 -4
  132. data/vendor/libgit2/src/global.c +4 -3
  133. data/vendor/libgit2/src/global.h +1 -5
  134. data/vendor/libgit2/src/graph.c +2 -0
  135. data/vendor/libgit2/src/hash.c +0 -1
  136. data/vendor/libgit2/src/hash.h +3 -1
  137. data/vendor/libgit2/src/hash/hash_collisiondetect.h +3 -3
  138. data/vendor/libgit2/src/hash/hash_common_crypto.h +18 -5
  139. data/vendor/libgit2/src/hash/hash_generic.c +2 -2
  140. data/vendor/libgit2/src/hash/hash_generic.h +5 -3
  141. data/vendor/libgit2/src/hash/hash_openssl.h +3 -3
  142. data/vendor/libgit2/src/hash/hash_win32.c +57 -14
  143. data/vendor/libgit2/src/hash/hash_win32.h +4 -3
  144. data/vendor/libgit2/src/hashsig.c +3 -0
  145. data/vendor/libgit2/src/ident.c +2 -0
  146. data/vendor/libgit2/src/idxmap.h +2 -1
  147. data/vendor/libgit2/src/ignore.c +14 -2
  148. data/vendor/libgit2/src/ignore.h +2 -0
  149. data/vendor/libgit2/src/index.c +20 -40
  150. data/vendor/libgit2/src/index.h +2 -0
  151. data/vendor/libgit2/src/indexer.c +13 -5
  152. data/vendor/libgit2/src/indexer.h +5 -1
  153. data/vendor/libgit2/src/integer.h +1 -1
  154. data/vendor/libgit2/src/iterator.c +44 -3
  155. data/vendor/libgit2/src/iterator.h +3 -0
  156. data/vendor/libgit2/src/map.h +1 -1
  157. data/vendor/libgit2/src/merge.c +155 -33
  158. data/vendor/libgit2/src/merge.h +2 -0
  159. data/vendor/libgit2/src/merge_driver.c +2 -2
  160. data/vendor/libgit2/src/merge_driver.h +2 -0
  161. data/vendor/libgit2/src/merge_file.c +3 -0
  162. data/vendor/libgit2/src/message.h +3 -1
  163. data/vendor/libgit2/src/mwindow.c +1 -1
  164. data/vendor/libgit2/src/mwindow.h +2 -0
  165. data/vendor/libgit2/src/netops.c +75 -62
  166. data/vendor/libgit2/src/netops.h +2 -1
  167. data/vendor/libgit2/src/notes.c +164 -48
  168. data/vendor/libgit2/src/notes.h +1 -1
  169. data/vendor/libgit2/src/object.c +14 -3
  170. data/vendor/libgit2/src/object.h +4 -0
  171. data/vendor/libgit2/src/object_api.c +3 -2
  172. data/vendor/libgit2/src/odb.c +104 -38
  173. data/vendor/libgit2/src/odb.h +3 -1
  174. data/vendor/libgit2/src/odb_loose.c +414 -267
  175. data/vendor/libgit2/src/odb_mempack.c +1 -0
  176. data/vendor/libgit2/src/odb_pack.c +2 -1
  177. data/vendor/libgit2/src/offmap.h +1 -0
  178. data/vendor/libgit2/src/oid.c +2 -1
  179. data/vendor/libgit2/src/oid.h +3 -8
  180. data/vendor/libgit2/src/oidarray.c +2 -1
  181. data/vendor/libgit2/src/oidarray.h +1 -0
  182. data/vendor/libgit2/src/oidmap.h +1 -0
  183. data/vendor/libgit2/src/pack-objects.c +5 -1
  184. data/vendor/libgit2/src/pack-objects.h +1 -1
  185. data/vendor/libgit2/src/pack.c +2 -6
  186. data/vendor/libgit2/src/pack.h +2 -1
  187. data/vendor/libgit2/src/parse.c +121 -0
  188. data/vendor/libgit2/src/parse.h +61 -0
  189. data/vendor/libgit2/src/patch.c +9 -2
  190. data/vendor/libgit2/src/patch.h +2 -0
  191. data/vendor/libgit2/src/patch_generate.c +6 -5
  192. data/vendor/libgit2/src/patch_generate.h +1 -0
  193. data/vendor/libgit2/src/patch_parse.c +265 -276
  194. data/vendor/libgit2/src/patch_parse.h +6 -11
  195. data/vendor/libgit2/src/path.c +24 -181
  196. data/vendor/libgit2/src/path.h +14 -73
  197. data/vendor/libgit2/src/pathspec.c +2 -1
  198. data/vendor/libgit2/src/pathspec.h +2 -1
  199. data/vendor/libgit2/src/pool.c +8 -0
  200. data/vendor/libgit2/src/pool.h +1 -0
  201. data/vendor/libgit2/src/posix.c +2 -1
  202. data/vendor/libgit2/src/posix.h +1 -0
  203. data/vendor/libgit2/src/pqueue.c +1 -0
  204. data/vendor/libgit2/src/pqueue.h +2 -0
  205. data/vendor/libgit2/src/proxy.c +2 -1
  206. data/vendor/libgit2/src/proxy.h +3 -1
  207. data/vendor/libgit2/src/push.c +4 -171
  208. data/vendor/libgit2/src/push.h +2 -0
  209. data/vendor/libgit2/src/rebase.c +1 -0
  210. data/vendor/libgit2/src/refdb.c +2 -3
  211. data/vendor/libgit2/src/refdb.h +2 -0
  212. data/vendor/libgit2/src/refdb_fs.c +5 -3
  213. data/vendor/libgit2/src/refdb_fs.h +4 -0
  214. data/vendor/libgit2/src/reflog.c +1 -0
  215. data/vendor/libgit2/src/reflog.h +2 -1
  216. data/vendor/libgit2/src/refs.c +1 -0
  217. data/vendor/libgit2/src/refs.h +2 -1
  218. data/vendor/libgit2/src/refspec.c +2 -2
  219. data/vendor/libgit2/src/refspec.h +2 -0
  220. data/vendor/libgit2/src/remote.c +56 -10
  221. data/vendor/libgit2/src/remote.h +2 -0
  222. data/vendor/libgit2/src/repository.c +16 -14
  223. data/vendor/libgit2/src/repository.h +2 -0
  224. data/vendor/libgit2/src/reset.c +6 -5
  225. data/vendor/libgit2/src/revert.c +1 -0
  226. data/vendor/libgit2/src/revparse.c +3 -5
  227. data/vendor/libgit2/src/revwalk.c +2 -2
  228. data/vendor/libgit2/src/revwalk.h +2 -0
  229. data/vendor/libgit2/src/settings.c +6 -8
  230. data/vendor/libgit2/src/sha1_lookup.c +2 -216
  231. data/vendor/libgit2/src/sha1_lookup.h +2 -6
  232. data/vendor/libgit2/src/signature.c +8 -3
  233. data/vendor/libgit2/src/signature.h +2 -0
  234. data/vendor/libgit2/src/sortedcache.c +7 -0
  235. data/vendor/libgit2/src/sortedcache.h +2 -0
  236. data/vendor/libgit2/src/stash.c +1 -0
  237. data/vendor/libgit2/src/status.c +14 -9
  238. data/vendor/libgit2/src/status.h +2 -0
  239. data/vendor/libgit2/src/{curl_stream.c → streams/curl.c} +2 -0
  240. data/vendor/libgit2/src/{curl_stream.h → streams/curl.h} +4 -2
  241. data/vendor/libgit2/src/{openssl_stream.c → streams/openssl.c} +47 -18
  242. data/vendor/libgit2/src/{openssl_stream.h → streams/openssl.h} +6 -2
  243. data/vendor/libgit2/src/{socket_stream.c → streams/socket.c} +2 -2
  244. data/vendor/libgit2/src/{socket_stream.h → streams/socket.h} +4 -2
  245. data/vendor/libgit2/src/{stransport_stream.c → streams/stransport.c} +4 -2
  246. data/vendor/libgit2/src/{stransport_stream.h → streams/stransport.h} +4 -2
  247. data/vendor/libgit2/src/{tls_stream.c → streams/tls.c} +4 -3
  248. data/vendor/libgit2/src/{tls_stream.h → streams/tls.h} +4 -2
  249. data/vendor/libgit2/src/submodule.c +28 -80
  250. data/vendor/libgit2/src/submodule.h +2 -13
  251. data/vendor/libgit2/src/sysdir.c +75 -8
  252. data/vendor/libgit2/src/sysdir.h +2 -1
  253. data/vendor/libgit2/src/tag.c +2 -2
  254. data/vendor/libgit2/src/tag.h +2 -0
  255. data/vendor/libgit2/src/thread-utils.c +1 -0
  256. data/vendor/libgit2/src/thread-utils.h +1 -1
  257. data/vendor/libgit2/src/trace.c +2 -2
  258. data/vendor/libgit2/src/trace.h +2 -0
  259. data/vendor/libgit2/src/trailer.c +416 -0
  260. data/vendor/libgit2/src/transaction.c +2 -1
  261. data/vendor/libgit2/src/transport.c +2 -0
  262. data/vendor/libgit2/src/transports/auth.c +2 -1
  263. data/vendor/libgit2/src/transports/auth.h +4 -3
  264. data/vendor/libgit2/src/transports/auth_negotiate.c +2 -1
  265. data/vendor/libgit2/src/transports/auth_negotiate.h +3 -3
  266. data/vendor/libgit2/src/transports/cred.c +2 -0
  267. data/vendor/libgit2/src/transports/cred.h +4 -2
  268. data/vendor/libgit2/src/transports/cred_helpers.c +1 -0
  269. data/vendor/libgit2/src/transports/git.c +3 -1
  270. data/vendor/libgit2/src/transports/http.c +10 -14
  271. data/vendor/libgit2/src/transports/http.h +23 -0
  272. data/vendor/libgit2/src/transports/local.c +23 -5
  273. data/vendor/libgit2/src/transports/smart.c +3 -1
  274. data/vendor/libgit2/src/transports/smart.h +23 -16
  275. data/vendor/libgit2/src/transports/smart_pkt.c +114 -130
  276. data/vendor/libgit2/src/transports/smart_protocol.c +26 -22
  277. data/vendor/libgit2/src/transports/ssh.c +12 -7
  278. data/vendor/libgit2/src/transports/ssh.h +4 -2
  279. data/vendor/libgit2/src/transports/winhttp.c +19 -21
  280. data/vendor/libgit2/src/tree-cache.c +1 -0
  281. data/vendor/libgit2/src/tree-cache.h +1 -0
  282. data/vendor/libgit2/src/tree.c +20 -14
  283. data/vendor/libgit2/src/tree.h +2 -0
  284. data/vendor/libgit2/src/tsort.c +0 -1
  285. data/vendor/libgit2/src/unix/map.c +4 -1
  286. data/vendor/libgit2/src/unix/posix.h +8 -4
  287. data/vendor/libgit2/src/unix/pthread.h +1 -1
  288. data/vendor/libgit2/src/unix/realpath.c +4 -1
  289. data/vendor/libgit2/src/util.c +6 -5
  290. data/vendor/libgit2/src/util.h +39 -111
  291. data/vendor/libgit2/src/varint.c +0 -1
  292. data/vendor/libgit2/src/varint.h +2 -0
  293. data/vendor/libgit2/src/vector.c +1 -1
  294. data/vendor/libgit2/src/win32/dir.c +3 -0
  295. data/vendor/libgit2/src/win32/dir.h +4 -3
  296. data/vendor/libgit2/src/win32/error.c +1 -1
  297. data/vendor/libgit2/src/win32/error.h +4 -2
  298. data/vendor/libgit2/src/win32/findfile.c +2 -1
  299. data/vendor/libgit2/src/win32/findfile.h +4 -2
  300. data/vendor/libgit2/src/win32/map.c +2 -0
  301. data/vendor/libgit2/src/win32/mingw-compat.h +3 -3
  302. data/vendor/libgit2/src/win32/msvc-compat.h +3 -3
  303. data/vendor/libgit2/src/win32/path_w32.c +7 -12
  304. data/vendor/libgit2/src/win32/path_w32.h +3 -2
  305. data/vendor/libgit2/src/win32/posix.h +2 -2
  306. data/vendor/libgit2/src/win32/posix_w32.c +11 -5
  307. data/vendor/libgit2/src/win32/precompiled.h +2 -1
  308. data/vendor/libgit2/src/win32/reparse.h +2 -2
  309. data/vendor/libgit2/src/win32/thread.c +1 -0
  310. data/vendor/libgit2/src/win32/thread.h +2 -2
  311. data/vendor/libgit2/src/win32/utf-conv.c +0 -1
  312. data/vendor/libgit2/src/win32/utf-conv.h +4 -3
  313. data/vendor/libgit2/src/win32/w32_buffer.c +1 -1
  314. data/vendor/libgit2/src/win32/w32_buffer.h +4 -2
  315. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -1
  316. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +85 -2
  317. data/vendor/libgit2/src/win32/w32_stack.c +2 -1
  318. data/vendor/libgit2/src/win32/w32_stack.h +5 -3
  319. data/vendor/libgit2/src/win32/w32_util.h +4 -2
  320. data/vendor/libgit2/src/win32/win32-compat.h +3 -3
  321. data/vendor/libgit2/src/worktree.c +4 -5
  322. data/vendor/libgit2/src/worktree.h +2 -0
  323. data/vendor/libgit2/src/xdiff/xdiff.h +22 -13
  324. data/vendor/libgit2/src/xdiff/xdiffi.c +523 -81
  325. data/vendor/libgit2/src/xdiff/xdiffi.h +2 -2
  326. data/vendor/libgit2/src/xdiff/xemit.c +63 -39
  327. data/vendor/libgit2/src/xdiff/xemit.h +2 -2
  328. data/vendor/libgit2/src/xdiff/xhistogram.c +0 -1
  329. data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
  330. data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
  331. data/vendor/libgit2/src/xdiff/xmerge.c +80 -20
  332. data/vendor/libgit2/src/xdiff/xpatience.c +41 -9
  333. data/vendor/libgit2/src/xdiff/xprepare.c +2 -2
  334. data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
  335. data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
  336. data/vendor/libgit2/src/xdiff/xutils.c +47 -27
  337. data/vendor/libgit2/src/xdiff/xutils.h +2 -5
  338. data/vendor/libgit2/src/zstream.c +65 -45
  339. data/vendor/libgit2/src/zstream.h +9 -2
  340. metadata +27 -13
  341. data/vendor/libgit2/include/git2/sys/remote.h +0 -16
@@ -7,12 +7,14 @@
7
7
  #ifndef INCLUDE_config_file_h__
8
8
  #define INCLUDE_config_file_h__
9
9
 
10
+ #include "common.h"
11
+
10
12
  #include "git2/sys/config.h"
11
13
  #include "git2/config.h"
12
14
 
13
- GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level)
15
+ GIT_INLINE(int) git_config_file_open(git_config_backend *cfg, unsigned int level, const git_repository *repo)
14
16
  {
15
- return cfg->open(cfg, level);
17
+ return cfg->open(cfg, level, repo);
16
18
  }
17
19
 
18
20
  GIT_INLINE(void) git_config_file_free(git_config_backend *cfg)
@@ -69,4 +71,3 @@ GIT_INLINE(int) git_config_file_unlock(git_config_backend *cfg, int success)
69
71
  extern int git_config_file_normalize_section(char *start, char *end);
70
72
 
71
73
  #endif
72
-
@@ -0,0 +1,525 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include "config_parse.h"
9
+
10
+ #include "buf_text.h"
11
+
12
+ #include <ctype.h>
13
+
14
+ static void set_parse_error(git_config_parser *reader, int col, const char *error_str)
15
+ {
16
+ giterr_set(GITERR_CONFIG, "failed to parse config file: %s (in %s:%"PRIuZ", column %d)",
17
+ error_str, reader->file->path, reader->ctx.line_num, col);
18
+ }
19
+
20
+
21
+ GIT_INLINE(int) config_keychar(int c)
22
+ {
23
+ return isalnum(c) || c == '-';
24
+ }
25
+
26
+ static int strip_comments(char *line, int in_quotes)
27
+ {
28
+ int quote_count = in_quotes, backslash_count = 0;
29
+ char *ptr;
30
+
31
+ for (ptr = line; *ptr; ++ptr) {
32
+ if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
33
+ quote_count++;
34
+
35
+ if ((ptr[0] == ';' || ptr[0] == '#') &&
36
+ (quote_count % 2) == 0 &&
37
+ (backslash_count % 2) == 0) {
38
+ ptr[0] = '\0';
39
+ break;
40
+ }
41
+
42
+ if (ptr[0] == '\\')
43
+ backslash_count++;
44
+ else
45
+ backslash_count = 0;
46
+ }
47
+
48
+ /* skip any space at the end */
49
+ while (ptr > line && git__isspace(ptr[-1])) {
50
+ ptr--;
51
+ }
52
+ ptr[0] = '\0';
53
+
54
+ return quote_count;
55
+ }
56
+
57
+
58
+ static int parse_section_header_ext(git_config_parser *reader, const char *line, const char *base_name, char **section_name)
59
+ {
60
+ int c, rpos;
61
+ char *first_quote, *last_quote;
62
+ git_buf buf = GIT_BUF_INIT;
63
+ size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
64
+
65
+ /*
66
+ * base_name is what came before the space. We should be at the
67
+ * first quotation mark, except for now, line isn't being kept in
68
+ * sync so we only really use it to calculate the length.
69
+ */
70
+
71
+ first_quote = strchr(line, '"');
72
+ if (first_quote == NULL) {
73
+ set_parse_error(reader, 0, "Missing quotation marks in section header");
74
+ goto end_error;
75
+ }
76
+
77
+ last_quote = strrchr(line, '"');
78
+ quoted_len = last_quote - first_quote;
79
+
80
+ if (quoted_len == 0) {
81
+ set_parse_error(reader, 0, "Missing closing quotation mark in section header");
82
+ goto end_error;
83
+ }
84
+
85
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
86
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
87
+
88
+ if (git_buf_grow(&buf, alloc_len) < 0 ||
89
+ git_buf_printf(&buf, "%s.", base_name) < 0)
90
+ goto end_error;
91
+
92
+ rpos = 0;
93
+
94
+ line = first_quote;
95
+ c = line[++rpos];
96
+
97
+ /*
98
+ * At the end of each iteration, whatever is stored in c will be
99
+ * added to the string. In case of error, jump to out
100
+ */
101
+ do {
102
+
103
+ switch (c) {
104
+ case 0:
105
+ set_parse_error(reader, 0, "Unexpected end-of-line in section header");
106
+ goto end_error;
107
+
108
+ case '"':
109
+ goto end_parse;
110
+
111
+ case '\\':
112
+ c = line[++rpos];
113
+
114
+ if (c == 0) {
115
+ set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
116
+ goto end_error;
117
+ }
118
+
119
+ default:
120
+ break;
121
+ }
122
+
123
+ git_buf_putc(&buf, (char)c);
124
+ c = line[++rpos];
125
+ } while (line + rpos < last_quote);
126
+
127
+ end_parse:
128
+ if (git_buf_oom(&buf))
129
+ goto end_error;
130
+
131
+ if (line[rpos] != '"' || line[rpos + 1] != ']') {
132
+ set_parse_error(reader, rpos, "Unexpected text after closing quotes");
133
+ git_buf_free(&buf);
134
+ return -1;
135
+ }
136
+
137
+ *section_name = git_buf_detach(&buf);
138
+ return 0;
139
+
140
+ end_error:
141
+ git_buf_free(&buf);
142
+
143
+ return -1;
144
+ }
145
+
146
+ static int parse_section_header(git_config_parser *reader, char **section_out)
147
+ {
148
+ char *name, *name_end;
149
+ int name_length, c, pos;
150
+ int result;
151
+ char *line;
152
+ size_t line_len;
153
+
154
+ git_parse_advance_ws(&reader->ctx);
155
+ line = git__strndup(reader->ctx.line, reader->ctx.line_len);
156
+ if (line == NULL)
157
+ return -1;
158
+
159
+ /* find the end of the variable's name */
160
+ name_end = strrchr(line, ']');
161
+ if (name_end == NULL) {
162
+ git__free(line);
163
+ set_parse_error(reader, 0, "Missing ']' in section header");
164
+ return -1;
165
+ }
166
+
167
+ GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
168
+ name = git__malloc(line_len);
169
+ GITERR_CHECK_ALLOC(name);
170
+
171
+ name_length = 0;
172
+ pos = 0;
173
+
174
+ /* Make sure we were given a section header */
175
+ c = line[pos++];
176
+ assert(c == '[');
177
+
178
+ c = line[pos++];
179
+
180
+ do {
181
+ if (git__isspace(c)){
182
+ name[name_length] = '\0';
183
+ result = parse_section_header_ext(reader, line, name, section_out);
184
+ git__free(line);
185
+ git__free(name);
186
+ return result;
187
+ }
188
+
189
+ if (!config_keychar(c) && c != '.') {
190
+ set_parse_error(reader, pos, "Unexpected character in header");
191
+ goto fail_parse;
192
+ }
193
+
194
+ name[name_length++] = (char)git__tolower(c);
195
+
196
+ } while ((c = line[pos++]) != ']');
197
+
198
+ if (line[pos - 1] != ']') {
199
+ set_parse_error(reader, pos, "Unexpected end of file");
200
+ goto fail_parse;
201
+ }
202
+
203
+ git__free(line);
204
+
205
+ name[name_length] = 0;
206
+ *section_out = name;
207
+
208
+ return 0;
209
+
210
+ fail_parse:
211
+ git__free(line);
212
+ git__free(name);
213
+ return -1;
214
+ }
215
+
216
+ static int skip_bom(git_parse_ctx *parser)
217
+ {
218
+ git_buf buf = GIT_BUF_INIT_CONST(parser->content, parser->content_len);
219
+ git_bom_t bom;
220
+ int bom_offset = git_buf_text_detect_bom(&bom, &buf);
221
+
222
+ if (bom == GIT_BOM_UTF8)
223
+ git_parse_advance_chars(parser, bom_offset);
224
+
225
+ /* TODO: reference implementation is pretty stupid with BoM */
226
+
227
+ return 0;
228
+ }
229
+
230
+ /*
231
+ (* basic types *)
232
+ digit = "0".."9"
233
+ integer = digit { digit }
234
+ alphabet = "a".."z" + "A" .. "Z"
235
+
236
+ section_char = alphabet | "." | "-"
237
+ extension_char = (* any character except newline *)
238
+ any_char = (* any character *)
239
+ variable_char = "alphabet" | "-"
240
+
241
+
242
+ (* actual grammar *)
243
+ config = { section }
244
+
245
+ section = header { definition }
246
+
247
+ header = "[" section [subsection | subsection_ext] "]"
248
+
249
+ subsection = "." section
250
+ subsection_ext = "\"" extension "\""
251
+
252
+ section = section_char { section_char }
253
+ extension = extension_char { extension_char }
254
+
255
+ definition = variable_name ["=" variable_value] "\n"
256
+
257
+ variable_name = variable_char { variable_char }
258
+ variable_value = string | boolean | integer
259
+
260
+ string = quoted_string | plain_string
261
+ quoted_string = "\"" plain_string "\""
262
+ plain_string = { any_char }
263
+
264
+ boolean = boolean_true | boolean_false
265
+ boolean_true = "yes" | "1" | "true" | "on"
266
+ boolean_false = "no" | "0" | "false" | "off"
267
+ */
268
+
269
+ /* '\"' -> '"' etc */
270
+ static int unescape_line(
271
+ char **out, bool *is_multi, const char *ptr, int quote_count)
272
+ {
273
+ char *str, *fixed, *esc;
274
+ size_t ptr_len = strlen(ptr), alloc_len;
275
+
276
+ *is_multi = false;
277
+
278
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
279
+ (str = git__malloc(alloc_len)) == NULL) {
280
+ return -1;
281
+ }
282
+
283
+ fixed = str;
284
+
285
+ while (*ptr != '\0') {
286
+ if (*ptr == '"') {
287
+ quote_count++;
288
+ } else if (*ptr != '\\') {
289
+ *fixed++ = *ptr;
290
+ } else {
291
+ /* backslash, check the next char */
292
+ ptr++;
293
+ /* if we're at the end, it's a multiline, so keep the backslash */
294
+ if (*ptr == '\0') {
295
+ *is_multi = true;
296
+ goto done;
297
+ }
298
+ if ((esc = strchr(git_config_escapes, *ptr)) != NULL) {
299
+ *fixed++ = git_config_escaped[esc - git_config_escapes];
300
+ } else {
301
+ git__free(str);
302
+ giterr_set(GITERR_CONFIG, "invalid escape at %s", ptr);
303
+ return -1;
304
+ }
305
+ }
306
+ ptr++;
307
+ }
308
+
309
+ done:
310
+ *fixed = '\0';
311
+ *out = str;
312
+
313
+ return 0;
314
+ }
315
+
316
+ static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes)
317
+ {
318
+ char *line = NULL, *proc_line = NULL;
319
+ int quote_count;
320
+ bool multiline;
321
+
322
+ /* Check that the next line exists */
323
+ git_parse_advance_line(&reader->ctx);
324
+ line = git__strndup(reader->ctx.line, reader->ctx.line_len);
325
+ if (line == NULL)
326
+ return -1;
327
+
328
+ /* We've reached the end of the file, there is no continuation.
329
+ * (this is not an error).
330
+ */
331
+ if (line[0] == '\0') {
332
+ git__free(line);
333
+ return 0;
334
+ }
335
+
336
+ quote_count = strip_comments(line, !!in_quotes);
337
+
338
+ /* If it was just a comment, pretend it didn't exist */
339
+ if (line[0] == '\0') {
340
+ git__free(line);
341
+ return parse_multiline_variable(reader, value, quote_count);
342
+ /* TODO: unbounded recursion. This **could** be exploitable */
343
+ }
344
+
345
+ if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
346
+ git__free(line);
347
+ return -1;
348
+ }
349
+ /* add this line to the multiline var */
350
+
351
+ git_buf_puts(value, proc_line);
352
+ git__free(line);
353
+ git__free(proc_line);
354
+
355
+ /*
356
+ * If we need to continue reading the next line, let's just
357
+ * keep putting stuff in the buffer
358
+ */
359
+ if (multiline)
360
+ return parse_multiline_variable(reader, value, quote_count);
361
+
362
+ return 0;
363
+ }
364
+
365
+ GIT_INLINE(bool) is_namechar(char c)
366
+ {
367
+ return isalnum(c) || c == '-';
368
+ }
369
+
370
+ static int parse_name(
371
+ char **name, const char **value, git_config_parser *reader, const char *line)
372
+ {
373
+ const char *name_end = line, *value_start;
374
+
375
+ *name = NULL;
376
+ *value = NULL;
377
+
378
+ while (*name_end && is_namechar(*name_end))
379
+ name_end++;
380
+
381
+ if (line == name_end) {
382
+ set_parse_error(reader, 0, "Invalid configuration key");
383
+ return -1;
384
+ }
385
+
386
+ value_start = name_end;
387
+
388
+ while (*value_start && git__isspace(*value_start))
389
+ value_start++;
390
+
391
+ if (*value_start == '=') {
392
+ *value = value_start + 1;
393
+ } else if (*value_start) {
394
+ set_parse_error(reader, 0, "Invalid configuration key");
395
+ return -1;
396
+ }
397
+
398
+ if ((*name = git__strndup(line, name_end - line)) == NULL)
399
+ return -1;
400
+
401
+ return 0;
402
+ }
403
+
404
+ static int parse_variable(git_config_parser *reader, char **var_name, char **var_value)
405
+ {
406
+ const char *value_start = NULL;
407
+ char *line;
408
+ int quote_count;
409
+ bool multiline;
410
+
411
+ git_parse_advance_ws(&reader->ctx);
412
+ line = git__strndup(reader->ctx.line, reader->ctx.line_len);
413
+ if (line == NULL)
414
+ return -1;
415
+
416
+ quote_count = strip_comments(line, 0);
417
+
418
+ /* If there is no value, boolean true is assumed */
419
+ *var_value = NULL;
420
+
421
+ if (parse_name(var_name, &value_start, reader, line) < 0)
422
+ goto on_error;
423
+
424
+ /*
425
+ * Now, let's try to parse the value
426
+ */
427
+ if (value_start != NULL) {
428
+ while (git__isspace(value_start[0]))
429
+ value_start++;
430
+
431
+ if (unescape_line(var_value, &multiline, value_start, 0) < 0)
432
+ goto on_error;
433
+
434
+ if (multiline) {
435
+ git_buf multi_value = GIT_BUF_INIT;
436
+ git_buf_attach(&multi_value, *var_value, 0);
437
+
438
+ if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
439
+ git_buf_oom(&multi_value)) {
440
+ git_buf_free(&multi_value);
441
+ goto on_error;
442
+ }
443
+
444
+ *var_value = git_buf_detach(&multi_value);
445
+ }
446
+ }
447
+
448
+ git__free(line);
449
+ return 0;
450
+
451
+ on_error:
452
+ git__free(*var_name);
453
+ git__free(line);
454
+ return -1;
455
+ }
456
+
457
+ int git_config_parse(
458
+ git_config_parser *parser,
459
+ git_config_parser_section_cb on_section,
460
+ git_config_parser_variable_cb on_variable,
461
+ git_config_parser_comment_cb on_comment,
462
+ git_config_parser_eof_cb on_eof,
463
+ void *data)
464
+ {
465
+ git_parse_ctx *ctx;
466
+ char *current_section = NULL, *var_name, *var_value;
467
+ int result = 0;
468
+
469
+ ctx = &parser->ctx;
470
+
471
+ skip_bom(ctx);
472
+
473
+ for (; ctx->remain_len > 0; git_parse_advance_line(ctx)) {
474
+ const char *line_start = parser->ctx.line;
475
+ size_t line_len = parser->ctx.line_len;
476
+ char c;
477
+
478
+ /*
479
+ * Get either first non-whitespace character or, if that does
480
+ * not exist, the first whitespace character. This is required
481
+ * to preserve whitespaces when writing back the file.
482
+ */
483
+ if (git_parse_peek(&c, ctx, GIT_PARSE_PEEK_SKIP_WHITESPACE) < 0 &&
484
+ git_parse_peek(&c, ctx, 0) < 0)
485
+ continue;
486
+
487
+ switch (c) {
488
+ case '[': /* section header, new section begins */
489
+ git__free(current_section);
490
+ current_section = NULL;
491
+
492
+ if ((result = parse_section_header(parser, &current_section)) == 0 && on_section) {
493
+ result = on_section(parser, current_section, line_start, line_len, data);
494
+ }
495
+ break;
496
+
497
+ case '\n': /* comment or whitespace-only */
498
+ case '\r':
499
+ case ' ':
500
+ case '\t':
501
+ case ';':
502
+ case '#':
503
+ if (on_comment) {
504
+ result = on_comment(parser, line_start, line_len, data);
505
+ }
506
+ break;
507
+
508
+ default: /* assume variable declaration */
509
+ if ((result = parse_variable(parser, &var_name, &var_value)) == 0 && on_variable) {
510
+ result = on_variable(parser, current_section, var_name, var_value, line_start, line_len, data);
511
+ }
512
+ break;
513
+ }
514
+
515
+ if (result < 0)
516
+ goto out;
517
+ }
518
+
519
+ if (on_eof)
520
+ result = on_eof(parser, current_section, data);
521
+
522
+ out:
523
+ git__free(current_section);
524
+ return result;
525
+ }