rugged 0.25.0b2 → 0.25.0b3

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/extconf.rb +3 -1
  4. data/ext/rugged/rugged.c +1 -1
  5. data/ext/rugged/rugged.h +1 -1
  6. data/ext/rugged/rugged_blob.c +29 -38
  7. data/ext/rugged/rugged_commit.c +215 -78
  8. data/ext/rugged/rugged_rebase.c +18 -11
  9. data/ext/rugged/rugged_remote.c +2 -2
  10. data/ext/rugged/rugged_tree.c +132 -0
  11. data/lib/rugged/version.rb +1 -1
  12. data/vendor/libgit2/CMakeLists.txt +11 -3
  13. data/vendor/libgit2/include/git2.h +1 -0
  14. data/vendor/libgit2/include/git2/blob.h +39 -28
  15. data/vendor/libgit2/include/git2/commit.h +30 -0
  16. data/vendor/libgit2/include/git2/common.h +16 -1
  17. data/vendor/libgit2/include/git2/merge.h +10 -1
  18. data/vendor/libgit2/include/git2/proxy.h +92 -0
  19. data/vendor/libgit2/include/git2/refs.h +11 -0
  20. data/vendor/libgit2/include/git2/remote.h +17 -4
  21. data/vendor/libgit2/include/git2/signature.h +13 -0
  22. data/vendor/libgit2/include/git2/sys/merge.h +177 -0
  23. data/vendor/libgit2/include/git2/sys/remote.h +16 -0
  24. data/vendor/libgit2/include/git2/sys/stream.h +2 -1
  25. data/vendor/libgit2/include/git2/sys/transport.h +3 -1
  26. data/vendor/libgit2/include/git2/tag.h +9 -0
  27. data/vendor/libgit2/include/git2/tree.h +55 -0
  28. data/vendor/libgit2/src/annotated_commit.c +99 -80
  29. data/vendor/libgit2/src/annotated_commit.h +5 -2
  30. data/vendor/libgit2/src/array.h +40 -0
  31. data/vendor/libgit2/src/blame.c +8 -3
  32. data/vendor/libgit2/src/blame_git.c +2 -1
  33. data/vendor/libgit2/src/blob.c +71 -39
  34. data/vendor/libgit2/src/branch.c +2 -1
  35. data/vendor/libgit2/src/checkout.c +66 -42
  36. data/vendor/libgit2/src/commit.c +67 -3
  37. data/vendor/libgit2/src/config_cache.c +2 -1
  38. data/vendor/libgit2/src/config_file.c +32 -27
  39. data/vendor/libgit2/src/curl_stream.c +89 -6
  40. data/vendor/libgit2/src/delta-apply.c +36 -5
  41. data/vendor/libgit2/src/delta-apply.h +12 -0
  42. data/vendor/libgit2/src/describe.c +3 -2
  43. data/vendor/libgit2/src/diff.c +13 -20
  44. data/vendor/libgit2/src/diff_tform.c +5 -3
  45. data/vendor/libgit2/src/filebuf.c +12 -2
  46. data/vendor/libgit2/src/filebuf.h +1 -0
  47. data/vendor/libgit2/src/fnmatch.c +18 -5
  48. data/vendor/libgit2/src/global.c +18 -0
  49. data/vendor/libgit2/src/global.h +1 -0
  50. data/vendor/libgit2/src/ignore.c +11 -3
  51. data/vendor/libgit2/src/index.c +11 -5
  52. data/vendor/libgit2/src/indexer.c +11 -7
  53. data/vendor/libgit2/src/iterator.c +1575 -1468
  54. data/vendor/libgit2/src/iterator.h +52 -69
  55. data/vendor/libgit2/src/merge.c +160 -63
  56. data/vendor/libgit2/src/merge.h +61 -2
  57. data/vendor/libgit2/src/merge_driver.c +397 -0
  58. data/vendor/libgit2/src/merge_driver.h +60 -0
  59. data/vendor/libgit2/src/merge_file.c +11 -49
  60. data/vendor/libgit2/src/netops.c +12 -10
  61. data/vendor/libgit2/src/object.c +3 -6
  62. data/vendor/libgit2/src/object_api.c +19 -1
  63. data/vendor/libgit2/src/odb_loose.c +1 -1
  64. data/vendor/libgit2/src/openssl_stream.c +16 -3
  65. data/vendor/libgit2/src/pack-objects.c +3 -1
  66. data/vendor/libgit2/src/pack.c +5 -9
  67. data/vendor/libgit2/src/path.c +14 -0
  68. data/vendor/libgit2/src/path.h +12 -0
  69. data/vendor/libgit2/src/pathspec.c +1 -1
  70. data/vendor/libgit2/src/posix.c +7 -0
  71. data/vendor/libgit2/src/posix.h +1 -0
  72. data/vendor/libgit2/src/proxy.c +32 -0
  73. data/vendor/libgit2/src/proxy.h +14 -0
  74. data/vendor/libgit2/src/push.c +7 -7
  75. data/vendor/libgit2/src/rebase.c +61 -31
  76. data/vendor/libgit2/src/refdb_fs.c +1 -0
  77. data/vendor/libgit2/src/refs.c +16 -1
  78. data/vendor/libgit2/src/remote.c +20 -6
  79. data/vendor/libgit2/src/repository.c +1 -1
  80. data/vendor/libgit2/src/reset.c +1 -1
  81. data/vendor/libgit2/src/settings.c +23 -1
  82. data/vendor/libgit2/src/signature.c +26 -1
  83. data/vendor/libgit2/src/stransport_stream.c +5 -2
  84. data/vendor/libgit2/src/stream.h +2 -2
  85. data/vendor/libgit2/src/submodule.c +3 -2
  86. data/vendor/libgit2/src/tag.c +8 -2
  87. data/vendor/libgit2/src/transports/http.c +32 -9
  88. data/vendor/libgit2/src/transports/local.c +4 -1
  89. data/vendor/libgit2/src/transports/smart.c +6 -0
  90. data/vendor/libgit2/src/transports/smart.h +1 -0
  91. data/vendor/libgit2/src/transports/smart_protocol.c +61 -17
  92. data/vendor/libgit2/src/transports/winhttp.c +130 -11
  93. data/vendor/libgit2/src/tree.c +329 -98
  94. data/vendor/libgit2/src/tree.h +4 -5
  95. data/vendor/libgit2/src/unix/map.c +5 -0
  96. data/vendor/libgit2/src/win32/map.c +24 -5
  97. data/vendor/libgit2/src/xdiff/xprepare.c +2 -1
  98. metadata +10 -4
  99. data/vendor/libgit2/Makefile.embed +0 -60
@@ -104,7 +104,7 @@ static int validate_tree_and_parents(git_array_oid_t *parents, git_repository *r
104
104
  i++;
105
105
  }
106
106
 
107
- if (current_id && git_oid_cmp(current_id, git_array_get(*parents, 0))) {
107
+ if (current_id && (parents->size == 0 || git_oid_cmp(current_id, git_array_get(*parents, 0)))) {
108
108
  giterr_set(GITERR_OBJECT, "failed to create commit: current tip is not the first parent");
109
109
  error = GIT_EMODIFIED;
110
110
  goto on_error;
@@ -615,7 +615,7 @@ int git_commit_nth_gen_ancestor(
615
615
 
616
616
  assert(ancestor && commit);
617
617
 
618
- if (git_object_dup((git_object **) &current, (git_object *) commit) < 0)
618
+ if (git_commit_dup(&current, (git_commit *)commit) < 0)
619
619
  return -1;
620
620
 
621
621
  if (n == 0) {
@@ -726,7 +726,7 @@ int git_commit_extract_signature(git_buf *signature, git_buf *signed_data, git_r
726
726
 
727
727
  buf = git_odb_object_data(obj);
728
728
 
729
- while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') {
729
+ while ((h = strchr(buf, '\n')) && h[1] != '\0') {
730
730
  h++;
731
731
  if (git__prefixcmp(buf, field)) {
732
732
  if (git_buf_put(signed_data, buf, h - buf) < 0)
@@ -820,3 +820,67 @@ int git_commit_create_buffer(git_buf *out,
820
820
  git_array_clear(parents_arr);
821
821
  return error;
822
822
  }
823
+
824
+ /**
825
+ * Append to 'out' properly marking continuations when there's a newline in 'content'
826
+ */
827
+ static void format_header_field(git_buf *out, const char *field, const char *content)
828
+ {
829
+ const char *lf;
830
+
831
+ assert(out && field && content);
832
+
833
+ git_buf_puts(out, field);
834
+ git_buf_putc(out, ' ');
835
+
836
+ while ((lf = strchr(content, '\n')) != NULL) {
837
+ git_buf_put(out, content, lf - content);
838
+ git_buf_puts(out, "\n ");
839
+ content = lf + 1;
840
+ }
841
+
842
+ git_buf_puts(out, content);
843
+ git_buf_putc(out, '\n');
844
+ }
845
+
846
+ int git_commit_create_with_signature(
847
+ git_oid *out,
848
+ git_repository *repo,
849
+ const char *commit_content,
850
+ const char *signature,
851
+ const char *signature_field)
852
+ {
853
+ git_odb *odb;
854
+ int error = 0;
855
+ const char *field;
856
+ const char *header_end;
857
+ git_buf commit = GIT_BUF_INIT;
858
+
859
+ /* We start by identifying the end of the commit header */
860
+ header_end = strstr(commit_content, "\n\n");
861
+ if (!header_end) {
862
+ giterr_set(GITERR_INVALID, "malformed commit contents");
863
+ return -1;
864
+ }
865
+
866
+ field = signature_field ? signature_field : "gpgsig";
867
+
868
+ /* The header ends after the first LF */
869
+ header_end++;
870
+ git_buf_put(&commit, commit_content, header_end - commit_content);
871
+ format_header_field(&commit, field, signature);
872
+ git_buf_puts(&commit, header_end);
873
+
874
+ if (git_buf_oom(&commit))
875
+ return -1;
876
+
877
+ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0)
878
+ goto cleanup;
879
+
880
+ if ((error = git_odb_write(out, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT)) < 0)
881
+ goto cleanup;
882
+
883
+ cleanup:
884
+ git_buf_free(&commit);
885
+ return error;
886
+ }
@@ -86,7 +86,8 @@ int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)
86
86
  struct map_data *data = &_cvar_maps[(int)cvar];
87
87
  git_config_entry *entry;
88
88
 
89
- git_config__lookup_entry(&entry, config, data->cvar_name, false);
89
+ if ((error = git_config__lookup_entry(&entry, config, data->cvar_name, false)) < 0)
90
+ return error;
90
91
 
91
92
  if (!entry)
92
93
  *out = data->default_value;
@@ -232,7 +232,10 @@ static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
232
232
  {
233
233
  refcounted_strmap *map;
234
234
 
235
- git_mutex_lock(&h->values_mutex);
235
+ if (git_mutex_lock(&h->values_mutex) < 0) {
236
+ giterr_set(GITERR_OS, "Failed to lock config backend");
237
+ return NULL;
238
+ }
236
239
 
237
240
  map = h->values;
238
241
  git_atomic_inc(&map->refcount);
@@ -318,7 +321,10 @@ static int config__refresh(git_config_backend *cfg)
318
321
  if ((error = config_read(values->values, b, reader, b->level, 0)) < 0)
319
322
  goto out;
320
323
 
321
- git_mutex_lock(&b->header.values_mutex);
324
+ if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
325
+ giterr_set(GITERR_OS, "Failed to lock config backend");
326
+ goto out;
327
+ }
322
328
 
323
329
  tmp = b->header.values;
324
330
  b->header.values = values;
@@ -460,7 +466,8 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
460
466
  if ((rval = git_config__normalize_name(name, &key)) < 0)
461
467
  return rval;
462
468
 
463
- map = refcounted_strmap_take(&b->header);
469
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
470
+ return -1;
464
471
  values = map->values;
465
472
 
466
473
  /*
@@ -527,7 +534,8 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry
527
534
  if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
528
535
  return error;
529
536
 
530
- map = refcounted_strmap_take(h);
537
+ if ((map = refcounted_strmap_take(h)) == NULL)
538
+ return -1;
531
539
  values = map->values;
532
540
 
533
541
  pos = git_strmap_lookup_index(values, key);
@@ -553,30 +561,15 @@ static int config_set_multivar(
553
561
  git_config_backend *cfg, const char *name, const char *regexp, const char *value)
554
562
  {
555
563
  diskfile_backend *b = (diskfile_backend *)cfg;
556
- refcounted_strmap *map;
557
- git_strmap *values;
558
564
  char *key;
559
565
  regex_t preg;
560
566
  int result;
561
- khiter_t pos;
562
567
 
563
568
  assert(regexp);
564
569
 
565
570
  if ((result = git_config__normalize_name(name, &key)) < 0)
566
571
  return result;
567
572
 
568
- map = refcounted_strmap_take(&b->header);
569
- values = b->header.values->values;
570
-
571
- pos = git_strmap_lookup_index(values, key);
572
- if (!git_strmap_valid_index(values, pos)) {
573
- /* If we don't have it, behave like a normal set */
574
- result = config_set(cfg, name, value);
575
- refcounted_strmap_free(map);
576
- git__free(key);
577
- return result;
578
- }
579
-
580
573
  result = regcomp(&preg, regexp, REG_EXTENDED);
581
574
  if (result != 0) {
582
575
  giterr_set_regex(&preg, result);
@@ -591,7 +584,6 @@ static int config_set_multivar(
591
584
  result = config_refresh(cfg);
592
585
 
593
586
  out:
594
- refcounted_strmap_free(map);
595
587
  git__free(key);
596
588
  regfree(&preg);
597
589
 
@@ -610,7 +602,8 @@ static int config_delete(git_config_backend *cfg, const char *name)
610
602
  if ((result = git_config__normalize_name(name, &key)) < 0)
611
603
  return result;
612
604
 
613
- map = refcounted_strmap_take(&b->header);
605
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
606
+ return -1;
614
607
  values = b->header.values->values;
615
608
 
616
609
  pos = git_strmap_lookup_index(values, key);
@@ -649,7 +642,8 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
649
642
  if ((result = git_config__normalize_name(name, &key)) < 0)
650
643
  return result;
651
644
 
652
- map = refcounted_strmap_take(&b->header);
645
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
646
+ return -1;
653
647
  values = b->header.values->values;
654
648
 
655
649
  pos = git_strmap_lookup_index(values, key);
@@ -832,7 +826,8 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
832
826
  /* We're just copying data, don't care about the level */
833
827
  GIT_UNUSED(level);
834
828
 
835
- src_map = refcounted_strmap_take(src_header);
829
+ if ((src_map = refcounted_strmap_take(src_header)) == NULL)
830
+ return -1;
836
831
  b->header.values = src_map;
837
832
 
838
833
  return 0;
@@ -1032,6 +1027,11 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
1032
1027
  */
1033
1028
 
1034
1029
  first_quote = strchr(line, '"');
1030
+ if (first_quote == NULL) {
1031
+ set_parse_error(reader, 0, "Missing quotation marks in section header");
1032
+ return -1;
1033
+ }
1034
+
1035
1035
  last_quote = strrchr(line, '"');
1036
1036
  quoted_len = last_quote - first_quote;
1037
1037
 
@@ -1483,7 +1483,7 @@ static int config_parse(
1483
1483
  int (*on_section)(struct reader **reader, const char *current_section, const char *line, size_t line_len, void *data),
1484
1484
  int (*on_variable)(struct reader **reader, const char *current_section, char *var_name, char *var_value, const char *line, size_t line_len, void *data),
1485
1485
  int (*on_comment)(struct reader **reader, const char *line, size_t line_len, void *data),
1486
- int (*on_eof)(struct reader **reader, void *data),
1486
+ int (*on_eof)(struct reader **reader, const char *current_section, void *data),
1487
1487
  void *data)
1488
1488
  {
1489
1489
  char *current_section = NULL, *var_name, *var_value, *line_start;
@@ -1534,7 +1534,7 @@ static int config_parse(
1534
1534
  }
1535
1535
 
1536
1536
  if (on_eof)
1537
- result = on_eof(&reader, data);
1537
+ result = on_eof(&reader, current_section, data);
1538
1538
 
1539
1539
  git__free(current_section);
1540
1540
  return result;
@@ -1850,7 +1850,8 @@ static int write_on_comment(struct reader **reader, const char *line, size_t lin
1850
1850
  return write_line_to(&write_data->buffered_comment, line, line_len);
1851
1851
  }
1852
1852
 
1853
- static int write_on_eof(struct reader **reader, void *data)
1853
+ static int write_on_eof(
1854
+ struct reader **reader, const char *current_section, void *data)
1854
1855
  {
1855
1856
  struct write_data *write_data = (struct write_data *)data;
1856
1857
  int result = 0;
@@ -1869,7 +1870,11 @@ static int write_on_eof(struct reader **reader, void *data)
1869
1870
  * value.
1870
1871
  */
1871
1872
  if ((!write_data->preg || !write_data->preg_replaced) && write_data->value) {
1872
- if ((result = write_section(write_data->buf, write_data->section)) == 0)
1873
+ /* write the section header unless we're already in it */
1874
+ if (!current_section || strcmp(current_section, write_data->section))
1875
+ result = write_section(write_data->buf, write_data->section);
1876
+
1877
+ if (!result)
1873
1878
  result = write_value(write_data);
1874
1879
  }
1875
1880
 
@@ -13,6 +13,7 @@
13
13
  #include "git2/transport.h"
14
14
  #include "buffer.h"
15
15
  #include "vector.h"
16
+ #include "proxy.h"
16
17
 
17
18
  typedef struct {
18
19
  git_stream parent;
@@ -21,6 +22,8 @@ typedef struct {
21
22
  char curl_error[CURL_ERROR_SIZE + 1];
22
23
  git_cert_x509 cert_info;
23
24
  git_strarray cert_info_strings;
25
+ git_proxy_options proxy;
26
+ git_cred *proxy_cred;
24
27
  } curl_stream;
25
28
 
26
29
  static int seterr_curl(curl_stream *s)
@@ -29,21 +32,94 @@ static int seterr_curl(curl_stream *s)
29
32
  return -1;
30
33
  }
31
34
 
35
+ GIT_INLINE(int) error_no_credentials(void)
36
+ {
37
+ giterr_set(GITERR_NET, "proxy authentication required, but no callback provided");
38
+ return GIT_EAUTH;
39
+ }
40
+
41
+ static int apply_proxy_creds(curl_stream *s)
42
+ {
43
+ CURLcode res;
44
+ git_cred_userpass_plaintext *userpass;
45
+
46
+ if (!s->proxy_cred)
47
+ return GIT_ENOTFOUND;
48
+
49
+ userpass = (git_cred_userpass_plaintext *) s->proxy_cred;
50
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYUSERNAME, userpass->username)) != CURLE_OK)
51
+ return seterr_curl(s);
52
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYPASSWORD, userpass->password)) != CURLE_OK)
53
+ return seterr_curl(s);
54
+
55
+ return 0;
56
+ }
57
+
58
+ static int ask_and_apply_proxy_creds(curl_stream *s)
59
+ {
60
+ int error;
61
+ git_proxy_options *opts = &s->proxy;
62
+
63
+ if (!opts->credentials)
64
+ return error_no_credentials();
65
+
66
+ /* TODO: see if PROXYAUTH_AVAIL helps us here */
67
+ git_cred_free(s->proxy_cred);
68
+ s->proxy_cred = NULL;
69
+ giterr_clear();
70
+ error = opts->credentials(&s->proxy_cred, opts->url, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, opts->payload);
71
+ if (error == GIT_PASSTHROUGH)
72
+ return error_no_credentials();
73
+ if (error < 0) {
74
+ if (!giterr_last())
75
+ giterr_set(GITERR_NET, "proxy authentication was aborted by the user");
76
+ return error;
77
+ }
78
+
79
+ if (s->proxy_cred->credtype != GIT_CREDTYPE_USERPASS_PLAINTEXT) {
80
+ giterr_set(GITERR_NET, "credentials callback returned invalid credential type");
81
+ return -1;
82
+ }
83
+
84
+ return apply_proxy_creds(s);
85
+ }
86
+
32
87
  static int curls_connect(git_stream *stream)
33
88
  {
34
89
  curl_stream *s = (curl_stream *) stream;
35
- long sockextr;
36
- int failed_cert = 0;
90
+ long sockextr, connect_last = 0;
91
+ int failed_cert = 0, error;
92
+ bool retry_connect;
37
93
  CURLcode res;
38
- res = curl_easy_perform(s->handle);
94
+
95
+ /* Apply any credentials we've already established */
96
+ error = apply_proxy_creds(s);
97
+ if (error < 0 && error != GIT_ENOTFOUND)
98
+ return seterr_curl(s);
99
+
100
+ do {
101
+ retry_connect = 0;
102
+ res = curl_easy_perform(s->handle);
103
+
104
+ curl_easy_getinfo(s->handle, CURLINFO_HTTP_CONNECTCODE, &connect_last);
105
+
106
+ /* HTTP 407 Proxy Authentication Required */
107
+ if (connect_last == 407) {
108
+ if ((error = ask_and_apply_proxy_creds(s)) < 0)
109
+ return error;
110
+
111
+ retry_connect = true;
112
+ }
113
+ } while (retry_connect);
39
114
 
40
115
  if (res != CURLE_OK && res != CURLE_PEER_FAILED_VERIFICATION)
41
116
  return seterr_curl(s);
42
117
  if (res == CURLE_PEER_FAILED_VERIFICATION)
43
118
  failed_cert = 1;
44
119
 
45
- if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK)
120
+ if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK) {
46
121
  return seterr_curl(s);
122
+ }
47
123
 
48
124
  s->socket = sockextr;
49
125
 
@@ -95,12 +171,19 @@ static int curls_certificate(git_cert **out, git_stream *stream)
95
171
  return 0;
96
172
  }
97
173
 
98
- static int curls_set_proxy(git_stream *stream, const char *proxy_url)
174
+ static int curls_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)
99
175
  {
176
+ int error;
100
177
  CURLcode res;
101
178
  curl_stream *s = (curl_stream *) stream;
102
179
 
103
- if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK)
180
+ if ((error = git_proxy_options_dup(&s->proxy, proxy_opts)) < 0)
181
+ return error;
182
+
183
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, s->proxy.url)) != CURLE_OK)
184
+ return seterr_curl(s);
185
+
186
+ if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY)) != CURLE_OK)
104
187
  return seterr_curl(s);
105
188
 
106
189
  return 0;
@@ -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)