integrity-metadata = *WSP hash-with-options *(1*WSP hash-with-options) *WSP hash-with-options = hash-expression *("?" option-expression) hash-expression = hash-algorithm "-" base64-value hash-algorithm = "sha256" / "sha384" / "sha512" base64-value = *VCHAR (visible chars, no whitespace)
| 115 | // hash-algorithm = "sha256" / "sha384" / "sha512" |
| 116 | // base64-value = *VCHAR (visible chars, no whitespace) |
| 117 | bool isIntegrityMetadata(std::string_view Input) { |
| 118 | while (!Input.empty() && Input.front() == ' ') |
| 119 | Input.remove_prefix(1); |
| 120 | while (!Input.empty() && Input.back() == ' ') |
| 121 | Input.remove_suffix(1); |
| 122 | if (Input.empty()) |
| 123 | return false; |
| 124 | |
| 125 | bool HasToken = false; |
| 126 | while (!Input.empty()) { |
| 127 | while (!Input.empty() && Input.front() == ' ') |
| 128 | Input.remove_prefix(1); |
| 129 | if (Input.empty()) |
| 130 | break; |
| 131 | |
| 132 | size_t TokenEnd = Input.find(' '); |
| 133 | std::string_view Token = |
| 134 | (TokenEnd == Input.npos) ? Input : Input.substr(0, TokenEnd); |
| 135 | Input = |
| 136 | (TokenEnd == Input.npos) ? std::string_view{} : Input.substr(TokenEnd); |
| 137 | |
| 138 | size_t OptPos = Token.find('?'); |
| 139 | std::string_view HashExpr = |
| 140 | (OptPos == Token.npos) ? Token : Token.substr(0, OptPos); |
| 141 | |
| 142 | bool ValidAlgo = false; |
| 143 | static constexpr std::string_view Algos[3] = {"sha256-", "sha384-", |
| 144 | "sha512-"}; |
| 145 | for (auto AlgoSV : Algos) { |
| 146 | if (HashExpr.size() > AlgoSV.size() && |
| 147 | HashExpr.substr(0, AlgoSV.size()) == AlgoSV) { |
| 148 | auto Value = HashExpr.substr(AlgoSV.size()); |
| 149 | if (std::all_of(Value.begin(), Value.end(), |
| 150 | [](char C) { return C >= 0x21 && C <= 0x7E; })) { |
| 151 | ValidAlgo = true; |
| 152 | } |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | if (!ValidAlgo) |
| 157 | return false; |
| 158 | |
| 159 | HasToken = true; |
| 160 | } |
| 161 | |
| 162 | return HasToken; |
| 163 | } |
| 164 | |
| 165 | // Parses a non-negative integer without leading zeros. |
| 166 | // Returns the end position, or npos on failure. |