@@ -75,11 +75,11 @@ struct refname_atom {
7575 int lstrip , rstrip ;
7676};
7777
78- static struct ref_trailer_buf {
78+ struct ref_trailer_buf {
7979 struct string_list filter_list ;
8080 struct strbuf sepbuf ;
8181 struct strbuf kvsepbuf ;
82- } ref_trailer_buf = { STRING_LIST_INIT_NODUP , STRBUF_INIT , STRBUF_INIT } ;
82+ };
8383
8484static struct expand_data {
8585 struct object_id oid ;
@@ -201,6 +201,7 @@ static struct used_atom {
201201 enum { C_BARE , C_BODY , C_BODY_DEP , C_LENGTH , C_LINES ,
202202 C_SIG , C_SUB , C_SUB_SANITIZE , C_TRAILERS } option ;
203203 struct process_trailer_options trailer_opts ;
204+ struct ref_trailer_buf * trailer_buf ;
204205 unsigned int nlines ;
205206 } contents ;
206207 struct {
@@ -232,7 +233,7 @@ static struct used_atom {
232233 enum { S_BARE , S_GRADE , S_SIGNER , S_KEY ,
233234 S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
234235 } signature ;
235- const char * * describe_args ;
236+ struct strvec describe_args ;
236237 struct refname_atom refname ;
237238 char * head ;
238239 } u ;
@@ -566,21 +567,36 @@ static int trailers_atom_parser(struct ref_format *format UNUSED,
566567 atom -> u .contents .trailer_opts .no_divider = 1 ;
567568
568569 if (arg ) {
569- const char * argbuf = xstrfmt ("%s)" , arg );
570+ char * argbuf = xstrfmt ("%s)" , arg );
571+ const char * arg = argbuf ;
570572 char * invalid_arg = NULL ;
573+ struct ref_trailer_buf * tb ;
574+
575+ /*
576+ * Do not inline these directly into the used_atom struct!
577+ * When we parse them in format_set_trailers_options(),
578+ * we will make pointer references directly to them,
579+ * which will not survive a realloc() of the used_atom list.
580+ * They must be allocated in a separate, stable struct.
581+ */
582+ atom -> u .contents .trailer_buf = tb = xmalloc (sizeof (* tb ));
583+ string_list_init_dup (& tb -> filter_list );
584+ strbuf_init (& tb -> sepbuf , 0 );
585+ strbuf_init (& tb -> kvsepbuf , 0 );
571586
572587 if (format_set_trailers_options (& atom -> u .contents .trailer_opts ,
573- & ref_trailer_buf .filter_list ,
574- & ref_trailer_buf .sepbuf ,
575- & ref_trailer_buf .kvsepbuf ,
576- & argbuf , & invalid_arg )) {
588+ & tb -> filter_list ,
589+ & tb -> sepbuf , & tb -> kvsepbuf ,
590+ & arg , & invalid_arg )) {
577591 if (!invalid_arg )
578592 strbuf_addf (err , _ ("expected %%(trailers:key=<value>)" ));
579593 else
580594 strbuf_addf (err , _ ("unknown %%(trailers) argument: %s" ), invalid_arg );
581- free ((char * )invalid_arg );
595+ free (invalid_arg );
596+ free (argbuf );
582597 return -1 ;
583598 }
599+ free (argbuf );
584600 }
585601 atom -> u .contents .option = C_TRAILERS ;
586602 return 0 ;
@@ -677,7 +693,7 @@ static int describe_atom_parser(struct ref_format *format UNUSED,
677693 struct used_atom * atom ,
678694 const char * arg , struct strbuf * err )
679695{
680- struct strvec args = STRVEC_INIT ;
696+ strvec_init ( & atom -> u . describe_args ) ;
681697
682698 for (;;) {
683699 int found = 0 ;
@@ -686,13 +702,12 @@ static int describe_atom_parser(struct ref_format *format UNUSED,
686702 if (!arg || !* arg )
687703 break ;
688704
689- found = describe_atom_option_parser (& args , & arg , err );
705+ found = describe_atom_option_parser (& atom -> u . describe_args , & arg , err );
690706 if (found < 0 )
691707 return found ;
692708 if (!found )
693709 return err_bad_arg (err , "describe" , bad_arg );
694710 }
695- atom -> u .describe_args = strvec_detach (& args );
696711 return 0 ;
697712}
698713
@@ -986,6 +1001,7 @@ struct ref_formatting_stack {
9861001 struct ref_formatting_stack * prev ;
9871002 struct strbuf output ;
9881003 void (* at_end )(struct ref_formatting_stack * * stack );
1004+ void (* at_end_data_free )(void * data );
9891005 void * at_end_data ;
9901006};
9911007
@@ -1154,6 +1170,8 @@ static void pop_stack_element(struct ref_formatting_stack **stack)
11541170 if (prev )
11551171 strbuf_addbuf (& prev -> output , & current -> output );
11561172 strbuf_release (& current -> output );
1173+ if (current -> at_end_data_free )
1174+ current -> at_end_data_free (current -> at_end_data );
11571175 free (current );
11581176 * stack = prev ;
11591177}
@@ -1213,15 +1231,13 @@ static void if_then_else_handler(struct ref_formatting_stack **stack)
12131231 }
12141232
12151233 * stack = cur ;
1216- free (if_then_else );
12171234}
12181235
12191236static int if_atom_handler (struct atom_value * atomv , struct ref_formatting_state * state ,
12201237 struct strbuf * err UNUSED )
12211238{
12221239 struct ref_formatting_stack * new_stack ;
1223- struct if_then_else * if_then_else = xcalloc (1 ,
1224- sizeof (struct if_then_else ));
1240+ struct if_then_else * if_then_else = xcalloc (1 , sizeof (* if_then_else ));
12251241
12261242 if_then_else -> str = atomv -> atom -> u .if_then_else .str ;
12271243 if_then_else -> cmp_status = atomv -> atom -> u .if_then_else .cmp_status ;
@@ -1230,6 +1246,7 @@ static int if_atom_handler(struct atom_value *atomv, struct ref_formatting_state
12301246 new_stack = state -> stack ;
12311247 new_stack -> at_end = if_then_else_handler ;
12321248 new_stack -> at_end_data = if_then_else ;
1249+ new_stack -> at_end_data_free = free ;
12331250 return 0 ;
12341251}
12351252
@@ -1833,16 +1850,10 @@ static void find_subpos(const char *buf,
18331850 size_t * nonsiglen ,
18341851 const char * * sig , size_t * siglen )
18351852{
1836- struct strbuf payload = STRBUF_INIT ;
1837- struct strbuf signature = STRBUF_INIT ;
18381853 const char * eol ;
18391854 const char * end = buf + strlen (buf );
18401855 const char * sigstart ;
18411856
1842- /* parse signature first; we might not even have a subject line */
1843- parse_signature (buf , end - buf , & payload , & signature );
1844- strbuf_release (& payload );
1845-
18461857 /* skip past header until we hit empty line */
18471858 while (* buf && * buf != '\n' ) {
18481859 eol = strchrnul (buf , '\n' );
@@ -1853,8 +1864,10 @@ static void find_subpos(const char *buf,
18531864 /* skip any empty lines */
18541865 while (* buf == '\n' )
18551866 buf ++ ;
1856- * sig = strbuf_detach ( & signature , siglen );
1867+ /* parse signature first; we might not even have a subject line */
18571868 sigstart = buf + parse_signed_buffer (buf , strlen (buf ));
1869+ * sig = sigstart ;
1870+ * siglen = end - * sig ;
18581871
18591872 /* subject is first non-empty line */
18601873 * sub = buf ;
@@ -1929,7 +1942,7 @@ static void grab_describe_values(struct atom_value *val, int deref,
19291942
19301943 cmd .git_cmd = 1 ;
19311944 strvec_push (& cmd .args , "describe" );
1932- strvec_pushv (& cmd .args , atom -> u .describe_args );
1945+ strvec_pushv (& cmd .args , atom -> u .describe_args . v );
19331946 strvec_push (& cmd .args , oid_to_hex (& commit -> object .oid ));
19341947 if (pipe_command (& cmd , NULL , 0 , & out , 0 , & err , 0 ) < 0 ) {
19351948 error (_ ("failed to run 'describe'" ));
@@ -2012,16 +2025,23 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct exp
20122025 v -> s = strbuf_detach (& s , NULL );
20132026 } else if (atom -> u .contents .option == C_TRAILERS ) {
20142027 struct strbuf s = STRBUF_INIT ;
2028+ const char * msg ;
2029+ char * to_free = NULL ;
2030+
2031+ if (siglen )
2032+ msg = to_free = xmemdupz (subpos , sigpos - subpos );
2033+ else
2034+ msg = subpos ;
20152035
20162036 /* Format the trailer info according to the trailer_opts given */
2017- format_trailers_from_commit (& atom -> u .contents .trailer_opts , subpos , & s );
2037+ format_trailers_from_commit (& atom -> u .contents .trailer_opts , msg , & s );
2038+ free (to_free );
20182039
20192040 v -> s = strbuf_detach (& s , NULL );
20202041 } else if (atom -> u .contents .option == C_BARE )
20212042 v -> s = xstrdup (subpos );
20222043
20232044 }
2024- free ((void * )sigpos );
20252045}
20262046
20272047/*
@@ -2219,7 +2239,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
22192239 const char * merge ;
22202240
22212241 merge = remote_ref_for_branch (branch , atom -> u .remote_ref .push );
2222- * s = xstrdup ( merge ? merge : "" );
2242+ * s = merge ? merge : xstrdup ( "" );
22232243 } else
22242244 BUG ("unhandled RR_* enum" );
22252245}
@@ -2985,6 +3005,19 @@ void ref_array_clear(struct ref_array *array)
29853005 struct used_atom * atom = & used_atom [i ];
29863006 if (atom -> atom_type == ATOM_HEAD )
29873007 free (atom -> u .head );
3008+ else if (atom -> atom_type == ATOM_DESCRIBE )
3009+ strvec_clear (& atom -> u .describe_args );
3010+ else if (atom -> atom_type == ATOM_TRAILERS ||
3011+ (atom -> atom_type == ATOM_CONTENTS &&
3012+ atom -> u .contents .option == C_TRAILERS )) {
3013+ struct ref_trailer_buf * tb = atom -> u .contents .trailer_buf ;
3014+ if (tb ) {
3015+ string_list_clear (& tb -> filter_list , 0 );
3016+ strbuf_release (& tb -> sepbuf );
3017+ strbuf_release (& tb -> kvsepbuf );
3018+ free (tb );
3019+ }
3020+ }
29883021 free ((char * )atom -> name );
29893022 }
29903023 FREE_AND_NULL (used_atom );
@@ -3590,3 +3623,16 @@ void ref_filter_clear(struct ref_filter *filter)
35903623 free_commit_list (filter -> unreachable_from );
35913624 ref_filter_init (filter );
35923625}
3626+
3627+ void ref_format_init (struct ref_format * format )
3628+ {
3629+ struct ref_format blank = REF_FORMAT_INIT ;
3630+ memcpy (format , & blank , sizeof (blank ));
3631+ }
3632+
3633+ void ref_format_clear (struct ref_format * format )
3634+ {
3635+ string_list_clear (& format -> bases , 0 );
3636+ string_list_clear (& format -> is_base_tips , 0 );
3637+ ref_format_init (format );
3638+ }
0 commit comments