rugged 0.22.0b4 → 0.22.0b5
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.c +8 -7
- data/ext/rugged/rugged_note.c +1 -1
- data/ext/rugged/rugged_remote.c +0 -5
- data/ext/rugged/rugged_tree.c +23 -25
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/include/git2/blame.h +0 -1
- data/vendor/libgit2/include/git2/branch.h +1 -1
- data/vendor/libgit2/include/git2/buffer.h +1 -1
- data/vendor/libgit2/include/git2/cherrypick.h +5 -2
- data/vendor/libgit2/include/git2/clone.h +0 -1
- data/vendor/libgit2/include/git2/common.h +6 -1
- data/vendor/libgit2/include/git2/config.h +13 -4
- data/vendor/libgit2/include/git2/filter.h +3 -0
- data/vendor/libgit2/include/git2/global.h +10 -4
- data/vendor/libgit2/include/git2/index.h +3 -0
- data/vendor/libgit2/include/git2/merge.h +20 -5
- data/vendor/libgit2/include/git2/net.h +3 -2
- data/vendor/libgit2/include/git2/notes.h +5 -7
- data/vendor/libgit2/include/git2/push.h +7 -14
- data/vendor/libgit2/include/git2/rebase.h +14 -1
- data/vendor/libgit2/include/git2/refs.h +7 -1
- data/vendor/libgit2/include/git2/remote.h +6 -1
- data/vendor/libgit2/include/git2/repository.h +6 -0
- data/vendor/libgit2/include/git2/revert.h +5 -2
- data/vendor/libgit2/include/git2/stash.h +15 -6
- data/vendor/libgit2/include/git2/submodule.h +1 -1
- data/vendor/libgit2/include/git2/sys/diff.h +5 -2
- data/vendor/libgit2/include/git2/sys/hashsig.h +3 -0
- data/vendor/libgit2/include/git2/sys/mempack.h +1 -1
- data/vendor/libgit2/include/git2/sys/stream.h +40 -0
- data/vendor/libgit2/include/git2/sys/transport.h +17 -4
- data/vendor/libgit2/include/git2/tree.h +3 -3
- data/vendor/libgit2/src/checkout.c +27 -1
- data/vendor/libgit2/src/commit_list.c +1 -1
- data/vendor/libgit2/src/common.h +1 -1
- data/vendor/libgit2/src/config_cache.c +2 -0
- data/vendor/libgit2/src/config_file.c +1 -1
- data/vendor/libgit2/src/describe.c +2 -2
- data/vendor/libgit2/src/global.c +31 -14
- data/vendor/libgit2/src/ignore.c +86 -3
- data/vendor/libgit2/src/index.c +48 -25
- data/vendor/libgit2/src/indexer.c +1 -0
- data/vendor/libgit2/src/netops.c +18 -474
- data/vendor/libgit2/src/netops.h +3 -8
- data/vendor/libgit2/src/notes.c +3 -3
- data/vendor/libgit2/src/odb.c +1 -0
- data/vendor/libgit2/src/odb_loose.c +1 -1
- data/vendor/libgit2/src/openssl_stream.c +375 -0
- data/vendor/libgit2/src/openssl_stream.h +14 -0
- data/vendor/libgit2/src/path.c +256 -0
- data/vendor/libgit2/src/path.h +44 -1
- data/vendor/libgit2/src/pool.c +1 -1
- data/vendor/libgit2/src/push.c +5 -5
- data/vendor/libgit2/src/rebase.c +2 -2
- data/vendor/libgit2/src/refdb_fs.c +11 -1
- data/vendor/libgit2/src/remote.c +2 -7
- data/vendor/libgit2/src/repository.c +25 -0
- data/vendor/libgit2/src/repository.h +26 -2
- data/vendor/libgit2/src/socket_stream.c +212 -0
- data/vendor/libgit2/src/socket_stream.h +21 -0
- data/vendor/libgit2/src/stream.h +48 -0
- data/vendor/libgit2/src/tag.c +1 -1
- data/vendor/libgit2/src/transports/git.c +71 -57
- data/vendor/libgit2/src/transports/http.c +40 -62
- data/vendor/libgit2/src/transports/local.c +6 -11
- data/vendor/libgit2/src/transports/smart.c +3 -3
- data/vendor/libgit2/src/transports/ssh.c +12 -8
- data/vendor/libgit2/src/transports/winhttp.c +68 -47
- data/vendor/libgit2/src/tree.c +16 -14
- data/vendor/libgit2/src/tree.h +1 -0
- data/vendor/libgit2/src/util.c +91 -0
- data/vendor/libgit2/src/util.h +12 -0
- data/vendor/libgit2/src/win32/findfile.c +1 -0
- data/vendor/libgit2/src/win32/path_w32.c +305 -0
- data/vendor/libgit2/src/win32/path_w32.h +80 -0
- data/vendor/libgit2/src/win32/posix.h +1 -0
- data/vendor/libgit2/src/win32/posix_w32.c +25 -42
- data/vendor/libgit2/src/win32/utf-conv.c +36 -6
- data/vendor/libgit2/src/win32/utf-conv.h +0 -39
- data/vendor/libgit2/src/win32/w32_util.h +1 -0
- data/vendor/libgit2/src/xdiff/xdiffi.c +1 -1
- data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
- metadata +10 -2
data/vendor/libgit2/src/global.c
CHANGED
@@ -131,6 +131,7 @@ int git_openssl_set_locking(void)
|
|
131
131
|
giterr_set(GITERR_THREAD, "libgit2 as not built with threads");
|
132
132
|
return -1;
|
133
133
|
# endif
|
134
|
+
#else
|
134
135
|
giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support");
|
135
136
|
return -1;
|
136
137
|
#endif
|
@@ -194,19 +195,21 @@ static int synchronized_threads_init(void)
|
|
194
195
|
|
195
196
|
int git_libgit2_init(void)
|
196
197
|
{
|
197
|
-
int
|
198
|
+
int ret;
|
198
199
|
|
199
200
|
/* Enter the lock */
|
200
201
|
while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
|
201
202
|
|
202
203
|
/* Only do work on a 0 -> 1 transition of the refcount */
|
203
|
-
if (
|
204
|
-
|
204
|
+
if ((ret = git_atomic_inc(&git__n_inits)) == 1) {
|
205
|
+
if (synchronized_threads_init() < 0)
|
206
|
+
ret = -1;
|
207
|
+
}
|
205
208
|
|
206
209
|
/* Exit the lock */
|
207
210
|
InterlockedExchange(&_mutex, 0);
|
208
211
|
|
209
|
-
return
|
212
|
+
return ret;
|
210
213
|
}
|
211
214
|
|
212
215
|
static void synchronized_threads_shutdown(void)
|
@@ -217,17 +220,21 @@ static void synchronized_threads_shutdown(void)
|
|
217
220
|
git_mutex_free(&git__mwindow_mutex);
|
218
221
|
}
|
219
222
|
|
220
|
-
|
223
|
+
int git_libgit2_shutdown(void)
|
221
224
|
{
|
225
|
+
int ret;
|
226
|
+
|
222
227
|
/* Enter the lock */
|
223
228
|
while (InterlockedCompareExchange(&_mutex, 1, 0)) { Sleep(0); }
|
224
229
|
|
225
230
|
/* Only do work on a 1 -> 0 transition of the refcount */
|
226
|
-
if (
|
231
|
+
if ((ret = git_atomic_dec(&git__n_inits)) == 0)
|
227
232
|
synchronized_threads_shutdown();
|
228
233
|
|
229
234
|
/* Exit the lock */
|
230
235
|
InterlockedExchange(&_mutex, 0);
|
236
|
+
|
237
|
+
return ret;
|
231
238
|
}
|
232
239
|
|
233
240
|
git_global_st *git__global_state(void)
|
@@ -281,17 +288,22 @@ static void init_once(void)
|
|
281
288
|
|
282
289
|
int git_libgit2_init(void)
|
283
290
|
{
|
291
|
+
int ret;
|
292
|
+
|
284
293
|
pthread_once(&_once_init, init_once);
|
285
|
-
git_atomic_inc(&git__n_inits);
|
286
|
-
|
294
|
+
ret = git_atomic_inc(&git__n_inits);
|
295
|
+
|
296
|
+
return init_error ? init_error : ret;
|
287
297
|
}
|
288
298
|
|
289
|
-
|
299
|
+
int git_libgit2_shutdown(void)
|
290
300
|
{
|
291
301
|
void *ptr = NULL;
|
292
302
|
pthread_once_t new_once = PTHREAD_ONCE_INIT;
|
303
|
+
int ret;
|
293
304
|
|
294
|
-
if (git_atomic_dec(&git__n_inits) > 0)
|
305
|
+
if ((ret = git_atomic_dec(&git__n_inits)) > 0)
|
306
|
+
return ret;
|
295
307
|
|
296
308
|
/* Shut down any subsystems that have global state */
|
297
309
|
git__shutdown();
|
@@ -303,6 +315,8 @@ void git_libgit2_shutdown(void)
|
|
303
315
|
pthread_key_delete(_tls_key);
|
304
316
|
git_mutex_free(&git__mwindow_mutex);
|
305
317
|
_once_init = new_once;
|
318
|
+
|
319
|
+
return ret;
|
306
320
|
}
|
307
321
|
|
308
322
|
git_global_st *git__global_state(void)
|
@@ -336,15 +350,18 @@ int git_libgit2_init(void)
|
|
336
350
|
ssl_inited = 1;
|
337
351
|
}
|
338
352
|
|
339
|
-
git_atomic_inc(&git__n_inits);
|
340
|
-
return 0;
|
353
|
+
return git_atomic_inc(&git__n_inits);
|
341
354
|
}
|
342
355
|
|
343
|
-
|
356
|
+
int git_libgit2_shutdown(void)
|
344
357
|
{
|
358
|
+
int ret;
|
359
|
+
|
345
360
|
/* Shut down any subsystems that have global state */
|
346
|
-
if (
|
361
|
+
if (ret = git_atomic_dec(&git__n_inits))
|
347
362
|
git__shutdown();
|
363
|
+
|
364
|
+
return ret;
|
348
365
|
}
|
349
366
|
|
350
367
|
git_global_st *git__global_state(void)
|
data/vendor/libgit2/src/ignore.c
CHANGED
@@ -4,11 +4,87 @@
|
|
4
4
|
#include "attrcache.h"
|
5
5
|
#include "path.h"
|
6
6
|
#include "config.h"
|
7
|
+
#include "fnmatch.h"
|
7
8
|
|
8
9
|
#define GIT_IGNORE_INTERNAL "[internal]exclude"
|
9
10
|
|
10
11
|
#define GIT_IGNORE_DEFAULT_RULES ".\n..\n.git\n"
|
11
12
|
|
13
|
+
/**
|
14
|
+
* A negative ignore can only unignore a file which is given explicitly before, thus
|
15
|
+
*
|
16
|
+
* foo
|
17
|
+
* !foo/bar
|
18
|
+
*
|
19
|
+
* does not unignore 'foo/bar' as it's not in the list. However
|
20
|
+
*
|
21
|
+
* foo/<star>
|
22
|
+
* !foo/bar
|
23
|
+
*
|
24
|
+
* does unignore 'foo/bar', as it is contained within the 'foo/<star>' rule.
|
25
|
+
*/
|
26
|
+
static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match)
|
27
|
+
{
|
28
|
+
int error = 0;
|
29
|
+
size_t i;
|
30
|
+
git_attr_fnmatch *rule;
|
31
|
+
char *path;
|
32
|
+
git_buf buf = GIT_BUF_INIT;
|
33
|
+
|
34
|
+
/* path of the file relative to the workdir, so we match the rules in subdirs */
|
35
|
+
if (match->containing_dir) {
|
36
|
+
git_buf_puts(&buf, match->containing_dir);
|
37
|
+
}
|
38
|
+
if (git_buf_puts(&buf, match->pattern) < 0)
|
39
|
+
return -1;
|
40
|
+
|
41
|
+
path = git_buf_detach(&buf);
|
42
|
+
|
43
|
+
git_vector_foreach(rules, i, rule) {
|
44
|
+
/* no chance of matching w/o a wilcard */
|
45
|
+
if (!(rule->flags & GIT_ATTR_FNMATCH_HASWILD))
|
46
|
+
continue;
|
47
|
+
|
48
|
+
/*
|
49
|
+
* If we're dealing with a directory (which we know via the
|
50
|
+
* strchr() check) we want to use 'dirname/<star>' as the
|
51
|
+
* pattern so p_fnmatch() honours FNM_PATHNAME
|
52
|
+
*/
|
53
|
+
git_buf_clear(&buf);
|
54
|
+
if (rule->containing_dir) {
|
55
|
+
git_buf_puts(&buf, rule->containing_dir);
|
56
|
+
}
|
57
|
+
if (!strchr(rule->pattern, '*'))
|
58
|
+
error = git_buf_printf(&buf, "%s/*", rule->pattern);
|
59
|
+
else
|
60
|
+
error = git_buf_puts(&buf, rule->pattern);
|
61
|
+
|
62
|
+
if (error < 0)
|
63
|
+
goto out;
|
64
|
+
|
65
|
+
|
66
|
+
if ((error = p_fnmatch(git_buf_cstr(&buf), path, FNM_PATHNAME)) < 0) {
|
67
|
+
giterr_set(GITERR_INVALID, "error matching pattern");
|
68
|
+
goto out;
|
69
|
+
}
|
70
|
+
|
71
|
+
/* if we found a match, we want to keep this rule */
|
72
|
+
if (error != FNM_NOMATCH) {
|
73
|
+
*out = 1;
|
74
|
+
error = 0;
|
75
|
+
goto out;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
*out = 0;
|
80
|
+
error = 0;
|
81
|
+
|
82
|
+
out:
|
83
|
+
git__free(path);
|
84
|
+
git_buf_free(&buf);
|
85
|
+
return error;
|
86
|
+
}
|
87
|
+
|
12
88
|
static int parse_ignore_file(
|
13
89
|
git_repository *repo, git_attr_file *attrs, const char *data)
|
14
90
|
{
|
@@ -32,6 +108,8 @@ static int parse_ignore_file(
|
|
32
108
|
}
|
33
109
|
|
34
110
|
while (!error && *scan) {
|
111
|
+
int valid_rule = 1;
|
112
|
+
|
35
113
|
if (!match && !(match = git__calloc(1, sizeof(*match)))) {
|
36
114
|
error = -1;
|
37
115
|
break;
|
@@ -48,11 +126,16 @@ static int parse_ignore_file(
|
|
48
126
|
match->flags |= GIT_ATTR_FNMATCH_ICASE;
|
49
127
|
|
50
128
|
scan = git__next_line(scan);
|
51
|
-
|
129
|
+
|
130
|
+
/* if a negative match doesn't actually do anything, throw it away */
|
131
|
+
if (match->flags & GIT_ATTR_FNMATCH_NEGATIVE)
|
132
|
+
error = does_negate_rule(&valid_rule, &attrs->rules, match);
|
133
|
+
|
134
|
+
if (!error && valid_rule)
|
135
|
+
error = git_vector_insert(&attrs->rules, match);
|
52
136
|
}
|
53
137
|
|
54
|
-
if (error != 0) {
|
55
|
-
git__free(match->pattern);
|
138
|
+
if (error != 0 || !valid_rule) {
|
56
139
|
match->pattern = NULL;
|
57
140
|
|
58
141
|
if (error == GIT_ENOTFOUND)
|
data/vendor/libgit2/src/index.c
CHANGED
@@ -762,23 +762,35 @@ void git_index_entry__init_from_stat(
|
|
762
762
|
entry->file_size = st->st_size;
|
763
763
|
}
|
764
764
|
|
765
|
-
static
|
765
|
+
static int index_entry_create(
|
766
|
+
git_index_entry **out,
|
767
|
+
git_repository *repo,
|
768
|
+
const char *path)
|
766
769
|
{
|
767
770
|
size_t pathlen = strlen(path);
|
768
|
-
struct entry_internal *entry
|
769
|
-
|
770
|
-
if (!
|
771
|
-
|
771
|
+
struct entry_internal *entry;
|
772
|
+
|
773
|
+
if (!git_path_isvalid(repo, path,
|
774
|
+
GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT)) {
|
775
|
+
giterr_set(GITERR_INDEX, "Invalid path: '%s'", path);
|
776
|
+
return -1;
|
777
|
+
}
|
778
|
+
|
779
|
+
entry = git__calloc(sizeof(struct entry_internal) + pathlen + 1, 1);
|
780
|
+
GITERR_CHECK_ALLOC(entry);
|
772
781
|
|
773
782
|
entry->pathlen = pathlen;
|
774
783
|
memcpy(entry->path, path, pathlen);
|
775
784
|
entry->entry.path = entry->path;
|
776
785
|
|
777
|
-
|
786
|
+
*out = (git_index_entry *)entry;
|
787
|
+
return 0;
|
778
788
|
}
|
779
789
|
|
780
790
|
static int index_entry_init(
|
781
|
-
git_index_entry **entry_out,
|
791
|
+
git_index_entry **entry_out,
|
792
|
+
git_index *index,
|
793
|
+
const char *rel_path)
|
782
794
|
{
|
783
795
|
int error = 0;
|
784
796
|
git_index_entry *entry = NULL;
|
@@ -790,14 +802,17 @@ static int index_entry_init(
|
|
790
802
|
"Could not initialize index entry. "
|
791
803
|
"Index is not backed up by an existing repository.");
|
792
804
|
|
805
|
+
if (index_entry_create(&entry, INDEX_OWNER(index), rel_path) < 0)
|
806
|
+
return -1;
|
807
|
+
|
793
808
|
/* write the blob to disk and get the oid and stat info */
|
794
809
|
error = git_blob__create_from_paths(
|
795
810
|
&oid, &st, INDEX_OWNER(index), NULL, rel_path, 0, true);
|
796
|
-
if (error < 0)
|
797
|
-
return error;
|
798
811
|
|
799
|
-
|
800
|
-
|
812
|
+
if (error < 0) {
|
813
|
+
index_entry_free(entry);
|
814
|
+
return error;
|
815
|
+
}
|
801
816
|
|
802
817
|
entry->id = oid;
|
803
818
|
git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
|
@@ -853,7 +868,10 @@ static void index_entry_cpy(git_index_entry *tgt, const git_index_entry *src)
|
|
853
868
|
tgt->path = tgt_path; /* reset to existing path data */
|
854
869
|
}
|
855
870
|
|
856
|
-
static int index_entry_dup(
|
871
|
+
static int index_entry_dup(
|
872
|
+
git_index_entry **out,
|
873
|
+
git_repository *repo,
|
874
|
+
const git_index_entry *src)
|
857
875
|
{
|
858
876
|
git_index_entry *entry;
|
859
877
|
|
@@ -862,11 +880,11 @@ static int index_entry_dup(git_index_entry **out, const git_index_entry *src)
|
|
862
880
|
return 0;
|
863
881
|
}
|
864
882
|
|
865
|
-
|
866
|
-
|
883
|
+
if (index_entry_create(&entry, repo, src->path) < 0)
|
884
|
+
return -1;
|
867
885
|
|
868
886
|
index_entry_cpy(entry, src);
|
869
|
-
|
887
|
+
*out = entry;
|
870
888
|
return 0;
|
871
889
|
}
|
872
890
|
|
@@ -1131,7 +1149,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry)
|
|
1131
1149
|
return -1;
|
1132
1150
|
}
|
1133
1151
|
|
1134
|
-
if ((ret = index_entry_dup(&entry, source_entry)) < 0 ||
|
1152
|
+
if ((ret = index_entry_dup(&entry, INDEX_OWNER(index), source_entry)) < 0 ||
|
1135
1153
|
(ret = index_insert(index, &entry, 1)) < 0)
|
1136
1154
|
return ret;
|
1137
1155
|
|
@@ -1251,9 +1269,9 @@ int git_index_conflict_add(git_index *index,
|
|
1251
1269
|
|
1252
1270
|
assert (index);
|
1253
1271
|
|
1254
|
-
if ((ret = index_entry_dup(&entries[0], ancestor_entry)) < 0 ||
|
1255
|
-
(ret = index_entry_dup(&entries[1], our_entry)) < 0 ||
|
1256
|
-
(ret = index_entry_dup(&entries[2], their_entry)) < 0)
|
1272
|
+
if ((ret = index_entry_dup(&entries[0], INDEX_OWNER(index), ancestor_entry)) < 0 ||
|
1273
|
+
(ret = index_entry_dup(&entries[1], INDEX_OWNER(index), our_entry)) < 0 ||
|
1274
|
+
(ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
|
1257
1275
|
goto on_error;
|
1258
1276
|
|
1259
1277
|
for (i = 0; i < 3; i++) {
|
@@ -1770,7 +1788,10 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size
|
|
1770
1788
|
}
|
1771
1789
|
|
1772
1790
|
static size_t read_entry(
|
1773
|
-
git_index_entry **out,
|
1791
|
+
git_index_entry **out,
|
1792
|
+
git_index *index,
|
1793
|
+
const void *buffer,
|
1794
|
+
size_t buffer_size)
|
1774
1795
|
{
|
1775
1796
|
size_t path_length, entry_size;
|
1776
1797
|
const char *path_ptr;
|
@@ -1834,7 +1855,7 @@ static size_t read_entry(
|
|
1834
1855
|
|
1835
1856
|
entry.path = (char *)path_ptr;
|
1836
1857
|
|
1837
|
-
if (index_entry_dup(out, &entry) < 0)
|
1858
|
+
if (index_entry_dup(out, INDEX_OWNER(index), &entry) < 0)
|
1838
1859
|
return 0;
|
1839
1860
|
|
1840
1861
|
return entry_size;
|
@@ -1935,7 +1956,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
1935
1956
|
/* Parse all the entries */
|
1936
1957
|
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
|
1937
1958
|
git_index_entry *entry;
|
1938
|
-
size_t entry_size = read_entry(&entry, buffer, buffer_size);
|
1959
|
+
size_t entry_size = read_entry(&entry, index, buffer, buffer_size);
|
1939
1960
|
|
1940
1961
|
/* 0 bytes read means an object corruption */
|
1941
1962
|
if (entry_size == 0) {
|
@@ -2296,6 +2317,7 @@ int git_index_entry_stage(const git_index_entry *entry)
|
|
2296
2317
|
}
|
2297
2318
|
|
2298
2319
|
typedef struct read_tree_data {
|
2320
|
+
git_index *index;
|
2299
2321
|
git_vector *old_entries;
|
2300
2322
|
git_vector *new_entries;
|
2301
2323
|
git_vector_cmp entry_cmp;
|
@@ -2316,8 +2338,8 @@ static int read_tree_cb(
|
|
2316
2338
|
if (git_buf_joinpath(&path, root, tentry->filename) < 0)
|
2317
2339
|
return -1;
|
2318
2340
|
|
2319
|
-
entry
|
2320
|
-
|
2341
|
+
if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr) < 0)
|
2342
|
+
return -1;
|
2321
2343
|
|
2322
2344
|
entry->mode = tentry->attr;
|
2323
2345
|
entry->id = tentry->oid;
|
@@ -2357,6 +2379,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
|
|
2357
2379
|
|
2358
2380
|
git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
|
2359
2381
|
|
2382
|
+
data.index = index;
|
2360
2383
|
data.old_entries = &index->entries;
|
2361
2384
|
data.new_entries = &entries;
|
2362
2385
|
data.entry_cmp = index->entries_search;
|
@@ -2476,7 +2499,7 @@ int git_index_add_all(
|
|
2476
2499
|
break;
|
2477
2500
|
|
2478
2501
|
/* make the new entry to insert */
|
2479
|
-
if ((error = index_entry_dup(&entry, wd)) < 0)
|
2502
|
+
if ((error = index_entry_dup(&entry, INDEX_OWNER(index), wd)) < 0)
|
2480
2503
|
break;
|
2481
2504
|
|
2482
2505
|
entry->id = blobid;
|
data/vendor/libgit2/src/netops.c
CHANGED
@@ -4,27 +4,6 @@
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
6
6
|
*/
|
7
|
-
#ifndef _WIN32
|
8
|
-
# include <sys/types.h>
|
9
|
-
# include <sys/socket.h>
|
10
|
-
# include <sys/select.h>
|
11
|
-
# include <sys/time.h>
|
12
|
-
# include <netdb.h>
|
13
|
-
# include <netinet/in.h>
|
14
|
-
# include <arpa/inet.h>
|
15
|
-
#else
|
16
|
-
# include <winsock2.h>
|
17
|
-
# include <ws2tcpip.h>
|
18
|
-
# ifdef _MSC_VER
|
19
|
-
# pragma comment(lib, "ws2_32")
|
20
|
-
# endif
|
21
|
-
#endif
|
22
|
-
|
23
|
-
#ifdef GIT_SSL
|
24
|
-
# include <openssl/ssl.h>
|
25
|
-
# include <openssl/err.h>
|
26
|
-
# include <openssl/x509v3.h>
|
27
|
-
#endif
|
28
7
|
|
29
8
|
#include <ctype.h>
|
30
9
|
#include "git2/errors.h"
|
@@ -36,136 +15,46 @@
|
|
36
15
|
#include "http_parser.h"
|
37
16
|
#include "global.h"
|
38
17
|
|
39
|
-
#ifdef GIT_WIN32
|
40
|
-
static void net_set_error(const char *str)
|
41
|
-
{
|
42
|
-
int error = WSAGetLastError();
|
43
|
-
char * win32_error = git_win32_get_error_message(error);
|
44
|
-
|
45
|
-
if (win32_error) {
|
46
|
-
giterr_set(GITERR_NET, "%s: %s", str, win32_error);
|
47
|
-
git__free(win32_error);
|
48
|
-
} else {
|
49
|
-
giterr_set(GITERR_NET, str);
|
50
|
-
}
|
51
|
-
}
|
52
|
-
#else
|
53
|
-
static void net_set_error(const char *str)
|
54
|
-
{
|
55
|
-
giterr_set(GITERR_NET, "%s: %s", str, strerror(errno));
|
56
|
-
}
|
57
|
-
#endif
|
58
|
-
|
59
|
-
#ifdef GIT_SSL
|
60
|
-
static int ssl_set_error(gitno_ssl *ssl, int error)
|
61
|
-
{
|
62
|
-
int err;
|
63
|
-
unsigned long e;
|
64
|
-
|
65
|
-
err = SSL_get_error(ssl->ssl, error);
|
66
|
-
|
67
|
-
assert(err != SSL_ERROR_WANT_READ);
|
68
|
-
assert(err != SSL_ERROR_WANT_WRITE);
|
69
|
-
|
70
|
-
switch (err) {
|
71
|
-
case SSL_ERROR_WANT_CONNECT:
|
72
|
-
case SSL_ERROR_WANT_ACCEPT:
|
73
|
-
giterr_set(GITERR_NET, "SSL error: connection failure\n");
|
74
|
-
break;
|
75
|
-
case SSL_ERROR_WANT_X509_LOOKUP:
|
76
|
-
giterr_set(GITERR_NET, "SSL error: x509 error\n");
|
77
|
-
break;
|
78
|
-
case SSL_ERROR_SYSCALL:
|
79
|
-
e = ERR_get_error();
|
80
|
-
if (e > 0) {
|
81
|
-
giterr_set(GITERR_NET, "SSL error: %s",
|
82
|
-
ERR_error_string(e, NULL));
|
83
|
-
break;
|
84
|
-
} else if (error < 0) {
|
85
|
-
giterr_set(GITERR_OS, "SSL error: syscall failure");
|
86
|
-
break;
|
87
|
-
}
|
88
|
-
giterr_set(GITERR_NET, "SSL error: received early EOF");
|
89
|
-
break;
|
90
|
-
case SSL_ERROR_SSL:
|
91
|
-
e = ERR_get_error();
|
92
|
-
giterr_set(GITERR_NET, "SSL error: %s",
|
93
|
-
ERR_error_string(e, NULL));
|
94
|
-
break;
|
95
|
-
case SSL_ERROR_NONE:
|
96
|
-
case SSL_ERROR_ZERO_RETURN:
|
97
|
-
default:
|
98
|
-
giterr_set(GITERR_NET, "SSL error: unknown error");
|
99
|
-
break;
|
100
|
-
}
|
101
|
-
return -1;
|
102
|
-
}
|
103
|
-
#endif
|
104
|
-
|
105
18
|
int gitno_recv(gitno_buffer *buf)
|
106
19
|
{
|
107
20
|
return buf->recv(buf);
|
108
21
|
}
|
109
22
|
|
110
|
-
|
111
|
-
|
23
|
+
void gitno_buffer_setup_callback(
|
24
|
+
gitno_buffer *buf,
|
25
|
+
char *data,
|
26
|
+
size_t len,
|
27
|
+
int (*recv)(gitno_buffer *buf), void *cb_data)
|
112
28
|
{
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
if (ret < 0) {
|
120
|
-
net_set_error("Error receiving socket data");
|
121
|
-
return -1;
|
122
|
-
}
|
123
|
-
|
124
|
-
buf->offset += ret;
|
125
|
-
return ret;
|
29
|
+
memset(data, 0x0, len);
|
30
|
+
buf->data = data;
|
31
|
+
buf->len = len;
|
32
|
+
buf->offset = 0;
|
33
|
+
buf->recv = recv;
|
34
|
+
buf->cb_data = cb_data;
|
126
35
|
}
|
127
|
-
#endif
|
128
36
|
|
129
|
-
static int
|
37
|
+
static int recv_stream(gitno_buffer *buf)
|
130
38
|
{
|
39
|
+
git_stream *io = (git_stream *) buf->cb_data;
|
131
40
|
int ret;
|
132
41
|
|
133
|
-
ret =
|
134
|
-
if (ret < 0)
|
135
|
-
net_set_error("Error receiving socket data");
|
42
|
+
ret = git_stream_read(io, buf->data + buf->offset, buf->len - buf->offset);
|
43
|
+
if (ret < 0)
|
136
44
|
return -1;
|
137
|
-
}
|
138
45
|
|
139
46
|
buf->offset += ret;
|
140
47
|
return ret;
|
141
48
|
}
|
142
49
|
|
143
|
-
void
|
144
|
-
gitno_socket *socket,
|
145
|
-
gitno_buffer *buf,
|
146
|
-
char *data,
|
147
|
-
size_t len,
|
148
|
-
int (*recv)(gitno_buffer *buf), void *cb_data)
|
50
|
+
void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len)
|
149
51
|
{
|
150
52
|
memset(data, 0x0, len);
|
151
53
|
buf->data = data;
|
152
54
|
buf->len = len;
|
153
55
|
buf->offset = 0;
|
154
|
-
buf->
|
155
|
-
buf->
|
156
|
-
buf->cb_data = cb_data;
|
157
|
-
}
|
158
|
-
|
159
|
-
void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, size_t len)
|
160
|
-
{
|
161
|
-
#ifdef GIT_SSL
|
162
|
-
if (socket->ssl.ssl) {
|
163
|
-
gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv_ssl, NULL);
|
164
|
-
return;
|
165
|
-
}
|
166
|
-
#endif
|
167
|
-
|
168
|
-
gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv, NULL);
|
56
|
+
buf->recv = recv_stream;
|
57
|
+
buf->cb_data = st;
|
169
58
|
}
|
170
59
|
|
171
60
|
/* Consume up to ptr and move the rest of the buffer to the beginning */
|
@@ -191,24 +80,6 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
|
|
191
80
|
buf->offset -= cons;
|
192
81
|
}
|
193
82
|
|
194
|
-
#ifdef GIT_SSL
|
195
|
-
|
196
|
-
static int gitno_ssl_teardown(gitno_ssl *ssl)
|
197
|
-
{
|
198
|
-
int ret;
|
199
|
-
|
200
|
-
ret = SSL_shutdown(ssl->ssl);
|
201
|
-
if (ret < 0)
|
202
|
-
ret = ssl_set_error(ssl, ret);
|
203
|
-
else
|
204
|
-
ret = 0;
|
205
|
-
|
206
|
-
SSL_free(ssl->ssl);
|
207
|
-
return ret;
|
208
|
-
}
|
209
|
-
|
210
|
-
#endif
|
211
|
-
|
212
83
|
/* Match host names according to RFC 2818 rules */
|
213
84
|
int gitno__match_host(const char *pattern, const char *host)
|
214
85
|
{
|
@@ -248,333 +119,6 @@ int gitno__match_host(const char *pattern, const char *host)
|
|
248
119
|
return -1;
|
249
120
|
}
|
250
121
|
|
251
|
-
static int check_host_name(const char *name, const char *host)
|
252
|
-
{
|
253
|
-
if (!strcasecmp(name, host))
|
254
|
-
return 0;
|
255
|
-
|
256
|
-
if (gitno__match_host(name, host) < 0)
|
257
|
-
return -1;
|
258
|
-
|
259
|
-
return 0;
|
260
|
-
}
|
261
|
-
|
262
|
-
#ifdef GIT_SSL
|
263
|
-
|
264
|
-
static int verify_server_cert(gitno_ssl *ssl, const char *host)
|
265
|
-
{
|
266
|
-
X509 *cert;
|
267
|
-
X509_NAME *peer_name;
|
268
|
-
ASN1_STRING *str;
|
269
|
-
unsigned char *peer_cn = NULL;
|
270
|
-
int matched = -1, type = GEN_DNS;
|
271
|
-
GENERAL_NAMES *alts;
|
272
|
-
struct in6_addr addr6;
|
273
|
-
struct in_addr addr4;
|
274
|
-
void *addr;
|
275
|
-
int i = -1,j;
|
276
|
-
|
277
|
-
if (SSL_get_verify_result(ssl->ssl) != X509_V_OK) {
|
278
|
-
giterr_set(GITERR_SSL, "The SSL certificate is invalid");
|
279
|
-
return GIT_ECERTIFICATE;
|
280
|
-
}
|
281
|
-
|
282
|
-
/* Try to parse the host as an IP address to see if it is */
|
283
|
-
if (p_inet_pton(AF_INET, host, &addr4)) {
|
284
|
-
type = GEN_IPADD;
|
285
|
-
addr = &addr4;
|
286
|
-
} else {
|
287
|
-
if(p_inet_pton(AF_INET6, host, &addr6)) {
|
288
|
-
type = GEN_IPADD;
|
289
|
-
addr = &addr6;
|
290
|
-
}
|
291
|
-
}
|
292
|
-
|
293
|
-
|
294
|
-
cert = SSL_get_peer_certificate(ssl->ssl);
|
295
|
-
if (!cert) {
|
296
|
-
giterr_set(GITERR_SSL, "the server did not provide a certificate");
|
297
|
-
return -1;
|
298
|
-
}
|
299
|
-
|
300
|
-
/* Check the alternative names */
|
301
|
-
alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
|
302
|
-
if (alts) {
|
303
|
-
int num;
|
304
|
-
|
305
|
-
num = sk_GENERAL_NAME_num(alts);
|
306
|
-
for (i = 0; i < num && matched != 1; i++) {
|
307
|
-
const GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, i);
|
308
|
-
const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
|
309
|
-
size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);
|
310
|
-
|
311
|
-
/* Skip any names of a type we're not looking for */
|
312
|
-
if (gn->type != type)
|
313
|
-
continue;
|
314
|
-
|
315
|
-
if (type == GEN_DNS) {
|
316
|
-
/* If it contains embedded NULs, don't even try */
|
317
|
-
if (memchr(name, '\0', namelen))
|
318
|
-
continue;
|
319
|
-
|
320
|
-
if (check_host_name(name, host) < 0)
|
321
|
-
matched = 0;
|
322
|
-
else
|
323
|
-
matched = 1;
|
324
|
-
} else if (type == GEN_IPADD) {
|
325
|
-
/* Here name isn't so much a name but a binary representation of the IP */
|
326
|
-
matched = !!memcmp(name, addr, namelen);
|
327
|
-
}
|
328
|
-
}
|
329
|
-
}
|
330
|
-
GENERAL_NAMES_free(alts);
|
331
|
-
|
332
|
-
if (matched == 0)
|
333
|
-
goto cert_fail_name;
|
334
|
-
|
335
|
-
if (matched == 1)
|
336
|
-
return 0;
|
337
|
-
|
338
|
-
/* If no alternative names are available, check the common name */
|
339
|
-
peer_name = X509_get_subject_name(cert);
|
340
|
-
if (peer_name == NULL)
|
341
|
-
goto on_error;
|
342
|
-
|
343
|
-
if (peer_name) {
|
344
|
-
/* Get the index of the last CN entry */
|
345
|
-
while ((j = X509_NAME_get_index_by_NID(peer_name, NID_commonName, i)) >= 0)
|
346
|
-
i = j;
|
347
|
-
}
|
348
|
-
|
349
|
-
if (i < 0)
|
350
|
-
goto on_error;
|
351
|
-
|
352
|
-
str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(peer_name, i));
|
353
|
-
if (str == NULL)
|
354
|
-
goto on_error;
|
355
|
-
|
356
|
-
/* Work around a bug in OpenSSL whereby ASN1_STRING_to_UTF8 fails if it's already in utf-8 */
|
357
|
-
if (ASN1_STRING_type(str) == V_ASN1_UTF8STRING) {
|
358
|
-
int size = ASN1_STRING_length(str);
|
359
|
-
|
360
|
-
if (size > 0) {
|
361
|
-
peer_cn = OPENSSL_malloc(size + 1);
|
362
|
-
GITERR_CHECK_ALLOC(peer_cn);
|
363
|
-
memcpy(peer_cn, ASN1_STRING_data(str), size);
|
364
|
-
peer_cn[size] = '\0';
|
365
|
-
}
|
366
|
-
} else {
|
367
|
-
int size = ASN1_STRING_to_UTF8(&peer_cn, str);
|
368
|
-
GITERR_CHECK_ALLOC(peer_cn);
|
369
|
-
if (memchr(peer_cn, '\0', size))
|
370
|
-
goto cert_fail_name;
|
371
|
-
}
|
372
|
-
|
373
|
-
if (check_host_name((char *)peer_cn, host) < 0)
|
374
|
-
goto cert_fail_name;
|
375
|
-
|
376
|
-
OPENSSL_free(peer_cn);
|
377
|
-
|
378
|
-
return 0;
|
379
|
-
|
380
|
-
on_error:
|
381
|
-
OPENSSL_free(peer_cn);
|
382
|
-
return ssl_set_error(ssl, 0);
|
383
|
-
|
384
|
-
cert_fail_name:
|
385
|
-
OPENSSL_free(peer_cn);
|
386
|
-
giterr_set(GITERR_SSL, "hostname does not match certificate");
|
387
|
-
return GIT_ECERTIFICATE;
|
388
|
-
}
|
389
|
-
|
390
|
-
static int ssl_setup(gitno_socket *socket, const char *host)
|
391
|
-
{
|
392
|
-
int ret;
|
393
|
-
|
394
|
-
if (git__ssl_ctx == NULL) {
|
395
|
-
giterr_set(GITERR_NET, "OpenSSL initialization failed");
|
396
|
-
return -1;
|
397
|
-
}
|
398
|
-
|
399
|
-
socket->ssl.ssl = SSL_new(git__ssl_ctx);
|
400
|
-
if (socket->ssl.ssl == NULL)
|
401
|
-
return ssl_set_error(&socket->ssl, 0);
|
402
|
-
|
403
|
-
if((ret = SSL_set_fd(socket->ssl.ssl, socket->socket)) == 0)
|
404
|
-
return ssl_set_error(&socket->ssl, ret);
|
405
|
-
|
406
|
-
if ((ret = SSL_connect(socket->ssl.ssl)) <= 0)
|
407
|
-
return ssl_set_error(&socket->ssl, ret);
|
408
|
-
|
409
|
-
return verify_server_cert(&socket->ssl, host);
|
410
|
-
}
|
411
|
-
#endif
|
412
|
-
|
413
|
-
static int gitno__close(GIT_SOCKET s)
|
414
|
-
{
|
415
|
-
#ifdef GIT_WIN32
|
416
|
-
if (SOCKET_ERROR == closesocket(s))
|
417
|
-
return -1;
|
418
|
-
|
419
|
-
if (0 != WSACleanup()) {
|
420
|
-
giterr_set(GITERR_OS, "Winsock cleanup failed");
|
421
|
-
return -1;
|
422
|
-
}
|
423
|
-
|
424
|
-
return 0;
|
425
|
-
#else
|
426
|
-
return close(s);
|
427
|
-
#endif
|
428
|
-
}
|
429
|
-
|
430
|
-
int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int flags)
|
431
|
-
{
|
432
|
-
struct addrinfo *info = NULL, *p;
|
433
|
-
struct addrinfo hints;
|
434
|
-
GIT_SOCKET s = INVALID_SOCKET;
|
435
|
-
int ret;
|
436
|
-
|
437
|
-
#ifdef GIT_WIN32
|
438
|
-
/* on win32, the WSA context needs to be initialized
|
439
|
-
* before any socket calls can be performed */
|
440
|
-
WSADATA wsd;
|
441
|
-
|
442
|
-
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
|
443
|
-
giterr_set(GITERR_OS, "Winsock init failed");
|
444
|
-
return -1;
|
445
|
-
}
|
446
|
-
|
447
|
-
if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
|
448
|
-
WSACleanup();
|
449
|
-
giterr_set(GITERR_OS, "Winsock init failed");
|
450
|
-
return -1;
|
451
|
-
}
|
452
|
-
#endif
|
453
|
-
|
454
|
-
/* Zero the socket structure provided */
|
455
|
-
memset(s_out, 0x0, sizeof(gitno_socket));
|
456
|
-
|
457
|
-
memset(&hints, 0x0, sizeof(struct addrinfo));
|
458
|
-
hints.ai_socktype = SOCK_STREAM;
|
459
|
-
hints.ai_family = AF_UNSPEC;
|
460
|
-
|
461
|
-
if ((ret = p_getaddrinfo(host, port, &hints, &info)) != 0) {
|
462
|
-
giterr_set(GITERR_NET,
|
463
|
-
"Failed to resolve address for %s: %s", host, p_gai_strerror(ret));
|
464
|
-
return -1;
|
465
|
-
}
|
466
|
-
|
467
|
-
for (p = info; p != NULL; p = p->ai_next) {
|
468
|
-
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
469
|
-
|
470
|
-
if (s == INVALID_SOCKET) {
|
471
|
-
net_set_error("error creating socket");
|
472
|
-
break;
|
473
|
-
}
|
474
|
-
|
475
|
-
if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
|
476
|
-
break;
|
477
|
-
|
478
|
-
/* If we can't connect, try the next one */
|
479
|
-
gitno__close(s);
|
480
|
-
s = INVALID_SOCKET;
|
481
|
-
}
|
482
|
-
|
483
|
-
/* Oops, we couldn't connect to any address */
|
484
|
-
if (s == INVALID_SOCKET && p == NULL) {
|
485
|
-
giterr_set(GITERR_OS, "Failed to connect to %s", host);
|
486
|
-
p_freeaddrinfo(info);
|
487
|
-
return -1;
|
488
|
-
}
|
489
|
-
|
490
|
-
s_out->socket = s;
|
491
|
-
p_freeaddrinfo(info);
|
492
|
-
|
493
|
-
#ifdef GIT_SSL
|
494
|
-
if ((flags & GITNO_CONNECT_SSL) &&
|
495
|
-
(ret = ssl_setup(s_out, host)) < 0)
|
496
|
-
return ret;
|
497
|
-
#else
|
498
|
-
/* SSL is not supported */
|
499
|
-
if (flags & GITNO_CONNECT_SSL) {
|
500
|
-
giterr_set(GITERR_OS, "SSL is not supported by this copy of libgit2.");
|
501
|
-
return -1;
|
502
|
-
}
|
503
|
-
#endif
|
504
|
-
|
505
|
-
return 0;
|
506
|
-
}
|
507
|
-
|
508
|
-
#ifdef GIT_SSL
|
509
|
-
static int gitno_send_ssl(gitno_ssl *ssl, const char *msg, size_t len, int flags)
|
510
|
-
{
|
511
|
-
int ret;
|
512
|
-
size_t off = 0;
|
513
|
-
|
514
|
-
GIT_UNUSED(flags);
|
515
|
-
|
516
|
-
while (off < len) {
|
517
|
-
ret = SSL_write(ssl->ssl, msg + off, len - off);
|
518
|
-
if (ret <= 0 && ret != SSL_ERROR_WANT_WRITE)
|
519
|
-
return ssl_set_error(ssl, ret);
|
520
|
-
|
521
|
-
off += ret;
|
522
|
-
}
|
523
|
-
|
524
|
-
return off;
|
525
|
-
}
|
526
|
-
#endif
|
527
|
-
|
528
|
-
int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
|
529
|
-
{
|
530
|
-
int ret;
|
531
|
-
size_t off = 0;
|
532
|
-
|
533
|
-
#ifdef GIT_SSL
|
534
|
-
if (socket->ssl.ssl)
|
535
|
-
return gitno_send_ssl(&socket->ssl, msg, len, flags);
|
536
|
-
#endif
|
537
|
-
|
538
|
-
while (off < len) {
|
539
|
-
errno = 0;
|
540
|
-
ret = p_send(socket->socket, msg + off, len - off, flags);
|
541
|
-
if (ret < 0) {
|
542
|
-
net_set_error("Error sending data");
|
543
|
-
return -1;
|
544
|
-
}
|
545
|
-
|
546
|
-
off += ret;
|
547
|
-
}
|
548
|
-
|
549
|
-
return (int)off;
|
550
|
-
}
|
551
|
-
|
552
|
-
int gitno_close(gitno_socket *s)
|
553
|
-
{
|
554
|
-
#ifdef GIT_SSL
|
555
|
-
if (s->ssl.ssl &&
|
556
|
-
gitno_ssl_teardown(&s->ssl) < 0)
|
557
|
-
return -1;
|
558
|
-
#endif
|
559
|
-
|
560
|
-
return gitno__close(s->socket);
|
561
|
-
}
|
562
|
-
|
563
|
-
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
|
564
|
-
{
|
565
|
-
fd_set fds;
|
566
|
-
struct timeval tv;
|
567
|
-
|
568
|
-
tv.tv_sec = sec;
|
569
|
-
tv.tv_usec = usec;
|
570
|
-
|
571
|
-
FD_ZERO(&fds);
|
572
|
-
FD_SET(buf->socket->socket, &fds);
|
573
|
-
|
574
|
-
/* The select(2) interface is silly */
|
575
|
-
return select((int)buf->socket->socket + 1, &fds, NULL, NULL, &tv);
|
576
|
-
}
|
577
|
-
|
578
122
|
static const char *prefix_http = "http://";
|
579
123
|
static const char *prefix_https = "https://";
|
580
124
|
|