@@ -87,25 +87,40 @@ int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
87
87
/**
88
88
* Allocate either from the pool or from the system allocator
89
89
*/
90
- static git_tree_entry * alloc_entry_base (git_pool * pool , const char * filename , size_t filename_len )
90
+ static git_tree_entry * alloc_entry_base (git_pool * pool , const char * filename , size_t filename_len , const git_oid * id )
91
91
{
92
92
git_tree_entry * entry = NULL ;
93
93
size_t tree_len ;
94
94
95
95
TREE_ENTRY_CHECK_NAMELEN (filename_len );
96
+ tree_len = sizeof (git_tree_entry );
96
97
97
- if (GIT_ADD_SIZET_OVERFLOW (& tree_len , sizeof (git_tree_entry ), filename_len ) ||
98
- GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , 1 ))
98
+ if (!pool && (GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , filename_len ) ||
99
+ GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , 1 ) ||
100
+ GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , GIT_OID_RAWSZ )))
99
101
return NULL ;
100
102
101
- entry = pool ? git_pool_malloc (pool , tree_len ) :
102
- git__malloc ( tree_len );
103
+ entry = pool ? git_pool_mallocz (pool , tree_len ) :
104
+ git__calloc ( 1 , tree_len );
103
105
if (!entry )
104
106
return NULL ;
105
107
106
- memset (entry , 0x0 , sizeof (git_tree_entry ));
107
- memcpy (entry -> filename , filename , filename_len );
108
- entry -> filename [filename_len ] = 0 ;
108
+ if (pool ) {
109
+ entry -> filename = filename ;
110
+ entry -> oid = (git_oid * ) id ;
111
+ } else {
112
+ char * filename_ptr ;
113
+ void * id_ptr ;
114
+
115
+ filename_ptr = ((char * ) entry ) + sizeof (git_tree_entry );
116
+ memcpy (filename_ptr , filename , filename_len );
117
+ entry -> filename = filename_ptr ;
118
+
119
+ id_ptr = filename_ptr + filename_len + 1 ;
120
+ git_oid_cpy (id_ptr , id );
121
+ entry -> oid = id_ptr ;
122
+ }
123
+
109
124
entry -> filename_len = (uint16_t )filename_len ;
110
125
111
126
return entry ;
@@ -116,11 +131,11 @@ static git_tree_entry *alloc_entry_base(git_pool *pool, const char *filename, si
116
131
* it. This is useful when reading trees, so we don't allocate a ton
117
132
* of small strings but can use the pool.
118
133
*/
119
- static git_tree_entry * alloc_entry_pooled (git_pool * pool , const char * filename , size_t filename_len )
134
+ static git_tree_entry * alloc_entry_pooled (git_pool * pool , const char * filename , size_t filename_len , const git_oid * id )
120
135
{
121
136
git_tree_entry * entry = NULL ;
122
137
123
- if (!(entry = alloc_entry_base (pool , filename , filename_len )))
138
+ if (!(entry = alloc_entry_base (pool , filename , filename_len , id )))
124
139
return NULL ;
125
140
126
141
entry -> pooled = true;
@@ -130,7 +145,8 @@ static git_tree_entry *alloc_entry_pooled(git_pool *pool, const char *filename,
130
145
131
146
static git_tree_entry * alloc_entry (const char * filename )
132
147
{
133
- return alloc_entry_base (NULL , filename , strlen (filename ));
148
+ git_oid dummy_id = { 0 };
149
+ return alloc_entry_base (NULL , filename , strlen (filename ), & dummy_id );
134
150
}
135
151
136
152
struct tree_key_search {
@@ -242,22 +258,12 @@ void git_tree_entry_free(git_tree_entry *entry)
242
258
243
259
int git_tree_entry_dup (git_tree_entry * * dest , const git_tree_entry * source )
244
260
{
245
- size_t total_size ;
246
- git_tree_entry * copy ;
247
-
248
261
assert (source );
249
262
250
- GITERR_CHECK_ALLOC_ADD (& total_size , sizeof (git_tree_entry ), source -> filename_len );
251
- GITERR_CHECK_ALLOC_ADD (& total_size , total_size , 1 );
252
-
253
- copy = git__malloc (total_size );
254
- GITERR_CHECK_ALLOC (copy );
255
-
256
- memcpy (copy , source , total_size );
257
-
258
- copy -> pooled = 0 ;
263
+ * dest = alloc_entry_base (NULL , source -> filename , source -> filename_len , source -> oid );
264
+ if (* dest == NULL )
265
+ return -1 ;
259
266
260
- * dest = copy ;
261
267
return 0 ;
262
268
}
263
269
@@ -270,6 +276,7 @@ void git_tree__free(void *_tree)
270
276
git_vector_foreach (& tree -> entries , i , e )
271
277
git_tree_entry_free (e );
272
278
279
+ git_odb_object_free (tree -> odb_obj );
273
280
git_vector_free (& tree -> entries );
274
281
git_pool_clear (& tree -> pool );
275
282
git__free (tree );
@@ -294,7 +301,7 @@ const char *git_tree_entry_name(const git_tree_entry *entry)
294
301
const git_oid * git_tree_entry_id (const git_tree_entry * entry )
295
302
{
296
303
assert (entry );
297
- return & entry -> oid ;
304
+ return entry -> oid ;
298
305
}
299
306
300
307
git_otype git_tree_entry_type (const git_tree_entry * entry )
@@ -315,7 +322,7 @@ int git_tree_entry_to_object(
315
322
const git_tree_entry * entry )
316
323
{
317
324
assert (entry && object_out );
318
- return git_object_lookup (object_out , repo , & entry -> oid , GIT_OBJ_ANY );
325
+ return git_object_lookup (object_out , repo , entry -> oid , GIT_OBJ_ANY );
319
326
}
320
327
321
328
static const git_tree_entry * entry_fromname (
@@ -356,7 +363,7 @@ const git_tree_entry *git_tree_entry_byid(
356
363
assert (tree );
357
364
358
365
git_vector_foreach (& tree -> entries , i , e ) {
359
- if (memcmp (& e -> oid . id , & id -> id , sizeof (id -> id )) == 0 )
366
+ if (memcmp (& e -> oid -> id , & id -> id , sizeof (id -> id )) == 0 )
360
367
return e ;
361
368
}
362
369
@@ -444,8 +451,14 @@ static int parse_mode(unsigned int *modep, const char *buffer, const char **buff
444
451
int git_tree__parse (void * _tree , git_odb_object * odb_obj )
445
452
{
446
453
git_tree * tree = _tree ;
447
- const char * buffer = git_odb_object_data (odb_obj );
448
- const char * buffer_end = buffer + git_odb_object_size (odb_obj );
454
+ const char * buffer ;
455
+ const char * buffer_end ;
456
+
457
+ if (git_odb_object_dup (& tree -> odb_obj , odb_obj ) < 0 )
458
+ return -1 ;
459
+
460
+ buffer = git_odb_object_data (tree -> odb_obj );
461
+ buffer_end = buffer + git_odb_object_size (tree -> odb_obj );
449
462
450
463
git_pool_init (& tree -> pool , 1 );
451
464
if (git_vector_init (& tree -> entries , DEFAULT_TREE_SIZE , entry_sort_cmp ) < 0 )
@@ -466,7 +479,9 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
466
479
filename_len = nul - buffer ;
467
480
/** Allocate the entry and store it in the entries vector */
468
481
{
469
- entry = alloc_entry_pooled (& tree -> pool , buffer , filename_len );
482
+ /* Jump to the ID just after the path */
483
+ const void * oid_ptr = buffer + filename_len + 1 ;
484
+ entry = alloc_entry_pooled (& tree -> pool , buffer , filename_len , oid_ptr );
470
485
GITERR_CHECK_ALLOC (entry );
471
486
472
487
if (git_vector_insert (& tree -> entries , entry ) < 0 )
@@ -475,10 +490,7 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
475
490
entry -> attr = attr ;
476
491
}
477
492
478
- /* Advance to the ID just after the path */
479
493
buffer += filename_len + 1 ;
480
-
481
- git_oid_fromraw (& entry -> oid , (const unsigned char * )buffer );
482
494
buffer += GIT_OID_RAWSZ ;
483
495
}
484
496
@@ -520,7 +532,7 @@ static int append_entry(
520
532
entry = alloc_entry (filename );
521
533
GITERR_CHECK_ALLOC (entry );
522
534
523
- git_oid_cpy (& entry -> oid , id );
535
+ git_oid_cpy (entry -> oid , id );
524
536
entry -> attr = (uint16_t )filemode ;
525
537
526
538
git_strmap_insert (bld -> map , entry -> filename , entry , error );
@@ -712,7 +724,7 @@ int git_treebuilder_new(
712
724
git_vector_foreach (& source -> entries , i , entry_src ) {
713
725
if (append_entry (
714
726
bld , entry_src -> filename ,
715
- & entry_src -> oid ,
727
+ entry_src -> oid ,
716
728
entry_src -> attr ) < 0 )
717
729
goto on_error ;
718
730
}
@@ -777,7 +789,7 @@ int git_treebuilder_insert(
777
789
}
778
790
}
779
791
780
- git_oid_cpy (& entry -> oid , id );
792
+ git_oid_cpy (entry -> oid , id );
781
793
entry -> attr = filemode ;
782
794
783
795
if (entry_out )
@@ -848,7 +860,7 @@ int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
848
860
849
861
git_buf_printf (& tree , "%o " , entry -> attr );
850
862
git_buf_put (& tree , entry -> filename , entry -> filename_len + 1 );
851
- git_buf_put (& tree , (char * )entry -> oid . id , GIT_OID_RAWSZ );
863
+ git_buf_put (& tree , (char * )entry -> oid -> id , GIT_OID_RAWSZ );
852
864
853
865
if (git_buf_oom (& tree ))
854
866
error = -1 ;
@@ -960,7 +972,7 @@ int git_tree_entry_bypath(
960
972
return git_tree_entry_dup (entry_out , entry );
961
973
}
962
974
963
- if (git_tree_lookup (& subtree , root -> object .repo , & entry -> oid ) < 0 )
975
+ if (git_tree_lookup (& subtree , root -> object .repo , entry -> oid ) < 0 )
964
976
return -1 ;
965
977
966
978
error = git_tree_entry_bypath (
@@ -1001,7 +1013,7 @@ static int tree_walk(
1001
1013
git_tree * subtree ;
1002
1014
size_t path_len = git_buf_len (path );
1003
1015
1004
- error = git_tree_lookup (& subtree , tree -> object .repo , & entry -> oid );
1016
+ error = git_tree_lookup (& subtree , tree -> object .repo , entry -> oid );
1005
1017
if (error < 0 )
1006
1018
break ;
1007
1019
0 commit comments