Какой тип URL-адреса не соответствует RFC 3986, но соответствует RFC 1808, RFC 1738 и RFC 2732?

Документ URLComponents.init(url:resolvingAgainstBaseURL:) говорит:

Returns the initialized URL components object, or nil if the URL could not be parsed.

Знаю это:

Я предполагаю, что инициализация URLComponents завершится ошибкой, если URL-адрес соответствует RFC 1808/1738/2732, но не RFC 3986. Что это за URL? Любой пример?

Единственный намек, который у меня есть, насколько разница может быть связана с разными зарезервированными символами?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
911
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Давайте рассмотрим его из исходного кода, поскольку Swift Foundation является открытым исходным кодом.

  1. Инициализатор URLComponents реализован в яблоко/свифт – URLComponents.swift и apple/swift-corelibs-foundation – URLComponents.swift и просто вызывает инициализатор NSURLComponents.

  2. Инициализатор NSURLComponents реализован в apple/swift-corelibs-foundation – NSURL.swift и просто вызывает _CFURLComponentsCreateWithURL.

  3. _CFURLComponentsCreateWithURL реализован в apple/swift-corelibs-foundation — CFURLComponents.c и выполняет:

    • неудачная копия с CFURLCopyAbsoluteURL
    • неудачное создание с _CFURLComponentsCreateWithString, которое вызывает:
      • _CFURIParserParseURIReference + неудачный _CFURIParserURLStringIsValid
  4. CFURLCopyAbsoluteURL реализован в apple/swift-corelibs-foundation – CFURL.c и не работает только для:

    #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        if ( base && CFURLIsFileReferenceURL(base) && !CFURLHasDirectoryPath(base) ) {
            // 16695827 - If the base URL is a file reference URL which doesn't end with a slash, we have to convert it to a file path URL before we can make it absolute.
            base = CFURLCreateFilePathURL(alloc, base, NULL);
            if ( !base ) {
                // could not convert file reference URL to file path URL -- fail will NULL
                return NULL;
            }
        }
    #endif
    

    Реализация CFURLCreateFilePathURL находится в opensource.apple.com/source/CF — CFURL.c, и я понимаю, что она завершится ошибкой только в том случае, если нет схемы или пути, что невозможно, поскольку мы ранее проверяли файловую схему или существование файла с помощью CFURLIsFileReferenceURL.

  5. _CFURIParserParseURIReference реализован в apple/swift-corelibs-foundation — CFURLComponents_URIParser.c и будет давать сбой только в том случае, если длина URL-адреса превышает 2 ГБ, что, как я полагаю, не связано со спецификациями RFC.

  6. _CFURIParserURLStringIsValid по существу вызовет _CFURIParserValidateComponent для каждого компонента и завершится ошибкой для недопустимых символов или escape-последовательностей. Это, пожалуй, самая актуальная часть.

Теперь, немного поэкспериментировав, мы знаем, что нам нужна схема (например, https:// или просто a://), и мы играем с зарезервированными символами, чтобы придумать такие примеры, как:

// OK
let url = URL(string: "a://@@")!
// CRASH
let components = URLComponents(url: url, resolvingAgainstBaseURL: true)!

Попытка альтернативного инициализатора URLComponents также потерпит неудачу, поэтому не пытайтесь думать, что он другой:

// CRASH
let components = URLComponents(string: url.absoluteString)!

Заключение

"a://@@" является примером действительного NSURL, но недопустимого RFC 3986.


Кстати, некоторые пользователи Swift, похоже, хотят в будущем унифицировать поддержку URL и URLComponents (больше никаких различий RFC) как показано в URL.swift:

// Future implementation note:
// NSURL (really CFURL, which provides its implementation) has quite a few quirks in its processing of some more esoteric (and some not so esoteric) strings. We would like to move much of this over to the more modern NSURLComponents, but binary compat concerns have made this difficult.
// Hopefully soon, we can replace some of the below delegation to NSURL with delegation to NSURLComponents instead. It cannot be done piecemeal, because otherwise we will get inconsistent results from the API.

Я не уверен, как они планируют это сделать, так как это будет означать, что либо URL(string: "a://@@") потерпит неудачу, либо URLComponents(string: "a://@@") преуспеет.

Это действительно интересно, спасибо! Также помог мне избавиться от одной красной строки, которая беспокоила меня в моем отчете о покрытии кода, хотя это такой крайний случай!

Tim 10.05.2019 22:54

Умная колбаса :-)

pikuseru 11.11.2021 13:09

Другие вопросы по теме