summaryrefslogtreecommitdiffstats
path: root/chrome/common/extensions
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-03 10:01:26 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-03 10:01:26 +0000
commitab57a59d94280b432f728787fc2563227797d101 (patch)
tree0bebabb8be797300add05b6673cafc824fc4a9b0 /chrome/common/extensions
parentf979ce4f17143dc97f7bfbdc81759993fd283bc5 (diff)
downloadchromium_src-ab57a59d94280b432f728787fc2563227797d101.zip
chromium_src-ab57a59d94280b432f728787fc2563227797d101.tar.gz
chromium_src-ab57a59d94280b432f728787fc2563227797d101.tar.bz2
Revert 61323 - Component extensions (and whitelisted extensions) specifying <all_urls> in their Extension match pattern should be allowed to run content scripts everywhere (including chrome://, chrome-extension://, about: and gallery pages.
The intent was to also allow these extensions to specify more granular permissions, such as about:version instead of <all_urls>, but that didn't make the cut this time. This CL also enables <all_urls> for host permissions for regular extensions, which was disabled before. Note: That still doesn't give them permission to script the gallery and chrome:// pages, etc. BUG=36275 TEST=New: ExtensionBrowserTest.AllUrlsWhitelistedExtension, ExtensionBrowserTest.AllUrlsRegularExtensions Review URL: http://codereview.chromium.org/3440027 TBR=finnur@chromium.org Review URL: http://codereview.chromium.org/3557006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61327 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/extensions')
-rw-r--r--chrome/common/extensions/extension.cc99
-rw-r--r--chrome/common/extensions/extension.h28
-rw-r--r--chrome/common/extensions/extension_constants.cc3
-rw-r--r--chrome/common/extensions/url_pattern.cc49
-rw-r--r--chrome/common/extensions/url_pattern.h24
-rw-r--r--chrome/common/extensions/url_pattern_unittest.cc88
6 files changed, 34 insertions, 257 deletions
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index bddd6ec..b88e7c1 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -33,7 +33,6 @@
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
-#include "googleurl/src/url_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/registry_controlled_domain.h"
@@ -131,17 +130,6 @@ const char* kNonPermissionFunctionNames[] = {
const size_t kNumNonPermissionFunctionNames =
arraysize(kNonPermissionFunctionNames);
-// Ids of extensions allowed to execute scripts everywhere. Do not add to this
-// list without consulting the Extensions team first.
-// Note: Component extensions have this right implicitly and do not need to be
-// added to this list.
-const char* kCanExecuteScriptsEverywhere[] = {
- "", // Extension ids for whitelisted extensions go here.
-};
-
-// The size of the kCanExecuteScriptsEverywhere list.
-static size_t kNumCanExecuteScriptsEverywhere =
- arraysize(kCanExecuteScriptsEverywhere);
// A map between permission name and its install warning message.
class PermissionMap {
@@ -174,8 +162,6 @@ static const char kWindowPermission[] = "windows";
} // namespace
-char** Extension::scripting_whitelist_ =
- const_cast<char**>(&kCanExecuteScriptsEverywhere[0]);
const FilePath::CharType Extension::kManifestFilename[] =
FILE_PATH_LITERAL("manifest.json");
@@ -488,11 +474,7 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script,
return false;
}
- URLPattern pattern;
- if (CanExecuteScriptEverywhere())
- pattern = URLPattern(URLPattern::SCHEME_ALL);
- else
- pattern = URLPattern(UserScript::kValidUserScriptSchemes);
+ URLPattern pattern(UserScript::kValidUserScriptSchemes);
if (!pattern.Parse(match_str)) {
*error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidMatch,
base::IntToString(definition_index), base::IntToString(j));
@@ -1532,11 +1514,11 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key,
UserScript script;
if (!LoadUserScriptHelper(content_script, i, error, &script))
- return false; // Failed to parse script context definition.
+ return false; // Failed to parse script context definition
script.set_extension_id(id());
if (converted_from_user_script_) {
script.set_emulate_greasemonkey(true);
- script.set_match_all_frames(true); // Greasemonkey matches all frames.
+ script.set_match_all_frames(true); // greasemonkey matches all frames
}
content_scripts_.push_back(script);
}
@@ -1689,18 +1671,16 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key,
}
// Otherwise, it's a host pattern permission.
- URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ?
- URLPattern::SCHEME_ALL :
- (UserScript::kValidUserScriptSchemes |
- URLPattern::SCHEME_CHROMEUI) & ~URLPattern::SCHEME_FILE);
-
+ URLPattern pattern(URLPattern::SCHEME_HTTP |
+ URLPattern::SCHEME_HTTPS |
+ URLPattern::SCHEME_CHROMEUI);
if (!pattern.Parse(permission_str)) {
*error = ExtensionErrorUtils::FormatErrorMessage(
errors::kInvalidPermission, base::IntToString(i));
return false;
}
- if (!CanSpecifyHostPermission(pattern)) {
+ if (!CanAccessURL(pattern)) {
*error = ExtensionErrorUtils::FormatErrorMessage(
errors::kInvalidPermissionScheme, base::IntToString(i));
return false;
@@ -1906,13 +1886,6 @@ static std::string SizeToString(const gfx::Size& max_size) {
base::IntToString(max_size.height());
}
-// static
-void Extension::SetScriptingWhitelist(const char** whitelist, size_t size) {
- DCHECK(whitelist);
- scripting_whitelist_ = const_cast<char**>(whitelist);
- kNumCanExecuteScriptsEverywhere = size;
-}
-
void Extension::SetCachedImage(const ExtensionResource& source,
const SkBitmap& image,
const gfx::Size& original_size) {
@@ -1981,13 +1954,12 @@ GURL Extension::GetIconURL(int size, ExtensionIconSet::MatchType match_type) {
return GetResourceURL(path);
}
-bool Extension::CanSpecifyHostPermission(const URLPattern pattern) const {
- if (!pattern.match_all_urls() &&
- pattern.MatchesScheme(chrome::kChromeUIScheme)) {
+bool Extension::CanAccessURL(const URLPattern pattern) const {
+ if (pattern.MatchesScheme(chrome::kChromeUIScheme)) {
// Only allow access to chrome://favicon to regular extensions. Component
// extensions can have access to all of chrome://*.
return (pattern.host() == chrome::kChromeUIFavIconHost ||
- CanExecuteScriptEverywhere());
+ location() == Extension::COMPONENT);
}
// Otherwise, the valid schemes were handled by URLPattern.
@@ -2051,45 +2023,6 @@ void Extension::InitEffectiveHostPermissions() {
}
}
-// static
-bool Extension::CanExecuteScriptOnPage(
- const GURL& page_url, bool can_execute_script_everywhere,
- const std::vector<URLPattern>* host_permissions,
- UserScript* script,
- std::string* error) {
- DCHECK(!(host_permissions && script)) << "Shouldn't specify both";
-
- // The gallery is special-cased as a restricted URL for scripting to prevent
- // access to special JS bindings we expose to the gallery (and avoid things
- // like extensions removing the "report abuse" link).
- if ((page_url.host() == GURL(Extension::ChromeStoreURL()).host()) &&
- !can_execute_script_everywhere &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kAllowScriptingGallery)) {
- if (error)
- *error = errors::kCannotScriptGallery;
- return false;
- }
-
- if (host_permissions) {
- for (size_t i = 0; i < host_permissions->size(); ++i) {
- if ((*host_permissions)[i].MatchesUrl(page_url))
- return true;
- }
- }
- if (script) {
- if (script->MatchesUrl(page_url))
- return true;
- }
-
- if (error) {
- *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
- page_url.spec());
- }
-
- return false;
-}
-
bool Extension::HasEffectiveAccessToAllHosts() const {
// Some APIs effectively grant access to every site. New ones should be
// added here. (I'm looking at you, network API)
@@ -2137,18 +2070,6 @@ bool Extension::IsAPIPermission(const std::string& str) {
return false;
}
-bool Extension::CanExecuteScriptEverywhere() const {
- if (location() == Extension::COMPONENT)
- return true;
-
- for (size_t i = 0; i < kNumCanExecuteScriptsEverywhere; ++i) {
- if (id() == scripting_whitelist_[i])
- return true;
- }
-
- return false;
-}
-
ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest,
const std::string& id,
const FilePath& path,
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index b1b00d3..f55ffe0 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -308,23 +308,6 @@ class Extension {
// slash.
static std::string ChromeStoreURL();
- // Helper function that consolidates the check for whether the script can
- // execute into one location. |page_url| is the page that is the candidate
- // for running the script, |can_execute_script_everywhere| specifies whether
- // the extension is on the whitelist, |allowed_pages| is a vector of
- // URLPatterns, listing what access the extension has, |script| is the script
- // pointer (if content script) and |error| is an optional parameter, which
- // will receive the error string listing why access was denied.
- static bool CanExecuteScriptOnPage(
- const GURL& page_url,
- bool can_execute_script_everywhere,
- const std::vector<URLPattern>* allowed_pages,
- UserScript* script,
- std::string* error);
-
- // Adds an extension to the scripting whitelist. Used for testing only.
- static void SetScriptingWhitelist(const char** whitelist, size_t size);
-
// Initialize the extension from a parsed manifest.
// Usually, the id of an extension is generated by the "key" property of
// its manifest, but if |require_key| is |false|, a temporary ID will be
@@ -379,7 +362,7 @@ class Extension {
// the manifest. http, https, and chrome://favicon/ is allowed for all
// extensions, while component extensions are allowed access to
// chrome://resources.
- bool CanSpecifyHostPermission(const URLPattern pattern) const;
+ bool CanAccessURL(const URLPattern pattern) const;
// Whether the extension has access to the given URL.
bool HasHostPermission(const GURL& url) const;
@@ -479,10 +462,6 @@ class Extension {
bool is_hosted_app() const { return is_app() && !web_extent().is_empty(); }
bool is_packaged_app() const { return is_app() && web_extent().is_empty(); }
- // Returns true if this extension is a COMPONENT extension, or if it is
- // on the whitelist of extensions that can script all pages.
- bool CanExecuteScriptEverywhere() const;
-
private:
// We keep a cache of images loaded from extension resources based on their
// path and a string representation of a size that may have been used to
@@ -645,9 +624,6 @@ class Extension {
// The type of container to launch into.
extension_misc::LaunchContainer launch_container_;
- // A whitelist of extensions that can script anywhere.
- static char** scripting_whitelist_;
-
// The default size of the container when launching. Only respected for
// containers like panels and windows.
int launch_width_;
@@ -656,7 +632,7 @@ class Extension {
// Cached images for this extension.
ImageCache image_cache_;
- // The Omnibox keyword for this extension, or empty if there is none.
+ // The omnibox keyword for this extension, or empty if there is none.
std::string omnibox_keyword_;
// Runtime data:
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 17444ee..f725181 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -202,7 +202,8 @@ const char* kInvalidPermission =
const char* kInvalidPermissions =
"Required value 'permissions' is missing or invalid.";
const char* kInvalidPermissionScheme =
- "Invalid scheme for 'permissions[*]'.";
+ "Invalid scheme for 'permissions[*]'. Only 'http' and 'https' are "
+ "allowed.";
const char* kInvalidPlugins =
"Invalid value for 'plugins'.";
const char* kInvalidPluginsPath =
diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc
index 62459a3..80fc5fb 100644
--- a/chrome/common/extensions/url_pattern.cc
+++ b/chrome/common/extensions/url_pattern.cc
@@ -9,7 +9,6 @@
#include "base/string_util.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
-#include "googleurl/src/url_util.h"
// TODO(aa): Consider adding chrome-extension? What about more obscure ones
// like data: and javascript: ?
@@ -35,21 +34,10 @@ COMPILE_ASSERT(arraysize(kValidSchemes) == arraysize(kValidSchemeMasks),
static const char kPathSeparator[] = "/";
-const char URLPattern::kAllUrlsPattern[] = "<all_urls>";
-
-static bool IsStandardScheme(const std::string& scheme) {
- // "*" gets the same treatment as a standard scheme.
- if (scheme == "*")
- return true;
-
- return url_util::IsStandard(scheme.c_str(),
- url_parse::Component(0, static_cast<int>(scheme.length())));
-}
+static const char kAllUrlsPattern[] = "<all_urls>";
URLPattern::URLPattern()
- : valid_schemes_(SCHEME_NONE),
- match_all_urls_(false),
- match_subdomains_(false) {}
+ : valid_schemes_(0), match_all_urls_(false), match_subdomains_(false) {}
URLPattern::URLPattern(int valid_schemes)
: valid_schemes_(valid_schemes), match_all_urls_(false),
@@ -76,32 +64,24 @@ bool URLPattern::Parse(const std::string& pattern) {
return true;
}
- size_t scheme_end_pos = pattern.find(":");
+ size_t scheme_end_pos = pattern.find(chrome::kStandardSchemeSeparator);
if (scheme_end_pos == std::string::npos)
return false;
if (!SetScheme(pattern.substr(0, scheme_end_pos)))
return false;
- std::string separator =
- pattern.substr(scheme_end_pos, strlen(chrome::kStandardSchemeSeparator));
- if (separator == chrome::kStandardSchemeSeparator)
- scheme_end_pos += strlen(chrome::kStandardSchemeSeparator);
- else
- scheme_end_pos += 1;
-
- // Advance past the scheme separator.
- size_t host_start_pos = scheme_end_pos;
+ size_t host_start_pos = scheme_end_pos +
+ strlen(chrome::kStandardSchemeSeparator);
if (host_start_pos >= pattern.length())
return false;
// Parse out the host and path.
size_t path_start_pos = 0;
- bool standard_scheme = IsStandardScheme(scheme_);
-
- // File URLs are special because they have no host.
- if (scheme_ == chrome::kFileScheme || !standard_scheme) {
+ // File URLs are special because they have no host. There are other schemes
+ // with the same structure, but we don't support them (yet).
+ if (scheme_ == chrome::kFileScheme) {
path_start_pos = host_start_pos;
} else {
size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
@@ -145,9 +125,6 @@ bool URLPattern::SetScheme(const std::string& scheme) {
}
bool URLPattern::IsValidScheme(const std::string& scheme) const {
- if (valid_schemes_ == SCHEME_ALL)
- return true;
-
for (size_t i = 0; i < arraysize(kValidSchemes); ++i) {
if (scheme == kValidSchemes[i] && (valid_schemes_ & kValidSchemeMasks[i]))
return true;
@@ -160,9 +137,6 @@ bool URLPattern::MatchesUrl(const GURL &test) const {
if (!MatchesScheme(test.scheme()))
return false;
- if (match_all_urls_)
- return true;
-
if (!MatchesHost(test))
return false;
@@ -235,12 +209,9 @@ std::string URLPattern::GetAsString() const {
if (match_all_urls_)
return kAllUrlsPattern;
- bool standard_scheme = IsStandardScheme(scheme_);
-
- std::string spec = scheme_ +
- (standard_scheme ? chrome::kStandardSchemeSeparator : ":");
+ std::string spec = scheme_ + chrome::kStandardSchemeSeparator;
- if (scheme_ != chrome::kFileScheme && standard_scheme) {
+ if (scheme_ != chrome::kFileScheme) {
if (match_subdomains_) {
spec += "*";
if (!host_.empty())
diff --git a/chrome/common/extensions/url_pattern.h b/chrome/common/extensions/url_pattern.h
index 0067678..3fe6eb6 100644
--- a/chrome/common/extensions/url_pattern.h
+++ b/chrome/common/extensions/url_pattern.h
@@ -77,23 +77,13 @@ class URLPattern {
public:
// A collection of scheme bitmasks for use with valid_schemes.
enum SchemeMasks {
- SCHEME_NONE = 0,
- SCHEME_HTTP = 1 << 0,
- SCHEME_HTTPS = 1 << 1,
- SCHEME_FILE = 1 << 2,
- SCHEME_FTP = 1 << 3,
- SCHEME_CHROMEUI = 1 << 4,
- // SCHEME_ALL will match every scheme, including chrome://, chrome-
- // extension://, about:, etc. Because this has lots of security
- // implications, third-party extensions should never be able to get access
- // to URL patterns initialized this way. It should only be used for internal
- // Chrome code.
- SCHEME_ALL = -1,
+ SCHEME_HTTP = 1<<0,
+ SCHEME_HTTPS = 1<<1,
+ SCHEME_FILE = 1<<2,
+ SCHEME_FTP = 1<<3,
+ SCHEME_CHROMEUI = 1<<4,
};
- // The <all_urls> string pattern.
- static const char kAllUrlsPattern[];
-
// Note: don't use this directly. This exists so URLPattern can be used
// with STL containers.
URLPattern();
@@ -171,8 +161,8 @@ class URLPattern {
// would result in the same answer.
bool OverlapsWith(const URLPattern& other) const;
- // Convert this URLPattern into an equivalent set of URLPatterns that don't
- // use a wildcard in the scheme component. If this URLPattern doesn't use a
+ // Conver this URLPattern into an equivalent set of URLPatterns that don't use
+ // a wildcard in the scheme component. If this URLPattern doesn't use a
// wildcard scheme, then the returned set will contain one element that is
// equivalent to this instance.
std::vector<URLPattern> ConvertToExplicitSchemes() const;
diff --git a/chrome/common/extensions/url_pattern_unittest.cc b/chrome/common/extensions/url_pattern_unittest.cc
index a9ef21e..47cbdc8 100644
--- a/chrome/common/extensions/url_pattern_unittest.cc
+++ b/chrome/common/extensions/url_pattern_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,20 +19,18 @@ static const int kAllSchemes =
TEST(URLPatternTest, ParseInvalid) {
const char* kInvalidPatterns[] = {
"http", // no scheme
- "http:",
- "http:/",
"http://", // no path separator
"http://foo", // no path separator
"http://*foo/bar", // not allowed as substring of host component
"http://foo.*.bar/baz", // must be first component
"http:/bar", // scheme separator not found
"foo://*", // invalid scheme
- "chrome-extension://*/*", // we don't support chrome extension URLs
+ "chrome-extenstions://*/*", // we don't support chrome extension URLs
};
for (size_t i = 0; i < arraysize(kInvalidPatterns); ++i) {
URLPattern pattern;
- EXPECT_FALSE(pattern.Parse(kInvalidPatterns[i])) << kInvalidPatterns[i];
+ EXPECT_FALSE(pattern.Parse(kInvalidPatterns[i]));
}
};
@@ -185,86 +183,6 @@ TEST(URLPatternTest, Match11) {
EXPECT_TRUE(pattern.MatchesUrl(GURL("file:///foo/bar")));
};
-// SCHEME_ALL matches all schemes.
-TEST(URLPatternTest, Match12) {
- URLPattern pattern(URLPattern::SCHEME_ALL);
- EXPECT_TRUE(pattern.Parse("<all_urls>"));
- EXPECT_TRUE(pattern.MatchesScheme("chrome"));
- EXPECT_TRUE(pattern.MatchesScheme("http"));
- EXPECT_TRUE(pattern.MatchesScheme("https"));
- EXPECT_TRUE(pattern.MatchesScheme("file"));
- EXPECT_TRUE(pattern.MatchesScheme("javascript"));
- EXPECT_TRUE(pattern.MatchesScheme("data"));
- EXPECT_TRUE(pattern.MatchesScheme("about"));
- EXPECT_TRUE(pattern.MatchesScheme("chrome-extension"));
- EXPECT_TRUE(pattern.match_subdomains());
- EXPECT_TRUE(pattern.match_all_urls());
- EXPECT_EQ("/*", pattern.path());
- EXPECT_TRUE(pattern.MatchesUrl(GURL("chrome://favicon/http://google.com")));
- EXPECT_TRUE(pattern.MatchesUrl(GURL("http://127.0.0.1")));
- EXPECT_TRUE(pattern.MatchesUrl(GURL("file:///foo/bar")));
- EXPECT_TRUE(pattern.MatchesUrl(GURL("chrome://newtab")));
- EXPECT_TRUE(pattern.MatchesUrl(GURL("about:blank")));
- EXPECT_TRUE(pattern.MatchesUrl(GURL("about:version")));
- EXPECT_TRUE(pattern.MatchesUrl(
- GURL("data:text/html;charset=utf-8,<html>asdf</html>")));
-};
-
-static const struct MatchPatterns {
- const char* pattern;
- const char* matches;
-} kMatch13UrlPatternTestCases[] = {
- {"about:*", "about:blank"},
- {"about:blank", "about:blank"},
- {"about:*", "about:version"},
- {"chrome-extension://*/*", "chrome-extension://FTW"},
- {"data:*", "data:monkey"},
- {"javascript:*", "javascript:atemyhomework"},
-};
-
-// SCHEME_ALL and specific schemes.
-TEST(URLPatternTest, Match13) {
- for (size_t i = 0; i < arraysize(kMatch13UrlPatternTestCases); ++i) {
- URLPattern pattern(URLPattern::SCHEME_ALL);
- EXPECT_TRUE(pattern.Parse(kMatch13UrlPatternTestCases[i].pattern))
- << " while parsing " << kMatch13UrlPatternTestCases[i].pattern;
- EXPECT_TRUE(pattern.MatchesUrl(
- GURL(kMatch13UrlPatternTestCases[i].matches)))
- << " while matching " << kMatch13UrlPatternTestCases[i].matches;
- }
-
- // Negative test.
- URLPattern pattern(URLPattern::SCHEME_ALL);
- EXPECT_TRUE(pattern.Parse("data:*"));
- EXPECT_FALSE(pattern.MatchesUrl(GURL("about:blank")));
-};
-
-static const struct GetAsStringPatterns {
- const char* pattern;
-} kGetAsStringTestCases[] = {
- { "http://www/" },
- { "http://*/*" },
- { "chrome://*/*" },
- { "chrome://newtab/" },
- { "about:*" },
- { "about:blank" },
- { "chrome-extension://*/*" },
- { "chrome-extension://FTW/" },
- { "data:*" },
- { "data:monkey" },
- { "javascript:*" },
- { "javascript:atemyhomework" },
-};
-
-TEST(URLPatternTest, GetAsString) {
- for (size_t i = 0; i < arraysize(kGetAsStringTestCases); ++i) {
- URLPattern pattern(URLPattern::SCHEME_ALL);
- EXPECT_TRUE(pattern.Parse(kGetAsStringTestCases[i].pattern));
- EXPECT_STREQ(kGetAsStringTestCases[i].pattern,
- pattern.GetAsString().c_str());
- }
-}
-
void TestPatternOverlap(const URLPattern& pattern1, const URLPattern& pattern2,
bool expect_overlap) {
EXPECT_EQ(expect_overlap, pattern1.OverlapsWith(pattern2))