blob: c105f7c666b24454c141a0d8905b2f09ec45ca3a [file] [log] [blame]
// 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