| // 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_ |