@@ -207,6 +207,9 @@ static void free_patch(struct patch *patch)
207207 free (fragment );
208208 fragment = fragment_next ;
209209 }
210+ free (patch -> def_name );
211+ free (patch -> old_name );
212+ free (patch -> new_name );
210213 free (patch );
211214}
212215
@@ -439,7 +442,7 @@ static char *squash_slash(char *name)
439442 return name ;
440443}
441444
442- static char * find_name_gnu (const char * line , char * def , int p_value )
445+ static char * find_name_gnu (const char * line , const char * def , int p_value )
443446{
444447 struct strbuf name = STRBUF_INIT ;
445448 char * cp ;
@@ -462,11 +465,7 @@ static char *find_name_gnu(const char *line, char *def, int p_value)
462465 cp ++ ;
463466 }
464467
465- /* name can later be freed, so we need
466- * to memmove, not just return cp
467- */
468468 strbuf_remove (& name , 0 , cp - name .buf );
469- free (def );
470469 if (root )
471470 strbuf_insert (& name , 0 , root , root_len );
472471 return squash_slash (strbuf_detach (& name , NULL ));
@@ -631,8 +630,13 @@ static size_t diff_timestamp_len(const char *line, size_t len)
631630 return line + len - end ;
632631}
633632
634- static char * find_name_common (const char * line , char * def , int p_value ,
635- const char * end , int terminate )
633+ static char * null_strdup (const char * s )
634+ {
635+ return s ? xstrdup (s ) : NULL ;
636+ }
637+
638+ static char * find_name_common (const char * line , const char * def ,
639+ int p_value , const char * end , int terminate )
636640{
637641 int len ;
638642 const char * start = NULL ;
@@ -653,10 +657,10 @@ static char *find_name_common(const char *line, char *def, int p_value,
653657 start = line ;
654658 }
655659 if (!start )
656- return squash_slash (def );
660+ return squash_slash (null_strdup ( def ) );
657661 len = line - start ;
658662 if (!len )
659- return squash_slash (def );
663+ return squash_slash (null_strdup ( def ) );
660664
661665 /*
662666 * Generally we prefer the shorter name, especially
@@ -667,8 +671,7 @@ static char *find_name_common(const char *line, char *def, int p_value,
667671 if (def ) {
668672 int deflen = strlen (def );
669673 if (deflen < len && !strncmp (start , def , deflen ))
670- return squash_slash (def );
671- free (def );
674+ return squash_slash (xstrdup (def ));
672675 }
673676
674677 if (root ) {
@@ -865,8 +868,10 @@ static void parse_traditional_patch(const char *first, const char *second, struc
865868 name = find_name_traditional (first , NULL , p_value );
866869 patch -> old_name = name ;
867870 } else {
868- name = find_name_traditional (first , NULL , p_value );
869- name = find_name_traditional (second , name , p_value );
871+ char * first_name ;
872+ first_name = find_name_traditional (first , NULL , p_value );
873+ name = find_name_traditional (second , first_name , p_value );
874+ free (first_name );
870875 if (has_epoch_timestamp (first )) {
871876 patch -> is_new = 1 ;
872877 patch -> is_delete = 0 ;
@@ -876,7 +881,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc
876881 patch -> is_delete = 1 ;
877882 patch -> old_name = name ;
878883 } else {
879- patch -> old_name = patch -> new_name = name ;
884+ patch -> old_name = name ;
885+ patch -> new_name = xstrdup (name );
880886 }
881887 }
882888 if (!name )
@@ -926,13 +932,19 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
926932
927933static int gitdiff_oldname (const char * line , struct patch * patch )
928934{
935+ char * orig = patch -> old_name ;
929936 patch -> old_name = gitdiff_verify_name (line , patch -> is_new , patch -> old_name , "old" );
937+ if (orig != patch -> old_name )
938+ free (orig );
930939 return 0 ;
931940}
932941
933942static int gitdiff_newname (const char * line , struct patch * patch )
934943{
944+ char * orig = patch -> new_name ;
935945 patch -> new_name = gitdiff_verify_name (line , patch -> is_delete , patch -> new_name , "new" );
946+ if (orig != patch -> new_name )
947+ free (orig );
936948 return 0 ;
937949}
938950
@@ -951,41 +963,47 @@ static int gitdiff_newmode(const char *line, struct patch *patch)
951963static int gitdiff_delete (const char * line , struct patch * patch )
952964{
953965 patch -> is_delete = 1 ;
954- patch -> old_name = patch -> def_name ;
966+ free (patch -> old_name );
967+ patch -> old_name = null_strdup (patch -> def_name );
955968 return gitdiff_oldmode (line , patch );
956969}
957970
958971static int gitdiff_newfile (const char * line , struct patch * patch )
959972{
960973 patch -> is_new = 1 ;
961- patch -> new_name = patch -> def_name ;
974+ free (patch -> new_name );
975+ patch -> new_name = null_strdup (patch -> def_name );
962976 return gitdiff_newmode (line , patch );
963977}
964978
965979static int gitdiff_copysrc (const char * line , struct patch * patch )
966980{
967981 patch -> is_copy = 1 ;
982+ free (patch -> old_name );
968983 patch -> old_name = find_name (line , NULL , p_value ? p_value - 1 : 0 , 0 );
969984 return 0 ;
970985}
971986
972987static int gitdiff_copydst (const char * line , struct patch * patch )
973988{
974989 patch -> is_copy = 1 ;
990+ free (patch -> new_name );
975991 patch -> new_name = find_name (line , NULL , p_value ? p_value - 1 : 0 , 0 );
976992 return 0 ;
977993}
978994
979995static int gitdiff_renamesrc (const char * line , struct patch * patch )
980996{
981997 patch -> is_rename = 1 ;
998+ free (patch -> old_name );
982999 patch -> old_name = find_name (line , NULL , p_value ? p_value - 1 : 0 , 0 );
9831000 return 0 ;
9841001}
9851002
9861003static int gitdiff_renamedst (const char * line , struct patch * patch )
9871004{
9881005 patch -> is_rename = 1 ;
1006+ free (patch -> new_name );
9891007 patch -> new_name = find_name (line , NULL , p_value ? p_value - 1 : 0 , 0 );
9901008 return 0 ;
9911009}
@@ -1426,7 +1444,8 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
14261444 if (!patch -> def_name )
14271445 die ("git diff header lacks filename information when removing "
14281446 "%d leading pathname components (line %d)" , p_value , linenr );
1429- patch -> old_name = patch -> new_name = patch -> def_name ;
1447+ patch -> old_name = xstrdup (patch -> def_name );
1448+ patch -> new_name = xstrdup (patch -> def_name );
14301449 }
14311450 if (!patch -> is_delete && !patch -> new_name )
14321451 die ("git diff header lacks filename information "
@@ -3109,6 +3128,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
31093128 is_new :
31103129 patch -> is_new = 1 ;
31113130 patch -> is_delete = 0 ;
3131+ free (patch -> old_name );
31123132 patch -> old_name = NULL ;
31133133 return 0 ;
31143134}
@@ -3689,15 +3709,8 @@ static void prefix_patches(struct patch *p)
36893709 if (!prefix || p -> is_toplevel_relative )
36903710 return ;
36913711 for ( ; p ; p = p -> next ) {
3692- if (p -> new_name == p -> old_name ) {
3693- char * prefixed = p -> new_name ;
3694- prefix_one (& prefixed );
3695- p -> new_name = p -> old_name = prefixed ;
3696- }
3697- else {
3698- prefix_one (& p -> new_name );
3699- prefix_one (& p -> old_name );
3700- }
3712+ prefix_one (& p -> new_name );
3713+ prefix_one (& p -> old_name );
37013714 }
37023715}
37033716
0 commit comments