rugged 0.26.3 → 0.26.6

Sign up to get free protection for your applications and to get access to all the features.
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;