Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: PRESUBMIT.py

Issue 2070483002: Add PRESUBMIT rule to make sure IPC changes are security reviewed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/common/OWNERS » ('j') | content/common/OWNERS » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Top-level presubmit script for Chromium. 5 """Top-level presubmit script for Chromium.
6 6
7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
8 for more details about the presubmit API built into depot_tools. 8 for more details about the presubmit API built into depot_tools.
9 """ 9 """
10 10
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 def _CheckDCHECK_IS_ONHasBraces(input_api, output_api): 421 def _CheckDCHECK_IS_ONHasBraces(input_api, output_api):
422 """Checks to make sure DCHECK_IS_ON() does not skip the braces.""" 422 """Checks to make sure DCHECK_IS_ON() does not skip the braces."""
423 errors = [] 423 errors = []
424 pattern = input_api.re.compile(r'DCHECK_IS_ON(?!\(\))', 424 pattern = input_api.re.compile(r'DCHECK_IS_ON(?!\(\))',
425 input_api.re.MULTILINE) 425 input_api.re.MULTILINE)
426 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): 426 for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
427 if (not f.LocalPath().endswith(('.cc', '.mm', '.h'))): 427 if (not f.LocalPath().endswith(('.cc', '.mm', '.h'))):
428 continue 428 continue
429 for lnum, line in f.ChangedContents(): 429 for lnum, line in f.ChangedContents():
430 if input_api.re.search(pattern, line): 430 if input_api.re.search(pattern, line):
431 errors.append(output_api.PresubmitError( 431 errors.append(output_api.PresubmitError(
432 ('%s:%d: Use of DCHECK_IS_ON() must be written as "#if ' + 432 ('%s:%d: Use of DCHECK_IS_ON() must be written as "#if ' +
433 'DCHECK_IS_ON()", not forgetting the braces.') 433 'DCHECK_IS_ON()", not forgetting the braces.')
434 % (f.LocalPath(), lnum))) 434 % (f.LocalPath(), lnum)))
435 return errors 435 return errors
436 436
437 437
438 def _FindHistogramNameInLine(histogram_name, line): 438 def _FindHistogramNameInLine(histogram_name, line):
439 """Tries to find a histogram name or prefix in a line.""" 439 """Tries to find a histogram name or prefix in a line."""
440 if not "affected-histogram" in line: 440 if not "affected-histogram" in line:
441 return histogram_name in line 441 return histogram_name in line
442 # A histogram_suffixes tag type has an affected-histogram name as a prefix of 442 # A histogram_suffixes tag type has an affected-histogram name as a prefix of
443 # the histogram_name. 443 # the histogram_name.
444 if not '"' in line: 444 if not '"' in line:
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 return True 583 return True
584 return False 584 return False
585 585
586 def CheckForMatch(affected_file, line_num, line, func_name, message, error): 586 def CheckForMatch(affected_file, line_num, line, func_name, message, error):
587 matched = False 587 matched = False
588 if func_name[0:1] == '/': 588 if func_name[0:1] == '/':
589 regex = func_name[1:] 589 regex = func_name[1:]
590 if input_api.re.search(regex, line): 590 if input_api.re.search(regex, line):
591 matched = True 591 matched = True
592 elif func_name in line: 592 elif func_name in line:
593 matched = True 593 matched = True
594 if matched: 594 if matched:
595 problems = warnings; 595 problems = warnings
596 if error: 596 if error:
597 problems = errors; 597 problems = errors
598 problems.append(' %s:%d:' % (affected_file.LocalPath(), line_num)) 598 problems.append(' %s:%d:' % (affected_file.LocalPath(), line_num))
599 for message_line in message: 599 for message_line in message:
600 problems.append(' %s' % message_line) 600 problems.append(' %s' % message_line)
601 601
602 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h')) 602 file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
603 for f in input_api.AffectedFiles(file_filter=file_filter): 603 for f in input_api.AffectedFiles(file_filter=file_filter):
604 for line_num, line in f.ChangedContents(): 604 for line_num, line in f.ChangedContents():
605 for func_name, message, error in _BANNED_OBJC_FUNCTIONS: 605 for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
606 CheckForMatch(f, line_num, line, func_name, message, error) 606 CheckForMatch(f, line_num, line, func_name, message, error)
607 607
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 import checkstyle 1392 import checkstyle
1393 finally: 1393 finally:
1394 # Restore sys.path to what it was before. 1394 # Restore sys.path to what it was before.
1395 sys.path = original_sys_path 1395 sys.path = original_sys_path
1396 1396
1397 return checkstyle.RunCheckstyle( 1397 return checkstyle.RunCheckstyle(
1398 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml', 1398 input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml',
1399 black_list=_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST) 1399 black_list=_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
1400 1400
1401 1401
1402 def _CheckIpcOwners(input_api, output_api):
1403 file_patterns = [
1404 '*_messages.cc',
1405 '*_messages*.h',
1406 '*_param_traits*.*',
1407 '*.mojom',
1408 '*_struct_traits*.*',
1409 '*_type_converters*.*',
1410 ]
1411
1412 to_check = {}
1413
1414 for f in input_api.change.AffectedFiles():
1415 for pattern in file_patterns:
1416 if input_api.fnmatch.fnmatch(
1417 input_api.os_path.basename(f.LocalPath()), pattern):
1418 owners_file = input_api.os_path.join(
1419 input_api.os_path.dirname(f.LocalPath()), 'OWNERS')
1420 if owners_file not in to_check:
1421 to_check[owners_file] = {}
1422 if pattern not in to_check[owners_file]:
1423 to_check[owners_file][pattern] = {
1424 'files': [],
1425 'missing_lines': [
1426 'per-file %s=set noparent' % pattern,
1427 'per-file %s=file://ipc/SECURITY_OWNERS' % pattern,
1428 ]
1429 }
1430 to_check[owners_file][pattern]['files'].append(f)
1431 break
1432
1433 for owners_file, patterns in to_check.iteritems():
1434 with file(owners_file) as f:
1435 for line in f.read().splitlines():
1436 for entry in patterns.itervalues():
1437 entry['missing_lines'] = [missing
1438 for missing in entry['missing_lines']
1439 if missing != line]
1440
1441 errors = []
1442 for owners_file, patterns in to_check.iteritems():
1443 missing_lines = []
1444 files = []
1445 for pattern, entry in patterns.iteritems():
1446 missing_lines.extend(entry['missing_lines'])
1447 files.extend([' %s' % f.LocalPath() for f in entry['files']])
1448 if missing_lines:
1449 errors.append(
1450 '%s is missing the following lines:\n\n%s\n\nfor changed files:\n%s' %
1451 (owners_file, '\n'.join(missing_lines), '\n'.join(files)))
1452
1453 results = []
1454 if errors:
1455 results.append(output_api.PresubmitError(
1456 'Found changes to IPC files without a security OWNER!',
1457 long_text='\n\n'.join(errors)))
1458
1459 return results
1460
1461
1402 def _CheckAndroidToastUsage(input_api, output_api): 1462 def _CheckAndroidToastUsage(input_api, output_api):
1403 """Checks that code uses org.chromium.ui.widget.Toast instead of 1463 """Checks that code uses org.chromium.ui.widget.Toast instead of
1404 android.widget.Toast (Chromium Toast doesn't force hardware 1464 android.widget.Toast (Chromium Toast doesn't force hardware
1405 acceleration on low-end devices, saving memory). 1465 acceleration on low-end devices, saving memory).
1406 """ 1466 """
1407 toast_import_pattern = input_api.re.compile( 1467 toast_import_pattern = input_api.re.compile(
1408 r'^import android\.widget\.Toast;$') 1468 r'^import android\.widget\.Toast;$')
1409 1469
1410 errors = [] 1470 errors = []
1411 1471
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 results.extend(_CheckNoDeprecatedCSS(input_api, output_api)) 1915 results.extend(_CheckNoDeprecatedCSS(input_api, output_api))
1856 results.extend(_CheckNoDeprecatedJS(input_api, output_api)) 1916 results.extend(_CheckNoDeprecatedJS(input_api, output_api))
1857 results.extend(_CheckParseErrors(input_api, output_api)) 1917 results.extend(_CheckParseErrors(input_api, output_api))
1858 results.extend(_CheckForIPCRules(input_api, output_api)) 1918 results.extend(_CheckForIPCRules(input_api, output_api))
1859 results.extend(_CheckForCopyrightedCode(input_api, output_api)) 1919 results.extend(_CheckForCopyrightedCode(input_api, output_api))
1860 results.extend(_CheckForWindowsLineEndings(input_api, output_api)) 1920 results.extend(_CheckForWindowsLineEndings(input_api, output_api))
1861 results.extend(_CheckSingletonInHeaders(input_api, output_api)) 1921 results.extend(_CheckSingletonInHeaders(input_api, output_api))
1862 results.extend(_CheckNoDeprecatedCompiledResourcesGYP(input_api, output_api)) 1922 results.extend(_CheckNoDeprecatedCompiledResourcesGYP(input_api, output_api))
1863 results.extend(_CheckPydepsNeedsUpdating(input_api, output_api)) 1923 results.extend(_CheckPydepsNeedsUpdating(input_api, output_api))
1864 results.extend(_CheckJavaStyle(input_api, output_api)) 1924 results.extend(_CheckJavaStyle(input_api, output_api))
1925 results.extend(_CheckIpcOwners(input_api, output_api))
1865 1926
1866 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()): 1927 if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
1867 results.extend(input_api.canned_checks.RunUnitTestsInDirectory( 1928 results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
1868 input_api, output_api, 1929 input_api, output_api,
1869 input_api.PresubmitLocalPath(), 1930 input_api.PresubmitLocalPath(),
1870 whitelist=[r'^PRESUBMIT_test\.py$'])) 1931 whitelist=[r'^PRESUBMIT_test\.py$']))
1871 return results 1932 return results
1872 1933
1873 1934
1874 def _CheckAuthorizedAuthor(input_api, output_api): 1935 def _CheckAuthorizedAuthor(input_api, output_api):
1875 """For non-googler/chromites committers, verify the author's email address is 1936 """For non-googler/chromites committers, verify the author's email address is
1876 in AUTHORS. 1937 in AUTHORS.
1877 """ 1938 """
1878 # TODO(maruel): Add it to input_api?
1879 import fnmatch
1880
1881 author = input_api.change.author_email 1939 author = input_api.change.author_email
1882 if not author: 1940 if not author:
1883 input_api.logging.info('No author, skipping AUTHOR check') 1941 input_api.logging.info('No author, skipping AUTHOR check')
1884 return [] 1942 return []
1885 authors_path = input_api.os_path.join( 1943 authors_path = input_api.os_path.join(
1886 input_api.PresubmitLocalPath(), 'AUTHORS') 1944 input_api.PresubmitLocalPath(), 'AUTHORS')
1887 valid_authors = ( 1945 valid_authors = (
1888 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line) 1946 input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
1889 for line in open(authors_path)) 1947 for line in open(authors_path))
1890 valid_authors = [item.group(1).lower() for item in valid_authors if item] 1948 valid_authors = [item.group(1).lower() for item in valid_authors if item]
1891 if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors): 1949 if not any(input_api.fnmatch.fnmatch(author.lower(), valid)
1950 for valid in valid_authors):
1892 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors)) 1951 input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
1893 return [output_api.PresubmitPromptWarning( 1952 return [output_api.PresubmitPromptWarning(
1894 ('%s is not in AUTHORS file. If you are a new contributor, please visit' 1953 ('%s is not in AUTHORS file. If you are a new contributor, please visit'
1895 '\n' 1954 '\n'
1896 'http://www.chromium.org/developers/contributing-code and read the ' 1955 'http://www.chromium.org/developers/contributing-code and read the '
1897 '"Legal" section\n' 1956 '"Legal" section\n'
1898 'If you are a chromite, verify the contributor signed the CLA.') % 1957 'If you are a chromite, verify the contributor signed the CLA.') %
1899 author)] 1958 author)]
1900 return [] 1959 return []
1901 1960
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 results.extend(input_api.canned_checks.CheckTreeIsOpen( 2181 results.extend(input_api.canned_checks.CheckTreeIsOpen(
2123 input_api, 2182 input_api,
2124 output_api, 2183 output_api,
2125 json_url='http://chromium-status.appspot.com/current?format=json')) 2184 json_url='http://chromium-status.appspot.com/current?format=json'))
2126 2185
2127 results.extend(input_api.canned_checks.CheckChangeHasBugField( 2186 results.extend(input_api.canned_checks.CheckChangeHasBugField(
2128 input_api, output_api)) 2187 input_api, output_api))
2129 results.extend(input_api.canned_checks.CheckChangeHasDescription( 2188 results.extend(input_api.canned_checks.CheckChangeHasDescription(
2130 input_api, output_api)) 2189 input_api, output_api))
2131 return results 2190 return results
OLDNEW
« no previous file with comments | « no previous file | content/common/OWNERS » ('j') | content/common/OWNERS » ('J')

Powered by Google App Engine
This is Rietveld 408576698