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
a9eac6a6
Unverified
Commit
a9eac6a6
authored
Apr 12, 2022
by
Edward Thomson
Committed by
GitHub
Apr 12, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6268 from libgit2/ethomson/ownership_13
Validate repository directory ownership (v1.3)
parents
37caa8dc
b58e9053
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
605 additions
and
152 deletions
+605
-152
include/git2/common.h
+11
-1
include/git2/errors.h
+1
-0
src/config.c
+10
-6
src/libgit2.c
+8
-0
src/path.c
+213
-54
src/path.h
+28
-8
src/repository.c
+103
-22
src/repository.h
+1
-0
tests/clar_libgit2.c
+5
-0
tests/clar_libgit2.h
+1
-0
tests/core/path.c
+25
-0
tests/fetchhead/fetchhead_data.h
+32
-32
tests/fetchhead/nonetwork.c
+6
-6
tests/main.c
+1
-0
tests/online/clone.c
+8
-8
tests/online/fetch.c
+2
-7
tests/online/fetchhead.c
+2
-6
tests/online/remotes.c
+1
-1
tests/repo/config.c
+0
-1
tests/repo/open.c
+147
-0
No files found.
include/git2/common.h
View file @
a9eac6a6
...
@@ -211,7 +211,9 @@ typedef enum {
...
@@ -211,7 +211,9 @@ typedef enum {
GIT_OPT_SET_ODB_PACKED_PRIORITY
,
GIT_OPT_SET_ODB_PACKED_PRIORITY
,
GIT_OPT_SET_ODB_LOOSE_PRIORITY
,
GIT_OPT_SET_ODB_LOOSE_PRIORITY
,
GIT_OPT_GET_EXTENSIONS
,
GIT_OPT_GET_EXTENSIONS
,
GIT_OPT_SET_EXTENSIONS
GIT_OPT_SET_EXTENSIONS
,
GIT_OPT_GET_OWNER_VALIDATION
,
GIT_OPT_SET_OWNER_VALIDATION
}
git_libgit2_opt_t
;
}
git_libgit2_opt_t
;
/**
/**
...
@@ -449,6 +451,14 @@ typedef enum {
...
@@ -449,6 +451,14 @@ typedef enum {
* > to support repositories with the `noop` extension but does want
* > to support repositories with the `noop` extension but does want
* > to support repositories with the `newext` extension.
* > to support repositories with the `newext` extension.
*
*
* opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled)
* > Gets the owner validation setting for repository
* > directories.
*
* opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled)
* > Set that repository directories should be owned by the current
* > user. The default is to validate ownership.
*
* @param option Option key
* @param option Option key
* @param ... value to set the option
* @param ... value to set the option
* @return 0 on success, <0 on failure
* @return 0 on success, <0 on failure
...
...
include/git2/errors.h
View file @
a9eac6a6
...
@@ -58,6 +58,7 @@ typedef enum {
...
@@ -58,6 +58,7 @@ typedef enum {
GIT_EMISMATCH
=
-
33
,
/**< Hashsum mismatch in object */
GIT_EMISMATCH
=
-
33
,
/**< Hashsum mismatch in object */
GIT_EINDEXDIRTY
=
-
34
,
/**< Unsaved changes in the index would be overwritten */
GIT_EINDEXDIRTY
=
-
34
,
/**< Unsaved changes in the index would be overwritten */
GIT_EAPPLYFAIL
=
-
35
,
/**< Patch application failed */
GIT_EAPPLYFAIL
=
-
35
,
/**< Patch application failed */
GIT_EOWNER
=
-
36
/**< The object is not owned by the current user */
}
git_error_code
;
}
git_error_code
;
/**
/**
...
...
src/config.c
View file @
a9eac6a6
...
@@ -1118,16 +1118,20 @@ int git_config_find_system(git_buf *path)
...
@@ -1118,16 +1118,20 @@ int git_config_find_system(git_buf *path)
int
git_config_find_programdata
(
git_buf
*
path
)
int
git_config_find_programdata
(
git_buf
*
path
)
{
{
int
ret
;
int
ret
;
bool
is_safe
;
if
((
ret
=
git_buf_sanitize
(
path
))
<
0
)
if
((
ret
=
git_buf_sanitize
(
path
))
<
0
||
(
ret
=
git_sysdir_find_programdata_file
(
path
,
GIT_CONFIG_FILENAME_PROGRAMDATA
))
<
0
||
(
ret
=
git_path_owner_is_system_or_current_user
(
&
is_safe
,
path
->
ptr
))
<
0
)
return
ret
;
return
ret
;
ret
=
git_sysdir_find_programdata_file
(
path
,
if
(
!
is_safe
)
{
GIT_CONFIG_FILENAME_PROGRAMDATA
);
git_error_set
(
GIT_ERROR_CONFIG
,
"programdata path has invalid ownership"
);
if
(
ret
!=
GIT_OK
)
return
-
1
;
return
ret
;
}
return
git_path_validate_system_file_ownership
(
path
->
ptr
)
;
return
0
;
}
}
int
git_config__global_location
(
git_buf
*
buf
)
int
git_config__global_location
(
git_buf
*
buf
)
...
...
src/libgit2.c
View file @
a9eac6a6
...
@@ -390,6 +390,14 @@ int git_libgit2_opts(int key, ...)
...
@@ -390,6 +390,14 @@ int git_libgit2_opts(int key, ...)
}
}
break
;
break
;
case
GIT_OPT_GET_OWNER_VALIDATION
:
*
(
va_arg
(
ap
,
int
*
))
=
git_repository__validate_ownership
;
break
;
case
GIT_OPT_SET_OWNER_VALIDATION
:
git_repository__validate_ownership
=
(
va_arg
(
ap
,
int
)
!=
0
);
break
;
default:
default:
git_error_set
(
GIT_ERROR_INVALID
,
"invalid option key"
);
git_error_set
(
GIT_ERROR_INVALID
,
"invalid option key"
);
error
=
-
1
;
error
=
-
1
;
...
...
src/path.c
View file @
a9eac6a6
...
@@ -2024,78 +2024,237 @@ done:
...
@@ -2024,78 +2024,237 @@ done:
return
supported
;
return
supported
;
}
}
int
git_path_validate_system_file_ownership
(
const
char
*
path
)
static
git_path__mock_owner_t
mock_owner
=
GIT_PATH_MOCK_OWNER_NONE
;
void
git_path__set_owner
(
git_path__mock_owner_t
owner
)
{
mock_owner
=
owner
;
}
#ifdef GIT_WIN32
static
PSID
*
sid_dup
(
PSID
sid
)
{
DWORD
len
;
PSID
dup
;
len
=
GetLengthSid
(
sid
);
if
((
dup
=
git__malloc
(
len
))
==
NULL
)
return
NULL
;
if
(
!
CopySid
(
len
,
dup
,
sid
))
{
git_error_set
(
GIT_ERROR_OS
,
"could not duplicate sid"
);
git__free
(
dup
);
return
NULL
;
}
return
dup
;
}
static
int
current_user_sid
(
PSID
*
out
)
{
{
#ifndef GIT_WIN32
GIT_UNUSED
(
path
);
return
GIT_OK
;
#else
git_win32_path
buf
;
PSID
owner_sid
;
PSECURITY_DESCRIPTOR
descriptor
=
NULL
;
HANDLE
token
;
TOKEN_USER
*
info
=
NULL
;
TOKEN_USER
*
info
=
NULL
;
DWORD
err
,
len
;
HANDLE
token
=
NULL
;
int
ret
;
DWORD
len
=
0
;
int
error
=
-
1
;
if
(
git_win32_path_from_utf8
(
buf
,
path
)
<
0
)
if
(
!
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
,
&
token
))
{
return
-
1
;
git_error_set
(
GIT_ERROR_OS
,
"could not lookup process information"
);
goto
done
;
}
if
(
GetTokenInformation
(
token
,
TokenUser
,
NULL
,
0
,
&
len
)
||
GetLastError
()
!=
ERROR_INSUFFICIENT_BUFFER
)
{
git_error_set
(
GIT_ERROR_OS
,
"could not lookup token metadata"
);
goto
done
;
}
err
=
GetNamedSecurityInfoW
(
buf
,
SE_FILE_OBJECT
,
info
=
git__malloc
(
len
);
OWNER_SECURITY_INFORMATION
|
GIT_ERROR_CHECK_ALLOC
(
info
);
DACL_SECURITY_INFORMATION
,
&
owner_sid
,
NULL
,
NULL
,
NULL
,
&
descriptor
);
if
(
err
==
ERROR_FILE_NOT_FOUND
||
err
==
ERROR_PATH_NOT_FOUND
)
{
if
(
!
GetTokenInformation
(
token
,
TokenUser
,
info
,
len
,
&
len
)
)
{
ret
=
GIT_ENOTFOUND
;
git_error_set
(
GIT_ERROR_OS
,
"could not lookup current user"
)
;
goto
cleanup
;
goto
done
;
}
}
if
(
err
!=
ERROR_SUCCESS
)
{
if
((
*
out
=
sid_dup
(
info
->
User
.
Sid
)))
error
=
0
;
done:
if
(
token
)
CloseHandle
(
token
);
git__free
(
info
);
return
error
;
}
static
int
file_owner_sid
(
PSID
*
out
,
const
char
*
path
)
{
git_win32_path
path_w32
;
PSECURITY_DESCRIPTOR
descriptor
=
NULL
;
PSID
owner_sid
;
DWORD
ret
;
int
error
=
-
1
;
if
(
git_win32_path_from_utf8
(
path_w32
,
path
)
<
0
)
return
-
1
;
ret
=
GetNamedSecurityInfoW
(
path_w32
,
SE_FILE_OBJECT
,
OWNER_SECURITY_INFORMATION
|
DACL_SECURITY_INFORMATION
,
&
owner_sid
,
NULL
,
NULL
,
NULL
,
&
descriptor
);
if
(
ret
==
ERROR_FILE_NOT_FOUND
||
ret
==
ERROR_PATH_NOT_FOUND
)
error
=
GIT_ENOTFOUND
;
else
if
(
ret
!=
ERROR_SUCCESS
)
git_error_set
(
GIT_ERROR_OS
,
"failed to get security information"
);
git_error_set
(
GIT_ERROR_OS
,
"failed to get security information"
);
ret
=
GIT_ERROR
;
else
if
(
!
IsValidSid
(
owner_sid
))
goto
cleanup
;
git_error_set
(
GIT_ERROR_OS
,
"file owner is not valid"
);
else
if
((
*
out
=
sid_dup
(
owner_sid
)))
error
=
0
;
if
(
descriptor
)
LocalFree
(
descriptor
);
return
error
;
}
int
git_path_owner_is_current_user
(
bool
*
out
,
const
char
*
path
)
{
PSID
owner_sid
=
NULL
,
user_sid
=
NULL
;
int
error
=
-
1
;
if
(
mock_owner
)
{
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_CURRENT_USER
);
return
0
;
}
if
((
error
=
file_owner_sid
(
&
owner_sid
,
path
))
<
0
||
(
error
=
current_user_sid
(
&
user_sid
))
<
0
)
goto
done
;
*
out
=
EqualSid
(
owner_sid
,
user_sid
);
error
=
0
;
done:
git__free
(
owner_sid
);
git__free
(
user_sid
);
return
error
;
}
int
git_path_owner_is_system
(
bool
*
out
,
const
char
*
path
)
{
PSID
owner_sid
;
if
(
mock_owner
)
{
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_SYSTEM
);
return
0
;
}
}
if
(
!
IsValidSid
(
owner_sid
))
{
if
(
file_owner_sid
(
&
owner_sid
,
path
)
<
0
)
git_error_set
(
GIT_ERROR_INVALID
,
"programdata configuration file owner is unknown"
);
return
-
1
;
ret
=
GIT_ERROR
;
goto
cleanup
;
*
out
=
IsWellKnownSid
(
owner_sid
,
WinBuiltinAdministratorsSid
)
||
IsWellKnownSid
(
owner_sid
,
WinLocalSystemSid
);
git__free
(
owner_sid
);
return
0
;
}
int
git_path_owner_is_system_or_current_user
(
bool
*
out
,
const
char
*
path
)
{
PSID
owner_sid
=
NULL
,
user_sid
=
NULL
;
int
error
=
-
1
;
if
(
mock_owner
)
{
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_SYSTEM
||
mock_owner
==
GIT_PATH_MOCK_OWNER_CURRENT_USER
);
return
0
;
}
}
if
(
file_owner_sid
(
&
owner_sid
,
path
)
<
0
)
goto
done
;
if
(
IsWellKnownSid
(
owner_sid
,
WinBuiltinAdministratorsSid
)
||
if
(
IsWellKnownSid
(
owner_sid
,
WinBuiltinAdministratorsSid
)
||
IsWellKnownSid
(
owner_sid
,
WinLocalSystemSid
))
{
IsWellKnownSid
(
owner_sid
,
WinLocalSystemSid
))
{
ret
=
GIT_OK
;
*
out
=
1
;
goto
cleanup
;
error
=
0
;
}
goto
done
;
}
/* Obtain current user's SID */
if
(
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
,
&
token
)
&&
if
(
current_user_sid
(
&
user_sid
)
<
0
)
!
GetTokenInformation
(
token
,
TokenUser
,
NULL
,
0
,
&
len
))
{
goto
done
;
info
=
git__malloc
(
len
);
GIT_ERROR_CHECK_ALLOC
(
info
);
*
out
=
EqualSid
(
owner_sid
,
user_sid
);
if
(
!
GetTokenInformation
(
token
,
TokenUser
,
info
,
len
,
&
len
))
{
error
=
0
;
git__free
(
info
);
info
=
NULL
;
done:
git__free
(
owner_sid
);
git__free
(
user_sid
);
return
error
;
}
#else
static
int
path_owner_is
(
bool
*
out
,
const
char
*
path
,
uid_t
*
uids
,
size_t
uids_len
)
{
struct
stat
st
;
size_t
i
;
*
out
=
false
;
if
(
p_lstat
(
path
,
&
st
)
!=
0
)
{
if
(
errno
==
ENOENT
)
return
GIT_ENOTFOUND
;
git_error_set
(
GIT_ERROR_OS
,
"could not stat '%s'"
,
path
);
return
-
1
;
}
for
(
i
=
0
;
i
<
uids_len
;
i
++
)
{
if
(
uids
[
i
]
==
st
.
st_uid
)
{
*
out
=
true
;
break
;
}
}
}
}
/*
return
0
;
* If the file is owned by the same account that is running the current
}
* process, it's okay to read from that file.
*/
int
git_path_owner_is_current_user
(
bool
*
out
,
const
char
*
path
)
if
(
info
&&
EqualSid
(
owner_sid
,
info
->
User
.
Sid
))
{
ret
=
GIT_OK
;
uid_t
userid
=
geteuid
();
else
{
git_error_set
(
GIT_ERROR_INVALID
,
"programdata configuration file owner is not valid"
);
if
(
mock_owner
)
{
ret
=
GIT_ERROR
;
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_CURRENT_USER
);
return
0
;
}
}
git__free
(
info
);
cleanup:
return
path_owner_is
(
out
,
path
,
&
userid
,
1
);
if
(
descriptor
)
}
LocalFree
(
descriptor
);
return
ret
;
int
git_path_owner_is_system
(
bool
*
out
,
const
char
*
path
)
#endif
{
uid_t
userid
=
0
;
if
(
mock_owner
)
{
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_SYSTEM
);
return
0
;
}
return
path_owner_is
(
out
,
path
,
&
userid
,
1
);
}
int
git_path_owner_is_system_or_current_user
(
bool
*
out
,
const
char
*
path
)
{
uid_t
userids
[
2
]
=
{
geteuid
(),
0
};
if
(
mock_owner
)
{
*
out
=
(
mock_owner
==
GIT_PATH_MOCK_OWNER_SYSTEM
||
mock_owner
==
GIT_PATH_MOCK_OWNER_CURRENT_USER
);
return
0
;
}
return
path_owner_is
(
out
,
path
,
userids
,
2
);
}
}
#endif
src/path.h
View file @
a9eac6a6
...
@@ -722,16 +722,36 @@ int git_path_normalize_slashes(git_buf *out, const char *path);
...
@@ -722,16 +722,36 @@ int git_path_normalize_slashes(git_buf *out, const char *path);
bool
git_path_supports_symlinks
(
const
char
*
dir
);
bool
git_path_supports_symlinks
(
const
char
*
dir
);
typedef
enum
{
GIT_PATH_MOCK_OWNER_NONE
=
0
,
/* do filesystem lookups as normal */
GIT_PATH_MOCK_OWNER_SYSTEM
=
1
,
GIT_PATH_MOCK_OWNER_CURRENT_USER
=
2
,
GIT_PATH_MOCK_OWNER_OTHER
=
3
}
git_path__mock_owner_t
;
/**
* Sets the mock ownership for files; subsequent calls to
* `git_path_owner_is_*` functions will return this data until cleared
* with `GIT_PATH_MOCK_OWNER_NONE`.
*/
void
git_path__set_owner
(
git_path__mock_owner_t
owner
);
/**
/**
* Validate a system file's ownership
*
* Verify that the file in question is owned by an administrator or system
* Verify that the file in question is owned by an administrator or system
* account, or at least by the current user.
* account.
*
*/
* This function returns 0 if successful. If the file is not owned by any of
int
git_path_owner_is_system
(
bool
*
out
,
const
char
*
path
);
* these, or any other if there have been problems determining the file
* ownership, it returns -1.
/**
* Verify that the file in question is owned by the current user;
*/
int
git_path_owner_is_current_user
(
bool
*
out
,
const
char
*
path
);
/**
* Verify that the file in question is owned by an administrator or system
* account _or_ the current user;
*/
*/
int
git_path_
validate_system_file_ownership
(
const
char
*
path
);
int
git_path_
owner_is_system_or_current_user
(
bool
*
out
,
const
char
*
path
);
#endif
#endif
src/repository.c
View file @
a9eac6a6
...
@@ -38,6 +38,7 @@
...
@@ -38,6 +38,7 @@
# include "win32/w32_util.h"
# include "win32/w32_util.h"
#endif
#endif
bool
git_repository__validate_ownership
=
true
;
bool
git_repository__fsync_gitdir
=
false
;
bool
git_repository__fsync_gitdir
=
false
;
static
const
struct
{
static
const
struct
{
...
@@ -64,6 +65,7 @@ static const struct {
...
@@ -64,6 +65,7 @@ static const struct {
static
int
check_repositoryformatversion
(
int
*
version
,
git_config
*
config
);
static
int
check_repositoryformatversion
(
int
*
version
,
git_config
*
config
);
static
int
check_extensions
(
git_config
*
config
,
int
version
);
static
int
check_extensions
(
git_config
*
config
,
int
version
);
static
int
load_global_config
(
git_config
**
config
);
#define GIT_COMMONDIR_FILE "commondir"
#define GIT_COMMONDIR_FILE "commondir"
#define GIT_GITDIR_FILE "gitdir"
#define GIT_GITDIR_FILE "gitdir"
...
@@ -482,6 +484,63 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
...
@@ -482,6 +484,63 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
return
error
;
return
error
;
}
}
typedef
struct
{
const
char
*
repo_path
;
git_buf
tmp
;
bool
is_safe
;
}
validate_ownership_data
;
static
int
validate_ownership_cb
(
const
git_config_entry
*
entry
,
void
*
payload
)
{
validate_ownership_data
*
data
=
payload
;
if
(
strcmp
(
entry
->
value
,
""
)
==
0
)
data
->
is_safe
=
false
;
if
(
git_path_prettify_dir
(
&
data
->
tmp
,
entry
->
value
,
NULL
)
==
0
&&
strcmp
(
data
->
tmp
.
ptr
,
data
->
repo_path
)
==
0
)
data
->
is_safe
=
true
;
return
0
;
}
static
int
validate_ownership
(
const
char
*
repo_path
)
{
git_config
*
config
=
NULL
;
validate_ownership_data
data
=
{
repo_path
,
GIT_BUF_INIT
,
false
};
bool
is_safe
;
int
error
;
if
((
error
=
git_path_owner_is_current_user
(
&
is_safe
,
repo_path
))
<
0
)
{
if
(
error
==
GIT_ENOTFOUND
)
error
=
0
;
goto
done
;
}
if
(
is_safe
)
{
error
=
0
;
goto
done
;
}
if
(
load_global_config
(
&
config
)
==
0
)
{
error
=
git_config_get_multivar_foreach
(
config
,
"safe.directory"
,
NULL
,
validate_ownership_cb
,
&
data
);
if
(
!
error
&&
data
.
is_safe
)
goto
done
;
}
git_error_set
(
GIT_ERROR_CONFIG
,
"repository path '%s' is not owned by current user"
,
repo_path
);
error
=
GIT_EOWNER
;
done:
git_config_free
(
config
);
git_buf_dispose
(
&
data
.
tmp
);
return
error
;
}
static
int
find_repo
(
static
int
find_repo
(
git_buf
*
gitdir_path
,
git_buf
*
gitdir_path
,
git_buf
*
workdir_path
,
git_buf
*
workdir_path
,
...
@@ -855,6 +914,7 @@ int git_repository_open_ext(
...
@@ -855,6 +914,7 @@ int git_repository_open_ext(
gitlink
=
GIT_BUF_INIT
,
commondir
=
GIT_BUF_INIT
;
gitlink
=
GIT_BUF_INIT
,
commondir
=
GIT_BUF_INIT
;
git_repository
*
repo
=
NULL
;
git_repository
*
repo
=
NULL
;
git_config
*
config
=
NULL
;
git_config
*
config
=
NULL
;
const
char
*
validation_path
;
int
version
=
0
;
int
version
=
0
;
if
(
flags
&
GIT_REPOSITORY_OPEN_FROM_ENV
)
if
(
flags
&
GIT_REPOSITORY_OPEN_FROM_ENV
)
...
@@ -903,16 +963,24 @@ int git_repository_open_ext(
...
@@ -903,16 +963,24 @@ int git_repository_open_ext(
if
((
error
=
check_extensions
(
config
,
version
))
<
0
)
if
((
error
=
check_extensions
(
config
,
version
))
<
0
)
goto
cleanup
;
goto
cleanup
;
if
((
flags
&
GIT_REPOSITORY_OPEN_BARE
)
!=
0
)
if
((
flags
&
GIT_REPOSITORY_OPEN_BARE
)
!=
0
)
{
repo
->
is_bare
=
1
;
repo
->
is_bare
=
1
;
else
{
}
else
{
if
(
config
&&
if
(
config
&&
((
error
=
load_config_data
(
repo
,
config
))
<
0
||
((
error
=
load_config_data
(
repo
,
config
))
<
0
||
(
error
=
load_workdir
(
repo
,
config
,
&
workdir
))
<
0
))
(
error
=
load_workdir
(
repo
,
config
,
&
workdir
))
<
0
))
goto
cleanup
;
goto
cleanup
;
}
}
/*
* Ensure that the git directory is owned by the current user.
*/
validation_path
=
repo
->
is_bare
?
repo
->
gitdir
:
repo
->
workdir
;
if
(
git_repository__validate_ownership
&&
(
error
=
validate_ownership
(
validation_path
))
<
0
)
goto
cleanup
;
cleanup:
cleanup:
git_buf_dispose
(
&
gitdir
);
git_buf_dispose
(
&
gitdir
);
git_buf_dispose
(
&
workdir
);
git_buf_dispose
(
&
workdir
);
...
@@ -1609,13 +1677,40 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
...
@@ -1609,13 +1677,40 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
return
is_insensitive
;
return
is_insensitive
;
}
}
static
bool
are_symlinks_supported
(
const
char
*
wd_path
)
/*
* Return a configuration object with only the global and system
* configurations; no repository-level configuration.
*/
static
int
load_global_config
(
git_config
**
config
)
{
{
git_config
*
config
=
NULL
;
git_buf
global_buf
=
GIT_BUF_INIT
;
git_buf
global_buf
=
GIT_BUF_INIT
;
git_buf
xdg_buf
=
GIT_BUF_INIT
;
git_buf
xdg_buf
=
GIT_BUF_INIT
;
git_buf
system_buf
=
GIT_BUF_INIT
;
git_buf
system_buf
=
GIT_BUF_INIT
;
git_buf
programdata_buf
=
GIT_BUF_INIT
;
git_buf
programdata_buf
=
GIT_BUF_INIT
;
int
error
;
git_config_find_global
(
&
global_buf
);
git_config_find_xdg
(
&
xdg_buf
);
git_config_find_system
(
&
system_buf
);
git_config_find_programdata
(
&
programdata_buf
);
error
=
load_config
(
config
,
NULL
,
path_unless_empty
(
&
global_buf
),
path_unless_empty
(
&
xdg_buf
),
path_unless_empty
(
&
system_buf
),
path_unless_empty
(
&
programdata_buf
));
git_buf_dispose
(
&
global_buf
);
git_buf_dispose
(
&
xdg_buf
);
git_buf_dispose
(
&
system_buf
);
git_buf_dispose
(
&
programdata_buf
);
return
error
;
}
static
bool
are_symlinks_supported
(
const
char
*
wd_path
)
{
git_config
*
config
=
NULL
;
int
symlinks
=
0
;
int
symlinks
=
0
;
/*
/*
...
@@ -1626,19 +1721,9 @@ static bool are_symlinks_supported(const char *wd_path)
...
@@ -1626,19 +1721,9 @@ static bool are_symlinks_supported(const char *wd_path)
* _not_ set, then we do not test or enable symlink support.
* _not_ set, then we do not test or enable symlink support.
*/
*/
#ifdef GIT_WIN32
#ifdef GIT_WIN32
git_config_find_global
(
&
global_buf
);
if
(
load_global_config
(
&
config
)
<
0
||
git_config_find_xdg
(
&
xdg_buf
);
git_config_get_bool
(
&
symlinks
,
config
,
"core.symlinks"
)
<
0
||
git_config_find_system
(
&
system_buf
);
!
symlinks
)
git_config_find_programdata
(
&
programdata_buf
);
if
(
load_config
(
&
config
,
NULL
,
path_unless_empty
(
&
global_buf
),
path_unless_empty
(
&
xdg_buf
),
path_unless_empty
(
&
system_buf
),
path_unless_empty
(
&
programdata_buf
))
<
0
)
goto
done
;
if
(
git_config_get_bool
(
&
symlinks
,
config
,
"core.symlinks"
)
<
0
||
!
symlinks
)
goto
done
;
goto
done
;
#endif
#endif
...
@@ -1646,10 +1731,6 @@ static bool are_symlinks_supported(const char *wd_path)
...
@@ -1646,10 +1731,6 @@ static bool are_symlinks_supported(const char *wd_path)
goto
done
;
goto
done
;
done:
done:
git_buf_dispose
(
&
global_buf
);
git_buf_dispose
(
&
xdg_buf
);
git_buf_dispose
(
&
system_buf
);
git_buf_dispose
(
&
programdata_buf
);
git_config_free
(
config
);
git_config_free
(
config
);
return
symlinks
!=
0
;
return
symlinks
!=
0
;
}
}
...
...
src/repository.h
View file @
a9eac6a6
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#define GIT_DIR_SHORTNAME "GIT~1"
#define GIT_DIR_SHORTNAME "GIT~1"
extern
bool
git_repository__fsync_gitdir
;
extern
bool
git_repository__fsync_gitdir
;
extern
bool
git_repository__validate_ownership
;
/** Cvar cache identifiers */
/** Cvar cache identifiers */
typedef
enum
{
typedef
enum
{
...
...
tests/clar_libgit2.c
View file @
a9eac6a6
...
@@ -603,6 +603,11 @@ void cl_sandbox_set_search_path_defaults(void)
...
@@ -603,6 +603,11 @@ void cl_sandbox_set_search_path_defaults(void)
git_buf_dispose
(
&
path
);
git_buf_dispose
(
&
path
);
}
}
void
cl_sandbox_disable_ownership_validation
(
void
)
{
git_libgit2_opts
(
GIT_OPT_SET_OWNER_VALIDATION
,
0
);
}
#ifdef GIT_WIN32
#ifdef GIT_WIN32
bool
cl_sandbox_supports_8dot3
(
void
)
bool
cl_sandbox_supports_8dot3
(
void
)
{
{
...
...
tests/clar_libgit2.h
View file @
a9eac6a6
...
@@ -222,6 +222,7 @@ void cl_fake_home(void);
...
@@ -222,6 +222,7 @@ void cl_fake_home(void);
void
cl_fake_home_cleanup
(
void
*
);
void
cl_fake_home_cleanup
(
void
*
);
void
cl_sandbox_set_search_path_defaults
(
void
);
void
cl_sandbox_set_search_path_defaults
(
void
);
void
cl_sandbox_disable_ownership_validation
(
void
);
#ifdef GIT_WIN32
#ifdef GIT_WIN32
# define cl_msleep(x) Sleep(x)
# define cl_msleep(x) Sleep(x)
...
...
tests/core/path.c
View file @
a9eac6a6
...
@@ -659,3 +659,28 @@ void test_core_path__git_path_is_file(void)
...
@@ -659,3 +659,28 @@ void test_core_path__git_path_is_file(void)
cl_git_pass
(
git_path_is_gitfile
(
"blob"
,
4
,
GIT_PATH_GITFILE_GITATTRIBUTES
,
GIT_PATH_FS_HFS
));
cl_git_pass
(
git_path_is_gitfile
(
"blob"
,
4
,
GIT_PATH_GITFILE_GITATTRIBUTES
,
GIT_PATH_FS_HFS
));
cl_git_fail
(
git_path_is_gitfile
(
"blob"
,
4
,
3
,
GIT_PATH_FS_HFS
));
cl_git_fail
(
git_path_is_gitfile
(
"blob"
,
4
,
3
,
GIT_PATH_FS_HFS
));
}
}
void
test_core_path__validate_current_user_ownership
(
void
)
{
bool
is_cur
;
cl_must_pass
(
p_mkdir
(
"testdir"
,
0777
));
cl_git_pass
(
git_path_owner_is_current_user
(
&
is_cur
,
"testdir"
));
cl_assert_equal_i
(
is_cur
,
1
);
cl_git_rewritefile
(
"testfile"
,
"This is a test file."
);
cl_git_pass
(
git_path_owner_is_current_user
(
&
is_cur
,
"testfile"
));
cl_assert_equal_i
(
is_cur
,
1
);
#ifdef GIT_WIN32
cl_git_pass
(
git_path_owner_is_current_user
(
&
is_cur
,
"C:
\\
"
));
cl_assert_equal_i
(
is_cur
,
0
);
cl_git_fail
(
git_path_owner_is_current_user
(
&
is_cur
,
"c:
\\
path
\\
does
\\
not
\\
exist"
));
#else
cl_git_pass
(
git_path_owner_is_current_user
(
&
is_cur
,
"/"
));
cl_assert_equal_i
(
is_cur
,
0
);
cl_git_fail
(
git_path_owner_is_current_user
(
&
is_cur
,
"/path/does/not/exist"
));
#endif
}
tests/fetchhead/fetchhead_data.h
View file @
a9eac6a6
#define FETCH_HEAD_WILDCARD_DATA_LOCAL \
#define FETCH_HEAD_WILDCARD_DATA_LOCAL \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
git
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
https
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
git
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
https
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
git
://github.com/libgit2/TestGitRepository\n"
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
https
://github.com/libgit2/TestGitRepository\n"
#define FETCH_HEAD_WILDCARD_DATA \
#define FETCH_HEAD_WILDCARD_DATA \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
git
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
https
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
git
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
https
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
git
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
https
://github.com/libgit2/TestGitRepository\n" \
"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of
git
://github.com/libgit2/TestGitRepository\n"
"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of
https
://github.com/libgit2/TestGitRepository\n"
#define FETCH_HEAD_WILDCARD_DATA2 \
#define FETCH_HEAD_WILDCARD_DATA2 \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\t\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
#define FETCH_HEAD_NO_MERGE_DATA \
#define FETCH_HEAD_NO_MERGE_DATA \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
git
://github.com/libgit2/TestGitRepository\n" \
"d96c4e80345534eccee5ac7b07fc7603b56124cb\tnot-for-merge\ttag 'annotated_tag' of
https
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
git
://github.com/libgit2/TestGitRepository\n" \
"55a1a760df4b86a02094a904dfa511deb5655905\tnot-for-merge\ttag 'blob' of
https
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
git
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
https
://github.com/libgit2/TestGitRepository\n" \
"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of
git
://github.com/libgit2/TestGitRepository\n"
"6e0c7bdb9b4ed93212491ee778ca1c65047cab4e\tnot-for-merge\ttag 'nearly-dangling' of
https
://github.com/libgit2/TestGitRepository\n"
#define FETCH_HEAD_NO_MERGE_DATA2 \
#define FETCH_HEAD_NO_MERGE_DATA2 \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
#define FETCH_HEAD_NO_MERGE_DATA3 \
#define FETCH_HEAD_NO_MERGE_DATA3 \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n" \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\tnot-for-merge\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
git
://github.com/libgit2/TestGitRepository\n" \
"49322bb17d3acc9146f98c97d078513228bbf3c0\tnot-for-merge\tbranch 'master' of
https
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
git
://github.com/libgit2/TestGitRepository\n" \
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1\tnot-for-merge\tbranch 'no-parent' of
https
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
git
://github.com/libgit2/TestGitRepository\n" \
"8f50ba15d49353813cc6e20298002c0d17b0a9ee\tnot-for-merge\ttag 'commit_tree' of
https
://github.com/libgit2/TestGitRepository\n" \
#define FETCH_HEAD_EXPLICIT_DATA \
#define FETCH_HEAD_EXPLICIT_DATA \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of
git
://github.com/libgit2/TestGitRepository\n"
"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of
https
://github.com/libgit2/TestGitRepository\n"
#define FETCH_HEAD_QUOTE_DATA \
#define FETCH_HEAD_QUOTE_DATA \
"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of
git
://github.com/libgit2/TestGitRepository\n"
"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of
https
://github.com/libgit2/TestGitRepository\n"
tests/fetchhead/nonetwork.c
View file @
a9eac6a6
...
@@ -33,42 +33,42 @@ static void populate_fetchhead(git_vector *out, git_repository *repo)
...
@@ -33,42 +33,42 @@ static void populate_fetchhead(git_vector *out, git_repository *repo)
"49322bb17d3acc9146f98c97d078513228bbf3c0"
));
"49322bb17d3acc9146f98c97d078513228bbf3c0"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
1
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
1
,
"refs/heads/master"
,
"refs/heads/master"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
"0966a434eb1a025db6b71485ab63a3bfbea520b6"
));
"0966a434eb1a025db6b71485ab63a3bfbea520b6"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
"refs/heads/first-merge"
,
"refs/heads/first-merge"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1"
));
"42e4e7c5e507e113ebbb7801b16b52cf867b7ce1"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
"refs/heads/no-parent"
,
"refs/heads/no-parent"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
"d96c4e80345534eccee5ac7b07fc7603b56124cb"
));
"d96c4e80345534eccee5ac7b07fc7603b56124cb"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
"refs/tags/annotated_tag"
,
"refs/tags/annotated_tag"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
"55a1a760df4b86a02094a904dfa511deb5655905"
));
"55a1a760df4b86a02094a904dfa511deb5655905"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
"refs/tags/blob"
,
"refs/tags/blob"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
cl_git_pass
(
git_oid_fromstr
(
&
oid
,
"8f50ba15d49353813cc6e20298002c0d17b0a9ee"
));
"8f50ba15d49353813cc6e20298002c0d17b0a9ee"
));
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
cl_git_pass
(
git_fetchhead_ref_create
(
&
fetchhead_ref
,
&
oid
,
0
,
"refs/tags/commit_tree"
,
"refs/tags/commit_tree"
,
"
git
://github.com/libgit2/TestGitRepository"
));
"
https
://github.com/libgit2/TestGitRepository"
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_vector_insert
(
out
,
fetchhead_ref
));
cl_git_pass
(
git_fetchhead_write
(
repo
,
out
));
cl_git_pass
(
git_fetchhead_write
(
repo
,
out
));
...
...
tests/main.c
View file @
a9eac6a6
...
@@ -26,6 +26,7 @@ int main(int argc, char *argv[])
...
@@ -26,6 +26,7 @@ int main(int argc, char *argv[])
cl_global_trace_register
();
cl_global_trace_register
();
cl_sandbox_set_search_path_defaults
();
cl_sandbox_set_search_path_defaults
();
cl_sandbox_disable_ownership_validation
();
/* Run the test suite */
/* Run the test suite */
res
=
clar_test_run
();
res
=
clar_test_run
();
...
...
tests/online/clone.c
View file @
a9eac6a6
...
@@ -8,9 +8,9 @@
...
@@ -8,9 +8,9 @@
#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
#define LIVE_REPO_URL "http://github.com/libgit2/TestGitRepository"
#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
#define LIVE_EMPTYREPO_URL "http://github.com/libgit2/TestEmptyRepository"
#define BB_REPO_URL "https://libgit
3@bitbucket.org/libgit2
/testgitrepository.git"
#define BB_REPO_URL "https://libgit
2-test@bitbucket.org/libgit2-test
/testgitrepository.git"
#define BB_REPO_URL_WITH_PASS "https://libgit
3:libgit3@bitbucket.org/libgit2
/testgitrepository.git"
#define BB_REPO_URL_WITH_PASS "https://libgit
2-test:YT77Ppm2nq8w4TYjGS8U@bitbucket.org/libgit2-test
/testgitrepository.git"
#define BB_REPO_URL_WITH_WRONG_PASS "https://libgit
3:wrong@bitbucket.org/libgit2
/testgitrepository.git"
#define BB_REPO_URL_WITH_WRONG_PASS "https://libgit
2-test:wrong@bitbucket.org/libgit2-test
/testgitrepository.git"
#define GOOGLESOURCE_REPO_URL "https://chromium.googlesource.com/external/github.com/sergi/go-diff"
#define GOOGLESOURCE_REPO_URL "https://chromium.googlesource.com/external/github.com/sergi/go-diff"
#define SSH_REPO_URL "ssh://github.com/libgit2/TestGitRepository"
#define SSH_REPO_URL "ssh://github.com/libgit2/TestGitRepository"
...
@@ -405,7 +405,7 @@ void test_online_clone__credentials(void)
...
@@ -405,7 +405,7 @@ void test_online_clone__credentials(void)
void
test_online_clone__credentials_via_custom_headers
(
void
)
void
test_online_clone__credentials_via_custom_headers
(
void
)
{
{
const
char
*
creds
=
"libgit
3:libgit3
"
;
const
char
*
creds
=
"libgit
2-test:YT77Ppm2nq8w4TYjGS8U
"
;
git_buf
auth
=
GIT_BUF_INIT
;
git_buf
auth
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_puts
(
&
auth
,
"Authorization: Basic "
));
cl_git_pass
(
git_buf_puts
(
&
auth
,
"Authorization: Basic "
));
...
@@ -413,7 +413,7 @@ void test_online_clone__credentials_via_custom_headers(void)
...
@@ -413,7 +413,7 @@ void test_online_clone__credentials_via_custom_headers(void)
g_options
.
fetch_opts
.
custom_headers
.
count
=
1
;
g_options
.
fetch_opts
.
custom_headers
.
count
=
1
;
g_options
.
fetch_opts
.
custom_headers
.
strings
=
&
auth
.
ptr
;
g_options
.
fetch_opts
.
custom_headers
.
strings
=
&
auth
.
ptr
;
cl_git_pass
(
git_clone
(
&
g_repo
,
"https://bitbucket.org/libgit2/testgitrepository.git"
,
"./foo"
,
&
g_options
));
cl_git_pass
(
git_clone
(
&
g_repo
,
"https://bitbucket.org/libgit2
-test
/testgitrepository.git"
,
"./foo"
,
&
g_options
));
git_buf_dispose
(
&
auth
);
git_buf_dispose
(
&
auth
);
}
}
...
@@ -421,7 +421,7 @@ void test_online_clone__credentials_via_custom_headers(void)
...
@@ -421,7 +421,7 @@ void test_online_clone__credentials_via_custom_headers(void)
void
test_online_clone__bitbucket_style
(
void
)
void
test_online_clone__bitbucket_style
(
void
)
{
{
git_credential_userpass_payload
user_pass
=
{
git_credential_userpass_payload
user_pass
=
{
"libgit
3"
,
"libgit3
"
"libgit
2-test"
,
"YT77Ppm2nq8w4TYjGS8U
"
};
};
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
...
@@ -435,7 +435,7 @@ void test_online_clone__bitbucket_style(void)
...
@@ -435,7 +435,7 @@ void test_online_clone__bitbucket_style(void)
void
test_online_clone__bitbucket_uses_creds_in_url
(
void
)
void
test_online_clone__bitbucket_uses_creds_in_url
(
void
)
{
{
git_credential_userpass_payload
user_pass
=
{
git_credential_userpass_payload
user_pass
=
{
"libgit2"
,
"wrong"
"libgit2
-test
"
,
"wrong"
};
};
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
...
@@ -453,7 +453,7 @@ void test_online_clone__bitbucket_uses_creds_in_url(void)
...
@@ -453,7 +453,7 @@ void test_online_clone__bitbucket_uses_creds_in_url(void)
void
test_online_clone__bitbucket_falls_back_to_specified_creds
(
void
)
void
test_online_clone__bitbucket_falls_back_to_specified_creds
(
void
)
{
{
git_credential_userpass_payload
user_pass
=
{
git_credential_userpass_payload
user_pass
=
{
"libgit2"
,
"libgit2"
"libgit2
-test
"
,
"libgit2"
};
};
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
g_options
.
fetch_opts
.
callbacks
.
credentials
=
git_credential_userpass
;
...
...
tests/online/fetch.c
View file @
a9eac6a6
...
@@ -67,11 +67,6 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
...
@@ -67,11 +67,6 @@ static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
git_remote_free
(
remote
);
git_remote_free
(
remote
);
}
}
void
test_online_fetch__default_git
(
void
)
{
do_fetch
(
"git://github.com/libgit2/TestGitRepository.git"
,
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
,
6
);
}
void
test_online_fetch__default_http
(
void
)
void
test_online_fetch__default_http
(
void
)
{
{
do_fetch
(
"http://github.com/libgit2/TestGitRepository.git"
,
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
,
6
);
do_fetch
(
"http://github.com/libgit2/TestGitRepository.git"
,
GIT_REMOTE_DOWNLOAD_TAGS_AUTO
,
6
);
...
@@ -84,7 +79,7 @@ void test_online_fetch__default_https(void)
...
@@ -84,7 +79,7 @@ void test_online_fetch__default_https(void)
void
test_online_fetch__no_tags_git
(
void
)
void
test_online_fetch__no_tags_git
(
void
)
{
{
do_fetch
(
"
git
://github.com/libgit2/TestGitRepository.git"
,
GIT_REMOTE_DOWNLOAD_TAGS_NONE
,
3
);
do_fetch
(
"
https
://github.com/libgit2/TestGitRepository.git"
,
GIT_REMOTE_DOWNLOAD_TAGS_NONE
,
3
);
}
}
void
test_online_fetch__no_tags_http
(
void
)
void
test_online_fetch__no_tags_http
(
void
)
...
@@ -95,7 +90,7 @@ void test_online_fetch__no_tags_http(void)
...
@@ -95,7 +90,7 @@ void test_online_fetch__no_tags_http(void)
void
test_online_fetch__fetch_twice
(
void
)
void
test_online_fetch__fetch_twice
(
void
)
{
{
git_remote
*
remote
;
git_remote
*
remote
;
cl_git_pass
(
git_remote_create
(
&
remote
,
_repo
,
"test"
,
"
git
://github.com/libgit2/TestGitRepository.git"
));
cl_git_pass
(
git_remote_create
(
&
remote
,
_repo
,
"test"
,
"
https
://github.com/libgit2/TestGitRepository.git"
));
cl_git_pass
(
git_remote_connect
(
remote
,
GIT_DIRECTION_FETCH
,
NULL
,
NULL
,
NULL
));
cl_git_pass
(
git_remote_connect
(
remote
,
GIT_DIRECTION_FETCH
,
NULL
,
NULL
,
NULL
));
cl_git_pass
(
git_remote_download
(
remote
,
NULL
,
NULL
));
cl_git_pass
(
git_remote_download
(
remote
,
NULL
,
NULL
));
git_remote_disconnect
(
remote
);
git_remote_disconnect
(
remote
);
...
...
tests/online/fetchhead.c
View file @
a9eac6a6
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
#include "../fetchhead/fetchhead_data.h"
#include "../fetchhead/fetchhead_data.h"
#include "git2/clone.h"
#include "git2/clone.h"
#define LIVE_REPO_URL "
git
://github.com/libgit2/TestGitRepository"
#define LIVE_REPO_URL "
https
://github.com/libgit2/TestGitRepository"
static
git_repository
*
g_repo
;
static
git_repository
*
g_repo
;
static
git_clone_options
g_options
;
static
git_clone_options
g_options
;
...
@@ -53,7 +53,6 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
...
@@ -53,7 +53,6 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
git_remote
*
remote
;
git_remote
*
remote
;
git_fetch_options
fetch_opts
=
GIT_FETCH_OPTIONS_INIT
;
git_fetch_options
fetch_opts
=
GIT_FETCH_OPTIONS_INIT
;
git_buf
fetchhead_buf
=
GIT_BUF_INIT
;
git_buf
fetchhead_buf
=
GIT_BUF_INIT
;
int
equals
=
0
;
git_strarray
array
,
*
active_refs
=
NULL
;
git_strarray
array
,
*
active_refs
=
NULL
;
cl_git_pass
(
git_remote_lookup
(
&
remote
,
g_repo
,
"origin"
));
cl_git_pass
(
git_remote_lookup
(
&
remote
,
g_repo
,
"origin"
));
...
@@ -70,11 +69,8 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
...
@@ -70,11 +69,8 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
cl_git_pass
(
git_futils_readbuffer
(
&
fetchhead_buf
,
"./foo/.git/FETCH_HEAD"
));
cl_git_pass
(
git_futils_readbuffer
(
&
fetchhead_buf
,
"./foo/.git/FETCH_HEAD"
));
equals
=
(
strcmp
(
fetchhead_buf
.
ptr
,
expected_fetchhead
)
==
0
);
cl_assert_equal_s
(
fetchhead_buf
.
ptr
,
expected_fetchhead
);
git_buf_dispose
(
&
fetchhead_buf
);
git_buf_dispose
(
&
fetchhead_buf
);
cl_assert
(
equals
);
}
}
void
test_online_fetchhead__wildcard_spec
(
void
)
void
test_online_fetchhead__wildcard_spec
(
void
)
...
...
tests/online/remotes.c
View file @
a9eac6a6
#include "clar_libgit2.h"
#include "clar_libgit2.h"
#define URL "
git
://github.com/libgit2/TestGitRepository"
#define URL "
https
://github.com/libgit2/TestGitRepository"
#define REFSPEC "refs/heads/first-merge:refs/remotes/origin/first-merge"
#define REFSPEC "refs/heads/first-merge:refs/remotes/origin/first-merge"
static
int
remote_single_branch
(
git_remote
**
out
,
git_repository
*
repo
,
const
char
*
name
,
const
char
*
url
,
void
*
payload
)
static
int
remote_single_branch
(
git_remote
**
out
,
git_repository
*
repo
,
const
char
*
name
,
const
char
*
url
,
void
*
payload
)
...
...
tests/repo/config.c
View file @
a9eac6a6
...
@@ -28,7 +28,6 @@ void test_repo_config__cleanup(void)
...
@@ -28,7 +28,6 @@ void test_repo_config__cleanup(void)
cl_assert
(
!
git_path_isdir
(
"alternate"
));
cl_assert
(
!
git_path_isdir
(
"alternate"
));
cl_fixture_cleanup
(
"empty_standard_repo"
);
cl_fixture_cleanup
(
"empty_standard_repo"
);
}
}
void
test_repo_config__can_open_global_when_there_is_no_file
(
void
)
void
test_repo_config__can_open_global_when_there_is_no_file
(
void
)
...
...
tests/repo/open.c
View file @
a9eac6a6
...
@@ -3,13 +3,30 @@
...
@@ -3,13 +3,30 @@
#include "sysdir.h"
#include "sysdir.h"
#include <ctype.h>
#include <ctype.h>
static
int
validate_ownership
=
0
;
static
git_buf
config_path
=
GIT_BUF_INIT
;
void
test_repo_open__initialize
(
void
)
{
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_GET_SEARCH_PATH
,
GIT_CONFIG_LEVEL_GLOBAL
,
&
config_path
));
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_GET_OWNER_VALIDATION
,
&
validate_ownership
));
}
void
test_repo_open__cleanup
(
void
)
void
test_repo_open__cleanup
(
void
)
{
{
cl_git_sandbox_cleanup
();
cl_git_sandbox_cleanup
();
cl_fixture_cleanup
(
"empty_standard_repo"
);
cl_fixture_cleanup
(
"__global_config"
);
if
(
git_path_isdir
(
"alternate"
))
if
(
git_path_isdir
(
"alternate"
))
git_futils_rmdir_r
(
"alternate"
,
NULL
,
GIT_RMDIR_REMOVE_FILES
);
git_futils_rmdir_r
(
"alternate"
,
NULL
,
GIT_RMDIR_REMOVE_FILES
);
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_NONE
);
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_SET_SEARCH_PATH
,
GIT_CONFIG_LEVEL_GLOBAL
,
config_path
.
ptr
));
git_buf_dispose
(
&
config_path
);
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_SET_OWNER_VALIDATION
,
validate_ownership
));
}
}
void
test_repo_open__bare_empty_repo
(
void
)
void
test_repo_open__bare_empty_repo
(
void
)
...
@@ -453,3 +470,133 @@ void test_repo_open__force_bare(void)
...
@@ -453,3 +470,133 @@ void test_repo_open__force_bare(void)
git_repository_free
(
barerepo
);
git_repository_free
(
barerepo
);
}
}
void
test_repo_open__validates_dir_ownership
(
void
)
{
git_repository
*
repo
;
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_SET_OWNER_VALIDATION
,
1
));
cl_fixture_sandbox
(
"empty_standard_repo"
);
cl_git_pass
(
cl_rename
(
"empty_standard_repo/.gitted"
,
"empty_standard_repo/.git"
));
/* When the current user owns the repo config, that's acceptable */
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_CURRENT_USER
);
cl_git_pass
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
git_repository_free
(
repo
);
/* When the system user owns the repo config, fail */
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_SYSTEM
);
cl_git_fail
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
/* When an unknown user owns the repo config, fail */
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_OTHER
);
cl_git_fail
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
}
void
test_repo_open__can_allowlist_dirs_with_problematic_ownership
(
void
)
{
git_repository
*
repo
;
git_buf
config_path
=
GIT_BUF_INIT
,
config_filename
=
GIT_BUF_INIT
,
config_data
=
GIT_BUF_INIT
;
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_SET_OWNER_VALIDATION
,
1
));
cl_fixture_sandbox
(
"empty_standard_repo"
);
cl_git_pass
(
cl_rename
(
"empty_standard_repo/.gitted"
,
"empty_standard_repo/.git"
));
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_OTHER
);
cl_git_fail
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
/* Add safe.directory options to the global configuration */
git_buf_joinpath
(
&
config_path
,
clar_sandbox_path
(),
"__global_config"
);
cl_must_pass
(
p_mkdir
(
config_path
.
ptr
,
0777
));
git_libgit2_opts
(
GIT_OPT_SET_SEARCH_PATH
,
GIT_CONFIG_LEVEL_GLOBAL
,
config_path
.
ptr
);
git_buf_joinpath
(
&
config_filename
,
config_path
.
ptr
,
".gitconfig"
);
git_buf_printf
(
&
config_data
,
"[foo]
\n
"
\
"
\t
bar = Foobar
\n
"
\
"
\t
baz = Baz!
\n
"
\
"[safe]
\n
"
\
"
\t
directory = /non/existent/path
\n
"
\
"
\t
directory = /
\n
"
\
"
\t
directory = c:
\\\\
temp
\n
"
\
"
\t
directory = %s/%s
\n
"
\
"
\t
directory = /tmp
\n
"
\
"[bar]
\n
"
\
"
\t
foo = barfoo
\n
"
,
clar_sandbox_path
(),
"empty_standard_repo"
);
cl_git_rewritefile
(
config_filename
.
ptr
,
config_data
.
ptr
);
cl_git_pass
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
git_repository_free
(
repo
);
git_buf_dispose
(
&
config_path
);
git_buf_dispose
(
&
config_filename
);
git_buf_dispose
(
&
config_data
);
}
void
test_repo_open__can_reset_safe_directory_list
(
void
)
{
git_repository
*
repo
;
git_buf
config_path
=
GIT_BUF_INIT
,
config_filename
=
GIT_BUF_INIT
,
config_data
=
GIT_BUF_INIT
;
cl_git_pass
(
git_libgit2_opts
(
GIT_OPT_SET_OWNER_VALIDATION
,
1
));
cl_fixture_sandbox
(
"empty_standard_repo"
);
cl_git_pass
(
cl_rename
(
"empty_standard_repo/.gitted"
,
"empty_standard_repo/.git"
));
git_path__set_owner
(
GIT_PATH_MOCK_OWNER_OTHER
);
cl_git_fail
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
/* Add safe.directory options to the global configuration */
git_buf_joinpath
(
&
config_path
,
clar_sandbox_path
(),
"__global_config"
);
cl_must_pass
(
p_mkdir
(
config_path
.
ptr
,
0777
));
git_libgit2_opts
(
GIT_OPT_SET_SEARCH_PATH
,
GIT_CONFIG_LEVEL_GLOBAL
,
config_path
.
ptr
);
git_buf_joinpath
(
&
config_filename
,
config_path
.
ptr
,
".gitconfig"
);
/* The blank resets our sandbox directory and opening fails */
git_buf_printf
(
&
config_data
,
"[foo]
\n
"
\
"
\t
bar = Foobar
\n
"
\
"
\t
baz = Baz!
\n
"
\
"[safe]
\n
"
\
"
\t
directory = %s/%s
\n
"
\
"
\t
directory =
\n
"
\
"
\t
directory = /tmp
\n
"
\
"[bar]
\n
"
\
"
\t
foo = barfoo
\n
"
,
clar_sandbox_path
(),
"empty_standard_repo"
);
cl_git_rewritefile
(
config_filename
.
ptr
,
config_data
.
ptr
);
cl_git_fail
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
/* The blank resets tmp and allows subsequent declarations to succeed */
git_buf_clear
(
&
config_data
);
git_buf_printf
(
&
config_data
,
"[foo]
\n
"
\
"
\t
bar = Foobar
\n
"
\
"
\t
baz = Baz!
\n
"
\
"[safe]
\n
"
\
"
\t
directory = /tmp
\n
"
\
"
\t
directory =
\n
"
\
"
\t
directory = %s/%s
\n
"
\
"[bar]
\n
"
\
"
\t
foo = barfoo
\n
"
,
clar_sandbox_path
(),
"empty_standard_repo"
);
cl_git_rewritefile
(
config_filename
.
ptr
,
config_data
.
ptr
);
cl_git_pass
(
git_repository_open
(
&
repo
,
"empty_standard_repo"
));
git_repository_free
(
repo
);
git_buf_dispose
(
&
config_path
);
git_buf_dispose
(
&
config_filename
);
git_buf_dispose
(
&
config_data
);
}
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