@@ -25,6 +25,12 @@ void test_diff_patch__cleanup(void)
2525
2626#define EXPECTED_HUNK "@@ -1,2 +0,0 @@\n"
2727
28+ #define UTF8_HUNK_HEADER "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\n"
29+
30+ #define UTF8_TRUNCATED_A_HUNK_HEADER "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\n"
31+
32+ #define UTF8_TRUNCATED_L_HUNK_HEADER "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE6\x97\xA5\n"
33+
2834static int check_removal_cb (
2935 const git_diff_delta * delta ,
3036 const git_diff_hunk * hunk ,
@@ -610,3 +616,89 @@ void test_diff_patch__line_counts_with_eofnl(void)
610616
611617 git_buf_free (& content );
612618}
619+
620+ void test_diff_patch__can_strip_bad_utf8 (void )
621+ {
622+ const char * a = "A " UTF8_HUNK_HEADER
623+ " B\n"
624+ " C\n"
625+ " D\n"
626+ " E\n"
627+ " F\n"
628+ " G\n"
629+ " H\n"
630+ " I\n"
631+ " J\n"
632+ " K\n"
633+ "L " UTF8_HUNK_HEADER
634+ " M\n"
635+ " N\n"
636+ " O\n"
637+ " P\n"
638+ " Q\n"
639+ " R\n"
640+ " S\n"
641+ " T\n"
642+ " U\n"
643+ " V\n" ;
644+
645+ const char * b = "A " UTF8_HUNK_HEADER
646+ " B\n"
647+ " C\n"
648+ " D\n"
649+ " E modified\n"
650+ " F\n"
651+ " G\n"
652+ " H\n"
653+ " I\n"
654+ " J\n"
655+ " K\n"
656+ "L " UTF8_HUNK_HEADER
657+ " M\n"
658+ " N\n"
659+ " O\n"
660+ " P modified\n"
661+ " Q\n"
662+ " R\n"
663+ " S\n"
664+ " T\n"
665+ " U\n"
666+ " V\n" ;
667+
668+ const char * expected = "diff --git a/file b/file\n"
669+ "index d0647c4..7827ce5 100644\n"
670+ "--- a/file\n"
671+ "+++ b/file\n"
672+ "@@ -2,7 +2,7 @@ A " UTF8_TRUNCATED_A_HUNK_HEADER
673+ " B\n"
674+ " C\n"
675+ " D\n"
676+ "- E\n"
677+ "+ E modified\n"
678+ " F\n"
679+ " G\n"
680+ " H\n"
681+ "@@ -13,7 +13,7 @@ L " UTF8_TRUNCATED_L_HUNK_HEADER
682+ " M\n"
683+ " N\n"
684+ " O\n"
685+ "- P\n"
686+ "+ P modified\n"
687+ " Q\n"
688+ " R\n"
689+ " S\n" ;
690+
691+ git_diff_options opts ;
692+ git_patch * patch ;
693+ git_buf buf = GIT_BUF_INIT ;
694+
695+ cl_git_pass (git_diff_init_options (& opts , GIT_DIFF_OPTIONS_VERSION ));
696+
697+ cl_git_pass (git_patch_from_buffers (& patch , a , strlen (a ), NULL , b , strlen (b ), NULL , & opts ));
698+ cl_git_pass (git_patch_to_buf (& buf , patch ));
699+
700+ cl_assert_equal_s (expected , buf .ptr );
701+
702+ git_patch_free (patch );
703+ git_buf_free (& buf );
704+ }
0 commit comments