| // Copyright 2017 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. |
| |
| #include "extensions/browser/api/declarative_net_request/parse_info.h" |
| |
| #include <utility> |
| |
| #include "base/check_op.h" |
| #include "base/containers/span.h" |
| #include "base/notreached.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "extensions/common/error_utils.h" |
| |
| namespace extensions { |
| namespace declarative_net_request { |
| |
| namespace { |
| |
| // Helper to ensure pointers to string literals can be used with |
| // base::JoinString. |
| std::string JoinString(base::span<const char* const> parts) { |
| std::vector<base::StringPiece> parts_piece; |
| for (const char* part : parts) |
| parts_piece.push_back(part); |
| return base::JoinString(parts_piece, ", "); |
| } |
| |
| std::string GetError(ParseResult error_reason, const int* rule_id) { |
| // Every error except ERROR_PERSISTING_RULESET requires |rule_id|. |
| DCHECK_EQ(!rule_id, error_reason == ParseResult::ERROR_PERSISTING_RULESET); |
| |
| switch (error_reason) { |
| case ParseResult::NONE: |
| break; |
| case ParseResult::SUCCESS: |
| break; |
| case ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED: |
| return ErrorUtils::FormatErrorMessage(kErrorResourceTypeDuplicated, |
| base::NumberToString(*rule_id)); |
| case ParseResult::ERROR_INVALID_RULE_ID: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidRuleKey, base::NumberToString(*rule_id), kIDKey, |
| base::NumberToString(kMinValidID)); |
| case ParseResult::ERROR_EMPTY_RULE_PRIORITY: |
| return ErrorUtils::FormatErrorMessage(kErrorEmptyRulePriority, |
| base::NumberToString(*rule_id)); |
| case ParseResult::ERROR_INVALID_RULE_PRIORITY: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidRuleKey, base::NumberToString(*rule_id), kPriorityKey, |
| base::NumberToString(kMinValidPriority)); |
| case ParseResult::ERROR_NO_APPLICABLE_RESOURCE_TYPES: |
| return ErrorUtils::FormatErrorMessage(kErrorNoApplicableResourceTypes, |
| |
| base::NumberToString(*rule_id)); |
| case ParseResult::ERROR_EMPTY_DOMAINS_LIST: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorEmptyList, base::NumberToString(*rule_id), kDomainsKey); |
| case ParseResult::ERROR_EMPTY_RESOURCE_TYPES_LIST: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorEmptyList, base::NumberToString(*rule_id), kResourceTypesKey); |
| case ParseResult::ERROR_EMPTY_URL_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorEmptyKey, base::NumberToString(*rule_id), kUrlFilterKey); |
| case ParseResult::ERROR_INVALID_REDIRECT_URL: |
| return ErrorUtils::FormatErrorMessage(kErrorInvalidRedirectUrl, |
| base::NumberToString(*rule_id), |
| kRedirectUrlPath); |
| case ParseResult::ERROR_DUPLICATE_IDS: |
| return ErrorUtils::FormatErrorMessage(kErrorDuplicateIDs, |
| base::NumberToString(*rule_id)); |
| case ParseResult::ERROR_PERSISTING_RULESET: |
| return kErrorPersisting; |
| case ParseResult::ERROR_NON_ASCII_URL_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorNonAscii, base::NumberToString(*rule_id), kUrlFilterKey); |
| case ParseResult::ERROR_NON_ASCII_DOMAIN: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorNonAscii, base::NumberToString(*rule_id), kDomainsKey); |
| case ParseResult::ERROR_NON_ASCII_EXCLUDED_DOMAIN: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorNonAscii, base::NumberToString(*rule_id), kExcludedDomainsKey); |
| case ParseResult::ERROR_INVALID_URL_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidKey, base::NumberToString(*rule_id), kUrlFilterKey); |
| case ParseResult::ERROR_EMPTY_REMOVE_HEADERS_LIST: |
| return ErrorUtils::FormatErrorMessage(kErrorEmptyRemoveHeadersList, |
| base::NumberToString(*rule_id), |
| kRemoveHeadersListKey); |
| case ParseResult::ERROR_INVALID_REDIRECT: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidKey, base::NumberToString(*rule_id), kRedirectPath); |
| case ParseResult::ERROR_INVALID_EXTENSION_PATH: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidKey, base::NumberToString(*rule_id), kExtensionPathPath); |
| case ParseResult::ERROR_INVALID_TRANSFORM_SCHEME: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidTransformScheme, base::NumberToString(*rule_id), |
| kTransformSchemePath, |
| JoinString(base::span<const char* const>(kAllowedTransformSchemes))); |
| case ParseResult::ERROR_INVALID_TRANSFORM_PORT: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidKey, base::NumberToString(*rule_id), kTransformPortPath); |
| case ParseResult::ERROR_INVALID_TRANSFORM_QUERY: |
| return ErrorUtils::FormatErrorMessage(kErrorInvalidKey, |
| base::NumberToString(*rule_id), |
| kTransformQueryPath); |
| case ParseResult::ERROR_INVALID_TRANSFORM_FRAGMENT: |
| return ErrorUtils::FormatErrorMessage(kErrorInvalidKey, |
| base::NumberToString(*rule_id), |
| kTransformFragmentPath); |
| case ParseResult::ERROR_QUERY_AND_TRANSFORM_BOTH_SPECIFIED: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorQueryAndTransformBothSpecified, base::NumberToString(*rule_id), |
| kTransformQueryPath, kTransformQueryTransformPath); |
| case ParseResult::ERROR_JAVASCRIPT_REDIRECT: |
| return ErrorUtils::FormatErrorMessage(kErrorJavascriptRedirect, |
| base::NumberToString(*rule_id), |
| kRedirectUrlPath); |
| case ParseResult::ERROR_EMPTY_REGEX_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorEmptyKey, base::NumberToString(*rule_id), kRegexFilterKey); |
| case ParseResult::ERROR_NON_ASCII_REGEX_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorNonAscii, base::NumberToString(*rule_id), kRegexFilterKey); |
| case ParseResult::ERROR_INVALID_REGEX_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidKey, base::NumberToString(*rule_id), kRegexFilterKey); |
| case ParseResult::ERROR_NO_HEADERS_SPECIFIED: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorNoHeaderListsSpecified, base::NumberToString(*rule_id), |
| kRequestHeadersPath, kResponseHeadersPath); |
| case ParseResult::ERROR_EMPTY_REQUEST_HEADERS_LIST: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorEmptyList, base::NumberToString(*rule_id), kRequestHeadersPath); |
| case ParseResult::ERROR_EMPTY_RESPONSE_HEADERS_LIST: |
| return ErrorUtils::FormatErrorMessage(kErrorEmptyList, |
| base::NumberToString(*rule_id), |
| kResponseHeadersPath); |
| case ParseResult::ERROR_INVALID_HEADER_NAME: |
| return ErrorUtils::FormatErrorMessage(kErrorInvalidHeaderName, |
| base::NumberToString(*rule_id)); |
| case ParseResult::ERROR_REGEX_TOO_LARGE: |
| // These rules are ignored while indexing and so won't cause an error. |
| break; |
| case ParseResult::ERROR_MULTIPLE_FILTERS_SPECIFIED: |
| return ErrorUtils::FormatErrorMessage(kErrorMultipleFilters, |
| base::NumberToString(*rule_id), |
| kUrlFilterKey, kRegexFilterKey); |
| case ParseResult::ERROR_REGEX_SUBSTITUTION_WITHOUT_FILTER: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorRegexSubstitutionWithoutFilter, base::NumberToString(*rule_id), |
| kRegexSubstitutionKey, kRegexFilterKey); |
| case ParseResult::ERROR_INVALID_REGEX_SUBSTITUTION: |
| return ErrorUtils::FormatErrorMessage(kErrorInvalidKey, |
| base::NumberToString(*rule_id), |
| kRegexSubstitutionPath); |
| case ParseResult::ERROR_INVALID_ALLOW_ALL_REQUESTS_RESOURCE_TYPE: |
| return ErrorUtils::FormatErrorMessage( |
| kErrorInvalidAllowAllRequestsResourceType, |
| base::NumberToString(*rule_id)); |
| } |
| NOTREACHED(); |
| return std::string(); |
| } |
| |
| } // namespace |
| |
| ParseInfo::ParseInfo(size_t rules_count, |
| size_t regex_rules_count, |
| int ruleset_checksum, |
| std::vector<int> regex_limit_exceeded_rules) |
| : has_error_(false), |
| rules_count_(rules_count), |
| regex_rules_count_(regex_rules_count), |
| ruleset_checksum_(ruleset_checksum), |
| regex_limit_exceeded_rules_(std::move(regex_limit_exceeded_rules)) {} |
| |
| ParseInfo::ParseInfo(ParseResult error_reason, const int* rule_id) |
| : has_error_(true), |
| error_(GetError(error_reason, rule_id)), |
| error_reason_(error_reason) {} |
| |
| ParseInfo::ParseInfo(ParseInfo&&) = default; |
| ParseInfo& ParseInfo::operator=(ParseInfo&&) = default; |
| ParseInfo::~ParseInfo() = default; |
| |
| } // namespace declarative_net_request |
| } // namespace extensions |