@@ -1036,30 +1036,34 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
10361036}
10371037
10381038int parse_signed_commit (const struct commit * commit ,
1039- struct strbuf * payload , struct strbuf * signature )
1039+ struct strbuf * payload , struct strbuf * signature ,
1040+ const struct git_hash_algo * algop )
10401041{
10411042
10421043 unsigned long size ;
10431044 const char * buffer = get_commit_buffer (commit , & size );
1044- int in_signature , saw_signature = -1 ;
1045- const char * line , * tail ;
1046- const char * gpg_sig_header = gpg_sig_headers [hash_algo_by_ptr (the_hash_algo )];
1047- int gpg_sig_header_len = strlen (gpg_sig_header );
1045+ int in_signature = 0 , saw_signature = 0 , other_signature = 0 ;
1046+ const char * line , * tail , * p ;
1047+ const char * gpg_sig_header = gpg_sig_headers [hash_algo_by_ptr (algop )];
10481048
10491049 line = buffer ;
10501050 tail = buffer + size ;
1051- in_signature = 0 ;
1052- saw_signature = 0 ;
10531051 while (line < tail ) {
10541052 const char * sig = NULL ;
10551053 const char * next = memchr (line , '\n' , tail - line );
10561054
10571055 next = next ? next + 1 : tail ;
10581056 if (in_signature && line [0 ] == ' ' )
10591057 sig = line + 1 ;
1060- else if (starts_with (line , gpg_sig_header ) &&
1061- line [gpg_sig_header_len ] == ' ' )
1062- sig = line + gpg_sig_header_len + 1 ;
1058+ else if (skip_prefix (line , gpg_sig_header , & p ) &&
1059+ * p == ' ' ) {
1060+ sig = line + strlen (gpg_sig_header ) + 1 ;
1061+ other_signature = 0 ;
1062+ }
1063+ else if (starts_with (line , "gpgsig" ))
1064+ other_signature = 1 ;
1065+ else if (other_signature && line [0 ] != ' ' )
1066+ other_signature = 0 ;
10631067 if (sig ) {
10641068 strbuf_add (signature , sig , next - sig );
10651069 saw_signature = 1 ;
@@ -1068,7 +1072,8 @@ int parse_signed_commit(const struct commit *commit,
10681072 if (* line == '\n' )
10691073 /* dump the whole remainder of the buffer */
10701074 next = tail ;
1071- strbuf_add (payload , line , next - line );
1075+ if (!other_signature )
1076+ strbuf_add (payload , line , next - line );
10721077 in_signature = 0 ;
10731078 }
10741079 line = next ;
@@ -1082,39 +1087,48 @@ int remove_signature(struct strbuf *buf)
10821087 const char * line = buf -> buf ;
10831088 const char * tail = buf -> buf + buf -> len ;
10841089 int in_signature = 0 ;
1085- const char * sig_start = NULL ;
1086- const char * sig_end = NULL ;
1090+ struct sigbuf {
1091+ const char * start ;
1092+ const char * end ;
1093+ } sigs [2 ], * sigp = & sigs [0 ];
1094+ int i ;
1095+ const char * orig_buf = buf -> buf ;
1096+
1097+ memset (sigs , 0 , sizeof (sigs ));
10871098
10881099 while (line < tail ) {
10891100 const char * next = memchr (line , '\n' , tail - line );
10901101 next = next ? next + 1 : tail ;
10911102
10921103 if (in_signature && line [0 ] == ' ' )
1093- sig_end = next ;
1104+ sigp -> end = next ;
10941105 else if (starts_with (line , "gpgsig" )) {
10951106 int i ;
10961107 for (i = 1 ; i < GIT_HASH_NALGOS ; i ++ ) {
10971108 const char * p ;
10981109 if (skip_prefix (line , gpg_sig_headers [i ], & p ) &&
10991110 * p == ' ' ) {
1100- sig_start = line ;
1101- sig_end = next ;
1111+ sigp -> start = line ;
1112+ sigp -> end = next ;
11021113 in_signature = 1 ;
11031114 }
11041115 }
11051116 } else {
11061117 if (* line == '\n' )
11071118 /* dump the whole remainder of the buffer */
11081119 next = tail ;
1120+ if (in_signature && sigp - sigs != ARRAY_SIZE (sigs ))
1121+ sigp ++ ;
11091122 in_signature = 0 ;
11101123 }
11111124 line = next ;
11121125 }
11131126
1114- if (sig_start )
1115- strbuf_remove (buf , sig_start - buf -> buf , sig_end - sig_start );
1127+ for (i = ARRAY_SIZE (sigs ) - 1 ; i >= 0 ; i -- )
1128+ if (sigs [i ].start )
1129+ strbuf_remove (buf , sigs [i ].start - orig_buf , sigs [i ].end - sigs [i ].start );
11161130
1117- return sig_start != NULL ;
1131+ return sigs [ 0 ]. start != NULL ;
11181132}
11191133
11201134static void handle_signed_tag (struct commit * parent , struct commit_extra_header * * * tail )
@@ -1165,7 +1179,7 @@ int check_commit_signature(const struct commit *commit, struct signature_check *
11651179
11661180 sigc -> result = 'N' ;
11671181
1168- if (parse_signed_commit (commit , & payload , & signature ) <= 0 )
1182+ if (parse_signed_commit (commit , & payload , & signature , the_hash_algo ) <= 0 )
11691183 goto out ;
11701184 ret = check_signature (payload .buf , payload .len , signature .buf ,
11711185 signature .len , sigc );
0 commit comments