@@ -248,8 +248,10 @@ static void line_log_data_init(struct line_log_data *r)
248
248
static void line_log_data_clear (struct line_log_data * r )
249
249
{
250
250
range_set_release (& r -> ranges );
251
+ free (r -> path );
251
252
if (r -> pair )
252
253
diff_free_filepair (r -> pair );
254
+ diff_ranges_release (& r -> diff );
253
255
}
254
256
255
257
static void free_line_log_data (struct line_log_data * r )
@@ -571,7 +573,8 @@ parse_lines(struct repository *r, struct commit *commit,
571
573
struct line_log_data * p ;
572
574
573
575
for_each_string_list_item (item , args ) {
574
- const char * name_part , * range_part ;
576
+ const char * name_part ;
577
+ char * range_part ;
575
578
char * full_name ;
576
579
struct diff_filespec * spec ;
577
580
long begin = 0 , end = 0 ;
@@ -615,6 +618,7 @@ parse_lines(struct repository *r, struct commit *commit,
615
618
616
619
free_filespec (spec );
617
620
FREE_AND_NULL (ends );
621
+ free (range_part );
618
622
}
619
623
620
624
for (p = ranges ; p ; p = p -> next )
@@ -760,15 +764,13 @@ static void parse_pathspec_from_ranges(struct pathspec *pathspec,
760
764
{
761
765
struct line_log_data * r ;
762
766
struct strvec array = STRVEC_INIT ;
763
- const char * * paths ;
764
767
765
768
for (r = range ; r ; r = r -> next )
766
769
strvec_push (& array , r -> path );
767
- paths = strvec_detach (& array );
768
770
769
- parse_pathspec (pathspec , 0 , PATHSPEC_PREFER_FULL , "" , paths );
770
- /* strings are now owned by pathspec */
771
- free ( paths );
771
+ parse_pathspec (pathspec , 0 , PATHSPEC_PREFER_FULL , "" , array . v );
772
+
773
+ strvec_clear ( & array );
772
774
}
773
775
774
776
void line_log_init (struct rev_info * rev , const char * prefix , struct string_list * args )
@@ -781,6 +783,8 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
781
783
add_line_range (rev , commit , range );
782
784
783
785
parse_pathspec_from_ranges (& rev -> diffopt .pathspec , range );
786
+
787
+ free_line_log_data (range );
784
788
}
785
789
786
790
static void move_diff_queue (struct diff_queue_struct * dst ,
@@ -1131,10 +1135,18 @@ static int process_all_files(struct line_log_data **range_out,
1131
1135
while (rg && strcmp (rg -> path , pair -> two -> path ))
1132
1136
rg = rg -> next ;
1133
1137
assert (rg );
1138
+ if (rg -> pair )
1139
+ diff_free_filepair (rg -> pair );
1134
1140
rg -> pair = diff_filepair_dup (queue -> queue [i ]);
1141
+ diff_ranges_release (& rg -> diff );
1135
1142
memcpy (& rg -> diff , pairdiff , sizeof (struct diff_ranges ));
1143
+ FREE_AND_NULL (pairdiff );
1144
+ }
1145
+
1146
+ if (pairdiff ) {
1147
+ diff_ranges_release (pairdiff );
1148
+ free (pairdiff );
1136
1149
}
1137
- free (pairdiff );
1138
1150
}
1139
1151
1140
1152
return changed ;
@@ -1212,12 +1224,13 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1212
1224
struct commit_list * p ;
1213
1225
int i ;
1214
1226
int nparents = commit_list_count (commit -> parents );
1227
+ int ret ;
1215
1228
1216
1229
if (nparents > 1 && rev -> first_parent_only )
1217
1230
nparents = 1 ;
1218
1231
1219
1232
ALLOC_ARRAY (diffqueues , nparents );
1220
- ALLOC_ARRAY (cand , nparents );
1233
+ CALLOC_ARRAY (cand , nparents );
1221
1234
ALLOC_ARRAY (parents , nparents );
1222
1235
1223
1236
p = commit -> parents ;
@@ -1229,40 +1242,43 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
1229
1242
1230
1243
for (i = 0 ; i < nparents ; i ++ ) {
1231
1244
int changed ;
1232
- cand [i ] = NULL ;
1233
1245
changed = process_all_files (& cand [i ], rev , & diffqueues [i ], range );
1234
1246
if (!changed ) {
1235
1247
/*
1236
1248
* This parent can take all the blame, so we
1237
1249
* don't follow any other path in history
1238
1250
*/
1239
1251
add_line_range (rev , parents [i ], cand [i ]);
1240
- clear_commit_line_range (rev , commit );
1241
1252
commit_list_append (parents [i ], & commit -> parents );
1242
- free (parents );
1243
- free (cand );
1244
- free_diffqueues (nparents , diffqueues );
1245
- /* NEEDSWORK leaking like a sieve */
1246
- return 0 ;
1253
+
1254
+ ret = 0 ;
1255
+ goto out ;
1247
1256
}
1248
1257
}
1249
1258
1250
1259
/*
1251
1260
* No single parent took the blame. We add the candidates
1252
1261
* from the above loop to the parents.
1253
1262
*/
1254
- for (i = 0 ; i < nparents ; i ++ ) {
1263
+ for (i = 0 ; i < nparents ; i ++ )
1255
1264
add_line_range (rev , parents [i ], cand [i ]);
1256
- }
1257
1265
1266
+ ret = 1 ;
1267
+
1268
+ out :
1258
1269
clear_commit_line_range (rev , commit );
1259
1270
free (parents );
1271
+ for (i = 0 ; i < nparents ; i ++ ) {
1272
+ if (!cand [i ])
1273
+ continue ;
1274
+ line_log_data_clear (cand [i ]);
1275
+ free (cand [i ]);
1276
+ }
1260
1277
free (cand );
1261
1278
free_diffqueues (nparents , diffqueues );
1262
- return 1 ;
1279
+ return ret ;
1263
1280
1264
1281
/* NEEDSWORK evil merge detection stuff */
1265
- /* NEEDSWORK leaking like a sieve */
1266
1282
}
1267
1283
1268
1284
int line_log_process_ranges_arbitrary_commit (struct rev_info * rev , struct commit * commit )
0 commit comments