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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/rugged/rugged_blame.c +6 -3
- data/ext/rugged/rugged_branch_collection.c +3 -6
- data/ext/rugged/rugged_commit.c +56 -0
- data/ext/rugged/rugged_config.c +44 -9
- data/ext/rugged/rugged_diff.c +3 -14
- data/ext/rugged/rugged_diff_hunk.c +1 -3
- data/ext/rugged/rugged_index.c +1 -5
- data/ext/rugged/rugged_note.c +1 -4
- data/ext/rugged/rugged_patch.c +1 -4
- data/ext/rugged/rugged_reference_collection.c +1 -7
- data/ext/rugged/rugged_remote.c +5 -8
- data/ext/rugged/rugged_remote_collection.c +1 -6
- data/ext/rugged/rugged_repo.c +16 -48
- data/ext/rugged/rugged_revwalk.c +7 -16
- data/ext/rugged/rugged_settings.c +28 -0
- data/ext/rugged/rugged_submodule_collection.c +3 -4
- data/ext/rugged/rugged_tag_collection.c +1 -5
- data/ext/rugged/rugged_tree.c +2 -3
- data/lib/rugged/repository.rb +43 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +61 -510
- data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +14 -0
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +25 -8
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +27 -8
- data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
- data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +3 -0
- data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +4 -0
- data/vendor/libgit2/include/git2/config.h +29 -2
- data/vendor/libgit2/include/git2/describe.h +1 -1
- data/vendor/libgit2/include/git2/diff.h +59 -8
- data/vendor/libgit2/include/git2/graph.h +3 -0
- data/vendor/libgit2/include/git2/merge.h +6 -0
- data/vendor/libgit2/include/git2/message.h +43 -3
- data/vendor/libgit2/include/git2/notes.h +89 -0
- data/vendor/libgit2/include/git2/odb.h +8 -1
- data/vendor/libgit2/include/git2/patch.h +2 -2
- data/vendor/libgit2/include/git2/pathspec.h +35 -18
- data/vendor/libgit2/include/git2/refs.h +3 -0
- data/vendor/libgit2/include/git2/remote.h +34 -4
- data/vendor/libgit2/include/git2/repository.h +6 -6
- data/vendor/libgit2/include/git2/reset.h +4 -4
- data/vendor/libgit2/include/git2/status.h +4 -0
- data/vendor/libgit2/include/git2/sys/config.h +4 -1
- data/vendor/libgit2/include/git2/sys/odb_backend.h +2 -1
- data/vendor/libgit2/include/git2/tree.h +4 -3
- data/vendor/libgit2/include/git2/types.h +1 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +1 -1
- data/vendor/libgit2/src/CMakeLists.txt +463 -0
- data/vendor/libgit2/src/annotated_commit.c +1 -1
- data/vendor/libgit2/src/annotated_commit.h +2 -0
- data/vendor/libgit2/src/apply.c +2 -1
- data/vendor/libgit2/src/apply.h +2 -0
- data/vendor/libgit2/src/attr.c +24 -4
- data/vendor/libgit2/src/attr.h +2 -0
- data/vendor/libgit2/src/attr_file.c +9 -2
- data/vendor/libgit2/src/attr_file.h +2 -0
- data/vendor/libgit2/src/attrcache.c +9 -1
- data/vendor/libgit2/src/attrcache.h +2 -0
- data/vendor/libgit2/src/blame.c +1 -0
- data/vendor/libgit2/src/blame.h +2 -1
- data/vendor/libgit2/src/blame_git.c +1 -0
- data/vendor/libgit2/src/blame_git.h +2 -0
- data/vendor/libgit2/src/blob.c +2 -2
- data/vendor/libgit2/src/blob.h +2 -0
- data/vendor/libgit2/src/branch.c +8 -1
- data/vendor/libgit2/src/branch.h +2 -0
- data/vendor/libgit2/src/buf_text.c +7 -7
- data/vendor/libgit2/src/buf_text.h +3 -3
- data/vendor/libgit2/src/buffer.c +31 -1
- data/vendor/libgit2/src/buffer.h +3 -0
- data/vendor/libgit2/src/cache.c +2 -2
- data/vendor/libgit2/src/cache.h +2 -0
- data/vendor/libgit2/src/cc-compat.h +3 -3
- data/vendor/libgit2/src/checkout.c +30 -19
- data/vendor/libgit2/src/checkout.h +2 -0
- data/vendor/libgit2/src/cherrypick.c +1 -0
- data/vendor/libgit2/src/clone.c +2 -1
- data/vendor/libgit2/src/clone.h +4 -0
- data/vendor/libgit2/src/commit.c +2 -1
- data/vendor/libgit2/src/commit.h +2 -0
- data/vendor/libgit2/src/commit_list.c +1 -1
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +11 -5
- data/vendor/libgit2/src/config.c +12 -10
- data/vendor/libgit2/src/config.h +2 -0
- data/vendor/libgit2/src/config_cache.c +1 -0
- data/vendor/libgit2/src/config_file.c +287 -786
- data/vendor/libgit2/src/config_file.h +4 -3
- data/vendor/libgit2/src/config_parse.c +525 -0
- data/vendor/libgit2/src/config_parse.h +64 -0
- data/vendor/libgit2/src/crlf.c +2 -1
- data/vendor/libgit2/src/delta.c +28 -30
- data/vendor/libgit2/src/delta.h +1 -0
- data/vendor/libgit2/src/describe.c +3 -1
- data/vendor/libgit2/src/diff.c +148 -2
- data/vendor/libgit2/src/diff.h +3 -1
- data/vendor/libgit2/src/diff_driver.c +12 -9
- data/vendor/libgit2/src/diff_driver.h +4 -1
- data/vendor/libgit2/src/diff_file.c +7 -4
- data/vendor/libgit2/src/diff_file.h +1 -0
- data/vendor/libgit2/src/diff_generate.c +6 -3
- data/vendor/libgit2/src/diff_generate.h +6 -1
- data/vendor/libgit2/src/diff_parse.c +5 -4
- data/vendor/libgit2/src/diff_parse.h +2 -0
- data/vendor/libgit2/src/diff_print.c +2 -0
- data/vendor/libgit2/src/diff_stats.c +2 -0
- data/vendor/libgit2/src/diff_tform.c +2 -1
- data/vendor/libgit2/src/diff_tform.h +4 -1
- data/vendor/libgit2/src/diff_xdiff.c +5 -2
- data/vendor/libgit2/src/diff_xdiff.h +2 -0
- data/vendor/libgit2/src/errors.c +2 -0
- data/vendor/libgit2/src/features.h.in +36 -0
- data/vendor/libgit2/src/fetch.c +2 -2
- data/vendor/libgit2/src/fetch.h +4 -0
- data/vendor/libgit2/src/fetchhead.c +3 -3
- data/vendor/libgit2/src/fetchhead.h +3 -0
- data/vendor/libgit2/src/filebuf.c +2 -1
- data/vendor/libgit2/src/filebuf.h +2 -0
- data/vendor/libgit2/src/fileops.c +12 -1
- data/vendor/libgit2/src/fileops.h +7 -1
- data/vendor/libgit2/src/filter.c +2 -1
- data/vendor/libgit2/src/filter.h +1 -0
- data/vendor/libgit2/src/fnmatch.c +2 -2
- data/vendor/libgit2/src/fnmatch.h +3 -4
- data/vendor/libgit2/src/global.c +4 -3
- data/vendor/libgit2/src/global.h +1 -5
- data/vendor/libgit2/src/graph.c +2 -0
- data/vendor/libgit2/src/hash.c +0 -1
- data/vendor/libgit2/src/hash.h +3 -1
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +3 -3
- data/vendor/libgit2/src/hash/hash_common_crypto.h +18 -5
- data/vendor/libgit2/src/hash/hash_generic.c +2 -2
- data/vendor/libgit2/src/hash/hash_generic.h +5 -3
- data/vendor/libgit2/src/hash/hash_openssl.h +3 -3
- data/vendor/libgit2/src/hash/hash_win32.c +57 -14
- data/vendor/libgit2/src/hash/hash_win32.h +4 -3
- data/vendor/libgit2/src/hashsig.c +3 -0
- data/vendor/libgit2/src/ident.c +2 -0
- data/vendor/libgit2/src/idxmap.h +2 -1
- data/vendor/libgit2/src/ignore.c +14 -2
- data/vendor/libgit2/src/ignore.h +2 -0
- data/vendor/libgit2/src/index.c +20 -40
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/indexer.c +13 -5
- data/vendor/libgit2/src/indexer.h +5 -1
- data/vendor/libgit2/src/integer.h +1 -1
- data/vendor/libgit2/src/iterator.c +44 -3
- data/vendor/libgit2/src/iterator.h +3 -0
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +155 -33
- data/vendor/libgit2/src/merge.h +2 -0
- data/vendor/libgit2/src/merge_driver.c +2 -2
- data/vendor/libgit2/src/merge_driver.h +2 -0
- data/vendor/libgit2/src/merge_file.c +3 -0
- data/vendor/libgit2/src/message.h +3 -1
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/mwindow.h +2 -0
- data/vendor/libgit2/src/netops.c +75 -62
- data/vendor/libgit2/src/netops.h +2 -1
- data/vendor/libgit2/src/notes.c +164 -48
- data/vendor/libgit2/src/notes.h +1 -1
- data/vendor/libgit2/src/object.c +14 -3
- data/vendor/libgit2/src/object.h +4 -0
- data/vendor/libgit2/src/object_api.c +3 -2
- data/vendor/libgit2/src/odb.c +104 -38
- data/vendor/libgit2/src/odb.h +3 -1
- data/vendor/libgit2/src/odb_loose.c +414 -267
- data/vendor/libgit2/src/odb_mempack.c +1 -0
- data/vendor/libgit2/src/odb_pack.c +2 -1
- data/vendor/libgit2/src/offmap.h +1 -0
- data/vendor/libgit2/src/oid.c +2 -1
- data/vendor/libgit2/src/oid.h +3 -8
- data/vendor/libgit2/src/oidarray.c +2 -1
- data/vendor/libgit2/src/oidarray.h +1 -0
- data/vendor/libgit2/src/oidmap.h +1 -0
- data/vendor/libgit2/src/pack-objects.c +5 -1
- data/vendor/libgit2/src/pack-objects.h +1 -1
- data/vendor/libgit2/src/pack.c +2 -6
- data/vendor/libgit2/src/pack.h +2 -1
- data/vendor/libgit2/src/parse.c +121 -0
- data/vendor/libgit2/src/parse.h +61 -0
- data/vendor/libgit2/src/patch.c +9 -2
- data/vendor/libgit2/src/patch.h +2 -0
- data/vendor/libgit2/src/patch_generate.c +6 -5
- data/vendor/libgit2/src/patch_generate.h +1 -0
- data/vendor/libgit2/src/patch_parse.c +265 -276
- data/vendor/libgit2/src/patch_parse.h +6 -11
- data/vendor/libgit2/src/path.c +24 -181
- data/vendor/libgit2/src/path.h +14 -73
- data/vendor/libgit2/src/pathspec.c +2 -1
- data/vendor/libgit2/src/pathspec.h +2 -1
- data/vendor/libgit2/src/pool.c +8 -0
- data/vendor/libgit2/src/pool.h +1 -0
- data/vendor/libgit2/src/posix.c +2 -1
- data/vendor/libgit2/src/posix.h +1 -0
- data/vendor/libgit2/src/pqueue.c +1 -0
- data/vendor/libgit2/src/pqueue.h +2 -0
- data/vendor/libgit2/src/proxy.c +2 -1
- data/vendor/libgit2/src/proxy.h +3 -1
- data/vendor/libgit2/src/push.c +4 -171
- data/vendor/libgit2/src/push.h +2 -0
- data/vendor/libgit2/src/rebase.c +1 -0
- data/vendor/libgit2/src/refdb.c +2 -3
- data/vendor/libgit2/src/refdb.h +2 -0
- data/vendor/libgit2/src/refdb_fs.c +5 -3
- data/vendor/libgit2/src/refdb_fs.h +4 -0
- data/vendor/libgit2/src/reflog.c +1 -0
- data/vendor/libgit2/src/reflog.h +2 -1
- data/vendor/libgit2/src/refs.c +1 -0
- data/vendor/libgit2/src/refs.h +2 -1
- data/vendor/libgit2/src/refspec.c +2 -2
- data/vendor/libgit2/src/refspec.h +2 -0
- data/vendor/libgit2/src/remote.c +56 -10
- data/vendor/libgit2/src/remote.h +2 -0
- data/vendor/libgit2/src/repository.c +16 -14
- data/vendor/libgit2/src/repository.h +2 -0
- data/vendor/libgit2/src/reset.c +6 -5
- data/vendor/libgit2/src/revert.c +1 -0
- data/vendor/libgit2/src/revparse.c +3 -5
- data/vendor/libgit2/src/revwalk.c +2 -2
- data/vendor/libgit2/src/revwalk.h +2 -0
- data/vendor/libgit2/src/settings.c +6 -8
- data/vendor/libgit2/src/sha1_lookup.c +2 -216
- data/vendor/libgit2/src/sha1_lookup.h +2 -6
- data/vendor/libgit2/src/signature.c +8 -3
- data/vendor/libgit2/src/signature.h +2 -0
- data/vendor/libgit2/src/sortedcache.c +7 -0
- data/vendor/libgit2/src/sortedcache.h +2 -0
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +14 -9
- data/vendor/libgit2/src/status.h +2 -0
- data/vendor/libgit2/src/{curl_stream.c → streams/curl.c} +2 -0
- data/vendor/libgit2/src/{curl_stream.h → streams/curl.h} +4 -2
- data/vendor/libgit2/src/{openssl_stream.c → streams/openssl.c} +47 -18
- data/vendor/libgit2/src/{openssl_stream.h → streams/openssl.h} +6 -2
- data/vendor/libgit2/src/{socket_stream.c → streams/socket.c} +2 -2
- data/vendor/libgit2/src/{socket_stream.h → streams/socket.h} +4 -2
- data/vendor/libgit2/src/{stransport_stream.c → streams/stransport.c} +4 -2
- data/vendor/libgit2/src/{stransport_stream.h → streams/stransport.h} +4 -2
- data/vendor/libgit2/src/{tls_stream.c → streams/tls.c} +4 -3
- data/vendor/libgit2/src/{tls_stream.h → streams/tls.h} +4 -2
- data/vendor/libgit2/src/submodule.c +28 -80
- data/vendor/libgit2/src/submodule.h +2 -13
- data/vendor/libgit2/src/sysdir.c +75 -8
- data/vendor/libgit2/src/sysdir.h +2 -1
- data/vendor/libgit2/src/tag.c +2 -2
- data/vendor/libgit2/src/tag.h +2 -0
- data/vendor/libgit2/src/thread-utils.c +1 -0
- data/vendor/libgit2/src/thread-utils.h +1 -1
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +2 -0
- data/vendor/libgit2/src/trailer.c +416 -0
- data/vendor/libgit2/src/transaction.c +2 -1
- data/vendor/libgit2/src/transport.c +2 -0
- data/vendor/libgit2/src/transports/auth.c +2 -1
- data/vendor/libgit2/src/transports/auth.h +4 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +2 -1
- data/vendor/libgit2/src/transports/auth_negotiate.h +3 -3
- data/vendor/libgit2/src/transports/cred.c +2 -0
- data/vendor/libgit2/src/transports/cred.h +4 -2
- data/vendor/libgit2/src/transports/cred_helpers.c +1 -0
- data/vendor/libgit2/src/transports/git.c +3 -1
- data/vendor/libgit2/src/transports/http.c +10 -14
- data/vendor/libgit2/src/transports/http.h +23 -0
- data/vendor/libgit2/src/transports/local.c +23 -5
- data/vendor/libgit2/src/transports/smart.c +3 -1
- data/vendor/libgit2/src/transports/smart.h +23 -16
- data/vendor/libgit2/src/transports/smart_pkt.c +114 -130
- data/vendor/libgit2/src/transports/smart_protocol.c +26 -22
- data/vendor/libgit2/src/transports/ssh.c +12 -7
- data/vendor/libgit2/src/transports/ssh.h +4 -2
- data/vendor/libgit2/src/transports/winhttp.c +19 -21
- data/vendor/libgit2/src/tree-cache.c +1 -0
- data/vendor/libgit2/src/tree-cache.h +1 -0
- data/vendor/libgit2/src/tree.c +20 -14
- data/vendor/libgit2/src/tree.h +2 -0
- data/vendor/libgit2/src/tsort.c +0 -1
- data/vendor/libgit2/src/unix/map.c +4 -1
- data/vendor/libgit2/src/unix/posix.h +8 -4
- data/vendor/libgit2/src/unix/pthread.h +1 -1
- data/vendor/libgit2/src/unix/realpath.c +4 -1
- data/vendor/libgit2/src/util.c +6 -5
- data/vendor/libgit2/src/util.h +39 -111
- data/vendor/libgit2/src/varint.c +0 -1
- data/vendor/libgit2/src/varint.h +2 -0
- data/vendor/libgit2/src/vector.c +1 -1
- data/vendor/libgit2/src/win32/dir.c +3 -0
- data/vendor/libgit2/src/win32/dir.h +4 -3
- data/vendor/libgit2/src/win32/error.c +1 -1
- data/vendor/libgit2/src/win32/error.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +2 -1
- data/vendor/libgit2/src/win32/findfile.h +4 -2
- data/vendor/libgit2/src/win32/map.c +2 -0
- data/vendor/libgit2/src/win32/mingw-compat.h +3 -3
- data/vendor/libgit2/src/win32/msvc-compat.h +3 -3
- data/vendor/libgit2/src/win32/path_w32.c +7 -12
- data/vendor/libgit2/src/win32/path_w32.h +3 -2
- data/vendor/libgit2/src/win32/posix.h +2 -2
- data/vendor/libgit2/src/win32/posix_w32.c +11 -5
- data/vendor/libgit2/src/win32/precompiled.h +2 -1
- data/vendor/libgit2/src/win32/reparse.h +2 -2
- data/vendor/libgit2/src/win32/thread.c +1 -0
- data/vendor/libgit2/src/win32/thread.h +2 -2
- data/vendor/libgit2/src/win32/utf-conv.c +0 -1
- data/vendor/libgit2/src/win32/utf-conv.h +4 -3
- data/vendor/libgit2/src/win32/w32_buffer.c +1 -1
- data/vendor/libgit2/src/win32/w32_buffer.h +4 -2
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -1
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +85 -2
- data/vendor/libgit2/src/win32/w32_stack.c +2 -1
- data/vendor/libgit2/src/win32/w32_stack.h +5 -3
- data/vendor/libgit2/src/win32/w32_util.h +4 -2
- data/vendor/libgit2/src/win32/win32-compat.h +3 -3
- data/vendor/libgit2/src/worktree.c +4 -5
- data/vendor/libgit2/src/worktree.h +2 -0
- data/vendor/libgit2/src/xdiff/xdiff.h +22 -13
- data/vendor/libgit2/src/xdiff/xdiffi.c +523 -81
- data/vendor/libgit2/src/xdiff/xdiffi.h +2 -2
- data/vendor/libgit2/src/xdiff/xemit.c +63 -39
- data/vendor/libgit2/src/xdiff/xemit.h +2 -2
- data/vendor/libgit2/src/xdiff/xhistogram.c +0 -1
- data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
- data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
- data/vendor/libgit2/src/xdiff/xmerge.c +80 -20
- data/vendor/libgit2/src/xdiff/xpatience.c +41 -9
- data/vendor/libgit2/src/xdiff/xprepare.c +2 -2
- data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
- data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
- data/vendor/libgit2/src/xdiff/xutils.c +47 -27
- data/vendor/libgit2/src/xdiff/xutils.h +2 -5
- data/vendor/libgit2/src/zstream.c +65 -45
- data/vendor/libgit2/src/zstream.h +9 -2
- metadata +27 -13
- data/vendor/libgit2/include/git2/sys/remote.h +0 -16
data/vendor/libgit2/src/notes.h
CHANGED
data/vendor/libgit2/src/object.c
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
#include "object.h"
|
|
9
|
+
|
|
7
10
|
#include "git2/object.h"
|
|
8
11
|
|
|
9
|
-
#include "common.h"
|
|
10
12
|
#include "repository.h"
|
|
11
13
|
|
|
12
14
|
#include "commit.h"
|
|
@@ -233,14 +235,23 @@ const char *git_object_type2string(git_otype type)
|
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
git_otype git_object_string2type(const char *str)
|
|
238
|
+
{
|
|
239
|
+
if (!str)
|
|
240
|
+
return GIT_OBJ_BAD;
|
|
241
|
+
|
|
242
|
+
return git_object_stringn2type(str, strlen(str));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
git_otype git_object_stringn2type(const char *str, size_t len)
|
|
236
246
|
{
|
|
237
247
|
size_t i;
|
|
238
248
|
|
|
239
|
-
if (!str || !*str)
|
|
249
|
+
if (!str || !len || !*str)
|
|
240
250
|
return GIT_OBJ_BAD;
|
|
241
251
|
|
|
242
252
|
for (i = 0; i < ARRAY_SIZE(git_objects_table); i++)
|
|
243
|
-
if (
|
|
253
|
+
if (*git_objects_table[i].str &&
|
|
254
|
+
!git__prefixncmp(str, len, git_objects_table[i].str))
|
|
244
255
|
return (git_otype)i;
|
|
245
256
|
|
|
246
257
|
return GIT_OBJ_BAD;
|
data/vendor/libgit2/src/object.h
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
#ifndef INCLUDE_object_h__
|
|
8
8
|
#define INCLUDE_object_h__
|
|
9
9
|
|
|
10
|
+
#include "common.h"
|
|
11
|
+
|
|
10
12
|
#include "repository.h"
|
|
11
13
|
|
|
12
14
|
extern bool git_object__strict_input_validation;
|
|
@@ -28,6 +30,8 @@ int git_object__from_odb_object(
|
|
|
28
30
|
|
|
29
31
|
int git_object__resolve_to_type(git_object **obj, git_otype type);
|
|
30
32
|
|
|
33
|
+
git_otype git_object_stringn2type(const char *str, size_t len);
|
|
34
|
+
|
|
31
35
|
int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header);
|
|
32
36
|
|
|
33
37
|
void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid);
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
|
-
#include "git2/object.h"
|
|
8
7
|
|
|
9
8
|
#include "common.h"
|
|
10
|
-
#include "repository.h"
|
|
11
9
|
|
|
10
|
+
#include "git2/object.h"
|
|
11
|
+
|
|
12
|
+
#include "repository.h"
|
|
12
13
|
#include "commit.h"
|
|
13
14
|
#include "tree.h"
|
|
14
15
|
#include "blob.h"
|
data/vendor/libgit2/src/odb.c
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#include "
|
|
8
|
+
#include "odb.h"
|
|
9
|
+
|
|
9
10
|
#include <zlib.h>
|
|
10
11
|
#include "git2/object.h"
|
|
11
12
|
#include "git2/sys/odb_backend.h"
|
|
12
13
|
#include "fileops.h"
|
|
13
14
|
#include "hash.h"
|
|
14
|
-
#include "odb.h"
|
|
15
15
|
#include "delta.h"
|
|
16
16
|
#include "filter.h"
|
|
17
17
|
#include "repository.h"
|
|
@@ -53,6 +53,7 @@ static git_cache *odb_cache(git_odb *odb)
|
|
|
53
53
|
|
|
54
54
|
static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id);
|
|
55
55
|
static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
|
|
56
|
+
static int error_null_oid(int error, const char *message);
|
|
56
57
|
|
|
57
58
|
static git_otype odb_hardcoded_type(const git_oid *id)
|
|
58
59
|
{
|
|
@@ -65,50 +66,75 @@ static git_otype odb_hardcoded_type(const git_oid *id)
|
|
|
65
66
|
return GIT_OBJ_BAD;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
static int odb_read_hardcoded(git_rawobj *raw, const git_oid *id)
|
|
69
|
+
static int odb_read_hardcoded(bool *found, git_rawobj *raw, const git_oid *id)
|
|
69
70
|
{
|
|
70
|
-
git_otype type
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
git_otype type;
|
|
72
|
+
|
|
73
|
+
*found = false;
|
|
74
|
+
|
|
75
|
+
if ((type = odb_hardcoded_type(id)) == GIT_OBJ_BAD)
|
|
76
|
+
return 0;
|
|
73
77
|
|
|
74
78
|
raw->type = type;
|
|
75
79
|
raw->len = 0;
|
|
76
80
|
raw->data = git__calloc(1, sizeof(uint8_t));
|
|
81
|
+
GITERR_CHECK_ALLOC(raw->data);
|
|
82
|
+
|
|
83
|
+
*found = true;
|
|
77
84
|
return 0;
|
|
78
85
|
}
|
|
79
86
|
|
|
80
|
-
int git_odb__format_object_header(
|
|
87
|
+
int git_odb__format_object_header(
|
|
88
|
+
size_t *written,
|
|
89
|
+
char *hdr,
|
|
90
|
+
size_t hdr_size,
|
|
91
|
+
git_off_t obj_len,
|
|
92
|
+
git_otype obj_type)
|
|
81
93
|
{
|
|
82
94
|
const char *type_str = git_object_type2string(obj_type);
|
|
83
|
-
int
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
int hdr_max = (hdr_size > INT_MAX-2) ? (INT_MAX-2) : (int)hdr_size;
|
|
96
|
+
int len;
|
|
97
|
+
|
|
98
|
+
len = p_snprintf(hdr, hdr_max, "%s %lld", type_str, (long long)obj_len);
|
|
99
|
+
|
|
100
|
+
if (len < 0 || len >= hdr_max) {
|
|
101
|
+
giterr_set(GITERR_OS, "object header creation failed");
|
|
102
|
+
return -1;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
*written = (size_t)(len + 1);
|
|
106
|
+
return 0;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
int git_odb__hashobj(git_oid *id, git_rawobj *obj)
|
|
89
110
|
{
|
|
90
111
|
git_buf_vec vec[2];
|
|
91
112
|
char header[64];
|
|
92
|
-
|
|
113
|
+
size_t hdrlen;
|
|
114
|
+
int error;
|
|
93
115
|
|
|
94
116
|
assert(id && obj);
|
|
95
117
|
|
|
96
|
-
if (!git_object_typeisloose(obj->type))
|
|
118
|
+
if (!git_object_typeisloose(obj->type)) {
|
|
119
|
+
giterr_set(GITERR_INVALID, "invalid object type");
|
|
97
120
|
return -1;
|
|
121
|
+
}
|
|
98
122
|
|
|
99
|
-
if (!obj->data && obj->len != 0)
|
|
123
|
+
if (!obj->data && obj->len != 0) {
|
|
124
|
+
giterr_set(GITERR_INVALID, "invalid object");
|
|
100
125
|
return -1;
|
|
126
|
+
}
|
|
101
127
|
|
|
102
|
-
|
|
128
|
+
if ((error = git_odb__format_object_header(&hdrlen,
|
|
129
|
+
header, sizeof(header), obj->len, obj->type)) < 0)
|
|
130
|
+
return error;
|
|
103
131
|
|
|
104
132
|
vec[0].data = header;
|
|
105
133
|
vec[0].len = hdrlen;
|
|
106
134
|
vec[1].data = obj->data;
|
|
107
135
|
vec[1].len = obj->len;
|
|
108
136
|
|
|
109
|
-
git_hash_vec(id, vec, 2);
|
|
110
|
-
|
|
111
|
-
return 0;
|
|
137
|
+
return git_hash_vec(id, vec, 2);
|
|
112
138
|
}
|
|
113
139
|
|
|
114
140
|
|
|
@@ -171,7 +197,7 @@ void git_odb_object_free(git_odb_object *object)
|
|
|
171
197
|
|
|
172
198
|
int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
|
|
173
199
|
{
|
|
174
|
-
|
|
200
|
+
size_t hdr_len;
|
|
175
201
|
char hdr[64], buffer[FILEIO_BUFSIZE];
|
|
176
202
|
git_hash_ctx ctx;
|
|
177
203
|
ssize_t read_len = 0;
|
|
@@ -183,9 +209,11 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
|
|
|
183
209
|
}
|
|
184
210
|
|
|
185
211
|
if ((error = git_hash_ctx_init(&ctx)) < 0)
|
|
186
|
-
return
|
|
212
|
+
return error;
|
|
187
213
|
|
|
188
|
-
|
|
214
|
+
if ((error = git_odb__format_object_header(&hdr_len, hdr,
|
|
215
|
+
sizeof(hdr), size, type)) < 0)
|
|
216
|
+
goto done;
|
|
189
217
|
|
|
190
218
|
if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0)
|
|
191
219
|
goto done;
|
|
@@ -341,8 +369,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t
|
|
|
341
369
|
{
|
|
342
370
|
fake_wstream *stream = (fake_wstream *)_stream;
|
|
343
371
|
|
|
344
|
-
|
|
345
|
-
return -1;
|
|
372
|
+
assert(stream->written + len <= stream->size);
|
|
346
373
|
|
|
347
374
|
memcpy(stream->buffer + stream->written, data, len);
|
|
348
375
|
stream->written += len;
|
|
@@ -735,6 +762,9 @@ int git_odb_exists(git_odb *db, const git_oid *id)
|
|
|
735
762
|
|
|
736
763
|
assert(db && id);
|
|
737
764
|
|
|
765
|
+
if (git_oid_iszero(id))
|
|
766
|
+
return 0;
|
|
767
|
+
|
|
738
768
|
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
|
|
739
769
|
git_odb_object_free(object);
|
|
740
770
|
return 1;
|
|
@@ -796,7 +826,7 @@ int git_odb_exists_prefix(
|
|
|
796
826
|
git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
|
|
797
827
|
{
|
|
798
828
|
int error;
|
|
799
|
-
git_oid key = {{0}};
|
|
829
|
+
git_oid key = {{0}};
|
|
800
830
|
|
|
801
831
|
assert(db && short_id);
|
|
802
832
|
|
|
@@ -958,6 +988,11 @@ int git_odb__read_header_or_object(
|
|
|
958
988
|
|
|
959
989
|
assert(db && id && out && len_p && type_p);
|
|
960
990
|
|
|
991
|
+
*out = NULL;
|
|
992
|
+
|
|
993
|
+
if (git_oid_iszero(id))
|
|
994
|
+
return error_null_oid(GIT_ENOTFOUND, "cannot read object");
|
|
995
|
+
|
|
961
996
|
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
|
|
962
997
|
*len_p = object->cached.size;
|
|
963
998
|
*type_p = object->cached.type;
|
|
@@ -965,7 +1000,6 @@ int git_odb__read_header_or_object(
|
|
|
965
1000
|
return 0;
|
|
966
1001
|
}
|
|
967
1002
|
|
|
968
|
-
*out = NULL;
|
|
969
1003
|
error = odb_read_header_1(len_p, type_p, db, id, false);
|
|
970
1004
|
|
|
971
1005
|
if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
|
|
@@ -1004,8 +1038,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
|
|
|
1004
1038
|
bool found = false;
|
|
1005
1039
|
int error = 0;
|
|
1006
1040
|
|
|
1007
|
-
if (!only_refreshed
|
|
1008
|
-
|
|
1041
|
+
if (!only_refreshed) {
|
|
1042
|
+
if ((error = odb_read_hardcoded(&found, &raw, id)) < 0)
|
|
1043
|
+
return error;
|
|
1044
|
+
}
|
|
1009
1045
|
|
|
1010
1046
|
for (i = 0; i < db->backends.length && !found; ++i) {
|
|
1011
1047
|
backend_internal *internal = git_vector_get(&db->backends, i);
|
|
@@ -1040,8 +1076,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
|
|
|
1040
1076
|
}
|
|
1041
1077
|
|
|
1042
1078
|
giterr_clear();
|
|
1043
|
-
if ((object = odb_object__alloc(id, &raw)) == NULL)
|
|
1079
|
+
if ((object = odb_object__alloc(id, &raw)) == NULL) {
|
|
1080
|
+
error = -1;
|
|
1044
1081
|
goto out;
|
|
1082
|
+
}
|
|
1045
1083
|
|
|
1046
1084
|
*out = git_cache_store_raw(odb_cache(db), object);
|
|
1047
1085
|
|
|
@@ -1057,6 +1095,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
|
|
|
1057
1095
|
|
|
1058
1096
|
assert(out && db && id);
|
|
1059
1097
|
|
|
1098
|
+
if (git_oid_iszero(id))
|
|
1099
|
+
return error_null_oid(GIT_ENOTFOUND, "cannot read object");
|
|
1100
|
+
|
|
1060
1101
|
*out = git_cache_get_raw(odb_cache(db), id);
|
|
1061
1102
|
if (*out != NULL)
|
|
1062
1103
|
return 0;
|
|
@@ -1078,11 +1119,14 @@ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id)
|
|
|
1078
1119
|
size_t _unused;
|
|
1079
1120
|
int error;
|
|
1080
1121
|
|
|
1122
|
+
if (git_oid_iszero(id))
|
|
1123
|
+
return error_null_oid(GIT_ENOTFOUND, "cannot get object type");
|
|
1124
|
+
|
|
1081
1125
|
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
|
|
1082
1126
|
*type_p = object->cached.type;
|
|
1083
1127
|
return 0;
|
|
1084
1128
|
}
|
|
1085
|
-
|
|
1129
|
+
|
|
1086
1130
|
error = odb_read_header_1(&_unused, type_p, db, id, false);
|
|
1087
1131
|
|
|
1088
1132
|
if (error == GIT_PASSTHROUGH) {
|
|
@@ -1161,8 +1205,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
|
|
|
1161
1205
|
}
|
|
1162
1206
|
}
|
|
1163
1207
|
|
|
1164
|
-
if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL)
|
|
1208
|
+
if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL) {
|
|
1209
|
+
error = -1;
|
|
1165
1210
|
goto out;
|
|
1211
|
+
}
|
|
1166
1212
|
|
|
1167
1213
|
*out = git_cache_store_raw(odb_cache(db), object);
|
|
1168
1214
|
|
|
@@ -1231,6 +1277,10 @@ int git_odb_write(
|
|
|
1231
1277
|
assert(oid && db);
|
|
1232
1278
|
|
|
1233
1279
|
git_odb_hash(oid, data, len, type);
|
|
1280
|
+
|
|
1281
|
+
if (git_oid_iszero(oid))
|
|
1282
|
+
return error_null_oid(GIT_EINVALID, "cannot write object");
|
|
1283
|
+
|
|
1234
1284
|
if (git_odb__freshen(db, oid))
|
|
1235
1285
|
return 0;
|
|
1236
1286
|
|
|
@@ -1263,13 +1313,17 @@ int git_odb_write(
|
|
|
1263
1313
|
return error;
|
|
1264
1314
|
}
|
|
1265
1315
|
|
|
1266
|
-
static
|
|
1316
|
+
static int hash_header(git_hash_ctx *ctx, git_off_t size, git_otype type)
|
|
1267
1317
|
{
|
|
1268
1318
|
char header[64];
|
|
1269
|
-
|
|
1319
|
+
size_t hdrlen;
|
|
1320
|
+
int error;
|
|
1270
1321
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1322
|
+
if ((error = git_odb__format_object_header(&hdrlen,
|
|
1323
|
+
header, sizeof(header), size, type)) < 0)
|
|
1324
|
+
return error;
|
|
1325
|
+
|
|
1326
|
+
return git_hash_update(ctx, header, hdrlen);
|
|
1273
1327
|
}
|
|
1274
1328
|
|
|
1275
1329
|
int git_odb_open_wstream(
|
|
@@ -1310,16 +1364,17 @@ int git_odb_open_wstream(
|
|
|
1310
1364
|
ctx = git__malloc(sizeof(git_hash_ctx));
|
|
1311
1365
|
GITERR_CHECK_ALLOC(ctx);
|
|
1312
1366
|
|
|
1313
|
-
if ((error = git_hash_ctx_init(ctx)) < 0
|
|
1367
|
+
if ((error = git_hash_ctx_init(ctx)) < 0 ||
|
|
1368
|
+
(error = hash_header(ctx, size, type)) < 0)
|
|
1314
1369
|
goto done;
|
|
1315
1370
|
|
|
1316
|
-
hash_header(ctx, size, type);
|
|
1317
1371
|
(*stream)->hash_ctx = ctx;
|
|
1318
|
-
|
|
1319
1372
|
(*stream)->declared_size = size;
|
|
1320
1373
|
(*stream)->received_bytes = 0;
|
|
1321
1374
|
|
|
1322
1375
|
done:
|
|
1376
|
+
if (error)
|
|
1377
|
+
git__free(ctx);
|
|
1323
1378
|
return error;
|
|
1324
1379
|
}
|
|
1325
1380
|
|
|
@@ -1378,7 +1433,12 @@ void git_odb_stream_free(git_odb_stream *stream)
|
|
|
1378
1433
|
stream->free(stream);
|
|
1379
1434
|
}
|
|
1380
1435
|
|
|
1381
|
-
int git_odb_open_rstream(
|
|
1436
|
+
int git_odb_open_rstream(
|
|
1437
|
+
git_odb_stream **stream,
|
|
1438
|
+
size_t *len,
|
|
1439
|
+
git_otype *type,
|
|
1440
|
+
git_odb *db,
|
|
1441
|
+
const git_oid *oid)
|
|
1382
1442
|
{
|
|
1383
1443
|
size_t i, reads = 0;
|
|
1384
1444
|
int error = GIT_ERROR;
|
|
@@ -1391,7 +1451,7 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
|
|
|
1391
1451
|
|
|
1392
1452
|
if (b->readstream != NULL) {
|
|
1393
1453
|
++reads;
|
|
1394
|
-
error = b->readstream(stream, b, oid);
|
|
1454
|
+
error = b->readstream(stream, len, type, b, oid);
|
|
1395
1455
|
}
|
|
1396
1456
|
}
|
|
1397
1457
|
|
|
@@ -1484,6 +1544,12 @@ int git_odb__error_notfound(
|
|
|
1484
1544
|
return GIT_ENOTFOUND;
|
|
1485
1545
|
}
|
|
1486
1546
|
|
|
1547
|
+
static int error_null_oid(int error, const char *message)
|
|
1548
|
+
{
|
|
1549
|
+
giterr_set(GITERR_ODB, "odb: %s: null OID cannot exist", message);
|
|
1550
|
+
return error;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1487
1553
|
int git_odb__error_ambiguous(const char *message)
|
|
1488
1554
|
{
|
|
1489
1555
|
giterr_set(GITERR_ODB, "ambiguous SHA1 prefix - %s", message);
|
data/vendor/libgit2/src/odb.h
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
#ifndef INCLUDE_odb_h__
|
|
8
8
|
#define INCLUDE_odb_h__
|
|
9
9
|
|
|
10
|
+
#include "common.h"
|
|
11
|
+
|
|
10
12
|
#include "git2/odb.h"
|
|
11
13
|
#include "git2/oid.h"
|
|
12
14
|
#include "git2/types.h"
|
|
@@ -68,7 +70,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj);
|
|
|
68
70
|
/*
|
|
69
71
|
* Format the object header such as it would appear in the on-disk object
|
|
70
72
|
*/
|
|
71
|
-
int git_odb__format_object_header(char *hdr, size_t
|
|
73
|
+
int git_odb__format_object_header(size_t *out_len, char *hdr, size_t hdr_size, git_off_t obj_len, git_otype obj_type);
|
|
72
74
|
/*
|
|
73
75
|
* Hash an open file descriptor.
|
|
74
76
|
* This is a performance call when the contents of a fd need to be hashed,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#include "common.h"
|
|
9
|
+
|
|
9
10
|
#include <zlib.h>
|
|
10
11
|
#include "git2/object.h"
|
|
11
12
|
#include "git2/sys/odb_backend.h"
|
|
@@ -15,10 +16,14 @@
|
|
|
15
16
|
#include "delta.h"
|
|
16
17
|
#include "filebuf.h"
|
|
17
18
|
#include "object.h"
|
|
19
|
+
#include "zstream.h"
|
|
18
20
|
|
|
19
21
|
#include "git2/odb_backend.h"
|
|
20
22
|
#include "git2/types.h"
|
|
21
23
|
|
|
24
|
+
/* maximum possible header length */
|
|
25
|
+
#define MAX_HEADER_LEN 64
|
|
26
|
+
|
|
22
27
|
typedef struct { /* object header data */
|
|
23
28
|
git_otype type; /* object type */
|
|
24
29
|
size_t size; /* object size */
|
|
@@ -29,6 +34,15 @@ typedef struct {
|
|
|
29
34
|
git_filebuf fbuf;
|
|
30
35
|
} loose_writestream;
|
|
31
36
|
|
|
37
|
+
typedef struct {
|
|
38
|
+
git_odb_stream stream;
|
|
39
|
+
git_map map;
|
|
40
|
+
char start[MAX_HEADER_LEN];
|
|
41
|
+
size_t start_len;
|
|
42
|
+
size_t start_read;
|
|
43
|
+
git_zstream zstream;
|
|
44
|
+
} loose_readstream;
|
|
45
|
+
|
|
32
46
|
typedef struct loose_backend {
|
|
33
47
|
git_odb_backend parent;
|
|
34
48
|
|
|
@@ -90,222 +104,117 @@ static int object_mkdir(const git_buf *name, const loose_backend *be)
|
|
|
90
104
|
GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL);
|
|
91
105
|
}
|
|
92
106
|
|
|
93
|
-
static
|
|
107
|
+
static int parse_header_packlike(
|
|
108
|
+
obj_hdr *out, size_t *out_len, const unsigned char *data, size_t len)
|
|
94
109
|
{
|
|
95
110
|
unsigned long c;
|
|
96
|
-
unsigned char *data = (unsigned char *)obj->ptr;
|
|
97
111
|
size_t shift, size, used = 0;
|
|
98
112
|
|
|
99
|
-
if (
|
|
100
|
-
|
|
113
|
+
if (len == 0)
|
|
114
|
+
goto on_error;
|
|
101
115
|
|
|
102
116
|
c = data[used++];
|
|
103
|
-
|
|
117
|
+
out->type = (c >> 4) & 7;
|
|
104
118
|
|
|
105
119
|
size = c & 15;
|
|
106
120
|
shift = 4;
|
|
107
121
|
while (c & 0x80) {
|
|
108
|
-
if (
|
|
109
|
-
|
|
122
|
+
if (len <= used)
|
|
123
|
+
goto on_error;
|
|
124
|
+
|
|
110
125
|
if (sizeof(size_t) * 8 <= shift)
|
|
111
|
-
|
|
126
|
+
goto on_error;
|
|
127
|
+
|
|
112
128
|
c = data[used++];
|
|
113
129
|
size += (c & 0x7f) << shift;
|
|
114
130
|
shift += 7;
|
|
115
131
|
}
|
|
116
|
-
hdr->size = size;
|
|
117
|
-
|
|
118
|
-
return used;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
static size_t get_object_header(obj_hdr *hdr, unsigned char *data)
|
|
122
|
-
{
|
|
123
|
-
char c, typename[10];
|
|
124
|
-
size_t size, used = 0;
|
|
125
|
-
|
|
126
|
-
/*
|
|
127
|
-
* type name string followed by space.
|
|
128
|
-
*/
|
|
129
|
-
while ((c = data[used]) != ' ') {
|
|
130
|
-
typename[used++] = c;
|
|
131
|
-
if (used >= sizeof(typename))
|
|
132
|
-
return 0;
|
|
133
|
-
}
|
|
134
|
-
typename[used] = 0;
|
|
135
|
-
if (used == 0)
|
|
136
|
-
return 0;
|
|
137
|
-
hdr->type = git_object_string2type(typename);
|
|
138
|
-
used++; /* consume the space */
|
|
139
|
-
|
|
140
|
-
/*
|
|
141
|
-
* length follows immediately in decimal (without
|
|
142
|
-
* leading zeros).
|
|
143
|
-
*/
|
|
144
|
-
size = data[used++] - '0';
|
|
145
|
-
if (size > 9)
|
|
146
|
-
return 0;
|
|
147
|
-
if (size) {
|
|
148
|
-
while ((c = data[used]) != '\0') {
|
|
149
|
-
size_t d = c - '0';
|
|
150
|
-
if (d > 9)
|
|
151
|
-
break;
|
|
152
|
-
used++;
|
|
153
|
-
size = size * 10 + d;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
hdr->size = size;
|
|
157
|
-
|
|
158
|
-
/*
|
|
159
|
-
* the length must be followed by a zero byte
|
|
160
|
-
*/
|
|
161
|
-
if (data[used++] != '\0')
|
|
162
|
-
return 0;
|
|
163
|
-
|
|
164
|
-
return used;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
132
|
|
|
133
|
+
out->size = size;
|
|
168
134
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
* ZLIB RELATED FUNCTIONS
|
|
172
|
-
*
|
|
173
|
-
***********************************************************/
|
|
174
|
-
|
|
175
|
-
static void init_stream(z_stream *s, void *out, size_t len)
|
|
176
|
-
{
|
|
177
|
-
memset(s, 0, sizeof(*s));
|
|
178
|
-
s->next_out = out;
|
|
179
|
-
s->avail_out = (uInt)len;
|
|
180
|
-
}
|
|
135
|
+
if (out_len)
|
|
136
|
+
*out_len = used;
|
|
181
137
|
|
|
182
|
-
|
|
183
|
-
{
|
|
184
|
-
s->next_in = in;
|
|
185
|
-
s->avail_in = (uInt)len;
|
|
186
|
-
}
|
|
138
|
+
return 0;
|
|
187
139
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
s->avail_out = (uInt)len;
|
|
140
|
+
on_error:
|
|
141
|
+
giterr_set(GITERR_OBJECT, "failed to parse loose object: invalid header");
|
|
142
|
+
return -1;
|
|
192
143
|
}
|
|
193
144
|
|
|
194
|
-
|
|
195
|
-
|
|
145
|
+
static int parse_header(
|
|
146
|
+
obj_hdr *out,
|
|
147
|
+
size_t *out_len,
|
|
148
|
+
const unsigned char *_data,
|
|
149
|
+
size_t data_len)
|
|
196
150
|
{
|
|
197
|
-
|
|
151
|
+
const char *data = (char *)_data;
|
|
152
|
+
size_t i, typename_len, size_idx, size_len;
|
|
153
|
+
int64_t size;
|
|
198
154
|
|
|
199
|
-
|
|
200
|
-
set_stream_input(s, obj->ptr, git_buf_len(obj));
|
|
155
|
+
*out_len = 0;
|
|
201
156
|
|
|
202
|
-
|
|
203
|
-
|
|
157
|
+
/* find the object type name */
|
|
158
|
+
for (i = 0, typename_len = 0; i < data_len; i++, typename_len++) {
|
|
159
|
+
if (data[i] == ' ')
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
204
162
|
|
|
205
|
-
|
|
206
|
-
|
|
163
|
+
if (typename_len == data_len)
|
|
164
|
+
goto on_error;
|
|
207
165
|
|
|
208
|
-
|
|
209
|
-
{
|
|
210
|
-
inflateEnd(s);
|
|
211
|
-
}
|
|
166
|
+
out->type = git_object_stringn2type(data, typename_len);
|
|
212
167
|
|
|
213
|
-
|
|
214
|
-
{
|
|
215
|
-
|
|
168
|
+
size_idx = typename_len + 1;
|
|
169
|
+
for (i = size_idx, size_len = 0; i < data_len; i++, size_len++) {
|
|
170
|
+
if (data[i] == '\0')
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
216
173
|
|
|
217
|
-
|
|
218
|
-
|
|
174
|
+
if (i == data_len)
|
|
175
|
+
goto on_error;
|
|
219
176
|
|
|
220
|
-
|
|
177
|
+
if (git__strntol64(&size, &data[size_idx], size_len, NULL, 10) < 0 ||
|
|
178
|
+
size < 0)
|
|
179
|
+
goto on_error;
|
|
221
180
|
|
|
222
|
-
if ((
|
|
223
|
-
giterr_set(
|
|
181
|
+
if ((uint64_t)size > SIZE_MAX) {
|
|
182
|
+
giterr_set(GITERR_OBJECT, "object is larger than available memory");
|
|
224
183
|
return -1;
|
|
225
184
|
}
|
|
226
185
|
|
|
186
|
+
out->size = size;
|
|
187
|
+
|
|
188
|
+
if (GIT_ADD_SIZET_OVERFLOW(out_len, i, 1))
|
|
189
|
+
goto on_error;
|
|
190
|
+
|
|
227
191
|
return 0;
|
|
192
|
+
|
|
193
|
+
on_error:
|
|
194
|
+
giterr_set(GITERR_OBJECT, "failed to parse loose object: invalid header");
|
|
195
|
+
return -1;
|
|
228
196
|
}
|
|
229
197
|
|
|
230
|
-
static int is_zlib_compressed_data(unsigned char *data)
|
|
198
|
+
static int is_zlib_compressed_data(unsigned char *data, size_t data_len)
|
|
231
199
|
{
|
|
232
200
|
unsigned int w;
|
|
233
201
|
|
|
202
|
+
if (data_len < 2)
|
|
203
|
+
return 0;
|
|
204
|
+
|
|
234
205
|
w = ((unsigned int)(data[0]) << 8) + data[1];
|
|
235
206
|
return (data[0] & 0x8F) == 0x08 && !(w % 31);
|
|
236
207
|
}
|
|
237
208
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
zs.avail_out = (uInt)outlen;
|
|
247
|
-
|
|
248
|
-
zs.next_in = in;
|
|
249
|
-
zs.avail_in = (uInt)inlen;
|
|
250
|
-
|
|
251
|
-
if (inflateInit(&zs) < Z_OK) {
|
|
252
|
-
giterr_set(GITERR_ZLIB, "failed to inflate buffer");
|
|
253
|
-
return -1;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
while (status == Z_OK)
|
|
257
|
-
status = inflate(&zs, Z_FINISH);
|
|
258
|
-
|
|
259
|
-
inflateEnd(&zs);
|
|
260
|
-
|
|
261
|
-
if (status != Z_STREAM_END /* || zs.avail_in != 0 */ ||
|
|
262
|
-
zs.total_out != outlen)
|
|
263
|
-
{
|
|
264
|
-
giterr_set(GITERR_ZLIB, "failed to inflate buffer; stream aborted prematurely");
|
|
265
|
-
return -1;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
return 0;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
|
|
272
|
-
{
|
|
273
|
-
unsigned char *buf, *head = hb;
|
|
274
|
-
size_t tail, alloc_size;
|
|
275
|
-
|
|
276
|
-
/*
|
|
277
|
-
* allocate a buffer to hold the inflated data and copy the
|
|
278
|
-
* initial sequence of inflated data from the tail of the
|
|
279
|
-
* head buffer, if any.
|
|
280
|
-
*/
|
|
281
|
-
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr->size, 1) ||
|
|
282
|
-
(buf = git__malloc(alloc_size)) == NULL) {
|
|
283
|
-
inflateEnd(s);
|
|
284
|
-
return NULL;
|
|
285
|
-
}
|
|
286
|
-
tail = s->total_out - used;
|
|
287
|
-
if (used > 0 && tail > 0) {
|
|
288
|
-
if (tail > hdr->size)
|
|
289
|
-
tail = hdr->size;
|
|
290
|
-
memcpy(buf, head + used, tail);
|
|
291
|
-
}
|
|
292
|
-
used = tail;
|
|
293
|
-
|
|
294
|
-
/*
|
|
295
|
-
* inflate the remainder of the object data, if any
|
|
296
|
-
*/
|
|
297
|
-
if (hdr->size < used)
|
|
298
|
-
inflateEnd(s);
|
|
299
|
-
else {
|
|
300
|
-
set_stream_output(s, buf + used, hdr->size - used);
|
|
301
|
-
if (finish_inflate(s)) {
|
|
302
|
-
git__free(buf);
|
|
303
|
-
return NULL;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
209
|
+
/***********************************************************
|
|
210
|
+
*
|
|
211
|
+
* ODB OBJECT READING & WRITING
|
|
212
|
+
*
|
|
213
|
+
* Backend for the public API; read headers and full objects
|
|
214
|
+
* from the ODB. Write raw data to the ODB.
|
|
215
|
+
*
|
|
216
|
+
***********************************************************/
|
|
306
217
|
|
|
307
|
-
return buf;
|
|
308
|
-
}
|
|
309
218
|
|
|
310
219
|
/*
|
|
311
220
|
* At one point, there was a loose object format that was intended to
|
|
@@ -313,98 +222,122 @@ static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
|
|
|
313
222
|
* of loose object data into packs. This format is no longer used, but
|
|
314
223
|
* we must still read it.
|
|
315
224
|
*/
|
|
316
|
-
static int
|
|
225
|
+
static int read_loose_packlike(git_rawobj *out, git_buf *obj)
|
|
317
226
|
{
|
|
318
|
-
|
|
227
|
+
git_buf body = GIT_BUF_INIT;
|
|
228
|
+
const unsigned char *obj_data;
|
|
319
229
|
obj_hdr hdr;
|
|
320
|
-
size_t
|
|
230
|
+
size_t obj_len, head_len, alloc_size;
|
|
231
|
+
int error;
|
|
232
|
+
|
|
233
|
+
obj_data = (unsigned char *)obj->ptr;
|
|
234
|
+
obj_len = obj->size;
|
|
321
235
|
|
|
322
236
|
/*
|
|
323
237
|
* read the object header, which is an (uncompressed)
|
|
324
238
|
* binary encoding of the object type and size.
|
|
325
239
|
*/
|
|
326
|
-
if ((
|
|
327
|
-
|
|
240
|
+
if ((error = parse_header_packlike(&hdr, &head_len, obj_data, obj_len)) < 0)
|
|
241
|
+
goto done;
|
|
242
|
+
|
|
243
|
+
if (!git_object_typeisloose(hdr.type) || head_len > obj_len) {
|
|
328
244
|
giterr_set(GITERR_ODB, "failed to inflate loose object");
|
|
329
|
-
|
|
245
|
+
error = -1;
|
|
246
|
+
goto done;
|
|
330
247
|
}
|
|
331
248
|
|
|
249
|
+
obj_data += head_len;
|
|
250
|
+
obj_len -= head_len;
|
|
251
|
+
|
|
332
252
|
/*
|
|
333
253
|
* allocate a buffer and inflate the data into it
|
|
334
254
|
*/
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
in = ((unsigned char *)obj->ptr) + used;
|
|
340
|
-
len = obj->size - used;
|
|
341
|
-
if (inflate_buffer(in, len, buf, hdr.size) < 0) {
|
|
342
|
-
git__free(buf);
|
|
343
|
-
return -1;
|
|
255
|
+
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) ||
|
|
256
|
+
git_buf_init(&body, alloc_size) < 0) {
|
|
257
|
+
error = -1;
|
|
258
|
+
goto done;
|
|
344
259
|
}
|
|
345
|
-
buf[hdr.size] = '\0';
|
|
346
260
|
|
|
347
|
-
|
|
261
|
+
if ((error = git_zstream_inflatebuf(&body, obj_data, obj_len)) < 0)
|
|
262
|
+
goto done;
|
|
263
|
+
|
|
348
264
|
out->len = hdr.size;
|
|
349
265
|
out->type = hdr.type;
|
|
266
|
+
out->data = git_buf_detach(&body);
|
|
350
267
|
|
|
351
|
-
|
|
268
|
+
done:
|
|
269
|
+
git_buf_free(&body);
|
|
270
|
+
return error;
|
|
352
271
|
}
|
|
353
272
|
|
|
354
|
-
static int
|
|
273
|
+
static int read_loose_standard(git_rawobj *out, git_buf *obj)
|
|
355
274
|
{
|
|
356
|
-
|
|
357
|
-
|
|
275
|
+
git_zstream zstream = GIT_ZSTREAM_INIT;
|
|
276
|
+
unsigned char head[MAX_HEADER_LEN], *body = NULL;
|
|
277
|
+
size_t decompressed, head_len, body_len, alloc_size;
|
|
358
278
|
obj_hdr hdr;
|
|
359
|
-
|
|
279
|
+
int error;
|
|
360
280
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
281
|
+
if ((error = git_zstream_init(&zstream, GIT_ZSTREAM_INFLATE)) < 0 ||
|
|
282
|
+
(error = git_zstream_set_input(&zstream, git_buf_cstr(obj), git_buf_len(obj))) < 0)
|
|
283
|
+
goto done;
|
|
284
|
+
|
|
285
|
+
decompressed = sizeof(head);
|
|
366
286
|
|
|
367
287
|
/*
|
|
368
|
-
* inflate the initial part of the
|
|
369
|
-
*
|
|
288
|
+
* inflate the initial part of the compressed buffer in order to
|
|
289
|
+
* parse the header; read the largest header possible, then push the
|
|
290
|
+
* remainder into the body buffer.
|
|
370
291
|
*/
|
|
371
|
-
if (
|
|
372
|
-
(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
292
|
+
if ((error = git_zstream_get_output(head, &decompressed, &zstream)) < 0 ||
|
|
293
|
+
(error = parse_header(&hdr, &head_len, head, decompressed)) < 0)
|
|
294
|
+
goto done;
|
|
295
|
+
|
|
296
|
+
if (!git_object_typeisloose(hdr.type)) {
|
|
376
297
|
giterr_set(GITERR_ODB, "failed to inflate disk object");
|
|
377
|
-
|
|
298
|
+
error = -1;
|
|
299
|
+
goto done;
|
|
378
300
|
}
|
|
379
301
|
|
|
380
302
|
/*
|
|
381
303
|
* allocate a buffer and inflate the object data into it
|
|
382
304
|
* (including the initial sequence in the head buffer).
|
|
383
305
|
*/
|
|
384
|
-
if ((
|
|
385
|
-
|
|
386
|
-
|
|
306
|
+
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) ||
|
|
307
|
+
(body = git__malloc(alloc_size)) == NULL) {
|
|
308
|
+
error = -1;
|
|
309
|
+
goto done;
|
|
310
|
+
}
|
|
387
311
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
out->type = hdr.type;
|
|
312
|
+
assert(decompressed >= head_len);
|
|
313
|
+
body_len = decompressed - head_len;
|
|
391
314
|
|
|
392
|
-
|
|
393
|
-
|
|
315
|
+
if (body_len)
|
|
316
|
+
memcpy(body, head + head_len, body_len);
|
|
394
317
|
|
|
318
|
+
decompressed = hdr.size - body_len;
|
|
319
|
+
if ((error = git_zstream_get_output(body + body_len, &decompressed, &zstream)) < 0)
|
|
320
|
+
goto done;
|
|
395
321
|
|
|
322
|
+
if (!git_zstream_done(&zstream)) {
|
|
323
|
+
giterr_set(GITERR_ZLIB, "failed to finish zlib inflation: stream aborted prematurely");
|
|
324
|
+
error = -1;
|
|
325
|
+
goto done;
|
|
326
|
+
}
|
|
396
327
|
|
|
328
|
+
body[hdr.size] = '\0';
|
|
397
329
|
|
|
330
|
+
out->data = body;
|
|
331
|
+
out->len = hdr.size;
|
|
332
|
+
out->type = hdr.type;
|
|
398
333
|
|
|
334
|
+
done:
|
|
335
|
+
if (error < 0)
|
|
336
|
+
git__free(body);
|
|
399
337
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
*
|
|
404
|
-
* Backend for the public API; read headers and full objects
|
|
405
|
-
* from the ODB. Write raw data to the ODB.
|
|
406
|
-
*
|
|
407
|
-
***********************************************************/
|
|
338
|
+
git_zstream_free(&zstream);
|
|
339
|
+
return error;
|
|
340
|
+
}
|
|
408
341
|
|
|
409
342
|
static int read_loose(git_rawobj *out, git_buf *loc)
|
|
410
343
|
{
|
|
@@ -420,21 +353,62 @@ static int read_loose(git_rawobj *out, git_buf *loc)
|
|
|
420
353
|
out->len = 0;
|
|
421
354
|
out->type = GIT_OBJ_BAD;
|
|
422
355
|
|
|
423
|
-
if (
|
|
424
|
-
|
|
356
|
+
if ((error = git_futils_readbuffer(&obj, loc->ptr)) < 0)
|
|
357
|
+
goto done;
|
|
425
358
|
|
|
359
|
+
if (!is_zlib_compressed_data((unsigned char *)obj.ptr, obj.size))
|
|
360
|
+
error = read_loose_packlike(out, &obj);
|
|
361
|
+
else
|
|
362
|
+
error = read_loose_standard(out, &obj);
|
|
363
|
+
|
|
364
|
+
done:
|
|
426
365
|
git_buf_free(&obj);
|
|
366
|
+
return error;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
static int read_header_loose_packlike(
|
|
370
|
+
git_rawobj *out, const unsigned char *data, size_t len)
|
|
371
|
+
{
|
|
372
|
+
obj_hdr hdr;
|
|
373
|
+
size_t header_len;
|
|
374
|
+
int error;
|
|
375
|
+
|
|
376
|
+
if ((error = parse_header_packlike(&hdr, &header_len, data, len)) < 0)
|
|
377
|
+
return error;
|
|
378
|
+
|
|
379
|
+
out->len = hdr.size;
|
|
380
|
+
out->type = hdr.type;
|
|
381
|
+
|
|
382
|
+
return error;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
static int read_header_loose_standard(
|
|
386
|
+
git_rawobj *out, const unsigned char *data, size_t len)
|
|
387
|
+
{
|
|
388
|
+
git_zstream zs = GIT_ZSTREAM_INIT;
|
|
389
|
+
obj_hdr hdr;
|
|
390
|
+
unsigned char inflated[MAX_HEADER_LEN];
|
|
391
|
+
size_t header_len, inflated_len = sizeof(inflated);
|
|
392
|
+
int error;
|
|
427
393
|
|
|
394
|
+
if ((error = git_zstream_init(&zs, GIT_ZSTREAM_INFLATE)) < 0 ||
|
|
395
|
+
(error = git_zstream_set_input(&zs, data, len)) < 0 ||
|
|
396
|
+
(error = git_zstream_get_output_chunk(inflated, &inflated_len, &zs)) < 0 ||
|
|
397
|
+
(error = parse_header(&hdr, &header_len, inflated, inflated_len)) < 0)
|
|
398
|
+
goto done;
|
|
399
|
+
|
|
400
|
+
out->len = hdr.size;
|
|
401
|
+
out->type = hdr.type;
|
|
402
|
+
|
|
403
|
+
done:
|
|
404
|
+
git_zstream_free(&zs);
|
|
428
405
|
return error;
|
|
429
406
|
}
|
|
430
407
|
|
|
431
408
|
static int read_header_loose(git_rawobj *out, git_buf *loc)
|
|
432
409
|
{
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
z_stream zs;
|
|
436
|
-
obj_hdr header_obj;
|
|
437
|
-
unsigned char raw_buffer[16], inflated_buffer[64];
|
|
410
|
+
unsigned char obj[1024];
|
|
411
|
+
int fd, obj_len, error;
|
|
438
412
|
|
|
439
413
|
assert(out && loc);
|
|
440
414
|
|
|
@@ -443,35 +417,24 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
|
|
|
443
417
|
|
|
444
418
|
out->data = NULL;
|
|
445
419
|
|
|
446
|
-
if ((fd = git_futils_open_ro(loc->ptr)) < 0
|
|
447
|
-
|
|
420
|
+
if ((error = fd = git_futils_open_ro(loc->ptr)) < 0 ||
|
|
421
|
+
(error = obj_len = p_read(fd, obj, sizeof(obj))) < 0)
|
|
422
|
+
goto done;
|
|
448
423
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
while (z_return == Z_OK) {
|
|
454
|
-
if ((read_bytes = p_read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
|
|
455
|
-
set_stream_input(&zs, raw_buffer, read_bytes);
|
|
456
|
-
z_return = inflate(&zs, 0);
|
|
457
|
-
} else
|
|
458
|
-
z_return = Z_STREAM_END;
|
|
459
|
-
}
|
|
424
|
+
if (!is_zlib_compressed_data(obj, (size_t)obj_len))
|
|
425
|
+
error = read_header_loose_packlike(out, obj, (size_t)obj_len);
|
|
426
|
+
else
|
|
427
|
+
error = read_header_loose_standard(out, obj, (size_t)obj_len);
|
|
460
428
|
|
|
461
|
-
if (
|
|
462
|
-
|| get_object_header(&header_obj, inflated_buffer) == 0
|
|
463
|
-
|| git_object_typeisloose(header_obj.type) == 0)
|
|
464
|
-
{
|
|
429
|
+
if (!error && !git_object_typeisloose(out->type)) {
|
|
465
430
|
giterr_set(GITERR_ZLIB, "failed to read loose object header");
|
|
466
431
|
error = -1;
|
|
467
|
-
|
|
468
|
-
out->len = header_obj.size;
|
|
469
|
-
out->type = header_obj.type;
|
|
432
|
+
goto done;
|
|
470
433
|
}
|
|
471
434
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
435
|
+
done:
|
|
436
|
+
if (fd >= 0)
|
|
437
|
+
p_close(fd);
|
|
475
438
|
return error;
|
|
476
439
|
}
|
|
477
440
|
|
|
@@ -812,7 +775,7 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb
|
|
|
812
775
|
return error;
|
|
813
776
|
}
|
|
814
777
|
|
|
815
|
-
static int
|
|
778
|
+
static int loose_backend__writestream_finalize(git_odb_stream *_stream, const git_oid *oid)
|
|
816
779
|
{
|
|
817
780
|
loose_writestream *stream = (loose_writestream *)_stream;
|
|
818
781
|
loose_backend *backend = (loose_backend *)_stream->backend;
|
|
@@ -831,13 +794,13 @@ static int loose_backend__stream_fwrite(git_odb_stream *_stream, const git_oid *
|
|
|
831
794
|
return error;
|
|
832
795
|
}
|
|
833
796
|
|
|
834
|
-
static int
|
|
797
|
+
static int loose_backend__writestream_write(git_odb_stream *_stream, const char *data, size_t len)
|
|
835
798
|
{
|
|
836
799
|
loose_writestream *stream = (loose_writestream *)_stream;
|
|
837
800
|
return git_filebuf_write(&stream->fbuf, data, len);
|
|
838
801
|
}
|
|
839
802
|
|
|
840
|
-
static void
|
|
803
|
+
static void loose_backend__writestream_free(git_odb_stream *_stream)
|
|
841
804
|
{
|
|
842
805
|
loose_writestream *stream = (loose_writestream *)_stream;
|
|
843
806
|
|
|
@@ -856,29 +819,32 @@ static int filebuf_flags(loose_backend *backend)
|
|
|
856
819
|
return flags;
|
|
857
820
|
}
|
|
858
821
|
|
|
859
|
-
static int
|
|
822
|
+
static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backend *_backend, git_off_t length, git_otype type)
|
|
860
823
|
{
|
|
861
824
|
loose_backend *backend;
|
|
862
825
|
loose_writestream *stream = NULL;
|
|
863
|
-
char hdr[
|
|
826
|
+
char hdr[MAX_HEADER_LEN];
|
|
864
827
|
git_buf tmp_path = GIT_BUF_INIT;
|
|
865
|
-
|
|
828
|
+
size_t hdrlen;
|
|
829
|
+
int error;
|
|
866
830
|
|
|
867
831
|
assert(_backend && length >= 0);
|
|
868
832
|
|
|
869
833
|
backend = (loose_backend *)_backend;
|
|
870
834
|
*stream_out = NULL;
|
|
871
835
|
|
|
872
|
-
|
|
836
|
+
if ((error = git_odb__format_object_header(&hdrlen,
|
|
837
|
+
hdr, sizeof(hdr), length, type)) < 0)
|
|
838
|
+
return error;
|
|
873
839
|
|
|
874
840
|
stream = git__calloc(1, sizeof(loose_writestream));
|
|
875
841
|
GITERR_CHECK_ALLOC(stream);
|
|
876
842
|
|
|
877
843
|
stream->stream.backend = _backend;
|
|
878
844
|
stream->stream.read = NULL; /* read only */
|
|
879
|
-
stream->stream.write = &
|
|
880
|
-
stream->stream.finalize_write = &
|
|
881
|
-
stream->stream.free = &
|
|
845
|
+
stream->stream.write = &loose_backend__writestream_write;
|
|
846
|
+
stream->stream.finalize_write = &loose_backend__writestream_finalize;
|
|
847
|
+
stream->stream.free = &loose_backend__writestream_free;
|
|
882
848
|
stream->stream.mode = GIT_STREAM_WRONLY;
|
|
883
849
|
|
|
884
850
|
if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
|
|
@@ -896,18 +862,198 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
|
|
|
896
862
|
return !stream ? -1 : 0;
|
|
897
863
|
}
|
|
898
864
|
|
|
865
|
+
static int loose_backend__readstream_read(
|
|
866
|
+
git_odb_stream *_stream,
|
|
867
|
+
char *buffer,
|
|
868
|
+
size_t buffer_len)
|
|
869
|
+
{
|
|
870
|
+
loose_readstream *stream = (loose_readstream *)_stream;
|
|
871
|
+
size_t start_remain = stream->start_len - stream->start_read;
|
|
872
|
+
int total = 0, error;
|
|
873
|
+
|
|
874
|
+
/*
|
|
875
|
+
* if we read more than just the header in the initial read, play
|
|
876
|
+
* that back for the caller.
|
|
877
|
+
*/
|
|
878
|
+
if (start_remain && buffer_len) {
|
|
879
|
+
size_t chunk = min(start_remain, buffer_len);
|
|
880
|
+
memcpy(buffer, stream->start + stream->start_read, chunk);
|
|
881
|
+
|
|
882
|
+
buffer += chunk;
|
|
883
|
+
stream->start_read += chunk;
|
|
884
|
+
|
|
885
|
+
total += chunk;
|
|
886
|
+
buffer_len -= chunk;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
if (buffer_len) {
|
|
890
|
+
size_t chunk = min(buffer_len, INT_MAX);
|
|
891
|
+
|
|
892
|
+
if ((error = git_zstream_get_output(buffer, &chunk, &stream->zstream)) < 0)
|
|
893
|
+
return error;
|
|
894
|
+
|
|
895
|
+
total += chunk;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
return total;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
static void loose_backend__readstream_free(git_odb_stream *_stream)
|
|
902
|
+
{
|
|
903
|
+
loose_readstream *stream = (loose_readstream *)_stream;
|
|
904
|
+
|
|
905
|
+
git_futils_mmap_free(&stream->map);
|
|
906
|
+
git_zstream_free(&stream->zstream);
|
|
907
|
+
git__free(stream);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
static int loose_backend__readstream_packlike(
|
|
911
|
+
obj_hdr *hdr,
|
|
912
|
+
loose_readstream *stream)
|
|
913
|
+
{
|
|
914
|
+
const unsigned char *data;
|
|
915
|
+
size_t data_len, head_len;
|
|
916
|
+
int error;
|
|
917
|
+
|
|
918
|
+
data = stream->map.data;
|
|
919
|
+
data_len = stream->map.len;
|
|
920
|
+
|
|
921
|
+
/*
|
|
922
|
+
* read the object header, which is an (uncompressed)
|
|
923
|
+
* binary encoding of the object type and size.
|
|
924
|
+
*/
|
|
925
|
+
if ((error = parse_header_packlike(hdr, &head_len, data, data_len)) < 0)
|
|
926
|
+
return error;
|
|
927
|
+
|
|
928
|
+
if (!git_object_typeisloose(hdr->type)) {
|
|
929
|
+
giterr_set(GITERR_ODB, "failed to inflate loose object");
|
|
930
|
+
return -1;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
return git_zstream_set_input(&stream->zstream,
|
|
934
|
+
data + head_len, data_len - head_len);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
static int loose_backend__readstream_standard(
|
|
938
|
+
obj_hdr *hdr,
|
|
939
|
+
loose_readstream *stream)
|
|
940
|
+
{
|
|
941
|
+
unsigned char head[MAX_HEADER_LEN];
|
|
942
|
+
size_t init, head_len;
|
|
943
|
+
int error;
|
|
944
|
+
|
|
945
|
+
if ((error = git_zstream_set_input(&stream->zstream,
|
|
946
|
+
stream->map.data, stream->map.len)) < 0)
|
|
947
|
+
return error;
|
|
948
|
+
|
|
949
|
+
init = sizeof(head);
|
|
950
|
+
|
|
951
|
+
/*
|
|
952
|
+
* inflate the initial part of the compressed buffer in order to
|
|
953
|
+
* parse the header; read the largest header possible, then store
|
|
954
|
+
* it in the `start` field of the stream object.
|
|
955
|
+
*/
|
|
956
|
+
if ((error = git_zstream_get_output(head, &init, &stream->zstream)) < 0 ||
|
|
957
|
+
(error = parse_header(hdr, &head_len, head, init)) < 0)
|
|
958
|
+
return error;
|
|
959
|
+
|
|
960
|
+
if (!git_object_typeisloose(hdr->type)) {
|
|
961
|
+
giterr_set(GITERR_ODB, "failed to inflate disk object");
|
|
962
|
+
return -1;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
if (init > head_len) {
|
|
966
|
+
stream->start_len = init - head_len;
|
|
967
|
+
memcpy(stream->start, head + head_len, init - head_len);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return 0;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
static int loose_backend__readstream(
|
|
974
|
+
git_odb_stream **stream_out,
|
|
975
|
+
size_t *len_out,
|
|
976
|
+
git_otype *type_out,
|
|
977
|
+
git_odb_backend *_backend,
|
|
978
|
+
const git_oid *oid)
|
|
979
|
+
{
|
|
980
|
+
loose_backend *backend;
|
|
981
|
+
loose_readstream *stream = NULL;
|
|
982
|
+
git_hash_ctx *hash_ctx = NULL;
|
|
983
|
+
git_buf object_path = GIT_BUF_INIT;
|
|
984
|
+
obj_hdr hdr;
|
|
985
|
+
int error = 0;
|
|
986
|
+
|
|
987
|
+
assert(stream_out && len_out && type_out && _backend && oid);
|
|
988
|
+
|
|
989
|
+
backend = (loose_backend *)_backend;
|
|
990
|
+
*stream_out = NULL;
|
|
991
|
+
*len_out = 0;
|
|
992
|
+
*type_out = GIT_OBJ_BAD;
|
|
993
|
+
|
|
994
|
+
if (locate_object(&object_path, backend, oid) < 0) {
|
|
995
|
+
error = git_odb__error_notfound("no matching loose object",
|
|
996
|
+
oid, GIT_OID_HEXSZ);
|
|
997
|
+
goto done;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
stream = git__calloc(1, sizeof(loose_readstream));
|
|
1001
|
+
GITERR_CHECK_ALLOC(stream);
|
|
1002
|
+
|
|
1003
|
+
hash_ctx = git__malloc(sizeof(git_hash_ctx));
|
|
1004
|
+
GITERR_CHECK_ALLOC(hash_ctx);
|
|
1005
|
+
|
|
1006
|
+
if ((error = git_hash_ctx_init(hash_ctx)) < 0 ||
|
|
1007
|
+
(error = git_futils_mmap_ro_file(&stream->map, object_path.ptr)) < 0 ||
|
|
1008
|
+
(error = git_zstream_init(&stream->zstream, GIT_ZSTREAM_INFLATE)) < 0)
|
|
1009
|
+
goto done;
|
|
1010
|
+
|
|
1011
|
+
/* check for a packlike loose object */
|
|
1012
|
+
if (!is_zlib_compressed_data(stream->map.data, stream->map.len))
|
|
1013
|
+
error = loose_backend__readstream_packlike(&hdr, stream);
|
|
1014
|
+
else
|
|
1015
|
+
error = loose_backend__readstream_standard(&hdr, stream);
|
|
1016
|
+
|
|
1017
|
+
if (error < 0)
|
|
1018
|
+
goto done;
|
|
1019
|
+
|
|
1020
|
+
stream->stream.backend = _backend;
|
|
1021
|
+
stream->stream.hash_ctx = hash_ctx;
|
|
1022
|
+
stream->stream.read = &loose_backend__readstream_read;
|
|
1023
|
+
stream->stream.free = &loose_backend__readstream_free;
|
|
1024
|
+
|
|
1025
|
+
*stream_out = (git_odb_stream *)stream;
|
|
1026
|
+
*len_out = hdr.size;
|
|
1027
|
+
*type_out = hdr.type;
|
|
1028
|
+
|
|
1029
|
+
done:
|
|
1030
|
+
if (error < 0) {
|
|
1031
|
+
git_futils_mmap_free(&stream->map);
|
|
1032
|
+
git_zstream_free(&stream->zstream);
|
|
1033
|
+
git_hash_ctx_cleanup(hash_ctx);
|
|
1034
|
+
git__free(hash_ctx);
|
|
1035
|
+
git__free(stream);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
git_buf_free(&object_path);
|
|
1039
|
+
return error;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
899
1042
|
static int loose_backend__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
|
|
900
1043
|
{
|
|
901
|
-
int error = 0
|
|
1044
|
+
int error = 0;
|
|
902
1045
|
git_buf final_path = GIT_BUF_INIT;
|
|
903
|
-
char header[
|
|
1046
|
+
char header[MAX_HEADER_LEN];
|
|
1047
|
+
size_t header_len;
|
|
904
1048
|
git_filebuf fbuf = GIT_FILEBUF_INIT;
|
|
905
1049
|
loose_backend *backend;
|
|
906
1050
|
|
|
907
1051
|
backend = (loose_backend *)_backend;
|
|
908
1052
|
|
|
909
1053
|
/* prepare the header for the file */
|
|
910
|
-
|
|
1054
|
+
if ((error = git_odb__format_object_header(&header_len,
|
|
1055
|
+
header, sizeof(header), len, type)) < 0)
|
|
1056
|
+
goto cleanup;
|
|
911
1057
|
|
|
912
1058
|
if (git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
|
|
913
1059
|
git_filebuf_open(&fbuf, final_path.ptr, filebuf_flags(backend),
|
|
@@ -1002,7 +1148,8 @@ int git_odb_backend_loose(
|
|
|
1002
1148
|
backend->parent.write = &loose_backend__write;
|
|
1003
1149
|
backend->parent.read_prefix = &loose_backend__read_prefix;
|
|
1004
1150
|
backend->parent.read_header = &loose_backend__read_header;
|
|
1005
|
-
backend->parent.writestream = &
|
|
1151
|
+
backend->parent.writestream = &loose_backend__writestream;
|
|
1152
|
+
backend->parent.readstream = &loose_backend__readstream;
|
|
1006
1153
|
backend->parent.exists = &loose_backend__exists;
|
|
1007
1154
|
backend->parent.exists_prefix = &loose_backend__exists_prefix;
|
|
1008
1155
|
backend->parent.foreach = &loose_backend__foreach;
|