rugged 0.24.6.1 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/extconf.rb +9 -2
  4. data/ext/rugged/rugged.c +85 -21
  5. data/ext/rugged/rugged.h +7 -21
  6. data/ext/rugged/rugged_backend.c +3 -20
  7. data/ext/rugged/rugged_blame.c +7 -24
  8. data/ext/rugged/rugged_blob.c +136 -59
  9. data/ext/rugged/rugged_branch.c +3 -20
  10. data/ext/rugged/rugged_branch_collection.c +3 -20
  11. data/ext/rugged/rugged_commit.c +251 -101
  12. data/ext/rugged/rugged_config.c +3 -20
  13. data/ext/rugged/rugged_cred.c +3 -20
  14. data/ext/rugged/rugged_diff.c +3 -20
  15. data/ext/rugged/rugged_diff_delta.c +3 -20
  16. data/ext/rugged/rugged_diff_hunk.c +3 -20
  17. data/ext/rugged/rugged_diff_line.c +3 -20
  18. data/ext/rugged/rugged_index.c +46 -229
  19. data/ext/rugged/rugged_note.c +3 -20
  20. data/ext/rugged/rugged_object.c +3 -20
  21. data/ext/rugged/rugged_patch.c +192 -34
  22. data/ext/rugged/rugged_rebase.c +90 -48
  23. data/ext/rugged/rugged_reference.c +4 -21
  24. data/ext/rugged/rugged_reference_collection.c +3 -20
  25. data/ext/rugged/rugged_remote.c +70 -42
  26. data/ext/rugged/rugged_remote_collection.c +3 -20
  27. data/ext/rugged/rugged_repo.c +50 -59
  28. data/ext/rugged/rugged_revwalk.c +4 -21
  29. data/ext/rugged/rugged_settings.c +3 -20
  30. data/ext/rugged/rugged_signature.c +3 -20
  31. data/ext/rugged/rugged_submodule.c +4 -21
  32. data/ext/rugged/rugged_submodule_collection.c +3 -20
  33. data/ext/rugged/rugged_tag.c +3 -20
  34. data/ext/rugged/rugged_tag_collection.c +3 -20
  35. data/ext/rugged/rugged_tree.c +189 -184
  36. data/lib/rugged/attributes.rb +5 -0
  37. data/lib/rugged/blob.rb +5 -0
  38. data/lib/rugged/branch.rb +6 -1
  39. data/lib/rugged/commit.rb +5 -0
  40. data/lib/rugged/console.rb +5 -0
  41. data/lib/rugged/credentials.rb +5 -0
  42. data/lib/rugged/diff/delta.rb +5 -0
  43. data/lib/rugged/diff/hunk.rb +5 -0
  44. data/lib/rugged/diff/line.rb +5 -0
  45. data/lib/rugged/diff.rb +5 -0
  46. data/lib/rugged/index.rb +120 -0
  47. data/lib/rugged/object.rb +5 -0
  48. data/lib/rugged/patch.rb +5 -0
  49. data/lib/rugged/reference.rb +5 -0
  50. data/lib/rugged/remote.rb +5 -0
  51. data/lib/rugged/repository.rb +9 -4
  52. data/lib/rugged/submodule_collection.rb +5 -0
  53. data/lib/rugged/tag.rb +5 -0
  54. data/lib/rugged/tree.rb +156 -1
  55. data/lib/rugged/version.rb +6 -1
  56. data/lib/rugged/walker.rb +5 -0
  57. data/lib/rugged.rb +5 -0
  58. data/vendor/libgit2/CMakeLists.txt +12 -2
  59. data/vendor/libgit2/include/git2/blob.h +39 -28
  60. data/vendor/libgit2/include/git2/commit.h +76 -0
  61. data/vendor/libgit2/include/git2/common.h +21 -1
  62. data/vendor/libgit2/include/git2/describe.h +5 -2
  63. data/vendor/libgit2/include/git2/diff.h +62 -7
  64. data/vendor/libgit2/include/git2/errors.h +2 -1
  65. data/vendor/libgit2/include/git2/index.h +25 -0
  66. data/vendor/libgit2/include/git2/merge.h +10 -1
  67. data/vendor/libgit2/include/git2/odb.h +47 -1
  68. data/vendor/libgit2/include/git2/pack.h +4 -4
  69. data/vendor/libgit2/include/git2/patch.h +1 -1
  70. data/vendor/libgit2/include/git2/proxy.h +92 -0
  71. data/vendor/libgit2/include/git2/refs.h +11 -0
  72. data/vendor/libgit2/include/git2/remote.h +21 -8
  73. data/vendor/libgit2/include/git2/repository.h +20 -1
  74. data/vendor/libgit2/include/git2/revwalk.h +4 -6
  75. data/vendor/libgit2/include/git2/signature.h +13 -0
  76. data/vendor/libgit2/include/git2/submodule.h +11 -3
  77. data/vendor/libgit2/include/git2/sys/merge.h +177 -0
  78. data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
  79. data/vendor/libgit2/include/git2/sys/remote.h +16 -0
  80. data/vendor/libgit2/include/git2/sys/stream.h +2 -1
  81. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  82. data/vendor/libgit2/include/git2/sys/transport.h +3 -1
  83. data/vendor/libgit2/include/git2/tag.h +9 -0
  84. data/vendor/libgit2/include/git2/transaction.h +9 -0
  85. data/vendor/libgit2/include/git2/tree.h +55 -0
  86. data/vendor/libgit2/include/git2/version.h +4 -4
  87. data/vendor/libgit2/include/git2.h +1 -0
  88. data/vendor/libgit2/src/annotated_commit.c +99 -80
  89. data/vendor/libgit2/src/annotated_commit.h +5 -2
  90. data/vendor/libgit2/src/apply.c +377 -0
  91. data/vendor/libgit2/src/apply.h +21 -0
  92. data/vendor/libgit2/src/array.h +0 -1
  93. data/vendor/libgit2/src/blob.c +71 -39
  94. data/vendor/libgit2/src/branch.c +7 -5
  95. data/vendor/libgit2/src/buffer.c +252 -20
  96. data/vendor/libgit2/src/buffer.h +8 -0
  97. data/vendor/libgit2/src/checkout.c +69 -42
  98. data/vendor/libgit2/src/clone.c +0 -8
  99. data/vendor/libgit2/src/commit.c +193 -49
  100. data/vendor/libgit2/src/commit_list.c +8 -3
  101. data/vendor/libgit2/src/commit_list.h +1 -0
  102. data/vendor/libgit2/src/common.h +2 -1
  103. data/vendor/libgit2/src/config.c +3 -3
  104. data/vendor/libgit2/src/config_file.c +20 -10
  105. data/vendor/libgit2/src/crlf.c +1 -0
  106. data/vendor/libgit2/src/curl_stream.c +106 -6
  107. data/vendor/libgit2/src/delta.c +238 -62
  108. data/vendor/libgit2/src/delta.h +79 -58
  109. data/vendor/libgit2/src/describe.c +1 -1
  110. data/vendor/libgit2/src/diff.c +32 -1554
  111. data/vendor/libgit2/src/diff.h +14 -122
  112. data/vendor/libgit2/src/diff_driver.c +4 -6
  113. data/vendor/libgit2/src/diff_file.c +3 -0
  114. data/vendor/libgit2/src/diff_generate.c +1613 -0
  115. data/vendor/libgit2/src/diff_generate.h +123 -0
  116. data/vendor/libgit2/src/diff_parse.c +101 -0
  117. data/vendor/libgit2/src/diff_parse.h +18 -0
  118. data/vendor/libgit2/src/diff_print.c +263 -144
  119. data/vendor/libgit2/src/diff_stats.c +21 -12
  120. data/vendor/libgit2/src/diff_tform.c +1 -0
  121. data/vendor/libgit2/src/diff_tform.h +22 -0
  122. data/vendor/libgit2/src/diff_xdiff.c +9 -9
  123. data/vendor/libgit2/src/diff_xdiff.h +5 -5
  124. data/vendor/libgit2/src/fetchhead.c +8 -8
  125. data/vendor/libgit2/src/filebuf.c +6 -1
  126. data/vendor/libgit2/src/filebuf.h +1 -0
  127. data/vendor/libgit2/src/fileops.c +22 -1
  128. data/vendor/libgit2/src/fileops.h +8 -2
  129. data/vendor/libgit2/src/fnmatch.c +18 -5
  130. data/vendor/libgit2/src/global.c +21 -4
  131. data/vendor/libgit2/src/global.h +6 -0
  132. data/vendor/libgit2/src/graph.c +1 -1
  133. data/vendor/libgit2/src/index.c +159 -46
  134. data/vendor/libgit2/src/index.h +2 -0
  135. data/vendor/libgit2/src/iterator.c +1573 -1468
  136. data/vendor/libgit2/src/iterator.h +52 -69
  137. data/vendor/libgit2/src/merge.c +163 -64
  138. data/vendor/libgit2/src/merge.h +61 -2
  139. data/vendor/libgit2/src/merge_driver.c +397 -0
  140. data/vendor/libgit2/src/merge_driver.h +60 -0
  141. data/vendor/libgit2/src/merge_file.c +11 -49
  142. data/vendor/libgit2/src/netops.c +12 -10
  143. data/vendor/libgit2/src/object_api.c +19 -1
  144. data/vendor/libgit2/src/odb.c +228 -52
  145. data/vendor/libgit2/src/odb_loose.c +19 -1
  146. data/vendor/libgit2/src/odb_mempack.c +1 -1
  147. data/vendor/libgit2/src/odb_pack.c +27 -1
  148. data/vendor/libgit2/src/openssl_stream.c +4 -5
  149. data/vendor/libgit2/src/pack-objects.c +105 -76
  150. data/vendor/libgit2/src/pack-objects.h +13 -12
  151. data/vendor/libgit2/src/pack.c +16 -10
  152. data/vendor/libgit2/src/pack.h +2 -0
  153. data/vendor/libgit2/src/patch.c +216 -0
  154. data/vendor/libgit2/src/patch.h +66 -0
  155. data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +203 -376
  156. data/vendor/libgit2/src/patch_generate.h +68 -0
  157. data/vendor/libgit2/src/patch_parse.c +1159 -0
  158. data/vendor/libgit2/src/patch_parse.h +56 -0
  159. data/vendor/libgit2/src/path.c +38 -2
  160. data/vendor/libgit2/src/path.h +18 -0
  161. data/vendor/libgit2/src/pathspec.c +1 -1
  162. data/vendor/libgit2/src/pool.h +5 -0
  163. data/vendor/libgit2/src/pqueue.c +12 -5
  164. data/vendor/libgit2/src/pqueue.h +1 -0
  165. data/vendor/libgit2/src/proxy.c +32 -0
  166. data/vendor/libgit2/src/proxy.h +14 -0
  167. data/vendor/libgit2/src/push.c +1 -1
  168. data/vendor/libgit2/src/rebase.c +63 -36
  169. data/vendor/libgit2/src/refdb.c +4 -2
  170. data/vendor/libgit2/src/refdb_fs.c +82 -54
  171. data/vendor/libgit2/src/refs.c +13 -1
  172. data/vendor/libgit2/src/remote.c +20 -81
  173. data/vendor/libgit2/src/repository.c +212 -29
  174. data/vendor/libgit2/src/reset.c +1 -1
  175. data/vendor/libgit2/src/revparse.c +1 -1
  176. data/vendor/libgit2/src/revwalk.c +260 -184
  177. data/vendor/libgit2/src/settings.c +11 -3
  178. data/vendor/libgit2/src/signature.c +27 -2
  179. data/vendor/libgit2/src/sortedcache.c +14 -5
  180. data/vendor/libgit2/src/stash.c +1 -0
  181. data/vendor/libgit2/src/status.c +1 -0
  182. data/vendor/libgit2/src/stransport_stream.c +4 -2
  183. data/vendor/libgit2/src/stream.h +2 -2
  184. data/vendor/libgit2/src/submodule.c +16 -4
  185. data/vendor/libgit2/src/sysdir.c +1 -1
  186. data/vendor/libgit2/src/transport.c +3 -5
  187. data/vendor/libgit2/src/transports/http.c +38 -13
  188. data/vendor/libgit2/src/transports/local.c +4 -1
  189. data/vendor/libgit2/src/transports/smart.c +6 -0
  190. data/vendor/libgit2/src/transports/smart.h +1 -0
  191. data/vendor/libgit2/src/transports/smart_pkt.c +5 -13
  192. data/vendor/libgit2/src/transports/smart_protocol.c +22 -7
  193. data/vendor/libgit2/src/transports/winhttp.c +144 -11
  194. data/vendor/libgit2/src/tree.c +267 -2
  195. data/vendor/libgit2/src/unix/posix.h +10 -0
  196. data/vendor/libgit2/src/unix/pthread.h +2 -0
  197. data/vendor/libgit2/src/util.c +25 -2
  198. data/vendor/libgit2/src/util.h +10 -0
  199. data/vendor/libgit2/src/varint.c +44 -0
  200. data/vendor/libgit2/src/varint.h +15 -0
  201. data/vendor/libgit2/src/vector.c +58 -0
  202. data/vendor/libgit2/src/vector.h +8 -0
  203. data/vendor/libgit2/src/win32/posix.h +3 -0
  204. data/vendor/libgit2/src/win32/thread.c +18 -0
  205. data/vendor/libgit2/src/win32/thread.h +2 -0
  206. data/vendor/libgit2/src/win32/w32_util.h +1 -1
  207. data/vendor/libgit2/src/zstream.c +37 -8
  208. data/vendor/libgit2/src/zstream.h +8 -1
  209. metadata +100 -82
  210. data/vendor/libgit2/Makefile.embed +0 -60
  211. data/vendor/libgit2/src/delta-apply.c +0 -166
  212. data/vendor/libgit2/src/delta-apply.h +0 -62
  213. data/vendor/libgit2/src/diff_patch.h +0 -83
@@ -114,7 +114,7 @@ struct index_entry {
114
114
  struct git_delta_index {
115
115
  unsigned long memsize;
116
116
  const void *src_buf;
117
- unsigned long src_size;
117
+ size_t src_size;
118
118
  unsigned int hash_mask;
119
119
  struct index_entry *hash[GIT_FLEX_ARRAY];
120
120
  };
@@ -142,8 +142,8 @@ static int lookup_index_alloc(
142
142
  return 0;
143
143
  }
144
144
 
145
- struct git_delta_index *
146
- git_delta_create_index(const void *buf, unsigned long bufsize)
145
+ int git_delta_index_init(
146
+ git_delta_index **out, const void *buf, size_t bufsize)
147
147
  {
148
148
  unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
149
149
  const unsigned char *data, *buffer = buf;
@@ -152,8 +152,10 @@ git_delta_create_index(const void *buf, unsigned long bufsize)
152
152
  void *mem;
153
153
  unsigned long memsize;
154
154
 
155
+ *out = NULL;
156
+
155
157
  if (!buf || !bufsize)
156
- return NULL;
158
+ return 0;
157
159
 
158
160
  /* Determine index hash size. Note that indexing skips the
159
161
  first byte to allow for optimizing the rabin polynomial
@@ -172,7 +174,7 @@ git_delta_create_index(const void *buf, unsigned long bufsize)
172
174
  hmask = hsize - 1;
173
175
 
174
176
  if (lookup_index_alloc(&mem, &memsize, entries, hsize) < 0)
175
- return NULL;
177
+ return -1;
176
178
 
177
179
  index = mem;
178
180
  mem = index->hash;
@@ -190,7 +192,7 @@ git_delta_create_index(const void *buf, unsigned long bufsize)
190
192
  hash_count = git__calloc(hsize, sizeof(*hash_count));
191
193
  if (!hash_count) {
192
194
  git__free(index);
193
- return NULL;
195
+ return -1;
194
196
  }
195
197
 
196
198
  /* then populate the index */
@@ -243,20 +245,20 @@ git_delta_create_index(const void *buf, unsigned long bufsize)
243
245
  }
244
246
  git__free(hash_count);
245
247
 
246
- return index;
248
+ *out = index;
249
+ return 0;
247
250
  }
248
251
 
249
- void git_delta_free_index(struct git_delta_index *index)
252
+ void git_delta_index_free(git_delta_index *index)
250
253
  {
251
254
  git__free(index);
252
255
  }
253
256
 
254
- unsigned long git_delta_sizeof_index(struct git_delta_index *index)
257
+ size_t git_delta_index_size(git_delta_index *index)
255
258
  {
256
- if (index)
257
- return index->memsize;
258
- else
259
- return 0;
259
+ assert(index);
260
+
261
+ return index->memsize;
260
262
  }
261
263
 
262
264
  /*
@@ -265,55 +267,57 @@ unsigned long git_delta_sizeof_index(struct git_delta_index *index)
265
267
  */
266
268
  #define MAX_OP_SIZE (5 + 5 + 1 + RABIN_WINDOW + 7)
267
269
 
268
- void *
269
- git_delta_create(
270
+ int git_delta_create_from_index(
271
+ void **out,
272
+ size_t *out_len,
270
273
  const struct git_delta_index *index,
271
274
  const void *trg_buf,
272
- unsigned long trg_size,
273
- unsigned long *delta_size,
274
- unsigned long max_size)
275
+ size_t trg_size,
276
+ size_t max_size)
275
277
  {
276
- unsigned int i, outpos, outsize, moff, msize, val;
278
+ unsigned int i, bufpos, bufsize, moff, msize, val;
277
279
  int inscnt;
278
280
  const unsigned char *ref_data, *ref_top, *data, *top;
279
- unsigned char *out;
281
+ unsigned char *buf;
282
+
283
+ *out = NULL;
284
+ *out_len = 0;
280
285
 
281
286
  if (!trg_buf || !trg_size)
282
- return NULL;
287
+ return 0;
283
288
 
284
- outpos = 0;
285
- outsize = 8192;
286
- if (max_size && outsize >= max_size)
287
- outsize = (unsigned int)(max_size + MAX_OP_SIZE + 1);
288
- out = git__malloc(outsize);
289
- if (!out)
290
- return NULL;
289
+ bufpos = 0;
290
+ bufsize = 8192;
291
+ if (max_size && bufsize >= max_size)
292
+ bufsize = (unsigned int)(max_size + MAX_OP_SIZE + 1);
293
+ buf = git__malloc(bufsize);
294
+ GITERR_CHECK_ALLOC(buf);
291
295
 
292
296
  /* store reference buffer size */
293
297
  i = index->src_size;
294
298
  while (i >= 0x80) {
295
- out[outpos++] = i | 0x80;
299
+ buf[bufpos++] = i | 0x80;
296
300
  i >>= 7;
297
301
  }
298
- out[outpos++] = i;
302
+ buf[bufpos++] = i;
299
303
 
300
304
  /* store target buffer size */
301
305
  i = trg_size;
302
306
  while (i >= 0x80) {
303
- out[outpos++] = i | 0x80;
307
+ buf[bufpos++] = i | 0x80;
304
308
  i >>= 7;
305
309
  }
306
- out[outpos++] = i;
310
+ buf[bufpos++] = i;
307
311
 
308
312
  ref_data = index->src_buf;
309
313
  ref_top = ref_data + index->src_size;
310
314
  data = trg_buf;
311
315
  top = (const unsigned char *) trg_buf + trg_size;
312
316
 
313
- outpos++;
317
+ bufpos++;
314
318
  val = 0;
315
319
  for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
316
- out[outpos++] = *data;
320
+ buf[bufpos++] = *data;
317
321
  val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
318
322
  }
319
323
  inscnt = i;
@@ -350,11 +354,11 @@ git_delta_create(
350
354
 
351
355
  if (msize < 4) {
352
356
  if (!inscnt)
353
- outpos++;
354
- out[outpos++] = *data++;
357
+ bufpos++;
358
+ buf[bufpos++] = *data++;
355
359
  inscnt++;
356
360
  if (inscnt == 0x7f) {
357
- out[outpos - inscnt - 1] = inscnt;
361
+ buf[bufpos - inscnt - 1] = inscnt;
358
362
  inscnt = 0;
359
363
  }
360
364
  msize = 0;
@@ -368,14 +372,14 @@ git_delta_create(
368
372
  msize++;
369
373
  moff--;
370
374
  data--;
371
- outpos--;
375
+ bufpos--;
372
376
  if (--inscnt)
373
377
  continue;
374
- outpos--; /* remove count slot */
378
+ bufpos--; /* remove count slot */
375
379
  inscnt--; /* make it -1 */
376
380
  break;
377
381
  }
378
- out[outpos - inscnt - 1] = inscnt;
382
+ buf[bufpos - inscnt - 1] = inscnt;
379
383
  inscnt = 0;
380
384
  }
381
385
 
@@ -383,22 +387,22 @@ git_delta_create(
383
387
  left = (msize < 0x10000) ? 0 : (msize - 0x10000);
384
388
  msize -= left;
385
389
 
386
- op = out + outpos++;
390
+ op = buf + bufpos++;
387
391
  i = 0x80;
388
392
 
389
393
  if (moff & 0x000000ff)
390
- out[outpos++] = moff >> 0, i |= 0x01;
394
+ buf[bufpos++] = moff >> 0, i |= 0x01;
391
395
  if (moff & 0x0000ff00)
392
- out[outpos++] = moff >> 8, i |= 0x02;
396
+ buf[bufpos++] = moff >> 8, i |= 0x02;
393
397
  if (moff & 0x00ff0000)
394
- out[outpos++] = moff >> 16, i |= 0x04;
398
+ buf[bufpos++] = moff >> 16, i |= 0x04;
395
399
  if (moff & 0xff000000)
396
- out[outpos++] = moff >> 24, i |= 0x08;
400
+ buf[bufpos++] = moff >> 24, i |= 0x08;
397
401
 
398
402
  if (msize & 0x00ff)
399
- out[outpos++] = msize >> 0, i |= 0x10;
403
+ buf[bufpos++] = msize >> 0, i |= 0x10;
400
404
  if (msize & 0xff00)
401
- out[outpos++] = msize >> 8, i |= 0x20;
405
+ buf[bufpos++] = msize >> 8, i |= 0x20;
402
406
 
403
407
  *op = i;
404
408
 
@@ -415,29 +419,201 @@ git_delta_create(
415
419
  }
416
420
  }
417
421
 
418
- if (outpos >= outsize - MAX_OP_SIZE) {
419
- void *tmp = out;
420
- outsize = outsize * 3 / 2;
421
- if (max_size && outsize >= max_size)
422
- outsize = max_size + MAX_OP_SIZE + 1;
423
- if (max_size && outpos > max_size)
422
+ if (bufpos >= bufsize - MAX_OP_SIZE) {
423
+ void *tmp = buf;
424
+ bufsize = bufsize * 3 / 2;
425
+ if (max_size && bufsize >= max_size)
426
+ bufsize = max_size + MAX_OP_SIZE + 1;
427
+ if (max_size && bufpos > max_size)
424
428
  break;
425
- out = git__realloc(out, outsize);
426
- if (!out) {
429
+ buf = git__realloc(buf, bufsize);
430
+ if (!buf) {
427
431
  git__free(tmp);
428
- return NULL;
432
+ return -1;
429
433
  }
430
434
  }
431
435
  }
432
436
 
433
437
  if (inscnt)
434
- out[outpos - inscnt - 1] = inscnt;
438
+ buf[bufpos - inscnt - 1] = inscnt;
435
439
 
436
- if (max_size && outpos > max_size) {
437
- git__free(out);
438
- return NULL;
440
+ if (max_size && bufpos > max_size) {
441
+ giterr_set(GITERR_NOMEMORY, "delta would be larger than maximum size");
442
+ git__free(buf);
443
+ return GIT_EBUFS;
439
444
  }
440
445
 
441
- *delta_size = outpos;
442
- return out;
446
+ *out_len = bufpos;
447
+ *out = buf;
448
+ return 0;
449
+ }
450
+
451
+ /*
452
+ * Delta application was heavily cribbed from BinaryDelta.java in JGit, which
453
+ * itself was heavily cribbed from <code>patch-delta.c</code> in the
454
+ * GIT project. The original delta patching code was written by
455
+ * Nicolas Pitre <nico@cam.org>.
456
+ */
457
+
458
+ static int hdr_sz(
459
+ size_t *size,
460
+ const unsigned char **delta,
461
+ const unsigned char *end)
462
+ {
463
+ const unsigned char *d = *delta;
464
+ size_t r = 0;
465
+ unsigned int c, shift = 0;
466
+
467
+ do {
468
+ if (d == end) {
469
+ giterr_set(GITERR_INVALID, "truncated delta");
470
+ return -1;
471
+ }
472
+
473
+ c = *d++;
474
+ r |= (c & 0x7f) << shift;
475
+ shift += 7;
476
+ } while (c & 0x80);
477
+ *delta = d;
478
+ *size = r;
479
+ return 0;
480
+ }
481
+
482
+ int git_delta_read_header(
483
+ size_t *base_out,
484
+ size_t *result_out,
485
+ const unsigned char *delta,
486
+ size_t delta_len)
487
+ {
488
+ const unsigned char *delta_end = delta + delta_len;
489
+ if ((hdr_sz(base_out, &delta, delta_end) < 0) ||
490
+ (hdr_sz(result_out, &delta, delta_end) < 0))
491
+ return -1;
492
+ return 0;
493
+ }
494
+
495
+ #define DELTA_HEADER_BUFFER_LEN 16
496
+ int git_delta_read_header_fromstream(
497
+ size_t *base_sz, size_t *res_sz, git_packfile_stream *stream)
498
+ {
499
+ static const size_t buffer_len = DELTA_HEADER_BUFFER_LEN;
500
+ unsigned char buffer[DELTA_HEADER_BUFFER_LEN];
501
+ const unsigned char *delta, *delta_end;
502
+ size_t len;
503
+ ssize_t read;
504
+
505
+ len = read = 0;
506
+ while (len < buffer_len) {
507
+ read = git_packfile_stream_read(stream, &buffer[len], buffer_len - len);
508
+
509
+ if (read == 0)
510
+ break;
511
+
512
+ if (read == GIT_EBUFS)
513
+ continue;
514
+
515
+ len += read;
516
+ }
517
+
518
+ delta = buffer;
519
+ delta_end = delta + len;
520
+ if ((hdr_sz(base_sz, &delta, delta_end) < 0) ||
521
+ (hdr_sz(res_sz, &delta, delta_end) < 0))
522
+ return -1;
523
+
524
+ return 0;
525
+ }
526
+
527
+ int git_delta_apply(
528
+ void **out,
529
+ size_t *out_len,
530
+ const unsigned char *base,
531
+ size_t base_len,
532
+ const unsigned char *delta,
533
+ size_t delta_len)
534
+ {
535
+ const unsigned char *delta_end = delta + delta_len;
536
+ size_t base_sz, res_sz, alloc_sz;
537
+ unsigned char *res_dp;
538
+
539
+ *out = NULL;
540
+ *out_len = 0;
541
+
542
+ /* Check that the base size matches the data we were given;
543
+ * if not we would underflow while accessing data from the
544
+ * base object, resulting in data corruption or segfault.
545
+ */
546
+ if ((hdr_sz(&base_sz, &delta, delta_end) < 0) || (base_sz != base_len)) {
547
+ giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
548
+ return -1;
549
+ }
550
+
551
+ if (hdr_sz(&res_sz, &delta, delta_end) < 0) {
552
+ giterr_set(GITERR_INVALID, "Failed to apply delta. Base size does not match given data");
553
+ return -1;
554
+ }
555
+
556
+ GITERR_CHECK_ALLOC_ADD(&alloc_sz, res_sz, 1);
557
+ res_dp = git__malloc(alloc_sz);
558
+ GITERR_CHECK_ALLOC(res_dp);
559
+
560
+ res_dp[res_sz] = '\0';
561
+ *out = res_dp;
562
+ *out_len = res_sz;
563
+
564
+ while (delta < delta_end) {
565
+ unsigned char cmd = *delta++;
566
+ if (cmd & 0x80) {
567
+ /* cmd is a copy instruction; copy from the base.
568
+ */
569
+ size_t off = 0, len = 0;
570
+
571
+ if (cmd & 0x01) off = *delta++;
572
+ if (cmd & 0x02) off |= *delta++ << 8UL;
573
+ if (cmd & 0x04) off |= *delta++ << 16UL;
574
+ if (cmd & 0x08) off |= *delta++ << 24UL;
575
+
576
+ if (cmd & 0x10) len = *delta++;
577
+ if (cmd & 0x20) len |= *delta++ << 8UL;
578
+ if (cmd & 0x40) len |= *delta++ << 16UL;
579
+ if (!len) len = 0x10000;
580
+
581
+ if (base_len < off + len || res_sz < len)
582
+ goto fail;
583
+ memcpy(res_dp, base + off, len);
584
+ res_dp += len;
585
+ res_sz -= len;
586
+
587
+ }
588
+ else if (cmd) {
589
+ /* cmd is a literal insert instruction; copy from
590
+ * the delta stream itself.
591
+ */
592
+ if (delta_end - delta < cmd || res_sz < cmd)
593
+ goto fail;
594
+ memcpy(res_dp, delta, cmd);
595
+ delta += cmd;
596
+ res_dp += cmd;
597
+ res_sz -= cmd;
598
+
599
+ }
600
+ else {
601
+ /* cmd == 0 is reserved for future encodings.
602
+ */
603
+ goto fail;
604
+ }
605
+ }
606
+
607
+ if (delta != delta_end || res_sz)
608
+ goto fail;
609
+ return 0;
610
+
611
+ fail:
612
+ git__free(*out);
613
+
614
+ *out = NULL;
615
+ *out_len = 0;
616
+
617
+ giterr_set(GITERR_INVALID, "Failed to apply delta");
618
+ return -1;
443
619
  }
@@ -6,12 +6,12 @@
6
6
  #define INCLUDE_git_delta_h__
7
7
 
8
8
  #include "common.h"
9
+ #include "pack.h"
9
10
 
10
- /* opaque object for delta index */
11
- struct git_delta_index;
11
+ typedef struct git_delta_index git_delta_index;
12
12
 
13
13
  /*
14
- * create_delta_index: compute index data from given buffer
14
+ * git_delta_index_init: compute index data from given buffer
15
15
  *
16
16
  * This returns a pointer to a struct delta_index that should be passed to
17
17
  * subsequent create_delta() calls, or to free_delta_index(). A NULL pointer
@@ -19,22 +19,18 @@ struct git_delta_index;
19
19
  * before free_delta_index() is called. The returned pointer must be freed
20
20
  * using free_delta_index().
21
21
  */
22
- extern struct git_delta_index *
23
- git_delta_create_index(const void *buf, unsigned long bufsize);
22
+ extern int git_delta_index_init(
23
+ git_delta_index **out, const void *buf, size_t bufsize);
24
24
 
25
25
  /*
26
- * free_delta_index: free the index created by create_delta_index()
27
- *
28
- * Given pointer must be what create_delta_index() returned, or NULL.
26
+ * Free the index created by git_delta_index_init()
29
27
  */
30
- extern void git_delta_free_index(struct git_delta_index *index);
28
+ extern void git_delta_index_free(git_delta_index *index);
31
29
 
32
30
  /*
33
- * sizeof_delta_index: returns memory usage of delta index
34
- *
35
- * Given pointer must be what create_delta_index() returned, or NULL.
31
+ * Returns memory usage of delta index.
36
32
  */
37
- extern unsigned long git_delta_sizeof_index(struct git_delta_index *index);
33
+ extern size_t git_delta_index_size(git_delta_index *index);
38
34
 
39
35
  /*
40
36
  * create_delta: create a delta from given index for the given buffer
@@ -46,69 +42,94 @@ extern unsigned long git_delta_sizeof_index(struct git_delta_index *index);
46
42
  * returned and *delta_size is updated with its size. The returned buffer
47
43
  * must be freed by the caller.
48
44
  */
49
- extern void *git_delta_create(
45
+ extern int git_delta_create_from_index(
46
+ void **out,
47
+ size_t *out_size,
50
48
  const struct git_delta_index *index,
51
49
  const void *buf,
52
- unsigned long bufsize,
53
- unsigned long *delta_size,
54
- unsigned long max_delta_size);
50
+ size_t bufsize,
51
+ size_t max_delta_size);
55
52
 
56
53
  /*
57
54
  * diff_delta: create a delta from source buffer to target buffer
58
55
  *
59
56
  * If max_delta_size is non-zero and the resulting delta is to be larger
60
- * than max_delta_size then NULL is returned. On success, a non-NULL
57
+ * than max_delta_size then GIT_EBUFS is returned. On success, a non-NULL
61
58
  * pointer to the buffer with the delta data is returned and *delta_size is
62
59
  * updated with its size. The returned buffer must be freed by the caller.
63
60
  */
64
- GIT_INLINE(void *) git_delta(
65
- const void *src_buf, unsigned long src_bufsize,
66
- const void *trg_buf, unsigned long trg_bufsize,
67
- unsigned long *delta_size,
68
- unsigned long max_delta_size)
61
+ GIT_INLINE(int) git_delta(
62
+ void **out, size_t *out_len,
63
+ const void *src_buf, size_t src_bufsize,
64
+ const void *trg_buf, size_t trg_bufsize,
65
+ size_t max_delta_size)
69
66
  {
70
- struct git_delta_index *index = git_delta_create_index(src_buf, src_bufsize);
67
+ git_delta_index *index;
68
+ int error = 0;
69
+
70
+ *out = NULL;
71
+ *out_len = 0;
72
+
73
+ if ((error = git_delta_index_init(&index, src_buf, src_bufsize)) < 0)
74
+ return error;
75
+
71
76
  if (index) {
72
- void *delta = git_delta_create(
73
- index, trg_buf, trg_bufsize, delta_size, max_delta_size);
74
- git_delta_free_index(index);
75
- return delta;
77
+ error = git_delta_create_from_index(out, out_len,
78
+ index, trg_buf, trg_bufsize, max_delta_size);
79
+
80
+ git_delta_index_free(index);
76
81
  }
77
- return NULL;
78
- }
79
82
 
80
- /*
81
- * patch_delta: recreate target buffer given source buffer and delta data
82
- *
83
- * On success, a non-NULL pointer to the target buffer is returned and
84
- * *trg_bufsize is updated with its size. On failure a NULL pointer is
85
- * returned. The returned buffer must be freed by the caller.
86
- */
87
- extern void *git_delta_patch(
88
- const void *src_buf, unsigned long src_size,
89
- const void *delta_buf, unsigned long delta_size,
90
- unsigned long *dst_size);
83
+ return error;
84
+ }
91
85
 
92
86
  /* the smallest possible delta size is 4 bytes */
93
87
  #define GIT_DELTA_SIZE_MIN 4
94
88
 
95
- /*
96
- * This must be called twice on the delta data buffer, first to get the
97
- * expected source buffer size, and again to get the target buffer size.
89
+ /**
90
+ * Apply a git binary delta to recover the original content.
91
+ * The caller is responsible for freeing the returned buffer.
92
+ *
93
+ * @param out the output buffer
94
+ * @param out_len the length of the output buffer
95
+ * @param base the base to copy from during copy instructions.
96
+ * @param base_len number of bytes available at base.
97
+ * @param delta the delta to execute copy/insert instructions from.
98
+ * @param delta_len total number of bytes in the delta.
99
+ * @return 0 on success or an error code
100
+ */
101
+ extern int git_delta_apply(
102
+ void **out,
103
+ size_t *out_len,
104
+ const unsigned char *base,
105
+ size_t base_len,
106
+ const unsigned char *delta,
107
+ size_t delta_len);
108
+
109
+ /**
110
+ * Read the header of a git binary delta.
111
+ *
112
+ * @param base_out pointer to store the base size field.
113
+ * @param result_out pointer to store the result size field.
114
+ * @param delta the delta to execute copy/insert instructions from.
115
+ * @param delta_len total number of bytes in the delta.
116
+ * @return 0 on success or an error code
117
+ */
118
+ extern int git_delta_read_header(
119
+ size_t *base_out,
120
+ size_t *result_out,
121
+ const unsigned char *delta,
122
+ size_t delta_len);
123
+
124
+ /**
125
+ * Read the header of a git binary delta
126
+ *
127
+ * This variant reads just enough from the packfile stream to read the
128
+ * delta header.
98
129
  */
99
- GIT_INLINE(unsigned long) git_delta_get_hdr_size(
100
- const unsigned char **datap, const unsigned char *top)
101
- {
102
- const unsigned char *data = *datap;
103
- unsigned long cmd, size = 0;
104
- int i = 0;
105
- do {
106
- cmd = *data++;
107
- size |= (cmd & 0x7f) << i;
108
- i += 7;
109
- } while (cmd & 0x80 && data < top);
110
- *datap = data;
111
- return size;
112
- }
130
+ extern int git_delta_read_header_fromstream(
131
+ size_t *base_out,
132
+ size_t *result_out,
133
+ git_packfile_stream *stream);
113
134
 
114
135
  #endif
@@ -197,7 +197,7 @@ static int commit_name_dup(struct commit_name **out, struct commit_name *in)
197
197
  name->tag = NULL;
198
198
  name->path = NULL;
199
199
 
200
- if (in->tag && git_object_dup((git_object **) &name->tag, (git_object *) in->tag) < 0)
200
+ if (in->tag && git_tag_dup(&name->tag, in->tag) < 0)
201
201
  return -1;
202
202
 
203
203
  name->path = git__strdup(in->path);