Cherry-pick c93cca1a0e69. rdar://problem/96912101

    [WebAuthn] CBOR encoded extensions not passed along during assertions
    https://bugs.webkit.org/show_bug.cgi?id=242913
    rdar://96912101

    Reviewed by Chris Dumez.

    * Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
    (+[_WKWebAuthenticationPanel convertToCoreRequestOptionsWithOptions:]):
    * Source/WTF/wtf/cocoa/SpanCocoa.h:
    (WTF::asUInt8Span):
    * Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp:
    (WebCore::AuthenticationExtensionsClientInputs::fromCBOR):
    * Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h:
    * Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
    (+[_WKWebAuthenticationPanel convertToCoreCreationOptionsWithOptions:]):
    (+[_WKWebAuthenticationPanel convertToCoreRequestOptionsWithOptions:]):
    Pass along CBOR encoded extension to ASC, use span to avoid copy. Rest of callsites to be fixed in
    https://bugs.webkit.org/show_bug.cgi?id=242919.

    Canonical link: https://commits.webkit.org/252626@main

Canonical link: https://commits.webkit.org/252432.14@safari-7614.1.22.0-branch
diff --git a/Source/WTF/wtf/cocoa/SpanCocoa.h b/Source/WTF/wtf/cocoa/SpanCocoa.h
index 47a96d6..3f16504 100644
--- a/Source/WTF/wtf/cocoa/SpanCocoa.h
+++ b/Source/WTF/wtf/cocoa/SpanCocoa.h
@@ -41,6 +41,12 @@
     return asBytes(data.get());
 }
 
+inline Span<const uint8_t> asUInt8Span(NSData* data)
+{
+    return { reinterpret_cast<const uint8_t*>(data.bytes), data.length };
+}
+
 }
 
 using WTF::asBytes;
+using WTF::asUInt8Span;
diff --git a/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp b/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp
index c7bb628..1d37c3a 100644
--- a/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp
+++ b/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.cpp
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-std::optional<AuthenticationExtensionsClientInputs> AuthenticationExtensionsClientInputs::fromCBOR(const Vector<uint8_t>& buffer)
+std::optional<AuthenticationExtensionsClientInputs> AuthenticationExtensionsClientInputs::fromCBOR(Span<const uint8_t> buffer)
 {
     std::optional<cbor::CBORValue> decodedValue = cbor::CBORReader::read(buffer);
     if (!decodedValue || !decodedValue->isMap())
diff --git a/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h b/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h
index 7d58a3a..2eefc57 100644
--- a/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h
+++ b/Source/WebCore/Modules/webauthn/AuthenticationExtensionsClientInputs.h
@@ -40,7 +40,7 @@
     template<class Decoder> static std::optional<AuthenticationExtensionsClientInputs> decode(Decoder&);
 
     WEBCORE_EXPORT Vector<uint8_t> toCBOR() const;
-    WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientInputs> fromCBOR(const Vector<uint8_t>&);
+    WEBCORE_EXPORT static std::optional<AuthenticationExtensionsClientInputs> fromCBOR(Span<const uint8_t>);
 };
 
 template<class Encoder>
diff --git a/Source/WebCore/Modules/webauthn/cbor/CBORReader.cpp b/Source/WebCore/Modules/webauthn/cbor/CBORReader.cpp
index 13c80fa..16fd3ac 100644
--- a/Source/WebCore/Modules/webauthn/cbor/CBORReader.cpp
+++ b/Source/WebCore/Modules/webauthn/cbor/CBORReader.cpp
@@ -68,7 +68,7 @@
 
 } // namespace
 
-CBORReader::CBORReader(Bytes::const_iterator it, Bytes::const_iterator end)
+CBORReader::CBORReader(Bytes::iterator it, Bytes::iterator end)
     : m_it(it)
     , m_end(end)
     , m_errorCode(DecoderError::CBORNoError)
@@ -239,7 +239,7 @@
         return std::nullopt;
     }
 
-    Bytes cborByteString;
+    Vector<uint8_t> cborByteString;
     ASSERT(numBytes <= std::numeric_limits<size_t>::max());
     cborByteString.append(m_it, static_cast<size_t>(numBytes));
     m_it += numBytes;
diff --git a/Source/WebCore/Modules/webauthn/cbor/CBORReader.h b/Source/WebCore/Modules/webauthn/cbor/CBORReader.h
index 16164de..b8f35cd 100644
--- a/Source/WebCore/Modules/webauthn/cbor/CBORReader.h
+++ b/Source/WebCore/Modules/webauthn/cbor/CBORReader.h
@@ -72,7 +72,7 @@
 class CBORReader {
     WTF_MAKE_NONCOPYABLE(CBORReader);
 public:
-    using Bytes = Vector<uint8_t>;
+    using Bytes = Span<const uint8_t>;
 
     enum class DecoderError {
         CBORNoError = 0,
@@ -107,7 +107,7 @@
     static const char* errorCodeToString(DecoderError errorCode);
 
 private:
-    CBORReader(Bytes::const_iterator, const Bytes::const_iterator);
+    CBORReader(Bytes::iterator, const Bytes::iterator);
     std::optional<CBORValue> decodeCBOR(int maxNestingLevel);
     std::optional<CBORValue> decodeValueToNegative(uint64_t value);
     std::optional<CBORValue> decodeValueToUnsigned(uint64_t value);
@@ -126,8 +126,8 @@
 
     DecoderError getErrorCode();
 
-    Bytes::const_iterator m_it;
-    const Bytes::const_iterator m_end;
+    Bytes::iterator m_it;
+    const Bytes::iterator m_end;
     DecoderError m_errorCode;
 };
 
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm
index 8e4824b..c84c514 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm
@@ -62,6 +62,7 @@
 #import <pal/crypto/CryptoDigest.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
+#import <wtf/cocoa/SpanCocoa.h>
 #import <wtf/cocoa/TypeCastsCocoa.h>
 #import <wtf/cocoa/VectorCocoa.h>
 #import <wtf/text/Base64.h>
@@ -930,7 +931,7 @@
         result.authenticatorSelection = authenticatorSelectionCriteria(options.authenticatorSelection);
     result.attestation = attestationConveyancePreference(options.attestation);
     if (options.extensionsCBOR)
-        result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(vectorFromNSData(options.extensionsCBOR));
+        result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(asUInt8Span(options.extensionsCBOR));
     else
         result.extensions = authenticationExtensionsClientInputs(options.extensions);
 #endif
@@ -1014,7 +1015,10 @@
         result.allowCredentials = publicKeyCredentialDescriptors(options.allowCredentials);
     result.userVerification = userVerification(options.userVerification);
     result.authenticatorAttachment = authenticatorAttachment(options.authenticatorAttachment);
-    result.extensions = authenticationExtensionsClientInputs(options.extensions);
+    if (options.extensionsCBOR)
+        result.extensions = WebCore::AuthenticationExtensionsClientInputs::fromCBOR(asUInt8Span(options.extensionsCBOR));
+    else
+        result.extensions = authenticationExtensionsClientInputs(options.extensions);
 #endif
 
     return result;