rugged 0.24.0b13 → 0.24.0b14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/ext/rugged/rugged_commit.c +6 -6
  2. data/ext/rugged/rugged_revwalk.c +7 -3
  3. data/ext/rugged/rugged_settings.c +5 -0
  4. data/lib/rugged/tag.rb +1 -1
  5. data/lib/rugged/version.rb +1 -1
  6. data/vendor/libgit2/CMakeLists.txt +21 -8
  7. data/vendor/libgit2/include/git2/commit.h +6 -0
  8. data/vendor/libgit2/include/git2/common.h +15 -0
  9. data/vendor/libgit2/include/git2/errors.h +0 -5
  10. data/vendor/libgit2/include/git2/rebase.h +1 -1
  11. data/vendor/libgit2/include/git2/sys/filter.h +34 -25
  12. data/vendor/libgit2/include/git2/sys/index.h +1 -1
  13. data/vendor/libgit2/src/checkout.c +1 -1
  14. data/vendor/libgit2/src/commit.c +44 -12
  15. data/vendor/libgit2/src/common.h +11 -0
  16. data/vendor/libgit2/src/crlf.c +1 -1
  17. data/vendor/libgit2/src/diff_print.c +5 -1
  18. data/vendor/libgit2/src/diff_tform.c +16 -11
  19. data/vendor/libgit2/src/fileops.c +8 -15
  20. data/vendor/libgit2/src/filter.c +155 -124
  21. data/vendor/libgit2/src/filter.h +2 -0
  22. data/vendor/libgit2/src/global.c +56 -162
  23. data/vendor/libgit2/src/index.c +68 -30
  24. data/vendor/libgit2/src/index.h +1 -1
  25. data/vendor/libgit2/src/iterator.c +9 -3
  26. data/vendor/libgit2/src/netops.c +4 -0
  27. data/vendor/libgit2/src/object.c +26 -0
  28. data/vendor/libgit2/src/object.h +23 -0
  29. data/vendor/libgit2/src/openssl_stream.c +135 -3
  30. data/vendor/libgit2/src/openssl_stream.h +2 -0
  31. data/vendor/libgit2/src/pack-objects.c +6 -6
  32. data/vendor/libgit2/src/pack.c +18 -1
  33. data/vendor/libgit2/src/path.c +7 -3
  34. data/vendor/libgit2/src/path.h +14 -4
  35. data/vendor/libgit2/src/pool.c +78 -30
  36. data/vendor/libgit2/src/pool.h +28 -0
  37. data/vendor/libgit2/src/posix.c +5 -2
  38. data/vendor/libgit2/src/rebase.c +12 -10
  39. data/vendor/libgit2/src/refdb_fs.c +3 -4
  40. data/vendor/libgit2/src/refs.c +1 -7
  41. data/vendor/libgit2/src/refspec.c +4 -4
  42. data/vendor/libgit2/src/remote.c +2 -2
  43. data/vendor/libgit2/src/revwalk.c +1 -2
  44. data/vendor/libgit2/src/settings.c +9 -0
  45. data/vendor/libgit2/src/signature.c +2 -3
  46. data/vendor/libgit2/src/submodule.c +2 -2
  47. data/vendor/libgit2/src/thread-utils.h +1 -1
  48. data/vendor/libgit2/src/transports/smart_pkt.c +15 -9
  49. data/vendor/libgit2/src/transports/smart_protocol.c +2 -0
  50. data/vendor/libgit2/src/transports/winhttp.c +1 -1
  51. data/vendor/libgit2/src/tree.c +31 -10
  52. data/vendor/libgit2/src/unix/map.c +1 -1
  53. data/vendor/libgit2/src/unix/posix.h +15 -1
  54. data/vendor/libgit2/src/win32/posix.h +6 -4
  55. data/vendor/libgit2/src/win32/posix_w32.c +18 -2
  56. data/vendor/libgit2/src/win32/utf-conv.c +3 -18
  57. data/vendor/libgit2/src/win32/w32_util.h +44 -11
  58. data/vendor/libgit2/src/win32/win32-compat.h +10 -0
  59. data/vendor/libgit2/src/xdiff/xmerge.c +2 -0
  60. metadata +416 -405
  61. checksums.yaml +0 -7
@@ -92,7 +92,7 @@ GIT_INLINE(bool) git_index_entry_newer_than_index(
92
92
 
93
93
  /* If the timestamp is the same or newer than the index, it's racy */
94
94
  #if defined(GIT_USE_NSEC)
95
- if ((int32_t)index->stamp.tv_sec < entry->mtime.seconds)
95
+ if ((int32_t)index->stamp.mtime.tv_sec < entry->mtime.seconds)
96
96
  return true;
97
97
  else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds)
98
98
  return false;
@@ -558,6 +558,8 @@ static bool tree_iterator__pop_frame(tree_iterator *ti, bool final)
558
558
  {
559
559
  tree_iterator_frame *tf = ti->head;
560
560
 
561
+ assert(tf);
562
+
561
563
  if (!tf->up)
562
564
  return false;
563
565
 
@@ -581,6 +583,8 @@ static void tree_iterator__pop_all(tree_iterator *ti, bool to_end, bool final)
581
583
  while (tree_iterator__pop_frame(ti, final)) /* pop to root */;
582
584
 
583
585
  if (!final) {
586
+ assert(ti->head);
587
+
584
588
  ti->head->current = to_end ? ti->head->n_entries : 0;
585
589
  ti->path_ambiguities = 0;
586
590
  git_buf_clear(&ti->path);
@@ -773,10 +777,12 @@ static void tree_iterator__free(git_iterator *self)
773
777
  {
774
778
  tree_iterator *ti = (tree_iterator *)self;
775
779
 
776
- tree_iterator__pop_all(ti, true, false);
780
+ if (ti->head) {
781
+ tree_iterator__pop_all(ti, true, false);
782
+ git_tree_free(ti->head->entries[0]->tree);
783
+ git__free(ti->head);
784
+ }
777
785
 
778
- git_tree_free(ti->head->entries[0]->tree);
779
- git__free(ti->head);
780
786
  git_pool_clear(&ti->pool);
781
787
  git_buf_free(&ti->path);
782
788
  }
@@ -261,6 +261,10 @@ int gitno_extract_url_parts(
261
261
  *path = git__substrdup(_path, u.field_data[UF_PATH].len);
262
262
  GITERR_CHECK_ALLOC(*path);
263
263
  } else {
264
+ git__free(*port);
265
+ *port = NULL;
266
+ git__free(*host);
267
+ *host = NULL;
264
268
  giterr_set(GITERR_NET, "invalid url, missing path");
265
269
  return GIT_EINVALIDSPEC;
266
270
  }
@@ -14,6 +14,8 @@
14
14
  #include "blob.h"
15
15
  #include "tag.h"
16
16
 
17
+ bool git_object__strict_input_validation = true;
18
+
17
19
  typedef struct {
18
20
  const char *str; /* type name string */
19
21
  size_t size; /* size in bytes of the object structure */
@@ -465,3 +467,27 @@ int git_object_short_id(git_buf *out, const git_object *obj)
465
467
  return error;
466
468
  }
467
469
 
470
+ bool git_object__is_valid(
471
+ git_repository *repo, const git_oid *id, git_otype expected_type)
472
+ {
473
+ git_odb *odb;
474
+ git_otype actual_type;
475
+ size_t len;
476
+ int error;
477
+
478
+ if (!git_object__strict_input_validation)
479
+ return true;
480
+
481
+ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
482
+ (error = git_odb_read_header(&len, &actual_type, odb, id)) < 0)
483
+ return false;
484
+
485
+ if (expected_type != GIT_OBJ_ANY && expected_type != actual_type) {
486
+ giterr_set(GITERR_INVALID,
487
+ "the requested type does not match the type in the ODB");
488
+ return false;
489
+ }
490
+
491
+ return true;
492
+ }
493
+
@@ -7,6 +7,10 @@
7
7
  #ifndef INCLUDE_object_h__
8
8
  #define INCLUDE_object_h__
9
9
 
10
+ #include "repository.h"
11
+
12
+ extern bool git_object__strict_input_validation;
13
+
10
14
  /** Base git object for inheritance */
11
15
  struct git_object {
12
16
  git_cached_obj cached;
@@ -28,4 +32,23 @@ int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end
28
32
 
29
33
  void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid);
30
34
 
35
+ bool git_object__is_valid(
36
+ git_repository *repo, const git_oid *id, git_otype expected_type);
37
+
38
+ GIT_INLINE(git_otype) git_object__type_from_filemode(git_filemode_t mode)
39
+ {
40
+ switch (mode) {
41
+ case GIT_FILEMODE_TREE:
42
+ return GIT_OBJ_TREE;
43
+ case GIT_FILEMODE_COMMIT:
44
+ return GIT_OBJ_COMMIT;
45
+ case GIT_FILEMODE_BLOB:
46
+ case GIT_FILEMODE_BLOB_EXECUTABLE:
47
+ case GIT_FILEMODE_LINK:
48
+ return GIT_OBJ_BLOB;
49
+ default:
50
+ return GIT_OBJ_BAD;
51
+ }
52
+ }
53
+
31
54
  #endif
@@ -15,6 +15,7 @@
15
15
  #include "socket_stream.h"
16
16
  #include "netops.h"
17
17
  #include "git2/transport.h"
18
+ #include "git2/sys/openssl.h"
18
19
 
19
20
  #ifdef GIT_CURL
20
21
  # include "curl_stream.h"
@@ -31,6 +32,115 @@
31
32
  #include <openssl/x509v3.h>
32
33
  #include <openssl/bio.h>
33
34
 
35
+ SSL_CTX *git__ssl_ctx;
36
+
37
+ #ifdef GIT_THREADS
38
+
39
+ static git_mutex *openssl_locks;
40
+
41
+ static void openssl_locking_function(
42
+ int mode, int n, const char *file, int line)
43
+ {
44
+ int lock;
45
+
46
+ GIT_UNUSED(file);
47
+ GIT_UNUSED(line);
48
+
49
+ lock = mode & CRYPTO_LOCK;
50
+
51
+ if (lock) {
52
+ git_mutex_lock(&openssl_locks[n]);
53
+ } else {
54
+ git_mutex_unlock(&openssl_locks[n]);
55
+ }
56
+ }
57
+
58
+ static void shutdown_ssl_locking(void)
59
+ {
60
+ int num_locks, i;
61
+
62
+ num_locks = CRYPTO_num_locks();
63
+ CRYPTO_set_locking_callback(NULL);
64
+
65
+ for (i = 0; i < num_locks; ++i)
66
+ git_mutex_free(openssl_locks);
67
+ git__free(openssl_locks);
68
+ }
69
+
70
+ #endif /* GIT_THREADS */
71
+
72
+ /**
73
+ * This function aims to clean-up the SSL context which
74
+ * we allocated.
75
+ */
76
+ static void shutdown_ssl(void)
77
+ {
78
+ if (git__ssl_ctx) {
79
+ SSL_CTX_free(git__ssl_ctx);
80
+ git__ssl_ctx = NULL;
81
+ }
82
+ }
83
+
84
+ int git_openssl_stream_global_init(void)
85
+ {
86
+ #ifdef GIT_OPENSSL
87
+ long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
88
+
89
+ /* Older OpenSSL and MacOS OpenSSL doesn't have this */
90
+ #ifdef SSL_OP_NO_COMPRESSION
91
+ ssl_opts |= SSL_OP_NO_COMPRESSION;
92
+ #endif
93
+
94
+ SSL_load_error_strings();
95
+ OpenSSL_add_ssl_algorithms();
96
+ /*
97
+ * Load SSLv{2,3} and TLSv1 so that we can talk with servers
98
+ * which use the SSL hellos, which are often used for
99
+ * compatibility. We then disable SSL so we only allow OpenSSL
100
+ * to speak TLSv1 to perform the encryption itself.
101
+ */
102
+ git__ssl_ctx = SSL_CTX_new(SSLv23_method());
103
+ SSL_CTX_set_options(git__ssl_ctx, ssl_opts);
104
+ SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY);
105
+ SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL);
106
+ if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) {
107
+ SSL_CTX_free(git__ssl_ctx);
108
+ git__ssl_ctx = NULL;
109
+ return -1;
110
+ }
111
+ #endif
112
+
113
+ git__on_shutdown(shutdown_ssl);
114
+
115
+ return 0;
116
+ }
117
+
118
+ int git_openssl_set_locking(void)
119
+ {
120
+ #ifdef GIT_THREADS
121
+ int num_locks, i;
122
+
123
+ num_locks = CRYPTO_num_locks();
124
+ openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
125
+ GITERR_CHECK_ALLOC(openssl_locks);
126
+
127
+ for (i = 0; i < num_locks; i++) {
128
+ if (git_mutex_init(&openssl_locks[i]) != 0) {
129
+ giterr_set(GITERR_SSL, "failed to initialize openssl locks");
130
+ return -1;
131
+ }
132
+ }
133
+
134
+ CRYPTO_set_locking_callback(openssl_locking_function);
135
+ git__on_shutdown(shutdown_ssl_locking);
136
+ return 0;
137
+ #else
138
+ giterr_set(GITERR_THREAD, "libgit2 as not built with threads");
139
+ return -1;
140
+ #endif
141
+ }
142
+
143
+
34
144
  static int bio_create(BIO *b)
35
145
  {
36
146
  b->init = 1;
@@ -158,7 +268,6 @@ static int ssl_teardown(SSL *ssl)
158
268
  else
159
269
  ret = 0;
160
270
 
161
- SSL_free(ssl);
162
271
  return ret;
163
272
  }
164
273
 
@@ -274,6 +383,8 @@ static int verify_server_cert(SSL *ssl, const char *host)
274
383
  GITERR_CHECK_ALLOC(peer_cn);
275
384
  memcpy(peer_cn, ASN1_STRING_data(str), size);
276
385
  peer_cn[size] = '\0';
386
+ } else {
387
+ goto cert_fail_name;
277
388
  }
278
389
  } else {
279
390
  int size = ASN1_STRING_to_UTF8(&peer_cn, str);
@@ -421,6 +532,7 @@ void openssl_free(git_stream *stream)
421
532
  {
422
533
  openssl_stream *st = (openssl_stream *) stream;
423
534
 
535
+ SSL_free(st->ssl);
424
536
  git__free(st->host);
425
537
  git__free(st->cert_info.data);
426
538
  git_stream_free(st->io);
@@ -435,6 +547,7 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
435
547
  st = git__calloc(1, sizeof(openssl_stream));
436
548
  GITERR_CHECK_ALLOC(st);
437
549
 
550
+ st->io = NULL;
438
551
  #ifdef GIT_CURL
439
552
  error = git_curl_stream_new(&st->io, host, port);
440
553
  #else
@@ -442,12 +555,13 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
442
555
  #endif
443
556
 
444
557
  if (error < 0)
445
- return error;
558
+ goto out_err;
446
559
 
447
560
  st->ssl = SSL_new(git__ssl_ctx);
448
561
  if (st->ssl == NULL) {
449
562
  giterr_set(GITERR_SSL, "failed to create ssl object");
450
- return -1;
563
+ error = -1;
564
+ goto out_err;
451
565
  }
452
566
 
453
567
  st->host = git__strdup(host);
@@ -466,11 +580,29 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
466
580
 
467
581
  *out = (git_stream *) st;
468
582
  return 0;
583
+
584
+ out_err:
585
+ git_stream_free(st->io);
586
+ git__free(st);
587
+
588
+ return error;
469
589
  }
470
590
 
471
591
  #else
472
592
 
473
593
  #include "stream.h"
594
+ #include "git2/sys/openssl.h"
595
+
596
+ int git_openssl_stream_global_init(void)
597
+ {
598
+ return 0;
599
+ }
600
+
601
+ int git_openssl_set_locking(void)
602
+ {
603
+ giterr_set(GITERR_SSL, "libgit2 was not built with OpenSSL support");
604
+ return -1;
605
+ }
474
606
 
475
607
  int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
476
608
  {
@@ -9,6 +9,8 @@
9
9
 
10
10
  #include "git2/sys/stream.h"
11
11
 
12
+ extern int git_openssl_stream_global_init(void);
13
+
12
14
  extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
13
15
 
14
16
  #endif
@@ -629,10 +629,8 @@ static int write_pack(git_packbuilder *pb,
629
629
  int error = 0;
630
630
 
631
631
  write_order = compute_write_order(pb);
632
- if (write_order == NULL) {
633
- error = -1;
634
- goto done;
635
- }
632
+ if (write_order == NULL)
633
+ return -1;
636
634
 
637
635
  /* Write pack header */
638
636
  ph.hdr_signature = htonl(PACK_SIGNATURE);
@@ -850,9 +848,11 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
850
848
 
851
849
  git_packbuilder__cache_unlock(pb);
852
850
 
853
- if (overflow ||
854
- !(trg_object->delta_data = git__realloc(delta_buf, delta_size)))
851
+ if (overflow)
855
852
  return -1;
853
+
854
+ trg_object->delta_data = git__realloc(delta_buf, delta_size);
855
+ GITERR_CHECK_ALLOC(trg_object->delta_data);
856
856
  } else {
857
857
  /* create delta when writing the pack */
858
858
  git_packbuilder__cache_unlock(pb);
@@ -365,9 +365,14 @@ static unsigned char *pack_window_open(
365
365
  * pointless to ask for an offset into the middle of that
366
366
  * hash, and the pack_window_contains function above wouldn't match
367
367
  * don't allow an offset too close to the end of the file.
368
+ *
369
+ * Don't allow a negative offset, as that means we've wrapped
370
+ * around.
368
371
  */
369
372
  if (offset > (p->mwf.size - 20))
370
373
  return NULL;
374
+ if (offset < 0)
375
+ return NULL;
371
376
 
372
377
  return git_mwindow_open(&p->mwf, w_cursor, offset, 20, left);
373
378
  }
@@ -1175,6 +1180,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
1175
1180
  static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
1176
1181
  {
1177
1182
  const unsigned char *index = p->index_map.data;
1183
+ const unsigned char *end = index + p->index_map.len;
1178
1184
  index += 4 * 256;
1179
1185
  if (p->index_version == 1) {
1180
1186
  return ntohl(*((uint32_t *)(index + 24 * n)));
@@ -1185,6 +1191,11 @@ static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_
1185
1191
  if (!(off & 0x80000000))
1186
1192
  return off;
1187
1193
  index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
1194
+
1195
+ /* Make sure we're not being sent out of bounds */
1196
+ if (index >= end - 8)
1197
+ return -1;
1198
+
1188
1199
  return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
1189
1200
  ntohl(*((uint32_t *)(index + 4)));
1190
1201
  }
@@ -1264,6 +1275,7 @@ static int pack_entry_find_offset(
1264
1275
  const unsigned char *index = p->index_map.data;
1265
1276
  unsigned hi, lo, stride;
1266
1277
  int pos, found = 0;
1278
+ git_off_t offset;
1267
1279
  const unsigned char *current = 0;
1268
1280
 
1269
1281
  *offset_out = 0;
@@ -1336,7 +1348,12 @@ static int pack_entry_find_offset(
1336
1348
  if (found > 1)
1337
1349
  return git_odb__error_ambiguous("found multiple offsets for pack entry");
1338
1350
 
1339
- *offset_out = nth_packed_object_offset(p, pos);
1351
+ if ((offset = nth_packed_object_offset(p, pos)) < 0) {
1352
+ giterr_set(GITERR_ODB, "packfile index is corrupt");
1353
+ return -1;
1354
+ }
1355
+
1356
+ *offset_out = offset;
1340
1357
  git_oid_fromraw(found_oid, current);
1341
1358
 
1342
1359
  #ifdef INDEX_DEBUG_LOOKUP
@@ -705,8 +705,7 @@ int git_path_resolve_relative(git_buf *path, size_t ceiling)
705
705
  char *base, *to, *from, *next;
706
706
  size_t len;
707
707
 
708
- if (!path || git_buf_oom(path))
709
- return -1;
708
+ GITERR_CHECK_ALLOC_BUF(path);
710
709
 
711
710
  if (ceiling > path->size)
712
711
  ceiling = path->size;
@@ -1630,9 +1629,12 @@ static bool verify_component(
1630
1629
  !verify_dotgit_ntfs(repo, component, len))
1631
1630
  return false;
1632
1631
 
1632
+ /* don't bother rerunning the `.git` test if we ran the HFS or NTFS
1633
+ * specific tests, they would have already rejected `.git`.
1634
+ */
1633
1635
  if ((flags & GIT_PATH_REJECT_DOT_GIT_HFS) == 0 &&
1634
1636
  (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) == 0 &&
1635
- (flags & GIT_PATH_REJECT_DOT_GIT) &&
1637
+ (flags & GIT_PATH_REJECT_DOT_GIT_LITERAL) &&
1636
1638
  len == 4 &&
1637
1639
  component[0] == '.' &&
1638
1640
  (component[1] == 'g' || component[1] == 'G') &&
@@ -1649,6 +1651,8 @@ GIT_INLINE(unsigned int) dotgit_flags(
1649
1651
  {
1650
1652
  int protectHFS = 0, protectNTFS = 0;
1651
1653
 
1654
+ flags |= GIT_PATH_REJECT_DOT_GIT_LITERAL;
1655
+
1652
1656
  #ifdef __APPLE__
1653
1657
  protectHFS = 1;
1654
1658
  #endif