chromium/components/policy/core/common/schema.cc

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "components/policy/core/common/schema.h"

#include <limits.h>
#include <stddef.h>

#include <algorithm>
#include <climits>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <utility>

#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/containers/flat_set.h"
#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/values.h"
#include "components/policy/core/common/json_schema_constants.h"
#include "components/policy/core/common/schema_internal.h"
#include "third_party/re2/src/re2/re2.h"

schema;

namespace policy {

PropertiesNode;
PropertyNode;
RestrictionNode;
SchemaData;
SchemaNode;

std::string ErrorPathToString(const std::string& policy_name,
                              PolicyErrorPath error_path) {}

const char kSensitiveValueMask[] =;

namespace {

struct ReferencesAndIDs {};

// Sizes for the storage arrays. These are calculated in advance so that the
// arrays don't have to be resized during parsing, which would invalidate
// pointers into their contents (i.e. string's c_str() and address of indices
// for "$ref" attributes).
struct StorageSizes {};

// An invalid index, indicating that a node is not present; similar to a NULL
// pointer.
const short kInvalid =;

// Maps a schema key to the corresponding base::Value::Type
struct SchemaKeyToValueType {};

// Allowed types and their base::Value::Type equivalent. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kSchemaTypesToValueTypes[] =;
const SchemaKeyToValueType* kSchemaTypesToValueTypesEnd =;

// Allowed attributes and types for type 'array'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForArray[] =;
const SchemaKeyToValueType* kAttributesAndTypesForArrayEnd =;

// Allowed attributes and types for type 'boolean'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForBoolean[] =;
const SchemaKeyToValueType* kAttributesAndTypesForBooleanEnd =;

// Allowed attributes and types for type 'integer'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForInteger[] =;
const SchemaKeyToValueType* kAttributesAndTypesForIntegerEnd =;

// Allowed attributes and types for type 'number'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForNumber[] =;
const SchemaKeyToValueType* kAttributesAndTypesForNumberEnd =;

// Allowed attributes and types for type 'object'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForObject[] =;
const SchemaKeyToValueType* kAttributesAndTypesForObjectEnd =;

// Allowed attributes and types for $ref. These are ordered alphabetically to
// perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForRef[] =;
const SchemaKeyToValueType* kAttributesAndTypesForRefEnd =;

// Allowed attributes and types for type 'string'. These are ordered
// alphabetically to perform binary search.
const SchemaKeyToValueType kAttributesAndTypesForString[] =;
const SchemaKeyToValueType* kAttributesAndTypesForStringEnd =;

// Helper for std::lower_bound.
bool CompareToString(const SchemaKeyToValueType& entry,
                     const std::string& key) {}

// Returns true if a SchemaKeyToValueType with key==|schema_key| can be found in
// the array represented by |begin| and |end|. If so, |value_type| will be set
// to the SchemaKeyToValueType value type.
bool MapSchemaKeyToValueType(const std::string& schema_key,
                             const SchemaKeyToValueType* begin,
                             const SchemaKeyToValueType* end,
                             base::Value::Type* value_type) {}

// Shorthand method for |SchemaTypeToValueType()| with
// |kSchemaTypesToValueTypes|.
bool SchemaTypeToValueType(const std::string& schema_type,
                           base::Value::Type* value_type) {}

bool StrategyAllowUnknown(SchemaOnErrorStrategy strategy) {}

bool StrategyAllowInvalidListEntry(SchemaOnErrorStrategy strategy) {}

bool StrategyAllowUnknownWithoutWarning(SchemaOnErrorStrategy strategy) {}

void SchemaErrorFound(PolicyErrorPath* out_error_path,
                      std::string* out_error,
                      const std::string& msg) {}

void AddListIndexPrefixToPath(int index, PolicyErrorPath* path) {}

void AddDictKeyPrefixToPath(const std::string& key, PolicyErrorPath* path) {}

bool IgnoreUnknownAttributes(int options) {}

// Check that the value's type and the expected type are equal. We also allow
// integers when expecting doubles.
bool CheckType(const base::Value* value, base::Value::Type expected_type) {}

// Returns true if |type| is supported as schema's 'type' value.
bool IsValidType(const std::string& type) {}

// Validate that |dict| only contains attributes that are allowed for the
// corresponding value of 'type'. Also ensure that all of those attributes are
// of the expected type. |options| can be used to ignore unknown attributes.
base::expected<void, std::string> ValidateAttributesAndTypes(
    const base::Value::Dict& dict,
    const std::string& type,
    int options) {}

// Validates that |enum_list| is a list and its items are all of type |type|.
base::expected<void, std::string> ValidateEnum(const base::Value* enum_list,
                                               const std::string& type) {}

// Forward declaration (used in ValidateProperties).
base::expected<void, std::string> IsValidSchema(const base::Value::Dict& dict,
                                                int options);

// Validates that the values in the |properties| dict are valid schemas.
base::expected<void, std::string> ValidateProperties(
    const base::Value::Dict& properties,
    int options) {}

base::expected<void, std::string> IsFieldTypeObject(
    const base::Value& field,
    const std::string& field_name) {}

// Checks whether the passed dict is a valid schema. See
// |kAllowedAttributesAndTypes| for a list of supported types, supported
// attributes and their expected types. Values for 'minimum' and 'maximum' for
// type 'integer' can be of type int or double. Referenced IDs ($ref) are not
// checked for existence and IDs are not checked for duplicates. The 'pattern'
// attribute and keys for 'patternProperties' are not checked for valid regular
// expression syntax. Invalid regular expressions will cause a value validation
// error.
base::expected<void, std::string> IsValidSchema(const base::Value::Dict& dict,
                                                int options) {}

}  // namespace

// Contains the internal data representation of a Schema. This can either wrap
// a SchemaData owned elsewhere (currently used to wrap the Chrome schema, which
// is generated at compile time), or it can own its own SchemaData.
class Schema::InternalStorage
    : public base::RefCountedThreadSafe<InternalStorage> {};

Schema::InternalStorage::InternalStorage() = default;

Schema::InternalStorage::~InternalStorage() = default;

// static
scoped_refptr<const Schema::InternalStorage> Schema::InternalStorage::Wrap(
    const SchemaData* data) {}

// static
base::expected<scoped_refptr<const Schema::InternalStorage>, std::string>
Schema::InternalStorage::ParseSchema(const base::Value::Dict& schema) {}

re2::RE2* Schema::InternalStorage::CompileRegex(
    const std::string& pattern) const {}

// static
void Schema::InternalStorage::DetermineStorageSizes(
    const base::Value::Dict& schema,
    StorageSizes* sizes) {}

base::expected<void, std::string> Schema::InternalStorage::Parse(
    const base::Value::Dict& schema,
    short* index,
    ReferencesAndIDs* references_and_ids) {}

base::expected<void, std::string> Schema::InternalStorage::ParseDictionary(
    const base::Value::Dict& schema,
    SchemaNode* schema_node,
    ReferencesAndIDs* references_and_ids) {}

base::expected<void, std::string> Schema::InternalStorage::ParseList(
    const base::Value::Dict& schema,
    SchemaNode* schema_node,
    ReferencesAndIDs* references_and_ids) {}

base::expected<void, std::string> Schema::InternalStorage::ParseEnum(
    const base::Value::Dict& schema,
    base::Value::Type type,
    SchemaNode* schema_node) {}

base::expected<void, std::string> Schema::InternalStorage::ParseRangedInt(
    const base::Value::Dict& schema,
    SchemaNode* schema_node) {}

base::expected<void, std::string> Schema::InternalStorage::ParseStringPattern(
    const base::Value::Dict& schema,
    SchemaNode* schema_node) {}

// static
bool Schema::InternalStorage::ResolveReferences(
    const ReferencesAndIDs& references_and_ids,
    std::string* error) {}

void Schema::InternalStorage::FindSensitiveChildren() {}

bool Schema::InternalStorage::FindSensitiveChildrenRecursive(
    int index,
    std::set<int>* handled_schema_nodes) {}

Schema::Iterator::Iterator(const scoped_refptr<const InternalStorage>& storage,
                           const PropertiesNode* node) {}

Schema::Iterator::Iterator(const Iterator& iterator)
    :{}

Schema::Iterator::~Iterator() = default;

Schema::Iterator& Schema::Iterator::operator=(const Iterator& iterator) {}

bool Schema::Iterator::IsAtEnd() const {}

void Schema::Iterator::Advance() {}

const char* Schema::Iterator::key() const {}

Schema Schema::Iterator::schema() const {}

Schema::Schema() :{}

Schema::Schema(const scoped_refptr<const InternalStorage>& storage,
               const SchemaNode* node)
    :{}

Schema::Schema(const Schema& schema)
    :{}

Schema::~Schema() = default;

Schema& Schema::operator=(const Schema& schema) {}

// static
Schema Schema::Wrap(const SchemaData* data) {}

bool Schema::Validate(const base::Value& value,
                      SchemaOnErrorStrategy strategy,
                      PolicyErrorPath* out_error_path,
                      std::string* out_error) const {}

bool Schema::Normalize(base::Value* value,
                       SchemaOnErrorStrategy strategy,
                       PolicyErrorPath* out_error_path,
                       std::string* out_error,
                       bool* out_changed) const {}

void Schema::MaskSensitiveValues(base::Value* value) const {}

// static
base::expected<Schema, std::string> Schema::Parse(const std::string& content) {}

// static
base::expected<base::Value::Dict, std::string> Schema::ParseToDictAndValidate(
    const std::string& schema,
    int validator_options) {}

base::Value::Type Schema::type() const {}

Schema::Iterator Schema::GetPropertiesIterator() const {}

namespace {

bool CompareKeys(const PropertyNode& node, const std::string& key) {}

}  // namespace

Schema Schema::GetKnownProperty(const std::string& key) const {}

Schema Schema::GetAdditionalProperties() const {}

SchemaList Schema::GetPatternProperties(const std::string& key) const {}

std::vector<std::string> Schema::GetRequiredProperties() const {}

Schema Schema::GetProperty(const std::string& key) const {}

SchemaList Schema::GetMatchingProperties(const std::string& key) const {}

Schema Schema::GetItems() const {}

bool Schema::ValidateIntegerRestriction(int index, int value) const {}

bool Schema::ValidateStringRestriction(int index, const char* str) const {}

void Schema::MaskSensitiveValuesRecursive(base::Value* value) const {}

Schema Schema::GetValidationSchema() const {}

bool Schema::IsSensitiveValue() const {}

bool Schema::HasSensitiveChildren() const {}

}  // namespace policy