AbstractOperations.cpp 2.6 KB

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