@@ -1036,30 +1036,34 @@ static int do_sign_commit(struct strbuf *buf, const char *keyid)
1036
1036
}
1037
1037
1038
1038
int 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 )
1040
1041
{
1041
1042
1042
1043
unsigned long size ;
1043
1044
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 )];
1048
1048
1049
1049
line = buffer ;
1050
1050
tail = buffer + size ;
1051
- in_signature = 0 ;
1052
- saw_signature = 0 ;
1053
1051
while (line < tail ) {
1054
1052
const char * sig = NULL ;
1055
1053
const char * next = memchr (line , '\n' , tail - line );
1056
1054
1057
1055
next = next ? next + 1 : tail ;
1058
1056
if (in_signature && line [0 ] == ' ' )
1059
1057
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 ;
1063
1067
if (sig ) {
1064
1068
strbuf_add (signature , sig , next - sig );
1065
1069
saw_signature = 1 ;
@@ -1068,7 +1072,8 @@ int parse_signed_commit(const struct commit *commit,
1068
1072
if (* line == '\n' )
1069
1073
/* dump the whole remainder of the buffer */
1070
1074
next = tail ;
1071
- strbuf_add (payload , line , next - line );
1075
+ if (!other_signature )
1076
+ strbuf_add (payload , line , next - line );
1072
1077
in_signature = 0 ;
1073
1078
}
1074
1079
line = next ;
@@ -1082,39 +1087,48 @@ int remove_signature(struct strbuf *buf)
1082
1087
const char * line = buf -> buf ;
1083
1088
const char * tail = buf -> buf + buf -> len ;
1084
1089
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 ));
1087
1098
1088
1099
while (line < tail ) {
1089
1100
const char * next = memchr (line , '\n' , tail - line );
1090
1101
next = next ? next + 1 : tail ;
1091
1102
1092
1103
if (in_signature && line [0 ] == ' ' )
1093
- sig_end = next ;
1104
+ sigp -> end = next ;
1094
1105
else if (starts_with (line , "gpgsig" )) {
1095
1106
int i ;
1096
1107
for (i = 1 ; i < GIT_HASH_NALGOS ; i ++ ) {
1097
1108
const char * p ;
1098
1109
if (skip_prefix (line , gpg_sig_headers [i ], & p ) &&
1099
1110
* p == ' ' ) {
1100
- sig_start = line ;
1101
- sig_end = next ;
1111
+ sigp -> start = line ;
1112
+ sigp -> end = next ;
1102
1113
in_signature = 1 ;
1103
1114
}
1104
1115
}
1105
1116
} else {
1106
1117
if (* line == '\n' )
1107
1118
/* dump the whole remainder of the buffer */
1108
1119
next = tail ;
1120
+ if (in_signature && sigp - sigs != ARRAY_SIZE (sigs ))
1121
+ sigp ++ ;
1109
1122
in_signature = 0 ;
1110
1123
}
1111
1124
line = next ;
1112
1125
}
1113
1126
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 );
1116
1130
1117
- return sig_start != NULL ;
1131
+ return sigs [ 0 ]. start != NULL ;
1118
1132
}
1119
1133
1120
1134
static 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 *
1165
1179
1166
1180
sigc -> result = 'N' ;
1167
1181
1168
- if (parse_signed_commit (commit , & payload , & signature ) <= 0 )
1182
+ if (parse_signed_commit (commit , & payload , & signature , the_hash_algo ) <= 0 )
1169
1183
goto out ;
1170
1184
ret = check_signature (payload .buf , payload .len , signature .buf ,
1171
1185
signature .len , sigc );
0 commit comments