7586 lines · 225.6 KB · Perl
RawDownload
			if (defined $space_before && $space_before ne "") {				if (WARN("BAD_SIGN_OFF",					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =					    "$ucfirst_sign_off $email";				}			}			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {				if (WARN("BAD_SIGN_OFF",					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =					    "$ucfirst_sign_off $email";				} 			}			if (!defined $space_after || $space_after ne " ") {				if (WARN("BAD_SIGN_OFF",					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =					    "$ucfirst_sign_off $email";				}			} 			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));			if ($suggested_email eq "") {				ERROR("BAD_SIGN_OFF",				      "Unrecognized email address: '$email'\n" . $herecurr);			} else {				my $dequoted = $suggested_email;				$dequoted =~ s/^"//;				$dequoted =~ s/" </ </;				# Don't force email to have quotes				# Allow just an angle bracketed address				if (!same_email_addresses($email, $suggested_email)) {					if (WARN("BAD_SIGN_OFF",						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&					    $fix) {						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;					}				} 				# Address part shouldn't have comments				my $stripped_address = $email_address;				$stripped_address =~ s/\([^\(\)]*\)//g;				if ($email_address ne $stripped_address) {					if (WARN("BAD_SIGN_OFF",						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&					    $fix) {						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;					}				} 				# Only one name comment should be allowed				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;				if ($comment_count > 1) {					WARN("BAD_SIGN_OFF",					     "Use a single name comment in email: '$email'\n" . $herecurr);				}  				# stable@vger.kernel.org or stable@kernel.org shouldn't				# have an email name. In addition comments should strictly				# begin with a #				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {					if (($comment ne "" && $comment !~ /^#.+/) ||					    ($email_name ne "")) {						my $cur_name = $email_name;						my $new_comment = $comment;						$cur_name =~ s/[a-zA-Z\s\-\"]+//g; 						# Remove brackets enclosing comment text						# and # from start of comments to get comment text						$new_comment =~ s/^\((.*)\)$/$1/;						$new_comment =~ s/^\[(.*)\]$/$1/;						$new_comment =~ s/^[\s\#]+|\s+$//g; 						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);						$new_comment = " # $new_comment" if ($new_comment ne "");						my $new_email = "$email_address$new_comment"; 						if (WARN("BAD_STABLE_ADDRESS_STYLE",							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&						    $fix) {							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;						}					}				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {					my $new_comment = $comment; 					# Extract comment text from within brackets or					# c89 style /*...*/ comments					$new_comment =~ s/^\[(.*)\]$/$1/;					$new_comment =~ s/^\/\*(.*)\*\/$/$1/; 					$new_comment = trim($new_comment);					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo					$new_comment = "($new_comment)" if ($new_comment ne "");					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment); 					if (WARN("BAD_SIGN_OFF",						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&					    $fix) {						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;					}				}			} # Check for duplicate signatures			my $sig_nospace = $line;			$sig_nospace =~ s/\s//g;			$sig_nospace = lc($sig_nospace);			if (defined $signatures{$sig_nospace}) {				WARN("BAD_SIGN_OFF",				     "Duplicate signature\n" . $herecurr);			} else {				$signatures{$sig_nospace} = 1;			} # Check Co-developed-by: immediately followed by Signed-off-by: with same name and email			if ($sign_off =~ /^co-developed-by:$/i) {				if ($email eq $author) {					WARN("BAD_SIGN_OFF",					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);				}				if (!defined $lines[$linenr]) {					WARN("BAD_SIGN_OFF",					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {					WARN("BAD_SIGN_OFF",					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);				} elsif ($1 ne $email) {					WARN("BAD_SIGN_OFF",					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);				}			}		} # Check email subject for common tools that don't need to be mentioned		if ($in_header_lines &&		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {			WARN("EMAIL_SUBJECT",			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);		} # Check for Gerrit Change-Ids not in any patch context		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {			if (ERROR("GERRIT_CHANGE_ID",			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&			    $fix) {				fix_delete_line($fixlinenr, $rawline);			}		} # Check if the commit log is in a possible stack dump		if ($in_commit_log && !$commit_log_possible_stack_dump &&		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||					# timestamp		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {					# stack dump address styles			$commit_log_possible_stack_dump = 1;		} # Check for line lengths > 75 in commit log, warn once		if ($in_commit_log && !$commit_log_long_line &&		    length($line) > 75 &&		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||					# file delta changes		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||					# filename then :		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||					# A Fixes: or Link: line or signature tag line		      $commit_log_possible_stack_dump)) {			WARN("COMMIT_LOG_LONG_LINE",			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);			$commit_log_long_line = 1;		} # Reset possible stack dump if a blank line is found		if ($in_commit_log && $commit_log_possible_stack_dump &&		    $line =~ /^\s*$/) {			$commit_log_possible_stack_dump = 0;		} # Check for lines starting with a #		if ($in_commit_log && $line =~ /^#/) {			if (WARN("COMMIT_COMMENT_SYMBOL",				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/^/ /;			}		} # Check for git id commit length and improperly formed commit descriptions# A correctly formed commit description is:#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")# with the commit subject '("' prefix and '")' suffix# This is a fairly compilicated block as it tests for what appears to be# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of# possible SHA-1 matches.# A commit match can span multiple lines so this block attempts to find a# complete typical commit on a maximum of 3 lines		if ($perl_version_ok &&		    $in_commit_log && !$commit_log_possible_stack_dump &&		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {			my $init_char = "c";			my $orig_commit = "";			my $short = 1;			my $long = 0;			my $case = 1;			my $space = 1;			my $id = '0123456789ab';			my $orig_desc = "commit description";			my $description = "";			my $herectx = $herecurr;			my $has_parens = 0;			my $has_quotes = 0; 			my $input = $line;			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {				for (my $n = 0; $n < 2; $n++) {					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {						$orig_desc = $1;						$has_parens = 1;						# Always strip leading/trailing parens then double quotes if existing						$orig_desc = substr($orig_desc, 1, -1);						if ($orig_desc =~ /^".*"$/) {							$orig_desc = substr($orig_desc, 1, -1);							$has_quotes = 1;						}						last;					}					last if ($#lines < $linenr + $n);					$input .= " " . trim($rawlines[$linenr + $n]);					$herectx .= "$rawlines[$linenr + $n]\n";				}				$herectx = $herecurr if (!$has_parens);			} 			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {				$init_char = $1;				$orig_commit = lc($2);				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {				$orig_commit = lc($1);			} 			($id, $description) = git_commit_info($orig_commit,							      $id, $orig_desc); 			if (defined($id) &&			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&			    $last_git_commit_id_linenr != $linenr - 1) {				ERROR("GIT_COMMIT_ID",				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);			}			#don't report the next line if this line ends in commit and the sha1 hash is the next line			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);		} # Check for added, moved or deleted files		if (!$reported_maintainer_file && !$in_commit_log &&		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&		      (defined($1) || defined($2))))) {			$is_patch = 1;			$reported_maintainer_file = 1;			WARN("FILE_PATH_CHANGES",			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);		} # Check for adding new DT bindings not in schema format		if (!$in_commit_log &&		    ($line =~ /^new file mode\s*\d+\s*$/) &&		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {			WARN("DT_SCHEMA_BINDING_PATCH",			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");		} # Check for wrappage within a valid hunk of the file		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {			ERROR("CORRUPTED_PATCH",			      "patch seems to be corrupt (line wrapped?)\n" .				$herecurr) if (!$emitted_corrupt++);		} # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php		if (($realfile =~ /^$/ || $line =~ /^\+/) &&		    $rawline !~ m/^$UTF8*$/) {			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 			my $blank = copy_spacing($rawline);			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";			my $hereptr = "$hereline$ptr\n"; 			CHK("INVALID_UTF8",			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);		} # Check if it's the start of a commit log# (not a header line and we haven't seen the patch filename)		if ($in_header_lines && $realfile =~ /^$/ &&		    !($rawline =~ /^\s+(?:\S|$)/ ||		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {			$in_header_lines = 0;			$in_commit_log = 1;			$has_commit_log = 1;		} # Check if there is UTF-8 in a commit log when a mail header has explicitly# declined it, i.e defined some charset where it is missing.		if ($in_header_lines &&		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&		    $1 !~ /utf-8/i) {			$non_utf8_charset = 1;		} 		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&		    $rawline =~ /$NON_ASCII_UTF8/) {			WARN("UTF8_BEFORE_PATCH",			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);		} # Check for absolute kernel paths in commit message		if ($tree && $in_commit_log) {			while ($line =~ m{(?:^|\s)(/\S*)}g) {				my $file = $1; 				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&				    check_absolute_file($1, $herecurr)) {					#				} else {					check_absolute_file($file, $herecurr);				}			}		} # Check for various typo / spelling mistakes		if (defined($misspellings) &&		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {				my $typo = $1;				my $blank = copy_spacing($rawline);				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);				my $hereptr = "$hereline$ptr\n";				my $typo_fix = $spelling_fix{lc($typo)};				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);				my $msg_level = \&WARN;				$msg_level = \&CHK if ($file);				if (&{$msg_level}("TYPO_SPELLING",						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;				}			}		} # check for invalid commit id		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {			my $id;			my $description;			($id, $description) = git_commit_info($2, undef, undef);			if (!defined($id)) {				WARN("UNKNOWN_COMMIT_ID",				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);			}		} # check for repeated words separated by a single space# avoid false positive from list command eg, '-rw-r--r-- 1 root root'		if (($rawline =~ /^\+/ || $in_commit_log) &&		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {			pos($rawline) = 1 if (!$in_commit_log);			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { 				my $first = $1;				my $second = $2;				my $start_pos = $-[1];				my $end_pos = $+[2];				if ($first =~ /(?:struct|union|enum)/) {					pos($rawline) += length($first) + length($second) + 1;					next;				} 				next if (lc($first) ne lc($second));				next if ($first eq 'long'); 				# check for character before and after the word matches				my $start_char = '';				my $end_char = '';				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline)); 				next if ($start_char =~ /^\S$/);				next if (index(" \t.,;?!", $end_char) == -1); 				# avoid repeating hex occurrences like 'ff ff fe 09 ...'				if ($first =~ /\b[0-9a-f]{2,}\b/i) {					next if (!exists($allow_repeated_words{lc($first)}));				} 				if (WARN("REPEATED_WORD",					 "Possible repeated word: '$first'\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;				}			} 			# if it's a repeated word on consecutive lines in a comment block			if ($prevline =~ /$;+\s*$/ &&			    $prevrawline =~ /($word_pattern)\s*$/) {				my $last_word = $1;				if ($rawline =~ /^\+\s*\*\s*$last_word /) {					if (WARN("REPEATED_WORD",						 "Possible repeated word: '$last_word'\n" . $hereprev) &&					    $fix) {						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;					}				}			}		} # ignore non-hunk lines and lines being removed		next if (!$hunk_line || $line =~ /^-/); #trailing whitespace		if ($line =~ /^\+.*\015/) {			my $herevet = "$here\n" . cat_vet($rawline) . "\n";			if (ERROR("DOS_LINE_ENDINGS",				  "DOS line endings\n" . $herevet) &&			    $fix) {				$fixed[$fixlinenr] =~ s/[\s\015]+$//;			}		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {			my $herevet = "$here\n" . cat_vet($rawline) . "\n";			if (ERROR("TRAILING_WHITESPACE",				  "trailing whitespace\n" . $herevet) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\s+$//;			} 			$rpt_cleaners = 1;		} # Check for FSF mailing addresses.		if ($rawline =~ /\bwrite to the Free/i ||		    $rawline =~ /\b675\s+Mass\s+Ave/i ||		    $rawline =~ /\b59\s+Temple\s+Pl/i ||		    $rawline =~ /\b51\s+Franklin\s+St/i) {			my $herevet = "$here\n" . cat_vet($rawline) . "\n";			my $msg_level = \&ERROR;			$msg_level = \&CHK if ($file);			&{$msg_level}("FSF_MAILING_ADDRESS",				      "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)		} # check for Kconfig help text having a real description# Only applies when adding the entry originally, after that we do not have# sufficient context to determine whether it is indeed long enough.		if ($realfile =~ /Kconfig/ &&		    # 'choice' is usually the last thing on the line (though		    # Kconfig supports named choices), so use a word boundary		    # (\b) rather than a whitespace character (\s)		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {			my $ln = $linenr;			my $needs_help = 0;			my $has_help = 0;			my $help_length = 0;			while (defined $lines[$ln]) {				my $f = $lines[$ln++]; 				next if ($f =~ /^-/);				last if ($f !~ /^[\+ ]/);	# !patch context 				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {					$needs_help = 1;					next;				}				if ($f =~ /^\+\s*help\s*$/) {					$has_help = 1;					next;				} 

Lines 3001–3500 of 7586. Previous lines