The author signed-off-by checks are currently very vague. Cases like same name or same address are not handled separately. For example, running checkpatch on commit be6577af0cef ("parisc: Add atomic64_set_release() define to avoid CPU soft lockups"), gives: WARNING: Missing Signed-off-by: line by nominal patch author 'John David Anglin <dave.anglin@bell.net>' The signoff line was: "Signed-off-by: Dave Anglin <dave.anglin@bell.net>" Clearly the author has signed off but with a slightly different version of his name. A more appropriate warning would have been to point out at the name mismatch instead. Previously, the values assumed by $authorsignoff were either 0 or 1 to indicate whether a proper sign off by author is present. Extended the checks to handle four new cases. $authorsignoff values now denote the following: 0: Missing sign off by patch author. 1: Sign off present and identical. 2: Addresses and names match, but comments differ. "James Watson(JW) <james@gmail.com>", "James Watson <james@gmail.com>" 3: Addresses match, but names are different. "James Watson <james@gmail.com>", "James <james@gmail.com>" 4: Names match, but addresses are different. "James Watson <james@watson.com>", "James Watson <james@gmail.com>" 5: Names match, addresses excluding subaddress details (RFC 5233) match. "James Watson <james@gmail.com>", "James Watson <james+a@gmail.com>" Also introduced a new message type FROM_SIGN_OFF_MISMATCH for cases 2, 3, 4 and 5.
Showing the changes to scripts/checkpatch.pl (1 of 1 file). Show all
Unified · Split
| @@ -1181,10 +1181,10 @@ sub parse_email { · 1180 unmodified lines | ||
| 1181 | 1181 | } |
| 1182 | 1182 | } |
| 1183 | 1183 | |
| 1184 | + $comment = trim($comment); | |
| 1184 | 1185 | $name = trim($name); |
| 1185 | 1186 | $name =~ s/^\"|\"$//g; |
| 1186 | − $name =~ s/(\s*\([^\)]+\))\s*//; | |
| 1187 | − if (defined($1)) { | |
| 1187 | + if ($name =~ s/(\s*\([^\)]+\))\s*//) { | |
| 1188 | 1188 | $name_comment = trim($1); |
| 1189 | 1189 | } |
| 1190 | 1190 | $address = trim($address); |
| @@ -1199,10 +1199,12 @@ sub parse_email { · 8 unmodified lines | ||
| 1199 | 1199 | } |
| 1200 | 1200 | |
| 1201 | 1201 | sub format_email { |
| 1202 | − my ($name, $address) = @_; | |
| 1202 | + my ($name, $name_comment, $address, $comment) = @_; | |
| 1203 | 1203 | |
| 1204 | 1204 | my $formatted_email; |
| 1205 | 1205 | |
| 1206 | + $name_comment = trim($name_comment); | |
| 1207 | + $comment = trim($comment); | |
| 1206 | 1208 | $name = trim($name); |
| 1207 | 1209 | $name =~ s/^\"|\"$//g; |
| 1208 | 1210 | $address = trim($address); |
| @@ -1215,9 +1217,9 @@ sub format_email { · 6 unmodified lines | ||
| 1215 | 1217 | if ("$name" eq "") { |
| 1216 | 1218 | $formatted_email = "$address"; |
| 1217 | 1219 | } else { |
| 1218 | − $formatted_email = "$name <$address>"; | |
| 1220 | + $formatted_email = "$name$name_comment <$address>"; | |
| 1219 | 1221 | } |
| 1220 | − | |
| 1222 | + $formatted_email .= "$comment"; | |
| 1221 | 1223 | return $formatted_email; |
| 1222 | 1224 | } |
| 1223 | 1225 | |
| @@ -1225,17 +1227,23 @@ sub reformat_email { · 1 unmodified line | ||
| 1225 | 1227 | my ($email) = @_; |
| 1226 | 1228 | |
| 1227 | 1229 | my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); |
| 1228 | − return format_email($email_name, $email_address); | |
| 1230 | + return format_email($email_name, $name_comment, $email_address, $comment); | |
| 1229 | 1231 | } |
| 1230 | 1232 | |
| 1231 | 1233 | sub same_email_addresses { |
| 1232 | − my ($email1, $email2) = @_; | |
| 1234 | + my ($email1, $email2, $match_comment) = @_; | |
| 1233 | 1235 | |
| 1234 | 1236 | my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); |
| 1235 | 1237 | my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); |
| 1236 | 1238 | |
| 1239 | + if ($match_comment != 1) { | |
| 1240 | + return $email1_name eq $email2_name && | |
| 1241 | + $email1_address eq $email2_address; | |
| 1242 | + } | |
| 1237 | 1243 | return $email1_name eq $email2_name && |
| 1238 | − $email1_address eq $email2_address; | |
| 1244 | + $email1_address eq $email2_address && | |
| 1245 | + $name1_comment eq $name2_comment && | |
| 1246 | + $comment1 eq $comment2; | |
| 1239 | 1247 | } |
| 1240 | 1248 | |
| 1241 | 1249 | sub which { |
| @@ -2365,6 +2373,7 @@ sub process { · 1123 unmodified lines | ||
| 2365 | 2373 | my $signoff = 0; |
| 2366 | 2374 | my $author = ''; |
| 2367 | 2375 | my $authorsignoff = 0; |
| 2376 | + my $author_sob = ''; | |
| 2368 | 2377 | my $is_patch = 0; |
| 2369 | 2378 | my $is_binding_patch = -1; |
| 2370 | 2379 | my $in_header_lines = $file ? 0 : 1; |
| @@ -2692,9 +2701,37 @@ sub process { · 321 unmodified lines | ||
| 2692 | 2701 | if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { |
| 2693 | 2702 | $signoff++; |
| 2694 | 2703 | $in_commit_log = 0; |
| 2695 | − if ($author ne '') { | |
| 2696 | − if (same_email_addresses($1, $author)) { | |
| 2704 | + if ($author ne '' && $authorsignoff != 1) { | |
| 2705 | + if (same_email_addresses($1, $author, 1)) { | |
| 2697 | 2706 | $authorsignoff = 1; |
| 2707 | + } else { | |
| 2708 | + my $ctx = $1; | |
| 2709 | + my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); | |
| 2710 | + my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); | |
| 2711 | + | |
| 2712 | + if ($email_address eq $author_address && $email_name eq $author_name) { | |
| 2713 | + $author_sob = $ctx; | |
| 2714 | + $authorsignoff = 2; | |
| 2715 | + } elsif ($email_address eq $author_address) { | |
| 2716 | + $author_sob = $ctx; | |
| 2717 | + $authorsignoff = 3; | |
| 2718 | + } elsif ($email_name eq $author_name) { | |
| 2719 | + $author_sob = $ctx; | |
| 2720 | + $authorsignoff = 4; | |
| 2721 | + | |
| 2722 | + my $address1 = $email_address; | |
| 2723 | + my $address2 = $author_address; | |
| 2724 | + | |
| 2725 | + if ($address1 =~ /(\S+)\+\S+(\@.*)/) { | |
| 2726 | + $address1 = "$1$2"; | |
| 2727 | + } | |
| 2728 | + if ($address2 =~ /(\S+)\+\S+(\@.*)/) { | |
| 2729 | + $address2 = "$1$2"; | |
| 2730 | + } | |
| 2731 | + if ($address1 eq $address2) { | |
| 2732 | + $authorsignoff = 5; | |
| 2733 | + } | |
| 2734 | + } | |
| 2698 | 2735 | } |
| 2699 | 2736 | } |
| 2700 | 2737 | } |
| @@ -2751,7 +2788,7 @@ sub process { · 50 unmodified lines | ||
| 2751 | 2788 | } |
| 2752 | 2789 | |
| 2753 | 2790 | my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); |
| 2754 | − my $suggested_email = format_email(($email_name, $email_address)); | |
| 2791 | + my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); | |
| 2755 | 2792 | if ($suggested_email eq "") { |
| 2756 | 2793 | ERROR("BAD_SIGN_OFF", |
| 2757 | 2794 | "Unrecognized email address: '$email'\n" . $herecurr); |
| @@ -2761,9 +2798,9 @@ sub process { · 3 unmodified lines | ||
| 2761 | 2798 | $dequoted =~ s/" </ </; |
| 2762 | 2799 | # Don't force email to have quotes |
| 2763 | 2800 | # Allow just an angle bracketed address |
| 2764 | − if (!same_email_addresses($email, $suggested_email)) { | |
| 2801 | + if (!same_email_addresses($email, $suggested_email, 0)) { | |
| 2765 | 2802 | WARN("BAD_SIGN_OFF", |
| 2766 | − "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); | |
| 2803 | + "email address '$email' might be better as '$suggested_email'\n" . $herecurr); | |
| 2767 | 2804 | } |
| 2768 | 2805 | } |
| 2769 | 2806 | |
| @@ -6943,9 +6980,33 @@ sub process { · 4173 unmodified lines | ||
| 6943 | 6980 | if ($signoff == 0) { |
| 6944 | 6981 | ERROR("MISSING_SIGN_OFF", |
| 6945 | 6982 | "Missing Signed-off-by: line(s)\n"); |
| 6946 | − } elsif (!$authorsignoff) { | |
| 6947 | − WARN("NO_AUTHOR_SIGN_OFF", | |
| 6948 | − "Missing Signed-off-by: line by nominal patch author '$author'\n"); | |
| 6983 | + } elsif ($authorsignoff != 1) { | |
| 6984 | + # authorsignoff values: | |
| 6985 | + # 0 -> missing sign off | |
| 6986 | + # 1 -> sign off identical | |
| 6987 | + # 2 -> names and addresses match, comments mismatch | |
| 6988 | + # 3 -> addresses match, names different | |
| 6989 | + # 4 -> names match, addresses different | |
| 6990 | + # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match | |
| 6991 | + | |
| 6992 | + my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; | |
| 6993 | + | |
| 6994 | + if ($authorsignoff == 0) { | |
| 6995 | + ERROR("NO_AUTHOR_SIGN_OFF", | |
| 6996 | + "Missing Signed-off-by: line by nominal patch author '$author'\n"); | |
| 6997 | + } elsif ($authorsignoff == 2) { | |
| 6998 | + CHK("FROM_SIGN_OFF_MISMATCH", | |
| 6999 | + "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); | |
| 7000 | + } elsif ($authorsignoff == 3) { | |
| 7001 | + WARN("FROM_SIGN_OFF_MISMATCH", | |
| 7002 | + "From:/Signed-off-by: email name mismatch: $sob_msg\n"); | |
| 7003 | + } elsif ($authorsignoff == 4) { | |
| 7004 | + WARN("FROM_SIGN_OFF_MISMATCH", | |
| 7005 | + "From:/Signed-off-by: email address mismatch: $sob_msg\n"); | |
| 7006 | + } elsif ($authorsignoff == 5) { | |
| 7007 | + WARN("FROM_SIGN_OFF_MISMATCH", | |
| 7008 | + "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); | |
| 7009 | + } | |
| 6949 | 7010 | } |
| 6950 | 7011 | } |
| 6951 | 7012 | |