rugged 0.26.3 → 0.26.6

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/CMakeLists.txt +1 -1
  4. data/vendor/libgit2/deps/winhttp/winhttp.h +6 -4
  5. data/vendor/libgit2/deps/zlib/adler32.c +14 -7
  6. data/vendor/libgit2/deps/zlib/crc32.c +29 -12
  7. data/vendor/libgit2/deps/zlib/deflate.c +499 -303
  8. data/vendor/libgit2/deps/zlib/deflate.h +18 -15
  9. data/vendor/libgit2/deps/zlib/gzguts.h +218 -0
  10. data/vendor/libgit2/deps/zlib/infback.c +2 -2
  11. data/vendor/libgit2/deps/zlib/inffast.c +34 -51
  12. data/vendor/libgit2/deps/zlib/inflate.c +86 -37
  13. data/vendor/libgit2/deps/zlib/inflate.h +7 -4
  14. data/vendor/libgit2/deps/zlib/inftrees.c +12 -14
  15. data/vendor/libgit2/deps/zlib/trees.c +38 -61
  16. data/vendor/libgit2/deps/zlib/zconf.h +499 -23
  17. data/vendor/libgit2/deps/zlib/zlib.h +298 -154
  18. data/vendor/libgit2/deps/zlib/zutil.c +27 -23
  19. data/vendor/libgit2/deps/zlib/zutil.h +35 -17
  20. data/vendor/libgit2/include/git2.h +1 -0
  21. data/vendor/libgit2/include/git2/sys/mempack.h +5 -4
  22. data/vendor/libgit2/include/git2/version.h +2 -2
  23. data/vendor/libgit2/src/checkout.c +34 -11
  24. data/vendor/libgit2/src/curl_stream.c +21 -0
  25. data/vendor/libgit2/src/curl_stream.h +1 -0
  26. data/vendor/libgit2/src/delta.c +30 -28
  27. data/vendor/libgit2/src/diff.c +0 -7
  28. data/vendor/libgit2/src/diff_file.c +3 -1
  29. data/vendor/libgit2/src/diff_generate.c +1 -1
  30. data/vendor/libgit2/src/diff_tform.c +3 -1
  31. data/vendor/libgit2/src/global.c +4 -2
  32. data/vendor/libgit2/src/hash/hash_openssl.h +18 -3
  33. data/vendor/libgit2/src/ignore.c +60 -36
  34. data/vendor/libgit2/src/index.c +59 -26
  35. data/vendor/libgit2/src/indexer.c +15 -2
  36. data/vendor/libgit2/src/merge.c +18 -8
  37. data/vendor/libgit2/src/odb_mempack.c +1 -0
  38. data/vendor/libgit2/src/oidarray.c +12 -0
  39. data/vendor/libgit2/src/oidarray.h +1 -0
  40. data/vendor/libgit2/src/openssl_stream.c +17 -4
  41. data/vendor/libgit2/src/pack.c +10 -7
  42. data/vendor/libgit2/src/path.c +180 -22
  43. data/vendor/libgit2/src/path.h +73 -0
  44. data/vendor/libgit2/src/posix.c +1 -1
  45. data/vendor/libgit2/src/posix.h +3 -0
  46. data/vendor/libgit2/src/proxy.c +6 -0
  47. data/vendor/libgit2/src/proxy.h +1 -0
  48. data/vendor/libgit2/src/push.c +3 -0
  49. data/vendor/libgit2/src/refdb_fs.c +2 -2
  50. data/vendor/libgit2/src/refs.c +7 -1
  51. data/vendor/libgit2/src/repository.c +9 -3
  52. data/vendor/libgit2/src/sha1_lookup.c +2 -2
  53. data/vendor/libgit2/src/signature.c +1 -0
  54. data/vendor/libgit2/src/socket_stream.c +1 -1
  55. data/vendor/libgit2/src/stransport_stream.c +3 -1
  56. data/vendor/libgit2/src/submodule.c +54 -7
  57. data/vendor/libgit2/src/submodule.h +13 -0
  58. data/vendor/libgit2/src/transports/smart_pkt.c +8 -2
  59. data/vendor/libgit2/src/transports/smart_protocol.c +6 -6
  60. data/vendor/libgit2/src/transports/winhttp.c +22 -0
  61. data/vendor/libgit2/src/tree.c +1 -1
  62. metadata +3 -2
@@ -12,13 +12,6 @@
12
12
  #include "commit.h"
13
13
  #include "index.h"
14
14
 
15
- #define DIFF_FLAG_IS_SET(DIFF,FLAG) \
16
- (((DIFF)->opts.flags & (FLAG)) != 0)
17
- #define DIFF_FLAG_ISNT_SET(DIFF,FLAG) \
18
- (((DIFF)->opts.flags & (FLAG)) == 0)
19
- #define DIFF_FLAG_SET(DIFF,FLAG,VAL) (DIFF)->opts.flags = \
20
- (VAL) ? ((DIFF)->opts.flags | (FLAG)) : ((DIFF)->opts.flags & ~(VAL))
21
-
22
15
  GIT_INLINE(const char *) diff_delta__path(const git_diff_delta *delta)
23
16
  {
24
17
  const char *str = delta->old_file.path;
@@ -138,7 +138,6 @@ int git_diff_file_content__init_from_src(
138
138
  memset(fc, 0, sizeof(*fc));
139
139
  fc->repo = repo;
140
140
  fc->file = as_file;
141
- fc->blob = src->blob;
142
141
 
143
142
  if (!src->blob && !src->buf) {
144
143
  fc->flags |= GIT_DIFF_FLAG__NO_DATA;
@@ -148,12 +147,15 @@ int git_diff_file_content__init_from_src(
148
147
  fc->file->mode = GIT_FILEMODE_BLOB;
149
148
 
150
149
  if (src->blob) {
150
+ git_blob_dup((git_blob **)&fc->blob, (git_blob *) src->blob);
151
151
  fc->file->size = git_blob_rawsize(src->blob);
152
152
  git_oid_cpy(&fc->file->id, git_blob_id(src->blob));
153
153
  fc->file->id_abbrev = GIT_OID_HEXSZ;
154
154
 
155
155
  fc->map.len = (size_t)fc->file->size;
156
156
  fc->map.data = (char *)git_blob_rawcontent(src->blob);
157
+
158
+ fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
157
159
  } else {
158
160
  fc->file->size = src->buflen;
159
161
  git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJ_BLOB);
@@ -23,7 +23,7 @@
23
23
  (((DIFF)->base.opts.flags & (FLAG)) == 0)
24
24
  #define DIFF_FLAG_SET(DIFF,FLAG,VAL) (DIFF)->base.opts.flags = \
25
25
  (VAL) ? ((DIFF)->base.opts.flags | (FLAG)) : \
26
- ((DIFF)->base.opts.flags & ~(VAL))
26
+ ((DIFF)->base.opts.flags & ~(FLAG))
27
27
 
28
28
  typedef struct {
29
29
  struct git_diff base;
@@ -685,8 +685,10 @@ static bool is_rename_target(
685
685
  break;
686
686
  }
687
687
  if (FLAG_SET(opts, GIT_DIFF_FIND_RENAMES_FROM_REWRITES) &&
688
- delta->similarity < opts->rename_from_rewrite_threshold)
688
+ delta->similarity < opts->rename_from_rewrite_threshold) {
689
+ delta->flags |= GIT_DIFF_FLAG__TO_SPLIT;
689
690
  break;
691
+ }
690
692
 
691
693
  return false;
692
694
 
@@ -10,6 +10,7 @@
10
10
  #include "sysdir.h"
11
11
  #include "filter.h"
12
12
  #include "merge_driver.h"
13
+ #include "curl_stream.h"
13
14
  #include "openssl_stream.h"
14
15
  #include "thread-utils.h"
15
16
  #include "git2/global.h"
@@ -22,7 +23,7 @@
22
23
 
23
24
  git_mutex git__mwindow_mutex;
24
25
 
25
- #define MAX_SHUTDOWN_CB 9
26
+ #define MAX_SHUTDOWN_CB 10
26
27
 
27
28
  static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
28
29
  static git_atomic git__n_shutdown_callbacks;
@@ -62,7 +63,8 @@ static int init_common(void)
62
63
  (ret = git_filter_global_init()) == 0 &&
63
64
  (ret = git_merge_driver_global_init()) == 0 &&
64
65
  (ret = git_transport_ssh_global_init()) == 0 &&
65
- (ret = git_openssl_stream_global_init()) == 0)
66
+ (ret = git_openssl_stream_global_init()) == 0 &&
67
+ (ret = git_curl_stream_global_init()) == 0)
66
68
  ret = git_mwindow_global_init();
67
69
 
68
70
  GIT_MEMORY_BARRIER;
@@ -23,21 +23,36 @@ struct git_hash_ctx {
23
23
  GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
24
24
  {
25
25
  assert(ctx);
26
- SHA1_Init(&ctx->c);
26
+
27
+ if (SHA1_Init(&ctx->c) != 1) {
28
+ giterr_set(GITERR_SHA1, "hash_openssl: failed to initialize hash context");
29
+ return -1;
30
+ }
31
+
27
32
  return 0;
28
33
  }
29
34
 
30
35
  GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
31
36
  {
32
37
  assert(ctx);
33
- SHA1_Update(&ctx->c, data, len);
38
+
39
+ if (SHA1_Update(&ctx->c, data, len) != 1) {
40
+ giterr_set(GITERR_SHA1, "hash_openssl: failed to update hash");
41
+ return -1;
42
+ }
43
+
34
44
  return 0;
35
45
  }
36
46
 
37
47
  GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx)
38
48
  {
39
49
  assert(ctx);
40
- SHA1_Final(out->id, &ctx->c);
50
+
51
+ if (SHA1_Final(out->id, &ctx->c) != 1) {
52
+ giterr_set(GITERR_SHA1, "hash_openssl: failed to finalize hash");
53
+ return -1;
54
+ }
55
+
41
56
  return 0;
42
57
  }
43
58
 
@@ -40,38 +40,42 @@
40
40
  */
41
41
  static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
42
42
  {
43
+ int (*cmp)(const char *, const char *, size_t);
43
44
  git_attr_fnmatch *longer, *shorter;
44
45
  char *p;
45
46
 
46
- if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0
47
- && (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0) {
48
-
49
- /* If lengths match we need to have an exact match */
50
- if (rule->length == neg->length) {
51
- return strcmp(rule->pattern, neg->pattern) == 0;
52
- } else if (rule->length < neg->length) {
53
- shorter = rule;
54
- longer = neg;
55
- } else {
56
- shorter = neg;
57
- longer = rule;
58
- }
59
-
60
- /* Otherwise, we need to check if the shorter
61
- * rule is a basename only (that is, it contains
62
- * no path separator) and, if so, if it
63
- * matches the tail of the longer rule */
64
- p = longer->pattern + longer->length - shorter->length;
47
+ if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0
48
+ || (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0)
49
+ return false;
50
+
51
+ if (neg->flags & GIT_ATTR_FNMATCH_ICASE)
52
+ cmp = git__strncasecmp;
53
+ else
54
+ cmp = git__strncmp;
55
+
56
+ /* If lengths match we need to have an exact match */
57
+ if (rule->length == neg->length) {
58
+ return cmp(rule->pattern, neg->pattern, rule->length) == 0;
59
+ } else if (rule->length < neg->length) {
60
+ shorter = rule;
61
+ longer = neg;
62
+ } else {
63
+ shorter = neg;
64
+ longer = rule;
65
+ }
65
66
 
66
- if (p[-1] != '/')
67
- return false;
68
- if (memchr(shorter->pattern, '/', shorter->length) != NULL)
69
- return false;
67
+ /* Otherwise, we need to check if the shorter
68
+ * rule is a basename only (that is, it contains
69
+ * no path separator) and, if so, if it
70
+ * matches the tail of the longer rule */
71
+ p = longer->pattern + longer->length - shorter->length;
70
72
 
71
- return memcmp(p, shorter->pattern, shorter->length) == 0;
72
- }
73
+ if (p[-1] != '/')
74
+ return false;
75
+ if (memchr(shorter->pattern, '/', shorter->length) != NULL)
76
+ return false;
73
77
 
74
- return false;
78
+ return cmp(p, shorter->pattern, shorter->length) == 0;
75
79
  }
76
80
 
77
81
  /**
@@ -89,7 +93,7 @@ static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
89
93
  */
90
94
  static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match)
91
95
  {
92
- int error = 0;
96
+ int error = 0, fnflags;
93
97
  size_t i;
94
98
  git_attr_fnmatch *rule;
95
99
  char *path;
@@ -97,6 +101,10 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
97
101
 
98
102
  *out = 0;
99
103
 
104
+ fnflags = FNM_PATHNAME;
105
+ if (match->flags & GIT_ATTR_FNMATCH_ICASE)
106
+ fnflags |= FNM_IGNORECASE;
107
+
100
108
  /* path of the file relative to the workdir, so we match the rules in subdirs */
101
109
  if (match->containing_dir) {
102
110
  git_buf_puts(&buf, match->containing_dir);
@@ -117,12 +125,12 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
117
125
  continue;
118
126
  }
119
127
 
120
- /*
121
- * When dealing with a directory, we add '/<star>' so
122
- * p_fnmatch() honours FNM_PATHNAME. Checking for LEADINGDIR
123
- * alone isn't enough as that's also set for nagations, so we
124
- * need to check that NEGATIVE is off.
125
- */
128
+ /*
129
+ * When dealing with a directory, we add '/<star>' so
130
+ * p_fnmatch() honours FNM_PATHNAME. Checking for LEADINGDIR
131
+ * alone isn't enough as that's also set for nagations, so we
132
+ * need to check that NEGATIVE is off.
133
+ */
126
134
  git_buf_clear(&buf);
127
135
  if (rule->containing_dir) {
128
136
  git_buf_puts(&buf, rule->containing_dir);
@@ -136,7 +144,7 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
136
144
  if (error < 0)
137
145
  goto out;
138
146
 
139
- if ((error = p_fnmatch(git_buf_cstr(&buf), path, FNM_PATHNAME)) < 0) {
147
+ if ((error = p_fnmatch(git_buf_cstr(&buf), path, fnflags)) < 0) {
140
148
  giterr_set(GITERR_INVALID, "error matching pattern");
141
149
  goto out;
142
150
  }
@@ -197,10 +205,26 @@ static int parse_ignore_file(
197
205
  if (ignore_case)
198
206
  match->flags |= GIT_ATTR_FNMATCH_ICASE;
199
207
 
208
+ while (match->length > 0) {
209
+ if (match->pattern[match->length - 1] == ' ' ||
210
+ match->pattern[match->length - 1] == '\t') {
211
+ match->pattern[match->length - 1] = 0;
212
+ match->length --;
213
+ } else {
214
+ break;
215
+ }
216
+ }
217
+
200
218
  scan = git__next_line(scan);
201
219
 
202
- /* if a negative match doesn't actually do anything, throw it away */
203
- if (match->flags & GIT_ATTR_FNMATCH_NEGATIVE)
220
+ /*
221
+ * If a negative match doesn't actually do anything,
222
+ * throw it away. As we cannot always verify whether a
223
+ * rule containing wildcards negates another rule, we
224
+ * do not optimize away these rules, though.
225
+ * */
226
+ if (match->flags & GIT_ATTR_FNMATCH_NEGATIVE
227
+ && !(match->flags & GIT_ATTR_FNMATCH_HASWILD))
204
228
  error = does_negate_rule(&valid_rule, &attrs->rules, match);
205
229
 
206
230
  if (!error && valid_rule)
@@ -884,11 +884,13 @@ static int index_entry_create(
884
884
  git_index_entry **out,
885
885
  git_repository *repo,
886
886
  const char *path,
887
+ struct stat *st,
887
888
  bool from_workdir)
888
889
  {
889
890
  size_t pathlen = strlen(path), alloclen;
890
891
  struct entry_internal *entry;
891
892
  unsigned int path_valid_flags = GIT_PATH_REJECT_INDEX_DEFAULTS;
893
+ uint16_t mode = 0;
892
894
 
893
895
  /* always reject placing `.git` in the index and directory traversal.
894
896
  * when requested, disallow platform-specific filenames and upgrade to
@@ -896,8 +898,10 @@ static int index_entry_create(
896
898
  */
897
899
  if (from_workdir)
898
900
  path_valid_flags |= GIT_PATH_REJECT_WORKDIR_DEFAULTS;
901
+ if (st)
902
+ mode = st->st_mode;
899
903
 
900
- if (!git_path_isvalid(repo, path, path_valid_flags)) {
904
+ if (!git_path_isvalid(repo, path, mode, path_valid_flags)) {
901
905
  giterr_set(GITERR_INDEX, "invalid path: '%s'", path);
902
906
  return -1;
903
907
  }
@@ -922,15 +926,35 @@ static int index_entry_init(
922
926
  {
923
927
  int error = 0;
924
928
  git_index_entry *entry = NULL;
929
+ git_buf path = GIT_BUF_INIT;
925
930
  struct stat st;
926
931
  git_oid oid;
932
+ git_repository *repo;
927
933
 
928
934
  if (INDEX_OWNER(index) == NULL)
929
935
  return create_index_error(-1,
930
936
  "could not initialize index entry. "
931
937
  "Index is not backed up by an existing repository.");
932
938
 
933
- if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, true) < 0)
939
+ /*
940
+ * FIXME: this is duplicated with the work in
941
+ * git_blob__create_from_paths. It should accept an optional stat
942
+ * structure so we can pass in the one we have to do here.
943
+ */
944
+ repo = INDEX_OWNER(index);
945
+ if (git_repository__ensure_not_bare(repo, "create blob from file") < 0)
946
+ return GIT_EBAREREPO;
947
+
948
+ if (git_buf_joinpath(&path, git_repository_workdir(repo), rel_path) < 0)
949
+ return -1;
950
+
951
+ error = git_path_lstat(path.ptr, &st);
952
+ git_buf_free(&path);
953
+
954
+ if (error < 0)
955
+ return error;
956
+
957
+ if (index_entry_create(&entry, INDEX_OWNER(index), rel_path, &st, true) < 0)
934
958
  return -1;
935
959
 
936
960
  /* write the blob to disk and get the oid and stat info */
@@ -1016,7 +1040,7 @@ static int index_entry_dup(
1016
1040
  git_index *index,
1017
1041
  const git_index_entry *src)
1018
1042
  {
1019
- if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
1043
+ if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
1020
1044
  return -1;
1021
1045
 
1022
1046
  index_entry_cpy(*out, src);
@@ -1038,7 +1062,7 @@ static int index_entry_dup_nocache(
1038
1062
  git_index *index,
1039
1063
  const git_index_entry *src)
1040
1064
  {
1041
- if (index_entry_create(out, INDEX_OWNER(index), src->path, false) < 0)
1065
+ if (index_entry_create(out, INDEX_OWNER(index), src->path, NULL, false) < 0)
1042
1066
  return -1;
1043
1067
 
1044
1068
  index_entry_cpy_nocache(*out, src);
@@ -1457,9 +1481,6 @@ static int add_repo_as_submodule(git_index_entry **out, git_index *index, const
1457
1481
  struct stat st;
1458
1482
  int error;
1459
1483
 
1460
- if (index_entry_create(&entry, INDEX_OWNER(index), path, true) < 0)
1461
- return -1;
1462
-
1463
1484
  if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
1464
1485
  return error;
1465
1486
 
@@ -1468,6 +1489,9 @@ static int add_repo_as_submodule(git_index_entry **out, git_index *index, const
1468
1489
  return -1;
1469
1490
  }
1470
1491
 
1492
+ if (index_entry_create(&entry, INDEX_OWNER(index), path, &st, true) < 0)
1493
+ return -1;
1494
+
1471
1495
  git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
1472
1496
 
1473
1497
  if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
@@ -2295,8 +2319,9 @@ static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flag
2295
2319
  }
2296
2320
  }
2297
2321
 
2298
- static size_t read_entry(
2322
+ static int read_entry(
2299
2323
  git_index_entry **out,
2324
+ size_t *out_size,
2300
2325
  git_index *index,
2301
2326
  const void *buffer,
2302
2327
  size_t buffer_size,
@@ -2310,7 +2335,7 @@ static size_t read_entry(
2310
2335
  char *tmp_path = NULL;
2311
2336
 
2312
2337
  if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
2313
- return 0;
2338
+ return -1;
2314
2339
 
2315
2340
  /* buffer is not guaranteed to be aligned */
2316
2341
  memcpy(&source, buffer, sizeof(struct entry_short));
@@ -2352,7 +2377,7 @@ static size_t read_entry(
2352
2377
 
2353
2378
  path_end = memchr(path_ptr, '\0', buffer_size);
2354
2379
  if (path_end == NULL)
2355
- return 0;
2380
+ return -1;
2356
2381
 
2357
2382
  path_length = path_end - path_ptr;
2358
2383
  }
@@ -2360,19 +2385,24 @@ static size_t read_entry(
2360
2385
  entry_size = index_entry_size(path_length, 0, entry.flags);
2361
2386
  entry.path = (char *)path_ptr;
2362
2387
  } else {
2363
- size_t varint_len;
2364
- size_t strip_len = git_decode_varint((const unsigned char *)path_ptr,
2365
- &varint_len);
2366
- size_t last_len = strlen(last);
2367
- size_t prefix_len = last_len - strip_len;
2368
- size_t suffix_len = strlen(path_ptr + varint_len);
2369
- size_t path_len;
2370
-
2371
- if (varint_len == 0)
2388
+ size_t varint_len, last_len, prefix_len, suffix_len, path_len;
2389
+ uintmax_t strip_len;
2390
+
2391
+ strip_len = git_decode_varint((const unsigned char *)path_ptr, &varint_len);
2392
+ last_len = strlen(last);
2393
+
2394
+ if (varint_len == 0 || last_len < strip_len)
2372
2395
  return index_error_invalid("incorrect prefix length");
2373
2396
 
2397
+ prefix_len = last_len - strip_len;
2398
+ suffix_len = strlen(path_ptr + varint_len);
2399
+
2374
2400
  GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len);
2375
2401
  GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1);
2402
+
2403
+ if (path_len > GIT_PATH_MAX)
2404
+ return index_error_invalid("unreasonable path length");
2405
+
2376
2406
  tmp_path = git__malloc(path_len);
2377
2407
  GITERR_CHECK_ALLOC(tmp_path);
2378
2408
 
@@ -2382,16 +2412,20 @@ static size_t read_entry(
2382
2412
  entry.path = tmp_path;
2383
2413
  }
2384
2414
 
2415
+ if (entry_size == 0)
2416
+ return -1;
2417
+
2385
2418
  if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
2386
- return 0;
2419
+ return -1;
2387
2420
 
2388
2421
  if (index_entry_dup(out, index, &entry) < 0) {
2389
2422
  git__free(tmp_path);
2390
- return 0;
2423
+ return -1;
2391
2424
  }
2392
2425
 
2393
2426
  git__free(tmp_path);
2394
- return entry_size;
2427
+ *out_size = entry_size;
2428
+ return 0;
2395
2429
  }
2396
2430
 
2397
2431
  static int read_header(struct index_header *dest, const void *buffer)
@@ -2495,10 +2529,9 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2495
2529
  /* Parse all the entries */
2496
2530
  for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
2497
2531
  git_index_entry *entry;
2498
- size_t entry_size = read_entry(&entry, index, buffer, buffer_size, last);
2532
+ size_t entry_size;
2499
2533
 
2500
- /* 0 bytes read means an object corruption */
2501
- if (entry_size == 0) {
2534
+ if ((error = read_entry(&entry, &entry_size, index, buffer, buffer_size, last)) < 0) {
2502
2535
  error = index_error_invalid("invalid entry");
2503
2536
  goto done;
2504
2537
  }
@@ -2952,7 +2985,7 @@ static int read_tree_cb(
2952
2985
  if (git_buf_joinpath(&path, root, tentry->filename) < 0)
2953
2986
  return -1;
2954
2987
 
2955
- if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, false) < 0)
2988
+ if (index_entry_create(&entry, INDEX_OWNER(data->index), path.ptr, NULL, false) < 0)
2956
2989
  return -1;
2957
2990
 
2958
2991
  entry->mode = tentry->attr;