rugged 0.26.0b5 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged.c +24 -0
  3. data/ext/rugged/rugged.h +2 -0
  4. data/ext/rugged/rugged_signature.c +15 -2
  5. data/lib/rugged/version.rb +1 -1
  6. data/vendor/libgit2/CMakeLists.txt +9 -8
  7. data/vendor/libgit2/include/git2/common.h +29 -0
  8. data/vendor/libgit2/include/git2/errors.h +2 -0
  9. data/vendor/libgit2/include/git2/global.h +1 -1
  10. data/vendor/libgit2/include/git2/odb.h +2 -2
  11. data/vendor/libgit2/include/git2/odb_backend.h +1 -1
  12. data/vendor/libgit2/include/git2/remote.h +3 -3
  13. data/vendor/libgit2/include/git2/repository.h +2 -2
  14. data/vendor/libgit2/include/git2/sys/filter.h +11 -0
  15. data/vendor/libgit2/include/git2/sys/merge.h +5 -5
  16. data/vendor/libgit2/include/git2/sys/transport.h +10 -0
  17. data/vendor/libgit2/include/git2/transport.h +6 -6
  18. data/vendor/libgit2/include/git2/version.h +3 -3
  19. data/vendor/libgit2/include/git2/worktree.h +69 -10
  20. data/vendor/libgit2/libgit2.pc.in +2 -2
  21. data/vendor/libgit2/src/attr_file.c +6 -2
  22. data/vendor/libgit2/src/attrcache.c +7 -5
  23. data/vendor/libgit2/src/blame_git.c +12 -8
  24. data/vendor/libgit2/src/branch.c +17 -48
  25. data/vendor/libgit2/src/buffer.c +11 -12
  26. data/vendor/libgit2/src/buffer.h +2 -2
  27. data/vendor/libgit2/src/checkout.c +3 -6
  28. data/vendor/libgit2/src/config.c +42 -35
  29. data/vendor/libgit2/src/config_cache.c +1 -0
  30. data/vendor/libgit2/src/config_file.c +19 -11
  31. data/vendor/libgit2/src/config_file.h +1 -0
  32. data/vendor/libgit2/src/diff.c +35 -0
  33. data/vendor/libgit2/src/diff_parse.c +7 -1
  34. data/vendor/libgit2/src/filebuf.c +12 -1
  35. data/vendor/libgit2/src/filebuf.h +3 -1
  36. data/vendor/libgit2/src/fileops.c +83 -22
  37. data/vendor/libgit2/src/fileops.h +25 -0
  38. data/vendor/libgit2/src/filter.c +30 -14
  39. data/vendor/libgit2/src/global.c +1 -1
  40. data/vendor/libgit2/src/hash/hash_collisiondetect.h +1 -11
  41. data/vendor/libgit2/src/hash/sha1dc/sha1.c +894 -187
  42. data/vendor/libgit2/src/hash/sha1dc/sha1.h +69 -53
  43. data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +13 -2
  44. data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +20 -3
  45. data/vendor/libgit2/src/idxmap.c +1 -1
  46. data/vendor/libgit2/src/idxmap.h +1 -2
  47. data/vendor/libgit2/src/index.c +75 -42
  48. data/vendor/libgit2/src/indexer.c +31 -11
  49. data/vendor/libgit2/src/indexer.h +12 -0
  50. data/vendor/libgit2/src/merge.c +20 -0
  51. data/vendor/libgit2/src/merge_driver.c +29 -0
  52. data/vendor/libgit2/src/odb.c +96 -19
  53. data/vendor/libgit2/src/odb.h +25 -0
  54. data/vendor/libgit2/src/odb_loose.c +20 -6
  55. data/vendor/libgit2/src/odb_pack.c +1 -1
  56. data/vendor/libgit2/src/offmap.c +1 -1
  57. data/vendor/libgit2/src/offmap.h +1 -2
  58. data/vendor/libgit2/src/oidmap.c +1 -1
  59. data/vendor/libgit2/src/oidmap.h +1 -2
  60. data/vendor/libgit2/src/openssl_stream.c +11 -4
  61. data/vendor/libgit2/src/pack-objects.c +4 -0
  62. data/vendor/libgit2/src/pack-objects.h +1 -0
  63. data/vendor/libgit2/src/pack.c +5 -3
  64. data/vendor/libgit2/src/patch_generate.c +8 -79
  65. data/vendor/libgit2/src/patch_parse.c +5 -4
  66. data/vendor/libgit2/src/path.c +9 -7
  67. data/vendor/libgit2/src/posix.c +2 -0
  68. data/vendor/libgit2/src/posix.h +10 -0
  69. data/vendor/libgit2/src/rebase.c +12 -10
  70. data/vendor/libgit2/src/refdb_fs.c +33 -10
  71. data/vendor/libgit2/src/refs.c +89 -8
  72. data/vendor/libgit2/src/refs.h +14 -0
  73. data/vendor/libgit2/src/remote.c +9 -10
  74. data/vendor/libgit2/src/repository.c +178 -146
  75. data/vendor/libgit2/src/repository.h +25 -0
  76. data/vendor/libgit2/src/revparse.c +22 -3
  77. data/vendor/libgit2/src/revwalk.c +6 -3
  78. data/vendor/libgit2/src/settings.c +22 -1
  79. data/vendor/libgit2/src/signature.c +4 -1
  80. data/vendor/libgit2/src/socket_stream.c +2 -4
  81. data/vendor/libgit2/src/strmap.c +1 -1
  82. data/vendor/libgit2/src/strmap.h +1 -3
  83. data/vendor/libgit2/src/submodule.c +27 -7
  84. data/vendor/libgit2/src/sysdir.c +11 -0
  85. data/vendor/libgit2/src/sysdir.h +12 -0
  86. data/vendor/libgit2/src/transports/http.c +3 -0
  87. data/vendor/libgit2/src/transports/smart.c +6 -0
  88. data/vendor/libgit2/src/transports/smart_protocol.c +2 -1
  89. data/vendor/libgit2/src/transports/ssh.c +13 -1
  90. data/vendor/libgit2/src/transports/winhttp.c +1 -2
  91. data/vendor/libgit2/src/tree.c +13 -11
  92. data/vendor/libgit2/src/unix/posix.h +6 -1
  93. data/vendor/libgit2/src/varint.c +1 -1
  94. data/vendor/libgit2/src/win32/posix.h +3 -0
  95. data/vendor/libgit2/src/win32/posix_w32.c +334 -111
  96. data/vendor/libgit2/src/worktree.c +174 -48
  97. data/vendor/libgit2/src/worktree.h +1 -1
  98. metadata +77 -76
@@ -5,41 +5,41 @@
5
5
  * https://opensource.org/licenses/MIT
6
6
  ***/
7
7
 
8
- #include <stdint.h>
9
-
10
- // uses SHA-1 message expansion to expand the first 16 words of W[] to 80 words
11
- void sha1_message_expansion(uint32_t W[80]);
8
+ #ifndef SHA1DC_SHA1_H
9
+ #define SHA1DC_SHA1_H
12
10
 
13
- // sha-1 compression function; first version takes a message block pre-parsed as 16 32-bit integers, second version takes an already expanded message)
14
- void sha1_compression(uint32_t ihv[5], const uint32_t m[16]);
15
- void sha1_compression_W(uint32_t ihv[5], const uint32_t W[80]);
11
+ #if defined(__cplusplus)
12
+ extern "C" {
13
+ #endif
16
14
 
17
- // same as sha1_compression_W, but additionally store intermediate states
18
- // only stores states ii (the state between step ii-1 and step ii) when DOSTORESTATEii is defined in ubc_check.h
19
- void sha1_compression_states(uint32_t ihv[5], const uint32_t W[80], uint32_t states[80][5]);
20
-
21
- // function type for sha1_recompression_step_T (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5])
22
- // where 0 <= T < 80
23
- // me2 is an expanded message (the expansion of an original message block XOR'ed with a disturbance vector's message block difference)
24
- // state is the internal state (a,b,c,d,e) before step T of the SHA-1 compression function while processing the original message block
25
- // the function will return:
26
- // ihvin: the reconstructed input chaining value
27
- // ihvout: the reconstructed output chaining value
15
+ #ifndef SHA1DC_NO_STANDARD_INCLUDES
16
+ #include <stdint.h>
17
+ #endif
18
+
19
+ /* sha-1 compression function that takes an already expanded message, and additionally store intermediate states */
20
+ /* only stores states ii (the state between step ii-1 and step ii) when DOSTORESTATEii is defined in ubc_check.h */
21
+ void sha1_compression_states(uint32_t[5], const uint32_t[16], uint32_t[80], uint32_t[80][5]);
22
+
23
+ /*
24
+ // Function type for sha1_recompression_step_T (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5]).
25
+ // Where 0 <= T < 80
26
+ // me2 is an expanded message (the expansion of an original message block XOR'ed with a disturbance vector's message block difference.)
27
+ // state is the internal state (a,b,c,d,e) before step T of the SHA-1 compression function while processing the original message block.
28
+ // The function will return:
29
+ // ihvin: The reconstructed input chaining value.
30
+ // ihvout: The reconstructed output chaining value.
31
+ */
28
32
  typedef void(*sha1_recompression_type)(uint32_t*, uint32_t*, const uint32_t*, const uint32_t*);
29
33
 
30
- // table of sha1_recompression_step_0, ... , sha1_recompression_step_79
31
- extern sha1_recompression_type sha1_recompression_step[80];
32
-
33
- // a callback function type that can be set to be called when a collision block has been found:
34
- // void collision_block_callback(uint64_t byteoffset, const uint32_t ihvin1[5], const uint32_t ihvin2[5], const uint32_t m1[80], const uint32_t m2[80])
34
+ /* A callback function type that can be set to be called when a collision block has been found: */
35
+ /* void collision_block_callback(uint64_t byteoffset, const uint32_t ihvin1[5], const uint32_t ihvin2[5], const uint32_t m1[80], const uint32_t m2[80]) */
35
36
  typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
36
37
 
37
- // the SHA-1 context
38
+ /* The SHA-1 context. */
38
39
  typedef struct {
39
40
  uint64_t total;
40
41
  uint32_t ihv[5];
41
42
  unsigned char buffer[64];
42
- int bigendian;
43
43
  int found_collision;
44
44
  int safe_hash;
45
45
  int detect_coll;
@@ -54,41 +54,57 @@ typedef struct {
54
54
  uint32_t states[80][5];
55
55
  } SHA1_CTX;
56
56
 
57
- // initialize SHA-1 context
58
- void SHA1DCInit(SHA1_CTX*);
59
-
60
- // function to enable safe SHA-1 hashing:
61
- // collision attacks are thwarted by hashing a detected near-collision block 3 times
62
- // think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
63
- // the best collision attacks against SHA-1 have complexity about 2^60,
64
- // thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would 2^180
65
- // an attacker would be better off using a generic birthday search of complexity 2^80
66
- //
67
- // enabling safe SHA-1 hashing will result in the correct SHA-1 hash for messages where no collision attack was detected
68
- // but it will result in a different SHA-1 hash for messages where a collision attack was detected
69
- // this will automatically invalidate SHA-1 based digital signature forgeries
70
- // enabled by default
57
+ /* Initialize SHA-1 context. */
58
+ void SHA1DCInit(SHA1_CTX*);
59
+
60
+ /*
61
+ Function to enable safe SHA-1 hashing:
62
+ Collision attacks are thwarted by hashing a detected near-collision block 3 times.
63
+ Think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
64
+ The best collision attacks against SHA-1 have complexity about 2^60,
65
+ thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would be 2^180.
66
+ An attacker would be better off using a generic birthday search of complexity 2^80.
67
+
68
+ Enabling safe SHA-1 hashing will result in the correct SHA-1 hash for messages where no collision attack was detected,
69
+ but it will result in a different SHA-1 hash for messages where a collision attack was detected.
70
+ This will automatically invalidate SHA-1 based digital signature forgeries.
71
+ Enabled by default.
72
+ */
71
73
  void SHA1DCSetSafeHash(SHA1_CTX*, int);
72
74
 
73
- // function to disable or enable the use of Unavoidable Bitconditions (provides a significant speed up)
74
- // enabled by default
75
+ /*
76
+ Function to disable or enable the use of Unavoidable Bitconditions (provides a significant speed up).
77
+ Enabled by default
78
+ */
75
79
  void SHA1DCSetUseUBC(SHA1_CTX*, int);
76
80
 
77
- // function to disable or enable the use of Collision Detection
78
- // enabled by default
79
- void SHA1DCSetUseDetectColl(SHA1_CTX* ctx, int detect_coll);
81
+ /*
82
+ Function to disable or enable the use of Collision Detection.
83
+ Enabled by default.
84
+ */
85
+ void SHA1DCSetUseDetectColl(SHA1_CTX*, int);
80
86
 
81
- // function to disable or enable the detection of reduced-round SHA-1 collisions
82
- // disabled by default
87
+ /* function to disable or enable the detection of reduced-round SHA-1 collisions */
88
+ /* disabled by default */
83
89
  void SHA1DCSetDetectReducedRoundCollision(SHA1_CTX*, int);
84
90
 
85
- // function to set a callback function, pass NULL to disable
86
- // by default no callback set
91
+ /* function to set a callback function, pass NULL to disable */
92
+ /* by default no callback set */
87
93
  void SHA1DCSetCallback(SHA1_CTX*, collision_block_callback);
88
94
 
89
- // update SHA-1 context with buffer contents
90
- void SHA1DCUpdate(SHA1_CTX*, const char*, unsigned);
95
+ /* update SHA-1 context with buffer contents */
96
+ void SHA1DCUpdate(SHA1_CTX*, const char*, size_t);
97
+
98
+ /* obtain SHA-1 hash from SHA-1 context */
99
+ /* returns: 0 = no collision detected, otherwise = collision found => warn user for active attack */
100
+ int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
101
+
102
+ #if defined(__cplusplus)
103
+ }
104
+ #endif
105
+
106
+ #ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
107
+ #include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
108
+ #endif
91
109
 
92
- // obtain SHA-1 hash from SHA-1 context
93
- // returns: 0 = no collision detected, otherwise = collision found => warn user for active attack
94
- int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
110
+ #endif
@@ -5,6 +5,7 @@
5
5
  * https://opensource.org/licenses/MIT
6
6
  ***/
7
7
 
8
+ /*
8
9
  // this file was generated by the 'parse_bitrel' program in the tools section
9
10
  // using the data files from directory 'tools/data/3565'
10
11
  //
@@ -17,12 +18,18 @@
17
18
  // ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
18
19
  // it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
19
20
  // thus one needs to do the recompression check for each DV that has its bit set
20
- //
21
+ //
21
22
  // ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded
22
23
  // a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c
23
24
  // ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
25
+ */
24
26
 
27
+ #ifndef SHA1DC_NO_STANDARD_INCLUDES
25
28
  #include <stdint.h>
29
+ #endif
30
+ #ifdef SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
31
+ #include SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
32
+ #endif
26
33
  #include "ubc_check.h"
27
34
 
28
35
  static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
@@ -58,7 +65,7 @@ static const uint32_t DV_II_54_0_bit = (uint32_t)(1) << 29;
58
65
  static const uint32_t DV_II_55_0_bit = (uint32_t)(1) << 30;
59
66
  static const uint32_t DV_II_56_0_bit = (uint32_t)(1) << 31;
60
67
 
61
- dv_info_t sha1_dvs[] =
68
+ dv_info_t sha1_dvs[] =
62
69
  {
63
70
  {1,43,0,58,0,0, { 0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161,0x80000599 } }
64
71
  , {1,44,0,58,0,1, { 0xb4000008,0x08000000,0x9800000c,0xd8000010,0x08000010,0xb8000010,0x98000000,0x60000000,0x00000008,0xc0000000,0x90000014,0x10000010,0xb8000014,0x28000000,0x20000010,0x48000000,0x08000018,0x60000000,0x90000010,0xf0000010,0x90000008,0xc0000000,0x90000010,0xf0000010,0xb0000008,0x40000000,0x90000000,0xf0000010,0x90000018,0x60000000,0x90000010,0x90000010,0x90000000,0x80000000,0x00000010,0xa0000000,0x20000000,0xa0000000,0x20000010,0x00000000,0x20000010,0x20000000,0x00000010,0x20000000,0x00000010,0xa0000000,0x00000000,0x20000000,0x20000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,0x00000020,0x00000001,0x40000002,0x40000040,0x40000002,0x80000004,0x80000080,0x80000006,0x00000049,0x00000103,0x80000009,0x80000012,0x80000202,0x00000018,0x00000164,0x00000408,0x800000e6,0x8000004c,0x00000803,0x80000161 } }
@@ -359,3 +366,7 @@ if (mask) {
359
366
 
360
367
  dvmask[0]=mask;
361
368
  }
369
+
370
+ #ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
371
+ #include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
372
+ #endif
@@ -5,6 +5,7 @@
5
5
  * https://opensource.org/licenses/MIT
6
6
  ***/
7
7
 
8
+ /*
8
9
  // this file was generated by the 'parse_bitrel' program in the tools section
9
10
  // using the data files from directory 'tools/data/3565'
10
11
  //
@@ -17,11 +18,18 @@
17
18
  // ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
18
19
  // it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
19
20
  // thus one needs to do the recompression check for each DV that has its bit set
21
+ */
20
22
 
21
- #ifndef UBC_CHECK_H
22
- #define UBC_CHECK_H
23
+ #ifndef SHA1DC_UBC_CHECK_H
24
+ #define SHA1DC_UBC_CHECK_H
23
25
 
26
+ #if defined(__cplusplus)
27
+ extern "C" {
28
+ #endif
29
+
30
+ #ifndef SHA1DC_NO_STANDARD_INCLUDES
24
31
  #include <stdint.h>
32
+ #endif
25
33
 
26
34
  #define DVMASKSIZE 1
27
35
  typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
@@ -31,5 +39,14 @@ void ubc_check(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);
31
39
  #define DOSTORESTATE58
32
40
  #define DOSTORESTATE65
33
41
 
42
+ #define CHECK_DVMASK(_DVMASK) (0 != _DVMASK[0])
43
+
44
+ #if defined(__cplusplus)
45
+ }
46
+ #endif
47
+
48
+ #ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
49
+ #include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
50
+ #endif
34
51
 
35
- #endif // UBC_CHECK_H
52
+ #endif
@@ -99,7 +99,7 @@ void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size)
99
99
  kh_resize(idxicase, map, size);
100
100
  }
101
101
 
102
- void git_idxmap__free(git_idxmap *map)
102
+ void git_idxmap_free(git_idxmap *map)
103
103
  {
104
104
  kh_destroy(idx, map);
105
105
  }
@@ -39,8 +39,7 @@ int git_idxmap_has_data(git_idxmap *map, size_t idx);
39
39
 
40
40
  void git_idxmap_resize(git_idxmap *map, size_t size);
41
41
  void git_idxmap_icase_resize(git_idxmap_icase *map, size_t size);
42
- #define git_idxmap_free(h) git_idxmap__free(h); (h) = NULL
43
- void git_idxmap__free(git_idxmap *map);
42
+ void git_idxmap_free(git_idxmap *map);
44
43
  void git_idxmap_clear(git_idxmap *map);
45
44
 
46
45
  void git_idxmap_delete_at(git_idxmap *map, size_t idx);
@@ -54,10 +54,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
54
54
  unsigned int flags,
55
55
  git_index_matched_path_cb cb, void *payload);
56
56
 
57
- #define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
58
- #define short_entry_size(len) entry_size(struct entry_short, len)
59
- #define long_entry_size(len) entry_size(struct entry_long, len)
60
-
61
57
  #define minimal_entry_size (offsetof(struct entry_short, path))
62
58
 
63
59
  static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
@@ -2282,12 +2278,29 @@ out_err:
2282
2278
  return 0;
2283
2279
  }
2284
2280
 
2281
+ static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flags)
2282
+ {
2283
+ if (varint_len) {
2284
+ if (flags & GIT_IDXENTRY_EXTENDED)
2285
+ return offsetof(struct entry_long, path) + path_len + 1 + varint_len;
2286
+ else
2287
+ return offsetof(struct entry_short, path) + path_len + 1 + varint_len;
2288
+ } else {
2289
+ #define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
2290
+ if (flags & GIT_IDXENTRY_EXTENDED)
2291
+ return entry_size(struct entry_long, path_len);
2292
+ else
2293
+ return entry_size(struct entry_short, path_len);
2294
+ #undef entry_size
2295
+ }
2296
+ }
2297
+
2285
2298
  static size_t read_entry(
2286
2299
  git_index_entry **out,
2287
2300
  git_index *index,
2288
2301
  const void *buffer,
2289
2302
  size_t buffer_size,
2290
- const char **last)
2303
+ const char *last)
2291
2304
  {
2292
2305
  size_t path_length, entry_size;
2293
2306
  const char *path_ptr;
@@ -2344,35 +2357,34 @@ static size_t read_entry(
2344
2357
  path_length = path_end - path_ptr;
2345
2358
  }
2346
2359
 
2347
- if (entry.flags & GIT_IDXENTRY_EXTENDED)
2348
- entry_size = long_entry_size(path_length);
2349
- else
2350
- entry_size = short_entry_size(path_length);
2351
-
2352
- if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
2353
- return 0;
2354
-
2360
+ entry_size = index_entry_size(path_length, 0, entry.flags);
2355
2361
  entry.path = (char *)path_ptr;
2356
2362
  } else {
2357
2363
  size_t varint_len;
2358
- size_t shared = git_decode_varint((const unsigned char *)path_ptr,
2359
- &varint_len);
2360
- size_t len = strlen(path_ptr + varint_len);
2361
- size_t last_len = strlen(*last);
2362
- size_t tmp_path_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;
2363
2370
 
2364
2371
  if (varint_len == 0)
2365
2372
  return index_error_invalid("incorrect prefix length");
2366
2373
 
2367
- GITERR_CHECK_ALLOC_ADD(&tmp_path_len, shared, len + 1);
2368
- tmp_path = git__malloc(tmp_path_len);
2374
+ GITERR_CHECK_ALLOC_ADD(&path_len, prefix_len, suffix_len);
2375
+ GITERR_CHECK_ALLOC_ADD(&path_len, path_len, 1);
2376
+ tmp_path = git__malloc(path_len);
2369
2377
  GITERR_CHECK_ALLOC(tmp_path);
2370
- memcpy(tmp_path, last, last_len);
2371
- memcpy(tmp_path + last_len, path_ptr + varint_len, len);
2372
- entry_size = long_entry_size(shared + len);
2378
+
2379
+ memcpy(tmp_path, last, prefix_len);
2380
+ memcpy(tmp_path + prefix_len, path_ptr + varint_len, suffix_len + 1);
2381
+ entry_size = index_entry_size(suffix_len, varint_len, entry.flags);
2373
2382
  entry.path = tmp_path;
2374
2383
  }
2375
2384
 
2385
+ if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
2386
+ return 0;
2387
+
2376
2388
  if (index_entry_dup(out, index, &entry) < 0) {
2377
2389
  git__free(tmp_path);
2378
2390
  return 0;
@@ -2445,7 +2457,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2445
2457
  unsigned int i;
2446
2458
  struct index_header header = { 0 };
2447
2459
  git_oid checksum_calculated, checksum_expected;
2448
- const char **last = NULL;
2460
+ const char *last = NULL;
2449
2461
  const char *empty = "";
2450
2462
 
2451
2463
  #define seek_forward(_increase) { \
@@ -2469,7 +2481,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2469
2481
 
2470
2482
  index->version = header.version;
2471
2483
  if (index->version >= INDEX_VERSION_NUMBER_COMP)
2472
- last = &empty;
2484
+ last = empty;
2473
2485
 
2474
2486
  seek_forward(INDEX_HEADER_SIZE);
2475
2487
 
@@ -2504,6 +2516,9 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2504
2516
  }
2505
2517
  error = 0;
2506
2518
 
2519
+ if (index->version >= INDEX_VERSION_NUMBER_COMP)
2520
+ last = entry->path;
2521
+
2507
2522
  seek_forward(entry_size);
2508
2523
  }
2509
2524
 
@@ -2574,11 +2589,12 @@ static bool is_index_extended(git_index *index)
2574
2589
  return (extended > 0);
2575
2590
  }
2576
2591
 
2577
- static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char **last)
2592
+ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char *last)
2578
2593
  {
2579
2594
  void *mem = NULL;
2580
2595
  struct entry_short *ondisk;
2581
2596
  size_t path_len, disk_size;
2597
+ int varint_len = 0;
2582
2598
  char *path;
2583
2599
  const char *path_start = entry->path;
2584
2600
  size_t same_len = 0;
@@ -2586,7 +2602,7 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2586
2602
  path_len = ((struct entry_internal *)entry)->pathlen;
2587
2603
 
2588
2604
  if (last) {
2589
- const char *last_c = *last;
2605
+ const char *last_c = last;
2590
2606
 
2591
2607
  while (*path_start == *last_c) {
2592
2608
  if (!*path_start || !*last_c)
@@ -2596,13 +2612,10 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2596
2612
  ++same_len;
2597
2613
  }
2598
2614
  path_len -= same_len;
2599
- *last = entry->path;
2615
+ varint_len = git_encode_varint(NULL, 0, same_len);
2600
2616
  }
2601
2617
 
2602
- if (entry->flags & GIT_IDXENTRY_EXTENDED)
2603
- disk_size = long_entry_size(path_len);
2604
- else
2605
- disk_size = short_entry_size(path_len);
2618
+ disk_size = index_entry_size(path_len, varint_len, entry->flags);
2606
2619
 
2607
2620
  if (git_filebuf_reserve(file, &mem, disk_size) < 0)
2608
2621
  return -1;
@@ -2642,16 +2655,34 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2642
2655
  ondisk_ext->flags_extended = htons(entry->flags_extended &
2643
2656
  GIT_IDXENTRY_EXTENDED_FLAGS);
2644
2657
  path = ondisk_ext->path;
2645
- }
2646
- else
2658
+ disk_size -= offsetof(struct entry_long, path);
2659
+ } else {
2647
2660
  path = ondisk->path;
2661
+ disk_size -= offsetof(struct entry_short, path);
2662
+ }
2648
2663
 
2649
2664
  if (last) {
2650
- path += git_encode_varint((unsigned char *) path,
2651
- disk_size,
2652
- path_len - same_len);
2665
+ varint_len = git_encode_varint((unsigned char *) path,
2666
+ disk_size, same_len);
2667
+ assert(varint_len > 0);
2668
+ path += varint_len;
2669
+ disk_size -= varint_len;
2670
+
2671
+ /*
2672
+ * If using path compression, we are not allowed
2673
+ * to have additional trailing NULs.
2674
+ */
2675
+ assert(disk_size == path_len + 1);
2676
+ } else {
2677
+ /*
2678
+ * If no path compression is used, we do have
2679
+ * NULs as padding. As such, simply assert that
2680
+ * we have enough space left to write the path.
2681
+ */
2682
+ assert(disk_size > path_len);
2653
2683
  }
2654
- memcpy(path, path_start, path_len);
2684
+
2685
+ memcpy(path, path_start, path_len + 1);
2655
2686
 
2656
2687
  return 0;
2657
2688
  }
@@ -2662,8 +2693,7 @@ static int write_entries(git_index *index, git_filebuf *file)
2662
2693
  size_t i;
2663
2694
  git_vector case_sorted, *entries;
2664
2695
  git_index_entry *entry;
2665
- const char **last = NULL;
2666
- const char *empty = "";
2696
+ const char *last = NULL;
2667
2697
 
2668
2698
  /* If index->entries is sorted case-insensitively, then we need
2669
2699
  * to re-sort it case-sensitively before writing */
@@ -2676,11 +2706,14 @@ static int write_entries(git_index *index, git_filebuf *file)
2676
2706
  }
2677
2707
 
2678
2708
  if (index->version >= INDEX_VERSION_NUMBER_COMP)
2679
- last = &empty;
2709
+ last = "";
2680
2710
 
2681
- git_vector_foreach(entries, i, entry)
2711
+ git_vector_foreach(entries, i, entry) {
2682
2712
  if ((error = write_disk_entry(file, entry, last)) < 0)
2683
2713
  break;
2714
+ if (index->version >= INDEX_VERSION_NUMBER_COMP)
2715
+ last = entry->path;
2716
+ }
2684
2717
 
2685
2718
  if (index->ignore_case)
2686
2719
  git_vector_free(&case_sorted);