blob: cee88f4a17deee4f943351b303501b9c337192a2 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIBIPP_VALIDATOR_H_
#define LIBIPP_VALIDATOR_H_
#include <cstddef>
#include <cstdint>
#include <set>
#include <string>
#include <string_view>
#include <vector>
#include "errors.h"
#include "frame.h"
#include "ipp_export.h"
namespace ipp {
// Maximum size of 'text' value (rfc8011, section 5.1.2).
constexpr size_t kMaxLengthOfText = 1023;
// Maximum size of 'name' value (rfc8011, section 5.1.3).
constexpr size_t kMaxLengthOfName = 255;
// Maximum size of 'keyword' value (rfc8011, section 5.1.4).
constexpr size_t kMaxLengthOfKeyword = 255;
// Maximum size of 'uri' value (rfc8011, section 5.1.6).
constexpr size_t kMaxLengthOfUri = 1023;
// Maximum size of 'uriScheme' value (rfc8011, section 5.1.7).
constexpr size_t kMaxLengthOfUriScheme = 63;
// Maximum size of 'charset' value (rfc8011, section 5.1.8).
constexpr size_t kMaxLengthOfCharset = 63;
// Maximum size of 'naturalLanguage' value (rfc8011, section 5.1.9).
constexpr size_t kMaxLengthOfNaturalLanguage = 63;
// Maximum size of 'mimeMediaType' value (rfc8011, section 5.1.10).
constexpr size_t kMaxLengthOfMimeMediaType = 255;
// Maximum size of 'octetString' value (rfc8011, section 5.1.11).
constexpr size_t kMaxLengthOfOctetString = 1023;
// Describes types of validation errors in a single value.
enum class ValidatorCode : uint8_t {
// The string value is empty when it is not allowed.
kStringEmpty = 0,
// The string value is too long.
kStringTooLong,
// The string value is supposed to start with a lowercase letter and it
// doesn't.
kStringMustStartLowercaseLetter,
// The string value contains invalid character.
kStringInvalidCharacter,
// The value of type textWithLanguage or nameWithLanguage has invalid language
// part.
kStringWithLangInvalidLanguage,
// The dateTime value has invalid date.
kDateTimeInvalidDate,
// The dateTime value has invalid time of day.
kDateTimeInvalidTimeOfDay,
// The dateTime value has invalid timezone.
kDateTimeInvalidZone,
// The resolution value has invalid units.
kResolutionInvalidUnit,
// The resolution value has at least one invalid dimension.
kResolutionInvalidDimension,
// The rangeOfIntegers value has min threshold larger than max threshold.
kRangeOfIntegerMaxLessMin,
// The integer value is out of allowed range.
kIntegerOutOfRange
};
// Returns a string representation of `code`. Returned string contains a name
// of corresponding enum's value and has no whitespaces.
LIBIPP_EXPORT std::string_view ToStrView(ValidatorCode code);
// Represents information about invalid value or name of an attribute.
class LIBIPP_EXPORT AttrError {
public:
// `errors` contains validation errors of an attribute's name.
explicit AttrError(std::set<ValidatorCode>&& errors)
: index_(0xffffu), errors_(errors) {}
// `errors` contains validation errors for the value at `index`.
AttrError(uint16_t index, std::set<ValidatorCode>&& errors)
: index_(index), errors_(errors) {}
// Returns true if it is about the attribute's name.
bool IsInTheName() const { return Index() == 0xffffu; }
// Returns the index of the incorrect value or 0xffff if it is about
// the attribute's name.
uint16_t Index() const { return index_; }
// Returns errors as SetOfErrors.
const std::set<ValidatorCode> Errors() const { return errors_; }
// Returns errors as vector. Codes in the vector are sorted and unique.
std::vector<ValidatorCode> ErrorsAsVector() const;
private:
uint16_t index_;
std::set<ValidatorCode> errors_;
};
// The structure represents an `error` for the attribute at `path`.
struct ValidatorError {
AttrPath path;
AttrError error;
};
// Returns one-line string representation of the `error`. There is no EOL
// characters in the returned message.
LIBIPP_EXPORT std::string ToString(const ValidatorError& error);
// The interface of validator log.
class ValidatorLog {
public:
ValidatorLog() = default;
ValidatorLog(const ValidatorLog&) = delete;
ValidatorLog& operator=(const ValidatorLog&) = delete;
virtual ~ValidatorLog() = default;
// Reports an `error` found by the validator. The errors are reported in
// the same order as they occurred in the frame. Return false if you do not
// want to get any more AddValidationError() calls.
virtual bool AddValidatorError(const ValidatorError& error) = 0;
};
// Simple implementation of the ValidatorLog interface. It just saves the first
// `max_entries_count` (see the constructor) errors in the frame.
class LIBIPP_EXPORT SimpleValidatorLog : public ValidatorLog {
public:
explicit SimpleValidatorLog(size_t max_entries_count = 100)
: max_entries_count_(max_entries_count) {}
bool AddValidatorError(const ValidatorError& error) override;
const std::vector<ValidatorError>& Entries() const { return entries_; }
private:
const size_t max_entries_count_;
std::vector<ValidatorError> entries_;
};
// Validates all groups in the `frame`. All detected errors are saved in `log`
// in the order they occur in the original frame. The function returns true <=>
// no errors were detected.
// For string types only the basic features are validated, there is no UTF-8
// parsing or type-specific parsing like URL or MIME types.
bool LIBIPP_EXPORT Validate(const Frame& frame, ValidatorLog& log);
} // namespace ipp
#endif // LIBIPP_VALIDATOR_H_