rugged 1.1.0 → 1.1.1

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 (50) 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/ntlmclient/CMakeLists.txt +1 -0
  5. data/vendor/libgit2/deps/ntlmclient/compat.h +0 -34
  6. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +1 -1
  7. data/vendor/libgit2/deps/ntlmclient/ntlm.c +5 -5
  8. data/vendor/libgit2/deps/ntlmclient/util.c +15 -1
  9. data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
  10. data/vendor/libgit2/include/git2/apply.h +2 -0
  11. data/vendor/libgit2/include/git2/blob.h +17 -1
  12. data/vendor/libgit2/include/git2/common.h +5 -0
  13. data/vendor/libgit2/include/git2/config.h +1 -1
  14. data/vendor/libgit2/include/git2/diff.h +1 -1
  15. data/vendor/libgit2/include/git2/index.h +2 -2
  16. data/vendor/libgit2/include/git2/indexer.h +2 -1
  17. data/vendor/libgit2/include/git2/odb.h +15 -20
  18. data/vendor/libgit2/include/git2/refs.h +3 -3
  19. data/vendor/libgit2/include/git2/repository.h +95 -52
  20. data/vendor/libgit2/include/git2/transport.h +1 -1
  21. data/vendor/libgit2/include/git2/tree.h +2 -0
  22. data/vendor/libgit2/include/git2/version.h +2 -2
  23. data/vendor/libgit2/src/blame.c +15 -10
  24. data/vendor/libgit2/src/blob.c +9 -0
  25. data/vendor/libgit2/src/clone.c +42 -21
  26. data/vendor/libgit2/src/config_cache.c +6 -3
  27. data/vendor/libgit2/src/diff_tform.c +2 -2
  28. data/vendor/libgit2/src/index.c +6 -5
  29. data/vendor/libgit2/src/indexer.c +19 -3
  30. data/vendor/libgit2/src/integer.h +15 -0
  31. data/vendor/libgit2/src/merge.c +5 -2
  32. data/vendor/libgit2/src/mwindow.c +3 -1
  33. data/vendor/libgit2/src/odb.c +4 -3
  34. data/vendor/libgit2/src/pack.c +10 -6
  35. data/vendor/libgit2/src/posix.c +32 -9
  36. data/vendor/libgit2/src/posix.h +9 -0
  37. data/vendor/libgit2/src/refdb_fs.c +4 -2
  38. data/vendor/libgit2/src/refs.c +20 -7
  39. data/vendor/libgit2/src/refs.h +1 -1
  40. data/vendor/libgit2/src/refspec.c +48 -32
  41. data/vendor/libgit2/src/remote.c +13 -7
  42. data/vendor/libgit2/src/repository.c +15 -15
  43. data/vendor/libgit2/src/repository.h +1 -1
  44. data/vendor/libgit2/src/thread-utils.h +24 -19
  45. data/vendor/libgit2/src/transports/httpclient.c +9 -4
  46. data/vendor/libgit2/src/transports/winhttp.c +99 -52
  47. data/vendor/libgit2/src/unix/posix.h +3 -0
  48. data/vendor/libgit2/src/win32/posix_w32.c +70 -0
  49. data/vendor/libgit2/src/worktree.c +8 -1
  50. metadata +2 -2
@@ -23,7 +23,7 @@
23
23
  GIT_BEGIN_DECL
24
24
 
25
25
  /**
26
- * Callback for messages recieved by the transport.
26
+ * Callback for messages received by the transport.
27
27
  *
28
28
  * Return a negative value to cancel the network operation.
29
29
  *
@@ -334,6 +334,7 @@ GIT_EXTERN(int) git_treebuilder_insert(
334
334
  *
335
335
  * @param bld Tree builder
336
336
  * @param filename Filename of the entry to remove
337
+ * @return 0 or an error code
337
338
  */
338
339
  GIT_EXTERN(int) git_treebuilder_remove(
339
340
  git_treebuilder *bld, const char *filename);
@@ -477,6 +478,7 @@ typedef struct {
477
478
  * @param baseline the tree to base these changes on
478
479
  * @param nupdates the number of elements in the update list
479
480
  * @param updates the list of updates to perform
481
+ * @return 0 or an error code
480
482
  */
481
483
  GIT_EXTERN(int) git_tree_create_updated(git_oid *out, git_repository *repo, git_tree *baseline, size_t nupdates, const git_tree_update *updates);
482
484
 
@@ -7,10 +7,10 @@
7
7
  #ifndef INCLUDE_git_version_h__
8
8
  #define INCLUDE_git_version_h__
9
9
 
10
- #define LIBGIT2_VERSION "1.1.0"
10
+ #define LIBGIT2_VERSION "1.1.1"
11
11
  #define LIBGIT2_VER_MAJOR 1
12
12
  #define LIBGIT2_VER_MINOR 1
13
- #define LIBGIT2_VER_REVISION 0
13
+ #define LIBGIT2_VER_REVISION 1
14
14
  #define LIBGIT2_VER_PATCH 0
15
15
 
16
16
  #define LIBGIT2_SOVERSION "1.1"
@@ -76,6 +76,14 @@ static git_blame_hunk* new_hunk(
76
76
  return hunk;
77
77
  }
78
78
 
79
+ static void free_hunk(git_blame_hunk *hunk)
80
+ {
81
+ git__free((void*)hunk->orig_path);
82
+ git_signature_free(hunk->final_signature);
83
+ git_signature_free(hunk->orig_signature);
84
+ git__free(hunk);
85
+ }
86
+
79
87
  static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
80
88
  {
81
89
  git_blame_hunk *newhunk = new_hunk(
@@ -90,17 +98,14 @@ static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
90
98
  git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id);
91
99
  git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id);
92
100
  newhunk->boundary = hunk->boundary;
93
- git_signature_dup(&newhunk->final_signature, hunk->final_signature);
94
- git_signature_dup(&newhunk->orig_signature, hunk->orig_signature);
95
- return newhunk;
96
- }
97
101
 
98
- static void free_hunk(git_blame_hunk *hunk)
99
- {
100
- git__free((void*)hunk->orig_path);
101
- git_signature_free(hunk->final_signature);
102
- git_signature_free(hunk->orig_signature);
103
- git__free(hunk);
102
+ if (git_signature_dup(&newhunk->final_signature, hunk->final_signature) < 0 ||
103
+ git_signature_dup(&newhunk->orig_signature, hunk->orig_signature) < 0) {
104
+ free_hunk(newhunk);
105
+ return NULL;
106
+ }
107
+
108
+ return newhunk;
104
109
  }
105
110
 
106
111
  /* Starting with the hunk that includes start_line, shift all following hunks'
@@ -400,6 +400,15 @@ int git_blob_is_binary(const git_blob *blob)
400
400
  return git_buf_text_is_binary(&content);
401
401
  }
402
402
 
403
+ int git_blob_filter_options_init(
404
+ git_blob_filter_options *opts,
405
+ unsigned int version)
406
+ {
407
+ GIT_INIT_STRUCTURE_FROM_TEMPLATE(opts, version,
408
+ git_blob_filter_options, GIT_BLOB_FILTER_OPTIONS_INIT);
409
+ return 0;
410
+ }
411
+
403
412
  int git_blob_filter(
404
413
  git_buf *out,
405
414
  git_blob *blob,
@@ -162,6 +162,37 @@ done:
162
162
  return error;
163
163
  }
164
164
 
165
+ static int update_remote_head_byname(
166
+ git_repository *repo,
167
+ const char *remote_name,
168
+ const char *tracking_branch_name,
169
+ const char *reflog_message)
170
+ {
171
+ git_buf tracking_head_name = GIT_BUF_INIT;
172
+ git_reference *remote_head = NULL;
173
+ int error;
174
+
175
+ if ((error = git_buf_printf(&tracking_head_name,
176
+ "%s%s/%s",
177
+ GIT_REFS_REMOTES_DIR,
178
+ remote_name,
179
+ GIT_HEAD_FILE)) < 0)
180
+ goto cleanup;
181
+
182
+ error = git_reference_symbolic_create(
183
+ &remote_head,
184
+ repo,
185
+ git_buf_cstr(&tracking_head_name),
186
+ tracking_branch_name,
187
+ true,
188
+ reflog_message);
189
+
190
+ cleanup:
191
+ git_reference_free(remote_head);
192
+ git_buf_dispose(&tracking_head_name);
193
+ return error;
194
+ }
195
+
165
196
  static int update_remote_head(
166
197
  git_repository *repo,
167
198
  git_remote *remote,
@@ -169,9 +200,7 @@ static int update_remote_head(
169
200
  const char *reflog_message)
170
201
  {
171
202
  git_refspec *refspec;
172
- git_reference *remote_head = NULL;
173
- git_buf remote_head_name = GIT_BUF_INIT;
174
- git_buf remote_branch_name = GIT_BUF_INIT;
203
+ git_buf tracking_branch_name = GIT_BUF_INIT;
175
204
  int error;
176
205
 
177
206
  /* Determine the remote tracking ref name from the local branch */
@@ -184,30 +213,19 @@ static int update_remote_head(
184
213
  }
185
214
 
186
215
  if ((error = git_refspec_transform(
187
- &remote_branch_name,
216
+ &tracking_branch_name,
188
217
  refspec,
189
218
  git_buf_cstr(target))) < 0)
190
219
  goto cleanup;
191
220
 
192
- if ((error = git_buf_printf(&remote_head_name,
193
- "%s%s/%s",
194
- GIT_REFS_REMOTES_DIR,
195
- git_remote_name(remote),
196
- GIT_HEAD_FILE)) < 0)
197
- goto cleanup;
198
-
199
- error = git_reference_symbolic_create(
200
- &remote_head,
221
+ error = update_remote_head_byname(
201
222
  repo,
202
- git_buf_cstr(&remote_head_name),
203
- git_buf_cstr(&remote_branch_name),
204
- true,
223
+ git_remote_name(remote),
224
+ git_buf_cstr(&tracking_branch_name),
205
225
  reflog_message);
206
226
 
207
227
  cleanup:
208
- git_reference_free(remote_head);
209
- git_buf_dispose(&remote_branch_name);
210
- git_buf_dispose(&remote_head_name);
228
+ git_buf_dispose(&tracking_branch_name);
211
229
  return error;
212
230
  }
213
231
 
@@ -276,8 +294,11 @@ static int update_head_to_branch(
276
294
  if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0)
277
295
  goto cleanup;
278
296
 
279
- retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
280
- reflog_message);
297
+ if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
298
+ reflog_message)) < 0)
299
+ goto cleanup;
300
+
301
+ retcode = update_remote_head_byname(repo, remote_name, remote_branch_name.ptr, reflog_message);
281
302
 
282
303
  cleanup:
283
304
  git_reference_free(remote_ref);
@@ -111,9 +111,11 @@ int git_config__configmap_lookup(int *out, git_config *config, git_configmap_ite
111
111
 
112
112
  int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item)
113
113
  {
114
- *out = repo->configmap_cache[(int)item];
114
+ intptr_t value = repo->configmap_cache[(int)item];
115
115
 
116
- if (*out == GIT_CONFIGMAP_NOT_CACHED) {
116
+ *out = (int)value;
117
+
118
+ if (value == GIT_CONFIGMAP_NOT_CACHED) {
117
119
  int error;
118
120
  git_config *config;
119
121
 
@@ -121,7 +123,8 @@ int git_repository__configmap_lookup(int *out, git_repository *repo, git_configm
121
123
  (error = git_config__configmap_lookup(out, config, item)) < 0)
122
124
  return error;
123
125
 
124
- repo->configmap_cache[(int)item] = *out;
126
+ value = *out;
127
+ repo->configmap_cache[(int)item] = value;
125
128
  }
126
129
 
127
130
  return 0;
@@ -1038,7 +1038,7 @@ find_best_matches:
1038
1038
  memcpy(&src->old_file, &swap, sizeof(src->old_file));
1039
1039
 
1040
1040
  /* if we've just swapped the new element into the correct
1041
- * place, clear the SPLIT flag
1041
+ * place, clear the SPLIT and RENAME_TARGET flags
1042
1042
  */
1043
1043
  if (tgt2src[s].idx == t &&
1044
1044
  tgt2src[s].similarity >
@@ -1046,7 +1046,7 @@ find_best_matches:
1046
1046
  src->status = GIT_DELTA_RENAMED;
1047
1047
  src->similarity = tgt2src[s].similarity;
1048
1048
  tgt2src[s].similarity = 0;
1049
- src->flags &= ~GIT_DIFF_FLAG__TO_SPLIT;
1049
+ src->flags &= ~(GIT_DIFF_FLAG__TO_SPLIT | GIT_DIFF_FLAG__IS_RENAME_TARGET);
1050
1050
  num_rewrites--;
1051
1051
  }
1052
1052
  /* otherwise, if we just overwrote a source, update mapping */
@@ -2826,14 +2826,16 @@ static int write_entries(git_index *index, git_filebuf *file)
2826
2826
  {
2827
2827
  int error = 0;
2828
2828
  size_t i;
2829
- git_vector case_sorted, *entries;
2829
+ git_vector case_sorted = GIT_VECTOR_INIT, *entries = NULL;
2830
2830
  git_index_entry *entry;
2831
2831
  const char *last = NULL;
2832
2832
 
2833
2833
  /* If index->entries is sorted case-insensitively, then we need
2834
2834
  * to re-sort it case-sensitively before writing */
2835
2835
  if (index->ignore_case) {
2836
- git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp);
2836
+ if ((error = git_vector_dup(&case_sorted, &index->entries, git_index_entry_cmp)) < 0)
2837
+ goto done;
2838
+
2837
2839
  git_vector_sort(&case_sorted);
2838
2840
  entries = &case_sorted;
2839
2841
  } else {
@@ -2850,9 +2852,8 @@ static int write_entries(git_index *index, git_filebuf *file)
2850
2852
  last = entry->path;
2851
2853
  }
2852
2854
 
2853
- if (index->ignore_case)
2854
- git_vector_free(&case_sorted);
2855
-
2855
+ done:
2856
+ git_vector_free(&case_sorted);
2856
2857
  return error;
2857
2858
  }
2858
2859
 
@@ -604,6 +604,23 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
604
604
 
605
605
  static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t size)
606
606
  {
607
+ #ifdef NO_MMAP
608
+ size_t remaining_size = size;
609
+ const char *ptr = (const char *)data;
610
+
611
+ /* Handle data size larger that ssize_t */
612
+ while (remaining_size > 0) {
613
+ ssize_t nb;
614
+ HANDLE_EINTR(nb, p_pwrite(idx->pack->mwf.fd, (void *)ptr,
615
+ remaining_size, offset));
616
+ if (nb <= 0)
617
+ return -1;
618
+
619
+ ptr += nb;
620
+ offset += nb;
621
+ remaining_size -= nb;
622
+ }
623
+ #else
607
624
  git_file fd = idx->pack->mwf.fd;
608
625
  size_t mmap_alignment;
609
626
  size_t page_offset;
@@ -627,6 +644,7 @@ static int write_at(git_indexer *idx, const void *data, off64_t offset, size_t s
627
644
  map_data = (unsigned char *)map.data;
628
645
  memcpy(map_data + page_offset, data, size);
629
646
  p_munmap(&map);
647
+ #endif
630
648
 
631
649
  return 0;
632
650
  }
@@ -638,7 +656,6 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
638
656
  size_t page_offset;
639
657
  off64_t page_start;
640
658
  off64_t current_size = idx->pack->mwf.size;
641
- int fd = idx->pack->mwf.fd;
642
659
  int error;
643
660
 
644
661
  if (!size)
@@ -655,8 +672,7 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
655
672
  page_offset = new_size % mmap_alignment;
656
673
  page_start = new_size - page_offset;
657
674
 
658
- if (p_lseek(fd, page_start + mmap_alignment - 1, SEEK_SET) < 0 ||
659
- p_write(idx->pack->mwf.fd, data, 1) < 0) {
675
+ if (p_pwrite(idx->pack->mwf.fd, data, 1, page_start + mmap_alignment - 1) < 0) {
660
676
  git_error_set(GIT_ERROR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
661
677
  return -1;
662
678
  }
@@ -77,6 +77,9 @@ GIT_INLINE(int) git__is_int(long long p)
77
77
  # define git__sub_int_overflow(out, one, two) \
78
78
  __builtin_ssub_overflow(one, two, out)
79
79
 
80
+ # define git__add_int64_overflow(out, one, two) \
81
+ __builtin_add_overflow(one, two, out)
82
+
80
83
  /* Use Microsoft's safe integer handling functions where available */
81
84
  #elif defined(_MSC_VER)
82
85
 
@@ -92,6 +95,9 @@ GIT_INLINE(int) git__is_int(long long p)
92
95
  #define git__sub_int_overflow(out, one, two) \
93
96
  (IntSub(one, two, out) != S_OK)
94
97
 
98
+ #define git__add_int64_overflow(out, one, two) \
99
+ (LongLongAdd(one, two, out) != S_OK)
100
+
95
101
  #else
96
102
 
97
103
  /**
@@ -136,6 +142,15 @@ GIT_INLINE(bool) git__sub_int_overflow(int *out, int one, int two)
136
142
  return false;
137
143
  }
138
144
 
145
+ GIT_INLINE(bool) git__add_int64_overflow(int64_t *out, int64_t one, int64_t two)
146
+ {
147
+ if ((two > 0 && one > (INT64_MAX - two)) ||
148
+ (two < 0 && one < (INT64_MIN - two)))
149
+ return true;
150
+ *out = one + two;
151
+ return false;
152
+ }
153
+
139
154
  #endif
140
155
 
141
156
  #endif
@@ -2258,8 +2258,11 @@ static int create_virtual_base(
2258
2258
  result->type = GIT_ANNOTATED_COMMIT_VIRTUAL;
2259
2259
  result->index = index;
2260
2260
 
2261
- insert_head_ids(&result->parents, one);
2262
- insert_head_ids(&result->parents, two);
2261
+ if (insert_head_ids(&result->parents, one) < 0 ||
2262
+ insert_head_ids(&result->parents, two) < 0) {
2263
+ git_annotated_commit_free(result);
2264
+ return -1;
2265
+ }
2263
2266
 
2264
2267
  *out = result;
2265
2268
  return 0;
@@ -295,8 +295,10 @@ static int git_mwindow_close_lru_file(void)
295
295
  current_file, &mru_window, NULL, true, GIT_MWINDOW__MRU)) {
296
296
  continue;
297
297
  }
298
- if (!lru_window || lru_window->last_used > mru_window->last_used)
298
+ if (!lru_window || lru_window->last_used > mru_window->last_used) {
299
+ lru_window = mru_window;
299
300
  lru_file = current_file;
301
+ }
300
302
  }
301
303
 
302
304
  if (!lru_file) {
@@ -298,14 +298,15 @@ int git_odb__hashlink(git_oid *out, const char *path)
298
298
  GIT_ERROR_CHECK_ALLOC(link_data);
299
299
 
300
300
  read_len = p_readlink(path, link_data, size);
301
- link_data[size] = '\0';
302
- if (read_len != size) {
301
+ if (read_len == -1) {
303
302
  git_error_set(GIT_ERROR_OS, "failed to read symlink data for '%s'", path);
304
303
  git__free(link_data);
305
304
  return -1;
306
305
  }
306
+ GIT_ASSERT(read_len <= size);
307
+ link_data[read_len] = '\0';
307
308
 
308
- result = git_odb_hash(out, link_data, size, GIT_OBJECT_BLOB);
309
+ result = git_odb_hash(out, link_data, read_len, GIT_OBJECT_BLOB);
309
310
  git__free(link_data);
310
311
  } else {
311
312
  int fd = git_futils_open_ro(path);
@@ -841,7 +841,7 @@ static int packfile_unpack_compressed(
841
841
 
842
842
  do {
843
843
  size_t bytes = buffer_len - total;
844
- unsigned int window_len;
844
+ unsigned int window_len, consumed;
845
845
  unsigned char *in;
846
846
 
847
847
  if ((in = pack_window_open(p, mwindow, *position, &window_len)) == NULL) {
@@ -857,10 +857,15 @@ static int packfile_unpack_compressed(
857
857
 
858
858
  git_mwindow_close(mwindow);
859
859
 
860
- if (!bytes)
861
- break;
860
+ consumed = window_len - (unsigned int)zstream.in_len;
861
+
862
+ if (!bytes && !consumed) {
863
+ git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream");
864
+ error = -1;
865
+ goto out;
866
+ }
862
867
 
863
- *position += window_len - zstream.in_len;
868
+ *position += consumed;
864
869
  total += bytes;
865
870
  } while (!git_zstream_eos(&zstream));
866
871
 
@@ -1058,8 +1063,7 @@ static int packfile_open(struct git_pack_file *p)
1058
1063
 
1059
1064
  /* Verify the pack matches its index. */
1060
1065
  if (p->num_objects != ntohl(hdr.hdr_entries) ||
1061
- p_lseek(p->mwf.fd, p->mwf.size - GIT_OID_RAWSZ, SEEK_SET) == -1 ||
1062
- p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < 0)
1066
+ p_pread(p->mwf.fd, sha1.id, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0)
1063
1067
  goto cleanup;
1064
1068
 
1065
1069
  idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40;
@@ -237,24 +237,43 @@ int git__mmap_alignment(size_t *alignment)
237
237
 
238
238
  int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, off64_t offset)
239
239
  {
240
+ const char *ptr;
241
+ size_t remaining_len;
242
+
240
243
  GIT_MMAP_VALIDATE(out, len, prot, flags);
241
244
 
242
- out->data = NULL;
243
- out->len = 0;
245
+ /* writes cannot be emulated without handling pagefaults since write happens by
246
+ * writing to mapped memory */
247
+ if (prot & GIT_PROT_WRITE) {
248
+ git_error_set(GIT_ERROR_OS, "trying to map %s-writeable",
249
+ ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED) ? "shared": "private");
250
+ return -1;
251
+ }
244
252
 
245
- if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) {
246
- git_error_set(GIT_ERROR_OS, "trying to map shared-writeable");
253
+ if (!git__is_ssizet(len)) {
254
+ errno = EINVAL;
247
255
  return -1;
248
256
  }
249
257
 
258
+ out->len = 0;
250
259
  out->data = git__malloc(len);
251
260
  GIT_ERROR_CHECK_ALLOC(out->data);
252
261
 
253
- if (!git__is_ssizet(len) ||
254
- (p_lseek(fd, offset, SEEK_SET) < 0) ||
255
- (p_read(fd, out->data, len) != (ssize_t)len)) {
256
- git_error_set(GIT_ERROR_OS, "mmap emulation failed");
257
- return -1;
262
+ remaining_len = len;
263
+ ptr = (const char *)out->data;
264
+ while (remaining_len > 0) {
265
+ ssize_t nb;
266
+ HANDLE_EINTR(nb, p_pread(fd, (void *)ptr, remaining_len, offset));
267
+ if (nb <= 0) {
268
+ git_error_set(GIT_ERROR_OS, "mmap emulation failed");
269
+ git__free(out->data);
270
+ out->data = NULL;
271
+ return -1;
272
+ }
273
+
274
+ ptr += nb;
275
+ offset += nb;
276
+ remaining_len -= nb;
258
277
  }
259
278
 
260
279
  out->len = len;
@@ -266,6 +285,10 @@ int p_munmap(git_map *map)
266
285
  assert(map != NULL);
267
286
  git__free(map->data);
268
287
 
288
+ /* Initializing will help debug use-after-free */
289
+ map->len = 0;
290
+ map->data = NULL;
291
+
269
292
  return 0;
270
293
  }
271
294