[DNR] Add isRegexSupported API call
Add the isRegexSupported extension function which provides extension developers with a way to check that a given regular expression can be used as a regexFilter rule condition. Skipping presubmit since this seems to be hitting crbug.com/956368. R=karandeepb@chromium.org, kelvinjiang@chromium.org Bug: 1088457 No-Presubmit: True Change-Id: Ic51df5dd096806472f25e4053a020c0a08368179 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2372465 Commit-Queue: Karan Bhatia <karandeepb@chromium.org> Reviewed-by: Karan Bhatia <karandeepb@chromium.org> Cr-Commit-Position: refs/heads/master@{#808574}
This commit is contained in:
AUTHORS
chrome
browser
extensions
api
declarative_net_request
test
data
extensions
api_test
declarative_net_request
is_regex_supported
extensions
tools/metrics/histograms
2
AUTHORS
2
AUTHORS
@ -232,7 +232,7 @@ Daniel Waxweiler <daniel.waxweiler@gmail.com>
|
||||
Dániel Bátyai <dbatyai@inf.u-szeged.hu>
|
||||
Dániel Vince <vinced@inf.u-szeged.hu>
|
||||
Darshini KN <kn.darshini@samsung.com>
|
||||
Dave Barker <kzar@kzar.co.uk>
|
||||
Dave Vandyke <kzar@kzar.co.uk>
|
||||
David Benjamin <davidben@mit.edu>
|
||||
David Davidovic <david@davidovic.io>
|
||||
David Erceg <erceg.david@gmail.com>
|
||||
|
@ -98,4 +98,8 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestLazyAPItest, GetMatchedRules) {
|
||||
ASSERT_TRUE(RunTest("get_matched_rules")) << message_;
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestLazyAPItest, IsRegexSupported) {
|
||||
ASSERT_TRUE(RunTest("is_regex_supported")) << message_;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
54
chrome/test/data/extensions/api_test/declarative_net_request/is_regex_supported/background.js
Normal file
54
chrome/test/data/extensions/api_test/declarative_net_request/is_regex_supported/background.js
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
function isRegexSupported(regexOptions) {
|
||||
return new Promise(resolve => {
|
||||
chrome.declarativeNetRequest.isRegexSupported(regexOptions, resolve);
|
||||
});
|
||||
}
|
||||
|
||||
chrome.test.runTests([
|
||||
async function testSupportedRegex() {
|
||||
let result = await isRegexSupported({regex: '[0-9]+'});
|
||||
chrome.test.assertEq(result, {isSupported: true});
|
||||
chrome.test.succeed();
|
||||
},
|
||||
|
||||
async function testSupportedRegexWithOptions() {
|
||||
let result = await isRegexSupported(
|
||||
{regex: '[0-9]+', isCaseSensitive: false, requireCapturing: true});
|
||||
chrome.test.assertEq(result, {isSupported: true});
|
||||
chrome.test.succeed();
|
||||
},
|
||||
|
||||
async function testInvalidRegex() {
|
||||
let result = await isRegexSupported({regex: '[a-9]+'});
|
||||
chrome.test.assertEq(result, {isSupported: false, reason: 'syntaxError'});
|
||||
chrome.test.succeed();
|
||||
},
|
||||
|
||||
async function testInvalidRegexWithOptions() {
|
||||
let result = await isRegexSupported(
|
||||
{regex: '[a-9]+', isCaseSensitive: false, requireCapturing: true});
|
||||
chrome.test.assertEq(result, {isSupported: false, reason: 'syntaxError'});
|
||||
chrome.test.succeed();
|
||||
},
|
||||
|
||||
async function testMemoryError() {
|
||||
let result = await isRegexSupported({regex: '[0-9]+'.repeat(1000)});
|
||||
chrome.test.assertEq(
|
||||
result, {isSupported: false, reason: 'memoryLimitExceeded'});
|
||||
chrome.test.succeed();
|
||||
},
|
||||
|
||||
async function testMemoryErrorWithOptions() {
|
||||
let regex = '(a)'.repeat(50);
|
||||
let result = await isRegexSupported({regex});
|
||||
chrome.test.assertEq(result, {isSupported: true});
|
||||
result = await isRegexSupported({regex, requireCapturing: true});
|
||||
chrome.test.assertEq(
|
||||
result, {isSupported: false, reason: 'memoryLimitExceeded'});
|
||||
chrome.test.succeed();
|
||||
}
|
||||
]);
|
14
chrome/test/data/extensions/api_test/declarative_net_request/is_regex_supported/manifest.json
Normal file
14
chrome/test/data/extensions/api_test/declarative_net_request/is_regex_supported/manifest.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Test extension",
|
||||
"manifest_version": 2,
|
||||
"permissions": [
|
||||
"declarativeNetRequest"
|
||||
],
|
||||
"version": "1.0",
|
||||
"background": {
|
||||
"scripts": [
|
||||
"background.js"
|
||||
],
|
||||
"persistent": false
|
||||
}
|
||||
}
|
@ -354,4 +354,42 @@ DeclarativeNetRequestSetActionCountAsBadgeTextFunction::Run() {
|
||||
return RespondNow(NoArguments());
|
||||
}
|
||||
|
||||
DeclarativeNetRequestIsRegexSupportedFunction::
|
||||
DeclarativeNetRequestIsRegexSupportedFunction() = default;
|
||||
DeclarativeNetRequestIsRegexSupportedFunction::
|
||||
~DeclarativeNetRequestIsRegexSupportedFunction() = default;
|
||||
|
||||
ExtensionFunction::ResponseAction
|
||||
DeclarativeNetRequestIsRegexSupportedFunction::Run() {
|
||||
using Params = dnr_api::IsRegexSupported::Params;
|
||||
|
||||
base::string16 error;
|
||||
std::unique_ptr<Params> params(Params::Create(*args_, &error));
|
||||
EXTENSION_FUNCTION_VALIDATE(params);
|
||||
EXTENSION_FUNCTION_VALIDATE(error.empty());
|
||||
|
||||
bool is_case_sensitive = params->regex_options.is_case_sensitive
|
||||
? *params->regex_options.is_case_sensitive
|
||||
: true;
|
||||
bool require_capturing = params->regex_options.require_capturing
|
||||
? *params->regex_options.require_capturing
|
||||
: false;
|
||||
re2::RE2 regex(params->regex_options.regex,
|
||||
declarative_net_request::CreateRE2Options(is_case_sensitive,
|
||||
require_capturing));
|
||||
|
||||
dnr_api::IsRegexSupportedResult result;
|
||||
if (regex.ok()) {
|
||||
result.is_supported = true;
|
||||
} else {
|
||||
result.is_supported = false;
|
||||
result.reason = regex.error_code() == re2::RE2::ErrorPatternTooLarge
|
||||
? dnr_api::UNSUPPORTED_REGEX_REASON_MEMORYLIMITEXCEEDED
|
||||
: dnr_api::UNSUPPORTED_REGEX_REASON_SYNTAXERROR;
|
||||
}
|
||||
|
||||
return RespondNow(
|
||||
ArgumentList(dnr_api::IsRegexSupported::Results::Create(result)));
|
||||
}
|
||||
|
||||
} // namespace extensions
|
||||
|
@ -118,6 +118,19 @@ class DeclarativeNetRequestSetActionCountAsBadgeTextFunction
|
||||
ExtensionFunction::ResponseAction Run() override;
|
||||
};
|
||||
|
||||
class DeclarativeNetRequestIsRegexSupportedFunction : public ExtensionFunction {
|
||||
public:
|
||||
DeclarativeNetRequestIsRegexSupportedFunction();
|
||||
DECLARE_EXTENSION_FUNCTION("declarativeNetRequest.isRegexSupported",
|
||||
DECLARATIVENETREQUEST_ISREGEXSUPPORTED)
|
||||
|
||||
protected:
|
||||
~DeclarativeNetRequestIsRegexSupportedFunction() override;
|
||||
|
||||
// ExtensionFunction override:
|
||||
ExtensionFunction::ResponseAction Run() override;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_DECLARATIVE_NET_REQUEST_API_H_
|
||||
|
@ -1568,6 +1568,7 @@ enum HistogramValue {
|
||||
INPUTMETHODPRIVATE_SETCOMPOSINGRANGE = 1505,
|
||||
AUTOTESTPRIVATE_LAUNCHSYSTEMWEBAPP = 1506,
|
||||
ACCESSIBILITY_PRIVATE_PERFORMACCELERATORACTION = 1507,
|
||||
DECLARATIVENETREQUEST_ISREGEXSUPPORTED = 1508,
|
||||
// Last entry: Add new entries above, then run:
|
||||
// python tools/metrics/histograms/update_extension_histograms.py
|
||||
ENUM_BOUNDARY
|
||||
|
@ -66,6 +66,16 @@ namespace declarativeNetRequest {
|
||||
allowAllRequests
|
||||
};
|
||||
|
||||
// Describes the reason why a given regular expression isn't supported.
|
||||
enum UnsupportedRegexReason {
|
||||
// The regular expression is syntactically incorrect, or uses features
|
||||
// not available in the
|
||||
// <a href = "https://github.com/google/re2/wiki/Syntax">RE2 syntax</a>.
|
||||
syntaxError,
|
||||
// The regular expression exceeds the memory limit.
|
||||
memoryLimitExceeded
|
||||
};
|
||||
|
||||
// Describes a single static ruleset.
|
||||
dictionary Ruleset {
|
||||
// A non-empty string uniquely identifying the ruleset. IDs beginning with
|
||||
@ -379,11 +389,34 @@ namespace declarativeNetRequest {
|
||||
DNRInfo declarative_net_request;
|
||||
};
|
||||
|
||||
dictionary RegexOptions {
|
||||
// The regular expresson to check.
|
||||
DOMString regex;
|
||||
|
||||
// Whether the <code>regex</code> specified is case sensitive. Default is
|
||||
// true.
|
||||
boolean? isCaseSensitive;
|
||||
|
||||
// Whether the <code>regex</code> specified requires capturing. Capturing is
|
||||
// only required for redirect rules which specify a
|
||||
// <code>regexSubstition</code> action. The default is false.
|
||||
boolean? requireCapturing;
|
||||
};
|
||||
|
||||
dictionary IsRegexSupportedResult {
|
||||
boolean isSupported;
|
||||
|
||||
// Specifies the reason why the regular expression is not supported. Only
|
||||
// provided if <code>isSupported</code> is false.
|
||||
UnsupportedRegexReason? reason;
|
||||
};
|
||||
|
||||
callback EmptyCallback = void();
|
||||
callback GetAllowedPagesCallback = void(DOMString[] result);
|
||||
callback GetRulesCallback = void(Rule[] rules);
|
||||
callback GetMatchedRulesCallback = void(RulesMatchedDetails details);
|
||||
callback GetEnabledRulesetsCallback = void(DOMString[] rulesetIds);
|
||||
callback IsRegexSupportedCallback = void(IsRegexSupportedResult result);
|
||||
|
||||
interface Functions {
|
||||
|
||||
@ -460,6 +493,14 @@ namespace declarativeNetRequest {
|
||||
// action count for a tab. This preference is persisted across sessions and
|
||||
// is false by default.
|
||||
static void setActionCountAsBadgeText(boolean enable);
|
||||
|
||||
// Checks if the given regular expression will be supported as a
|
||||
// <code>regexFilter</code> rule condition.
|
||||
// |regexOptions|: The regular expression to check.
|
||||
// |callback|: Called with details consisting of whether the regular
|
||||
// expression is supported and the reason if not.
|
||||
static void isRegexSupported(RegexOptions regexOptions,
|
||||
IsRegexSupportedCallback callback);
|
||||
};
|
||||
|
||||
interface Properties {
|
||||
|
@ -24569,6 +24569,7 @@ Called by update_extension_histograms.py.-->
|
||||
<int value="1505" label="INPUTMETHODPRIVATE_SETCOMPOSINGRANGE"/>
|
||||
<int value="1506" label="AUTOTESTPRIVATE_LAUNCHSYSTEMWEBAPP"/>
|
||||
<int value="1507" label="ACCESSIBILITY_PRIVATE_PERFORMACCELERATORACTION"/>
|
||||
<int value="1508" label="DECLARATIVENETREQUEST_ISREGEXSUPPORTED"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ExtensionIconState">
|
||||
|
Reference in New Issue
Block a user