9
9
#include "commit.h"
10
10
#include "blob.h"
11
11
#include "xdiff/xinclude.h"
12
+ #include "diff_xdiff.h"
12
13
13
14
/*
14
15
* Origin is refcounted and usually we keep the blob contents to be
@@ -351,6 +352,13 @@ static int diff_hunks(mmfile_t file_a, mmfile_t file_b, void *cb_data)
351
352
ecb .priv = cb_data ;
352
353
353
354
trim_common_tail (& file_a , & file_b , 0 );
355
+
356
+ if (file_a .size > GIT_XDIFF_MAX_SIZE ||
357
+ file_b .size > GIT_XDIFF_MAX_SIZE ) {
358
+ giterr_set (GITERR_INVALID , "file too large to blame" );
359
+ return -1 ;
360
+ }
361
+
354
362
return xdl_diff (& file_a , & file_b , & xpp , & xecfg , & ecb );
355
363
}
356
364
@@ -379,7 +387,9 @@ static int pass_blame_to_parent(
379
387
fill_origin_blob (parent , & file_p );
380
388
fill_origin_blob (target , & file_o );
381
389
382
- diff_hunks (file_p , file_o , & d );
390
+ if (diff_hunks (file_p , file_o , & d ) < 0 )
391
+ return -1 ;
392
+
383
393
/* The reset (i.e. anything after tlno) are the same as the parent */
384
394
blame_chunk (blame , d .tlno , d .plno , last_in_target , target , parent );
385
395
@@ -477,12 +487,13 @@ static void pass_whole_blame(git_blame *blame,
477
487
}
478
488
}
479
489
480
- static void pass_blame (git_blame * blame , git_blame__origin * origin , uint32_t opt )
490
+ static int pass_blame (git_blame * blame , git_blame__origin * origin , uint32_t opt )
481
491
{
482
492
git_commit * commit = origin -> commit ;
483
493
int i , num_parents ;
484
494
git_blame__origin * sg_buf [16 ];
485
495
git_blame__origin * porigin , * * sg_origin = sg_buf ;
496
+ int ret , error = 0 ;
486
497
487
498
num_parents = git_commit_parentcount (commit );
488
499
if (!git_oid_cmp (git_commit_id (commit ), & blame -> options .oldest_commit ))
@@ -540,8 +551,13 @@ static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt
540
551
origin_incref (porigin );
541
552
origin -> previous = porigin ;
542
553
}
543
- if (pass_blame_to_parent (blame , origin , porigin ))
554
+
555
+ if ((ret = pass_blame_to_parent (blame , origin , porigin )) != 0 ) {
556
+ if (ret < 0 )
557
+ error = -1 ;
558
+
544
559
goto finish ;
560
+ }
545
561
}
546
562
547
563
/* TODO: optionally find moves in parents' files */
@@ -554,7 +570,7 @@ static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt
554
570
origin_decref (sg_origin [i ]);
555
571
if (sg_origin != sg_buf )
556
572
git__free (sg_origin );
557
- return ;
573
+ return error ;
558
574
}
559
575
560
576
/*
@@ -583,7 +599,7 @@ static void coalesce(git_blame *blame)
583
599
}
584
600
}
585
601
586
- void git_blame__like_git (git_blame * blame , uint32_t opt )
602
+ int git_blame__like_git (git_blame * blame , uint32_t opt )
587
603
{
588
604
while (true) {
589
605
git_blame__entry * ent ;
@@ -594,11 +610,13 @@ void git_blame__like_git(git_blame *blame, uint32_t opt)
594
610
if (!ent -> guilty )
595
611
suspect = ent -> suspect ;
596
612
if (!suspect )
597
- return ; /* all done */
613
+ return 0 ; /* all done */
598
614
599
615
/* We'll use this suspect later in the loop, so hold on to it for now. */
600
616
origin_incref (suspect );
601
- pass_blame (blame , suspect , opt );
617
+
618
+ if (pass_blame (blame , suspect , opt ) < 0 )
619
+ return -1 ;
602
620
603
621
/* Take responsibility for the remaining entries */
604
622
for (ent = blame -> ent ; ent ; ent = ent -> next ) {
@@ -613,6 +631,8 @@ void git_blame__like_git(git_blame *blame, uint32_t opt)
613
631
}
614
632
615
633
coalesce (blame );
634
+
635
+ return 0 ;
616
636
}
617
637
618
638
void git_blame__free_entry (git_blame__entry * ent )
0 commit comments