@@ -75,11 +75,11 @@ struct refname_atom {
75
75
int lstrip , rstrip ;
76
76
};
77
77
78
- static struct ref_trailer_buf {
78
+ struct ref_trailer_buf {
79
79
struct string_list filter_list ;
80
80
struct strbuf sepbuf ;
81
81
struct strbuf kvsepbuf ;
82
- } ref_trailer_buf = { STRING_LIST_INIT_NODUP , STRBUF_INIT , STRBUF_INIT } ;
82
+ };
83
83
84
84
static struct expand_data {
85
85
struct object_id oid ;
@@ -201,6 +201,7 @@ static struct used_atom {
201
201
enum { C_BARE , C_BODY , C_BODY_DEP , C_LENGTH , C_LINES ,
202
202
C_SIG , C_SUB , C_SUB_SANITIZE , C_TRAILERS } option ;
203
203
struct process_trailer_options trailer_opts ;
204
+ struct ref_trailer_buf * trailer_buf ;
204
205
unsigned int nlines ;
205
206
} contents ;
206
207
struct {
@@ -232,7 +233,7 @@ static struct used_atom {
232
233
enum { S_BARE , S_GRADE , S_SIGNER , S_KEY ,
233
234
S_FINGERPRINT , S_PRI_KEY_FP , S_TRUST_LEVEL } option ;
234
235
} signature ;
235
- const char * * describe_args ;
236
+ struct strvec describe_args ;
236
237
struct refname_atom refname ;
237
238
char * head ;
238
239
} u ;
@@ -566,21 +567,36 @@ static int trailers_atom_parser(struct ref_format *format UNUSED,
566
567
atom -> u .contents .trailer_opts .no_divider = 1 ;
567
568
568
569
if (arg ) {
569
- const char * argbuf = xstrfmt ("%s)" , arg );
570
+ char * argbuf = xstrfmt ("%s)" , arg );
571
+ const char * arg = argbuf ;
570
572
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 );
571
586
572
587
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 )) {
577
591
if (!invalid_arg )
578
592
strbuf_addf (err , _ ("expected %%(trailers:key=<value>)" ));
579
593
else
580
594
strbuf_addf (err , _ ("unknown %%(trailers) argument: %s" ), invalid_arg );
581
- free ((char * )invalid_arg );
595
+ free (invalid_arg );
596
+ free (argbuf );
582
597
return -1 ;
583
598
}
599
+ free (argbuf );
584
600
}
585
601
atom -> u .contents .option = C_TRAILERS ;
586
602
return 0 ;
@@ -677,7 +693,7 @@ static int describe_atom_parser(struct ref_format *format UNUSED,
677
693
struct used_atom * atom ,
678
694
const char * arg , struct strbuf * err )
679
695
{
680
- struct strvec args = STRVEC_INIT ;
696
+ strvec_init ( & atom -> u . describe_args ) ;
681
697
682
698
for (;;) {
683
699
int found = 0 ;
@@ -686,13 +702,12 @@ static int describe_atom_parser(struct ref_format *format UNUSED,
686
702
if (!arg || !* arg )
687
703
break ;
688
704
689
- found = describe_atom_option_parser (& args , & arg , err );
705
+ found = describe_atom_option_parser (& atom -> u . describe_args , & arg , err );
690
706
if (found < 0 )
691
707
return found ;
692
708
if (!found )
693
709
return err_bad_arg (err , "describe" , bad_arg );
694
710
}
695
- atom -> u .describe_args = strvec_detach (& args );
696
711
return 0 ;
697
712
}
698
713
@@ -986,6 +1001,7 @@ struct ref_formatting_stack {
986
1001
struct ref_formatting_stack * prev ;
987
1002
struct strbuf output ;
988
1003
void (* at_end )(struct ref_formatting_stack * * stack );
1004
+ void (* at_end_data_free )(void * data );
989
1005
void * at_end_data ;
990
1006
};
991
1007
@@ -1154,6 +1170,8 @@ static void pop_stack_element(struct ref_formatting_stack **stack)
1154
1170
if (prev )
1155
1171
strbuf_addbuf (& prev -> output , & current -> output );
1156
1172
strbuf_release (& current -> output );
1173
+ if (current -> at_end_data_free )
1174
+ current -> at_end_data_free (current -> at_end_data );
1157
1175
free (current );
1158
1176
* stack = prev ;
1159
1177
}
@@ -1213,15 +1231,13 @@ static void if_then_else_handler(struct ref_formatting_stack **stack)
1213
1231
}
1214
1232
1215
1233
* stack = cur ;
1216
- free (if_then_else );
1217
1234
}
1218
1235
1219
1236
static int if_atom_handler (struct atom_value * atomv , struct ref_formatting_state * state ,
1220
1237
struct strbuf * err UNUSED )
1221
1238
{
1222
1239
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 ));
1225
1241
1226
1242
if_then_else -> str = atomv -> atom -> u .if_then_else .str ;
1227
1243
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
1230
1246
new_stack = state -> stack ;
1231
1247
new_stack -> at_end = if_then_else_handler ;
1232
1248
new_stack -> at_end_data = if_then_else ;
1249
+ new_stack -> at_end_data_free = free ;
1233
1250
return 0 ;
1234
1251
}
1235
1252
@@ -1833,16 +1850,10 @@ static void find_subpos(const char *buf,
1833
1850
size_t * nonsiglen ,
1834
1851
const char * * sig , size_t * siglen )
1835
1852
{
1836
- struct strbuf payload = STRBUF_INIT ;
1837
- struct strbuf signature = STRBUF_INIT ;
1838
1853
const char * eol ;
1839
1854
const char * end = buf + strlen (buf );
1840
1855
const char * sigstart ;
1841
1856
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
-
1846
1857
/* skip past header until we hit empty line */
1847
1858
while (* buf && * buf != '\n' ) {
1848
1859
eol = strchrnul (buf , '\n' );
@@ -1853,8 +1864,10 @@ static void find_subpos(const char *buf,
1853
1864
/* skip any empty lines */
1854
1865
while (* buf == '\n' )
1855
1866
buf ++ ;
1856
- * sig = strbuf_detach ( & signature , siglen );
1867
+ /* parse signature first; we might not even have a subject line */
1857
1868
sigstart = buf + parse_signed_buffer (buf , strlen (buf ));
1869
+ * sig = sigstart ;
1870
+ * siglen = end - * sig ;
1858
1871
1859
1872
/* subject is first non-empty line */
1860
1873
* sub = buf ;
@@ -1929,7 +1942,7 @@ static void grab_describe_values(struct atom_value *val, int deref,
1929
1942
1930
1943
cmd .git_cmd = 1 ;
1931
1944
strvec_push (& cmd .args , "describe" );
1932
- strvec_pushv (& cmd .args , atom -> u .describe_args );
1945
+ strvec_pushv (& cmd .args , atom -> u .describe_args . v );
1933
1946
strvec_push (& cmd .args , oid_to_hex (& commit -> object .oid ));
1934
1947
if (pipe_command (& cmd , NULL , 0 , & out , 0 , & err , 0 ) < 0 ) {
1935
1948
error (_ ("failed to run 'describe'" ));
@@ -2012,16 +2025,23 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct exp
2012
2025
v -> s = strbuf_detach (& s , NULL );
2013
2026
} else if (atom -> u .contents .option == C_TRAILERS ) {
2014
2027
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 ;
2015
2035
2016
2036
/* 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 );
2018
2039
2019
2040
v -> s = strbuf_detach (& s , NULL );
2020
2041
} else if (atom -> u .contents .option == C_BARE )
2021
2042
v -> s = xstrdup (subpos );
2022
2043
2023
2044
}
2024
- free ((void * )sigpos );
2025
2045
}
2026
2046
2027
2047
/*
@@ -2219,7 +2239,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
2219
2239
const char * merge ;
2220
2240
2221
2241
merge = remote_ref_for_branch (branch , atom -> u .remote_ref .push );
2222
- * s = xstrdup ( merge ? merge : "" );
2242
+ * s = merge ? merge : xstrdup ( "" );
2223
2243
} else
2224
2244
BUG ("unhandled RR_* enum" );
2225
2245
}
@@ -2985,6 +3005,19 @@ void ref_array_clear(struct ref_array *array)
2985
3005
struct used_atom * atom = & used_atom [i ];
2986
3006
if (atom -> atom_type == ATOM_HEAD )
2987
3007
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
+ }
2988
3021
free ((char * )atom -> name );
2989
3022
}
2990
3023
FREE_AND_NULL (used_atom );
@@ -3590,3 +3623,16 @@ void ref_filter_clear(struct ref_filter *filter)
3590
3623
free_commit_list (filter -> unreachable_from );
3591
3624
ref_filter_init (filter );
3592
3625
}
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