rugged 0.23.0b1 → 0.23.0b2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rugged/rugged_note.c +7 -2
- data/ext/rugged/rugged_revwalk.c +321 -145
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +83 -8
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +9 -0
- data/vendor/libgit2/cmake/Modules/FindIconv.cmake +0 -3
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +9 -0
- data/vendor/libgit2/deps/winhttp/urlmon.h +45 -0
- data/vendor/libgit2/deps/winhttp/winhttp.def +29 -0
- data/vendor/libgit2/deps/winhttp/winhttp.h +592 -0
- data/vendor/libgit2/deps/winhttp/winhttp64.def +29 -0
- data/vendor/libgit2/include/git2/diff.h +6 -1
- data/vendor/libgit2/include/git2/index.h +1 -1
- data/vendor/libgit2/include/git2/merge.h +2 -1
- data/vendor/libgit2/include/git2/notes.h +2 -2
- data/vendor/libgit2/include/git2/pack.h +12 -0
- data/vendor/libgit2/include/git2/push.h +30 -0
- data/vendor/libgit2/include/git2/rebase.h +36 -16
- data/vendor/libgit2/include/git2/remote.h +6 -0
- data/vendor/libgit2/include/git2/reset.h +2 -2
- data/vendor/libgit2/include/git2/revwalk.h +10 -8
- data/vendor/libgit2/include/git2/submodule.h +16 -0
- data/vendor/libgit2/include/git2/sys/transport.h +12 -4
- data/vendor/libgit2/include/git2/types.h +1 -0
- data/vendor/libgit2/src/attr.c +3 -3
- data/vendor/libgit2/src/attr_file.c +24 -3
- data/vendor/libgit2/src/attr_file.h +3 -1
- data/vendor/libgit2/src/checkout.c +31 -7
- data/vendor/libgit2/src/config.c +5 -6
- data/vendor/libgit2/src/config_file.c +533 -469
- data/vendor/libgit2/src/describe.c +1 -1
- data/vendor/libgit2/src/diff.c +20 -10
- data/vendor/libgit2/src/diff_driver.c +1 -1
- data/vendor/libgit2/src/diff_tform.c +8 -2
- data/vendor/libgit2/src/filter.c +6 -3
- data/vendor/libgit2/src/global.c +17 -15
- data/vendor/libgit2/src/global.h +3 -1
- data/vendor/libgit2/src/ignore.c +48 -8
- data/vendor/libgit2/src/ignore.h +1 -1
- data/vendor/libgit2/src/index.c +12 -8
- data/vendor/libgit2/src/iterator.c +133 -12
- data/vendor/libgit2/src/netops.h +2 -2
- data/vendor/libgit2/src/notes.c +40 -21
- data/vendor/libgit2/src/openssl_stream.c +5 -1
- data/vendor/libgit2/src/pack-objects.c +36 -0
- data/vendor/libgit2/src/path.c +277 -140
- data/vendor/libgit2/src/path.h +132 -60
- data/vendor/libgit2/src/posix.h +0 -1
- data/vendor/libgit2/src/push.c +43 -4
- data/vendor/libgit2/src/push.h +8 -1
- data/vendor/libgit2/src/rebase.c +139 -119
- data/vendor/libgit2/src/reflog.c +1 -1
- data/vendor/libgit2/src/refs.c +3 -5
- data/vendor/libgit2/src/remote.c +6 -5
- data/vendor/libgit2/src/repository.c +7 -3
- data/vendor/libgit2/src/reset.c +3 -3
- data/vendor/libgit2/src/revwalk.c +26 -2
- data/vendor/libgit2/src/settings.c +3 -3
- data/vendor/libgit2/src/stransport_stream.c +249 -0
- data/vendor/libgit2/src/stransport_stream.h +14 -0
- data/vendor/libgit2/src/submodule.c +26 -2
- data/vendor/libgit2/src/tls_stream.c +28 -0
- data/vendor/libgit2/src/tls_stream.h +21 -0
- data/vendor/libgit2/src/transport.c +4 -4
- data/vendor/libgit2/src/transports/git.c +4 -1
- data/vendor/libgit2/src/transports/http.c +6 -4
- data/vendor/libgit2/src/transports/local.c +2 -1
- data/vendor/libgit2/src/transports/smart.c +1 -1
- data/vendor/libgit2/src/transports/ssh.c +5 -1
- data/vendor/libgit2/src/transports/winhttp.c +30 -23
- data/vendor/libgit2/src/tree.c +2 -2
- data/vendor/libgit2/src/unix/posix.h +1 -0
- data/vendor/libgit2/src/util.h +117 -0
- data/vendor/libgit2/src/win32/buffer.c +55 -0
- data/vendor/libgit2/src/win32/buffer.h +18 -0
- data/vendor/libgit2/src/win32/path_w32.c +75 -0
- data/vendor/libgit2/src/win32/path_w32.h +3 -0
- data/vendor/libgit2/src/win32/posix.h +2 -2
- data/vendor/libgit2/src/win32/posix_w32.c +2 -118
- data/vendor/libgit2/src/win32/pthread.c +2 -0
- data/vendor/libgit2/src/win32/utf-conv.c +0 -4
- data/vendor/libgit2/src/win32/utf-conv.h +4 -0
- data/vendor/libgit2/src/win32/w32_util.h +72 -0
- metadata +14 -2
@@ -17,19 +17,12 @@
|
|
17
17
|
#include "repository.h"
|
18
18
|
|
19
19
|
#include <wincrypt.h>
|
20
|
-
#pragma comment(lib, "crypt32")
|
21
20
|
#include <winhttp.h>
|
22
|
-
#pragma comment(lib, "winhttp")
|
23
|
-
|
24
|
-
#include <strsafe.h>
|
25
21
|
|
26
22
|
/* For IInternetSecurityManager zone check */
|
27
23
|
#include <objbase.h>
|
28
24
|
#include <urlmon.h>
|
29
25
|
|
30
|
-
/* For UuidCreate */
|
31
|
-
#pragma comment(lib, "rpcrt4")
|
32
|
-
|
33
26
|
#define WIDEN2(s) L ## s
|
34
27
|
#define WIDEN(s) WIDEN2(s)
|
35
28
|
|
@@ -43,7 +36,6 @@
|
|
43
36
|
#define WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH 0
|
44
37
|
#endif
|
45
38
|
|
46
|
-
static const char *prefix_http = "http://";
|
47
39
|
static const char *prefix_https = "https://";
|
48
40
|
static const char *upload_pack_service = "upload-pack";
|
49
41
|
static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
|
@@ -59,6 +51,13 @@ static const int no_check_cert_flags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
|
|
59
51
|
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
|
60
52
|
SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
61
53
|
|
54
|
+
#if defined(__MINGW32__)
|
55
|
+
const CLSID CLSID_InternetSecurityManager = { 0x7B8A2D94, 0x0AC9, 0x11D1,
|
56
|
+
{ 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4 } };
|
57
|
+
const IID IID_IInternetSecurityManager = { 0x79EAC9EE, 0xBAF9, 0x11CE,
|
58
|
+
{ 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B } };
|
59
|
+
#endif
|
60
|
+
|
62
61
|
#define OWNING_SUBTRANSPORT(s) ((winhttp_subtransport *)(s)->parent.subtransport)
|
63
62
|
|
64
63
|
typedef enum {
|
@@ -272,7 +271,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
272
271
|
git_buf buf = GIT_BUF_INIT;
|
273
272
|
char *proxy_url = NULL;
|
274
273
|
wchar_t ct[MAX_CONTENT_TYPE_LEN];
|
275
|
-
|
274
|
+
LPCWSTR types[] = { L"*/*", NULL };
|
276
275
|
BOOL peerdist = FALSE;
|
277
276
|
int error = -1;
|
278
277
|
unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
|
@@ -551,8 +550,7 @@ static int winhttp_close_connection(winhttp_subtransport *t)
|
|
551
550
|
}
|
552
551
|
|
553
552
|
static int winhttp_connect(
|
554
|
-
winhttp_subtransport *t
|
555
|
-
const char *url)
|
553
|
+
winhttp_subtransport *t)
|
556
554
|
{
|
557
555
|
wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
|
558
556
|
wchar_t *wide_host;
|
@@ -561,8 +559,6 @@ static int winhttp_connect(
|
|
561
559
|
int default_timeout = TIMEOUT_INFINITE;
|
562
560
|
int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
|
563
561
|
|
564
|
-
GIT_UNUSED(url);
|
565
|
-
|
566
562
|
t->session = NULL;
|
567
563
|
t->connection = NULL;
|
568
564
|
|
@@ -860,7 +856,7 @@ replay:
|
|
860
856
|
|
861
857
|
winhttp_close_connection(t);
|
862
858
|
|
863
|
-
if (winhttp_connect(t
|
859
|
+
if (winhttp_connect(t) < 0)
|
864
860
|
return -1;
|
865
861
|
}
|
866
862
|
|
@@ -963,7 +959,6 @@ static int winhttp_stream_write_single(
|
|
963
959
|
size_t len)
|
964
960
|
{
|
965
961
|
winhttp_stream *s = (winhttp_stream *)stream;
|
966
|
-
winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
|
967
962
|
DWORD bytes_written;
|
968
963
|
int error;
|
969
964
|
|
@@ -998,7 +993,7 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
998
993
|
{
|
999
994
|
UUID uuid;
|
1000
995
|
RPC_STATUS status = UuidCreate(&uuid);
|
1001
|
-
|
996
|
+
int result;
|
1002
997
|
|
1003
998
|
if (RPC_S_OK != status &&
|
1004
999
|
RPC_S_UUID_LOCAL_ONLY != status &&
|
@@ -1012,14 +1007,17 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
1012
1007
|
return -1;
|
1013
1008
|
}
|
1014
1009
|
|
1015
|
-
|
1016
|
-
|
1010
|
+
#if !defined(__MINGW32__) || defined(MINGW_HAS_SECURE_API)
|
1011
|
+
result = swprintf_s(buffer, buffer_len_cch,
|
1012
|
+
#else
|
1013
|
+
result = wsprintfW(buffer,
|
1014
|
+
#endif
|
1017
1015
|
L"%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
|
1018
1016
|
uuid.Data1, uuid.Data2, uuid.Data3,
|
1019
1017
|
uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3],
|
1020
1018
|
uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]);
|
1021
1019
|
|
1022
|
-
if (
|
1020
|
+
if (result < UUID_LENGTH_CCH) {
|
1023
1021
|
giterr_set(GITERR_OS, "Unable to generate name for temp file");
|
1024
1022
|
return -1;
|
1025
1023
|
}
|
@@ -1053,7 +1051,6 @@ static int winhttp_stream_write_buffered(
|
|
1053
1051
|
size_t len)
|
1054
1052
|
{
|
1055
1053
|
winhttp_stream *s = (winhttp_stream *)stream;
|
1056
|
-
winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
|
1057
1054
|
DWORD bytes_written;
|
1058
1055
|
|
1059
1056
|
if (!s->request && winhttp_stream_connect(s) < 0)
|
@@ -1135,7 +1132,7 @@ static int winhttp_stream_write_chunked(
|
|
1135
1132
|
}
|
1136
1133
|
else {
|
1137
1134
|
/* Append as much to the buffer as we can */
|
1138
|
-
int count = min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len,
|
1135
|
+
int count = (int)min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, len);
|
1139
1136
|
|
1140
1137
|
if (!s->chunk_buffer)
|
1141
1138
|
s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
|
@@ -1195,6 +1192,8 @@ static int winhttp_uploadpack_ls(
|
|
1195
1192
|
winhttp_subtransport *t,
|
1196
1193
|
winhttp_stream *s)
|
1197
1194
|
{
|
1195
|
+
GIT_UNUSED(t);
|
1196
|
+
|
1198
1197
|
s->service = upload_pack_service;
|
1199
1198
|
s->service_url = upload_pack_ls_service_url;
|
1200
1199
|
s->verb = get_verb;
|
@@ -1206,6 +1205,8 @@ static int winhttp_uploadpack(
|
|
1206
1205
|
winhttp_subtransport *t,
|
1207
1206
|
winhttp_stream *s)
|
1208
1207
|
{
|
1208
|
+
GIT_UNUSED(t);
|
1209
|
+
|
1209
1210
|
s->service = upload_pack_service;
|
1210
1211
|
s->service_url = upload_pack_service_url;
|
1211
1212
|
s->verb = post_verb;
|
@@ -1217,6 +1218,8 @@ static int winhttp_receivepack_ls(
|
|
1217
1218
|
winhttp_subtransport *t,
|
1218
1219
|
winhttp_stream *s)
|
1219
1220
|
{
|
1221
|
+
GIT_UNUSED(t);
|
1222
|
+
|
1220
1223
|
s->service = receive_pack_service;
|
1221
1224
|
s->service_url = receive_pack_ls_service_url;
|
1222
1225
|
s->verb = get_verb;
|
@@ -1228,6 +1231,8 @@ static int winhttp_receivepack(
|
|
1228
1231
|
winhttp_subtransport *t,
|
1229
1232
|
winhttp_stream *s)
|
1230
1233
|
{
|
1234
|
+
GIT_UNUSED(t);
|
1235
|
+
|
1231
1236
|
/* WinHTTP only supports Transfer-Encoding: chunked
|
1232
1237
|
* on Windows Vista (NT 6.0) and higher. */
|
1233
1238
|
s->chunked = git_has_win32_version(6, 0, 0);
|
@@ -1256,7 +1261,7 @@ static int winhttp_action(
|
|
1256
1261
|
|
1257
1262
|
if (!t->connection)
|
1258
1263
|
if ((ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0 ||
|
1259
|
-
(ret = winhttp_connect(t
|
1264
|
+
(ret = winhttp_connect(t)) < 0)
|
1260
1265
|
return ret;
|
1261
1266
|
|
1262
1267
|
if (winhttp_stream_alloc(t, &s) < 0)
|
@@ -1322,10 +1327,12 @@ static void winhttp_free(git_smart_subtransport *subtransport)
|
|
1322
1327
|
git__free(t);
|
1323
1328
|
}
|
1324
1329
|
|
1325
|
-
int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner)
|
1330
|
+
int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param)
|
1326
1331
|
{
|
1327
1332
|
winhttp_subtransport *t;
|
1328
1333
|
|
1334
|
+
GIT_UNUSED(param);
|
1335
|
+
|
1329
1336
|
if (!out)
|
1330
1337
|
return -1;
|
1331
1338
|
|
data/vendor/libgit2/src/tree.c
CHANGED
@@ -858,7 +858,7 @@ int git_tree_entry_bypath(
|
|
858
858
|
|
859
859
|
if (entry == NULL) {
|
860
860
|
giterr_set(GITERR_TREE,
|
861
|
-
|
861
|
+
"the path '%.*s' does not exist in the given tree", filename_len, path);
|
862
862
|
return GIT_ENOTFOUND;
|
863
863
|
}
|
864
864
|
|
@@ -868,7 +868,7 @@ int git_tree_entry_bypath(
|
|
868
868
|
* then this entry *must* be a tree */
|
869
869
|
if (!git_tree_entry__is_tree(entry)) {
|
870
870
|
giterr_set(GITERR_TREE,
|
871
|
-
|
871
|
+
"the path '%.*s' exists but is not a tree", filename_len, path);
|
872
872
|
return GIT_ENOTFOUND;
|
873
873
|
}
|
874
874
|
|
data/vendor/libgit2/src/util.h
CHANGED
@@ -7,6 +7,36 @@
|
|
7
7
|
#ifndef INCLUDE_util_h__
|
8
8
|
#define INCLUDE_util_h__
|
9
9
|
|
10
|
+
#if defined(GIT_MSVC_CRTDBG)
|
11
|
+
/* Enable MSVC CRTDBG memory leak reporting.
|
12
|
+
*
|
13
|
+
* We DO NOT use the "_CRTDBG_MAP_ALLOC" macro described in the MSVC
|
14
|
+
* documentation because all allocs/frees in libgit2 already go through
|
15
|
+
* the "git__" routines defined in this file. Simply using the normal
|
16
|
+
* reporting mechanism causes all leaks to be attributed to a routine
|
17
|
+
* here in util.h (ie, the actual call to calloc()) rather than the
|
18
|
+
* caller of git__calloc().
|
19
|
+
*
|
20
|
+
* Therefore, we declare a set of "git__crtdbg__" routines to replace
|
21
|
+
* the corresponding "git__" routines and re-define the "git__" symbols
|
22
|
+
* as macros. This allows us to get and report the file:line info of
|
23
|
+
* the real caller.
|
24
|
+
*
|
25
|
+
* We DO NOT replace the "git__free" routine because it needs to remain
|
26
|
+
* a function pointer because it is used as a function argument when
|
27
|
+
* setting up various structure "destructors".
|
28
|
+
*
|
29
|
+
* We also DO NOT use the "_CRTDBG_MAP_ALLOC" macro because it causes
|
30
|
+
* "free" to be remapped to "_free_dbg" and this causes problems for
|
31
|
+
* structures which define a field named "free".
|
32
|
+
*
|
33
|
+
* Finally, CRTDBG must be explicitly enabled and configured at program
|
34
|
+
* startup. See tests/main.c for an example.
|
35
|
+
*/
|
36
|
+
#include <stdlib.h>
|
37
|
+
#include <crtdbg.h>
|
38
|
+
#endif
|
39
|
+
|
10
40
|
#include "common.h"
|
11
41
|
#include "strnlen.h"
|
12
42
|
|
@@ -31,6 +61,91 @@
|
|
31
61
|
*/
|
32
62
|
#define CONST_STRLEN(x) ((sizeof(x)/sizeof(x[0])) - 1)
|
33
63
|
|
64
|
+
#if defined(GIT_MSVC_CRTDBG)
|
65
|
+
GIT_INLINE(void *) git__crtdbg__malloc(size_t len, const char *file, int line)
|
66
|
+
{
|
67
|
+
void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, file, line);
|
68
|
+
if (!ptr) giterr_set_oom();
|
69
|
+
return ptr;
|
70
|
+
}
|
71
|
+
|
72
|
+
GIT_INLINE(void *) git__crtdbg__calloc(size_t nelem, size_t elsize, const char *file, int line)
|
73
|
+
{
|
74
|
+
void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, file, line);
|
75
|
+
if (!ptr) giterr_set_oom();
|
76
|
+
return ptr;
|
77
|
+
}
|
78
|
+
|
79
|
+
GIT_INLINE(char *) git__crtdbg__strdup(const char *str, const char *file, int line)
|
80
|
+
{
|
81
|
+
char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, file, line);
|
82
|
+
if (!ptr) giterr_set_oom();
|
83
|
+
return ptr;
|
84
|
+
}
|
85
|
+
|
86
|
+
GIT_INLINE(char *) git__crtdbg__strndup(const char *str, size_t n, const char *file, int line)
|
87
|
+
{
|
88
|
+
size_t length = 0, alloclength;
|
89
|
+
char *ptr;
|
90
|
+
|
91
|
+
length = p_strnlen(str, n);
|
92
|
+
|
93
|
+
if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
|
94
|
+
!(ptr = git__crtdbg__malloc(alloclength, file, line)))
|
95
|
+
return NULL;
|
96
|
+
|
97
|
+
if (length)
|
98
|
+
memcpy(ptr, str, length);
|
99
|
+
|
100
|
+
ptr[length] = '\0';
|
101
|
+
|
102
|
+
return ptr;
|
103
|
+
}
|
104
|
+
|
105
|
+
GIT_INLINE(char *) git__crtdbg__substrdup(const char *start, size_t n, const char *file, int line)
|
106
|
+
{
|
107
|
+
char *ptr;
|
108
|
+
size_t alloclen;
|
109
|
+
|
110
|
+
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
|
111
|
+
!(ptr = git__crtdbg__malloc(alloclen, file, line)))
|
112
|
+
return NULL;
|
113
|
+
|
114
|
+
memcpy(ptr, start, n);
|
115
|
+
ptr[n] = '\0';
|
116
|
+
return ptr;
|
117
|
+
}
|
118
|
+
|
119
|
+
GIT_INLINE(void *) git__crtdbg__realloc(void *ptr, size_t size, const char *file, int line)
|
120
|
+
{
|
121
|
+
void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, file, line);
|
122
|
+
if (!new_ptr) giterr_set_oom();
|
123
|
+
return new_ptr;
|
124
|
+
}
|
125
|
+
|
126
|
+
GIT_INLINE(void *) git__crtdbg__reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line)
|
127
|
+
{
|
128
|
+
size_t newsize;
|
129
|
+
return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
|
130
|
+
NULL : _realloc_dbg(ptr, newsize, _NORMAL_BLOCK, file, line);
|
131
|
+
}
|
132
|
+
|
133
|
+
GIT_INLINE(void *) git__crtdbg__mallocarray(size_t nelem, size_t elsize, const char *file, int line)
|
134
|
+
{
|
135
|
+
return git__crtdbg__reallocarray(NULL, nelem, elsize, file, line);
|
136
|
+
}
|
137
|
+
|
138
|
+
#define git__malloc(len) git__crtdbg__malloc(len, __FILE__, __LINE__)
|
139
|
+
#define git__calloc(nelem, elsize) git__crtdbg__calloc(nelem, elsize, __FILE__, __LINE__)
|
140
|
+
#define git__strdup(str) git__crtdbg__strdup(str, __FILE__, __LINE__)
|
141
|
+
#define git__strndup(str, n) git__crtdbg__strndup(str, n, __FILE__, __LINE__)
|
142
|
+
#define git__substrdup(str, n) git__crtdbg__substrdup(str, n, __FILE__, __LINE__)
|
143
|
+
#define git__realloc(ptr, size) git__crtdbg__realloc(ptr, size, __FILE__, __LINE__)
|
144
|
+
#define git__reallocarray(ptr, nelem, elsize) git__crtdbg__reallocarray(ptr, nelem, elsize, __FILE__, __LINE__)
|
145
|
+
#define git__mallocarray(nelem, elsize) git__crtdbg__mallocarray(nelem, elsize, __FILE__, __LINE__)
|
146
|
+
|
147
|
+
#else
|
148
|
+
|
34
149
|
/*
|
35
150
|
* Custom memory allocation wrappers
|
36
151
|
* that set error code and error message
|
@@ -118,6 +233,8 @@ GIT_INLINE(void *) git__mallocarray(size_t nelem, size_t elsize)
|
|
118
233
|
return git__reallocarray(NULL, nelem, elsize);
|
119
234
|
}
|
120
235
|
|
236
|
+
#endif /* !MSVC_CTRDBG */
|
237
|
+
|
121
238
|
GIT_INLINE(void) git__free(void *ptr)
|
122
239
|
{
|
123
240
|
free(ptr);
|
@@ -0,0 +1,55 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "common.h"
|
9
|
+
#include "buffer.h"
|
10
|
+
#include "../buffer.h"
|
11
|
+
#include "utf-conv.h"
|
12
|
+
|
13
|
+
GIT_INLINE(int) handle_wc_error(void)
|
14
|
+
{
|
15
|
+
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
16
|
+
errno = ENAMETOOLONG;
|
17
|
+
else
|
18
|
+
errno = EINVAL;
|
19
|
+
|
20
|
+
return -1;
|
21
|
+
}
|
22
|
+
|
23
|
+
int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w)
|
24
|
+
{
|
25
|
+
int utf8_len, utf8_write_len;
|
26
|
+
size_t new_size;
|
27
|
+
|
28
|
+
if (!len_w)
|
29
|
+
return 0;
|
30
|
+
|
31
|
+
assert(string_w);
|
32
|
+
|
33
|
+
/* Measure the string necessary for conversion */
|
34
|
+
if ((utf8_len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, string_w, len_w, NULL, 0, NULL, NULL)) == 0)
|
35
|
+
return 0;
|
36
|
+
|
37
|
+
assert(utf8_len > 0);
|
38
|
+
|
39
|
+
GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, (size_t)utf8_len);
|
40
|
+
GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
|
41
|
+
|
42
|
+
if (git_buf_grow(buf, new_size) < 0)
|
43
|
+
return -1;
|
44
|
+
|
45
|
+
if ((utf8_write_len = WideCharToMultiByte(
|
46
|
+
CP_UTF8, WC_ERR_INVALID_CHARS, string_w, len_w, &buf->ptr[buf->size], utf8_len, NULL, NULL)) == 0)
|
47
|
+
return handle_wc_error();
|
48
|
+
|
49
|
+
assert(utf8_write_len == utf8_len);
|
50
|
+
|
51
|
+
buf->size += utf8_write_len;
|
52
|
+
buf->ptr[buf->size] = '\0';
|
53
|
+
return 0;
|
54
|
+
}
|
55
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
6
|
+
*/
|
7
|
+
#ifndef INCLUDE_git_win32_buffer_h__
|
8
|
+
#define INCLUDE_git_win32_buffer_h__
|
9
|
+
|
10
|
+
#include "../buffer.h"
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Convert a wide character string to UTF-8 and append the results to the
|
14
|
+
* buffer.
|
15
|
+
*/
|
16
|
+
int git_buf_put_w(git_buf *buf, const wchar_t *string_w, size_t len_w);
|
17
|
+
|
18
|
+
#endif
|
@@ -9,6 +9,9 @@
|
|
9
9
|
#include "path.h"
|
10
10
|
#include "path_w32.h"
|
11
11
|
#include "utf-conv.h"
|
12
|
+
#include "posix.h"
|
13
|
+
#include "reparse.h"
|
14
|
+
#include "dir.h"
|
12
15
|
|
13
16
|
#define PATH__NT_NAMESPACE L"\\\\?\\"
|
14
17
|
#define PATH__NT_NAMESPACE_LEN 4
|
@@ -303,3 +306,75 @@ char *git_win32_path_8dot3_name(const char *path)
|
|
303
306
|
|
304
307
|
return shortname;
|
305
308
|
}
|
309
|
+
|
310
|
+
static bool path_is_volume(wchar_t *target, size_t target_len)
|
311
|
+
{
|
312
|
+
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
|
313
|
+
}
|
314
|
+
|
315
|
+
/* On success, returns the length, in characters, of the path stored in dest.
|
316
|
+
* On failure, returns a negative value. */
|
317
|
+
int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path)
|
318
|
+
{
|
319
|
+
BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
320
|
+
GIT_REPARSE_DATA_BUFFER *reparse_buf = (GIT_REPARSE_DATA_BUFFER *)buf;
|
321
|
+
HANDLE handle = NULL;
|
322
|
+
DWORD ioctl_ret;
|
323
|
+
wchar_t *target;
|
324
|
+
size_t target_len;
|
325
|
+
|
326
|
+
int error = -1;
|
327
|
+
|
328
|
+
handle = CreateFileW(path, GENERIC_READ,
|
329
|
+
FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
330
|
+
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
331
|
+
|
332
|
+
if (handle == INVALID_HANDLE_VALUE) {
|
333
|
+
errno = ENOENT;
|
334
|
+
return -1;
|
335
|
+
}
|
336
|
+
|
337
|
+
if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
|
338
|
+
reparse_buf, sizeof(buf), &ioctl_ret, NULL)) {
|
339
|
+
errno = EINVAL;
|
340
|
+
goto on_error;
|
341
|
+
}
|
342
|
+
|
343
|
+
switch (reparse_buf->ReparseTag) {
|
344
|
+
case IO_REPARSE_TAG_SYMLINK:
|
345
|
+
target = reparse_buf->SymbolicLinkReparseBuffer.PathBuffer +
|
346
|
+
(reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
|
347
|
+
target_len = reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
348
|
+
break;
|
349
|
+
case IO_REPARSE_TAG_MOUNT_POINT:
|
350
|
+
target = reparse_buf->MountPointReparseBuffer.PathBuffer +
|
351
|
+
(reparse_buf->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
|
352
|
+
target_len = reparse_buf->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
353
|
+
break;
|
354
|
+
default:
|
355
|
+
errno = EINVAL;
|
356
|
+
goto on_error;
|
357
|
+
}
|
358
|
+
|
359
|
+
if (path_is_volume(target, target_len)) {
|
360
|
+
/* This path is a reparse point that represents another volume mounted
|
361
|
+
* at this location, it is not a symbolic link our input was canonical.
|
362
|
+
*/
|
363
|
+
errno = EINVAL;
|
364
|
+
error = -1;
|
365
|
+
} else if (target_len) {
|
366
|
+
/* The path may need to have a prefix removed. */
|
367
|
+
target_len = git_win32__canonicalize_path(target, target_len);
|
368
|
+
|
369
|
+
/* Need one additional character in the target buffer
|
370
|
+
* for the terminating NULL. */
|
371
|
+
if (GIT_WIN_PATH_UTF16 > target_len) {
|
372
|
+
wcscpy(dest, target);
|
373
|
+
error = (int)target_len;
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
377
|
+
on_error:
|
378
|
+
CloseHandle(handle);
|
379
|
+
return error;
|
380
|
+
}
|
@@ -8,6 +8,7 @@
|
|
8
8
|
#define INCLUDE_git_path_w32_h__
|
9
9
|
|
10
10
|
#include "common.h"
|
11
|
+
#include "vector.h"
|
11
12
|
|
12
13
|
/*
|
13
14
|
* Provides a large enough buffer to support Windows paths: MAX_PATH is
|
@@ -79,4 +80,6 @@ extern int git_win32_path_to_utf8(git_win32_utf8_path dest, const wchar_t *src);
|
|
79
80
|
*/
|
80
81
|
extern char *git_win32_path_8dot3_name(const char *path);
|
81
82
|
|
83
|
+
extern int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path);
|
84
|
+
|
82
85
|
#endif
|
@@ -49,7 +49,7 @@ extern int p_ftruncate(int fd, git_off_t size);
|
|
49
49
|
*/
|
50
50
|
extern int p_lstat_posixly(const char *filename, struct stat *buf);
|
51
51
|
|
52
|
-
extern struct tm * p_localtime_r
|
53
|
-
extern struct tm * p_gmtime_r
|
52
|
+
extern struct tm * p_localtime_r(const time_t *timer, struct tm *result);
|
53
|
+
extern struct tm * p_gmtime_r(const time_t *timer, struct tm *result);
|
54
54
|
|
55
55
|
#endif
|
@@ -130,88 +130,6 @@ int p_fsync(int fd)
|
|
130
130
|
return 0;
|
131
131
|
}
|
132
132
|
|
133
|
-
GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
|
134
|
-
{
|
135
|
-
long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
|
136
|
-
winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
|
137
|
-
winTime /= 10000000; /* Nano to seconds resolution */
|
138
|
-
return (time_t)winTime;
|
139
|
-
}
|
140
|
-
|
141
|
-
static bool path_is_volume(wchar_t *target, size_t target_len)
|
142
|
-
{
|
143
|
-
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
|
144
|
-
}
|
145
|
-
|
146
|
-
/* On success, returns the length, in characters, of the path stored in dest.
|
147
|
-
* On failure, returns a negative value. */
|
148
|
-
static int readlink_w(
|
149
|
-
git_win32_path dest,
|
150
|
-
const git_win32_path path)
|
151
|
-
{
|
152
|
-
BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
153
|
-
GIT_REPARSE_DATA_BUFFER *reparse_buf = (GIT_REPARSE_DATA_BUFFER *)buf;
|
154
|
-
HANDLE handle = NULL;
|
155
|
-
DWORD ioctl_ret;
|
156
|
-
wchar_t *target;
|
157
|
-
size_t target_len;
|
158
|
-
|
159
|
-
int error = -1;
|
160
|
-
|
161
|
-
handle = CreateFileW(path, GENERIC_READ,
|
162
|
-
FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
|
163
|
-
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
164
|
-
|
165
|
-
if (handle == INVALID_HANDLE_VALUE) {
|
166
|
-
errno = ENOENT;
|
167
|
-
return -1;
|
168
|
-
}
|
169
|
-
|
170
|
-
if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
|
171
|
-
reparse_buf, sizeof(buf), &ioctl_ret, NULL)) {
|
172
|
-
errno = EINVAL;
|
173
|
-
goto on_error;
|
174
|
-
}
|
175
|
-
|
176
|
-
switch (reparse_buf->ReparseTag) {
|
177
|
-
case IO_REPARSE_TAG_SYMLINK:
|
178
|
-
target = reparse_buf->SymbolicLinkReparseBuffer.PathBuffer +
|
179
|
-
(reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
|
180
|
-
target_len = reparse_buf->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
181
|
-
break;
|
182
|
-
case IO_REPARSE_TAG_MOUNT_POINT:
|
183
|
-
target = reparse_buf->MountPointReparseBuffer.PathBuffer +
|
184
|
-
(reparse_buf->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
|
185
|
-
target_len = reparse_buf->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
|
186
|
-
break;
|
187
|
-
default:
|
188
|
-
errno = EINVAL;
|
189
|
-
goto on_error;
|
190
|
-
}
|
191
|
-
|
192
|
-
if (path_is_volume(target, target_len)) {
|
193
|
-
/* This path is a reparse point that represents another volume mounted
|
194
|
-
* at this location, it is not a symbolic link our input was canonical.
|
195
|
-
*/
|
196
|
-
errno = EINVAL;
|
197
|
-
error = -1;
|
198
|
-
} else if (target_len) {
|
199
|
-
/* The path may need to have a prefix removed. */
|
200
|
-
target_len = git_win32__canonicalize_path(target, target_len);
|
201
|
-
|
202
|
-
/* Need one additional character in the target buffer
|
203
|
-
* for the terminating NULL. */
|
204
|
-
if (GIT_WIN_PATH_UTF16 > target_len) {
|
205
|
-
wcscpy(dest, target);
|
206
|
-
error = (int)target_len;
|
207
|
-
}
|
208
|
-
}
|
209
|
-
|
210
|
-
on_error:
|
211
|
-
CloseHandle(handle);
|
212
|
-
return error;
|
213
|
-
}
|
214
|
-
|
215
133
|
#define WIN32_IS_WSEP(CH) ((CH) == L'/' || (CH) == L'\\')
|
216
134
|
|
217
135
|
static int lstat_w(
|
@@ -222,44 +140,10 @@ static int lstat_w(
|
|
222
140
|
WIN32_FILE_ATTRIBUTE_DATA fdata;
|
223
141
|
|
224
142
|
if (GetFileAttributesExW(path, GetFileExInfoStandard, &fdata)) {
|
225
|
-
int fMode = S_IREAD;
|
226
|
-
|
227
143
|
if (!buf)
|
228
144
|
return 0;
|
229
145
|
|
230
|
-
|
231
|
-
fMode |= S_IFDIR;
|
232
|
-
else
|
233
|
-
fMode |= S_IFREG;
|
234
|
-
|
235
|
-
if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
236
|
-
fMode |= S_IWRITE;
|
237
|
-
|
238
|
-
buf->st_ino = 0;
|
239
|
-
buf->st_gid = 0;
|
240
|
-
buf->st_uid = 0;
|
241
|
-
buf->st_nlink = 1;
|
242
|
-
buf->st_mode = (mode_t)fMode;
|
243
|
-
buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
|
244
|
-
buf->st_dev = buf->st_rdev = (_getdrive() - 1);
|
245
|
-
buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
|
246
|
-
buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
|
247
|
-
buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
|
248
|
-
|
249
|
-
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
250
|
-
git_win32_path target;
|
251
|
-
|
252
|
-
if (readlink_w(target, path) >= 0) {
|
253
|
-
buf->st_mode = (buf->st_mode & ~S_IFMT) | S_IFLNK;
|
254
|
-
|
255
|
-
/* st_size gets the UTF-8 length of the target name, in bytes,
|
256
|
-
* not counting the NULL terminator */
|
257
|
-
if ((buf->st_size = git__utf16_to_8(NULL, 0, target)) < 0)
|
258
|
-
return -1;
|
259
|
-
}
|
260
|
-
}
|
261
|
-
|
262
|
-
return 0;
|
146
|
+
return git_win32__file_attribute_to_stat(buf, &fdata, path);
|
263
147
|
}
|
264
148
|
|
265
149
|
errno = ENOENT;
|
@@ -331,7 +215,7 @@ int p_readlink(const char *path, char *buf, size_t bufsiz)
|
|
331
215
|
* we need to buffer the result on the stack. */
|
332
216
|
|
333
217
|
if (git_win32_path_from_utf8(path_w, path) < 0 ||
|
334
|
-
|
218
|
+
git_win32_path_readlink_w(target_w, path_w) < 0 ||
|
335
219
|
(len = git_win32_path_to_utf8(target, target_w)) < 0)
|
336
220
|
return -1;
|
337
221
|
|