@@ -545,77 +545,80 @@ static int sane_ident_split(struct ident_split *person)
545545 return 1 ;
546546}
547547
548- static int parse_force_date (const char * in , char * out , int len )
548+ static int parse_force_date (const char * in , struct strbuf * out )
549549{
550- if (len < 1 )
551- return -1 ;
552- * out ++ = '@' ;
553- len -- ;
550+ strbuf_addch (out , '@' );
554551
555- if (parse_date (in , out , len ) < 0 ) {
552+ if (parse_date (in , out ) < 0 ) {
556553 int errors = 0 ;
557554 unsigned long t = approxidate_careful (in , & errors );
558555 if (errors )
559556 return -1 ;
560- snprintf (out , len , "%lu" , t );
557+ strbuf_addf (out , "%lu" , t );
561558 }
562559
563560 return 0 ;
564561}
565562
563+ static void set_ident_var (char * * buf , char * val )
564+ {
565+ free (* buf );
566+ * buf = val ;
567+ }
568+
569+ static char * envdup (const char * var )
570+ {
571+ const char * val = getenv (var );
572+ return val ? xstrdup (val ) : NULL ;
573+ }
574+
566575static void determine_author_info (struct strbuf * author_ident )
567576{
568577 char * name , * email , * date ;
569578 struct ident_split author ;
570- char date_buf [64 ];
571579
572- name = getenv ("GIT_AUTHOR_NAME" );
573- email = getenv ("GIT_AUTHOR_EMAIL" );
574- date = getenv ("GIT_AUTHOR_DATE" );
580+ name = envdup ("GIT_AUTHOR_NAME" );
581+ email = envdup ("GIT_AUTHOR_EMAIL" );
582+ date = envdup ("GIT_AUTHOR_DATE" );
575583
576584 if (author_message ) {
577- const char * a , * lb , * rb , * eol ;
585+ struct ident_split ident ;
578586 size_t len ;
587+ const char * a ;
579588
580- a = strstr (author_message_buffer , "\nauthor " );
589+ a = find_commit_header (author_message_buffer , "author" , & len );
581590 if (!a )
582- die (_ ("invalid commit: %s" ), author_message );
583-
584- lb = strchrnul (a + strlen ("\nauthor " ), '<' );
585- rb = strchrnul (lb , '>' );
586- eol = strchrnul (rb , '\n' );
587- if (!* lb || !* rb || !* eol )
588- die (_ ("invalid commit: %s" ), author_message );
589-
590- if (lb == a + strlen ("\nauthor " ))
591- /* \nauthor <foo@example.com> */
592- name = xcalloc (1 , 1 );
593- else
594- name = xmemdupz (a + strlen ("\nauthor " ),
595- (lb - strlen (" " ) -
596- (a + strlen ("\nauthor " ))));
597- email = xmemdupz (lb + strlen ("<" ), rb - (lb + strlen ("<" )));
598- len = eol - (rb + strlen ("> " ));
599- date = xmalloc (len + 2 );
600- * date = '@' ;
601- memcpy (date + 1 , rb + strlen ("> " ), len );
602- date [len + 1 ] = '\0' ;
591+ die (_ ("commit '%s' lacks author header" ), author_message );
592+ if (split_ident_line (& ident , a , len ) < 0 )
593+ die (_ ("commit '%s' has malformed author line" ), author_message );
594+
595+ set_ident_var (& name , xmemdupz (ident .name_begin , ident .name_end - ident .name_begin ));
596+ set_ident_var (& email , xmemdupz (ident .mail_begin , ident .mail_end - ident .mail_begin ));
597+
598+ if (ident .date_begin ) {
599+ struct strbuf date_buf = STRBUF_INIT ;
600+ strbuf_addch (& date_buf , '@' );
601+ strbuf_add (& date_buf , ident .date_begin , ident .date_end - ident .date_begin );
602+ strbuf_addch (& date_buf , ' ' );
603+ strbuf_add (& date_buf , ident .tz_begin , ident .tz_end - ident .tz_begin );
604+ set_ident_var (& date , strbuf_detach (& date_buf , NULL ));
605+ }
603606 }
604607
605608 if (force_author ) {
606- const char * lb = strstr (force_author , " <" );
607- const char * rb = strchr (force_author , '>' );
609+ struct ident_split ident ;
608610
609- if (! lb || ! rb )
611+ if (split_ident_line ( & ident , force_author , strlen ( force_author )) < 0 )
610612 die (_ ("malformed --author parameter" ));
611- name = xstrndup ( force_author , lb - force_author );
612- email = xstrndup ( lb + 2 , rb - ( lb + 2 ));
613+ set_ident_var ( & name , xmemdupz ( ident . name_begin , ident . name_end - ident . name_begin ) );
614+ set_ident_var ( & email , xmemdupz ( ident . mail_begin , ident . mail_end - ident . mail_begin ));
613615 }
614616
615617 if (force_date ) {
616- if (parse_force_date (force_date , date_buf , sizeof (date_buf )))
618+ struct strbuf date_buf = STRBUF_INIT ;
619+ if (parse_force_date (force_date , & date_buf ))
617620 die (_ ("invalid date format: %s" ), force_date );
618- date = date_buf ;
621+ set_ident_var ( & date , strbuf_detach ( & date_buf , NULL )) ;
619622 }
620623
621624 strbuf_addstr (author_ident , fmt_ident (name , email , date , IDENT_STRICT ));
@@ -625,6 +628,10 @@ static void determine_author_info(struct strbuf *author_ident)
625628 export_one ("GIT_AUTHOR_EMAIL" , author .mail_begin , author .mail_end , 0 );
626629 export_one ("GIT_AUTHOR_DATE" , author .date_begin , author .tz_end , '@' );
627630 }
631+
632+ free (name );
633+ free (email );
634+ free (date );
628635}
629636
630637static void split_ident_or_die (struct ident_split * id , const struct strbuf * buf )
0 commit comments