Serenity Operating System
at master 81 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/GenericLexer.h> 8#include <AK/String.h> 9#include <AK/StringBuilder.h> 10#include <LibWeb/Fetch/Infrastructure/HTTP.h> 11 12namespace Web::Fetch::Infrastructure { 13 14// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string 15ErrorOr<String> collect_an_http_quoted_string(GenericLexer& lexer, HttpQuotedStringExtractValue extract_value) 16{ 17 // To collect an HTTP quoted string from a string input, given a position variable position and optionally an extract-value flag, run these steps: 18 // 1. Let positionStart be position. 19 auto position_start = lexer.tell(); 20 21 // 2. Let value be the empty string. 22 StringBuilder value; 23 24 // 3. Assert: the code point at position within input is U+0022 ("). 25 VERIFY(lexer.peek() == '"'); 26 27 // 4. Advance position by 1. 28 lexer.ignore(1); 29 30 // 5. While true: 31 while (true) { 32 // 1. Append the result of collecting a sequence of code points that are not U+0022 (") or U+005C (\) from input, given position, to value. 33 auto value_part = lexer.consume_until([](char ch) { 34 return ch == '"' || ch == '\\'; 35 }); 36 37 value.append(value_part); 38 39 // 2. If position is past the end of input, then break. 40 if (lexer.is_eof()) 41 break; 42 43 // 3. Let quoteOrBackslash be the code point at position within input. 44 // 4. Advance position by 1. 45 char quote_or_backslash = lexer.consume(); 46 47 // 5. If quoteOrBackslash is U+005C (\), then: 48 if (quote_or_backslash == '\\') { 49 // 1. If position is past the end of input, then append U+005C (\) to value and break. 50 if (lexer.is_eof()) { 51 value.append('\\'); 52 break; 53 } 54 55 // 2. Append the code point at position within input to value. 56 // 3. Advance position by 1. 57 value.append(lexer.consume()); 58 } 59 60 // 6. Otherwise: 61 else { 62 // 1. Assert: quoteOrBackslash is U+0022 ("). 63 VERIFY(quote_or_backslash == '"'); 64 65 // 2. Break. 66 break; 67 } 68 } 69 70 // 6. If the extract-value flag is set, then return value. 71 if (extract_value == HttpQuotedStringExtractValue::Yes) 72 return value.to_string(); 73 74 // 7. Return the code points from positionStart to position, inclusive, within input. 75 auto position = lexer.tell(); 76 auto number_of_characters_to_consume = position - position_start + 1; 77 lexer.retreat(number_of_characters_to_consume); 78 return String::from_utf8(lexer.consume(number_of_characters_to_consume)); 79} 80 81}