rugged 0.21.2 → 0.21.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7fd19143d7ae79c19dcc780edd7399e0b96c677b
4
- data.tar.gz: c2e501d2d3525acc5a3a2297bc3726fc0c3465f8
3
+ metadata.gz: 4f476d2b5aaa786237a1a2e6c02ad6817395753a
4
+ data.tar.gz: bf560fd348d673a1ecf2082347cdcab68bc85141
5
5
  SHA512:
6
- metadata.gz: 2b6f3fb73a8d64f10b2dcac66dc7bc6a27c8257bf72f9d2d02b7d3179bb24a096a36593c87b420cfd31e889425c72b725d81f551907115ef717101716bb4f390
7
- data.tar.gz: 991a7b7aaa258c7fe858dedde2694493ce4af466e61ea42935fac3afe3ceaa1b80298f345f83cb82ee237256968ffe45faabfc182402d349ded4665bcf794424
6
+ metadata.gz: a47343b080593b0e668fdb259baafb7cd6f0a26dd7813476bafa83e60ded6e9218c417f4591b266825369ad8b600e3bd0e4016f2efa1c536501f39c64160256f
7
+ data.tar.gz: eec3ac2c4f8d77755e44c8f6d5e4358dbfa650905b6d6dfa8ecc2b404ffc466b4f1d34cfa8ea6879f9081a13d4a21cbf49c87ebb1826c2377c7a5094a3758d85
@@ -1,3 +1,3 @@
1
1
  module Rugged
2
- Version = VERSION = '0.21.2'
2
+ Version = VERSION = '0.21.4'
3
3
  end
@@ -11,6 +11,15 @@
11
11
  #include "git2/types.h"
12
12
  #include "git2/oid.h"
13
13
 
14
+ /**
15
+ * @file git2/sys/refs.h
16
+ * @brief Low-level Git ref creation
17
+ * @defgroup git_backend Git custom backend APIs
18
+ * @ingroup Git
19
+ * @{
20
+ */
21
+ GIT_BEGIN_DECL
22
+
14
23
  /**
15
24
  * Create a new direct reference from an OID.
16
25
  *
@@ -35,4 +44,6 @@ GIT_EXTERN(git_reference *) git_reference__alloc_symbolic(
35
44
  const char *name,
36
45
  const char *target);
37
46
 
47
+ /** @} */
48
+ GIT_END_DECL
38
49
  #endif
@@ -7,10 +7,10 @@
7
7
  #ifndef INCLUDE_git_version_h__
8
8
  #define INCLUDE_git_version_h__
9
9
 
10
- #define LIBGIT2_VERSION "0.21.2"
10
+ #define LIBGIT2_VERSION "0.21.4"
11
11
  #define LIBGIT2_VER_MAJOR 0
12
12
  #define LIBGIT2_VER_MINOR 21
13
- #define LIBGIT2_VER_REVISION 2
13
+ #define LIBGIT2_VER_REVISION 4
14
14
 
15
15
  #define LIBGIT2_SOVERSION 21
16
16
 
@@ -347,6 +347,21 @@ bool git_attr_fnmatch__match(
347
347
  const char *filename;
348
348
  int flags = 0;
349
349
 
350
+ /*
351
+ * If the rule was generated in a subdirectory, we must only
352
+ * use it for paths inside that directory. We can thus return
353
+ * a non-match if the prefixes don't match.
354
+ */
355
+ if (match->containing_dir) {
356
+ if (match->flags & GIT_ATTR_FNMATCH_ICASE) {
357
+ if (git__strncasecmp(path->path, match->containing_dir, match->containing_dir_length))
358
+ return 0;
359
+ } else {
360
+ if (git__prefixcmp(path->path, match->containing_dir))
361
+ return 0;
362
+ }
363
+ }
364
+
350
365
  if (match->flags & GIT_ATTR_FNMATCH_ICASE)
351
366
  flags |= FNM_CASEFOLD;
352
367
  if (match->flags & GIT_ATTR_FNMATCH_LEADINGDIR)
@@ -566,6 +581,17 @@ int git_attr_fnmatch__parse(
566
581
  /* leave FULLPATH match on, however */
567
582
  }
568
583
 
584
+ if (context) {
585
+ char *slash = strchr(context, '/');
586
+ size_t len;
587
+ if (slash) {
588
+ /* include the slash for easier matching */
589
+ len = slash - context + 1;
590
+ spec->containing_dir = git_pool_strndup(pool, context, len);
591
+ spec->containing_dir_length = len;
592
+ }
593
+ }
594
+
569
595
  if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 &&
570
596
  context != NULL && git_path_root(pattern) < 0)
571
597
  {
@@ -52,6 +52,8 @@ extern const char *git_attr__unset;
52
52
  typedef struct {
53
53
  char *pattern;
54
54
  size_t length;
55
+ char *containing_dir;
56
+ size_t containing_dir_length;
55
57
  unsigned int flags;
56
58
  } git_attr_fnmatch;
57
59
 
@@ -1078,6 +1078,30 @@ done:
1078
1078
  return error;
1079
1079
  }
1080
1080
 
1081
+ static int checkout_verify_paths(
1082
+ git_repository *repo,
1083
+ int action,
1084
+ git_diff_delta *delta)
1085
+ {
1086
+ unsigned int flags = GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT;
1087
+
1088
+ if (action & CHECKOUT_ACTION__REMOVE) {
1089
+ if (!git_path_isvalid(repo, delta->old_file.path, flags)) {
1090
+ giterr_set(GITERR_CHECKOUT, "Cannot remove invalid path '%s'", delta->old_file.path);
1091
+ return -1;
1092
+ }
1093
+ }
1094
+
1095
+ if (action & ~CHECKOUT_ACTION__REMOVE) {
1096
+ if (!git_path_isvalid(repo, delta->new_file.path, flags)) {
1097
+ giterr_set(GITERR_CHECKOUT, "Cannot checkout to invalid path '%s'", delta->old_file.path);
1098
+ return -1;
1099
+ }
1100
+ }
1101
+
1102
+ return 0;
1103
+ }
1104
+
1081
1105
  static int checkout_get_actions(
1082
1106
  uint32_t **actions_ptr,
1083
1107
  size_t **counts_ptr,
@@ -1111,7 +1135,9 @@ static int checkout_get_actions(
1111
1135
  }
1112
1136
 
1113
1137
  git_vector_foreach(deltas, i, delta) {
1114
- error = checkout_action(&act, data, delta, workdir, &wditem, &pathspec);
1138
+ if ((error = checkout_action(&act, data, delta, workdir, &wditem, &pathspec)) == 0)
1139
+ error = checkout_verify_paths(data->repo, act, delta);
1140
+
1115
1141
  if (error != 0)
1116
1142
  goto fail;
1117
1143
 
@@ -76,6 +76,8 @@ static struct map_data _cvar_maps[] = {
76
76
  {"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
77
77
  {"core.safecrlf", _cvar_map_safecrlf, ARRAY_SIZE(_cvar_map_safecrlf), GIT_SAFE_CRLF_DEFAULT},
78
78
  {"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
79
+ {"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
80
+ {"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
79
81
  };
80
82
 
81
83
  int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)
@@ -64,6 +64,13 @@ void openssl_locking_function(int mode, int n, const char *file, int line)
64
64
 
65
65
  static void shutdown_ssl(void)
66
66
  {
67
+ int num_locks, i;
68
+
69
+ num_locks = CRYPTO_num_locks();
70
+ CRYPTO_set_locking_callback(NULL);
71
+
72
+ for (i = 0; i < num_locks; ++i)
73
+ git_mutex_free(openssl_locks);
67
74
  git__free(openssl_locks);
68
75
  }
69
76
  #endif
@@ -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
- error = git_vector_insert(&attrs->rules, match);
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)
@@ -756,23 +756,35 @@ void git_index_entry__init_from_stat(
756
756
  entry->file_size = st->st_size;
757
757
  }
758
758
 
759
- static git_index_entry *index_entry_alloc(const char *path)
759
+ static int index_entry_create(
760
+ git_index_entry **out,
761
+ git_repository *repo,
762
+ const char *path)
760
763
  {
761
764
  size_t pathlen = strlen(path);
762
- struct entry_internal *entry =
763
- git__calloc(sizeof(struct entry_internal) + pathlen + 1, 1);
764
- if (!entry)
765
- return NULL;
765
+ struct entry_internal *entry;
766
+
767
+ if (!git_path_isvalid(repo, path,
768
+ GIT_PATH_REJECT_DEFAULTS | GIT_PATH_REJECT_DOT_GIT)) {
769
+ giterr_set(GITERR_INDEX, "Invalid path: '%s'", path);
770
+ return -1;
771
+ }
772
+
773
+ entry = git__calloc(sizeof(struct entry_internal) + pathlen + 1, 1);
774
+ GITERR_CHECK_ALLOC(entry);
766
775
 
767
776
  entry->pathlen = pathlen;
768
777
  memcpy(entry->path, path, pathlen);
769
778
  entry->entry.path = entry->path;
770
779
 
771
- return (git_index_entry *)entry;
780
+ *out = (git_index_entry *)entry;
781
+ return 0;
772
782
  }
773
783
 
774
784
  static int index_entry_init(
775
- git_index_entry **entry_out, git_index *index, const char *rel_path)
785
+ git_index_entry **entry_out,
786
+ git_index *index,
787
+ const char *rel_path)
776
788
  {
777
789
  int error = 0;
778
790
  git_index_entry *entry = NULL;
@@ -784,14 +796,17 @@ static int index_entry_init(
784
796
  "Could not initialize index entry. "
785
797
  "Index is not backed up by an existing repository.");
786
798
 
799
+ if (index_entry_create(&entry, INDEX_OWNER(index), rel_path) < 0)
800
+ return -1;
801
+
787
802
  /* write the blob to disk and get the oid and stat info */
788
803
  error = git_blob__create_from_paths(
789
804
  &oid, &st, INDEX_OWNER(index), NULL, rel_path, 0, true);
790
- if (error < 0)
791
- return error;
792
805
 
793
- entry = index_entry_alloc(rel_path);
794
- GITERR_CHECK_ALLOC(entry);
806
+ if (error < 0) {
807
+ index_entry_free(entry);
808
+ return error;
809
+ }
795
810
 
796
811
  entry->id = oid;
797
812
  git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
@@ -847,7 +862,10 @@ static void index_entry_cpy(git_index_entry *tgt, const git_index_entry *src)
847
862
  tgt->path = tgt_path; /* reset to existing path data */
848
863
  }
849
864
 
850
- static int index_entry_dup(git_index_entry **out, const git_index_entry *src)
865
+ static int index_entry_dup(
866
+ git_index_entry **out,
867
+ git_repository *repo,
868
+ const git_index_entry *src)
851
869
  {
852
870
  git_index_entry *entry;
853
871
 
@@ -856,11 +874,11 @@ static int index_entry_dup(git_index_entry **out, const git_index_entry *src)
856
874
  return 0;
857
875
  }
858
876
 
859
- *out = entry = index_entry_alloc(src->path);
860
- GITERR_CHECK_ALLOC(entry);
877
+ if (index_entry_create(&entry, repo, src->path) < 0)
878
+ return -1;
861
879
 
862
880
  index_entry_cpy(entry, src);
863
-
881
+ *out = entry;
864
882
  return 0;
865
883
  }
866
884
 
@@ -1125,7 +1143,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry)
1125
1143
  return -1;
1126
1144
  }
1127
1145
 
1128
- if ((ret = index_entry_dup(&entry, source_entry)) < 0 ||
1146
+ if ((ret = index_entry_dup(&entry, INDEX_OWNER(index), source_entry)) < 0 ||
1129
1147
  (ret = index_insert(index, &entry, 1)) < 0)
1130
1148
  return ret;
1131
1149
 
@@ -1245,9 +1263,9 @@ int git_index_conflict_add(git_index *index,
1245
1263
 
1246
1264
  assert (index);
1247
1265
 
1248
- if ((ret = index_entry_dup(&entries[0], ancestor_entry)) < 0 ||
1249
- (ret = index_entry_dup(&entries[1], our_entry)) < 0 ||
1250
- (ret = index_entry_dup(&entries[2], their_entry)) < 0)
1266
+ if ((ret = index_entry_dup(&entries[0], INDEX_OWNER(index), ancestor_entry)) < 0 ||
1267
+ (ret = index_entry_dup(&entries[1], INDEX_OWNER(index), our_entry)) < 0 ||
1268
+ (ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
1251
1269
  goto on_error;
1252
1270
 
1253
1271
  for (i = 0; i < 3; i++) {
@@ -1764,7 +1782,10 @@ static int read_conflict_names(git_index *index, const char *buffer, size_t size
1764
1782
  }
1765
1783
 
1766
1784
  static size_t read_entry(
1767
- git_index_entry **out, const void *buffer, size_t buffer_size)
1785
+ git_index_entry **out,
1786
+ git_index *index,
1787
+ const void *buffer,
1788
+ size_t buffer_size)
1768
1789
  {
1769
1790
  size_t path_length, entry_size;
1770
1791
  const char *path_ptr;
@@ -1828,7 +1849,7 @@ static size_t read_entry(
1828
1849
 
1829
1850
  entry.path = (char *)path_ptr;
1830
1851
 
1831
- if (index_entry_dup(out, &entry) < 0)
1852
+ if (index_entry_dup(out, INDEX_OWNER(index), &entry) < 0)
1832
1853
  return 0;
1833
1854
 
1834
1855
  return entry_size;
@@ -1929,7 +1950,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
1929
1950
  /* Parse all the entries */
1930
1951
  for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
1931
1952
  git_index_entry *entry;
1932
- size_t entry_size = read_entry(&entry, buffer, buffer_size);
1953
+ size_t entry_size = read_entry(&entry, index, buffer, buffer_size);
1933
1954
 
1934
1955
  /* 0 bytes read means an object corruption */
1935
1956
  if (entry_size == 0) {
@@ -2268,6 +2289,7 @@ int git_index_entry_stage(const git_index_entry *entry)
2268
2289
  }
2269
2290
 
2270
2291
  typedef struct read_tree_data {
2292
+ git_index *index;
2271
2293
  git_vector *old_entries;
2272
2294
  git_vector *new_entries;
2273
2295
  git_vector_cmp entry_cmp;
@@ -2287,8 +2309,8 @@ static int read_tree_cb(
2287
2309
  if (git_buf_joinpath(&path, root, tentry->filename) < 0)
2288
2310
  return -1;
2289
2311
 
2290
- entry = index_entry_alloc(path.ptr);
2291
- GITERR_CHECK_ALLOC(entry);
2312
+ if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr) < 0)
2313
+ return -1;
2292
2314
 
2293
2315
  entry->mode = tentry->attr;
2294
2316
  entry->id = tentry->oid;
@@ -2328,6 +2350,7 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
2328
2350
 
2329
2351
  git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
2330
2352
 
2353
+ data.index = index;
2331
2354
  data.old_entries = &index->entries;
2332
2355
  data.new_entries = &entries;
2333
2356
  data.entry_cmp = index->entries_search;
@@ -2440,7 +2463,7 @@ int git_index_add_all(
2440
2463
  break;
2441
2464
 
2442
2465
  /* make the new entry to insert */
2443
- if ((error = index_entry_dup(&entry, wd)) < 0)
2466
+ if ((error = index_entry_dup(&entry, INDEX_OWNER(index), wd)) < 0)
2444
2467
  break;
2445
2468
 
2446
2469
  entry->id = blobid;
@@ -433,6 +433,8 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
433
433
  git_map map;
434
434
  int error;
435
435
 
436
+ assert(data && size);
437
+
436
438
  /* the offset needs to be at the beginning of the a page boundary */
437
439
  page_start = (offset / page_size) * page_size;
438
440
  page_offset = offset - page_start;
@@ -451,6 +453,9 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
451
453
  {
452
454
  git_off_t current_size = idx->pack->mwf.size;
453
455
 
456
+ if (!size)
457
+ return 0;
458
+
454
459
  /* add the extra space we need at the end */
455
460
  if (p_ftruncate(idx->pack->mwf.fd, current_size + size) < 0) {
456
461
  giterr_set(GITERR_OS, "Failed to increase size of pack file '%s'", idx->pack->pack_name);