rugged 0.24.0 → 0.24.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/CMakeLists.txt +20 -9
  4. data/vendor/libgit2/deps/http-parser/http_parser.c +5 -2
  5. data/vendor/libgit2/include/git2/checkout.h +7 -0
  6. data/vendor/libgit2/include/git2/common.h +16 -1
  7. data/vendor/libgit2/include/git2/version.h +2 -2
  8. data/vendor/libgit2/src/array.h +40 -0
  9. data/vendor/libgit2/src/blame.c +8 -3
  10. data/vendor/libgit2/src/blame_git.c +20 -9
  11. data/vendor/libgit2/src/checkout.c +13 -5
  12. data/vendor/libgit2/src/commit.c +5 -4
  13. data/vendor/libgit2/src/common.h +1 -1
  14. data/vendor/libgit2/src/config_cache.c +2 -1
  15. data/vendor/libgit2/src/config_file.c +14 -20
  16. data/vendor/libgit2/src/delta-apply.c +36 -5
  17. data/vendor/libgit2/src/delta-apply.h +12 -0
  18. data/vendor/libgit2/src/describe.c +2 -1
  19. data/vendor/libgit2/src/diff_tform.c +5 -3
  20. data/vendor/libgit2/src/filebuf.c +6 -1
  21. data/vendor/libgit2/src/global.c +28 -8
  22. data/vendor/libgit2/src/global.h +1 -0
  23. data/vendor/libgit2/src/ignore.c +56 -19
  24. data/vendor/libgit2/src/index.c +27 -8
  25. data/vendor/libgit2/src/indexer.c +11 -7
  26. data/vendor/libgit2/src/iterator.c +2 -2
  27. data/vendor/libgit2/src/merge.c +1 -0
  28. data/vendor/libgit2/src/mwindow.c +20 -21
  29. data/vendor/libgit2/src/mwindow.h +1 -2
  30. data/vendor/libgit2/src/object.c +3 -6
  31. data/vendor/libgit2/src/odb.c +11 -15
  32. data/vendor/libgit2/src/odb.h +2 -1
  33. data/vendor/libgit2/src/odb_loose.c +13 -9
  34. data/vendor/libgit2/src/odb_pack.c +5 -6
  35. data/vendor/libgit2/src/oid.h +9 -0
  36. data/vendor/libgit2/src/openssl_stream.c +60 -27
  37. data/vendor/libgit2/src/openssl_stream.h +106 -0
  38. data/vendor/libgit2/src/pack-objects.c +4 -2
  39. data/vendor/libgit2/src/pack.c +10 -14
  40. data/vendor/libgit2/src/posix.c +7 -0
  41. data/vendor/libgit2/src/posix.h +1 -0
  42. data/vendor/libgit2/src/push.c +6 -6
  43. data/vendor/libgit2/src/refdb_fs.c +1 -0
  44. data/vendor/libgit2/src/refs.c +3 -0
  45. data/vendor/libgit2/src/refspec.c +4 -2
  46. data/vendor/libgit2/src/remote.c +15 -5
  47. data/vendor/libgit2/src/repository.c +29 -21
  48. data/vendor/libgit2/src/settings.c +23 -1
  49. data/vendor/libgit2/src/stransport_stream.c +15 -9
  50. data/vendor/libgit2/src/submodule.c +3 -2
  51. data/vendor/libgit2/src/sysdir.c +41 -47
  52. data/vendor/libgit2/src/sysdir.h +0 -5
  53. data/vendor/libgit2/src/tag.c +8 -2
  54. data/vendor/libgit2/src/thread-utils.h +5 -51
  55. data/vendor/libgit2/src/transport.c +2 -0
  56. data/vendor/libgit2/src/transports/http.c +2 -1
  57. data/vendor/libgit2/src/transports/smart_pkt.c +1 -0
  58. data/vendor/libgit2/src/transports/smart_protocol.c +72 -17
  59. data/vendor/libgit2/src/transports/ssh.c +32 -17
  60. data/vendor/libgit2/src/tree.c +83 -100
  61. data/vendor/libgit2/src/tree.h +4 -5
  62. data/vendor/libgit2/src/unix/map.c +5 -0
  63. data/vendor/libgit2/src/unix/pthread.h +54 -0
  64. data/vendor/libgit2/src/util.c +3 -3
  65. data/vendor/libgit2/src/win32/map.c +24 -5
  66. data/vendor/libgit2/src/win32/precompiled.h +1 -1
  67. data/vendor/libgit2/src/win32/{pthread.c → thread.c} +50 -80
  68. data/vendor/libgit2/src/win32/thread.h +62 -0
  69. data/vendor/libgit2/src/xdiff/xprepare.c +2 -1
  70. metadata +384 -394
  71. data/vendor/libgit2/src/win32/pthread.h +0 -92
@@ -49,6 +49,37 @@ int git__delta_read_header(
49
49
  return 0;
50
50
  }
51
51
 
52
+ #define DELTA_HEADER_BUFFER_LEN 16
53
+ int git__delta_read_header_fromstream(size_t *base_sz, size_t *res_sz, git_packfile_stream *stream)
54
+ {
55
+ static const size_t buffer_len = DELTA_HEADER_BUFFER_LEN;
56
+ unsigned char buffer[DELTA_HEADER_BUFFER_LEN];
57
+ const unsigned char *delta, *delta_end;
58
+ size_t len;
59
+ ssize_t read;
60
+
61
+ len = read = 0;
62
+ while (len < buffer_len) {
63
+ read = git_packfile_stream_read(stream, &buffer[len], buffer_len - len);
64
+
65
+ if (read == 0)
66
+ break;
67
+
68
+ if (read == GIT_EBUFS)
69
+ continue;
70
+
71
+ len += read;
72
+ }
73
+
74
+ delta = buffer;
75
+ delta_end = delta + len;
76
+ if ((hdr_sz(base_sz, &delta, delta_end) < 0) ||
77
+ (hdr_sz(res_sz, &delta, delta_end) < 0))
78
+ return -1;
79
+
80
+ return 0;
81
+ }
82
+
52
83
  int git__delta_apply(
53
84
  git_rawobj *out,
54
85
  const unsigned char *base,
@@ -90,13 +121,13 @@ int git__delta_apply(
90
121
  size_t off = 0, len = 0;
91
122
 
92
123
  if (cmd & 0x01) off = *delta++;
93
- if (cmd & 0x02) off |= *delta++ << 8;
94
- if (cmd & 0x04) off |= *delta++ << 16;
95
- if (cmd & 0x08) off |= *delta++ << 24;
124
+ if (cmd & 0x02) off |= *delta++ << 8UL;
125
+ if (cmd & 0x04) off |= *delta++ << 16UL;
126
+ if (cmd & 0x08) off |= *delta++ << 24UL;
96
127
 
97
128
  if (cmd & 0x10) len = *delta++;
98
- if (cmd & 0x20) len |= *delta++ << 8;
99
- if (cmd & 0x40) len |= *delta++ << 16;
129
+ if (cmd & 0x20) len |= *delta++ << 8UL;
130
+ if (cmd & 0x40) len |= *delta++ << 16UL;
100
131
  if (!len) len = 0x10000;
101
132
 
102
133
  if (base_len < off + len || res_sz < len)
@@ -8,6 +8,7 @@
8
8
  #define INCLUDE_delta_apply_h__
9
9
 
10
10
  #include "odb.h"
11
+ #include "pack.h"
11
12
 
12
13
  /**
13
14
  * Apply a git binary delta to recover the original content.
@@ -47,4 +48,15 @@ extern int git__delta_read_header(
47
48
  size_t *base_sz,
48
49
  size_t *res_sz);
49
50
 
51
+ /**
52
+ * Read the header of a git binary delta
53
+ *
54
+ * This variant reads just enough from the packfile stream to read the
55
+ * delta header.
56
+ */
57
+ extern int git__delta_read_header_fromstream(
58
+ size_t *base_sz,
59
+ size_t *res_sz,
60
+ git_packfile_stream *stream);
61
+
50
62
  #endif
@@ -582,7 +582,8 @@ static int describe(
582
582
  best = (struct possible_tag *)git_vector_get(&all_matches, 0);
583
583
 
584
584
  if (gave_up_on) {
585
- git_pqueue_insert(&list, gave_up_on);
585
+ if ((error = git_pqueue_insert(&list, gave_up_on)) < 0)
586
+ goto cleanup;
586
587
  seen_commits--;
587
588
  }
588
589
  if ((error = finish_depth_computation(
@@ -261,7 +261,7 @@ static int normalize_find_opts(
261
261
  if (!given ||
262
262
  (given->flags & GIT_DIFF_FIND_ALL) == GIT_DIFF_FIND_BY_CONFIG)
263
263
  {
264
- if (diff->repo) {
264
+ if (cfg) {
265
265
  char *rule =
266
266
  git_config__get_string_force(cfg, "diff.renames", "true");
267
267
  int boolval;
@@ -318,8 +318,10 @@ static int normalize_find_opts(
318
318
  #undef USE_DEFAULT
319
319
 
320
320
  if (!opts->rename_limit) {
321
- opts->rename_limit = git_config__get_int_force(
322
- cfg, "diff.renamelimit", DEFAULT_RENAME_LIMIT);
321
+ if (cfg) {
322
+ opts->rename_limit = git_config__get_int_force(
323
+ cfg, "diff.renamelimit", DEFAULT_RENAME_LIMIT);
324
+ }
323
325
 
324
326
  if (opts->rename_limit <= 0)
325
327
  opts->rename_limit = DEFAULT_RENAME_LIMIT;
@@ -70,6 +70,7 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
70
70
  git_file source;
71
71
  char buffer[FILEIO_BUFSIZE];
72
72
  ssize_t read_bytes;
73
+ int error = 0;
73
74
 
74
75
  source = p_open(file->path_original, O_RDONLY);
75
76
  if (source < 0) {
@@ -80,7 +81,8 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
80
81
  }
81
82
 
82
83
  while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) {
83
- p_write(file->fd, buffer, read_bytes);
84
+ if ((error = p_write(file->fd, buffer, read_bytes)) < 0)
85
+ break;
84
86
  if (file->compute_digest)
85
87
  git_hash_update(&file->digest, buffer, read_bytes);
86
88
  }
@@ -90,6 +92,9 @@ static int lock_file(git_filebuf *file, int flags, mode_t mode)
90
92
  if (read_bytes < 0) {
91
93
  giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original);
92
94
  return -1;
95
+ } else if (error < 0) {
96
+ giterr_set(GITERR_OS, "Failed to write file '%s'", file->path_lock);
97
+ return -1;
93
98
  }
94
99
  }
95
100
 
@@ -27,6 +27,7 @@ static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
27
27
  static git_atomic git__n_shutdown_callbacks;
28
28
  static git_atomic git__n_inits;
29
29
  char *git__user_agent;
30
+ char *git__ssl_ciphers;
30
31
 
31
32
  void git__on_shutdown(git_global_shutdown_fn callback)
32
33
  {
@@ -58,8 +59,9 @@ static int init_common(void)
58
59
  if ((ret = git_hash_global_init()) == 0 &&
59
60
  (ret = git_sysdir_global_init()) == 0 &&
60
61
  (ret = git_filter_global_init()) == 0 &&
61
- (ret = git_transport_ssh_global_init()) == 0)
62
- ret = git_openssl_stream_global_init();
62
+ (ret = git_transport_ssh_global_init()) == 0 &&
63
+ (ret = git_openssl_stream_global_init()) == 0)
64
+ ret = git_mwindow_global_init();
63
65
 
64
66
  GIT_MEMORY_BARRIER;
65
67
 
@@ -83,11 +85,7 @@ static void shutdown_common(void)
83
85
  }
84
86
 
85
87
  git__free(git__user_agent);
86
-
87
- #if defined(GIT_MSVC_CRTDBG)
88
- git_win32__crtdbg_stacktrace_cleanup();
89
- git_win32__stack_cleanup();
90
- #endif
88
+ git__free(git__ssl_ciphers);
91
89
  }
92
90
 
93
91
  /**
@@ -135,7 +133,7 @@ static int synchronized_threads_init(void)
135
133
 
136
134
  _tls_index = TlsAlloc();
137
135
 
138
- win32_pthread_initialize();
136
+ git_threads_init();
139
137
 
140
138
  if (git_mutex_init(&git__mwindow_mutex))
141
139
  return -1;
@@ -179,6 +177,11 @@ int git_libgit2_shutdown(void)
179
177
 
180
178
  TlsFree(_tls_index);
181
179
  git_mutex_free(&git__mwindow_mutex);
180
+
181
+ #if defined(GIT_MSVC_CRTDBG)
182
+ git_win32__crtdbg_stacktrace_cleanup();
183
+ git_win32__stack_cleanup();
184
+ #endif
182
185
  }
183
186
 
184
187
  /* Exit the lock */
@@ -222,6 +225,23 @@ void git__free_tls_data(void)
222
225
  TlsSetValue(_tls_index, NULL);
223
226
  }
224
227
 
228
+ BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
229
+ {
230
+ GIT_UNUSED(hInstDll);
231
+ GIT_UNUSED(lpvReserved);
232
+
233
+ /* This is how Windows lets us know our thread is being shut down */
234
+ if (fdwReason == DLL_THREAD_DETACH) {
235
+ git__free_tls_data();
236
+ }
237
+
238
+ /*
239
+ * Windows pays attention to this during library loading. We don't do anything
240
+ * so we trivially succeed.
241
+ */
242
+ return TRUE;
243
+ }
244
+
225
245
  #elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
226
246
 
227
247
  static pthread_key_t _tls_key;
@@ -36,5 +36,6 @@ extern void git__on_shutdown(git_global_shutdown_fn callback);
36
36
  extern void git__free_tls_data(void);
37
37
 
38
38
  extern const char *git_libgit2__user_agent(void);
39
+ extern const char *git_libgit2__ssl_ciphers(void);
39
40
 
40
41
  #endif
@@ -11,35 +11,64 @@
11
11
  #define GIT_IGNORE_DEFAULT_RULES ".\n..\n.git\n"
12
12
 
13
13
  /**
14
- * A negative ignore pattern can match a positive one without
15
- * wildcards if its pattern equals the tail of the positive
16
- * pattern. Thus
14
+ * A negative ignore pattern can negate a positive one without
15
+ * wildcards if it is a basename only and equals the basename of
16
+ * the positive pattern. Thus
17
17
  *
18
18
  * foo/bar
19
19
  * !bar
20
20
  *
21
- * would result in foo/bar being unignored again.
21
+ * would result in foo/bar being unignored again while
22
+ *
23
+ * moo/foo/bar
24
+ * !foo/bar
25
+ *
26
+ * would do nothing. The reverse also holds true: a positive
27
+ * basename pattern can be negated by unignoring the basename in
28
+ * subdirectories. Thus
29
+ *
30
+ * bar
31
+ * !foo/bar
32
+ *
33
+ * would result in foo/bar being unignored again. As with the
34
+ * first case,
35
+ *
36
+ * foo/bar
37
+ * !moo/foo/bar
38
+ *
39
+ * would do nothing, again.
22
40
  */
23
41
  static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
24
42
  {
43
+ git_attr_fnmatch *longer, *shorter;
25
44
  char *p;
26
45
 
27
46
  if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0
28
47
  && (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0) {
29
- /*
30
- * no chance of matching if rule is shorter than
31
- * the negated one
32
- */
33
- if (rule->length < neg->length)
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;
65
+
66
+ if (p[-1] != '/')
67
+ return false;
68
+ if (memchr(shorter->pattern, '/', shorter->length) != NULL)
34
69
  return false;
35
70
 
36
- /*
37
- * shift pattern so its tail aligns with the
38
- * negated pattern
39
- */
40
- p = rule->pattern + rule->length - neg->length;
41
- if (strcmp(p, neg->pattern) == 0)
42
- return true;
71
+ return memcmp(p, shorter->pattern, shorter->length) == 0;
43
72
  }
44
73
 
45
74
  return false;
@@ -263,10 +292,18 @@ int git_ignore__for_path(
263
292
  goto cleanup;
264
293
 
265
294
  /* given a unrooted path in a non-bare repo, resolve it */
266
- if (workdir && git_path_root(path) < 0)
267
- error = git_path_find_dir(&ignores->dir, path, workdir);
268
- else
295
+ if (workdir && git_path_root(path) < 0) {
296
+ git_buf local = GIT_BUF_INIT;
297
+
298
+ if ((error = git_path_dirname_r(&local, path)) < 0 ||
299
+ (error = git_path_resolve_relative(&local, 0)) < 0 ||
300
+ (error = git_path_to_dir(&local)) < 0 ||
301
+ (error = git_buf_joinpath(&ignores->dir, workdir, local.ptr)) < 0)
302
+ {;} /* Nothing, we just want to stop on the first error */
303
+ git_buf_free(&local);
304
+ } else {
269
305
  error = git_buf_joinpath(&ignores->dir, path, "");
306
+ }
270
307
  if (error < 0)
271
308
  goto cleanup;
272
309
 
@@ -505,10 +505,11 @@ static int index_remove_entry(git_index *index, size_t pos)
505
505
  int error = 0;
506
506
  git_index_entry *entry = git_vector_get(&index->entries, pos);
507
507
 
508
- if (entry != NULL)
508
+ if (entry != NULL) {
509
509
  git_tree_cache_invalidate_path(index->tree, entry->path);
510
+ DELETE_IN_MAP(index, entry);
511
+ }
510
512
 
511
- DELETE_IN_MAP(index, entry);
512
513
  error = git_vector_remove(&index->entries, pos);
513
514
 
514
515
  if (!error) {
@@ -963,14 +964,20 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
963
964
  *reuc_out = reuc = reuc_entry_alloc(path);
964
965
  GITERR_CHECK_ALLOC(reuc);
965
966
 
966
- if ((reuc->mode[0] = ancestor_mode) > 0)
967
+ if ((reuc->mode[0] = ancestor_mode) > 0) {
968
+ assert(ancestor_oid);
967
969
  git_oid_cpy(&reuc->oid[0], ancestor_oid);
970
+ }
968
971
 
969
- if ((reuc->mode[1] = our_mode) > 0)
972
+ if ((reuc->mode[1] = our_mode) > 0) {
973
+ assert(our_oid);
970
974
  git_oid_cpy(&reuc->oid[1], our_oid);
975
+ }
971
976
 
972
- if ((reuc->mode[2] = their_mode) > 0)
977
+ if ((reuc->mode[2] = their_mode) > 0) {
978
+ assert(their_oid);
973
979
  git_oid_cpy(&reuc->oid[2], their_oid);
980
+ }
974
981
 
975
982
  return 0;
976
983
  }
@@ -2830,7 +2837,7 @@ static int read_tree_cb(
2830
2837
  return -1;
2831
2838
 
2832
2839
  entry->mode = tentry->attr;
2833
- entry->id = tentry->oid;
2840
+ git_oid_cpy(&entry->id, git_tree_entry_id(tentry));
2834
2841
 
2835
2842
  /* look for corresponding old entry and copy data to new entry */
2836
2843
  if (data->old_entries != NULL &&
@@ -2962,6 +2969,8 @@ int git_index_read_index(
2962
2969
  *remove_entry = NULL;
2963
2970
  int diff;
2964
2971
 
2972
+ error = 0;
2973
+
2965
2974
  if (old_entry && new_entry)
2966
2975
  diff = git_index_entry_cmp(old_entry, new_entry);
2967
2976
  else if (!old_entry && new_entry)
@@ -2979,7 +2988,8 @@ int git_index_read_index(
2979
2988
  /* Path and stage are equal, if the OID is equal, keep it to
2980
2989
  * keep the stat cache data.
2981
2990
  */
2982
- if (git_oid_equal(&old_entry->id, &new_entry->id)) {
2991
+ if (git_oid_equal(&old_entry->id, &new_entry->id) &&
2992
+ old_entry->mode == new_entry->mode) {
2983
2993
  add_entry = (git_index_entry *)old_entry;
2984
2994
  } else {
2985
2995
  dup_entry = (git_index_entry *)new_entry;
@@ -2990,8 +3000,17 @@ int git_index_read_index(
2990
3000
  if (dup_entry) {
2991
3001
  if ((error = index_entry_dup_nocache(&add_entry, index, dup_entry)) < 0)
2992
3002
  goto done;
3003
+
3004
+ index_entry_adjust_namemask(add_entry,
3005
+ ((struct entry_internal *)add_entry)->pathlen);
2993
3006
  }
2994
3007
 
3008
+ /* invalidate this path in the tree cache if this is new (to
3009
+ * invalidate the parent trees)
3010
+ */
3011
+ if (dup_entry && !remove_entry && index->tree)
3012
+ git_tree_cache_invalidate_path(index->tree, dup_entry->path);
3013
+
2995
3014
  if (add_entry) {
2996
3015
  if ((error = git_vector_insert(&new_entries, add_entry)) == 0)
2997
3016
  INSERT_IN_MAP_EX(index, new_entries_map, add_entry, error);
@@ -3002,7 +3021,7 @@ int git_index_read_index(
3002
3021
 
3003
3022
  if (error < 0) {
3004
3023
  giterr_set(GITERR_INDEX, "failed to insert entry");
3005
- return error;
3024
+ goto done;
3006
3025
  }
3007
3026
 
3008
3027
  if (diff <= 0) {
@@ -449,7 +449,7 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
449
449
  static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t size)
450
450
  {
451
451
  git_file fd = idx->pack->mwf.fd;
452
- size_t page_size;
452
+ size_t mmap_alignment;
453
453
  size_t page_offset;
454
454
  git_off_t page_start;
455
455
  unsigned char *map_data;
@@ -458,11 +458,11 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
458
458
 
459
459
  assert(data && size);
460
460
 
461
- if ((error = git__page_size(&page_size)) < 0)
461
+ if ((error = git__mmap_alignment(&mmap_alignment)) < 0)
462
462
  return error;
463
463
 
464
- /* the offset needs to be at the beginning of the a page boundary */
465
- page_offset = offset % page_size;
464
+ /* the offset needs to be at the mmap boundary for the platform */
465
+ page_offset = offset % mmap_alignment;
466
466
  page_start = offset - page_offset;
467
467
 
468
468
  if ((error = p_mmap(&map, page_offset + size, GIT_PROT_WRITE, GIT_MAP_SHARED, fd, page_start)) < 0)
@@ -777,7 +777,6 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
777
777
 
778
778
  curpos = delta->delta_off;
779
779
  error = git_packfile_unpack_header(&size, &type, &idx->pack->mwf, &w, &curpos);
780
- git_mwindow_close(&w);
781
780
  if (error < 0)
782
781
  return error;
783
782
 
@@ -914,12 +913,17 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
914
913
  git_filebuf index_file = {0};
915
914
  void *packfile_trailer;
916
915
 
916
+ if (!idx->parsed_header) {
917
+ giterr_set(GITERR_INDEXER, "incomplete pack header");
918
+ return -1;
919
+ }
920
+
917
921
  if (git_hash_ctx_init(&ctx) < 0)
918
922
  return -1;
919
923
 
920
924
  /* Test for this before resolve_deltas(), as it plays with idx->off */
921
- if (idx->off < idx->pack->mwf.size - 20) {
922
- giterr_set(GITERR_INDEXER, "Unexpected data at the end of the pack");
925
+ if (idx->off + 20 < idx->pack->mwf.size) {
926
+ giterr_set(GITERR_INDEXER, "unexpected data at the end of the pack");
923
927
  return -1;
924
928
  }
925
929