Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
028a2806
Unverified
Commit
028a2806
authored
Feb 09, 2018
by
Edward Thomson
Committed by
GitHub
Feb 09, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4509 from libgit2/ethomson/odb_alloc_error
odb: error when we can't alloc an object
parents
0fd0bfe4
9985edb5
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
126 additions
and
53 deletions
+126
-53
src/hash/hash_win32.c
+33
-8
src/indexer.c
+11
-4
src/odb.c
+68
-33
src/odb.h
+1
-1
src/odb_loose.c
+10
-4
tests/odb/largefiles.c
+3
-3
No files found.
src/hash/hash_win32.c
View file @
028a2806
...
@@ -24,16 +24,20 @@ GIT_INLINE(int) hash_cng_prov_init(void)
...
@@ -24,16 +24,20 @@ GIT_INLINE(int) hash_cng_prov_init(void)
DWORD
dll_path_len
,
size_len
;
DWORD
dll_path_len
,
size_len
;
/* Only use CNG on Windows 2008 / Vista SP1 or better (Windows 6.0 SP1) */
/* Only use CNG on Windows 2008 / Vista SP1 or better (Windows 6.0 SP1) */
if
(
!
git_has_win32_version
(
6
,
0
,
1
))
if
(
!
git_has_win32_version
(
6
,
0
,
1
))
{
giterr_set
(
GITERR_SHA1
,
"CryptoNG is not supported on this platform"
);
return
-
1
;
return
-
1
;
}
/* Load bcrypt.dll explicitly from the system directory */
/* Load bcrypt.dll explicitly from the system directory */
if
((
dll_path_len
=
GetSystemDirectory
(
dll_path
,
MAX_PATH
))
==
0
||
if
((
dll_path_len
=
GetSystemDirectory
(
dll_path
,
MAX_PATH
))
==
0
||
dll_path_len
>
MAX_PATH
||
dll_path_len
>
MAX_PATH
||
StringCchCat
(
dll_path
,
MAX_PATH
,
"
\\
"
)
<
0
||
StringCchCat
(
dll_path
,
MAX_PATH
,
"
\\
"
)
<
0
||
StringCchCat
(
dll_path
,
MAX_PATH
,
GIT_HASH_CNG_DLL_NAME
)
<
0
||
StringCchCat
(
dll_path
,
MAX_PATH
,
GIT_HASH_CNG_DLL_NAME
)
<
0
||
(
hash_prov
.
prov
.
cng
.
dll
=
LoadLibrary
(
dll_path
))
==
NULL
)
(
hash_prov
.
prov
.
cng
.
dll
=
LoadLibrary
(
dll_path
))
==
NULL
)
{
giterr_set
(
GITERR_SHA1
,
"CryptoNG library could not be loaded"
);
return
-
1
;
return
-
1
;
}
/* Load the function addresses */
/* Load the function addresses */
if
((
hash_prov
.
prov
.
cng
.
open_algorithm_provider
=
(
hash_win32_cng_open_algorithm_provider_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptOpenAlgorithmProvider"
))
==
NULL
||
if
((
hash_prov
.
prov
.
cng
.
open_algorithm_provider
=
(
hash_win32_cng_open_algorithm_provider_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptOpenAlgorithmProvider"
))
==
NULL
||
...
@@ -44,12 +48,16 @@ GIT_INLINE(int) hash_cng_prov_init(void)
...
@@ -44,12 +48,16 @@ GIT_INLINE(int) hash_cng_prov_init(void)
(
hash_prov
.
prov
.
cng
.
destroy_hash
=
(
hash_win32_cng_destroy_hash_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptDestroyHash"
))
==
NULL
||
(
hash_prov
.
prov
.
cng
.
destroy_hash
=
(
hash_win32_cng_destroy_hash_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptDestroyHash"
))
==
NULL
||
(
hash_prov
.
prov
.
cng
.
close_algorithm_provider
=
(
hash_win32_cng_close_algorithm_provider_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptCloseAlgorithmProvider"
))
==
NULL
)
{
(
hash_prov
.
prov
.
cng
.
close_algorithm_provider
=
(
hash_win32_cng_close_algorithm_provider_fn
)
GetProcAddress
(
hash_prov
.
prov
.
cng
.
dll
,
"BCryptCloseAlgorithmProvider"
))
==
NULL
)
{
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
giterr_set
(
GITERR_OS
,
"CryptoNG functions could not be loaded"
);
return
-
1
;
return
-
1
;
}
}
/* Load the SHA1 algorithm */
/* Load the SHA1 algorithm */
if
(
hash_prov
.
prov
.
cng
.
open_algorithm_provider
(
&
hash_prov
.
prov
.
cng
.
handle
,
GIT_HASH_CNG_HASH_TYPE
,
NULL
,
GIT_HASH_CNG_HASH_REUSABLE
)
<
0
)
{
if
(
hash_prov
.
prov
.
cng
.
open_algorithm_provider
(
&
hash_prov
.
prov
.
cng
.
handle
,
GIT_HASH_CNG_HASH_TYPE
,
NULL
,
GIT_HASH_CNG_HASH_REUSABLE
)
<
0
)
{
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
giterr_set
(
GITERR_OS
"algorithm provider could not be initialized"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -57,6 +65,8 @@ GIT_INLINE(int) hash_cng_prov_init(void)
...
@@ -57,6 +65,8 @@ GIT_INLINE(int) hash_cng_prov_init(void)
if
(
hash_prov
.
prov
.
cng
.
get_property
(
hash_prov
.
prov
.
cng
.
handle
,
GIT_HASH_CNG_HASH_OBJECT_LEN
,
(
PBYTE
)
&
hash_prov
.
prov
.
cng
.
hash_object_size
,
sizeof
(
DWORD
),
&
size_len
,
0
)
<
0
)
{
if
(
hash_prov
.
prov
.
cng
.
get_property
(
hash_prov
.
prov
.
cng
.
handle
,
GIT_HASH_CNG_HASH_OBJECT_LEN
,
(
PBYTE
)
&
hash_prov
.
prov
.
cng
.
hash_object_size
,
sizeof
(
DWORD
),
&
size_len
,
0
)
<
0
)
{
hash_prov
.
prov
.
cng
.
close_algorithm_provider
(
hash_prov
.
prov
.
cng
.
handle
,
0
);
hash_prov
.
prov
.
cng
.
close_algorithm_provider
(
hash_prov
.
prov
.
cng
.
handle
,
0
);
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
FreeLibrary
(
hash_prov
.
prov
.
cng
.
dll
);
giterr_set
(
GITERR_OS
,
"algorithm handle could not be found"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -75,8 +85,10 @@ GIT_INLINE(void) hash_cng_prov_shutdown(void)
...
@@ -75,8 +85,10 @@ GIT_INLINE(void) hash_cng_prov_shutdown(void)
/* Initialize CryptoAPI */
/* Initialize CryptoAPI */
GIT_INLINE
(
int
)
hash_cryptoapi_prov_init
()
GIT_INLINE
(
int
)
hash_cryptoapi_prov_init
()
{
{
if
(
!
CryptAcquireContext
(
&
hash_prov
.
prov
.
cryptoapi
.
handle
,
NULL
,
0
,
PROV_RSA_FULL
,
CRYPT_VERIFYCONTEXT
))
if
(
!
CryptAcquireContext
(
&
hash_prov
.
prov
.
cryptoapi
.
handle
,
NULL
,
0
,
PROV_RSA_FULL
,
CRYPT_VERIFYCONTEXT
))
{
giterr_set
(
GITERR_OS
,
"legacy hash context could not be started"
);
return
-
1
;
return
-
1
;
}
hash_prov
.
type
=
CRYPTOAPI
;
hash_prov
.
type
=
CRYPTOAPI
;
return
0
;
return
0
;
...
@@ -129,6 +141,7 @@ GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx)
...
@@ -129,6 +141,7 @@ GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx)
if
(
!
CryptCreateHash
(
ctx
->
prov
->
prov
.
cryptoapi
.
handle
,
CALG_SHA1
,
0
,
0
,
&
ctx
->
ctx
.
cryptoapi
.
hash_handle
))
{
if
(
!
CryptCreateHash
(
ctx
->
prov
->
prov
.
cryptoapi
.
handle
,
CALG_SHA1
,
0
,
0
,
&
ctx
->
ctx
.
cryptoapi
.
hash_handle
))
{
ctx
->
ctx
.
cryptoapi
.
valid
=
0
;
ctx
->
ctx
.
cryptoapi
.
valid
=
0
;
giterr_set
(
GITERR_OS
,
"legacy hash implementation could not be created"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -145,8 +158,10 @@ GIT_INLINE(int) hash_cryptoapi_update(git_hash_ctx *ctx, const void *_data, size
...
@@ -145,8 +158,10 @@ GIT_INLINE(int) hash_cryptoapi_update(git_hash_ctx *ctx, const void *_data, size
while
(
len
>
0
)
{
while
(
len
>
0
)
{
DWORD
chunk
=
(
len
>
MAXDWORD
)
?
MAXDWORD
:
(
DWORD
)
len
;
DWORD
chunk
=
(
len
>
MAXDWORD
)
?
MAXDWORD
:
(
DWORD
)
len
;
if
(
!
CryptHashData
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
,
data
,
chunk
,
0
))
if
(
!
CryptHashData
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
,
data
,
chunk
,
0
))
{
giterr_set
(
GITERR_OS
,
"legacy hash data could not be updated"
);
return
-
1
;
return
-
1
;
}
data
+=
chunk
;
data
+=
chunk
;
len
-=
chunk
;
len
-=
chunk
;
...
@@ -162,8 +177,10 @@ GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx)
...
@@ -162,8 +177,10 @@ GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx)
assert
(
ctx
->
ctx
.
cryptoapi
.
valid
);
assert
(
ctx
->
ctx
.
cryptoapi
.
valid
);
if
(
!
CryptGetHashParam
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
,
HP_HASHVAL
,
out
->
id
,
&
len
,
0
))
if
(
!
CryptGetHashParam
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
,
HP_HASHVAL
,
out
->
id
,
&
len
,
0
))
{
giterr_set
(
GITERR_OS
,
"legacy hash data could not be finished"
);
error
=
-
1
;
error
=
-
1
;
}
CryptDestroyHash
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
);
CryptDestroyHash
(
ctx
->
ctx
.
cryptoapi
.
hash_handle
);
ctx
->
ctx
.
cryptoapi
.
valid
=
0
;
ctx
->
ctx
.
cryptoapi
.
valid
=
0
;
...
@@ -186,6 +203,8 @@ GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx)
...
@@ -186,6 +203,8 @@ GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx)
if
(
hash_prov
.
prov
.
cng
.
create_hash
(
hash_prov
.
prov
.
cng
.
handle
,
&
ctx
->
ctx
.
cng
.
hash_handle
,
ctx
->
ctx
.
cng
.
hash_object
,
hash_prov
.
prov
.
cng
.
hash_object_size
,
NULL
,
0
,
0
)
<
0
)
{
if
(
hash_prov
.
prov
.
cng
.
create_hash
(
hash_prov
.
prov
.
cng
.
handle
,
&
ctx
->
ctx
.
cng
.
hash_handle
,
ctx
->
ctx
.
cng
.
hash_object
,
hash_prov
.
prov
.
cng
.
hash_object_size
,
NULL
,
0
,
0
)
<
0
)
{
git__free
(
ctx
->
ctx
.
cng
.
hash_object
);
git__free
(
ctx
->
ctx
.
cng
.
hash_object
);
giterr_set
(
GITERR_OS
,
"hash implementation could not be created"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -203,8 +222,10 @@ GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx)
...
@@ -203,8 +222,10 @@ GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx)
return
0
;
return
0
;
/* CNG needs to be finished to restart */
/* CNG needs to be finished to restart */
if
(
ctx
->
prov
->
prov
.
cng
.
finish_hash
(
ctx
->
ctx
.
cng
.
hash_handle
,
hash
,
GIT_OID_RAWSZ
,
0
)
<
0
)
if
(
ctx
->
prov
->
prov
.
cng
.
finish_hash
(
ctx
->
ctx
.
cng
.
hash_handle
,
hash
,
GIT_OID_RAWSZ
,
0
)
<
0
)
{
giterr_set
(
GITERR_OS
,
"hash implementation could not be finished"
);
return
-
1
;
return
-
1
;
}
ctx
->
ctx
.
cng
.
updated
=
0
;
ctx
->
ctx
.
cng
.
updated
=
0
;
...
@@ -218,8 +239,10 @@ GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len
...
@@ -218,8 +239,10 @@ GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len
while
(
len
>
0
)
{
while
(
len
>
0
)
{
ULONG
chunk
=
(
len
>
ULONG_MAX
)
?
ULONG_MAX
:
(
ULONG
)
len
;
ULONG
chunk
=
(
len
>
ULONG_MAX
)
?
ULONG_MAX
:
(
ULONG
)
len
;
if
(
ctx
->
prov
->
prov
.
cng
.
hash_data
(
ctx
->
ctx
.
cng
.
hash_handle
,
data
,
chunk
,
0
)
<
0
)
if
(
ctx
->
prov
->
prov
.
cng
.
hash_data
(
ctx
->
ctx
.
cng
.
hash_handle
,
data
,
chunk
,
0
)
<
0
)
{
giterr_set
(
GITERR_OS
,
"hash could not be updated"
);
return
-
1
;
return
-
1
;
}
data
+=
chunk
;
data
+=
chunk
;
len
-=
chunk
;
len
-=
chunk
;
...
@@ -230,8 +253,10 @@ GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len
...
@@ -230,8 +253,10 @@ GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len
GIT_INLINE
(
int
)
hash_cng_final
(
git_oid
*
out
,
git_hash_ctx
*
ctx
)
GIT_INLINE
(
int
)
hash_cng_final
(
git_oid
*
out
,
git_hash_ctx
*
ctx
)
{
{
if
(
ctx
->
prov
->
prov
.
cng
.
finish_hash
(
ctx
->
ctx
.
cng
.
hash_handle
,
out
->
id
,
GIT_OID_RAWSZ
,
0
)
<
0
)
if
(
ctx
->
prov
->
prov
.
cng
.
finish_hash
(
ctx
->
ctx
.
cng
.
hash_handle
,
out
->
id
,
GIT_OID_RAWSZ
,
0
)
<
0
)
{
giterr_set
(
GITERR_OS
,
"hash could not be finished"
);
return
-
1
;
return
-
1
;
}
ctx
->
ctx
.
cng
.
updated
=
0
;
ctx
->
ctx
.
cng
.
updated
=
0
;
...
...
src/indexer.c
View file @
028a2806
...
@@ -187,13 +187,17 @@ static int store_delta(git_indexer *idx)
...
@@ -187,13 +187,17 @@ static int store_delta(git_indexer *idx)
return
0
;
return
0
;
}
}
static
void
hash_header
(
git_hash_ctx
*
ctx
,
git_off_t
len
,
git_otype
type
)
static
int
hash_header
(
git_hash_ctx
*
ctx
,
git_off_t
len
,
git_otype
type
)
{
{
char
buffer
[
64
];
char
buffer
[
64
];
size_t
hdrlen
;
size_t
hdrlen
;
int
error
;
if
((
error
=
git_odb__format_object_header
(
&
hdrlen
,
buffer
,
sizeof
(
buffer
),
(
size_t
)
len
,
type
))
<
0
)
return
error
;
hdrlen
=
git_odb__format_object_header
(
buffer
,
sizeof
(
buffer
),
(
size_t
)
len
,
type
);
return
git_hash_update
(
ctx
,
buffer
,
hdrlen
);
git_hash_update
(
ctx
,
buffer
,
hdrlen
);
}
}
static
int
hash_object_stream
(
git_indexer
*
idx
,
git_packfile_stream
*
stream
)
static
int
hash_object_stream
(
git_indexer
*
idx
,
git_packfile_stream
*
stream
)
...
@@ -621,7 +625,10 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
...
@@ -621,7 +625,10 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
idx
->
have_delta
=
1
;
idx
->
have_delta
=
1
;
}
else
{
}
else
{
idx
->
have_delta
=
0
;
idx
->
have_delta
=
0
;
hash_header
(
&
idx
->
hash_ctx
,
entry_size
,
type
);
error
=
hash_header
(
&
idx
->
hash_ctx
,
entry_size
,
type
);
if
(
error
<
0
)
goto
on_error
;
}
}
idx
->
have_stream
=
1
;
idx
->
have_stream
=
1
;
...
...
src/odb.c
View file @
028a2806
...
@@ -66,50 +66,75 @@ static git_otype odb_hardcoded_type(const git_oid *id)
...
@@ -66,50 +66,75 @@ static git_otype odb_hardcoded_type(const git_oid *id)
return
GIT_OBJ_BAD
;
return
GIT_OBJ_BAD
;
}
}
static
int
odb_read_hardcoded
(
git_rawobj
*
raw
,
const
git_oid
*
id
)
static
int
odb_read_hardcoded
(
bool
*
found
,
git_rawobj
*
raw
,
const
git_oid
*
id
)
{
{
git_otype
type
=
odb_hardcoded_type
(
id
);
git_otype
type
;
if
(
type
==
GIT_OBJ_BAD
)
return
-
1
;
*
found
=
false
;
if
((
type
=
odb_hardcoded_type
(
id
))
==
GIT_OBJ_BAD
)
return
0
;
raw
->
type
=
type
;
raw
->
type
=
type
;
raw
->
len
=
0
;
raw
->
len
=
0
;
raw
->
data
=
git__calloc
(
1
,
sizeof
(
uint8_t
));
raw
->
data
=
git__calloc
(
1
,
sizeof
(
uint8_t
));
GITERR_CHECK_ALLOC
(
raw
->
data
);
*
found
=
true
;
return
0
;
return
0
;
}
}
int
git_odb__format_object_header
(
char
*
hdr
,
size_t
n
,
git_off_t
obj_len
,
git_otype
obj_type
)
int
git_odb__format_object_header
(
size_t
*
written
,
char
*
hdr
,
size_t
hdr_size
,
git_off_t
obj_len
,
git_otype
obj_type
)
{
{
const
char
*
type_str
=
git_object_type2string
(
obj_type
);
const
char
*
type_str
=
git_object_type2string
(
obj_type
);
int
len
=
p_snprintf
(
hdr
,
n
,
"%s %lld"
,
type_str
,
(
long
long
)
obj_len
);
int
hdr_max
=
(
hdr_size
>
INT_MAX
-
2
)
?
(
INT_MAX
-
2
)
:
(
int
)
hdr_size
;
assert
(
len
>
0
&&
len
<=
(
int
)
n
);
int
len
;
return
len
+
1
;
len
=
p_snprintf
(
hdr
,
hdr_max
,
"%s %lld"
,
type_str
,
(
long
long
)
obj_len
);
if
(
len
<
0
||
len
>=
hdr_max
)
{
giterr_set
(
GITERR_OS
,
"object header creation failed"
);
return
-
1
;
}
*
written
=
(
size_t
)(
len
+
1
);
return
0
;
}
}
int
git_odb__hashobj
(
git_oid
*
id
,
git_rawobj
*
obj
)
int
git_odb__hashobj
(
git_oid
*
id
,
git_rawobj
*
obj
)
{
{
git_buf_vec
vec
[
2
];
git_buf_vec
vec
[
2
];
char
header
[
64
];
char
header
[
64
];
int
hdrlen
;
size_t
hdrlen
;
int
error
;
assert
(
id
&&
obj
);
assert
(
id
&&
obj
);
if
(
!
git_object_typeisloose
(
obj
->
type
))
if
(
!
git_object_typeisloose
(
obj
->
type
))
{
giterr_set
(
GITERR_INVALID
,
"invalid object type"
);
return
-
1
;
return
-
1
;
}
if
(
!
obj
->
data
&&
obj
->
len
!=
0
)
if
(
!
obj
->
data
&&
obj
->
len
!=
0
)
{
giterr_set
(
GITERR_INVALID
,
"invalid object"
);
return
-
1
;
return
-
1
;
}
hdrlen
=
git_odb__format_object_header
(
header
,
sizeof
(
header
),
obj
->
len
,
obj
->
type
);
if
((
error
=
git_odb__format_object_header
(
&
hdrlen
,
header
,
sizeof
(
header
),
obj
->
len
,
obj
->
type
))
<
0
)
return
error
;
vec
[
0
].
data
=
header
;
vec
[
0
].
data
=
header
;
vec
[
0
].
len
=
hdrlen
;
vec
[
0
].
len
=
hdrlen
;
vec
[
1
].
data
=
obj
->
data
;
vec
[
1
].
data
=
obj
->
data
;
vec
[
1
].
len
=
obj
->
len
;
vec
[
1
].
len
=
obj
->
len
;
git_hash_vec
(
id
,
vec
,
2
);
return
git_hash_vec
(
id
,
vec
,
2
);
return
0
;
}
}
...
@@ -172,7 +197,7 @@ void git_odb_object_free(git_odb_object *object)
...
@@ -172,7 +197,7 @@ void git_odb_object_free(git_odb_object *object)
int
git_odb__hashfd
(
git_oid
*
out
,
git_file
fd
,
size_t
size
,
git_otype
type
)
int
git_odb__hashfd
(
git_oid
*
out
,
git_file
fd
,
size_t
size
,
git_otype
type
)
{
{
in
t
hdr_len
;
size_
t
hdr_len
;
char
hdr
[
64
],
buffer
[
FILEIO_BUFSIZE
];
char
hdr
[
64
],
buffer
[
FILEIO_BUFSIZE
];
git_hash_ctx
ctx
;
git_hash_ctx
ctx
;
ssize_t
read_len
=
0
;
ssize_t
read_len
=
0
;
...
@@ -184,9 +209,11 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
...
@@ -184,9 +209,11 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type)
}
}
if
((
error
=
git_hash_ctx_init
(
&
ctx
))
<
0
)
if
((
error
=
git_hash_ctx_init
(
&
ctx
))
<
0
)
return
-
1
;
return
error
;
hdr_len
=
git_odb__format_object_header
(
hdr
,
sizeof
(
hdr
),
size
,
type
);
if
((
error
=
git_odb__format_object_header
(
&
hdr_len
,
hdr
,
sizeof
(
hdr
),
size
,
type
))
<
0
)
goto
done
;
if
((
error
=
git_hash_update
(
&
ctx
,
hdr
,
hdr_len
))
<
0
)
if
((
error
=
git_hash_update
(
&
ctx
,
hdr
,
hdr_len
))
<
0
)
goto
done
;
goto
done
;
...
@@ -342,8 +369,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t
...
@@ -342,8 +369,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t
{
{
fake_wstream
*
stream
=
(
fake_wstream
*
)
_stream
;
fake_wstream
*
stream
=
(
fake_wstream
*
)
_stream
;
if
(
stream
->
written
+
len
>
stream
->
size
)
assert
(
stream
->
written
+
len
>
stream
->
size
);
return
-
1
;
memcpy
(
stream
->
buffer
+
stream
->
written
,
data
,
len
);
memcpy
(
stream
->
buffer
+
stream
->
written
,
data
,
len
);
stream
->
written
+=
len
;
stream
->
written
+=
len
;
...
@@ -800,7 +826,7 @@ int git_odb_exists_prefix(
...
@@ -800,7 +826,7 @@ int git_odb_exists_prefix(
git_oid
*
out
,
git_odb
*
db
,
const
git_oid
*
short_id
,
size_t
len
)
git_oid
*
out
,
git_odb
*
db
,
const
git_oid
*
short_id
,
size_t
len
)
{
{
int
error
;
int
error
;
git_oid
key
=
{{
0
}};
git_oid
key
=
{{
0
}};
assert
(
db
&&
short_id
);
assert
(
db
&&
short_id
);
...
@@ -1012,8 +1038,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
...
@@ -1012,8 +1038,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
bool
found
=
false
;
bool
found
=
false
;
int
error
=
0
;
int
error
=
0
;
if
(
!
only_refreshed
&&
odb_read_hardcoded
(
&
raw
,
id
)
==
0
)
if
(
!
only_refreshed
)
{
found
=
true
;
if
((
error
=
odb_read_hardcoded
(
&
found
,
&
raw
,
id
))
<
0
)
return
error
;
}
for
(
i
=
0
;
i
<
db
->
backends
.
length
&&
!
found
;
++
i
)
{
for
(
i
=
0
;
i
<
db
->
backends
.
length
&&
!
found
;
++
i
)
{
backend_internal
*
internal
=
git_vector_get
(
&
db
->
backends
,
i
);
backend_internal
*
internal
=
git_vector_get
(
&
db
->
backends
,
i
);
...
@@ -1048,8 +1076,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
...
@@ -1048,8 +1076,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
}
}
giterr_clear
();
giterr_clear
();
if
((
object
=
odb_object__alloc
(
id
,
&
raw
))
==
NULL
)
if
((
object
=
odb_object__alloc
(
id
,
&
raw
))
==
NULL
)
{
error
=
-
1
;
goto
out
;
goto
out
;
}
*
out
=
git_cache_store_raw
(
odb_cache
(
db
),
object
);
*
out
=
git_cache_store_raw
(
odb_cache
(
db
),
object
);
...
@@ -1096,7 +1126,7 @@ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id)
...
@@ -1096,7 +1126,7 @@ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id)
*
type_p
=
object
->
cached
.
type
;
*
type_p
=
object
->
cached
.
type
;
return
0
;
return
0
;
}
}
error
=
odb_read_header_1
(
&
_unused
,
type_p
,
db
,
id
,
false
);
error
=
odb_read_header_1
(
&
_unused
,
type_p
,
db
,
id
,
false
);
if
(
error
==
GIT_PASSTHROUGH
)
{
if
(
error
==
GIT_PASSTHROUGH
)
{
...
@@ -1175,8 +1205,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
...
@@ -1175,8 +1205,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
}
}
}
}
if
((
object
=
odb_object__alloc
(
&
found_full_oid
,
&
raw
))
==
NULL
)
if
((
object
=
odb_object__alloc
(
&
found_full_oid
,
&
raw
))
==
NULL
)
{
error
=
-
1
;
goto
out
;
goto
out
;
}
*
out
=
git_cache_store_raw
(
odb_cache
(
db
),
object
);
*
out
=
git_cache_store_raw
(
odb_cache
(
db
),
object
);
...
@@ -1281,13 +1313,17 @@ int git_odb_write(
...
@@ -1281,13 +1313,17 @@ int git_odb_write(
return
error
;
return
error
;
}
}
static
void
hash_header
(
git_hash_ctx
*
ctx
,
git_off_t
size
,
git_otype
type
)
static
int
hash_header
(
git_hash_ctx
*
ctx
,
git_off_t
size
,
git_otype
type
)
{
{
char
header
[
64
];
char
header
[
64
];
int
hdrlen
;
size_t
hdrlen
;
int
error
;
if
((
error
=
git_odb__format_object_header
(
&
hdrlen
,
header
,
sizeof
(
header
),
size
,
type
))
<
0
)
return
error
;
hdrlen
=
git_odb__format_object_header
(
header
,
sizeof
(
header
),
size
,
type
);
return
git_hash_update
(
ctx
,
header
,
hdrlen
);
git_hash_update
(
ctx
,
header
,
hdrlen
);
}
}
int
git_odb_open_wstream
(
int
git_odb_open_wstream
(
...
@@ -1328,12 +1364,11 @@ int git_odb_open_wstream(
...
@@ -1328,12 +1364,11 @@ int git_odb_open_wstream(
ctx
=
git__malloc
(
sizeof
(
git_hash_ctx
));
ctx
=
git__malloc
(
sizeof
(
git_hash_ctx
));
GITERR_CHECK_ALLOC
(
ctx
);
GITERR_CHECK_ALLOC
(
ctx
);
if
((
error
=
git_hash_ctx_init
(
ctx
))
<
0
)
if
((
error
=
git_hash_ctx_init
(
ctx
))
<
0
||
(
error
=
hash_header
(
ctx
,
size
,
type
))
<
0
)
goto
done
;
goto
done
;
hash_header
(
ctx
,
size
,
type
);
(
*
stream
)
->
hash_ctx
=
ctx
;
(
*
stream
)
->
hash_ctx
=
ctx
;
(
*
stream
)
->
declared_size
=
size
;
(
*
stream
)
->
declared_size
=
size
;
(
*
stream
)
->
received_bytes
=
0
;
(
*
stream
)
->
received_bytes
=
0
;
...
...
src/odb.h
View file @
028a2806
...
@@ -70,7 +70,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj);
...
@@ -70,7 +70,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj);
/*
/*
* Format the object header such as it would appear in the on-disk object
* Format the object header such as it would appear in the on-disk object
*/
*/
int
git_odb__format_object_header
(
char
*
hdr
,
size_t
n
,
git_off_t
obj_len
,
git_otype
obj_type
);
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
);
/*
/*
* Hash an open file descriptor.
* Hash an open file descriptor.
* This is a performance call when the contents of a fd need to be hashed,
* This is a performance call when the contents of a fd need to be hashed,
...
...
src/odb_loose.c
View file @
028a2806
...
@@ -824,14 +824,17 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe
...
@@ -824,14 +824,17 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe
loose_writestream
*
stream
=
NULL
;
loose_writestream
*
stream
=
NULL
;
char
hdr
[
MAX_HEADER_LEN
];
char
hdr
[
MAX_HEADER_LEN
];
git_buf
tmp_path
=
GIT_BUF_INIT
;
git_buf
tmp_path
=
GIT_BUF_INIT
;
int
hdrlen
;
size_t
hdrlen
;
int
error
;
assert
(
_backend
&&
length
>=
0
);
assert
(
_backend
&&
length
>=
0
);
backend
=
(
loose_backend
*
)
_backend
;
backend
=
(
loose_backend
*
)
_backend
;
*
stream_out
=
NULL
;
*
stream_out
=
NULL
;
hdrlen
=
git_odb__format_object_header
(
hdr
,
sizeof
(
hdr
),
length
,
type
);
if
((
error
=
git_odb__format_object_header
(
&
hdrlen
,
hdr
,
sizeof
(
hdr
),
length
,
type
))
<
0
)
return
error
;
stream
=
git__calloc
(
1
,
sizeof
(
loose_writestream
));
stream
=
git__calloc
(
1
,
sizeof
(
loose_writestream
));
GITERR_CHECK_ALLOC
(
stream
);
GITERR_CHECK_ALLOC
(
stream
);
...
@@ -1036,16 +1039,19 @@ done:
...
@@ -1036,16 +1039,19 @@ done:
static
int
loose_backend__write
(
git_odb_backend
*
_backend
,
const
git_oid
*
oid
,
const
void
*
data
,
size_t
len
,
git_otype
type
)
static
int
loose_backend__write
(
git_odb_backend
*
_backend
,
const
git_oid
*
oid
,
const
void
*
data
,
size_t
len
,
git_otype
type
)
{
{
int
error
=
0
,
header_len
;
int
error
=
0
;
git_buf
final_path
=
GIT_BUF_INIT
;
git_buf
final_path
=
GIT_BUF_INIT
;
char
header
[
MAX_HEADER_LEN
];
char
header
[
MAX_HEADER_LEN
];
size_t
header_len
;
git_filebuf
fbuf
=
GIT_FILEBUF_INIT
;
git_filebuf
fbuf
=
GIT_FILEBUF_INIT
;
loose_backend
*
backend
;
loose_backend
*
backend
;
backend
=
(
loose_backend
*
)
_backend
;
backend
=
(
loose_backend
*
)
_backend
;
/* prepare the header for the file */
/* prepare the header for the file */
header_len
=
git_odb__format_object_header
(
header
,
sizeof
(
header
),
len
,
type
);
if
((
error
=
git_odb__format_object_header
(
&
header_len
,
header
,
sizeof
(
header
),
len
,
type
))
<
0
)
goto
cleanup
;
if
(
git_buf_joinpath
(
&
final_path
,
backend
->
objects_dir
,
"tmp_object"
)
<
0
||
if
(
git_buf_joinpath
(
&
final_path
,
backend
->
objects_dir
,
"tmp_object"
)
<
0
||
git_filebuf_open
(
&
fbuf
,
final_path
.
ptr
,
filebuf_flags
(
backend
),
git_filebuf_open
(
&
fbuf
,
final_path
.
ptr
,
filebuf_flags
(
backend
),
...
...
tests/odb/largefiles.c
View file @
028a2806
...
@@ -87,10 +87,10 @@ void test_odb_largefiles__streamread(void)
...
@@ -87,10 +87,10 @@ void test_odb_largefiles__streamread(void)
git_odb_stream
*
stream
;
git_odb_stream
*
stream
;
char
buf
[
10240
];
char
buf
[
10240
];
char
hdr
[
64
];
char
hdr
[
64
];
size_t
len
,
total
=
0
;
size_t
len
,
hdr_len
,
total
=
0
;
git_hash_ctx
hash
;
git_hash_ctx
hash
;
git_otype
type
;
git_otype
type
;
int
hdr_len
,
ret
;
int
ret
;
#ifndef GIT_ARCH_64
#ifndef GIT_ARCH_64
cl_skip
();
cl_skip
();
...
@@ -108,7 +108,7 @@ void test_odb_largefiles__streamread(void)
...
@@ -108,7 +108,7 @@ void test_odb_largefiles__streamread(void)
cl_assert_equal_i
(
GIT_OBJ_BLOB
,
type
);
cl_assert_equal_i
(
GIT_OBJ_BLOB
,
type
);
cl_git_pass
(
git_hash_ctx_init
(
&
hash
));
cl_git_pass
(
git_hash_ctx_init
(
&
hash
));
hdr_len
=
git_odb__format_object_header
(
hdr
,
sizeof
(
hdr
),
len
,
type
);
cl_git_pass
(
git_odb__format_object_header
(
&
hdr_len
,
hdr
,
sizeof
(
hdr
),
len
,
type
)
);
cl_git_pass
(
git_hash_update
(
&
hash
,
hdr
,
hdr_len
));
cl_git_pass
(
git_hash_update
(
&
hash
,
hdr
,
hdr_len
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment