| # Copyright 2012 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Top-level presubmit script for Chromium. |
| |
| See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts/ |
| for more details about the presubmit API built into depot_tools. |
| """ |
| |
| from typing import Callable |
| from typing import Optional |
| from typing import Sequence |
| from typing import Tuple |
| from dataclasses import dataclass |
| |
| PRESUBMIT_VERSION = '2.0.0' |
| |
| |
| _EXCLUDED_PATHS = ( |
| # Generated file |
| (r"chrome/android/webapk/shell_apk/src/org/chromium" |
| r"/webapk/lib/runtime_library/IWebApkApi.java"), |
| # File needs to write to stdout to emulate a tool it's replacing. |
| r"chrome/updater/mac/keystone/ksadmin.mm", |
| # Generated file. |
| (r"^components/variations/proto/devtools/" |
| r"client_variations.js"), |
| # These are video files, not typescript. |
| r"^media/test/data/.*.ts", |
| r"^native_client_sdksrc/build_tools/make_rules.py", |
| r"^native_client_sdk/src/build_tools/make_simple.py", |
| r"^native_client_sdk/src/tools/.*.mk", |
| r"^net/tools/spdyshark/.*", |
| r"^skia/.*", |
| r"^third_party/blink/.*", |
| r"^third_party/breakpad/.*", |
| # sqlite is an imported third party dependency. |
| r"^third_party/sqlite/.*", |
| r"^v8/.*", |
| r".*MakeFile$", |
| r".+_autogen\.h$", |
| r".+_pb2(_grpc)?\.py$", |
| r".+/pnacl_shim\.c$", |
| r"^gpu/config/.*_list_json\.cc$", |
| r"tools/md_browser/.*\.css$", |
| # Test pages for Maps telemetry tests. |
| r"tools/perf/page_sets/maps_perf_test.*", |
| # Test pages for WebRTC telemetry tests. |
| r"tools/perf/page_sets/webrtc_cases.*", |
| # Test file compared with generated output. |
| r"tools/polymer/tests/html_to_wrapper/.*.html.ts$", |
| # Third-party dependency frozen at a fixed version. |
| r"chrome/test/data/webui/chromeos/chai_v4.js$", |
| ) |
| |
| _EXCLUDED_SET_NO_PARENT_PATHS = ( |
| # It's for historical reasons that blink isn't a top level directory, where |
| # it would be allowed to have "set noparent" to avoid top level owners |
| # accidentally +1ing changes. |
| 'third_party/blink/OWNERS', |
| ) |
| |
| |
| # Fragment of a regular expression that matches C++ and Objective-C++ |
| # implementation files. |
| _IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$' |
| |
| |
| # Fragment of a regular expression that matches C++ and Objective-C++ |
| # header files. |
| _HEADER_EXTENSIONS = r'\.(h|hpp|hxx)$' |
| |
| |
| # Paths with sources that don't use //base. |
| _NON_BASE_DEPENDENT_PATHS = ( |
| r"^chrome/browser/browser_switcher/bho/", |
| r"^tools/win/", |
| ) |
| |
| |
| # Regular expression that matches code only used for test binaries |
| # (best effort). |
| _TEST_CODE_EXCLUDED_PATHS = ( |
| r'.*/(fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS, |
| # Test support files, like: |
| # foo_test_support.cc |
| # bar_test_util_linux.cc (suffix) |
| # baz_test_base.cc |
| r'.+_test_(base|support|util)(_[a-z]+)?%s' % _IMPLEMENTATION_EXTENSIONS, |
| # Test suite files, like: |
| # foo_browsertest.cc |
| # bar_unittest_mac.cc (suffix) |
| # baz_unittests.cc (plural) |
| r'.+_(api|browser|eg|int|perf|pixel|unit|ui)?test(s)?(_[a-z]+)?%s' % |
| _IMPLEMENTATION_EXTENSIONS, |
| r'.+_(fuzz|fuzzer)(_[a-z]+)?%s' % _IMPLEMENTATION_EXTENSIONS, |
| r'.+sync_service_impl_harness%s' % _IMPLEMENTATION_EXTENSIONS, |
| r'.*/(test|tool(s)?)/.*', |
| # content_shell is used for running content_browsertests. |
| r'content/shell/.*', |
| # Web test harness. |
| r'content/web_test/.*', |
| # Non-production example code. |
| r'mojo/examples/.*', |
| # Launcher for running iOS tests on the simulator. |
| r'testing/iossim/iossim\.mm$', |
| # EarlGrey app side code for tests. |
| r'ios/.*_app_interface\.mm$', |
| # Views Examples code |
| r'ui/views/examples/.*', |
| # Chromium Codelab |
| r'codelabs/*' |
| ) |
| |
| _THIRD_PARTY_EXCEPT_BLINK = 'third_party/(?!blink/)' |
| |
| _TEST_ONLY_WARNING = ( |
| 'You might be calling functions intended only for testing from\n' |
| 'production code. If you are doing this from inside another method\n' |
| 'named as *ForTesting(), then consider exposing things to have tests\n' |
| 'make that same call directly.\n' |
| 'If that is not possible, you may put a comment on the same line with\n' |
| ' // IN-TEST \n' |
| 'to tell the PRESUBMIT script that the code is inside a *ForTesting()\n' |
| 'method and can be ignored. Do not do this inside production code.\n' |
| 'The android-binary-size trybot will block if the method exists in the\n' |
| 'release apk.\n' |
| 'Note: this warning might be a false positive (crbug.com/1196548).') |
| |
| |
| @dataclass |
| class BanRule: |
| # String pattern. If the pattern begins with a slash, the pattern will be |
| # treated as a regular expression instead. |
| pattern: str |
| # Explanation as a sequence of strings. Each string in the sequence will be |
| # printed on its own line. |
| explanation: Tuple[str, ...] |
| # Whether or not to treat this ban as a fatal error. If unspecified, |
| # defaults to true. |
| treat_as_error: Optional[bool] = None |
| # Paths that should be excluded from the ban check. Each string is a regular |
| # expression that will be matched against the path of the file being checked |
| # relative to the root of the source tree. |
| excluded_paths: Optional[Sequence[str]] = None |
| |
| |
| _BANNED_JAVA_IMPORTS : Sequence[BanRule] = ( |
| BanRule( |
| 'import java.net.URI;', |
| ( |
| 'Use org.chromium.url.GURL instead of java.net.URI, where possible.', |
| ), |
| excluded_paths=( |
| (r'net/android/javatests/src/org/chromium/net/' |
| 'AndroidProxySelectorTest\.java'), |
| r'components/cronet/', |
| r'third_party/robolectric/local/', |
| ), |
| ), |
| BanRule( |
| 'import android.annotation.TargetApi;', |
| ( |
| 'Do not use TargetApi, use @androidx.annotation.RequiresApi instead. ' |
| 'RequiresApi ensures that any calls are guarded by the appropriate ' |
| 'SDK_INT check. See https://crbug.com/1116486.', |
| ), |
| ), |
| BanRule( |
| 'import androidx.test.rule.ActivityTestRule;', |
| ( |
| 'Do not use ActivityTestRule, use ' |
| 'org.chromium.base.test.BaseActivityTestRule instead.', |
| ), |
| excluded_paths=( |
| 'components/cronet/', |
| ), |
| ), |
| BanRule( |
| 'import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;', |
| ( |
| 'Do not use VectorDrawableCompat, use getResources().getDrawable() to ' |
| 'avoid extra indirections. Please also add trace event as the call ' |
| 'might take more than 20 ms to complete.', |
| ), |
| ), |
| ) |
| |
| _BANNED_JAVA_FUNCTIONS : Sequence[BanRule] = ( |
| BanRule( |
| 'StrictMode.allowThreadDiskReads()', |
| ( |
| 'Prefer using StrictModeContext.allowDiskReads() to using StrictMode ' |
| 'directly.', |
| ), |
| False, |
| ), |
| BanRule( |
| 'StrictMode.allowThreadDiskWrites()', |
| ( |
| 'Prefer using StrictModeContext.allowDiskWrites() to using StrictMode ' |
| 'directly.', |
| ), |
| False, |
| ), |
| BanRule( |
| '.waitForIdleSync()', |
| ( |
| 'Do not use waitForIdleSync as it masks underlying issues. There is ' |
| 'almost always something else you should wait on instead.', |
| ), |
| False, |
| ), |
| BanRule( |
| r'/(?<!\bsuper\.)(?<!\bIntent )\bregisterReceiver\(', |
| ( |
| 'Do not call android.content.Context.registerReceiver (or an override) ' |
| 'directly. Use one of the wrapper methods defined in ' |
| 'org.chromium.base.ContextUtils, such as ' |
| 'registerProtectedBroadcastReceiver, ' |
| 'registerExportedBroadcastReceiver, or ' |
| 'registerNonExportedBroadcastReceiver. See their documentation for ' |
| 'which one to use.', |
| ), |
| True, |
| excluded_paths=( |
| r'.*Test[^a-z]', |
| r'third_party/', |
| 'base/android/java/src/org/chromium/base/ContextUtils.java', |
| 'chromecast/browser/android/apk/src/org/chromium/chromecast/shell/BroadcastReceiverScope.java', |
| ), |
| ), |
| BanRule( |
| r'/(?:extends|new)\s*(?:android.util.)?Property<[A-Za-z.]+,\s*(?:Integer|Float)>', |
| ( |
| 'Do not use Property<..., Integer|Float>, but use FloatProperty or ' |
| 'IntProperty because it will avoid unnecessary autoboxing of ' |
| 'primitives.', |
| ), |
| ), |
| BanRule( |
| 'requestLayout()', |
| ( |
| 'Layouts can be expensive. Prefer using ViewUtils.requestLayout(), ' |
| 'which emits a trace event with additional information to help with ' |
| 'scroll jank investigations. See http://crbug.com/1354176.', |
| ), |
| False, |
| excluded_paths=( |
| 'ui/android/java/src/org/chromium/ui/base/ViewUtils.java', |
| ), |
| ), |
| BanRule( |
| 'ProfileManager.getLastUsedRegularProfile()', |
| ( |
| 'Prefer passing in the Profile reference instead of relying on the ' |
| 'static getLastUsedRegularProfile() call. Only top level entry points ' |
| '(e.g. Activities) should call this method. Otherwise, the Profile ' |
| 'should either be passed in explicitly or retreived from an existing ' |
| 'entity with a reference to the Profile (e.g. WebContents).', |
| ), |
| False, |
| excluded_paths=( |
| r'.*Test[A-Z]?.*\.java', |
| ), |
| ), |
| BanRule( |
| r'/(ResourcesCompat|getResources\(\))\.getDrawable\(\)', |
| ( |
| 'getDrawable() can be expensive. If you have a lot of calls to ' |
| 'GetDrawable() or your code may introduce janks, please put your calls ' |
| 'inside a trace().', |
| ), |
| False, |
| excluded_paths=( |
| r'.*Test[A-Z]?.*\.java', |
| ), |
| ), |
| BanRule( |
| r'/RecordHistogram\.getHistogram(ValueCount|TotalCount|Samples)ForTesting\(', |
| ( |
| 'Raw histogram counts are easy to misuse; for example they don\'t reset ' |
| 'between batched tests. Use HistogramWatcher to check histogram records ' |
| 'instead.', |
| ), |
| False, |
| excluded_paths=( |
| 'base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java', |
| 'base/test/android/javatests/src/org/chromium/base/test/util/HistogramWatcher.java', |
| ), |
| ), |
| ) |
| |
| _BANNED_JAVASCRIPT_FUNCTIONS : Sequence [BanRule] = ( |
| BanRule( |
| r'/\bchrome\.send\b', |
| ( |
| 'The use of chrome.send is disallowed in Chrome (context: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/security/handling-messages-from-web-content.md).', |
| 'Please use mojo instead for new webuis. https://docs.google.com/document/d/1RF-GSUoveYa37eoyZ9EhwMtaIwoW7Z88pIgNZ9YzQi4/edit#heading=h.gkk22wgk6wff', |
| ), |
| True, |
| ( |
| r'^(?!ash\/webui).+', |
| # TODO(crbug.com/1385601): pre-existing violations still need to be |
| # cleaned up. |
| 'ash/webui/common/resources/cr.m.js', |
| 'ash/webui/common/resources/multidevice_setup/multidevice_setup_browser_proxy.js', |
| 'ash/webui/common/resources/quick_unlock/lock_screen_constants.ts', |
| 'ash/webui/common/resources/smb_shares/smb_browser_proxy.js', |
| 'ash/webui/connectivity_diagnostics/resources/connectivity_diagnostics.ts', |
| 'ash/webui/diagnostics_ui/resources/diagnostics_browser_proxy.ts', |
| 'ash/webui/multidevice_debug/resources/logs.js', |
| 'ash/webui/multidevice_debug/resources/webui.js', |
| 'ash/webui/projector_app/resources/annotator/trusted/annotator_browser_proxy.js', |
| 'ash/webui/projector_app/resources/app/trusted/projector_browser_proxy.js', |
| # TODO(b/301634378): Remove violation exception once Scanning App |
| # migrated off usage of `chrome.send`. |
| 'ash/webui/scanning/resources/scanning_browser_proxy.ts', |
| ), |
| ), |
| ) |
| |
| _BANNED_OBJC_FUNCTIONS : Sequence[BanRule] = ( |
| BanRule( |
| 'addTrackingRect:', |
| ( |
| 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is' |
| 'prohibited. Please use CrTrackingArea instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| False, |
| ), |
| BanRule( |
| r'/NSTrackingArea\W', |
| ( |
| 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea', |
| 'instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| False, |
| ), |
| BanRule( |
| 'convertPointFromBase:', |
| ( |
| 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.', |
| 'Please use |convertPoint:(point) fromView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| 'convertPointToBase:', |
| ( |
| 'The use of -[NSView convertPointToBase:] is almost certainly wrong.', |
| 'Please use |convertPoint:(point) toView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| 'convertRectFromBase:', |
| ( |
| 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.', |
| 'Please use |convertRect:(point) fromView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| 'convertRectToBase:', |
| ( |
| 'The use of -[NSView convertRectToBase:] is almost certainly wrong.', |
| 'Please use |convertRect:(point) toView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| 'convertSizeFromBase:', |
| ( |
| 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.', |
| 'Please use |convertSize:(point) fromView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| 'convertSizeToBase:', |
| ( |
| 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.', |
| 'Please use |convertSize:(point) toView:nil| instead.', |
| 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', |
| ), |
| True, |
| ), |
| BanRule( |
| r"/\s+UTF8String\s*]", |
| ( |
| 'The use of -[NSString UTF8String] is dangerous as it can return null', |
| 'even if |canBeConvertedToEncoding:NSUTF8StringEncoding| returns YES.', |
| 'Please use |SysNSStringToUTF8| instead.', |
| ), |
| True, |
| excluded_paths = ( |
| '^third_party/ocmock/OCMock/', |
| ), |
| ), |
| BanRule( |
| r'__unsafe_unretained', |
| ( |
| 'The use of __unsafe_unretained is almost certainly wrong, unless', |
| 'when interacting with NSFastEnumeration or NSInvocation.', |
| 'Please use __weak in files build with ARC, nothing otherwise.', |
| ), |
| False, |
| ), |
| BanRule( |
| 'freeWhenDone:NO', |
| ( |
| 'The use of "freeWhenDone:NO" with the NoCopy creation of ', |
| 'Foundation types is prohibited.', |
| ), |
| True, |
| ), |
| BanRule( |
| 'This file requires ARC support.', |
| ( |
| 'ARC compilation is default in Chromium; do not add boilerplate to ', |
| 'files that require ARC.', |
| ), |
| True, |
| ), |
| ) |
| |
| _BANNED_IOS_OBJC_FUNCTIONS = ( |
| BanRule( |
| r'/\bTEST[(]', |
| ( |
| 'TEST() macro should not be used in Objective-C++ code as it does not ', |
| 'drain the autorelease pool at the end of the test. Use TEST_F() ', |
| 'macro instead with a fixture inheriting from PlatformTest (or a ', |
| 'typedef).' |
| ), |
| True, |
| ), |
| BanRule( |
| r'/\btesting::Test\b', |
| ( |
| 'testing::Test should not be used in Objective-C++ code as it does ', |
| 'not drain the autorelease pool at the end of the test. Use ', |
| 'PlatformTest instead.' |
| ), |
| True, |
| ), |
| BanRule( |
| ' systemImageNamed:', |
| ( |
| '+[UIImage systemImageNamed:] should not be used to create symbols.', |
| 'Instead use a wrapper defined in:', |
| 'ios/chrome/browser/shared/ui/symbols/symbol_helpers.h' |
| ), |
| True, |
| excluded_paths=( |
| 'ios/chrome/browser/shared/ui/symbols/symbol_helpers.mm', |
| 'ios/chrome/common', |
| # App extensions have restricted dependencies and thus can't use the |
| # wrappers. |
| '^ios/chrome/\w+_extension/', |
| ), |
| ), |
| ) |
| |
| _BANNED_IOS_EGTEST_FUNCTIONS : Sequence[BanRule] = ( |
| BanRule( |
| r'/\bEXPECT_OCMOCK_VERIFY\b', |
| ( |
| 'EXPECT_OCMOCK_VERIFY should not be used in EarlGrey tests because ', |
| 'it is meant for GTests. Use [mock verify] instead.' |
| ), |
| True, |
| ), |
| ) |
| |
| _BANNED_CPP_FUNCTIONS: Sequence[BanRule] = ( |
| BanRule( |
| '%#0', |
| ( |
| 'Zero-padded values that use "#" to add prefixes don\'t exhibit ', |
| 'consistent behavior, since the prefix is not prepended for zero ', |
| 'values. Use "0x%0..." instead.', |
| ), |
| False, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\busing namespace ', |
| ( |
| 'Using directives ("using namespace x") are banned by the Google Style', |
| 'Guide ( http://google.github.io/styleguide/cppguide.html#Namespaces ).', |
| 'Explicitly qualify symbols or use using declarations ("using x::foo").', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| # Make sure that gtest's FRIEND_TEST() macro is not used; the |
| # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be |
| # used instead since that allows for FLAKY_ and DISABLED_ prefixes. |
| BanRule( |
| 'FRIEND_TEST(', |
| ( |
| 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include', |
| 'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.', |
| ), |
| False, |
| excluded_paths=( |
| "base/gtest_prod_util.h", |
| "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/gtest_prod_util.h", |
| ), |
| ), |
| BanRule( |
| 'setMatrixClip', |
| ( |
| 'Overriding setMatrixClip() is prohibited; ', |
| 'the base function is deprecated. ', |
| ), |
| True, |
| (), |
| ), |
| BanRule( |
| 'SkRefPtr', |
| ('The use of SkRefPtr is prohibited. ', 'Please use sk_sp<> instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'SkAutoRef', |
| ('The indirect use of SkRefPtr via SkAutoRef is prohibited. ', |
| 'Please use sk_sp<> instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'SkAutoTUnref', |
| ('The use of SkAutoTUnref is dangerous because it implicitly ', |
| 'converts to a raw pointer. Please use sk_sp<> instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'SkAutoUnref', |
| ('The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ', |
| 'because it implicitly converts to a raw pointer. ', |
| 'Please use sk_sp<> instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| r'/HANDLE_EINTR\(.*close', |
| ('HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file', |
| 'descriptor will be closed, and it is incorrect to retry the close.', |
| 'Either call close directly and ignore its return value, or wrap close', |
| 'in IGNORE_EINTR to use its return value. See http://crbug.com/269623' |
| ), |
| True, |
| (), |
| ), |
| BanRule( |
| r'/IGNORE_EINTR\((?!.*close)', |
| ( |
| 'IGNORE_EINTR is only valid when wrapping close. To wrap other system', |
| 'calls, use HANDLE_EINTR. See http://crbug.com/269623', |
| ), |
| True, |
| ( |
| # Files that #define IGNORE_EINTR. |
| r'^base/posix/eintr_wrapper\.h$', |
| r'^ppapi/tests/test_broker\.cc$', |
| ), |
| ), |
| BanRule( |
| r'/v8::Extension\(', |
| ( |
| 'Do not introduce new v8::Extensions into the code base, use', |
| 'gin::Wrappable instead. See http://crbug.com/334679', |
| ), |
| True, |
| (r'extensions/renderer/safe_builtins\.*', ), |
| ), |
| BanRule( |
| '#pragma comment(lib,', |
| ('Specify libraries to link with in build files and not in the source.', |
| ), |
| True, |
| ( |
| r'^base/third_party/symbolize/.*', |
| r'^third_party/abseil-cpp/.*', |
| ), |
| ), |
| BanRule( |
| r'/base::SequenceChecker\b', |
| ('Consider using SEQUENCE_CHECKER macros instead of the class directly.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| r'/base::ThreadChecker\b', |
| ('Consider using THREAD_CHECKER macros instead of the class directly.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| r'/\b(?!(Sequenced|SingleThread))\w*TaskRunner::(GetCurrentDefault|CurrentDefaultHandle)', |
| ( |
| 'It is not allowed to call these methods from the subclasses ', |
| 'of Sequenced or SingleThread task runners.', |
| ), |
| True, |
| (), |
| ), |
| BanRule( |
| r'/(Time(|Delta|Ticks)|ThreadTicks)::FromInternalValue|ToInternalValue', |
| ( |
| 'base::TimeXXX::FromInternalValue() and ToInternalValue() are', |
| 'deprecated (http://crbug.com/634507). Please avoid converting away', |
| 'from the Time types in Chromium code, especially if any math is', |
| 'being done on time values. For interfacing with platform/library', |
| 'APIs, use base::Time::(From,To)DeltaSinceWindowsEpoch() or', |
| 'base::{TimeDelta::In}Microseconds(), or one of the other type', |
| 'converter methods instead. For faking TimeXXX values (for unit', |
| 'testing only), use TimeXXX() + Microseconds(N). For', |
| 'other use cases, please contact base/time/OWNERS.', |
| ), |
| False, |
| excluded_paths=( |
| "base/time/time.h", |
| "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/time/time.h", |
| ), |
| ), |
| BanRule( |
| 'CallJavascriptFunctionUnsafe', |
| ( |
| "Don't use CallJavascriptFunctionUnsafe() in new code. Instead, use", |
| 'AllowJavascript(), OnJavascriptAllowed()/OnJavascriptDisallowed(),', |
| 'and CallJavascriptFunction(). See https://goo.gl/qivavq.', |
| ), |
| False, |
| ( |
| r'^content/browser/webui/web_ui_impl\.(cc|h)$', |
| r'^content/public/browser/web_ui\.h$', |
| r'^content/public/test/test_web_ui\.(cc|h)$', |
| ), |
| ), |
| BanRule( |
| 'leveldb::DB::Open', |
| ( |
| 'Instead of leveldb::DB::Open() use leveldb_env::OpenDB() from', |
| 'third_party/leveldatabase/env_chromium.h. It exposes databases to', |
| "Chrome's tracing, making their memory usage visible.", |
| ), |
| True, |
| (r'^third_party/leveldatabase/.*\.(cc|h)$', ), |
| ), |
| BanRule( |
| 'leveldb::NewMemEnv', |
| ( |
| 'Instead of leveldb::NewMemEnv() use leveldb_chrome::NewMemEnv() from', |
| 'third_party/leveldatabase/leveldb_chrome.h. It exposes environments', |
| "to Chrome's tracing, making their memory usage visible.", |
| ), |
| True, |
| (r'^third_party/leveldatabase/.*\.(cc|h)$', ), |
| ), |
| BanRule( |
| 'RunLoop::QuitCurrent', |
| ( |
| 'Please migrate away from RunLoop::QuitCurrent*() methods. Use member', |
| 'methods of a specific RunLoop instance instead.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'base::ScopedMockTimeMessageLoopTaskRunner', |
| ( |
| 'ScopedMockTimeMessageLoopTaskRunner is deprecated. Prefer', |
| 'TaskEnvironment::TimeSource::MOCK_TIME. There are still a', |
| 'few cases that may require a ScopedMockTimeMessageLoopTaskRunner', |
| '(i.e. mocking the main MessageLoopForUI in browser_tests), but check', |
| 'with gab@ first if you think you need it)', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'std::regex', |
| ( |
| 'Using std::regex adds unnecessary binary size to Chrome. Please use', |
| 're2::RE2 instead (crbug.com/755321)', |
| ), |
| True, |
| [ |
| # Abseil's benchmarks never linked into chrome. |
| 'third_party/abseil-cpp/.*_benchmark.cc', |
| ], |
| ), |
| BanRule( |
| r'/\bstd::sto(i|l|ul|ll|ull)\b', |
| ( |
| 'std::sto{i,l,ul,ll,ull}() use exceptions to communicate results. ', |
| 'Use base::StringTo[U]Int[64]() instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::sto(f|d|ld)\b', |
| ( |
| 'std::sto{f,d,ld}() use exceptions to communicate results. ', |
| 'For locale-independent values, e.g. reading numbers from disk', |
| 'profiles, use base::StringToDouble().', |
| 'For user-visible values, parse using ICU.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::to_string\b', |
| ( |
| 'std::to_string() is locale dependent and slower than alternatives.', |
| 'For locale-independent strings, e.g. writing numbers to disk', |
| 'profiles, use base::NumberToString().', |
| 'For user-visible strings, use base::FormatNumber() and', |
| 'the related functions in base/i18n/number_formatting.h.', |
| ), |
| True, |
| [ |
| # TODO(crbug.com/335672557): Please do not add to this list. Existing |
| # uses should removed. |
| "third_party/blink/renderer/core/css/parser/css_proto_converter.cc", |
| "third_party/blink/renderer/core/editing/ime/edit_context.cc", |
| "third_party/blink/renderer/platform/graphics/bitmap_image_test.cc", |
| "tools/binary_size/libsupersize/viewer/caspian/diff_test.cc", |
| "tools/binary_size/libsupersize/viewer/caspian/tree_builder_test.cc", |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| r'/#include <(cctype|ctype\.h|cwctype|wctype.h)>', |
| ( |
| '<cctype>/<ctype.h>/<cwctype>/<wctype.h> are banned. Use', |
| '"third_party/abseil-cpp/absl/strings/ascii.h" instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::shared_ptr\b', |
| ('std::shared_ptr is banned. Use scoped_refptr instead.', ), |
| True, |
| [ |
| # Needed for interop with third-party library. |
| '^third_party/blink/renderer/core/typed_arrays/array_buffer/' + |
| 'array_buffer_contents\.(cc|h)', |
| '^third_party/blink/renderer/core/typed_arrays/dom_array_buffer\.cc', |
| '^third_party/blink/renderer/bindings/core/v8/' + |
| 'v8_wasm_response_extensions.cc', |
| '^gin/array_buffer\.(cc|h)', |
| '^gin/per_isolate_data\.(cc|h)', |
| '^chrome/services/sharing/nearby/', |
| # Needed for interop with third-party library libunwindstack. |
| '^base/profiler/libunwindstack_unwinder_android\.(cc|h)', |
| '^base/profiler/native_unwinder_android_memory_regions_map_impl.(cc|h)', |
| # Needed for interop with third-party boringssl cert verifier |
| '^third_party/boringssl/', |
| '^net/cert/', |
| '^net/tools/cert_verify_tool/', |
| '^services/cert_verifier/', |
| '^components/certificate_transparency/', |
| '^components/media_router/common/providers/cast/certificate/', |
| # gRPC provides some C++ libraries that use std::shared_ptr<>. |
| '^chromeos/ash/services/libassistant/grpc/', |
| '^chromecast/cast_core/grpc', |
| '^chromecast/cast_core/runtime/browser', |
| '^ios/chrome/test/earl_grey/chrome_egtest_plugin_client\.(mm|h)', |
| # Fuchsia provides C++ libraries that use std::shared_ptr<>. |
| '^base/fuchsia/.*\.(cc|h)', |
| '.*fuchsia.*test\.(cc|h)', |
| # Clang plugins have different build config. |
| '^tools/clang/plugins/', |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::weak_ptr\b', |
| ('std::weak_ptr is banned. Use base::WeakPtr instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\blong long\b', |
| ('long long is banned. Use [u]int64_t instead.', ), |
| False, # Only a warning since it is already used. |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\b(absl|std)::any\b', |
| ( |
| '{absl,std}::any are banned due to incompatibility with the component ', |
| 'build.', |
| ), |
| True, |
| # Not an error in third party folders, though it probably should be :) |
| [_THIRD_PARTY_EXCEPT_BLINK], |
| ), |
| BanRule( |
| r'/\bstd::bind\b', |
| ( |
| 'std::bind() is banned because of lifetime risks. Use ', |
| 'base::Bind{Once,Repeating}() instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| (r'/\bstd::(?:' |
| r'linear_congruential_engine|mersenne_twister_engine|' |
| r'subtract_with_carry_engine|discard_block_engine|' |
| r'independent_bits_engine|shuffle_order_engine|' |
| r'minstd_rand0?|mt19937(_64)?|ranlux(24|48)(_base)?|knuth_b|' |
| r'default_random_engine|' |
| r'random_device|' |
| r'seed_seq' |
| r')\b'), |
| ( |
| 'STL random number engines and generators are banned. Use the ', |
| 'helpers in base/rand_util.h instead, e.g. base::RandBytes() or ', |
| 'base::RandomBitGenerator.' |
| '', |
| 'Please reach out to cxx@chromium.org if the base APIs are ', |
| 'insufficient for your needs.', |
| ), |
| True, |
| [ |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # Various tools which build outside of Chrome. |
| r'testing/libfuzzer', |
| r'testing/perf/confidence', |
| r'tools/android/io_benchmark/', |
| # Fuzzers are allowed to use standard library random number generators |
| # since fuzzing speed + reproducibility is important. |
| r'tools/ipc_fuzzer/', |
| r'.+_fuzzer\.cc$', |
| r'.+_fuzzertest\.cc$', |
| # TODO(https://crbug.com/1380528): These are all unsanctioned uses of |
| # the standard library's random number generators, and should be |
| # migrated to the //base equivalent. |
| r'ash/ambient/model/ambient_topic_queue\.cc', |
| r'base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest\.cc', |
| r'base/ranges/algorithm_unittest\.cc', |
| r'base/test/launcher/test_launcher\.cc', |
| r'cc/metrics/video_playback_roughness_reporter_unittest\.cc', |
| r'chrome/browser/apps/app_service/metrics/website_metrics\.cc', |
| r'chrome/browser/ash/power/auto_screen_brightness/monotone_cubic_spline_unittest\.cc', |
| r'chrome/browser/ash/printing/zeroconf_printer_detector_unittest\.cc', |
| r'chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest\.cc', |
| r'chrome/browser/nearby_sharing/contacts/nearby_share_contacts_sorter_unittest\.cc', |
| r'chrome/browser/privacy_budget/mesa_distribution_unittest\.cc', |
| r'chrome/browser/web_applications/test/web_app_test_utils\.cc', |
| r'chrome/browser/web_applications/test/web_app_test_utils\.cc', |
| r'chrome/browser/win/conflicts/module_blocklist_cache_util_unittest\.cc', |
| r'chromeos/ash/components/memory/userspace_swap/swap_storage_unittest\.cc', |
| r'chromeos/ash/components/memory/userspace_swap/userspace_swap\.cc', |
| r'components/metrics/metrics_state_manager\.cc', |
| r'components/omnibox/browser/history_quick_provider_performance_unittest\.cc', |
| r'components/zucchini/disassembler_elf_unittest\.cc', |
| r'content/browser/webid/federated_auth_request_impl\.cc', |
| r'content/browser/webid/federated_auth_request_impl\.cc', |
| r'media/cast/test/utility/udp_proxy\.h', |
| r'sql/recover_module/module_unittest\.cc', |
| r'components/search_engines/template_url_prepopulate_data.cc', |
| # Do not add new entries to this list. If you have a use case which is |
| # not satisfied by the current APIs (i.e. you need an explicitly-seeded |
| # sequence, or stability of some sort is required), please contact |
| # cxx@chromium.org. |
| ], |
| ), |
| BanRule( |
| r'/\b(absl,std)::bind_front\b', |
| ('{absl,std}::bind_front() are banned. Use base::Bind{Once,Repeating}() ' |
| 'instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bABSL_FLAG\b', |
| ('ABSL_FLAG is banned. Use base::CommandLine instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\babsl::c_', |
| ( |
| 'Abseil container utilities are banned. Use base/ranges/algorithm.h ', |
| 'instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\babsl::FixedArray\b', |
| ('absl::FixedArray is banned. Use base::FixedArray instead.', ), |
| True, |
| [ |
| # base::FixedArray provides canonical access. |
| r'^base/types/fixed_array.h', |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| ], |
| ), |
| BanRule( |
| r'/\babsl::FunctionRef\b', |
| ('absl::FunctionRef is banned. Use base::FunctionRef instead.', ), |
| True, |
| [ |
| # base::Bind{Once,Repeating} references absl::FunctionRef to disallow |
| # interoperability. |
| r'^base/functional/bind_internal\.h', |
| # base::FunctionRef is implemented on top of absl::FunctionRef. |
| r'^base/functional/function_ref.*\..+', |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| ], |
| ), |
| BanRule( |
| r'/\babsl::(Insecure)?BitGen\b', |
| ('absl random number generators are banned. Use the helpers in ' |
| 'base/rand_util.h instead, e.g. base::RandBytes() or ', |
| 'base::RandomBitGenerator.'), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| pattern= |
| r'/\babsl::(optional|nullopt|make_optional)\b', |
| explanation=('absl::optional is banned. Use std::optional instead.', ), |
| treat_as_error=True, |
| excluded_paths=[ |
| _THIRD_PARTY_EXCEPT_BLINK, |
| ]), |
| BanRule( |
| r'/(\babsl::Span\b|#include <span>|\bstd::span\b)', |
| ( |
| 'absl::Span and std::span are banned. Use base::span instead.', |
| ), |
| True, |
| [ |
| # Included for conversions between base and std. |
| r'base/containers/span.h', |
| # Test base::span<> compatibility against std::span<>. |
| r'base/containers/span_unittest.cc', |
| # //base/numerics can't use base or absl. So it uses std. |
| r'base/numerics/.*' |
| |
| # Needed to use QUICHE API. |
| r'android_webview/browser/ip_protection/.*', |
| r'chrome/browser/ip_protection/.*', |
| r'components/ip_protection/.*', |
| r'net/third_party/quiche/overrides/quiche_platform_impl/quiche_stack_trace_impl\.*', |
| r'services/network/web_transport\.cc', |
| |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| ], |
| ), |
| BanRule( |
| r'/\babsl::StatusOr\b', |
| ('absl::StatusOr is banned. Use base::expected instead.', ), |
| True, |
| [ |
| # Needed to use liburlpattern API. |
| r'components/url_pattern/.*', |
| r'services/network/shared_dictionary/simple_url_pattern_matcher\.cc', |
| r'third_party/blink/renderer/core/url_pattern/.*', |
| r'third_party/blink/renderer/modules/manifest/manifest_parser\.cc', |
| |
| # Needed to use QUICHE API. |
| r'android_webview/browser/ip_protection/.*', |
| r'chrome/browser/ip_protection/.*', |
| r'components/ip_protection/.*', |
| |
| # Needed to use MediaPipe API. |
| r'components/media_effects/.*\.cc', |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| r'/\babsl::(StrSplit|StrJoin|StrCat|StrAppend|Substitute|StrContains)\b', |
| ('Abseil string utilities are banned. Use base/strings instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\babsl::(Mutex|CondVar|Notification|Barrier|BlockingCounter)\b', |
| ( |
| 'Abseil synchronization primitives are banned. Use', |
| 'base/synchronization instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\babsl::(Duration|Time|TimeZone|CivilDay)\b', |
| ('Abseil\'s time library is banned. Use base/time instead.', ), |
| True, |
| [ |
| # Needed to use QUICHE API. |
| r'android_webview/browser/ip_protection/.*', |
| r'chrome/browser/ip_protection/.*', |
| r'components/ip_protection/.*', |
| |
| # Needed to integrate with //third_party/nearby |
| r'components/cross_device/nearby/system_clock.cc', |
| _THIRD_PARTY_EXCEPT_BLINK # Not an error in third_party folders. |
| ], |
| ), |
| BanRule( |
| r'/#include <chrono>', |
| ('<chrono> is banned. Use base/time instead.', ), |
| True, |
| [ |
| # Not an error in third_party folders: |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # This uses openscreen API depending on std::chrono. |
| "components/openscreen_platform/task_runner.cc", |
| ]), |
| BanRule( |
| r'/#include <exception>', |
| ('Exceptions are banned and disabled in Chromium.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::function\b', |
| ('std::function is banned. Use base::{Once,Repeating}Callback instead.', |
| ), |
| True, |
| [ |
| # Has tests that template trait helpers don't unintentionally match |
| # std::function. |
| r'base/functional/callback_helpers_unittest\.cc', |
| # Required to implement interfaces from the third-party perfetto |
| # library. |
| r'base/tracing/perfetto_task_runner\.cc', |
| r'base/tracing/perfetto_task_runner\.h', |
| # Needed for interop with the third-party nearby library type |
| # location::nearby::connections::ResultCallback. |
| 'chrome/services/sharing/nearby/nearby_connections_conversions\.cc' |
| # Needed for interop with the internal libassistant library. |
| 'chromeos/ash/services/libassistant/callback_utils\.h', |
| # Needed for interop with Fuchsia fidl APIs. |
| 'fuchsia_web/webengine/browser/context_impl_browsertest\.cc', |
| 'fuchsia_web/webengine/browser/cookie_manager_impl_unittest\.cc', |
| 'fuchsia_web/webengine/browser/media_player_impl_unittest\.cc', |
| # Required to interop with interfaces from the third-party ChromeML |
| # library API. |
| 'services/on_device_model/ml/chrome_ml_api\.h', |
| 'services/on_device_model/ml/on_device_model_executor\.cc', |
| 'services/on_device_model/ml/on_device_model_executor\.h', |
| # Required to interop with interfaces from the third-party perfetto |
| # library. |
| 'services/tracing/public/cpp/perfetto/custom_event_recorder\.cc', |
| 'services/tracing/public/cpp/perfetto/perfetto_traced_process\.cc', |
| 'services/tracing/public/cpp/perfetto/perfetto_traced_process\.h', |
| 'services/tracing/public/cpp/perfetto/perfetto_tracing_backend\.cc', |
| 'services/tracing/public/cpp/perfetto/producer_client\.cc', |
| 'services/tracing/public/cpp/perfetto/producer_client\.h', |
| 'services/tracing/public/cpp/perfetto/producer_test_utils\.cc', |
| 'services/tracing/public/cpp/perfetto/producer_test_utils\.h', |
| # Required for interop with the third-party webrtc library. |
| 'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.cc', |
| 'third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl\.h', |
| # TODO(https://crbug.com/1364577): Various uses that should be |
| # migrated to something else. |
| # Should use base::OnceCallback or base::RepeatingCallback. |
| 'base/allocator/dispatcher/initializer_unittest\.cc', |
| 'chrome/browser/ash/accessibility/speech_monitor\.cc', |
| 'chrome/browser/ash/accessibility/speech_monitor\.h', |
| 'chrome/browser/ash/login/ash_hud_login_browsertest\.cc', |
| 'chromecast/base/observer_unittest\.cc', |
| 'chromecast/browser/cast_web_view\.h', |
| 'chromecast/public/cast_media_shlib\.h', |
| 'device/bluetooth/floss/exported_callback_manager\.h', |
| 'device/bluetooth/floss/floss_dbus_client\.h', |
| 'device/fido/cable/v2_handshake_unittest\.cc', |
| 'device/fido/pin\.cc', |
| 'services/tracing/perfetto/test_utils\.h', |
| # Should use base::FunctionRef. |
| 'chrome/browser/media/webrtc/test_stats_dictionary\.cc', |
| 'chrome/browser/media/webrtc/test_stats_dictionary\.h', |
| 'chromeos/ash/services/libassistant/device_settings_controller\.cc', |
| 'components/browser_ui/client_certificate/android/ssl_client_certificate_request\.cc', |
| 'components/gwp_asan/client/sampling_malloc_shims_unittest\.cc', |
| 'content/browser/font_unique_name_lookup/font_unique_name_lookup_unittest\.cc', |
| # Does not need std::function at all. |
| 'components/omnibox/browser/autocomplete_result\.cc', |
| 'device/fido/win/webauthn_api\.cc', |
| 'media/audio/alsa/alsa_util\.cc', |
| 'media/remoting/stream_provider\.h', |
| 'sql/vfs_wrapper\.cc', |
| # TODO(https://crbug.com/1364585): Remove usage and exception list |
| # entries. |
| 'extensions/renderer/api/automation/automation_internal_custom_bindings\.cc', |
| 'extensions/renderer/api/automation/automation_internal_custom_bindings\.h', |
| # TODO(https://crbug.com/1364579): Remove usage and exception list |
| # entry. |
| 'ui/views/controls/focus_ring\.h', |
| |
| # Various pre-existing uses in //tools that is low-priority to fix. |
| 'tools/binary_size/libsupersize/viewer/caspian/diff\.cc', |
| 'tools/binary_size/libsupersize/viewer/caspian/model\.cc', |
| 'tools/binary_size/libsupersize/viewer/caspian/model\.h', |
| 'tools/binary_size/libsupersize/viewer/caspian/tree_builder\.h', |
| 'tools/clang/base_bind_rewriters/BaseBindRewriters\.cpp', |
| |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| r'/#include <X11/', |
| ('Do not use Xlib. Use xproto (from //ui/gfx/x:xproto) instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::ratio\b', |
| ('std::ratio is banned by the Google Style Guide.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::aligned_alloc\b', |
| ( |
| 'std::aligned_alloc() is not yet allowed (crbug.com/1412818). Use ', |
| 'base::AlignedAlloc() instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/#include <(barrier|latch|semaphore|stop_token)>', |
| ('The thread support library is banned. Use base/synchronization ' |
| 'instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::execution::(par|seq)\b', |
| ('std::execution::(par|seq) is banned; they do not fit into ' |
| ' Chrome\'s threading model, and libc++ doesn\'t have full ' |
| 'support.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], |
| ), |
| BanRule( |
| r'/\bstd::bit_cast\b', |
| ('std::bit_cast is banned; use base::bit_cast instead for values and ' |
| 'standard C++ casting when pointers are involved.', ), |
| True, |
| [ |
| # Don't warn in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # //base/numerics can't use base or absl. |
| r'base/numerics/.*' |
| ], |
| ), |
| BanRule( |
| r'/\bstd::(c8rtomb|mbrtoc8)\b', |
| ('std::c8rtomb() and std::mbrtoc8() are banned.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bchar8_t|std::u8string\b', |
| ( |
| 'char8_t and std::u8string are not yet allowed. Can you use [unsigned]', |
| ' char and std::string instead?', |
| ), |
| True, |
| [ |
| # The demangler does not use this type but needs to know about it. |
| 'base/third_party/symbolize/demangle\.cc', |
| # Don't warn in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| r'/(\b(co_await|co_return|co_yield)\b|#include <coroutine>)', |
| ('Coroutines are not yet allowed (https://crbug.com/1403840).', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/^\s*(export\s|import\s+["<:\w]|module(;|\s+[:\w]))', |
| ('Modules are disallowed for now due to lack of toolchain support.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\[\[(\w*::)?no_unique_address\]\]', |
| ( |
| '[[no_unique_address]] does not work as expected on Windows ', |
| '(https://crbug.com/1414621). Use NO_UNIQUE_ADDRESS instead.', |
| ), |
| True, |
| [ |
| # NO_UNIQUE_ADDRESS / PA_NO_UNIQUE_ADDRESS provide canonical access. |
| r'^base/compiler_specific\.h', |
| r'^base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/compiler_specific\.h', |
| # Not an error in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK, |
| ], |
| ), |
| BanRule( |
| r'/#include <format>', |
| ('<format> is not yet allowed. Use base::StringPrintf() instead.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| pattern='std::views', |
| explanation=( |
| 'Use of std::views is banned in Chrome. If you need this ' |
| 'functionality, please contact cxx@chromium.org.', |
| ), |
| treat_as_error=True, |
| excluded_paths=[ |
| # Don't warn in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| # Ban everything except specifically allowlisted constructs. |
| pattern=r'/std::ranges::(?!' + '|'.join(( |
| # From https://en.cppreference.com/w/cpp/ranges: |
| # Range access |
| 'begin', |
| 'end', |
| 'cbegin', |
| 'cend', |
| 'rbegin', |
| 'rend', |
| 'crbegin', |
| 'crend', |
| 'size', |
| 'ssize', |
| 'empty', |
| 'data', |
| 'cdata', |
| # Range primitives |
| 'iterator_t', |
| 'const_iterator_t', |
| 'sentinel_t', |
| 'const_sentinel_t', |
| 'range_difference_t', |
| 'range_size_t', |
| 'range_value_t', |
| 'range_reference_t', |
| 'range_const_reference_t', |
| 'range_rvalue_reference_t', |
| 'range_common_reference_t', |
| # Dangling iterator handling |
| 'dangling', |
| 'borrowed_iterator_t', |
| # Banned: borrowed_subrange_t |
| # Range concepts |
| 'range', |
| 'borrowed_range', |
| 'sized_range', |
| 'view', |
| 'input_range', |
| 'output_range', |
| 'forward_range', |
| 'bidirectional_range', |
| 'random_access_range', |
| 'contiguous_range', |
| 'common_range', |
| 'viewable_range', |
| 'constant_range', |
| # Banned: Views |
| # Banned: Range factories |
| # Banned: Range adaptors |
| # Incidentally listed on |
| # https://en.cppreference.com/w/cpp/header/ranges: |
| 'enable_borrowed_range', |
| 'enable_view', |
| # From https://en.cppreference.com/w/cpp/algorithm/ranges: |
| # Constrained algorithms: non-modifying sequence operations |
| 'all_of', |
| 'any_of', |
| 'none_of', |
| 'for_each', |
| 'for_each_n', |
| 'count', |
| 'count_if', |
| 'mismatch', |
| 'equal', |
| 'lexicographical_compare', |
| 'find', |
| 'find_if', |
| 'find_if_not', |
| 'find_end', |
| 'find_first_of', |
| 'adjacent_find', |
| 'search', |
| 'search_n', |
| # Constrained algorithms: modifying sequence operations |
| 'copy', |
| 'copy_if', |
| 'copy_n', |
| 'copy_backward', |
| 'move', |
| 'move_backward', |
| 'fill', |
| 'fill_n', |
| 'transform', |
| 'generate', |
| 'generate_n', |
| 'remove', |
| 'remove_if', |
| 'remove_copy', |
| 'remove_copy_if', |
| 'replace', |
| 'replace_if', |
| 'replace_copy', |
| 'replace_copy_if', |
| 'swap_ranges', |
| 'reverse', |
| 'reverse_copy', |
| 'rotate', |
| 'rotate_copy', |
| 'shuffle', |
| 'sample', |
| 'unique', |
| 'unique_copy', |
| # Constrained algorithms: partitioning operations |
| 'is_partitioned', |
| 'partition', |
| 'partition_copy', |
| 'stable_partition', |
| 'partition_point', |
| # Constrained algorithms: sorting operations |
| 'is_sorted', |
| 'is_sorted_until', |
| 'sort', |
| 'partial_sort', |
| 'partial_sort_copy', |
| 'stable_sort', |
| 'nth_element', |
| # Constrained algorithms: binary search operations (on sorted ranges) |
| 'lower_bound', |
| 'upper_bound', |
| 'binary_search', |
| 'equal_range', |
| # Constrained algorithms: set operations (on sorted ranges) |
| 'merge', |
| 'inplace_merge', |
| 'includes', |
| 'set_difference', |
| 'set_intersection', |
| 'set_symmetric_difference', |
| 'set_union', |
| # Constrained algorithms: heap operations |
| 'is_heap', |
| 'is_heap_until', |
| 'make_heap', |
| 'push_heap', |
| 'pop_heap', |
| 'sort_heap', |
| # Constrained algorithms: minimum/maximum operations |
| 'max', |
| 'max_element', |
| 'min', |
| 'min_element', |
| 'minmax', |
| 'minmax_element', |
| 'clamp', |
| # Constrained algorithms: permutation operations |
| 'is_permutation', |
| 'next_permutation', |
| 'prev_premutation', |
| # Constrained uninitialized memory algorithms |
| 'uninitialized_copy', |
| 'uninitialized_copy_n', |
| 'uninitialized_fill', |
| 'uninitialized_fill_n', |
| 'uninitialized_move', |
| 'uninitialized_move_n', |
| 'uninitialized_default_construct', |
| 'uninitialized_default_construct_n', |
| 'uninitialized_value_construct', |
| 'uninitialized_value_construct_n', |
| 'destroy', |
| 'destroy_n', |
| 'destroy_at', |
| 'construct_at', |
| # Return types |
| 'in_fun_result', |
| 'in_in_result', |
| 'in_out_result', |
| 'in_in_out_result', |
| 'in_out_out_result', |
| 'min_max_result', |
| 'in_found_result', |
| # From https://en.cppreference.com/w/cpp/iterator |
| 'advance', |
| 'distance', |
| 'next', |
| 'prev', |
| )) + r')\w+', |
| explanation=( |
| 'Use of range views and associated helpers is banned in Chrome. ' |
| 'If you need this functionality, please contact cxx@chromium.org.', |
| ), |
| treat_as_error=True, |
| excluded_paths=[ |
| # Don't warn in third_party folders. |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], |
| ), |
| BanRule( |
| r'/#include <regex>', |
| ('<regex> is not allowed. Use third_party/re2 instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/#include <source_location>', |
| ('<source_location> is not yet allowed. Use base/location.h instead.', |
| ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bstd::to_address\b', |
| ( |
| 'std::to_address is banned because it is not guaranteed to be', |
| 'SFINAE-compatible. Use base::to_address from base/types/to_address.h', |
| 'instead.', |
| ), |
| True, |
| [ |
| # Needed in base::to_address implementation. |
| r'base/types/to_address.h', |
| _THIRD_PARTY_EXCEPT_BLINK |
| ], # Not an error in third_party folders. |
| ), |
| BanRule( |
| r'/#include <syncstream>', |
| ('<syncstream> is banned.', ), |
| True, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. |
| ), |
| BanRule( |
| r'/\bRunMessageLoop\b', |
| ('RunMessageLoop is deprecated, use RunLoop instead.', ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'RunAllPendingInMessageLoop()', |
| ( |
| "Prefer RunLoop over RunAllPendingInMessageLoop, please contact gab@", |
| "if you're convinced you need this.", |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'RunAllPendingInMessageLoop(BrowserThread', |
| ( |
| 'RunAllPendingInMessageLoop is deprecated. Use RunLoop for', |
| 'BrowserThread::UI, BrowserTaskEnvironment::RunIOThreadUntilIdle', |
| 'for BrowserThread::IO, and prefer RunLoop::QuitClosure to observe', |
| 'async events instead of flushing threads.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| r'MessageLoopRunner', |
| ('MessageLoopRunner is deprecated, use RunLoop instead.', ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'GetDeferredQuitTaskForRunLoop', |
| ( |
| "GetDeferredQuitTaskForRunLoop shouldn't be needed, please contact", |
| "gab@ if you found a use case where this is the only solution.", |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'sqlite3_initialize(', |
| ( |
| 'Instead of calling sqlite3_initialize(), depend on //sql, ', |
| '#include "sql/initialize.h" and use sql::EnsureSqliteInitialized().', |
| ), |
| True, |
| ( |
| r'^sql/initialization\.(cc|h)$', |
| r'^third_party/sqlite/.*\.(c|cc|h)$', |
| ), |
| ), |
| BanRule( |
| 'CREATE VIEW', |
| ( |
| 'SQL views are disabled in Chromium feature code', |
| 'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-views', |
| ), |
| True, |
| ( |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # sql/ itself uses views when using memory-mapped IO. |
| r'^sql/.*', |
| # Various performance tools that do not build as part of Chrome. |
| r'^infra/.*', |
| r'^tools/perf.*', |
| r'.*perfetto.*', |
| ), |
| ), |
| BanRule( |
| 'CREATE VIRTUAL TABLE', |
| ( |
| 'SQL virtual tables are disabled in Chromium feature code', |
| 'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-virtual-tables', |
| ), |
| True, |
| ( |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # sql/ itself uses virtual tables in the recovery module and tests. |
| r'^sql/.*', |
| # TODO(https://crbug.com/695592): Remove once WebSQL is deprecated. |
| r'third_party/blink/web_tests/storage/websql/.*' |
| # Various performance tools that do not build as part of Chrome. |
| r'^tools/perf.*', |
| r'.*perfetto.*', |
| ), |
| ), |
| BanRule( |
| 'std::random_shuffle', |
| ('std::random_shuffle is deprecated in C++14, and removed in C++17. Use', |
| 'base::RandomShuffle instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'ios/web/public/test/http_server', |
| ('web::HTTPserver is deprecated use net::EmbeddedTestServer instead.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'GetAddressOf', |
| ('Improper use of Microsoft::WRL::ComPtr<T>::GetAddressOf() has been ', |
| 'implicated in a few leaks. ReleaseAndGetAddressOf() is safe but ', |
| 'operator& is generally recommended. So always use operator& instead. ', |
| 'See http://crbug.com/914910 for more conversion guidance.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'SHFileOperation', |
| ('SHFileOperation was deprecated in Windows Vista, and there are less ', |
| 'complex functions to achieve the same goals. Use IFileOperation for ', |
| 'any esoteric actions instead.'), |
| True, |
| (), |
| ), |
| BanRule( |
| 'StringFromGUID2', |
| ('StringFromGUID2 introduces an unnecessary dependency on ole32.dll.', |
| 'Use base::win::WStringFromGUID instead.'), |
| True, |
| (r'/base/win/win_util_unittest.cc', ), |
| ), |
| BanRule( |
| 'StringFromCLSID', |
| ('StringFromCLSID introduces an unnecessary dependency on ole32.dll.', |
| 'Use base::win::WStringFromGUID instead.'), |
| True, |
| (r'/base/win/win_util_unittest.cc', ), |
| ), |
| BanRule( |
| 'kCFAllocatorNull', |
| ( |
| 'The use of kCFAllocatorNull with the NoCopy creation of ', |
| 'CoreFoundation types is prohibited.', |
| ), |
| True, |
| (), |
| ), |
| BanRule( |
| 'mojo::ConvertTo', |
| ('mojo::ConvertTo and TypeConverter are deprecated. Please consider', |
| 'StructTraits / UnionTraits / EnumTraits / ArrayTraits / MapTraits /', |
| 'StringTraits if you would like to convert between custom types and', |
| 'the wire format of mojom types.'), |
| False, |
| ( |
| r'^fuchsia_web/webengine/browser/url_request_rewrite_rules_manager\.cc$', |
| r'^fuchsia_web/webengine/url_request_rewrite_type_converters\.cc$', |
| r'^third_party/blink/.*\.(cc|h)$', |
| r'^content/renderer/.*\.(cc|h)$', |
| ), |
| ), |
| BanRule( |
| 'GetInterfaceProvider', |
| ('InterfaceProvider is deprecated.', |
| 'Please use ExecutionContext::GetBrowserInterfaceBroker and overrides', |
| 'or Platform::GetBrowserInterfaceBroker.'), |
| False, |
| (), |
| ), |
| BanRule( |
| 'CComPtr', |
| ('New code should use Microsoft::WRL::ComPtr from wrl/client.h as a ', |
| 'replacement for CComPtr from ATL. See http://crbug.com/5027 for more ', |
| 'details.'), |
| False, |
| (), |
| ), |
| BanRule( |
| r'/\b(IFACE|STD)METHOD_?\(', |
| ('IFACEMETHOD() and STDMETHOD() make code harder to format and read.', |
| 'Instead, always use IFACEMETHODIMP in the declaration.'), |
| False, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule( |
| 'set_owned_by_client', |
| ('set_owned_by_client is deprecated.', |
| 'views::View already owns the child views by default. This introduces ', |
| 'a competing ownership model which makes the code difficult to reason ', |
| 'about. See http://crbug.com/1044687 for more details.'), |
| False, |
| (), |
| ), |
| BanRule( |
| 'RemoveAllChildViewsWithoutDeleting', |
| ('RemoveAllChildViewsWithoutDeleting is deprecated.', |
| 'This method is deemed dangerous as, unless raw pointers are re-added,', |
| 'calls to this method introduce memory leaks.'), |
| False, |
| (), |
| ), |
| BanRule( |
| r'/\bTRACE_EVENT_ASYNC_', |
| ( |
| 'Please use TRACE_EVENT_NESTABLE_ASYNC_.. macros instead', |
| 'of TRACE_EVENT_ASYNC_.. (crbug.com/1038710).', |
| ), |
| False, |
| ( |
| r'^base/trace_event/.*', |
| r'^base/tracing/.*', |
| ), |
| ), |
| BanRule( |
| r'/\bbase::debug::DumpWithoutCrashingUnthrottled[(][)]', |
| ( |
| 'base::debug::DumpWithoutCrashingUnthrottled() does not throttle', |
| 'dumps and may spam crash reports. Consider if the throttled', |
| 'variants suffice instead.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'RoInitialize', |
| ('Improper use of [base::win]::RoInitialize() has been implicated in a ', |
| 'few COM initialization leaks. Use base::win::ScopedWinrtInitializer ', |
| 'instead. See http://crbug.com/1197722 for more information.'), |
| True, |
| ( |
| r'^base/win/scoped_winrt_initializer\.cc$', |
| r'^third_party/abseil-cpp/absl/.*', |
| ), |
| ), |
| BanRule( |
| r'base::Watchdog', |
| ( |
| 'base::Watchdog is deprecated because it creates its own thread.', |
| 'Instead, manually start a timer on a SequencedTaskRunner.', |
| ), |
| False, |
| (), |
| ), |
| BanRule( |
| 'base::Passed', |
| ('Do not use base::Passed. It is a legacy helper for capturing ', |
| 'move-only types with base::BindRepeating, but invoking the ', |
| 'resulting RepeatingCallback moves the captured value out of ', |
| 'the callback storage, and subsequent invocations may pass the ', |
| 'value in a valid but undefined state. Prefer base::BindOnce().', |
| 'See http://crbug.com/1326449 for context.'), |
| False, |
| ( |
| # False positive, but it is also fine to let bind internals reference |
| # base::Passed. |
| r'^base[\\/]functional[\\/]bind\.h', |
| r'^base[\\/]functional[\\/]bind_internal\.h', |
| ), |
| ), |
| BanRule( |
| r'base::Feature k', |
| ('Please use BASE_DECLARE_FEATURE() or BASE_FEATURE() instead of ', |
| 'directly declaring/defining features.'), |
| True, |
| [ |
| # Implements BASE_DECLARE_FEATURE(). |
| r'^base/feature_list\.h', |
| ], |
| ), |
| BanRule( |
| r'/\bchartorune\b', |
| ('chartorune is not memory-safe, unless you can guarantee the input ', |
| 'string is always null-terminated. Otherwise, please use charntorune ', |
| 'from libphonenumber instead.'), |
| True, |
| [ |
| _THIRD_PARTY_EXCEPT_BLINK, |
| # Exceptions to this rule should have a fuzzer. |
| ], |
| ), |
| BanRule( |
| r'/\b#include "base/atomicops\.h"\b', |
| ('Do not use base::subtle atomics, but std::atomic, which are simpler ' |
| 'to use, have better understood, clearer and richer semantics, and are ' |
| 'harder to mis-use. See details in base/atomicops.h.', ), |
| False, |
| [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. |
| ), |
| BanRule(r'CrossThreadPersistent<', ( |
| 'Do not use blink::CrossThreadPersistent, but ' |
| 'blink::CrossThreadHandle. It is harder to mis-use.', 'More info: ' |
| 'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs', |
| 'Please contact platform-architecture-dev@ before adding new instances.' |
| ), False, []), |
| BanRule(r'CrossThreadWeakPersistent<', ( |
| 'Do not use blink::CrossThreadWeakPersistent, but ' |
| 'blink::CrossThreadWeakHandle. It is harder to mis-use.', 'More info: ' |
| 'https://docs.google.com/document/d/1GIT0ysdQ84sGhIo1r9EscF_fFt93lmNVM_q4vvHj2FQ/edit#heading=h.3e4d6y61tgs', |
| 'Please contact platform-architecture-dev@ before adding new instances.' |
| ), False, []), |
| BanRule(r'objc/objc.h', ( |
| 'Do not include <objc/objc.h>. It defines away ARC lifetime ' |
| 'annotations, and is thus dangerous.', |
| 'Please use the pimpl pattern; search for `ObjCStorage` for examples.', |
| 'For further reading on how to safely mix C++ and Obj-C, see', |
| 'https://chromium.googlesource.com/chromium/src/+/main/docs/mac/mixing_cpp_and_objc.md' |
| ), True, []), |
| BanRule( |
| r'/#include <filesystem>', |
| ('libc++ <filesystem> is banned per the Google C++ styleguide.', ), |
| True, |
| # This fuzzing framework is a standalone open source project and |
| # cannot rely on Chromium base. |
| (r'third_party/centipede'), |
| ), |
| BanRule( |
| r'TopDocument()', |
| ('TopDocument() does not work correctly with out-of-process iframes. ' |
| 'Please do not introduce new uses.', ), |
| True, |
| ( |
| # TODO(crbug.com/617677): Remove all remaining uses. |
| r'^third_party/blink/renderer/core/dom/document\.cc', |
| r'^third_party/blink/renderer/core/dom/document\.h', |
| r'^third_party/blink/renderer/core/dom/element\.cc', |
| r'^third_party/blink/renderer/core/exported/web_disallow_transition_scope_test\.cc', |
| r'^third_party/blink/renderer/core/exported/web_document_test\.cc', |
| r'^third_party/blink/renderer/core/html/html_anchor_element\.cc', |
| r'^third_party/blink/renderer/core/html/html_dialog_element\.cc', |
| r'^third_party/blink/renderer/core/html/html_element\.cc', |
| r'^third_party/blink/renderer/core/html/html_frame_owner_element\.cc', |
| r'^third_party/blink/renderer/core/html/media/video_wake_lock\.cc', |
| r'^third_party/blink/renderer/core/loader/anchor_element_interaction_tracker\.cc', |
| r'^third_party/blink/renderer/core/page/scrolling/root_scroller_controller\.cc', |
| r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.cc', |
| r'^third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller\.h', |
| r'^third_party/blink/renderer/core/script/classic_pending_script\.cc', |
| r'^third_party/blink/renderer/core/script/script_loader\.cc', |
| ), |
| ), |
| BanRule( |
| pattern=r'base::raw_ptr<', |
| explanation=('Do not use base::raw_ptr, use raw_ptr.', ), |
| treat_as_error=True, |
| excluded_paths=( |
| '^base/', |
| '^tools/', |
| ), |
| ), |
| BanRule( |
| pattern=r'base:raw_ref<', |
| explanation=('Do not use base::raw_ref, use raw_ref.', ), |
| treat_as_error=True, |
| excluded_paths=( |
| '^base/', |
| '^tools/', |
| ), |
| ), |
| BanRule( |
| pattern=r'/raw_ptr<[^;}]*\w{};', |
| explanation=( |
| 'Do not use {} for raw_ptr initialization, use = nullptr instead.', |
| ), |
| treat_as_error=True, |
| excluded_paths=( |
| '^base/', |
| '^tools/', |
| ), |
| ), |
| BanRule( |
| pattern=r'/#include "base/allocator/.*/raw_' |
| r'(ptr|ptr_cast|ptr_exclusion|ref).h"', |
| explanation=( |
| 'Please include the corresponding facade headers:', |
| '- #include "base/memory/raw_ptr.h"', |
| '- #include "base/memory/raw_ptr_cast.h"', |
| '- #include "base/memory/raw_ptr_exclusion.h"', |
| '- #include "base/memory/raw_ref.h"', |
| ), |
| treat_as_error=True, |
| excluded_paths=( |
| '^base/', |
| '^tools/', |
| ), |
| ), |
| BanRule( |
| pattern=r'ContentSettingsType::COOKIES', |
| explanation= |
| ('Do not use ContentSettingsType::COOKIES to check whether cookies are ' |
| 'supported in the provided context. Instead rely on the ' |
| 'content_settings::CookieSettings API. If you are using ' |
| 'ContentSettingsType::COOKIES to check the user preference setting ' |
| 'specifically, disregard this warning.', ), |
| treat_as_error=False, |
| excluded_paths=( |
| '^chrome/browser/ui/content_settings/', |
| '^components/content_settings/', |
| '^services/network/cookie_settings.cc', |
| '.*test.cc', |
| ), |
| ), |
| BanRule( |
| pattern=r'ContentSettingsType::TRACKING_PROTECTION', |
| explanation= |
| ('Do not directly use ContentSettingsType::TRACKING_PROTECTION to check ' |
| 'for tracking protection exceptions. Instead rely on the ' |
| 'privacy_sandbox::TrackingProtectionSettings API.', ), |
| treat_as_error=False, |
| excluded_paths=( |
| '^chrome/browser/ui/content_settings/', |
| '^components/content_settings/', |
| '^components/privacy_sandbox/tracking_protection_settings.cc', |
| '.*test.cc', |
| ), |
| ), |
| BanRule( |
| pattern=r'/\bg_signal_connect', |
| explanation=('Use ScopedGSignal instead of g_signal_connect*()', ), |
| treat_as_error=True, |
| excluded_paths=('^ui/base/glib/scoped_gsignal.h', ), |
| ), |
| BanRule( |
| pattern=r'features::kIsolatedWebApps', |
| explanation=( |
| 'Do not use `features::kIsolatedWebApps` directly to guard Isolated ', |
| 'Web App code. ', |
| 'Use `content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled()` in ', |
| 'the browser process or check the `kEnableIsolatedWebAppsInRenderer` ', |
| 'command line flag in the renderer process.', |
| ), |
| treat_as_error=True, |
| excluded_paths=_TEST_CODE_EXCLUDED_PATHS + |
| ('^chrome/browser/about_flags.cc', |
| '^chrome/browser/web_applications/isolated_web_apps/chrome_content_browser_client_isolated_web_apps_part.cc', |
| '^chrome/browser/ui/startup/bad_flags_prompt.cc', |
| '^content/shell/browser/shell_content_browser_client.cc')), |
| BanRule( |
| pattern=r'features::kIsolatedWebAppDevMode', |
| explanation=( |
| 'Do not use `features::kIsolatedWebAppDevMode` directly to guard code ', |
| 'related to Isolated Web App Developer Mode. ', |
| 'Use `web_app::IsIwaDevModeEnabled()` instead.', |
| ), |
| treat_as_error=True, |
| excluded_paths=_TEST_CODE_EXCLUDED_PATHS + ( |
| '^chrome/browser/about_flags.cc', |
| '^chrome/browser/web_applications/isolated_web_apps/isolated_web_app_features.cc', |
| '^chrome/browser/ui/startup/bad_flags_prompt.cc', |
| )), |
| BanRule( |
| pattern=r'features::kIsolatedWebAppUnmanagedInstall', |
| explanation=( |
| 'Do not use `features::kIsolatedWebAppUnmanagedInstall` directly to ', |
| 'guard code related to unmanaged install flow for Isolated Web Apps. ', |
| 'Use `web_app::IsIwaUnmanagedInstallEnabled()` instead.', |
| ), |
| treat_as_error=True, |
| excluded_paths=_TEST_CODE_EXCLUDED_PATHS + ( |
| '^chrome/browser/about_flags.cc', |
| '^chrome/browser/web_applications/isolated_web_apps/isolated_web_app_features.cc', |
| )), |
| BanRule( |
| pattern='/(CUIAutomation|AccessibleObjectFromWindow)', |
| explanation= |
| ('Direct usage of UIAutomation or IAccessible2 in client code is ' |
| 'discouraged in Chromium, as it is not an assistive technology and ' |
| 'should not rely on accessibility APIs directly. These APIs can ' |
| 'introduce significant performance overhead. However, if you believe ' |
| 'your use case warrants an exception, please discuss it with an ' |
| 'accessibility owner before proceeding. For more information on the ' |
| 'performance implications, see https://docs.google.com/document/d/1jN4itpCe_bDXF0BhFaYwv4xVLsCWkL9eULdzjmLzkuk/edit#heading=h.pwth3nbwdub0.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern=r'/WIDGET_OWNS_NATIVE_WIDGET|' |
| r'NATIVE_WIDGET_OWNS_WIDGET', |
| explanation= |
| ('WIDGET_OWNS_NATIVE_WIDGET and NATIVE_WIDGET_OWNS_WIDGET are in the ' |
| 'process of being deprecated. Consider using the new ' |
| 'CLIENT_OWNS_WIDGET ownership model. Eventually, this will be the only ' |
| 'available ownership model available and the associated enumeration' |
| 'will be removed.', ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='ProfileManager::GetLastUsedProfile', |
| explanation= |
| ('Most code should already be scoped to a Profile. Pass in a Profile* ' |
| 'or retreive from an existing entity with a reference to the Profile ' |
| '(e.g. WebContents).', ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern=(r'/FindBrowserWithUiElementContext|' |
| r'FindBrowserWithTab|' |
| r'FindBrowserWithGroup|' |
| r'FindTabbedBrowser|' |
| r'FindAnyBrowser|' |
| r'FindBrowserWithProfile|' |
| r'FindLastActive|' |
| r'FindBrowserWithActiveWindow'), |
| explanation= |
| ('Most code should already be scoped to a Browser. Pass in a Browser* ' |
| 'or retreive from an existing entity with a reference to the Browser.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='BrowserUserData', |
| explanation= |
| ('Do not use BrowserUserData to store state on a Browser instance. ' |
| 'Instead use BrowserWindowFeatures. BrowserWindowFeatures is ' |
| 'functionally identical but has two benefits: it does not force a ' |
| 'dependency onto class Browser, and lifetime semantics are explicit ' |
| 'rather than implicit. See BrowserUserData header file for more ' |
| 'details.', ), |
| treat_as_error=False, |
| excluded_paths=( |
| # Exclude iOS as the iOS implementation of BrowserUserData is separate |
| # and still in use. |
| '^ios/', |
| ), |
| ), |
| BanRule( |
| pattern=r'UNSAFE_TODO(', |
| explanation= |
| ('Do not use UNSAFE_TODO() to write new unsafe code. Use only when ' |
| 'removing a pre-existing file-wide allow_unsafe_buffers pragma, or ' |
| 'when incrementally converting code off of unsafe interfaces', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern=r'UNSAFE_BUFFERS(', |
| explanation= |
| ('Try to avoid using UNSAFE_BUFFERS() if at all possible. Otherwise, ' |
| 'be sure to justify in a // SAFETY comment why other options are not ' |
| 'available, and why the code is safe.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='BrowserWithTestWindowTest', |
| explanation= |
| ('Do not use BrowserWithTestWindowTest. By instantiating an instance ' |
| 'of class Browser, the test is no longer a unit test but is instead a ' |
| 'browser test. The class BrowserWithTestWindowTest forces production ' |
| 'logic to take on test-only conditionals, which is an anti-pattern. ' |
| 'Features should be performing dependency injection rather than ' |
| 'directly using class Browser. See ' |
| 'docs/chrome_browser_design_principles.md for more details.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='TestWithBrowserView', |
| explanation= |
| ('Do not use TestWithBrowserView. See ' |
| 'docs/chrome_browser_design_principles.md for details. If you want ' |
| 'to write a test that has both a Browser and a BrowserView, create ' |
| 'a browser_test. If you want to write a unit_test, your code must ' |
| 'not reference Browser*.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='RunUntilIdle', |
| explanation= |
| ('Do not RunUntilIdle. If possible, explicitly quit the run loop using ' |
| 'run_loop.Quit() or run_loop.QuitClosure() if completion can be ' |
| 'observed using a lambda or callback. Otherwise, wait for the ' |
| 'condition to be true via base::test::RunUntil().', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern=r'/\bstd::(literals|string_literals|string_view_literals)\b', |
| explanation = ( |
| 'User-defined literals are banned by the Google C++ style guide. ' |
| 'Exceptions are provided in Chrome for string and string_view ' |
| 'literals that embed \\0.', |
| ), |
| treat_as_error=True, |
| excluded_paths=( |
| # Various tests or test helpers that embed NUL in strings or |
| # string_views. |
| r'^ash/components/arc/session/serial_number_util_unittest\.cc', |
| r'^base/strings/string_util_unittest\.cc', |
| r'^base/strings/utf_string_conversions_unittest\.cc', |
| r'^chrome/browser/ash/crosapi/browser_data_back_migrator_unittest\.cc', |
| r'^chrome/browser/ash/crosapi/browser_data_migrator_util_unittest\.cc', |
| r'^chrome/browser/ash/crosapi/move_migrator_unittest\.cc', |
| r'^components/history/core/browser/visit_annotations_database\.cc', |
| r'^components/history/core/browser/visit_annotations_database_unittest\.cc', |
| r'^components/os_crypt/sync/os_crypt_unittest\.cc', |
| r'^components/password_manager/core/browser/credentials_cleaner_unittest\.cc', |
| r'^content/browser/file_system_access/file_system_access_file_writer_impl_unittest\.cc', |
| r'^net/cookies/parsed_cookie_unittest\.cc', |
| r'^third_party/blink/renderer/modules/webcodecs/test_helpers\.cc', |
| r'^third_party/blink/renderer/modules/websockets/websocket_channel_impl_test\.cc', |
| ), |
| ), |
| BanRule( |
| pattern='BUILDFLAG(GOOGLE_CHROME_BRANDING)', |
| explanation= |
| ('Code gated by GOOGLE_CHROME_BRANDING is effectively untested. This ' |
| 'is typically wrong. Valid use cases are glue for private modules ' |
| 'shipped alongside Chrome, and installation-related logic.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='defined(OFFICIAL_BUILD)', |
| explanation= |
| ('Code gated by OFFICIAL_BUILD is effectively untested. This ' |
| 'is typically wrong. One valid use case is low-level code that ' |
| 'handles subtleties related to high-levels of optimizations that come ' |
| 'with OFFICIAL_BUILD.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern='WebContentsDestroyed', |
| explanation= |
| ('Do not use this method. It is invoked half-way through the ' |
| 'destructor of WebContentsImpl and using it often results in crashes ' |
| 'or surprising behavior. Conceptually, this is only necessary by ' |
| 'objects that depend on, but outlive the WebContents. These objects ' |
| 'should instead coordinate with the owner of the WebContents which is ' |
| 'responsible for destroying the WebContents.', |
| ), |
| treat_as_error=False, |
| ), |
| BanRule( |
| pattern=(r'/IS_CHROMEOS_ASH|' |
| r'IS_CHROMEOS_LACROS'), |
| explanation= |
| ('Lacros is deprecated. Please do not use IS_CHROMEOS_ASH and ' |
| 'IS_CHROMEOS_LACROS anymore. Prefer IS_CHROMEOS instead.', |
| ), |
| treat_as_error=False, |
| ), |
| ) |
| |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING = ( |
| 'Used a predicate related to signin::ConsentLevel::kSync which will always ' |
| 'return false in the future (crbug.com/40066949). Prefer using a predicate ' |
| 'that also supports signin::ConsentLevel::kSignin when appropriate. It is ' |
| 'safe to ignore this warning if you are just moving an existing call, or if ' |
| 'you want special handling for users in the legacy state. In doubt, reach ' |
| 'out to //components/sync/OWNERS.', |
| ) |
| |
| # C++ functions related to signin::ConsentLevel::kSync which are deprecated. |
| _DEPRECATED_SYNC_CONSENT_CPP_FUNCTIONS : Sequence[BanRule] = ( |
| BanRule( |
| 'HasSyncConsent', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'CanSyncFeatureStart', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'IsSyncFeatureEnabled', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'IsSyncFeatureActive', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| ) |
| |
| # Java functions related to signin::ConsentLevel::kSync which are deprecated. |
| _DEPRECATED_SYNC_CONSENT_JAVA_FUNCTIONS : Sequence[BanRule] = ( |
| BanRule( |
| 'hasSyncConsent', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'canSyncFeatureStart', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'isSyncFeatureEnabled', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| BanRule( |
| 'isSyncFeatureActive', |
| _DEPRECATED_SYNC_CONSENT_FUNCTION_WARNING, |
| False, |
| ), |
| ) |
| |
| _BANNED_MOJOM_PATTERNS : Sequence[BanRule] = ( |
| BanRule( |
| 'handle<shared_buffer>', |
| ( |
| 'Please use one of the more specific shared memory types instead:', |
| ' mojo_base.mojom.ReadOnlySharedMemoryRegion', |
| ' mojo_base.mojom.WritableSharedMemoryRegion', |
| ' mojo_base.mojom.UnsafeSharedMemoryRegion', |
| ), |
| True, |
| ), |
| ) |
| |
| _IPC_ENUM_TRAITS_DEPRECATED = ( |
| 'You are using IPC_ENUM_TRAITS() in your code. It has been deprecated.\n' |
| 'See http://www.chromium.org/Home/chromium-security/education/' |
| 'security-tips-for-ipc') |
| |
| _LONG_PATH_ERROR = ( |
| 'Some files included in this CL have file names that are too long (> 200' |
| ' characters). If committed, these files will cause issues on Windows. See' |
| ' https://crbug.com/612667 for more details.' |
| ) |
| |
| _JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS = [ |
| r".*/BuildHooksAndroidImpl\.java", |
| r".*/LicenseContentProvider\.java", |
| r".*/PlatformServiceBridgeImpl.java", |
| r".*chrome/android/feed/dummy/.*\.java", |
| ] |
| |
| # List of image extensions that are used as resources in chromium. |
| _IMAGE_EXTENSIONS = ['.svg', '.png', '.webp'] |
| |
| # These paths contain test data and other known invalid JSON files. |
| _KNOWN_TEST_DATA_AND_INVALID_JSON_FILE_PATTERNS = [ |
| r'test/data/', |
| r'testing/buildbot/', |
| r'^components/policy/resources/policy_templates\.json$', |
| r'^third_party/protobuf/', |
| r'^third_party/blink/perf_tests/speedometer.*/resources/todomvc/learn\.json', |
| r'^third_party/blink/renderer/devtools/protocol\.json$', |
| r'^third_party/blink/web_tests/external/wpt/', |
| r'^tools/perf/', |
| r'^tools/traceline/svgui/startup-release.json', |
| # vscode configuration files allow comments |
| r'^tools/vscode/', |
| ] |
| |
| # These are not checked on the public chromium-presubmit trybot. |
| # Add files here that rely on .py files that exists only for target_os="android" |
| # checkouts. |
| _ANDROID_SPECIFIC_PYDEPS_FILES = [ |
| 'chrome/android/features/create_stripped_java_factory.pydeps', |
| ] |
| |
| |
| _GENERIC_PYDEPS_FILES = [ |
| 'android_webview/tools/run_cts.pydeps', |
| 'build/android/apk_operations.pydeps', |
| 'build/android/devil_chromium.pydeps', |
| 'build/android/gyp/aar.pydeps', |
| 'build/android/gyp/aidl.pydeps', |
| 'build/android/gyp/apkbuilder.pydeps', |
| 'build/android/gyp/assert_static_initializers.pydeps', |
| 'build/android/gyp/binary_baseline_profile.pydeps', |
| 'build/android/gyp/bytecode_processor.pydeps', |
| 'build/android/gyp/bytecode_rewriter.pydeps', |
| 'build/android/gyp/check_flag_expectations.pydeps', |
| 'build/android/gyp/compile_java.pydeps', |
| 'build/android/gyp/compile_kt.pydeps', |
| 'build/android/gyp/compile_resources.pydeps', |
| 'build/android/gyp/copy_ex.pydeps', |
| 'build/android/gyp/create_apk_operations_script.pydeps', |
| 'build/android/gyp/create_app_bundle.pydeps', |
| 'build/android/gyp/create_app_bundle_apks.pydeps', |
| 'build/android/gyp/create_bundle_wrapper_script.pydeps', |
| 'build/android/gyp/create_java_binary_script.pydeps', |
| 'build/android/gyp/create_r_java.pydeps', |
| 'build/android/gyp/create_r_txt.pydeps', |
| 'build/android/gyp/create_size_info_files.pydeps', |
| 'build/android/gyp/create_test_apk_wrapper_script.pydeps', |
| 'build/android/gyp/create_ui_locale_resources.pydeps', |
| 'build/android/gyp/dex.pydeps', |
| 'build/android/gyp/dist_aar.pydeps', |
| 'build/android/gyp/filter_zip.pydeps', |
| 'build/android/gyp/flatc_java.pydeps', |
| 'build/android/gyp/gcc_preprocess.pydeps', |
| 'build/android/gyp/generate_linker_version_script.pydeps', |
| 'build/android/gyp/ijar.pydeps', |
| 'build/android/gyp/jacoco_instr.pydeps', |
| 'build/android/gyp/java_cpp_enum.pydeps', |
| 'build/android/gyp/java_cpp_features.pydeps', |
| 'build/android/gyp/java_cpp_strings.pydeps', |
| 'build/android/gyp/java_google_api_keys.pydeps', |
| 'build/android/gyp/jinja_template.pydeps', |
| 'build/android/gyp/lint.pydeps', |
| 'build/android/gyp/merge_manifest.pydeps', |
| 'build/android/gyp/optimize_resources.pydeps', |
| 'build/android/gyp/prepare_resources.pydeps', |
| 'build/android/gyp/process_native_prebuilt.pydeps', |
| 'build/android/gyp/proguard.pydeps', |
| 'build/android/gyp/rename_java_classes.pydeps', |
| 'build/android/gyp/system_image_apks.pydeps', |
| 'build/android/gyp/trace_event_bytecode_rewriter.pydeps', |
| 'build/android/gyp/turbine.pydeps', |
| 'build/android/gyp/unused_resources.pydeps', |
| 'build/android/gyp/validate_static_library_dex_references.pydeps', |
| 'build/android/gyp/write_build_config.pydeps', |
| 'build/android/gyp/write_native_libraries_java.pydeps', |
| 'build/android/gyp/zip.pydeps', |
| 'build/android/incremental_install/generate_android_manifest.pydeps', |
| 'build/android/incremental_install/write_installer_json.pydeps', |
| 'build/android/pylib/results/presentation/test_results_presentation.pydeps', |
| 'build/android/resource_sizes.pydeps', |
| 'build/android/test_runner.pydeps', |
| 'build/android/test_wrapper/logdog_wrapper.pydeps', |
| 'build/protoc_java.pydeps', |
| 'chrome/android/monochrome/scripts/monochrome_python_tests.pydeps', |
| 'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps', |
| 'chrome/test/chromedriver/test/run_py_tests.pydeps', |
| 'chromecast/resource_sizes/chromecast_resource_sizes.pydeps', |
| 'components/cronet/tools/check_combined_proguard_file.pydeps', |
| 'components/cronet/tools/generate_proguard_file.pydeps', |
| 'components/cronet/tools/jar_src.pydeps', |
| 'components/module_installer/android/module_desc_java.pydeps', |
| 'content/public/android/generate_child_service.pydeps', |
| 'fuchsia_web/av_testing/av_sync_tests.pydeps', |
| 'net/tools/testserver/testserver.pydeps', |
| 'testing/scripts/run_isolated_script_test.pydeps', |
| 'testing/merge_scripts/standard_isolated_script_merge.pydeps', |
| 'testing/merge_scripts/standard_gtest_merge.pydeps', |
| 'testing/merge_scripts/code_coverage/merge_results.pydeps', |
| 'testing/merge_scripts/code_coverage/merge_steps.pydeps', |
| 'third_party/android_platform/development/scripts/stack.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/generate_event_interface_names.pydeps', |
| 'third_party/blink/renderer/bindings/scripts/validate_web_idl.pydeps', |
| 'third_party/blink/tools/blinkpy/web_tests/merge_results.pydeps', |
| 'third_party/blink/tools/merge_web_test_results.pydeps', |
| 'tools/binary_size/sizes.pydeps', |
| 'tools/binary_size/supersize.pydeps', |
| 'tools/perf/process_perf_results.pydeps', |
| 'tools/pgo/generate_profile.pydeps', |
| ] |
| |
| |
| _ALL_PYDEPS_FILES = _ANDROID_SPECIFIC_PYDEPS_FILES + _GENERIC_PYDEPS_FILES |
| |
| |
| # Bypass the AUTHORS check for these accounts. |
| _KNOWN_ROBOTS = set( |
| ) | set('%s@appspot.gserviceaccount.com' % s for s in ('findit-for-me', 'luci-bisection') |
| ) | set('%s@developer.gserviceaccount.com' % s for s in ('3su6n15k.default',) |
| ) | set('%s@chops-service-accounts.iam.gserviceaccount.com' % s |
| for s in ('bling-autoroll-builder', 'v8-ci-autoroll-builder', |
| 'wpt-autoroller', 'chrome-weblayer-builder', |
| 'lacros-version-skew-roller', 'skylab-test-cros-roller', |
| 'infra-try-recipes-tester', 'lacros-tracking-roller', |
| 'lacros-sdk-version-roller', 'chrome-automated-expectation', |
| 'chromium-automated-expectation', 'chrome-branch-day', |
| 'chromium-autosharder') |
| ) | set('%s@skia-public.iam.gserviceaccount.com' % s |
| for s in ('chromium-autoroll', 'chromium-release-autoroll') |
| ) | set('%s@skia-corp.google.com.iam.gserviceaccount.com' % s |
| for s in ('chromium-internal-autoroll',) |
| ) | set('%s@system.gserviceaccount.com' % s |
| for s in ('chrome-screen-ai-releaser',) |
| ) | set('%s@owners-cleanup-prod.google.com.iam.gserviceaccount.com' % s |
| for s in ('swarming-tasks',) |
| ) | set('%s@fuchsia-infra.iam.gserviceaccount.com' % s |
| for s in ('global-integration-try-builder', |
| 'global-integration-ci-builder') |
| ) | set('%s@prod.google.com' % s |
| for s in ('chops-security-borg', |
| 'chops-security-cronjobs-cpesuggest')) |
| |
| _INVALID_GRD_FILE_LINE = [ |
| (r'<file lang=.* path=.*', 'Path should come before lang in GRD files.') |
| ] |
| |
| def _IsCPlusPlusFile(input_api, file_path): |
| """Returns True if this file contains C++-like code (and not Python, |
| Go, Java, MarkDown, ...)""" |
| |
| ext = input_api.os_path.splitext(file_path)[1] |
| # This list is compatible with CppChecker.IsCppFile but we should |
| # consider adding ".c" to it. If we do that we can use this function |
| # at more places in the code. |
| return ext in ( |
| '.h', |
| '.cc', |
| '.cpp', |
| '.m', |
| '.mm', |
| ) |
| |
| |
| def _IsCPlusPlusHeaderFile(input_api, file_path): |
| return input_api.os_path.splitext(file_path)[1] == ".h" |
| |
| |
| def _IsJavaFile(input_api, file_path): |
| return input_api.os_path.splitext(file_path)[1] == ".java" |
| |
| |
| def _IsProtoFile(input_api, file_path): |
| return input_api.os_path.splitext(file_path)[1] == ".proto" |
| |
| |
| def _IsXmlOrGrdFile(input_api, file_path): |
| ext = input_api.os_path.splitext(file_path)[1] |
| return ext in ('.grd', '.xml') |
| |
| |
| def _IsMojomFile(input_api, file_path): |
| return input_api.os_path.splitext(file_path)[1] == ".mojom" |
| |
| |
| def CheckNoUpstreamDepsOnClank(input_api, output_api): |
| """Prevent additions of dependencies from the upstream repo on //clank.""" |
| # clank can depend on clank |
| if input_api.change.RepositoryRoot().endswith('clank'): |
| return [] |
| build_file_patterns = [ |
| r'(.+/)?BUILD\.gn', |
| r'.+\.gni', |
| ] |
| excluded_files = [r'build[/\\]config[/\\]android[/\\]config\.gni'] |
| bad_pattern = input_api.re.compile(r'^[^#]*//clank') |
| |
| error_message = 'Disallowed import on //clank in an upstream build file:' |
| |
| def FilterFile(affected_file): |
| return input_api.FilterSourceFile(affected_file, |
| files_to_check=build_file_patterns, |
| files_to_skip=excluded_files) |
| |
| problems = [] |
| for f in input_api.AffectedSourceFiles(FilterFile): |
| local_path = f.LocalPath() |
| for line_number, line in f.ChangedContents(): |
| if (bad_pattern.search(line)): |
| problems.append('%s:%d\n %s' % |
| (local_path, line_number, line.strip())) |
| if problems: |
| return [output_api.PresubmitPromptOrNotify(error_message, problems)] |
| else: |
| return [] |
| |
| |
| def CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api): |
| """Attempts to prevent use of functions intended only for testing in |
| non-testing code. For now this is just a best-effort implementation |
| that ignores header files and may have some false positives. A |
| better implementation would probably need a proper C++ parser. |
| """ |
| # We only scan .cc files and the like, as the declaration of |
| # for-testing functions in header files are hard to distinguish from |
| # calls to such functions without a proper C++ parser. |
| file_inclusion_pattern = [r'.+%s' % _IMPLEMENTATION_EXTENSIONS] |
| |
| base_function_pattern = r'[ :]test::[^\s]+|ForTest(s|ing)?|for_test(s|ing)?' |
| inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % |
| base_function_pattern) |
| comment_pattern = input_api.re.compile(r'//.*(%s)' % base_function_pattern) |
| allowlist_pattern = input_api.re.compile(r'// IN-TEST$') |
| exclusion_pattern = input_api.re.compile( |
| r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % |
| (base_function_pattern, base_function_pattern)) |
| # Avoid a false positive in this case, where the method name, the ::, and |
| # the closing { are all on different lines due to line wrapping. |
| # HelperClassForTesting:: |
| # HelperClassForTesting( |
| # args) |
| # : member(0) {} |
| method_defn_pattern = input_api.re.compile(r'[A-Za-z0-9_]+::$') |
| |
| def FilterFile(affected_file): |
| files_to_skip = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS + |
| input_api.DEFAULT_FILES_TO_SKIP) |
| return input_api.FilterSourceFile( |
| affected_file, |
| files_to_check=file_inclusion_pattern, |
| files_to_skip=files_to_skip) |
| |
| problems = [] |
| for f in input_api.AffectedSourceFiles(FilterFile): |
| local_path = f.LocalPath() |
| in_method_defn = False |
| for line_number, line in f.ChangedContents(): |
| if (inclusion_pattern.search(line) |
| and not comment_pattern.search(line) |
| and not exclusion_pattern.search(line) |
| and not allowlist_pattern.search(line) |
| and not in_method_defn): |
| problems.append('%s:%d\n %s' % |
| (local_path, line_number, line.strip())) |
| in_method_defn = method_defn_pattern.search(line) |
| |
| if problems: |
| return [ |
| output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems) |
| ] |
| else: |
| return [] |
| |
| |
| def CheckNoProductionCodeUsingTestOnlyFunctionsJava(input_api, output_api): |
| """This is a simplified version of |
| CheckNoProductionCodeUsingTestOnlyFunctions for Java files. |
| """ |
| javadoc_start_re = input_api.re.compile(r'^\s*/\*\*') |
| javadoc_end_re = input_api.re.compile(r'^\s*\*/') |
| name_pattern = r'ForTest(s|ing)?' |
| # Describes an occurrence of "ForTest*" inside a // comment. |
| comment_re = input_api.re.compile(r'//.*%s' % name_pattern) |
| # Describes @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) |
| annotation_re = input_api.re.compile(r'@VisibleForTesting\(') |
| # Catch calls. |
| inclusion_re = input_api.re.compile(r'(%s)\s*\(' % name_pattern) |
| # Ignore definitions. (Comments are ignored separately.) |
| exclusion_re = input_api.re.compile(r'(%s)[^;]+\{' % name_pattern) |
| allowlist_re = input_api.re.compile(r'// IN-TEST$') |
| |
| problems = [] |
| sources = lambda x: input_api.FilterSourceFile( |
| x, |
| files_to_skip=(('(?i).*test', r'.*\/junit\/') + input_api. |
| DEFAULT_FILES_TO_SKIP), |
| files_to_check=[r'.*\.java$']) |
| for f in input_api.AffectedFiles(include_deletes=False, |
| file_filter=sources): |
| local_path = f.LocalPath() |
| is_inside_javadoc = False |
| for line_number, line in f.ChangedContents(): |
| if is_inside_javadoc and javadoc_end_re.search(line): |
| is_inside_javadoc = False |
| if not is_inside_javadoc and javadoc_start_re.search(line): |
| is_inside_javadoc = True |
| if is_inside_javadoc: |
| continue |
| if (inclusion_re.search(line) and not comment_re.search(line) |
| and not annotation_re.search(line) |
| and not allowlist_re.search(line) |
| and not exclusion_re.search(line)): |
| problems.append('%s:%d\n %s' % |
| (local_path, line_number, line.strip())) |
| |
| if problems: |
| return [ |
| output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems) |
| ] |
| else: |
| return [] |
| |
| |
| def CheckNoIOStreamInHeaders(input_api, output_api): |
| """Checks to make sure no .h files include <iostream>.""" |
| files = [] |
| pattern = input_api.re.compile(r'^#include\s*<iostream>', |
| input_api.re.MULTILINE) |
| for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): |
| if not f.LocalPath().endswith('.h'): |
| continue |
| contents = input_api.ReadFile(f) |
| if pattern.search(contents): |
| files.append(f) |
| |
| if len(files): |
| return [ |
| output_api.PresubmitError( |
| 'Do not #include <iostream> in header files, since it inserts static ' |
| 'initialization into every file including the header. Instead, ' |
| '#include <ostream>. See http://crbug.com/94794', files) |
| ] |
| return [] |
| |
| |
| def CheckNoStrCatRedefines(input_api, output_api): |
| """Checks no windows headers with StrCat redefined are included directly.""" |
| files = [] |
| files_to_check = (r'.+%s' % _HEADER_EXTENSIONS, |
| r'.+%s' % _IMPLEMENTATION_EXTENSIONS) |
| files_to_skip = (input_api.DEFAULT_FILES_TO_SKIP + |
| _NON_BASE_DEPENDENT_PATHS) |
| sources_filter = lambda f: input_api.FilterSourceFile( |
| f, files_to_check=files_to_check, files_to_skip=files_to_skip) |
| |
| pattern_deny = input_api.re.compile( |
| r'^#include\s*[<"](shlwapi|atlbase|propvarutil|sphelper).h[">]', |
| input_api.re.MULTILINE) |
| pattern_allow = input_api.re.compile( |
| r'^#include\s"base/win/windows_defines.inc"', input_api.re.MULTILINE) |
| for f in input_api.AffectedSourceFiles(sources_filter): |
| contents = input_api.ReadFile(f) |
| if pattern_deny.search( |
| contents) and not pattern_allow.search(contents): |
| files.append(f.LocalPath()) |
| |
| if len(files): |
| return [ |
| output_api.PresubmitError( |
| 'Do not #include shlwapi.h, atlbase.h, propvarutil.h or sphelper.h ' |
| 'directly since they pollute code with StrCat macro. Instead, ' |
| 'include matching header from base/win. See http://crbug.com/856536', |
| files) |
| ] |
| return [] |
| |
| |
| def _CheckNoUNIT_TESTInSourceFiles(input_api, f): |
| problems = [] |
| |
| unit_test_macro = input_api.re.compile( |
| '^\s*#.*(?:ifn?def\s+UNIT_TEST|defined\s*\(?\s*UNIT_TEST\s*\)?)(?:$|\s+)') |
| for line_num, line in f.ChangedContents(): |
| if unit_test_macro.match(line): |
| problems.append(' %s:%d' % (f.LocalPath(), line_num)) |
| |
| return problems |
| |
| |
| def CheckNoUNIT_TESTInSourceFiles(input_api, output_api): |
| """Checks to make sure no source files use UNIT_TEST.""" |
| problems = [] |
| for f in input_api.AffectedFiles(): |
| if (not f.LocalPath().endswith(('.cc', '.mm'))): |
| continue |
| problems.extend( |
| _CheckNoUNIT_TESTInSourceFiles(input_api, f)) |
| |
| if not problems: |
| return [] |
| return [ |
| output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' + |
| '\n'.join(problems)) |
| ] |
| |
| |
| def CheckNoDISABLETypoInTests(input_api, output_api): |
| """Checks to prevent attempts to disable tests with DISABLE_ prefix. |
| |
| This test warns if somebody tries to disable a test with the DISABLE_ prefix |
| instead of DISABLED_. To filter false positives, reports are only generated |
| if a corresponding MAYBE_ line exists. |
| """ |
| problems = [] |
| |
| # The following two patterns are looked for in tandem - is a test labeled |
| # as MAYBE_ followed by a DISABLE_ (instead of the correct DISABLED) |
| maybe_pattern = input_api.re.compile(r'MAYBE_([a-zA-Z0-9_]+)') |
| disable_pattern = input_api.re.compile(r'DISABLE_([a-zA-Z0-9_]+)') |
| |
| # This is for the case that a test is disabled on all platforms. |
| full_disable_pattern = input_api.re.compile( |
| r'^\s*TEST[^(]*\([a-zA-Z0-9_]+,\s*DISABLE_[a-zA-Z0-9_]+\)', |
| input_api.re.MULTILINE) |
| |
| for f in input_api.AffectedFiles(include_deletes=False): |
| if not 'test' in f.LocalPath() or not f.LocalPath().endswith('.cc'): |
| continue |
| |
| # Search for MAYBE_, DISABLE_ pairs. |
| disable_lines = {} # Maps of test name to line number. |
| maybe_lines = {} |
| for line_num, line in f.ChangedContents(): |
| disable_match = disable_pattern.search(line) |
| if disable_match: |
| disable_lines[disable_match.group(1)] = line_num |
| maybe_match = maybe_pattern.search(line) |
| if maybe_match: |
| maybe_lines[maybe_match.group(1)] = line_num |
| |
| # Search for DISABLE_ occurrences within a TEST() macro. |
| disable_tests = set(disable_lines.keys()) |
| maybe_tests = set(maybe_lines.keys()) |
| for test in disable_tests.intersection(maybe_tests): |
| problems.append(' %s:%d' % (f.LocalPath(), disable_lines[test])) |
| |
| contents = input_api.ReadFile(f) |
| full_disable_match = full_disable_pattern.search(contents) |
| if full_disable_match: |
| problems.append(' %s' % f.LocalPath()) |
| |
| if not problems: |
| return [] |
| return [ |
| output_api.PresubmitPromptWarning( |
| 'Attempt to disable a test with DISABLE_ instead of DISABLED_?\n' + |
| '\n'.join(problems)) |
| ] |
| |
| |
| def CheckForgettingMAYBEInTests(input_api, output_api): |
| """Checks to make sure tests disabled conditionally are not missing a |
| corresponding MAYBE_ prefix. |
| """ |
| # Expect at least a lowercase character in the test name. This helps rule out |
| # false positives with macros wrapping the actual tests name. |
| define_maybe_pattern = input_api.re.compile( |
| r'^\#define MAYBE_(?P<test_name>\w*[a-z]\w*)') |
| # The test_maybe_pattern needs to handle all of these forms. The standard: |
| # IN_PROC_TEST_F(SyncTest, MAYBE_Start) { |
| # With a wrapper macro around the test name: |
| # IN_PROC_TEST_F(SyncTest, E2E_ENABLED(MAYBE_Start)) { |
| # And the odd-ball NACL_BROWSER_TEST_f format: |
| # NACL_BROWSER_TEST_F(NaClBrowserTest, SimpleLoad, { |
| # The optional E2E_ENABLED-style is handled with (\w*\()? |
| # The NACL_BROWSER_TEST_F pattern is handled by allowing a trailing comma or |
| # trailing ')'. |
| test_maybe_pattern = ( |
| r'^\s*\w*TEST[^(]*\(\s*\w+,\s*(\w*\()?MAYBE_{test_name}[\),]') |
| suite_maybe_pattern = r'^\s*\w*TEST[^(]*\(\s*MAYBE_{test_name}[\),]' |
| warnings = [] |
| |
| # Read the entire files. We can't just read the affected lines, forgetting to |
| # add MAYBE_ on a change would not show up otherwise. |
| for f in input_api.AffectedFiles(include_deletes=False): |
| if not 'test' in f.LocalPath() or not f.LocalPath().endswith('.cc'): |
| continue |
| contents = input_api.ReadFile(f) |
| lines = contents.splitlines(True) |
| current_position = 0 |
| warning_test_names = set() |
| for line_num, line in enumerate(lines, start=1): |
| current_position += len(line) |
| maybe_match = define_maybe_pattern.search(line) |
| if maybe_match: |
| test_name = maybe_match.group('test_name') |
| # Do not warn twice for the same test. |
| if (test_name in warning_test_names): |
| continue |
| warning_test_names.add(test_name) |
| |
| # Attempt to find the corresponding MAYBE_ test or suite, starting from |
| # the current position. |
| test_match = input_api.re.compile( |
| test_maybe_pattern.format(test_name=test_name), |
| input_api.re.MULTILINE).search(contents, current_position) |
| suite_match = input_api.re.compile( |
| suite_maybe_pattern.format(test_name=test_name), |
| input_api.re.MULTILINE).search(contents, current_position) |
| if not test_match and not suite_match: |
| warnings.append( |
| output_api.PresubmitPromptWarning( |
| '%s:%d found MAYBE_ defined without corresponding test %s' |
| % (f.LocalPath(), line_num, test_name))) |
| return warnings |
| |
| |
| def CheckDCHECK_IS_ONHasBraces(input_api, output_api): |
| """Checks to make sure DCHECK_IS_ON() does not skip the parentheses.""" |
| errors = [] |
| pattern = input_api.re.compile(r'\bDCHECK_IS_ON\b(?!\(\))', |
| input_api.re.MULTILINE) |
| for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): |
| if (not f.LocalPath().endswith(('.cc', '.mm', '.h'))): |
| continue |
| for lnum, line in f.ChangedContents(): |
| if input_api.re.search(pattern, line): |
| errors.append( |
| output_api.PresubmitError(( |
| '%s:%d: Use of DCHECK_IS_ON() must be written as "#if ' |
| + 'DCHECK_IS_ON()", not forgetting the parentheses.') % |
| (f.LocalPath(), lnum))) |
| return errors |
| |
| |
| # TODO(crbug/1138055): Reimplement CheckUmaHistogramChangesOnUpload check in a |
| # more reliable way. See |
| # https://chromium-review.googlesource.com/c/chromium/src/+/2500269 |
| |
| |
| def CheckFlakyTestUsage(input_api, output_api): |
| """Check that FlakyTest annotation is our own instead of the android one""" |
| pattern = input_api.re.compile(r'import android.test.FlakyTest;') |
| files = [] |
| for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): |
| if f.LocalPath().endswith('Test.java'): |
| if pattern.search(input_api.ReadFile(f)): |
| files.append(f) |
| if len(files): |
| return [ |
| output_api.PresubmitError( |
| 'Use org.chromium.base.test.util.FlakyTest instead of ' |
| 'android.test.FlakyTest', files) |
| ] |
| return [] |
| |
| |
| def CheckNoDEPSGIT(input_api, output_api): |
| """Make sure .DEPS.git is never modified manually.""" |
| if any(f.LocalPath().endswith('.DEPS.git') |
| for f in input_api.AffectedFiles()): |
| return [ |
| output_api.PresubmitError( |
| 'Never commit changes to .DEPS.git. This file is maintained by an\n' |
| 'automated system based on what\'s in DEPS and your changes will be\n' |
| 'overwritten.\n' |
| 'See https://sites.google.com/a/chromium.org/dev/developers/how-tos/' |
| 'get-the-code#Rolling_DEPS\n' |
| 'for more information') |
| ] |
| return [] |
| |
| |
| def CheckCrosApiNeedBrowserTest(input_api, output_api): |
| """Check new crosapi should add browser test.""" |
| has_new_crosapi = False |
| has_browser_test = False |
| for f in input_api.AffectedFiles(): |
| path = f.LocalPath() |
| if (path.startswith('chromeos/crosapi/mojom') and |
| _IsMojomFile(input_api, path) and f.Action() == 'A'): |
| has_new_crosapi = True |
| if path.endswith('browsertest.cc') or path.endswith('browser_test.cc'): |
| has_browser_test = True |
| if has_new_crosapi and not has_browser_test: |
| return [ |
| output_api.PresubmitPromptWarning( |
| 'You are adding a new crosapi, but there is no file ends with ' |
| 'browsertest.cc file being added or modified. It is important ' |
| 'to add crosapi browser test coverage to avoid version ' |
| ' skew issues.\n' |
| 'Check //docs/lacros/test_instructions.md for more information.' |
| ) |
| ] |
| return [] |
| |
| |
| def CheckValidHostsInDEPSOnUpload(input_api, output_api): |
| """Checks that DEPS file deps are from allowed_hosts.""" |
| # Run only if DEPS file has been modified to annoy fewer bystanders. |
| if all(f.LocalPath() != 'DEPS' for f in input_api.AffectedFiles()): |
| return [] |
| # Outsource work to gclient verify |
| try: |
| gclient_path = input_api.os_path.join(input_api.PresubmitLocalPath(), |
| 'third_party', 'depot_tools', |
| 'gclient.py') |
| input_api.subprocess.check_output( |
| [input_api.python3_executable, gclient_path, 'verify'], |
| stderr=input_api.subprocess.STDOUT) |
| return [] |
| except input_api.subprocess.CalledProcessError as error: |
| return [ |
| output_api.PresubmitError( |
| 'DEPS file must have only git dependencies.', |
| long_text=error.output) |
| ] |
| |
| |
| def _GetMessageForMatchingType(input_api, affected_file, line_number, line, |
| ban_rule): |
| """Helper method for checking for banned constructs. |
| |
| Returns an string composed of the name of the file, the line number where the |
| match has been found and the additional text passed as |message| in case the |
| target type name matches the text inside the line passed as parameter. |
| """ |
| result = [] |
| |
| # Ignore comments about banned types. |
| if input_api.re.search(r"^ *//", line): |
| return result |
| # A // nocheck comment will bypass this error. |
| if line.endswith(" nocheck"): |
| return result |
| |
| matched = False |
| if ban_rule.pattern[0:1] == '/': |
| regex = ban_rule.pattern[1:] |
| if input_api.re.search(regex, line): |
| matched = True |
| elif ban_rule.pattern in line: |
| matched = True |
| |
| if matched: |
| result.append(' %s:%d:' % (affected_file.LocalPath(), line_number)) |
| for line in ban_rule.explanation: |
| result.append(' %s' % line) |
| |
| return result |
| |
| |
| def CheckNoBannedFunctions(input_api, output_api): |
| """Make sure that banned functions are not used.""" |
| warnings = [] |
| errors = [] |
| |
| def IsExcludedFile(affected_file, excluded_paths): |
| if not excluded_paths: |
| return False |
| |
| local_path = affected_file.LocalPath() |
| # Consistently use / as path separator to simplify the writing of regex |
| # expressions. |
| local_path = local_path.replace(input_api.os_path.sep, '/') |
| for item in excluded_paths: |
| if input_api.re.match(item, local_path): |
| return True |
| return False |
| |
| def IsIosObjcFile(affected_file): |
| local_path = affected_file.LocalPath() |
| if input_api.os_path.splitext(local_path)[-1] not in ('.mm', '.m', |
| '.h'): |
| return False |
| basename = input_api.os_path.basename(local_path) |
| if 'ios' in basename.split('_'): |
| return True |
| for sep in (input_api.os_path.sep, input_api.os_path.altsep): |
| if sep and 'ios' in local_path.split(sep): |
| return True |
| return False |
| |
| def CheckForMatch(affected_file, line_num: int, line: str, |
| ban_rule: BanRule): |
| if IsExcludedFile(affected_file, ban_rule.excluded_paths): |
| return |
| |
| problems = _GetMessageForMatchingType(input_api, f, line_num, line, |
| ban_rule) |
| if problems: |
| if ban_rule.treat_as_error is not None and ban_rule.treat_as_error: |
| errors.extend(problems) |
| else: |
| warnings.extend(problems) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.java')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_JAVA_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.js', '.ts')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_JAVASCRIPT_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_OBJC_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| for f in input_api.AffectedFiles(file_filter=IsIosObjcFile): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_IOS_OBJC_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| egtest_filter = lambda f: f.LocalPath().endswith(('_egtest.mm')) |
| for f in input_api.AffectedFiles(file_filter=egtest_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_IOS_EGTEST_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_CPP_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| # As of 05/2024, iOS fully migrated ConsentLevel::kSync to kSignin, and |
| # Android is in the process of preventing new users from entering kSync. |
| # So the warning is restricted to those platforms. |
| ios_pattern = input_api.re.compile('(^|[\W_])ios[\W_]') |
| file_filter = lambda f: (f.LocalPath().endswith(('.cc', '.mm', '.h')) and |
| ('android' in f.LocalPath() or |
| # Simply checking for an 'ios' substring would |
| # catch unrelated cases, use a regex. |
| ios_pattern.search(f.LocalPath()))) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _DEPRECATED_SYNC_CONSENT_CPP_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.java')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _DEPRECATED_SYNC_CONSENT_JAVA_FUNCTIONS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.mojom')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_MOJOM_PATTERNS: |
| CheckForMatch(f, line_num, line, ban_rule) |
| |
| |
| result = [] |
| if (warnings): |
| result.append( |
| output_api.PresubmitPromptWarning('Banned functions were used.\n' + |
| '\n'.join(warnings))) |
| if (errors): |
| result.append( |
| output_api.PresubmitError('Banned functions were used.\n' + |
| '\n'.join(errors))) |
| return result |
| |
| def _CheckAndroidNoBannedImports(input_api, output_api): |
| """Make sure that banned java imports are not used.""" |
| errors = [] |
| |
| file_filter = lambda f: f.LocalPath().endswith(('.java')) |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| for ban_rule in _BANNED_JAVA_IMPORTS: |
| # Consider merging this into the above function. There is no |
| # real difference anymore other than helping with a little |
| # bit of boilerplate text. Doing so means things like |
| # `treat_as_error` will also be uniformly handled. |
| problems = _GetMessageForMatchingType(input_api, f, line_num, |
| line, ban_rule) |
| if problems: |
| errors.extend(problems) |
| result = [] |
| if (errors): |
| result.append( |
| output_api.PresubmitError('Banned imports were used.\n' + |
| '\n'.join(errors))) |
| return result |
| |
| |
| def CheckNoPragmaOnce(input_api, output_api): |
| """Make sure that banned functions are not used.""" |
| files = [] |
| pattern = input_api.re.compile(r'^#pragma\s+once', input_api.re.MULTILINE) |
| for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile): |
| if not f.LocalPath().endswith('.h'): |
| continue |
| if f.LocalPath().endswith('com_imported_mstscax.h'): |
| continue |
| contents = input_api.ReadFile(f) |
| if pattern.search(contents): |
| files.append(f) |
| |
| if files: |
| return [ |
| output_api.PresubmitError( |
| 'Do not use #pragma once in header files.\n' |
| 'See http://www.chromium.org/developers/coding-style#TOC-File-headers', |
| files) |
| ] |
| return [] |
| |
| |
| def CheckNoTrinaryTrueFalse(input_api, output_api): |
| """Checks to make sure we don't introduce use of foo ? true : false.""" |
| problems = [] |
| pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)') |
| for f in input_api.AffectedFiles(): |
| if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')): |
| continue |
| |
| for line_num, line in f.ChangedContents(): |
| if pattern.match(line): |
| problems.append(' %s:%d' % (f.LocalPath(), line_num)) |
| |
| if not problems: |
| return [] |
| return [ |
| output_api.PresubmitPromptWarning( |
| 'Please consider avoiding the "? true : false" pattern if possible.\n' |
| + '\n'.join(problems)) |
| ] |
| |
| |
| def CheckUnwantedDependencies(input_api, output_api): |
| """Runs checkdeps on #include and import statements added in this |
| change. Breaking - rules is an error, breaking ! rules is a |
| warning. |
| """ |
| # Return early if no relevant file types were modified. |
| for f in input_api.AffectedFiles(): |
| path = f.LocalPath() |
| if (_IsCPlusPlusFile(input_api, path) or _IsProtoFile(input_api, path) |
| or _IsJavaFile(input_api, path)): |
| break |
| else: |
| return [] |
| |
| import sys |
| # We need to wait until we have an input_api object and use this |
| # roundabout construct to import checkdeps because this file is |
| # eval-ed and thus doesn't have __file__. |
| original_sys_path = sys.path |
| try: |
| sys.path = sys.path + [ |
| input_api.os_path.join(input_api.PresubmitLocalPath(), |
| 'buildtools', 'checkdeps') |
| ] |
| import checkdeps |
| from rules import Rule |
| finally: |
| # Restore sys.path to what it was before. |
| sys.path = original_sys_path |
| |
| added_includes = [] |
| added_imports = [] |
| added_java_imports = [] |
| for f in input_api.AffectedFiles(): |
| if _IsCPlusPlusFile(input_api, f.LocalPath()): |
| changed_lines = [line for _, line in f.ChangedContents()] |
| added_includes.append([f.AbsoluteLocalPath(), changed_lines]) |
| elif _IsProtoFile(input_api, f.LocalPath()): |
| changed_lines = [line for _, line in f.ChangedContents()] |
| added_imports.append([f.AbsoluteLocalPath(), changed_lines]) |
| elif _IsJavaFile(input_api, f.LocalPath()): |
| changed_lines = [line for _, line in f.ChangedContents()] |
| added_java_imports.append([f.AbsoluteLocalPath(), changed_lines]) |
| |
| deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath()) |
| |
| error_descriptions = [] |
| warning_descriptions = [] |
| error_subjects = set() |
| warning_subjects = set() |
| |
| for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes( |
| added_includes): |
| path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath()) |
| description_with_path = '%s\n %s' % (path, rule_description) |
| if rule_type == Rule.DISALLOW: |
| error_descriptions.append(description_with_path) |
| error_subjects.add("#includes") |
| else: |
| warning_descriptions.append(description_with_path) |
| warning_subjects.add("#includes") |
| |
| for path, rule_type, rule_description in deps_checker.CheckAddedProtoImports( |
| added_imports): |
| path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath()) |
| description_with_path = '%s\n %s' % (path, rule_description) |
| if rule_type == Rule.DISALLOW: |
| error_descriptions.append(description_with_path) |
| error_subjects.add("imports") |
| else: |
| warning_descriptions.append(description_with_path) |
| warning_subjects.add("imports") |
| |
| for path, rule_type, rule_description in deps_checker.CheckAddedJavaImports( |
| added_java_imports, _JAVA_MULTIPLE_DEFINITION_EXCLUDED_PATHS): |
| path = input_api.os_path.relpath(path, input_api.PresubmitLocalPath()) |
| description_with_path = '%s\n %s' % (path, rule_description) |
| if rule_type == Rule.DISALLOW: |
| error_descriptions.append(description_with_path) |
| error_subjects.add("imports") |
| else: |
| warning_descriptions.append(description_with_path) |
| warning_subjects.add("imports") |
| |
| results = [] |
| if error_descriptions: |
| results.append( |
| output_api.PresubmitError( |
| 'You added one or more %s that violate checkdeps rules.' % |
| " and ".join(error_subjects), error_descriptions)) |
| if warning_descriptions: |
| results.append( |
| output_api.PresubmitPromptOrNotify( |
| 'You added one or more %s of files that are temporarily\n' |
| 'allowed but being removed. Can you avoid introducing the\n' |
| '%s? See relevant DEPS file(s) for details and contacts.' % |
| (" and ".join(warning_subjects), "/".join(warning_subjects)), |
| warning_descriptions)) |
| return results |
| |
| |
| def CheckFilePermissions(input_api, output_api): |
| """Check that all files have their permissions properly set.""" |
| if input_api.platform == 'win32': |
| return [] |
| checkperms_tool = input_api.os_path.join(input_api.PresubmitLocalPath(), |
| 'tools', 'checkperms', |
| 'checkperms.py') |
| args = [ |
| input_api.python3_executable, checkperms_tool, '--root', |
| input_api.change.RepositoryRoot() |
| ] |
| with input_api.CreateTemporaryFile() as file_list: |
| for f in input_api.AffectedFiles(): |
| # checkperms.py file/directory arguments must be relative to the |
| # repository. |
| file_list.write((f.LocalPath() + '\n').encode('utf8')) |
| file_list.close() |
| args += ['--file-list', file_list.name] |
| try: |
| input_api.subprocess.check_output(args) |
| return [] |
| except input_api.subprocess.CalledProcessError as error: |
| return [ |
| output_api.PresubmitError('checkperms.py failed:', |
| long_text=error.output.decode( |
| 'utf-8', 'ignore')) |
| ] |
| |
| |
| def CheckNoAuraWindowPropertyHInHeaders(input_api, output_api): |
| """Makes sure we don't include ui/aura/window_property.h |
| in header files. |
| """ |
| pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"') |
| errors = [] |
| for f in input_api.AffectedFiles(): |
| if not f.LocalPath().endswith('.h'): |
| continue |
| for line_num, line in f.ChangedContents(): |
| if pattern.match(line): |
| errors.append(' %s:%d' % (f.LocalPath(), line_num)) |
| |
| results = [] |
| if errors: |
| results.append( |
| output_api.PresubmitError( |
| 'Header files should not include ui/aura/window_property.h', |
| errors)) |
| return results |
| |
| |
| def CheckNoInternalHeapIncludes(input_api, output_api): |
| """Makes sure we don't include any headers from |
| third_party/blink/renderer/platform/heap/impl or |
| third_party/blink/renderer/platform/heap/v8_wrapper from files outside of |
| third_party/blink/renderer/platform/heap |
| """ |
| impl_pattern = input_api.re.compile( |
| r'^\s*#include\s*"third_party/blink/renderer/platform/heap/impl/.*"') |
| v8_wrapper_pattern = input_api.re.compile( |
| r'^\s*#include\s*"third_party/blink/renderer/platform/heap/v8_wrapper/.*"' |
| ) |
| # Consistently use / as path separator to simplify the writing of regex |
| # expressions. |
| file_filter = lambda f: not input_api.re.match( |
| r"^third_party/blink/renderer/platform/heap/.*", |
| f.LocalPath().replace(input_api.os_path.sep, '/')) |
| errors = [] |
| |
| for f in input_api.AffectedFiles(file_filter=file_filter): |
| for line_num, line in f.ChangedContents(): |
| if impl_pattern.match(line) or v8_wrapper_pattern.match(line): |
| errors.append(' %s:%d' % (f.LocalPath(), line_num)) |
| |
| results = [] |
| if errors: |
| results.append( |
| output_api.PresubmitError( |
| 'Do not include files from third_party/blink/renderer/platform/heap/impl' |
| ' or third_party/blink/renderer/platform/heap/v8_wrapper. Use the ' |
| 'relevant counterparts from third_party/blink/renderer/platform/heap', |
| errors)) |
| return results |
| |
| |
| def _CheckForVersionControlConflictsInFile(input_api, f): |
| pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$') |
| errors = [] |
| for line_num, line in f.ChangedContents(): |
| if f.LocalPath().endswith(('.md', '.rst', '.txt')): |
| # First-level headers in markdown look a lot like version control |
| # conflict markers. http://daringfireball.net/projects/markdown/basics |
| continue |
| if pattern.match(line): |
| errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line)) |
| return errors |
| |
| |
| def CheckForVersionControlConflicts(input_api, output_api): |
| """Usually this is not intentional and will cause a compile failure.""" |
| errors = [] |
| for f in input_api.AffectedFiles(): |
| errors.extend(_CheckForVersionControlConflictsInFile(input_api, f)) |
| |
| results = [] |
| if errors: |
| results.append( |
| output_api.PresubmitError( |
| 'Version control conflict markers found, please resolve.', |
| errors)) |
| return results |
| |
| |
| def CheckGoogleSupportAnswerUrlOnUpload(input_api, output_api): |
| pattern = input_api.re.compile('support\.google\.com\/chrome.*/answer') |
| errors = [] |
| for f in input_api.AffectedFiles(): |
| for line_num, line in f.ChangedContents(): |
| if pattern.search(line): |
| errors.append(' %s:%d %s' % (f.LocalPath(), line_num, line)) |
| |
| results = [] |
| if errors: |
| results.append( |
| output_api.PresubmitPromptWarning( |
| 'Found Google support URL addressed by answer number. Please replace ' |
| 'with a p= identifier instead. See crbug.com/679462\n', |
| errors)) |
| return results |
<