[EME] Correctly report errors when generating key requests from AVContentKeySession.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jan 2016 17:15:16 +0000 (17:15 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jan 2016 17:15:16 +0000 (17:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=151963

Reviewed by Eric Carlson.

WebIDL's "unsigned long" is a 32-bit unsigned integer, and C++'s "unsigned long" is (or, can
be) a 64-bit integer on 64-bit platforms. Casting a negative integer to a 64-bit integer
results in a number which cannot be accurately stored in a double-length floating point
number. Previously, the mac CDM code would work around this issue by returning the absolute
value of NSError code returned by media frameworks. Instead, fix the underlying problem by
storing the MediaKeyError's systemCode as a uint32_t (which more accurately represents the
size of a WebIDL "unsigned long" on all platforms.)

Check the error code issued by -contentKeyRequestDataForApp:contentIdentifier:options:error:.

* Modules/encryptedmedia/CDM.h:
* Modules/encryptedmedia/CDMSessionClearKey.cpp:
(WebCore::CDMSessionClearKey::generateKeyRequest):
(WebCore::CDMSessionClearKey::update):
* Modules/encryptedmedia/CDMSessionClearKey.h:
* Modules/encryptedmedia/MediaKeySession.cpp:
(WebCore::MediaKeySession::keyRequestTimerFired):
(WebCore::MediaKeySession::addKeyTimerFired):
(WebCore::MediaKeySession::sendError):
* Modules/encryptedmedia/MediaKeySession.h:
* Modules/mediacontrols/mediaControlsApple.js:
(Controller.prototype.handleReadyStateChange):
* WebCore.xcodeproj/project.pbxproj:
* html/MediaKeyError.h:
(WebCore::MediaKeyError::create):
(WebCore::MediaKeyError::systemCode):
* html/MediaKeyEvent.h:
* platform/graphics/CDMSession.h:
* platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.cpp:
(WebCore::CDMSessionAVFoundationCF::generateKeyRequest):
(WebCore::CDMSessionAVFoundationCF::update):
* platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.h:
* platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h:
* platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
(WebCore::CDMSessionAVContentKeySession::generateKeyRequest):
(WebCore::CDMSessionAVContentKeySession::update):
(WebCore::CDMSessionAVContentKeySession::generateKeyReleaseMessage):
* platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.mm:
(WebCore::CDMSessionAVFoundationObjC::generateKeyRequest):
(WebCore::CDMSessionAVFoundationObjC::update):
* platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h:
* platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm:
(WebCore::CDMSessionAVStreamSession::generateKeyRequest):
(WebCore::CDMSessionAVStreamSession::update):
(WebCore::CDMSessionAVStreamSession::generateKeyReleaseMessage):
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
(WebCore::CDMSessionMediaSourceAVFObjC::layerDidReceiveError):
(WebCore::CDMSessionMediaSourceAVFObjC::rendererDidReceiveError):
(WebCore::CDMSessionMediaSourceAVFObjC::systemCodeForError): Deleted.
* testing/MockCDM.cpp:
(WebCore::MockCDMSession::generateKeyRequest):
(WebCore::MockCDMSession::update):2016-01-15  Simon Fraser  <simon.fraser@apple.com>

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195410 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/encryptedmedia/CDM.h
Source/WebCore/Modules/encryptedmedia/CDMSessionClearKey.cpp
Source/WebCore/Modules/encryptedmedia/CDMSessionClearKey.h
Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp
Source/WebCore/Modules/encryptedmedia/MediaKeySession.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/MediaKeyError.h
Source/WebCore/html/MediaKeyEvent.h
Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.h [new file with mode: 0644]
Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.mm [new file with mode: 0644]
Source/WebCore/platform/graphics/CDMSession.h
Source/WebCore/platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.cpp
Source/WebCore/platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.h
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm
Source/WebCore/testing/MockCDM.cpp

index 578a1b1..d313c37 100644 (file)
@@ -1,3 +1,65 @@
+2016-01-21  Jer Noble  <jer.noble@apple.com>
+
+        [EME] Correctly report errors when generating key requests from AVContentKeySession.
+        https://bugs.webkit.org/show_bug.cgi?id=151963
+
+        Reviewed by Eric Carlson.
+
+        WebIDL's "unsigned long" is a 32-bit unsigned integer, and C++'s "unsigned long" is (or, can
+        be) a 64-bit integer on 64-bit platforms. Casting a negative integer to a 64-bit integer
+        results in a number which cannot be accurately stored in a double-length floating point
+        number. Previously, the mac CDM code would work around this issue by returning the absolute
+        value of NSError code returned by media frameworks. Instead, fix the underlying problem by
+        storing the MediaKeyError's systemCode as a uint32_t (which more accurately represents the
+        size of a WebIDL "unsigned long" on all platforms.)
+
+        Check the error code issued by -contentKeyRequestDataForApp:contentIdentifier:options:error:.
+
+        * Modules/encryptedmedia/CDM.h:
+        * Modules/encryptedmedia/CDMSessionClearKey.cpp:
+        (WebCore::CDMSessionClearKey::generateKeyRequest):
+        (WebCore::CDMSessionClearKey::update):
+        * Modules/encryptedmedia/CDMSessionClearKey.h:
+        * Modules/encryptedmedia/MediaKeySession.cpp:
+        (WebCore::MediaKeySession::keyRequestTimerFired):
+        (WebCore::MediaKeySession::addKeyTimerFired):
+        (WebCore::MediaKeySession::sendError):
+        * Modules/encryptedmedia/MediaKeySession.h:
+        * Modules/mediacontrols/mediaControlsApple.js:
+        (Controller.prototype.handleReadyStateChange):
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/MediaKeyError.h:
+        (WebCore::MediaKeyError::create):
+        (WebCore::MediaKeyError::systemCode):
+        * html/MediaKeyEvent.h:
+        * platform/graphics/CDMSession.h:
+        * platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.cpp:
+        (WebCore::CDMSessionAVFoundationCF::generateKeyRequest):
+        (WebCore::CDMSessionAVFoundationCF::update):
+        * platform/graphics/avfoundation/cf/CDMSessionAVFoundationCF.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
+        (WebCore::CDMSessionAVContentKeySession::generateKeyRequest):
+        (WebCore::CDMSessionAVContentKeySession::update):
+        (WebCore::CDMSessionAVContentKeySession::generateKeyReleaseMessage):
+        * platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVFoundationObjC.mm:
+        (WebCore::CDMSessionAVFoundationObjC::generateKeyRequest):
+        (WebCore::CDMSessionAVFoundationObjC::update):
+        * platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm:
+        (WebCore::CDMSessionAVStreamSession::generateKeyRequest):
+        (WebCore::CDMSessionAVStreamSession::update):
+        (WebCore::CDMSessionAVStreamSession::generateKeyReleaseMessage):
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
+        (WebCore::CDMSessionMediaSourceAVFObjC::layerDidReceiveError):
+        (WebCore::CDMSessionMediaSourceAVFObjC::rendererDidReceiveError):
+        (WebCore::CDMSessionMediaSourceAVFObjC::systemCodeForError): Deleted.
+        * testing/MockCDM.cpp:
+        (WebCore::MockCDMSession::generateKeyRequest):
+        (WebCore::MockCDMSession::update):2016-01-15  Simon Fraser  <simon.fraser@apple.com>
+
 2016-01-21  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [SOUP] GResource resources should be cached indefinitely in memory cache
index 9bfd1bc..81d2da9 100644 (file)
@@ -55,7 +55,7 @@ class CDM {
 public:
     explicit CDM(const String& keySystem);
 
-    enum CDMErrorCode { UnknownError = 1, ClientError, ServiceError, OutputError, HardwareChangeError, DomainError };
+    enum CDMErrorCode { NoError, UnknownError, ClientError, ServiceError, OutputError, HardwareChangeError, DomainError };
     static bool supportsKeySystem(const String&);
     static bool keySystemSupportsMimeType(const String& keySystem, const String& mimeType);
     static std::unique_ptr<CDM> create(const String& keySystem);
index 9ec797f..589acd2 100644 (file)
@@ -69,7 +69,7 @@ CDMSessionClearKey::~CDMSessionClearKey()
 {
 }
 
-RefPtr<Uint8Array> CDMSessionClearKey::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
+RefPtr<Uint8Array> CDMSessionClearKey::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(mimeType);
     UNUSED_PARAM(destinationURL);
@@ -96,7 +96,7 @@ void CDMSessionClearKey::releaseKeys()
     m_cachedKeys.clear();
 }
 
-bool CDMSessionClearKey::update(Uint8Array* rawKeysData, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
+bool CDMSessionClearKey::update(Uint8Array* rawKeysData, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(nextMessage);
     UNUSED_PARAM(systemCode);
index e509fb6..4628709 100644 (file)
@@ -42,9 +42,9 @@ public:
     virtual CDMSessionType type() override { return CDMSessionTypeClearKey; }
     virtual void setClient(CDMSessionClient* client) override { m_client = client; }
     virtual const String& sessionId() const override { return m_sessionId; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array*, String&, unsigned short&, unsigned long&) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array*, String&, unsigned short&, uint32_t&) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>&, unsigned short&, unsigned long&) override;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>&, unsigned short&, uint32_t&) override;
     virtual RefPtr<ArrayBuffer> cachedKeyForKeyID(const String&) const override;
 
 protected:
index bf162de..873bc26 100644 (file)
@@ -111,7 +111,7 @@ void MediaKeySession::keyRequestTimerFired()
         // 2. Let destinationURL be null.
         String destinationURL;
         MediaKeyError::Code errorCode = 0;
-        unsigned long systemCode = 0;
+        uint32_t systemCode = 0;
 
         // 3. Use cdm to generate a key request and follow the steps for the first matching condition from the following list:
 
@@ -163,7 +163,7 @@ void MediaKeySession::addKeyTimerFired()
     while (!m_pendingKeys.isEmpty()) {
         RefPtr<Uint8Array> pendingKey = m_pendingKeys.takeFirst();
         unsigned short errorCode = 0;
-        unsigned long systemCode = 0;
+        uint32_t systemCode = 0;
 
         // NOTE: Continued from step 2. of MediaKeySession::update()
         // 2.1. Let cdm be the cdm loaded in the MediaKeys constructor.
@@ -219,7 +219,7 @@ void MediaKeySession::sendMessage(Uint8Array* message, String destinationURL)
     m_asyncEventQueue.enqueueEvent(event.release());
 }
 
-void MediaKeySession::sendError(CDMSessionClient::MediaKeyErrorCode errorCode, unsigned long systemCode)
+void MediaKeySession::sendError(CDMSessionClient::MediaKeyErrorCode errorCode, uint32_t systemCode)
 {
     Ref<MediaKeyError> error = MediaKeyError::create(errorCode, systemCode).get();
     setError(error.ptr());
index a46dba4..4b51714 100644 (file)
@@ -86,7 +86,7 @@ protected:
 
     // CDMSessionClient
     virtual void sendMessage(Uint8Array*, String destinationURL) override;
-    virtual void sendError(MediaKeyErrorCode, unsigned long systemCode) override;
+    virtual void sendError(MediaKeyErrorCode, uint32_t systemCode) override;
     virtual String mediaKeysStorageDirectory() const override;
 
     MediaKeys* m_keys;
index ad6da11..8cbfe82 100644 (file)
                CDC8B5AA18047FF10016E685 /* SourceBufferPrivateAVFObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC8B5A818047FF10016E685 /* SourceBufferPrivateAVFObjC.mm */; };
                CDC8B5AB18047FF10016E685 /* SourceBufferPrivateAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC8B5A918047FF10016E685 /* SourceBufferPrivateAVFObjC.h */; };
                CDC8B5AD1804AE5D0016E685 /* SourceBufferPrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC8B5AC1804AE5D0016E685 /* SourceBufferPrivateClient.h */; };
+               CDC979F41C498C0900DB50D4 /* WebCoreNSErrorExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDC979F21C498C0900DB50D4 /* WebCoreNSErrorExtras.mm */; };
+               CDC979F51C498C0900DB50D4 /* WebCoreNSErrorExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = CDC979F31C498C0900DB50D4 /* WebCoreNSErrorExtras.h */; };
                CDCA82961679100F00875714 /* TextTrackRepresentationIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDCA82941679100F00875714 /* TextTrackRepresentationIOS.mm */; };
                CDCA98EB18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCA98EA18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp */; };
                CDCFABBD18C0AF78006F8450 /* SelectionSubtreeRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CDC8B5A818047FF10016E685 /* SourceBufferPrivateAVFObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SourceBufferPrivateAVFObjC.mm; sourceTree = "<group>"; };
                CDC8B5A918047FF10016E685 /* SourceBufferPrivateAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceBufferPrivateAVFObjC.h; sourceTree = "<group>"; };
                CDC8B5AC1804AE5D0016E685 /* SourceBufferPrivateClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceBufferPrivateClient.h; sourceTree = "<group>"; };
+               CDC979F21C498C0900DB50D4 /* WebCoreNSErrorExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSErrorExtras.mm; sourceTree = "<group>"; };
+               CDC979F31C498C0900DB50D4 /* WebCoreNSErrorExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreNSErrorExtras.h; sourceTree = "<group>"; };
                CDCA82941679100F00875714 /* TextTrackRepresentationIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextTrackRepresentationIOS.mm; sourceTree = "<group>"; };
                CDCA98E918B2C8D000C12FF9 /* CDMPrivateMediaPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDMPrivateMediaPlayer.h; sourceTree = "<group>"; };
                CDCA98EA18B2C8EB00C12FF9 /* CDMPrivateMediaPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDMPrivateMediaPlayer.cpp; sourceTree = "<group>"; };
                                310D71931B335C9D009C7B73 /* ThemeCocoa.cpp */,
                                310D71941B335C9D009C7B73 /* ThemeCocoa.h */,
                                46DB7D561B20FE3C005651B2 /* VNodeTrackerCocoa.cpp */,
+                               CDC979F21C498C0900DB50D4 /* WebCoreNSErrorExtras.mm */,
+                               CDC979F31C498C0900DB50D4 /* WebCoreNSErrorExtras.h */,
                        );
                        path = cocoa;
                        sourceTree = "<group>";
                                316FE11A0E6E1DA700BF6088 /* KeyframeAnimation.h in Headers */,
                                BC5EBA110E823E4700B25965 /* KeyframeList.h in Headers */,
                                E15FF7D518C9553800FE4C87 /* KeypressCommand.h in Headers */,
+                               CDC979F51C498C0900DB50D4 /* WebCoreNSErrorExtras.h in Headers */,
                                521D46F811AEC9B100514613 /* KillRing.h in Headers */,
                                450CEBF115073BBE002BB149 /* LabelableElement.h in Headers */,
                                A456FA2711AD4A830020B420 /* LabelsNodeList.h in Headers */,
                                E16A84F914C85CCC002977DF /* CSSBorderImage.cpp in Sources */,
                                BC274B31140EBED800EADFA6 /* CSSBorderImageSliceValue.cpp in Sources */,
                                49AE2D8E134EE50C0072920A /* CSSCalculationValue.cpp in Sources */,
+                               CDC979F41C498C0900DB50D4 /* WebCoreNSErrorExtras.mm in Sources */,
                                BC604A430DB5634E00204739 /* CSSCanvasValue.cpp in Sources */,
                                E1EBBBD40AAC9B87001FE8E2 /* CSSCharsetRule.cpp in Sources */,
                                BCEA478F097CAAC80094C9E4 /* CSSComputedStyleDeclaration.cpp in Sources */,
index 115c961..487d465 100644 (file)
@@ -46,10 +46,10 @@ public:
     };
     typedef unsigned short Code;
 
-    static Ref<MediaKeyError> create(Code code, unsigned long systemCode = 0) { return adoptRef(*new MediaKeyError(code, systemCode)); }
+    static Ref<MediaKeyError> create(Code code, uint32_t systemCode = 0) { return adoptRef(*new MediaKeyError(code, systemCode)); }
 
     Code code() const { return m_code; }
-    unsigned long systemCode() { return m_systemCode; }
+    uint32_t systemCode() { return m_systemCode; }
 
 private:
     explicit MediaKeyError(Code code, unsigned long systemCode) : m_code(code), m_systemCode(systemCode) { }
index 774de30..f918322 100644 (file)
@@ -42,7 +42,7 @@ struct MediaKeyEventInit : public EventInit {
     RefPtr<Uint8Array> message;
     String defaultURL;
     RefPtr<MediaKeyError> errorCode;
-    unsigned short systemCode;
+    uint32_t systemCode;
 };
 
 class MediaKeyEvent final : public Event {
diff --git a/Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.h b/Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.h
new file mode 100644 (file)
index 0000000..fb24dd4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebCoreNSErrorExtras_h
+#define WebCoreNSErrorExtras_h
+
+namespace WebCore {
+
+WEBCORE_EXPORT long mediaKeyErrorSystemCode(NSError *);
+
+}
+
+#endif // WebCoreNSErrorExtras_h
diff --git a/Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.mm b/Source/WebCore/platform/cocoa/WebCoreNSErrorExtras.mm
new file mode 100644 (file)
index 0000000..52399d6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "WebCoreNSErrorExtras.h"
+
+#import <AVFoundation/AVError.h>
+
+namespace WebCore {
+
+long mediaKeyErrorSystemCode(NSError *error)
+{
+    NSInteger code = [error code];
+
+    if (code == AVErrorUnknown) {
+        NSError* underlyingError = [error.userInfo valueForKey:NSUnderlyingErrorKey];
+        if (underlyingError && [underlyingError isKindOfClass:[NSError class]])
+            return [underlyingError code];
+    }
+
+    return code;
+}
+
+}
index 4551405..a71ea5c 100644 (file)
@@ -49,7 +49,7 @@ public:
         MediaKeyErrorDomain,
     };
     typedef unsigned short MediaKeyErrorCode;
-    virtual void sendError(MediaKeyErrorCode, unsigned long systemCode) = 0;
+    virtual void sendError(MediaKeyErrorCode, uint32_t systemCode) = 0;
 
     virtual String mediaKeysStorageDirectory() const = 0;
 };
@@ -70,9 +70,9 @@ public:
     virtual CDMSessionType type() { return CDMSessionTypeUnknown; }
     virtual void setClient(CDMSessionClient*) = 0;
     virtual const String& sessionId() const = 0;
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) = 0;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) = 0;
     virtual void releaseKeys() = 0;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) = 0;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) = 0;
     virtual RefPtr<ArrayBuffer> cachedKeyForKeyID(const String&) const { return nullptr; }
 };
 
index 94ef102..76422f2 100644 (file)
@@ -51,7 +51,7 @@ CDMSessionAVFoundationCF::CDMSessionAVFoundationCF(MediaPlayerPrivateAVFoundatio
 {
 }
 
-RefPtr<Uint8Array> CDMSessionAVFoundationCF::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
+RefPtr<Uint8Array> CDMSessionAVFoundationCF::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(mimeType);
 
@@ -107,7 +107,7 @@ void CDMSessionAVFoundationCF::releaseKeys()
 {
 }
 
-bool CDMSessionAVFoundationCF::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
+bool CDMSessionAVFoundationCF::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode)
 {
     RetainPtr<CFMutableDataRef> keyData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, key->byteLength()));
     CFDataAppendBytes(keyData.get(), reinterpret_cast<const UInt8*>(key->baseAddress()), key->byteLength());
index 510d03f..14e12a5 100644 (file)
@@ -44,9 +44,9 @@ public:
 
     virtual void setClient(CDMSessionClient* client) override { m_client = client; }
     virtual const String& sessionId() const override { return m_sessionId; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
 
 protected:
     MediaPlayerPrivateAVFoundationCF* m_parent;
index 9186fcc..86dc5ac 100644 (file)
@@ -49,9 +49,9 @@ public:
 
     // CDMSession
     virtual CDMSessionType type() override { return CDMSessionTypeAVContentKeySession; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual bool update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
 
     // CDMSessionMediaSourceAVFObjC
     void addParser(AVStreamDataParser *) override;
@@ -60,7 +60,7 @@ public:
     void didProvideContentKeyRequest(AVContentKeyRequest *);
 
 protected:
-    PassRefPtr<Uint8Array> generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode);
+    PassRefPtr<Uint8Array> generateKeyReleaseMessage(unsigned short& errorCode, uint32_t& systemCode);
 
     bool hasContentKeySession() const { return m_contentKeySession; }
     AVContentKeySession* contentKeySession();
index 6026bc5..7e6cfee 100644 (file)
@@ -37,9 +37,9 @@
 #import "SoftLinking.h"
 #import "SourceBufferPrivateAVFObjC.h"
 #import "UUID.h"
+#import "WebCoreNSErrorExtras.h"
 #import <AVFoundation/AVError.h>
 #import <CoreMedia/CMBase.h>
-#import <cstdlib>
 #import <objc/objc-runtime.h>
 #import <runtime/TypedArrayInlines.h>
 #import <wtf/NeverDestroyed.h>
@@ -144,7 +144,7 @@ bool CDMSessionAVContentKeySession::isAvailable()
     return getAVContentKeySessionClass();
 }
 
-RefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
+RefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(mimeType);
     UNUSED_PARAM(destinationURL);
@@ -228,7 +228,7 @@ static bool isEqual(Uint8Array* data, const char* literal)
     return !literal[length];
 }
 
-bool CDMSessionAVContentKeySession::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
+bool CDMSessionAVContentKeySession::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(nextMessage);
 
@@ -281,9 +281,15 @@ bool CDMSessionAVContentKeySession::update(Uint8Array* key, RefPtr<Uint8Array>&
 
         errorCode = MediaPlayer::NoError;
         systemCode = 0;
-        NSData* requestData = [m_keyRequest contentKeyRequestDataForApp:certificateData.get() contentIdentifier:nil options:options.get() error:nil];
-        nextMessage = Uint8Array::create(static_cast<const uint8_t*>([requestData bytes]), [requestData length]);
+        NSError* error = nil;
+        NSData* requestData = [m_keyRequest contentKeyRequestDataForApp:certificateData.get() contentIdentifier:nil options:options.get() error:&error];
+        if (error) {
+            errorCode = MediaPlayerClient::DomainError;
+            systemCode = mediaKeyErrorSystemCode(error);
+            return false;
+        }
 
+        nextMessage = Uint8Array::create(static_cast<const uint8_t*>([requestData bytes]), [requestData length]);
         return false;
     }
 
@@ -306,7 +312,7 @@ void CDMSessionAVContentKeySession::removeParser(AVStreamDataParser* parser)
     [contentKeySession() removeStreamDataParser:parser];
 }
 
-PassRefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode)
+PassRefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyReleaseMessage(unsigned short& errorCode, uint32_t& systemCode)
 {
     ASSERT(m_mode == KeyRelease);
     m_certificate = m_initData;
index 5d93073..0eb125c 100644 (file)
@@ -45,9 +45,9 @@ public:
     virtual CDMSessionType type() override { return CDMSessionTypeAVFoundationObjC; }
     virtual void setClient(CDMSessionClient* client) override { m_client = client; }
     virtual const String& sessionId() const override { return m_sessionId; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
 
 protected:
     MediaPlayerPrivateAVFoundationObjC* m_parent;
index cbde198..081087b 100644 (file)
@@ -35,6 +35,7 @@
 #import "MediaPlayerPrivateAVFoundationObjC.h"
 #import "SoftLinking.h"
 #import "UUID.h"
+#import "WebCoreNSErrorExtras.h"
 #import <AVFoundation/AVFoundation.h>
 #import <objc/objc-runtime.h>
 
@@ -53,7 +54,7 @@ CDMSessionAVFoundationObjC::CDMSessionAVFoundationObjC(MediaPlayerPrivateAVFound
 {
 }
 
-RefPtr<Uint8Array> CDMSessionAVFoundationObjC::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
+RefPtr<Uint8Array> CDMSessionAVFoundationObjC::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(mimeType);
 
@@ -61,13 +62,13 @@ RefPtr<Uint8Array> CDMSessionAVFoundationObjC::generateKeyRequest(const String&
     String keyID;
     RefPtr<Uint8Array> certificate;
     if (!MediaPlayerPrivateAVFoundationObjC::extractKeyURIKeyIDAndCertificateFromInitData(initData, keyURI, keyID, certificate)) {
-        errorCode = MediaPlayer::InvalidPlayerState;
+        errorCode = CDM::UnknownError;
         return nullptr;
     }
 
     m_request = m_parent->takeRequestForKeyURI(keyURI);
     if (!m_request) {
-        errorCode = MediaPlayer::InvalidPlayerState;
+        errorCode = CDM::UnknownError;
         return nullptr;
     }
 
@@ -78,8 +79,8 @@ RefPtr<Uint8Array> CDMSessionAVFoundationObjC::generateKeyRequest(const String&
     RetainPtr<NSData> keyRequest = [m_request streamingContentKeyRequestDataForApp:certificateData.get() contentIdentifier:assetID.get() options:nil error:&nsError];
 
     if (!keyRequest) {
-        NSError* underlyingError = [[nsError userInfo] objectForKey:NSUnderlyingErrorKey];
-        systemCode = [underlyingError code];
+        errorCode = CDM::DomainError;
+        systemCode = mediaKeyErrorSystemCode(nsError);
         return nullptr;
     }
 
@@ -95,7 +96,7 @@ void CDMSessionAVFoundationObjC::releaseKeys()
 {
 }
 
-bool CDMSessionAVFoundationObjC::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
+bool CDMSessionAVFoundationObjC::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode)
 {
     RetainPtr<NSData> keyData = adoptNS([[NSData alloc] initWithBytes:key->baseAddress() length:key->byteLength()]);
     [[m_request dataRequest] respondWithData:keyData.get()];
index da57c47..4567f42 100644 (file)
@@ -47,9 +47,9 @@ public:
 
     // CDMSession
     virtual CDMSessionType type() override { return CDMSessionTypeAVStreamSession; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
 
     // CDMSessionMediaSourceAVFObjC
     void addParser(AVStreamDataParser*) override;
@@ -58,7 +58,7 @@ public:
     void setStreamSession(AVStreamSession*);
 
 protected:
-    PassRefPtr<Uint8Array> generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode);
+    PassRefPtr<Uint8Array> generateKeyReleaseMessage(unsigned short& errorCode, uint32_t systemCode);
 
     WeakPtrFactory<CDMSessionAVStreamSession> m_weakPtrFactory;
     RetainPtr<AVStreamSession> m_streamSession;
index 7db8bf8..90aaaf0 100644 (file)
@@ -37,9 +37,9 @@
 #import "SoftLinking.h"
 #import "SourceBufferPrivateAVFObjC.h"
 #import "UUID.h"
+#import "WebCoreNSErrorExtras.h"
 #import <AVFoundation/AVError.h>
 #import <CoreMedia/CMBase.h>
-#import <cstdlib>
 #import <objc/objc-runtime.h>
 #import <runtime/TypedArrayInlines.h>
 #import <wtf/NeverDestroyed.h>
@@ -112,7 +112,7 @@ CDMSessionAVStreamSession::~CDMSessionAVStreamSession()
         removeParser(sourceBuffer->parser());
 }
 
-RefPtr<Uint8Array> CDMSessionAVStreamSession::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
+RefPtr<Uint8Array> CDMSessionAVStreamSession::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode)
 {
     UNUSED_PARAM(mimeType);
     UNUSED_PARAM(destinationURL);
@@ -187,7 +187,7 @@ static bool isEqual(Uint8Array* data, const char* literal)
     return !literal[length];
 }
 
-bool CDMSessionAVStreamSession::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
+bool CDMSessionAVStreamSession::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode)
 {
     bool shouldGenerateKeyRequest = !m_certificate || isEqual(key, "renew");
     if (!m_certificate) {
@@ -255,7 +255,7 @@ bool CDMSessionAVStreamSession::update(Uint8Array* key, RefPtr<Uint8Array>& next
         if (error) {
             LOG(Media, "CDMSessionAVStreamSession::update(%p) - error:%@", this, [error description]);
             errorCode = MediaPlayer::InvalidPlayerState;
-            systemCode = std::abs(systemCodeForError(error));
+            systemCode = mediaKeyErrorSystemCode(error);
             return false;
         }
 
@@ -304,7 +304,7 @@ void CDMSessionAVStreamSession::removeParser(AVStreamDataParser* parser)
         [m_streamSession removeStreamDataParser:parser];
 }
 
-PassRefPtr<Uint8Array> CDMSessionAVStreamSession::generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode)
+PassRefPtr<Uint8Array> CDMSessionAVStreamSession::generateKeyReleaseMessage(unsigned short& errorCode, uint32_t systemCode)
 {
     ASSERT(m_mode == KeyRelease);
     m_certificate = m_initData;
index 75a448b..545d86a 100644 (file)
@@ -63,7 +63,6 @@ public:
     void invalidateCDM() { m_cdm = nullptr; }
 
 protected:
-    static long systemCodeForError(NSError *);
     String storagePath() const;
 
     CDMPrivateMediaSourceAVFObjC* m_cdm;
index 42cb88c..04fa35f 100644 (file)
@@ -30,8 +30,8 @@
 
 #import "CDMPrivateMediaSourceAVFObjC.h"
 #import "FileSystem.h"
+#import "WebCoreNSErrorExtras.h"
 #import <AVFoundation/AVError.h>
-#import <cstdlib>
 
 namespace WebCore {
 
@@ -52,7 +52,7 @@ void CDMSessionMediaSourceAVFObjC::layerDidReceiveError(AVSampleBufferDisplayLay
     if (!m_client)
         return;
 
-    unsigned long code = std::abs(systemCodeForError(error));
+    unsigned long code = mediaKeyErrorSystemCode(error);
 
     // FIXME(142246): Remove the following once <rdar://problem/20027434> is resolved.
     shouldIgnore = m_stopped && code == 12785;
@@ -65,7 +65,7 @@ void CDMSessionMediaSourceAVFObjC::rendererDidReceiveError(AVSampleBufferAudioRe
     if (!m_client)
         return;
 
-    unsigned long code = std::abs(systemCodeForError(error));
+    unsigned long code = mediaKeyErrorSystemCode(error);
 
     // FIXME(142246): Remove the following once <rdar://problem/20027434> is resolved.
     shouldIgnore = m_stopped && code == 12785;
@@ -96,19 +96,6 @@ void CDMSessionMediaSourceAVFObjC::removeSourceBuffer(SourceBufferPrivateAVFObjC
     m_sourceBuffers.remove(m_sourceBuffers.find(sourceBuffer));
 }
 
-long CDMSessionMediaSourceAVFObjC::systemCodeForError(NSError *error)
-{
-    NSInteger code = [error code];
-    if (code != AVErrorUnknown)
-        return code;
-
-    NSError* underlyingError = [error.userInfo valueForKey:NSUnderlyingErrorKey];
-    if (!underlyingError || ![underlyingError isKindOfClass:[NSError class]])
-        return code;
-
-    return [underlyingError code];
-}
-
 String CDMSessionMediaSourceAVFObjC::storagePath() const
 {
     return m_client ? pathByAppendingComponent(m_client->mediaKeysStorageDirectory(), "SecureStop.plist") : emptyString();
index b734ffd..c4b88d3 100644 (file)
@@ -44,9 +44,9 @@ public:
 
     virtual void setClient(CDMSessionClient* client) override { m_client = client; }
     virtual const String& sessionId() const override { return m_sessionId; }
-    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual RefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, uint32_t& systemCode) override;
     virtual void releaseKeys() override;
-    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) override;
+    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, uint32_t& systemCode) override;
 
 protected:
     CDMSessionClient* m_client;
@@ -112,7 +112,7 @@ MockCDMSession::MockCDMSession(CDMSessionClient* client)
 {
 }
 
-RefPtr<Uint8Array> MockCDMSession::generateKeyRequest(const String&, Uint8Array* initData, String&, unsigned short& errorCode, unsigned long&)
+RefPtr<Uint8Array> MockCDMSession::generateKeyRequest(const String&, Uint8Array* initData, String&, unsigned short& errorCode, uint32_t&)
 {
     for (unsigned i = 0; i < initDataPrefix()->length(); ++i) {
         if (!initData || i >= initData->length() || initData->item(i) != initDataPrefix()->item(i)) {
@@ -128,7 +128,7 @@ void MockCDMSession::releaseKeys()
     // no-op
 }
 
-bool MockCDMSession::update(Uint8Array* key, RefPtr<Uint8Array>&, unsigned short& errorCode, unsigned long&)
+bool MockCDMSession::update(Uint8Array* key, RefPtr<Uint8Array>&, unsigned short& errorCode, uint32_t&)
 {
     for (unsigned i = 0; i < keyPrefix()->length(); ++i) {
         if (i >= key->length() || key->item(i) != keyPrefix()->item(i)) {