7976 lines · 239.6 KB · Perl
RawDownload
		} # 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)) {			my $rawline_utf8 = decode("utf8", $rawline);			while ($rawline_utf8 =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {				my $typo = $1;				my $blank = copy_spacing($rawline_utf8);				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;				} 				$f =~ s/^.//;	# strip patch context [+ ]				$f =~ s/#.*//;	# strip # directives				$f =~ s/^\s+//;	# strip leading blanks				next if ($f =~ /^$/);	# skip blank lines 				# At the end of this Kconfig block:				# This only checks context lines in the patch				# and so hopefully shouldn't trigger false				# positives, even though some of these are				# common words in help texts				if ($f =~ /^(?:config|menuconfig|choice|endchoice|					       if|endif|menu|endmenu|source)\b/x) {					last;				}				$help_length++ if ($has_help);			}			if ($needs_help &&			    $help_length < $min_conf_desc_length) {				my $stat_real = get_stat_real($linenr, $ln - 1);				WARN("CONFIG_DESCRIPTION",				     "please write a help paragraph that fully describes the config symbol with at least $min_conf_desc_length lines\n" . "$here\n$stat_real\n");			}		} # check MAINTAINERS entries		if ($realfile =~ /^MAINTAINERS$/) {# check MAINTAINERS entries for the right form			if ($rawline =~ /^\+[A-Z]:/ &&			    $rawline !~ /^\+[A-Z]:\t\S/) {				if (WARN("MAINTAINERS_STYLE",					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;				}			}# check MAINTAINERS entries for the right ordering too			my $preferred_order = 'MRLSWQBCPTFXNK';			if ($rawline =~ /^\+[A-Z]:/ &&			    $prevrawline =~ /^[\+ ][A-Z]:/) {				$rawline =~ /^\+([A-Z]):\s*(.*)/;				my $cur = $1;				my $curval = $2;				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;				my $prev = $1;				my $prevval = $2;				my $curindex = index($preferred_order, $cur);				my $previndex = index($preferred_order, $prev);				if ($curindex < 0) {					WARN("MAINTAINERS_STYLE",					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);				} else {					if ($previndex >= 0 && $curindex < $previndex) {						WARN("MAINTAINERS_STYLE",						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);					} elsif ((($prev eq 'F' && $cur eq 'F') ||						  ($prev eq 'X' && $cur eq 'X')) &&						 ($prevval cmp $curval) > 0) {						WARN("MAINTAINERS_STYLE",						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);					}				}			}		} # check for DT compatible documentation		if (defined $root &&			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 			my $dt_path = $root . "/Documentation/devicetree/bindings/";			my $vp_file = $dt_path . "vendor-prefixes.yaml"; 			foreach my $compat (@compats) {				my $compat2 = $compat;				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;				my $compat3 = $compat;				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;				if ( $? >> 8 ) {					WARN("UNDOCUMENTED_DT_STRING",					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);				} 				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;				my $vendor = $1;				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;				if ( $? >> 8 ) {					WARN("UNDOCUMENTED_DT_STRING",					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);				}			}		} # Check for RGMII phy-mode with delay on PCB		if ($realfile =~ /\.(dts|dtsi|dtso)$/ &&		    $line =~ /^\+\s*(phy-mode|phy-connection-type)\s*=\s*"/ &&		    !ctx_has_comment($first_line, $linenr)) {			my $prop = $1;			my $mode = get_quoted_string($line, $rawline);			if ($mode =~ /^"rgmii(?:|-rxid|-txid)"$/) {				WARN("UNCOMMENTED_RGMII_MODE",				     "$prop $mode without comment -- delays on the PCB should be described, otherwise use \"rgmii-id\"\n" . $herecurr);			}		} # check for using SPDX license tag at beginning of files		if ($realline == $checklicenseline) {			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {				$checklicenseline = 2;			} elsif ($rawline =~ /^\+/) {				my $comment = "";				if ($realfile =~ /\.(c|rs|dts|dtsi)$/) {					$comment = '//';				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {					$comment = '#';				} elsif ($realfile =~ /\.rst$/) {					$comment = '..';				}				my $pattern = qr{\Q$comment\E};				if ($realfile =~ /\.(h|s|S)$/) {					$comment = '/*';					$pattern = qr{/\*};					if ($spdx_cxx_comments) {						$comment = '// or /*';						$pattern = qr{//|/\*};					}				} # check SPDX comment style for .[chsS] files				if ($realfile =~ /\.[chsS]$/ &&				    $rawline =~ /SPDX-License-Identifier:/ &&				    $rawline !~ m@^\+\s*$pattern\s*@) {					WARN("SPDX_LICENSE_TAG",					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);				} 				if ($comment !~ /^$/ &&				    $rawline !~ m@^\+$pattern SPDX-License-Identifier: @) {					WARN("SPDX_LICENSE_TAG",					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {					my $spdx_license = $1;					if (!is_SPDX_License_valid($spdx_license)) {						WARN("SPDX_LICENSE_TAG",						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);					}					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&					    $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) {						my $msg_level = \&WARN;						$msg_level = \&CHK if ($file);						if (&{$msg_level}("SPDX_LICENSE_TAG", 								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&						    $fix) {							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;						}					}					if ($realfile =~ m@^include/dt-bindings/@ &&					    $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) {						WARN("SPDX_LICENSE_TAG",						     "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr);					}				}			}		} # check for embedded filenames		if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {			WARN("EMBEDDED_FILENAME",			     "It's generally not useful to have the filename in the file\n" . $herecurr);		} # check we are in a valid source file if not then ignore this hunk		next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/); # check for using SPDX-License-Identifier on the wrong line number		if ($realline != $checklicenseline &&		    $rawline =~ /\bSPDX-License-Identifier:/ &&		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {			WARN("SPDX_LICENSE_TAG",			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);		} # check for disallowed SPDX file tags		if ($rawline =~ /\bSPDX-.*:/ &&		    $rawline !~ /\bSPDX-License-Identifier:/ &&		    $rawline !~ /\bSPDX-FileCopyrightText:/) {			WARN("SPDX_LICENSE_TAG",			     "Disallowed SPDX tag\n" . $herecurr);		} # line length limit (with some exclusions)## There are a few types of lines that may extend beyond $max_line_length:#	logging functions like pr_info that end in a string#	lines with a single string#	#defines that are a single string#	lines with an RFC3986 like URL## There are 3 different line length message types:# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length# LONG_LINE		all other lines longer than $max_line_length## if LONG_LINE is ignored, the other 2 types are also ignored# 		if ($line =~ /^\+/ && $length > $max_line_length) {			my $msg_type = "LONG_LINE"; 			# Check the allowed long line types first 			# logging functions that end in a string that starts			# before $max_line_length			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {				$msg_type = ""; 			# lines with only strings (w/ possible termination)			# #defines with only strings			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {				$msg_type = ""; 			# More special cases			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {				$msg_type = ""; 			# URL ($rawline is used in case the URL is in a comment)			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {				$msg_type = ""; 			# Otherwise set the alternate message types 			# a comment starts before $max_line_length			} elsif ($line =~ /($;[\s$;]*)$/ &&				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {				$msg_type = "LONG_LINE_COMMENT" 			# a quoted string starts before $max_line_length			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {				$msg_type = "LONG_LINE_STRING"			} 			if ($msg_type ne "" &&			    show_type("LONG_LINE") && show_type($msg_type)) {				my $msg_level = \&WARN;				$msg_level = \&CHK if ($file);				&{$msg_level}($msg_type,					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);			}		} # check for adding lines without a newline.		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {			if (WARN("MISSING_EOF_NEWLINE",			         "adding a line without newline at end of file\n" . $herecurr) &&			    $fix) {				fix_delete_line($fixlinenr+1, "No newline at end of file");			}		} # check for .L prefix local symbols in .S files		if ($realfile =~ /\.S$/ &&		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {			WARN("AVOID_L_PREFIX",			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr);		} # check we are in a valid source file C or perl if not then ignore this hunk		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); # at the beginning of a line any tabs must come first and anything# more than $tabsize must use tabs.		if ($rawline =~ /^\+\s* \t\s*\S/ ||		    $rawline =~ /^\+\s*        \s*/) {			my $herevet = "$here\n" . cat_vet($rawline) . "\n";			$rpt_cleaners = 1;			if (ERROR("CODE_INDENT",				  "code indent should use tabs where possible\n" . $herevet) &&			    $fix) {				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;			}		} # check for space before tabs.		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {			my $herevet = "$here\n" . cat_vet($rawline) . "\n";

Lines 3501–4000 of 7976. Previous lines