rugged 0.24.0b13 → 0.24.0b14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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