merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-09-29 15:42:55 +02:00
Родитель bb57cb7051 f7cb749319
Коммит 9d31360549
359 изменённых файлов: 38538 добавлений и 30985 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1065897: Updated moz.build requires CLOBBER
Bug 1069071: IPDL changes require CLOBBER

Просмотреть файл

@ -0,0 +1,3 @@
. "$topsrcdir/browser/config/mozconfigs/win32/nightly"
ac_add_options --enable-application=b2g/dev

Просмотреть файл

@ -132,8 +132,8 @@ let TimelineController = {
* updating the UI as needed.
*/
_stopRecordingAndDiscardData: function*() {
this._markers.length = 0;
yield this._stopRecording();
this._markers.length = 0;
},
/**

Просмотреть файл

@ -396,6 +396,15 @@ FunctionEnd
!macroend
!define ShowShortcuts "!insertmacro ShowShortcuts"
!macro AddAssociationIfNoneExist FILE_TYPE
ClearErrors
EnumRegKey $7 HKCR "${FILE_TYPE}" 0
${If} ${Errors}
WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}" "" "FirefoxHTML"
${EndIf}
!macroend
!define AddAssociationIfNoneExist "!insertmacro AddAssociationIfNoneExist"
; Adds the protocol and file handler registry entries for making Firefox the
; default handler (uses SHCTX).
!macro SetHandlers
@ -430,35 +439,12 @@ FunctionEnd
WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML"
${EndIf}
; Only add .oga if it's not present
${CheckIfRegistryKeyExists} "$0" ".oga" $7
${If} $7 == "false"
WriteRegStr SHCTX "$0\.oga" "" "FirefoxHTML"
${EndIf}
; Only add .ogg if it's not present
${CheckIfRegistryKeyExists} "$0" ".ogg" $7
${If} $7 == "false"
WriteRegStr SHCTX "$0\.ogg" "" "FirefoxHTML"
${EndIf}
; Only add .ogv if it's not present
${CheckIfRegistryKeyExists} "$0" ".ogv" $7
${If} $7 == "false"
WriteRegStr SHCTX "$0\.ogv" "" "FirefoxHTML"
${EndIf}
; Only add .pdf if it's not present
${CheckIfRegistryKeyExists} "$0" ".pdf" $7
${If} $7 == "false"
WriteRegStr SHCTX "$0\.pdf" "" "FirefoxHTML"
${EndIf}
; Only add webm if it's not present
${CheckIfRegistryKeyExists} "$0" ".webm" $7
${If} $7 == "false"
WriteRegStr SHCTX "$0\.webm" "" "FirefoxHTML"
${EndIf}
${AddAssociationIfNoneExist} ".pdf"
${AddAssociationIfNoneExist} ".oga"
${AddAssociationIfNoneExist} ".ogg"
${AddAssociationIfNoneExist} ".ogv"
${AddAssociationIfNoneExist} ".pdf"
${AddAssociationIfNoneExist} ".webm"
; An empty string is used for the 5th param because FirefoxHTML is not a
; protocol handler
@ -693,6 +679,40 @@ FunctionEnd
!macroend
!define SetUninstallKeys "!insertmacro SetUninstallKeys"
; Due to a bug when associating some file handlers, only SHCTX was checked for
; some file types such as ".pdf". SHCTX is set to HKCU or HKLM depending on
; whether the installer has write access to HKLM. The bug would happen when
; HCKU was checked and didn't exist since programs aren't required to set the
; HKCU Software\Classes keys when associating handlers. The fix uses the merged
; view in HKCR to check for existance of an existing association. This macro
; cleans affected installations by removing the HKLM and HKCU value if it is set
; to FirefoxHTML when there is a value for PersistentHandler or by removing the
; HKCU value when the HKLM value has a value other than an empty string.
!macro FixBadFileAssociation FILE_TYPE
; Only delete the default value in case the key has values for OpenWithList,
; OpenWithProgids, PersistentHandler, etc.
ReadRegStr $0 HKCU "Software\Classes\${FILE_TYPE}" ""
ReadRegStr $1 HKLM "Software\Classes\${FILE_TYPE}" ""
ReadRegStr $2 HKCR "${FILE_TYPE}\PersistentHandler" ""
${If} "$2" != ""
; Since there is a persistent handler remove FirefoxHTML as the default
; value from both HKCU and HKLM if it set to FirefoxHTML.
${If} "$0" == "FirefoxHTML"
DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" ""
${EndIf}
${If} "$1" == "FirefoxHTML"
DeleteRegValue HKLM "Software\Classes\${FILE_TYPE}" ""
${EndIf}
${ElseIf} "$0" == "FirefoxHTML"
; Since KHCU is set to FirefoxHTML remove FirefoxHTML as the default value
; from HKCU if HKLM is set to a value other than an empty string.
${If} "$1" != ""
DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" ""
${EndIf}
${EndIf}
!macroend
!define FixBadFileAssociation "!insertmacro FixBadFileAssociation"
; Add app specific handler registry entries under Software\Classes if they
; don't exist (does not use SHCTX).
!macro FixClassKeys
@ -719,6 +739,14 @@ FunctionEnd
${WriteRegStr2} $TmpVal "$1\.xhtml" "" "xhtmlfile" 0
${WriteRegStr2} $TmpVal "$1\.xhtml" "Content Type" "application/xhtml+xml" 0
${EndIf}
; Remove possibly badly associated file types
${FixBadFileAssociation} ".pdf"
${FixBadFileAssociation} ".oga"
${FixBadFileAssociation} ".ogg"
${FixBadFileAssociation} ".ogv"
${FixBadFileAssociation} ".pdf"
${FixBadFileAssociation} ".webm"
!macroend
!define FixClassKeys "!insertmacro FixClassKeys"

Просмотреть файл

@ -239,7 +239,7 @@ if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
AC_MSG_ERROR([Couldn't find path to gnu-libstdc++ in the android ndk])
fi
else
STLPORT_CPPFLAGS="-isystem $_topsrcdir/build/stlport/stlport -isystem $android_ndk/sources/cxx-stl/system/include"
STLPORT_CPPFLAGS="-isystem $_topsrcdir/build/stlport/stlport -isystem $_topsrcdir/build/stlport/overrides -isystem $android_ndk/sources/cxx-stl/system/include"
STLPORT_LIBS="$_objdir/build/stlport/libstlport_static.a -static-libstdc++"
fi
fi

Просмотреть файл

@ -1,6 +1,8 @@
This copy of STLport was taken from the Android NDK r8e.
Android specific changes are listed in README.android.
The libs/ directory containing prebuilt static libraries was removed.
The overrides/ directory contains Mozilla-specific overrides to the standard
C++ headers found in the NDK.
The following patches are applied on top:
- android-mozilla-config.patch: Adjusts Android-specific configuration

Просмотреть файл

@ -0,0 +1,65 @@
/* -*- c++ -*- */
/*
* Copyright (C) 2009 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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 THE COPYRIGHT HOLDERS AND 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 THE
* COPYRIGHT OWNER OR 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.
*/
/*
* This header is taken from $ndk/sources/cxx-stl/system/include/new,
* and it fixes a bug in the NDK header where the nothrow versions of
* placement new and delete are not specified with 'throw()'. This bug
* causes GCC to not null-check the results from these functions.
*/
#ifndef __NEW__
#define __NEW__
#include <cstddef>
extern "C++" {
namespace std {
struct nothrow_t {};
extern const nothrow_t nothrow;
}
void* operator new(std::size_t);
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
inline void* operator new(std::size_t, void* p) { return p; }
inline void* operator new[](std::size_t, void* p) { return p; }
// these next two are not really required, since exceptions are off
inline void operator delete(void*, void*) { }
inline void operator delete[](void*, void*) { }
} // extern C++
#endif // __NEW__

Просмотреть файл

@ -33,6 +33,7 @@
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWeakReference.h"
class nsDOMMultipartFile;
class nsIFile;
@ -64,6 +65,7 @@ class DOMFile MOZ_FINAL : public nsIDOMFile
, public nsIXHRSendable
, public nsIMutable
, public nsIJSNativeInitializer
, public nsSupportsWeakReference
{
public:
NS_DECL_NSIDOMBLOB
@ -190,9 +192,9 @@ public:
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) = 0;
nsresult Slice(int64_t aStart, int64_t aEnd, const nsAString& aContentType,
uint8_t aArgc, nsIDOMBlob **aBlob);
uint8_t aArgc, DOMFileImpl** aBlobImpl);
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) = 0;
@ -321,7 +323,7 @@ public:
virtual nsresult GetMozLastModifiedDate(uint64_t* aDate) MOZ_OVERRIDE;
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
@ -464,7 +466,7 @@ public:
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
@ -551,7 +553,7 @@ public:
virtual nsresult GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
@ -573,7 +575,7 @@ private:
nsString mContentType;
};
class DOMFileImplFile MOZ_FINAL : public DOMFileImplBase
class DOMFileImplFile : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -690,6 +692,9 @@ public:
void SetPath(const nsAString& aFullPath);
protected:
virtual ~DOMFileImplFile() {}
private:
// Create slice
DOMFileImplFile(const DOMFileImplFile* aOther, uint64_t aStart,
@ -719,9 +724,7 @@ private:
}
}
~DOMFileImplFile() {}
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;

Просмотреть файл

@ -834,6 +834,13 @@ Element::CreateShadowRoot(ErrorResult& aError)
SetShadowRoot(shadowRoot);
if (olderShadow) {
olderShadow->SetYoungerShadow(shadowRoot);
// Unbind children of older shadow root because they
// are no longer in the composed tree.
for (nsIContent* child = olderShadow->GetFirstChild(); child;
child = child->GetNextSibling()) {
child->UnbindFromTree(true, false);
}
}
// xblBinding takes ownership of docInfo.
@ -1384,6 +1391,18 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
}
// Call BindToTree on shadow root children.
ShadowRoot* shadowRoot = GetShadowRoot();
if (shadowRoot) {
for (nsIContent* child = shadowRoot->GetFirstChild(); child;
child = child->GetNextSibling()) {
rv = child->BindToTree(nullptr, shadowRoot,
shadowRoot->GetBindingParent(),
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
}
}
// XXXbz script execution during binding can trigger some of these
// postcondition asserts.... But we do want that, since things will
// generally be quite broken when that happens.
@ -1462,10 +1481,13 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
SetParentIsContent(false);
}
ClearInDocument();
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// Begin keeping track of our subtree root.
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
if (aNullParent || !mParent->IsInShadowTree()) {
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// Begin keeping track of our subtree root.
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
}
if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated
@ -1514,7 +1536,9 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
if (clearBindingParent) {
slots->mBindingParent = nullptr;
}
slots->mContainingShadow = nullptr;
if (aNullParent || !mParent->IsInShadowTree()) {
slots->mContainingShadow = nullptr;
}
}
// This has to be here, rather than in nsGenericHTMLElement::UnbindFromTree,
@ -1539,6 +1563,15 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
}
nsNodeUtils::ParentChainChanged(this);
// Unbind children of shadow root.
ShadowRoot* shadowRoot = GetShadowRoot();
if (shadowRoot) {
for (nsIContent* child = shadowRoot->GetFirstChild(); child;
child = child->GetNextSibling()) {
child->UnbindFromTree(true, false);
}
}
}
nsICSSDeclaration*

Просмотреть файл

@ -1393,6 +1393,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
unbind the child nodes.
} */
// Clear flag here because unlinking slots will clear the
// containing shadow root pointer.
tmp->UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// Unlink any DOM slots of interest.
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();

Просмотреть файл

@ -55,7 +55,7 @@ DOMMultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
return CallQueryInterface(stream, aStream);
}
already_AddRefed<nsIDOMBlob>
already_AddRefed<DOMFileImpl>
DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
@ -77,18 +77,17 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
if (skipStart < l) {
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
nsCOMPtr<nsIDOMBlob> firstBlob;
rv = blobImpl->Slice(skipStart, skipStart + upperBound,
aContentType, 3,
getter_AddRefs(firstBlob));
nsRefPtr<DOMFileImpl> firstImpl;
rv = blobImpl->Slice(skipStart, skipStart + upperBound, aContentType, 3,
getter_AddRefs(firstImpl));
NS_ENSURE_SUCCESS(rv, nullptr);
// Avoid wrapping a single blob inside an DOMMultipartFileImpl
if (length == upperBound) {
return firstBlob.forget();
return firstImpl.forget();
}
blobImpls.AppendElement(static_cast<DOMFile*>(firstBlob.get())->Impl());
blobImpls.AppendElement(firstImpl);
length -= upperBound;
i++;
break;
@ -105,12 +104,12 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
NS_ENSURE_SUCCESS(rv, nullptr);
if (length < l) {
nsCOMPtr<nsIDOMBlob> lastBlob;
nsRefPtr<DOMFileImpl> lastBlob;
rv = blobImpl->Slice(0, length, aContentType, 3,
getter_AddRefs(lastBlob));
NS_ENSURE_SUCCESS(rv, nullptr);
blobImpls.AppendElement(static_cast<DOMFile*>(lastBlob.get())->Impl());
blobImpls.AppendElement(lastBlob);
} else {
blobImpls.AppendElement(blobImpl);
}
@ -118,9 +117,9 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
}
// we can create our blob now
nsCOMPtr<nsIDOMBlob> blob =
new DOMFile(new DOMMultipartFileImpl(blobImpls, aContentType));
return blob.forget();
nsRefPtr<DOMFileImpl> impl =
new DOMMultipartFileImpl(blobImpls, aContentType);
return impl.forget();
}
/* static */ nsresult

Просмотреть файл

@ -78,7 +78,7 @@ public:
uint32_t aArgc,
JS::Value* aArgv);
virtual already_AddRefed<nsIDOMBlob>
virtual already_AddRefed<DOMFileImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;

Просмотреть файл

@ -147,6 +147,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMFile)
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, IsFile())
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
NS_INTERFACE_MAP_END
@ -298,7 +299,10 @@ already_AddRefed<nsIDOMBlob>
DOMFile::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
return mImpl->CreateSlice(aStart, aLength, aContentType);
nsRefPtr<DOMFileImpl> impl =
mImpl->CreateSlice(aStart, aLength, aContentType);
nsRefPtr<DOMFile> slice = new DOMFile(impl);
return slice.forget();
}
NS_IMETHODIMP
@ -400,7 +404,17 @@ DOMFile::Slice(int64_t aStart, int64_t aEnd,
nsIDOMBlob **aBlob)
{
MOZ_ASSERT(mImpl);
return mImpl->Slice(aStart, aEnd, aContentType, aArgc, aBlob);
nsRefPtr<DOMFileImpl> impl;
nsresult rv = mImpl->Slice(aStart, aEnd, aContentType, aArgc,
getter_AddRefs(impl));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsRefPtr<DOMFile> blob = new DOMFile(impl);
blob.forget(aBlob);
return NS_OK;
}
NS_IMETHODIMP
@ -460,9 +474,9 @@ DOMFile::IsMemoryFile()
nsresult
DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
const nsAString& aContentType, uint8_t aArgc,
nsIDOMBlob **aBlob)
DOMFileImpl** aBlobImpl)
{
*aBlob = nullptr;
*aBlobImpl = nullptr;
// Truncate aStart and aEnd so that we stay within this file.
uint64_t thisLength;
@ -475,12 +489,15 @@ DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
ParseSize((int64_t)thisLength, aStart, aEnd);
// Create the new file
nsCOMPtr<nsIDOMBlob> blob =
nsRefPtr<DOMFileImpl> impl =
CreateSlice((uint64_t)aStart, (uint64_t)(aEnd - aStart), aContentType);
blob.forget(aBlob);
return *aBlob ? NS_OK : NS_ERROR_UNEXPECTED;
if (!impl) {
return NS_ERROR_UNEXPECTED;
}
impl.forget(aBlobImpl);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
@ -575,7 +592,7 @@ DOMFileImplBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
return NS_OK;
}
already_AddRefed<nsIDOMBlob>
already_AddRefed<DOMFileImpl>
DOMFileImplBase::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
@ -724,13 +741,13 @@ DOMFileImplBase::SetMutable(bool aMutable)
////////////////////////////////////////////////////////////////////////////
// DOMFileImplFile implementation
already_AddRefed<nsIDOMBlob>
already_AddRefed<DOMFileImpl>
DOMFileImplFile::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
nsCOMPtr<nsIDOMBlob> blob =
new DOMFile(new DOMFileImplFile(this, aStart, aLength, aContentType));
return blob.forget();
nsRefPtr<DOMFileImpl> impl =
new DOMFileImplFile(this, aStart, aLength, aContentType);
return impl.forget();
}
nsresult
@ -832,7 +849,8 @@ DOMFileImplFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
const uint32_t sFileStreamFlags =
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND |
nsIFileInputStream::DEFER_OPEN;
nsIFileInputStream::DEFER_OPEN |
nsIFileInputStream::SHARE_DELETE;
nsresult
DOMFileImplFile::GetInternalStream(nsIInputStream** aStream)
@ -857,13 +875,13 @@ DOMFileImplFile::SetPath(const nsAString& aPath)
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplMemory, DOMFileImpl)
already_AddRefed<nsIDOMBlob>
already_AddRefed<DOMFileImpl>
DOMFileImplMemory::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
nsCOMPtr<nsIDOMBlob> blob =
new DOMFile(new DOMFileImplMemory(this, aStart, aLength, aContentType));
return blob.forget();
nsRefPtr<DOMFileImpl> impl =
new DOMFileImplMemory(this, aStart, aLength, aContentType);
return impl.forget();
}
nsresult
@ -982,17 +1000,17 @@ DOMFileImplMemory::DataOwner::EnsureMemoryReporterRegistered()
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplTemporaryFileBlob, DOMFileImpl)
already_AddRefed<nsIDOMBlob>
already_AddRefed<DOMFileImpl>
DOMFileImplTemporaryFileBlob::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
if (aStart + aLength > mLength)
return nullptr;
nsCOMPtr<nsIDOMBlob> blob =
new DOMFile(new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos,
aLength, aContentType));
return blob.forget();
nsRefPtr<DOMFileImpl> impl =
new DOMFileImplTemporaryFileBlob(this, aStart + mStartPos, aLength,
aContentType);
return impl.forget();
}
nsresult

Просмотреть файл

@ -154,7 +154,6 @@
#include "mozAutoDocUpdate.h"
#include "nsGlobalWindow.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "nsDOMNavigationTiming.h"
#include "nsSMILAnimationController.h"
@ -8539,13 +8538,6 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
}
}
// Check if we have running offline storage transactions
quota::QuotaManager* quotaManager =
win ? quota::QuotaManager::Get() : nullptr;
if (quotaManager && quotaManager->HasOpenTransactions(win)) {
return false;
}
#ifdef MOZ_MEDIA_NAVIGATOR
// Check if we have active GetUserMedia use
if (MediaManager::Exists() && win &&

Просмотреть файл

@ -34,8 +34,8 @@
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/dom/PBlobChild.h"
#include "mozilla/dom/PBlobParent.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "JavaScriptChild.h"
#include "JavaScriptParent.h"
#include "mozilla/dom/DOMStringList.h"

Просмотреть файл

@ -582,15 +582,20 @@ nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
SetParentIsContent(false);
}
ClearInDocument();
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// Begin keeping track of our subtree root.
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
if (aNullParent || !mParent->IsInShadowTree()) {
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
// Begin keeping track of our subtree root.
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
}
nsDataSlots *slots = GetExistingDataSlots();
if (slots) {
slots->mBindingParent = nullptr;
slots->mContainingShadow = nullptr;
if (aNullParent || !mParent->IsInShadowTree()) {
slots->mContainingShadow = nullptr;
}
}
nsNodeUtils::ParentChainChanged(this);

Просмотреть файл

@ -392,7 +392,15 @@ nsINode::GetComposedDocInternal() const
// Cross ShadowRoot boundary.
ShadowRoot* containingShadow = AsContent()->GetContainingShadow();
return containingShadow->GetHost()->GetCrossShadowCurrentDoc();
nsIContent* poolHost = containingShadow->GetPoolHost();
if (!poolHost) {
// This node is in an older shadow root that does not get projected into
// an insertion point, thus this node can not be in the composed document.
return nullptr;
}
return poolHost->GetComposedDoc();
}
#ifdef DEBUG

Просмотреть файл

@ -208,7 +208,8 @@ nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
// We remove this stylesheet from the cache to load a new version.
nsCOMPtr<nsIContent> thisContent;
CallQueryInterface(this, getter_AddRefs(thisContent));
nsIDocument* doc = thisContent->GetCrossShadowCurrentDoc();
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
if (doc && doc->CSSLoader()->GetEnabled() &&
mStyleSheet && mStyleSheet->GetOriginalURI()) {
doc->CSSLoader()->ObsoleteSheet(mStyleSheet->GetOriginalURI());
@ -344,7 +345,8 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = thisContent->GetCrossShadowCurrentDoc();
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
if (!doc || !doc->CSSLoader()->GetEnabled()) {
return NS_OK;
}

Просмотреть файл

@ -40,6 +40,11 @@
}
function runTests() {
function done() {
SpecialPowers.removePermission("browser", document);
SimpleTest.finish();
}
ok("Browser prefs set.");
let iframe = document.createElement("iframe");
@ -50,6 +55,8 @@
iframe.addEventListener("mozbrowserloadend", function() {
ok(true, "Got iframe load event.");
const blobString = "this is a great success!";
const messages = [
"hi!",
"",
@ -60,6 +67,8 @@
false,
null,
0,
// Make sure this one is always last.
new Blob(["this ", "is ", "a ", "great ", "success!"],
{"type" : "text\/plain"}),
];
@ -67,15 +76,45 @@
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("test:ipcClonedMessage", function(message) {
// We need to wrap to access message.json, and unwrap to do the
// identity check.
is(SpecialPowers.unwrap(SpecialPowers.wrap(message).json),
let data = message.json;
if (data instanceof Blob) {
is(receivedMessageIndex, messages.length - 1, "Blob is last");
is (data.size,
messages[receivedMessageIndex].size,
"Correct blob size");
is (data.type,
messages[receivedMessageIndex].type,
"Correct blob type");
let result1, result2;
let reader1 = new FileReader();
reader1.onload = function() {
result1 = reader1.result == blobString ? reader1.result : "bad1";
if (result2) {
is(result1, result2, "Same results");
done();
}
};
let reader2 = new FileReader();
reader2.onload = function() {
result2 = reader2.result == blobString ? reader2.result : "bad2";
if (result1) {
is(result1, result2, "Same results");
done();
}
};
reader1.readAsText(data);
reader2.readAsText(messages[receivedMessageIndex]);
return;
}
is(message.json,
messages[receivedMessageIndex++],
"Got correct round-tripped response");
if (receivedMessageIndex == messages.length) {
SpecialPowers.removePermission("browser", document);
SimpleTest.finish();
}
});
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);

Просмотреть файл

@ -82,46 +82,44 @@ BodyRule::MapRuleInfoInto(nsRuleData* aData)
marginBottom->SetFloatValue((float)bodyMarginHeight, eCSSUnit_Pixel);
}
if (eCompatibility_NavQuirks == mode){
// topmargin (IE-attribute)
value = mPart->GetParsedAttr(nsGkAtoms::topmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyTopMargin = value->GetIntegerValue();
if (bodyTopMargin < 0) bodyTopMargin = 0;
nsCSSValue* marginTop = aData->ValueForMarginTop();
if (marginTop->GetUnit() == eCSSUnit_Null)
marginTop->SetFloatValue((float)bodyTopMargin, eCSSUnit_Pixel);
}
value = mPart->GetParsedAttr(nsGkAtoms::topmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyTopMargin = value->GetIntegerValue();
if (bodyTopMargin < 0) bodyTopMargin = 0;
nsCSSValue* marginTop = aData->ValueForMarginTop();
if (marginTop->GetUnit() == eCSSUnit_Null)
marginTop->SetFloatValue((float)bodyTopMargin, eCSSUnit_Pixel);
}
// bottommargin (IE-attribute)
value = mPart->GetParsedAttr(nsGkAtoms::bottommargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyBottomMargin = value->GetIntegerValue();
if (bodyBottomMargin < 0) bodyBottomMargin = 0;
nsCSSValue* marginBottom = aData->ValueForMarginBottom();
if (marginBottom->GetUnit() == eCSSUnit_Null)
marginBottom->SetFloatValue((float)bodyBottomMargin, eCSSUnit_Pixel);
}
value = mPart->GetParsedAttr(nsGkAtoms::bottommargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyBottomMargin = value->GetIntegerValue();
if (bodyBottomMargin < 0) bodyBottomMargin = 0;
nsCSSValue* marginBottom = aData->ValueForMarginBottom();
if (marginBottom->GetUnit() == eCSSUnit_Null)
marginBottom->SetFloatValue((float)bodyBottomMargin, eCSSUnit_Pixel);
}
// leftmargin (IE-attribute)
value = mPart->GetParsedAttr(nsGkAtoms::leftmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyLeftMargin = value->GetIntegerValue();
if (bodyLeftMargin < 0) bodyLeftMargin = 0;
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel);
}
value = mPart->GetParsedAttr(nsGkAtoms::leftmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyLeftMargin = value->GetIntegerValue();
if (bodyLeftMargin < 0) bodyLeftMargin = 0;
nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
if (marginLeft->GetUnit() == eCSSUnit_Null)
marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel);
}
// rightmargin (IE-attribute)
value = mPart->GetParsedAttr(nsGkAtoms::rightmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyRightMargin = value->GetIntegerValue();
if (bodyRightMargin < 0) bodyRightMargin = 0;
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel);
}
value = mPart->GetParsedAttr(nsGkAtoms::rightmargin);
if (value && value->Type() == nsAttrValue::eInteger) {
bodyRightMargin = value->GetIntegerValue();
if (bodyRightMargin < 0) bodyRightMargin = 0;
nsCSSValue* marginRight = aData->ValueForMarginRightValue();
if (marginRight->GetUnit() == eCSSUnit_Null)
marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel);
}
}

Просмотреть файл

@ -55,13 +55,15 @@ HTMLContentElement::BindToTree(nsIDocument* aDocument,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
nsRefPtr<ShadowRoot> oldContainingShadow = GetContainingShadow();
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
ShadowRoot* containingShadow = GetContainingShadow();
if (containingShadow) {
if (containingShadow && !oldContainingShadow) {
nsINode* parentNode = nsINode::GetParentNode();
while (parentNode && parentNode != containingShadow) {
if (parentNode->IsElement() &&
@ -85,23 +87,20 @@ HTMLContentElement::BindToTree(nsIDocument* aDocument,
void
HTMLContentElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
if (mIsInsertionPoint) {
ShadowRoot* containingShadow = GetContainingShadow();
// Make sure that containingShadow exists, it may have been nulled
// during unlinking in which case the ShadowRoot is going away.
if (containingShadow) {
containingShadow->RemoveInsertionPoint(this);
nsRefPtr<ShadowRoot> oldContainingShadow = GetContainingShadow();
// Remove all the matched nodes now that the
// insertion point is no longer an insertion point.
ClearMatchedNodes();
containingShadow->SetInsertionPointChanged();
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
if (oldContainingShadow && !GetContainingShadow() && mIsInsertionPoint) {
oldContainingShadow->RemoveInsertionPoint(this);
// Remove all the matched nodes now that the
// insertion point is no longer an insertion point.
ClearMatchedNodes();
oldContainingShadow->SetInsertionPointChanged();
mIsInsertionPoint = false;
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
void

Просмотреть файл

@ -111,13 +111,15 @@ HTMLShadowElement::BindToTree(nsIDocument* aDocument,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
nsRefPtr<ShadowRoot> oldContainingShadow = GetContainingShadow();
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
ShadowRoot* containingShadow = GetContainingShadow();
if (containingShadow) {
if (containingShadow && !oldContainingShadow) {
// Keep track of all descendant <shadow> elements in tree order so
// that when the current shadow insertion point is removed, the next
// one can be found quickly.
@ -141,35 +143,58 @@ HTMLShadowElement::BindToTree(nsIDocument* aDocument,
containingShadow->SetInsertionPointChanged();
}
if (mIsInsertionPoint && containingShadow) {
// Propagate BindToTree calls to projected shadow root children.
ShadowRoot* projectedShadow = containingShadow->GetOlderShadow();
if (projectedShadow) {
for (nsIContent* child = projectedShadow->GetFirstChild(); child;
child = child->GetNextSibling()) {
rv = child->BindToTree(nullptr, projectedShadow,
projectedShadow->GetBindingParent(),
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
return NS_OK;
}
void
HTMLShadowElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
if (mIsInsertionPoint) {
ShadowRoot* containingShadow = GetContainingShadow();
// Make sure that containingShadow exists, it may have been nulled
// during unlinking in which case the ShadowRoot is going away.
if (containingShadow) {
nsTArray<HTMLShadowElement*>& shadowDescendants =
containingShadow->ShadowDescendants();
shadowDescendants.RemoveElement(this);
containingShadow->SetShadowElement(nullptr);
nsRefPtr<ShadowRoot> oldContainingShadow = GetContainingShadow();
// Find the next shadow insertion point.
if (shadowDescendants.Length() > 0 &&
!IsInFallbackContent(shadowDescendants[0])) {
containingShadow->SetShadowElement(shadowDescendants[0]);
if (mIsInsertionPoint && oldContainingShadow) {
// Propagate UnbindFromTree call to previous projected shadow
// root children.
ShadowRoot* projectedShadow = oldContainingShadow->GetOlderShadow();
if (projectedShadow) {
for (nsIContent* child = projectedShadow->GetFirstChild(); child;
child = child->GetNextSibling()) {
child->UnbindFromTree(true, false);
}
containingShadow->SetInsertionPointChanged();
}
mIsInsertionPoint = false;
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
if (oldContainingShadow && !GetContainingShadow() && mIsInsertionPoint) {
nsTArray<HTMLShadowElement*>& shadowDescendants =
oldContainingShadow->ShadowDescendants();
shadowDescendants.RemoveElement(this);
oldContainingShadow->SetShadowElement(nullptr);
// Find the next shadow insertion point.
if (shadowDescendants.Length() > 0 &&
!IsInFallbackContent(shadowDescendants[0])) {
oldContainingShadow->SetShadowElement(shadowDescendants[0]);
}
oldContainingShadow->SetInsertionPointChanged();
mIsInsertionPoint = false;
}
}
void

Просмотреть файл

@ -156,9 +156,19 @@ HTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
void
HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
nsCOMPtr<nsIDocument> oldComposedDoc = GetComposedDoc();
ShadowRoot* oldShadow = GetContainingShadow();
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
if (GetContainingShadow() && !oldComposedDoc) {
// The style is in a shadow tree and was already not
// in the composed document. Thus the sheet does not
// need to be updated.
return;
}
UpdateStyleSheetInternal(oldDoc, oldShadow);
}

Просмотреть файл

@ -418,6 +418,7 @@ skip-if = (toolkit == 'gonk' && debug) || e10s #debug-only failure
[test_bug879319.html]
[test_bug885024.html]
[test_bug893537.html]
[test_bug95530.html]
[test_bug969346.html]
[test_bug982039.html]
[test_bug1003539.html]

Просмотреть файл

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=95530
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 95530</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 95530 **/
function run() {
is(document.compatMode, "CSS1Compat", "Ensure we are in standards mode, not quirks mode.");
var body = document.getElementsByTagName("body");
is(computedStyle(body[0],"margin-top"), "100px", "Ensure margin-top matches topmargin");
is(computedStyle(body[0],"margin-bottom"), "150px", "Ensure margin-bottom matches bottommargin");
is(computedStyle(body[0],"margin-left"), "23px", "Ensure margin-left matches leftmargin");
is(computedStyle(body[0],"margin-right"), "64px", "Ensure margin-right matches rightmargin");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
window.addEventListener("load", run, false);
</script>
</head>
<body topmargin="100" bottommargin="150" leftmargin="23" rightmargin="64">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=95530">Mozilla Bug 95530</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -154,7 +154,8 @@ AudioSegment::WriteTo(uint64_t aID, AudioMixer& aMixer, uint32_t aOutputChannels
// Offset in the buffer that will end up sent to the AudioStream, in samples.
uint32_t offset = 0;
if (!GetDuration()) {
if (GetDuration() <= 0) {
MOZ_ASSERT(GetDuration() == 0);
return;
}

Просмотреть файл

@ -86,8 +86,8 @@ struct AudioChunk {
// Generic methods
void SliceTo(TrackTicks aStart, TrackTicks aEnd)
{
NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
"Slice out of bounds");
MOZ_ASSERT(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
"Slice out of bounds");
if (mBuffer) {
MOZ_ASSERT(aStart < INT32_MAX, "Can't slice beyond 32-bit sample lengths");
for (uint32_t channel = 0; channel < mChannelData.Length(); ++channel) {

Просмотреть файл

@ -53,7 +53,6 @@ GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
mNextStateComputedTime(0),
mGraphImpl(aGraphImpl),
mWaitState(WAITSTATE_RUNNING),
mNeedAnotherIteration(false),
mCurrentTimeStamp(TimeStamp::Now()),
mPreviousDriver(nullptr),
mNextDriver(nullptr)
@ -95,6 +94,7 @@ void GraphDriver::EnsureImmediateWakeUpLocked()
{
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
mWaitState = WAITSTATE_WAKING_UP;
mGraphImpl->mGraphDriverAsleep = false; // atomic
mGraphImpl->GetMonitor().Notify();
}
@ -113,22 +113,7 @@ void GraphDriver::UpdateStateComputedTime(GraphTime aStateComputedTime)
void GraphDriver::EnsureNextIteration()
{
MonitorAutoLock lock(mGraphImpl->GetMonitor());
EnsureNextIterationLocked();
}
void GraphDriver::EnsureNextIterationLocked()
{
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
if (IsWaitingIndefinitly()) {
WakeUp();
}
if (mNeedAnotherIteration) {
return;
}
mNeedAnotherIteration = true;
mGraphImpl->EnsureNextIteration();
}
class MediaStreamGraphShutdownThreadRunnable : public nsRunnable {
@ -225,7 +210,11 @@ ThreadedDriver::Start()
{
LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl);
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
// Note: mThread may be null during event->Run() if we pass to NewNamedThread! See AudioInitTask
nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
if (NS_SUCCEEDED(rv)) {
mThread->Dispatch(event, NS_DISPATCH_NORMAL);
}
}
void
@ -237,9 +226,12 @@ ThreadedDriver::Resume()
void
ThreadedDriver::Revive()
{
// Note: only called on MainThread, without monitor
// We know were weren't in a running state
STREAM_LOG(PR_LOG_DEBUG, ("AudioCallbackDriver reviving."));
// If we were switching, switch now. Otherwise, tell thread to run the main
// loop again.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime, mNextStateComputedTime);
@ -260,6 +252,7 @@ ThreadedDriver::Stop()
if (mThread) {
mThread->Shutdown();
mThread = nullptr;
}
}
@ -353,7 +346,7 @@ SystemClockDriver::WaitForNextIteration()
PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
TimeStamp now = TimeStamp::Now();
if (mNeedAnotherIteration) {
if (mGraphImpl->mNeedAnotherIteration) {
int64_t timeoutMS = MEDIA_GRAPH_TARGET_PERIOD_MS -
int64_t((now - mCurrentTimeStamp).ToMilliseconds());
// Make sure timeoutMS doesn't overflow 32 bits by waking up at
@ -361,8 +354,12 @@ SystemClockDriver::WaitForNextIteration()
timeoutMS = std::max<int64_t>(0, std::min<int64_t>(timeoutMS, 60*1000));
timeout = PR_MillisecondsToInterval(uint32_t(timeoutMS));
STREAM_LOG(PR_LOG_DEBUG+1, ("Waiting for next iteration; at %f, timeout=%f", (now - mInitialTimeStamp).ToSeconds(), timeoutMS/1000.0));
if (mWaitState == WAITSTATE_WAITING_INDEFINITELY) {
mGraphImpl->mGraphDriverAsleep = false; // atomic
}
mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
} else {
mGraphImpl->mGraphDriverAsleep = true; // atomic
mWaitState = WAITSTATE_WAITING_INDEFINITELY;
}
if (timeout > 0) {
@ -372,8 +369,11 @@ SystemClockDriver::WaitForNextIteration()
(TimeStamp::Now() - now).ToSeconds()));
}
if (mWaitState == WAITSTATE_WAITING_INDEFINITELY) {
mGraphImpl->mGraphDriverAsleep = false; // atomic
}
mWaitState = WAITSTATE_RUNNING;
mNeedAnotherIteration = false;
mGraphImpl->mNeedAnotherIteration = false;
}
void
@ -381,6 +381,7 @@ SystemClockDriver::WakeUp()
{
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
mWaitState = WAITSTATE_WAKING_UP;
mGraphImpl->mGraphDriverAsleep = false; // atomic
mGraphImpl->GetMonitor().Notify();
}
@ -400,19 +401,25 @@ public:
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mThread);
mThread->Shutdown();
mThread = nullptr;
return NS_OK;
}
private:
nsRefPtr<nsIThread> mThread;
nsCOMPtr<nsIThread> mThread;
};
OfflineClockDriver::~OfflineClockDriver()
{
// transfer the ownership of mThread to the event
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutdownThreadRunnable2(mThread);
mThread = nullptr;
NS_DispatchToMainThread(event);
// XXX should use .forget()/etc
if (mThread) {
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutdownThreadRunnable2(mThread);
mThread = nullptr;
NS_DispatchToMainThread(event);
}
}
void
@ -496,12 +503,14 @@ AsyncCubebTask::Run()
LIFECYCLE_LOG("AsyncCubebOperation::SLEEP\n");
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
// We might just have been awoken
if (mDriver->mNeedAnotherIteration) {
if (mDriver->mGraphImpl->mNeedAnotherIteration) {
mDriver->mPauseRequested = false;
mDriver->mWaitState = AudioCallbackDriver::WAITSTATE_RUNNING;
mDriver->mGraphImpl->mGraphDriverAsleep = false ; // atomic
break;
}
mDriver->Stop();
mDriver->mGraphImpl->mGraphDriverAsleep = true; // atomic
mDriver->mWaitState = AudioCallbackDriver::WAITSTATE_WAITING_INDEFINITELY;
mDriver->mPauseRequested = false;
mDriver->mGraphImpl->GetMonitor().Wait(PR_INTERVAL_NO_TIMEOUT);
@ -660,16 +669,21 @@ AudioCallbackDriver::Stop()
void
AudioCallbackDriver::Revive()
{
// Note: only called on MainThread, without monitor
// We know were weren't in a running state
STREAM_LOG(PR_LOG_DEBUG, ("AudioCallbackDriver reviving."));
// If we were switching, switch now. Otherwise, start the audio thread again.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime, mNextStateComputedTime);
mStateComputedTime, mNextStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
} else {
Init();
Start();
STREAM_LOG(PR_LOG_DEBUG, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
nsRefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(this, AsyncCubebTask::INIT);
initEvent->Dispatch();
}
}
@ -699,7 +713,7 @@ void AudioCallbackDriver::WaitForNextIteration()
// We can't block on the monitor in the audio callback, so we kick off a new
// thread that will pause the audio stream, and restart it when unblocked.
// We don't want to sleep when we haven't started the driver yet.
if (!mNeedAnotherIteration && mAudioStream && mGraphImpl->Running()) {
if (!mGraphImpl->mNeedAnotherIteration && mAudioStream && mGraphImpl->Running()) {
STREAM_LOG(PR_LOG_DEBUG+1, ("AudioCallbackDriver going to sleep"));
mPauseRequested = true;
nsRefPtr<AsyncCubebTask> sleepEvent =
@ -741,19 +755,16 @@ AudioCallbackDriver::DeviceChangedCallback_s(void* aUser)
}
bool AudioCallbackDriver::InCallback() {
MonitorAutoLock mon(mGraphImpl->GetMonitor());
return mInCallback;
}
AudioCallbackDriver::AutoInCallback::AutoInCallback(AudioCallbackDriver* aDriver)
: mDriver(aDriver)
{
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
mDriver->mInCallback = true;
}
AudioCallbackDriver::AutoInCallback::~AutoInCallback() {
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
mDriver->mInCallback = false;
}
@ -767,7 +778,12 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
return aFrames;
}
DebugOnly<AutoInCallback> aic(AutoInCallback(this));
#ifdef DEBUG
// DebugOnly<> doesn't work here... it forces an initialization that will cause
// mInCallback to be set back to false before we exit the statement. Do it by
// hand instead.
AutoInCallback aic(this);
#endif
if (mStateComputedTime == 0) {
MonitorAutoLock mon(mGraphImpl->GetMonitor());

Просмотреть файл

@ -11,6 +11,7 @@
#include "AudioBufferUtils.h"
#include "AudioMixer.h"
#include "AudioSegment.h"
#include "mozilla/Atomics.h"
struct cubeb_stream;
@ -198,6 +199,8 @@ public:
return mGraphImpl;
}
virtual bool OnThread() = 0;
protected:
// Time of the start of this graph iteration.
GraphTime mIterationStart;
@ -225,8 +228,6 @@ protected:
};
WaitState mWaitState;
// True if the graph needs another iteration after the current iteration.
bool mNeedAnotherIteration;
TimeStamp mCurrentTimeStamp;
// This is non-null only when this driver has recently switched from an other
// driver, and has not cleaned it up yet (for example because the audio stream
@ -262,6 +263,9 @@ public:
uint32_t IterationDuration() {
return MEDIA_GRAPH_TARGET_PERIOD_MS;
}
virtual bool OnThread() MOZ_OVERRIDE { return !mThread || NS_GetCurrentThread() == mThread; }
protected:
nsCOMPtr<nsIThread> mThread;
};
@ -384,6 +388,8 @@ public:
*/
bool InCallback();
virtual bool OnThread() MOZ_OVERRIDE { return !mStarted || InCallback(); }
/* Whether the underlying cubeb stream has been started. See comment for
* mStarted for details. */
bool IsStarted();
@ -449,8 +455,7 @@ private:
* shutdown of the audio stream. */
nsCOMPtr<nsIThread> mInitShutdownThread;
dom::AudioChannel mAudioChannel;
/* This can only be accessed with the graph's monitor held. */
bool mInCallback;
Atomic<bool> mInCallback;
/* A thread has been created to be able to pause and restart the audio thread,
* but has not done so yet. This indicates that the callback should return
* early */

Просмотреть файл

@ -1310,7 +1310,7 @@ void MediaDecoderStateMachine::UpdateEstimatedDuration(int64_t aDuration)
AssertCurrentThreadInMonitor();
int64_t duration = GetDuration();
if (aDuration != duration &&
abs(aDuration - duration) > ESTIMATED_DURATION_FUZZ_FACTOR_USECS) {
std::abs(aDuration - duration) > ESTIMATED_DURATION_FUZZ_FACTOR_USECS) {
SetDuration(aDuration);
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(mDecoder, &MediaDecoder::DurationChanged);

Просмотреть файл

@ -95,7 +95,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
// Force at least one more iteration of the control loop, since we rely
// on UpdateCurrentTimeForStreams to notify our listeners once the stream end
// has been reached.
CurrentDriver()->EnsureNextIteration();
EnsureNextIteration();
SetStreamOrderDirty();
}
@ -778,7 +778,7 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
if (blockingDecisionsWillChange) {
// Make sure we wake up to notify listeners about these changes.
CurrentDriver()->EnsureNextIteration();
EnsureNextIteration();
}
}
@ -1288,7 +1288,7 @@ MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecision)
// computed in next loop.
if (ensureNextIteration ||
aEndBlockingDecision == CurrentDriver()->StateComputedTime()) {
CurrentDriver()->EnsureNextIteration();
EnsureNextIteration();
}
// Figure out which streams are blocked and when.
@ -1382,7 +1382,7 @@ MediaStreamGraphImpl::Process(GraphTime aFrom, GraphTime aTo)
}
if (!allBlockedForever) {
CurrentDriver()->EnsureNextIteration();
EnsureNextIteration();
}
}
@ -1468,7 +1468,7 @@ MediaStreamGraphImpl::ForceShutDown()
{
MonitorAutoLock lock(mMonitor);
mForceShutDown = true;
CurrentDriver()->EnsureNextIterationLocked();
EnsureNextIterationLocked();
}
}
@ -1486,11 +1486,18 @@ public:
LIFECYCLE_LOG("Shutting down graph %p", mGraph.get());
if (mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
MOZ_ASSERT(!mGraph->CurrentDriver()->AsAudioCallbackDriver()->InCallback());
// We've asserted the graph isn't running. Use mDriver instead of CurrentDriver
// to avoid thread-safety checks
#if 0 // AudioCallbackDrivers are released asynchronously anyways
// XXX a better test would be have setting mDetectedNotRunning make sure
// any current callback has finished and block future ones -- or just
// handle it all in Shutdown()!
if (mGraph->mDriver->AsAudioCallbackDriver()) {
MOZ_ASSERT(!mGraph->mDriver->AsAudioCallbackDriver()->InCallback());
}
#endif
mGraph->CurrentDriver()->Shutdown();
mGraph->mDriver->Shutdown();
// mGraph's thread is not running so it's OK to do whatever here
if (mGraph->IsEmpty()) {
@ -1637,7 +1644,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
block->mMessages.SwapElements(mCurrentTaskMessageQueue);
block->mGraphUpdateIndex = mNextGraphUpdateIndex;
++mNextGraphUpdateIndex;
CurrentDriver()->EnsureNextIterationLocked();
EnsureNextIterationLocked();
}
// If the MediaStreamGraph has more messages going to it, try to revive
@ -1651,11 +1658,12 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
// Note that we need to put messages into its queue before reviving it,
// or it might exit immediately.
{
MonitorAutoUnlock unlock(mMonitor);
LIFECYCLE_LOG("Reviving a graph (%p) ! %s\n",
this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
"SystemDriver");
CurrentDriver()->Revive();
nsRefPtr<GraphDriver> driver = CurrentDriver();
MonitorAutoUnlock unlock(mMonitor);
driver->Revive();
}
}
}
@ -1671,12 +1679,13 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
{
// We should exit the monitor for now, because starting a stream might
// take locks, and we don't want to deadlock.
MonitorAutoUnlock unlock(mMonitor);
LIFECYCLE_LOG("Starting a graph (%p) ! %s\n",
this,
CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
"SystemDriver");
CurrentDriver()->Start();
nsRefPtr<GraphDriver> driver = CurrentDriver();
MonitorAutoUnlock unlock(mMonitor);
driver->Start();
}
}
@ -1718,6 +1727,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
#endif
}
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
void
@ -2258,7 +2268,7 @@ SourceMediaStream::SetPullEnabled(bool aEnabled)
MutexAutoLock lock(mMutex);
mPullEnabled = aEnabled;
if (mPullEnabled && GraphImpl()) {
GraphImpl()->CurrentDriver()->EnsureNextIteration();
GraphImpl()->EnsureNextIteration();
}
}
@ -2278,7 +2288,7 @@ SourceMediaStream::AddTrack(TrackID aID, TrackRate aRate, TrackTicks aStart,
data->mData = aSegment;
data->mHaveEnough = false;
if (auto graph = GraphImpl()) {
graph->CurrentDriver()->EnsureNextIteration();
graph->EnsureNextIteration();
}
}
@ -2340,7 +2350,7 @@ SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegme
NotifyDirectConsumers(track, aRawSegment ? aRawSegment : aSegment);
track->mData->AppendFrom(aSegment); // note: aSegment is now dead
appended = true;
GraphImpl()->CurrentDriver()->EnsureNextIteration();
GraphImpl()->EnsureNextIteration();
} else {
aSegment->Clear();
}
@ -2464,7 +2474,7 @@ SourceMediaStream::EndTrack(TrackID aID)
}
}
if (auto graph = GraphImpl()) {
graph->CurrentDriver()->EnsureNextIteration();
graph->EnsureNextIteration();
}
}
@ -2475,7 +2485,7 @@ SourceMediaStream::AdvanceKnownTracksTime(StreamTime aKnownTime)
MOZ_ASSERT(aKnownTime >= mUpdateKnownTracksTime);
mUpdateKnownTracksTime = aKnownTime;
if (auto graph = GraphImpl()) {
graph->CurrentDriver()->EnsureNextIteration();
graph->EnsureNextIteration();
}
}
@ -2485,7 +2495,7 @@ SourceMediaStream::FinishWithLockHeld()
mMutex.AssertCurrentThreadOwns();
mUpdateFinished = true;
if (auto graph = GraphImpl()) {
graph->CurrentDriver()->EnsureNextIteration();
graph->EnsureNextIteration();
}
}
@ -2702,6 +2712,8 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime,
dom::AudioChannel aChannel)
: mProcessingGraphUpdateIndex(0)
, mPortCount(0)
, mNeedAnotherIteration(false)
, mGraphDriverAsleep(false)
, mMonitor("MediaStreamGraphImpl")
, mLifecycleState(LIFECYCLE_THREAD_NOT_STARTED)
, mEndTime(GRAPH_TIME_MAX)

Просмотреть файл

@ -150,6 +150,12 @@ public:
void Init();
// The following methods run on the graph thread (or possibly the main thread if
// mLifecycleState > LIFECYCLE_RUNNING)
void AssertOnGraphThreadOrNotRunning() {
// either we're on the right thread (and calling CurrentDriver() is safe),
// or we're going to assert anyways, so don't cross-check CurrentDriver
MOZ_ASSERT(mDriver->OnThread() ||
(mLifecycleState > LIFECYCLE_RUNNING && NS_IsMainThread()));
}
/*
* This does the actual iteration: Message processing, MediaStream ordering,
* blocking computation and processing.
@ -414,7 +420,16 @@ public:
void PausedIndefinitly();
void ResumedFromPaused();
/**
* Not safe to call off the MediaStreamGraph thread unless monitor is held!
*/
GraphDriver* CurrentDriver() {
#ifdef DEBUG
// #ifdef since we're not wrapping it all in MOZ_ASSERT()
if (!mDriver->OnThread()) {
mMonitor.AssertCurrentThreadOwns();
}
#endif
return mDriver;
}
@ -423,8 +438,16 @@ public:
* It is only safe to call this at the very end of an iteration, when there
* has been a SwitchAtNextIteration call during the iteration. The driver
* should return and pass the control to the new driver shortly after.
* We can also switch from Revive() (on MainThread), in which case the
* monitor is held
*/
void SetCurrentDriver(GraphDriver* aDriver) {
#ifdef DEBUG
// #ifdef since we're not wrapping it all in MOZ_ASSERT()
if (!mDriver->OnThread()) {
mMonitor.AssertCurrentThreadOwns();
}
#endif
mDriver = aDriver;
}
@ -432,6 +455,21 @@ public:
return mMonitor;
}
void EnsureNextIteration() {
mNeedAnotherIteration = true; // atomic
if (mGraphDriverAsleep) { // atomic
MonitorAutoLock mon(mMonitor);
CurrentDriver()->WakeUp(); // Might not be the same driver; might have woken already
}
}
void EnsureNextIterationLocked() {
mNeedAnotherIteration = true; // atomic
if (mGraphDriverAsleep) { // atomic
CurrentDriver()->WakeUp(); // Might not be the same driver; might have woken already
}
}
// Data members
//
/**
@ -471,6 +509,11 @@ public:
*/
int32_t mPortCount;
// True if the graph needs another iteration after the current iteration.
Atomic<bool> mNeedAnotherIteration;
// GraphDriver may need a WakeUp() if something changes
Atomic<bool> mGraphDriverAsleep;
// mMonitor guards the data below.
// MediaStreamGraph normally does its work without holding mMonitor, so it is
// not safe to just grab mMonitor from some thread and start monkeying with
@ -479,7 +522,7 @@ public:
Monitor mMonitor;
// Data guarded by mMonitor (must always be accessed with mMonitor held,
// regardless of the value of mLifecycleState.
// regardless of the value of mLifecycleState).
/**
* State to copy to main thread
@ -559,10 +602,6 @@ public:
* at construction.
*/
TrackRate mSampleRate;
/**
* True when another iteration of the control loop is required.
*/
bool mNeedAnotherIteration;
/**
* True when we need to do a forced shutdown during application shutdown.
*/

Просмотреть файл

@ -0,0 +1,247 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "mozilla/ArrayUtils.h"
#include "WebMBufferedParser.h"
using namespace mozilla;
// This is a manually constructed WebM file containing several VP9 and Opus
// frames. It is stored parallel to this test as test.webm.
// XXX: This can be substituted for simple file access once bug 1054809 is
// addressed.
static const unsigned char gWebMData[] = {
0x1a, 0x45, 0xdf, 0xa3, 0x9f, 0x42, 0x86, 0x81, 0x01, 0x42, 0xf7, 0x81, 0x01,
0x42, 0xf2, 0x81, 0x04, 0x42, 0xf3, 0x81, 0x08, 0x42, 0x82, 0x84, 0x77, 0x65,
0x62, 0x6d, 0x42, 0x87, 0x81, 0x04, 0x42, 0x85, 0x81, 0x02, 0x18, 0x53, 0x80,
0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x29, 0x7b, 0x11, 0x4d, 0x9b, 0x74,
0x9e, 0x4d, 0xbb, 0x8c, 0x53, 0xab, 0x84, 0x15, 0x49, 0xa9, 0x66, 0x53, 0xac,
0x82, 0x10, 0x03, 0x4d, 0xbb, 0x8c, 0x53, 0xab, 0x84, 0x16, 0x54, 0xae, 0x6b,
0x53, 0xac, 0x82, 0x10, 0x91, 0x15, 0x49, 0xa9, 0x66, 0x40, 0x88, 0x2a, 0xd7,
0xb1, 0x83, 0x07, 0xa1, 0x20, 0x4d, 0x80, 0xa3, 0x6c, 0x69, 0x62, 0x65, 0x62,
0x6d, 0x6c, 0x20, 0x76, 0x31, 0x2e, 0x33, 0x2e, 0x30, 0x20, 0x2b, 0x20, 0x6c,
0x69, 0x62, 0x6d, 0x61, 0x74, 0x72, 0x6f, 0x73, 0x6b, 0x61, 0x20, 0x76, 0x31,
0x2e, 0x34, 0x2e, 0x31, 0x57, 0x41, 0xc6, 0x6d, 0x6b, 0x76, 0x6d, 0x65, 0x72,
0x67, 0x65, 0x20, 0x76, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x20, 0x28, 0x27, 0x57,
0x68, 0x65, 0x72, 0x65, 0x20, 0x57, 0x65, 0x20, 0x47, 0x6f, 0x69, 0x6e, 0x67,
0x27, 0x29, 0x20, 0x36, 0x34, 0x62, 0x69, 0x74, 0x20, 0x62, 0x75, 0x69, 0x6c,
0x74, 0x20, 0x6f, 0x6e, 0x20, 0x4a, 0x75, 0x6e, 0x20, 0x31, 0x38, 0x20, 0x32,
0x30, 0x31, 0x34, 0x20, 0x32, 0x32, 0x3a, 0x35, 0x39, 0x3a, 0x33, 0x33, 0x44,
0x89, 0x84, 0x46, 0x78, 0xf0, 0x00, 0x44, 0x61, 0x88, 0x06, 0x03, 0x72, 0xf2,
0x43, 0xa1, 0x5c, 0x00, 0x16, 0x54, 0xae, 0x6b, 0x40, 0x82, 0xae, 0xb0, 0xd7,
0x81, 0x01, 0x73, 0xc5, 0x84, 0x73, 0x13, 0x25, 0xf2, 0x83, 0x81, 0x01, 0x6d,
0xe7, 0x81, 0x01, 0x86, 0x85, 0x56, 0x5f, 0x56, 0x50, 0x39, 0xe0, 0x96, 0xb0,
0x82, 0x01, 0x68, 0xba, 0x82, 0x02, 0x80, 0x54, 0xb0, 0x84, 0x00, 0x00, 0x01,
0x68, 0x54, 0xba, 0x84, 0x00, 0x00, 0x02, 0x80, 0xae, 0xce, 0xd7, 0x81, 0x02,
0x73, 0xc5, 0x88, 0x1b, 0x43, 0x37, 0xbe, 0x2e, 0x33, 0x75, 0xb7, 0x83, 0x81,
0x02, 0x86, 0x86, 0x41, 0x5f, 0x4f, 0x50, 0x55, 0x53, 0x56, 0xbb, 0x84, 0x04,
0xc4, 0xb4, 0x00, 0x63, 0xa2, 0x93, 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61,
0x64, 0x01, 0x02, 0x38, 0x01, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
0xb5, 0x9c, 0x83, 0x75, 0x6e, 0x64, 0x56, 0xaa, 0x83, 0x63, 0x2e, 0xa0, 0xe1,
0x89, 0xb5, 0x84, 0x47, 0x3b, 0x80, 0x00, 0x9f, 0x81, 0x02, 0x1f, 0x43, 0xb6,
0x75, 0x20, 0x7b, 0x16, 0xe7, 0x81, 0x00, 0xa3, 0x40, 0x7f, 0x81, 0x00, 0x84,
0x00, 0x86, 0x00, 0x40, 0x96, 0x18, 0x6c, 0x5a, 0xa0, 0x00, 0x07, 0x70, 0xc9,
0x9f, 0x90, 0x50, 0xc6, 0x00, 0x68, 0x2b, 0x93, 0x3a, 0x84, 0x29, 0x51, 0x23,
0x14, 0x96, 0xf8, 0xbc, 0xeb, 0x12, 0xde, 0x2c, 0x10, 0x52, 0x96, 0x3f, 0x7f,
0xad, 0xb7, 0xea, 0x69, 0x08, 0x20, 0x9b, 0x70, 0x2a, 0x94, 0x85, 0x21, 0x90,
0x66, 0x93, 0x7d, 0x4f, 0xff, 0x20, 0x02, 0xbd, 0x5f, 0xa2, 0xb1, 0xd3, 0x4b,
0xae, 0x35, 0xdc, 0x7a, 0x2a, 0xcb, 0x2e, 0xdf, 0x0c, 0x9b, 0x57, 0xff, 0x2e,
0xe7, 0x4c, 0x61, 0xd0, 0x8b, 0xf6, 0x89, 0x3d, 0x79, 0x60, 0x8a, 0x61, 0xb9,
0xbf, 0x2c, 0x6c, 0x6f, 0x56, 0xe2, 0xb7, 0xf7, 0xcd, 0xc7, 0xf6, 0xe1, 0xd7,
0xc8, 0x84, 0x17, 0x4c, 0x0b, 0xb2, 0x41, 0x1d, 0x22, 0xb1, 0x3e, 0x01, 0x32,
0xa5, 0xc8, 0xde, 0x75, 0xd5, 0x96, 0x7c, 0xa3, 0x41, 0x0c, 0x82, 0x01, 0x40,
0x86, 0x07, 0xa1, 0xbc, 0xc1, 0xbe, 0xc0, 0xbf, 0xc0, 0x68, 0x08, 0xae, 0xc4,
0x07, 0x86, 0x80, 0x78, 0xe6, 0x60, 0x0c, 0x96, 0xf1, 0x0e, 0xc0, 0xdb, 0xce,
0x8c, 0xea, 0xbe, 0xf1, 0x38, 0x10, 0x6e, 0x55, 0x76, 0x86, 0xe0, 0x0c, 0x8b,
0x6e, 0x62, 0x1e, 0x68, 0x08, 0xae, 0xfa, 0x05, 0x7e, 0x38, 0x25, 0x6e, 0x8a,
0xe0, 0x68, 0xe4, 0x34, 0x91, 0x47, 0x1a, 0xb2, 0x9e, 0x8f, 0xb1, 0xc6, 0x2e,
0x6f, 0xd6, 0xda, 0x3b, 0x7f, 0x4b, 0x98, 0x68, 0x08, 0xae, 0xe6, 0xeb, 0xbf,
0xde, 0x84, 0x2e, 0xd9, 0xe1, 0x38, 0x90, 0xaa, 0x86, 0x3b, 0xd1, 0xa7, 0xd3,
0x8f, 0x77, 0x02, 0xe0, 0xd5, 0xf8, 0xa0, 0x28, 0x0f, 0xd2, 0x60, 0xe8, 0xe9,
0x68, 0x08, 0xad, 0xdc, 0x8b, 0x4b, 0x58, 0x92, 0x9c, 0xe3, 0x64, 0x98, 0x70,
0xdf, 0x04, 0x06, 0x0d, 0x47, 0x39, 0xbc, 0xcf, 0x08, 0xdc, 0x8e, 0x95, 0x0b,
0x1c, 0x30, 0x6a, 0x2f, 0xe7, 0x68, 0x08, 0xae, 0xca, 0x2c, 0xa3, 0x01, 0x61,
0xff, 0x31, 0x44, 0x65, 0x8f, 0x5f, 0xbe, 0x49, 0xdf, 0x3d, 0xa3, 0x76, 0xc6,
0x78, 0x0e, 0x31, 0xb3, 0xda, 0x67, 0x81, 0x7f, 0xa3, 0x69, 0x97, 0x68, 0x08,
0xae, 0xaf, 0xa5, 0xe2, 0x11, 0xca, 0x99, 0x40, 0xc3, 0x1f, 0xc1, 0x01, 0xd0,
0x45, 0x46, 0x10, 0xfc, 0x1f, 0xad, 0x18, 0xb7, 0xa2, 0x0b, 0x42, 0x86, 0x16,
0x8c, 0xf3, 0x00, 0x29, 0x68, 0x08, 0xae, 0xcb, 0x01, 0x40, 0x52, 0x77, 0xc4,
0xcb, 0xd3, 0x47, 0x22, 0x80, 0xde, 0x81, 0xed, 0x19, 0x6d, 0xf2, 0xd8, 0x02,
0xb4, 0xb9, 0x27, 0x18, 0xe1, 0xd1, 0x53, 0xc0, 0x5a, 0x7c, 0x9e, 0x68, 0x08,
0xc2, 0x87, 0xa4, 0xfc, 0x0b, 0x8c, 0xa3, 0xa9, 0xe0, 0x1d, 0xc0, 0x7a, 0x16,
0x0a, 0x0b, 0x1f, 0xd5, 0xc6, 0xa9, 0x41, 0xc4, 0x58, 0xf0, 0x30, 0x84, 0xf3,
0x0b, 0x3e, 0x55, 0xb5, 0xe0, 0xa3, 0x40, 0x9b, 0x81, 0x00, 0xc8, 0x00, 0x86,
0x00, 0x40, 0x96, 0x18, 0x34, 0x5a, 0xa0, 0x00, 0x05, 0x60, 0xf4, 0x40, 0x00,
0x00, 0x60, 0xfb, 0x4e, 0x88, 0x14, 0xf1, 0xff, 0x24, 0x86, 0xd8, 0x07, 0xd4,
0x3f, 0xf0, 0x2b, 0xcb, 0xd6, 0xcd, 0xe4, 0xea, 0x4d, 0xde, 0x1a, 0xc7, 0xf8,
0x9e, 0xab, 0x62, 0xd5, 0x2b, 0xf9, 0x21, 0x7f, 0xe1, 0x81, 0xef, 0xbd, 0xd6,
0x08, 0x8d, 0xba, 0x2e, 0xd3, 0x1d, 0xc4, 0x20, 0x45, 0xda, 0xde, 0x64, 0xa1,
0x90, 0x51, 0x15, 0x3e, 0xdf, 0x64, 0xf1, 0x97, 0x5f, 0xb6, 0x5d, 0x1e, 0x3e,
0xe6, 0x0c, 0x46, 0x04, 0x28, 0x5d, 0x72, 0x2f, 0x26, 0xec, 0x65, 0x09, 0x3c,
0xfa, 0xf7, 0x28, 0x73, 0xb4, 0x59, 0x37, 0x21, 0xf6, 0xc3, 0xd2, 0xfa, 0x26,
0xa5, 0xcc, 0x3c, 0x77, 0x12, 0x3e, 0x69, 0xd6, 0xf8, 0xf0, 0x7a, 0x32, 0xfe,
0x70, 0xe6, 0x61, 0x67, 0x39, 0xb1, 0x8f, 0xe1, 0x6f, 0x37, 0xf1, 0x43, 0xbc,
0xa1, 0xa0, 0xe9, 0x76, 0xe1, 0x48, 0x6d, 0xac, 0xf3, 0x60, 0x58, 0x2c, 0x19,
0xbe, 0x52, 0xa0, 0x15, 0xbc, 0x32, 0x80, 0xa3, 0x40, 0x98, 0x81, 0x01, 0x0a,
0x00, 0x86, 0x00, 0x40, 0x96, 0x28, 0x44, 0x5a, 0xa0, 0x00, 0x03, 0x60, 0x00,
0x00, 0x5c, 0xf9, 0xef, 0x22, 0x1b, 0x32, 0x7f, 0xb5, 0xc0, 0x29, 0x8d, 0x80,
0x5f, 0x15, 0x79, 0xbb, 0xa1, 0xa7, 0xde, 0x8f, 0xba, 0x67, 0x83, 0x88, 0xbc,
0x6a, 0xb0, 0x71, 0xa6, 0x14, 0xae, 0x47, 0x6f, 0xb6, 0x03, 0x5b, 0xe8, 0x50,
0x07, 0xa0, 0xbb, 0xcd, 0x0d, 0xc2, 0x28, 0xc1, 0x33, 0x7a, 0x6b, 0x4d, 0x5c,
0x00, 0xc8, 0x3c, 0x57, 0x92, 0x38, 0x78, 0xd8, 0x91, 0x45, 0x69, 0xb9, 0x78,
0xf7, 0x0c, 0xf9, 0x43, 0xc4, 0x94, 0x22, 0xd1, 0x61, 0x97, 0x32, 0xa9, 0x0b,
0x78, 0x3a, 0xcd, 0xcc, 0x12, 0xe3, 0x66, 0xef, 0x37, 0xb2, 0xbe, 0x8f, 0x2d,
0xea, 0xa0, 0x11, 0x9b, 0x03, 0xb1, 0x0d, 0x44, 0xe3, 0xd5, 0x64, 0x74, 0x3a,
0xc8, 0x63, 0x46, 0xef, 0x83, 0xb2, 0x9b, 0xac, 0xa4, 0xd5, 0x6d, 0xef, 0x0c,
0x5a, 0xfe, 0x1b, 0x01, 0xc5, 0xb3, 0x33, 0xe3, 0xca, 0xc4, 0x5a, 0xd6, 0xde,
0x67, 0x9c, 0x92, 0x9e, 0x2a, 0x44, 0xa3, 0x40, 0x9c, 0x81, 0x01, 0x4c, 0x00,
0x86, 0x00, 0x40, 0x96, 0x18, 0x5c, 0x5a, 0xa0, 0x00, 0x03, 0x60, 0x00, 0x00,
0x58, 0xec, 0xd2, 0x58, 0x0d, 0x75, 0x16, 0x57, 0x84, 0x79, 0x36, 0x68, 0xc0,
0x88, 0x22, 0x7f, 0xde, 0x47, 0x68, 0xfe, 0x16, 0x98, 0x0c, 0xcc, 0x7e, 0xa2,
0x8f, 0xd3, 0xe9, 0x9f, 0xf1, 0x63, 0x61, 0xc1, 0xf4, 0x2a, 0xbe, 0x84, 0xdb,
0x96, 0x8a, 0x72, 0x24, 0xd0, 0xda, 0x2d, 0x15, 0x43, 0xd2, 0xb5, 0x02, 0x27,
0xf0, 0x1c, 0x93, 0x3c, 0x0c, 0xa5, 0xda, 0x50, 0x94, 0xe4, 0xec, 0x92, 0x3a,
0x1a, 0xbc, 0xac, 0xbb, 0x79, 0x58, 0x8e, 0xaf, 0x8a, 0x6c, 0xe3, 0xb3, 0x23,
0x82, 0x48, 0x42, 0x7d, 0x1f, 0x67, 0x00, 0x95, 0xbe, 0xa4, 0x30, 0xe5, 0xc7,
0x88, 0xb3, 0xb0, 0x14, 0x03, 0x24, 0xba, 0x11, 0x95, 0x4a, 0xd9, 0xf4, 0xa2,
0x1f, 0xae, 0xaf, 0x96, 0x16, 0x41, 0x17, 0x76, 0x9e, 0x86, 0x33, 0xac, 0x34,
0x68, 0x0f, 0x77, 0xa9, 0x8c, 0xe6, 0xcb, 0xd9, 0x35, 0x21, 0x28, 0x01, 0x2f,
0x21, 0xce, 0x52, 0xff, 0xc6, 0x81, 0x87, 0x99, 0x80, 0xa3, 0x40, 0x85, 0x81,
0x01, 0x90, 0x00, 0x86, 0x00, 0x40, 0x96, 0x18, 0x7c, 0x5a, 0xc0, 0x00, 0x03,
0x60, 0x00, 0x00, 0x55, 0x18, 0xaa, 0xef, 0xc0, 0x94, 0x12, 0xd3, 0xb7, 0xc5,
0x38, 0xfa, 0xb1, 0xd8, 0xf1, 0x9e, 0x4f, 0x2d, 0xb0, 0xef, 0x92, 0xcd, 0xda,
0x79, 0x59, 0x95, 0x52, 0x11, 0xb3, 0x20, 0xae, 0x61, 0x0d, 0x90, 0xe3, 0x9a,
0x6c, 0x99, 0xae, 0x59, 0xd6, 0xbc, 0xa7, 0x16, 0x03, 0xc0, 0x2e, 0x39, 0xb6,
0x74, 0xa7, 0x4e, 0x23, 0xd9, 0x58, 0x8d, 0xc1, 0x30, 0x54, 0x84, 0x39, 0x91,
0xb2, 0x11, 0x7e, 0x0f, 0x4b, 0x6e, 0x41, 0x1c, 0x6c, 0x82, 0xaa, 0x86, 0xbb,
0x4a, 0x57, 0x76, 0x9b, 0xa1, 0x6e, 0x13, 0x72, 0x0c, 0x41, 0x64, 0xb4, 0xe9,
0xc1, 0x4d, 0x47, 0xa1, 0x24, 0x12, 0xdb, 0x78, 0xc4, 0xc4, 0x8a, 0xa8, 0x8b,
0x8d, 0xf7, 0x7a, 0x51, 0x2f, 0xf2, 0x75, 0xef, 0xd1, 0x7f, 0x46, 0x1a, 0xe4,
0x58, 0x00, 0xa3, 0x40, 0xa0, 0x81, 0x01, 0xd2, 0x00, 0x86, 0x00, 0x40, 0x96,
0x61, 0x11, 0x6b, 0x80, 0x00, 0x14, 0x60, 0xa5, 0x30, 0x00, 0x00, 0x53, 0x52,
0x29, 0x3a, 0xd0, 0xb9, 0xe3, 0x8b, 0x66, 0x7c, 0xc6, 0x2d, 0xae, 0x58, 0x27,
0x26, 0xd6, 0xb4, 0x06, 0xa2, 0xed, 0x73, 0xff, 0x69, 0x27, 0xfb, 0xe7, 0xe4,
0xc9, 0x6e, 0x55, 0x06, 0x79, 0xe3, 0x3b, 0x90, 0x18, 0x5b, 0x36, 0x7a, 0x6a,
0x80, 0x5e, 0xcf, 0x59, 0x1f, 0x83, 0x4b, 0xe2, 0x90, 0x6a, 0xfc, 0xd6, 0x7b,
0xb7, 0x97, 0x78, 0x7d, 0x13, 0x64, 0xc4, 0x3f, 0xf1, 0xd3, 0x25, 0x36, 0xa5,
0x1d, 0xe0, 0xdb, 0x4f, 0x7b, 0x48, 0xde, 0x2c, 0xde, 0x96, 0x7c, 0xc3, 0xd5,
0x72, 0x9b, 0xcb, 0x7a, 0xb6, 0x35, 0x18, 0x8f, 0x7e, 0xf8, 0xdb, 0x7c, 0x52,
0x6b, 0x5b, 0x17, 0xcf, 0xe3, 0xcc, 0x56, 0x5b, 0x0c, 0x7e, 0x3d, 0xf6, 0xf2,
0x0d, 0xc2, 0xfa, 0x52, 0xc8, 0x8e, 0x7d, 0x6e, 0x7c, 0x1a, 0x6b, 0xfb, 0xed,
0xe4, 0x95, 0xdf, 0x56, 0xed, 0x57, 0xc4, 0x14, 0x9c, 0xbf, 0xfa, 0xa0, 0xad,
0x98, 0x95, 0x13, 0xdd, 0x87, 0x73, 0xb9, 0x29, 0x00, 0xa3, 0x41, 0xd5, 0x82,
0x02, 0x80, 0x86, 0x07, 0xa9, 0xc7, 0xc2, 0xc4, 0xc8, 0xbb, 0xc4, 0x68, 0x09,
0xbc, 0x34, 0x69, 0x89, 0xaa, 0x8f, 0xe4, 0xff, 0xf4, 0x1d, 0x34, 0x67, 0x43,
0x2e, 0x1d, 0x26, 0x93, 0x14, 0x6e, 0x8f, 0xfa, 0x8e, 0xb0, 0xe2, 0x25, 0x7e,
0x1a, 0xce, 0x3a, 0x0e, 0xad, 0x50, 0x8c, 0xe9, 0xec, 0xed, 0x36, 0x4b, 0xb0,
0x68, 0x86, 0x19, 0xe2, 0xd9, 0xa5, 0xbc, 0x56, 0x9b, 0x2e, 0x19, 0x7c, 0x5b,
0x04, 0x2a, 0x84, 0x35, 0x80, 0x5a, 0xbe, 0x10, 0xb6, 0xff, 0x1c, 0x6d, 0x83,
0xa7, 0xf9, 0x20, 0x2e, 0x84, 0xe3, 0x83, 0x95, 0xe2, 0xf3, 0xa3, 0xc2, 0xe7,
0x0d, 0x05, 0x2b, 0x74, 0x25, 0x3a, 0x51, 0xbd, 0x93, 0x9f, 0x68, 0x80, 0x0a,
0x2d, 0x53, 0xde, 0xda, 0xb5, 0xc4, 0x32, 0x04, 0xec, 0xaf, 0xd7, 0xb0, 0x5b,
0x7d, 0x93, 0xb5, 0x44, 0xe7, 0x92, 0xb5, 0xba, 0x08, 0xbe, 0x8e, 0x23, 0x59,
0xef, 0xb1, 0x2b, 0x6b, 0xe2, 0x89, 0x59, 0xa7, 0x9c, 0x62, 0x9f, 0x97, 0x46,
0xd3, 0xe1, 0x33, 0x47, 0xf1, 0x1a, 0x69, 0x6b, 0xc1, 0xe8, 0x68, 0x80, 0x22,
0x95, 0x26, 0x69, 0x77, 0xdd, 0x3d, 0x66, 0x9d, 0xaa, 0xbf, 0xab, 0x9e, 0x18,
0x0a, 0x78, 0x17, 0xac, 0x58, 0x1e, 0x06, 0x2c, 0x5c, 0x66, 0x3c, 0x07, 0xb5,
0x5f, 0xd2, 0x55, 0xb7, 0xd3, 0x1c, 0xaf, 0x0f, 0xf3, 0xa6, 0x9d, 0x18, 0x3d,
0x65, 0x8c, 0x38, 0xd6, 0xdf, 0xa0, 0x21, 0x20, 0x72, 0x0f, 0x75, 0xa7, 0x0b,
0xde, 0x01, 0x68, 0x80, 0x45, 0x8f, 0x82, 0x6e, 0x30, 0x0a, 0x59, 0x93, 0x00,
0xab, 0x17, 0x2b, 0xfc, 0xfd, 0x5b, 0x42, 0x4d, 0x05, 0xf3, 0xb7, 0x2b, 0xcb,
0x88, 0x08, 0xf1, 0x93, 0xa0, 0xf4, 0x29, 0x53, 0x80, 0xef, 0xce, 0xe2, 0x18,
0x7f, 0xf7, 0x63, 0x91, 0x4d, 0x46, 0x32, 0x74, 0xa9, 0x1e, 0xf5, 0x2d, 0x04,
0x53, 0x3f, 0x44, 0x9c, 0x33, 0xb3, 0x91, 0x22, 0x0a, 0x51, 0x80, 0x73, 0xde,
0x27, 0x9e, 0x9b, 0x68, 0x80, 0x55, 0xd0, 0xd5, 0x84, 0x5e, 0x9d, 0xef, 0x6f,
0xc9, 0x22, 0x35, 0x5f, 0x44, 0x0d, 0xfe, 0xa2, 0x76, 0x77, 0x50, 0x00, 0x36,
0x81, 0xc7, 0x24, 0x1a, 0x8e, 0x90, 0x50, 0x2b, 0xf8, 0x19, 0x44, 0xbe, 0x86,
0x05, 0x28, 0x67, 0x7a, 0xbe, 0xad, 0x13, 0x94, 0x18, 0x23, 0x41, 0x4b, 0x2c,
0x60, 0x20, 0x4e, 0x02, 0x08, 0x99, 0xa8, 0x77, 0xb7, 0xcb, 0xef, 0x51, 0xa0,
0x68, 0x80, 0x76, 0x9b, 0x54, 0x21, 0xaa, 0x23, 0xb6, 0x7b, 0x17, 0xeb, 0xf3,
0x2b, 0xb5, 0xb6, 0xf0, 0x31, 0xb6, 0x0f, 0x52, 0x43, 0xd9, 0xb1, 0x1a, 0xba,
0x32, 0x43, 0xf1, 0x38, 0x32, 0xe7, 0x64, 0xea, 0xaf, 0x2c, 0xf9, 0x52, 0x86,
0x0e, 0xfa, 0xba, 0x1d, 0x29, 0x80, 0xc2, 0xa5, 0x40, 0x7c, 0x8b, 0xf8, 0x85,
0xfe, 0x28, 0x6a, 0x91, 0x76, 0x78, 0x22, 0xc0, 0xda, 0xfd, 0x8d, 0x92, 0xb1,
0x90, 0xa9, 0x68, 0x87, 0x4c, 0xac, 0xda, 0x9e, 0x36, 0x56, 0x5d, 0x7a, 0x79,
0xea, 0xe1, 0x0a, 0xb3, 0x67, 0x3b, 0x55, 0x2b, 0x4e, 0xde, 0x7f, 0x25, 0x4f,
0x34, 0xdb, 0x53, 0x53, 0x1e, 0x4d, 0x31, 0x51, 0x8c, 0x7b, 0xc8, 0x06, 0x73,
0x97, 0x7f, 0x47, 0xbe, 0xa7, 0xb7, 0x39, 0xbe, 0x89, 0xfb, 0x53, 0x6e, 0xd9,
0xf2, 0xfb, 0x80, 0xaf, 0x11, 0x28, 0xa3, 0x95, 0x3b, 0x88, 0xa3, 0x30, 0x00
};
// gWebMData contains 8 SimpleBlocks in a single Cluster with the following attributes
static const uint64_t gTimecodes[] = { 66000000, 160000000, 100000000, 133000000,
166000000, 200000000, 233000000, 320000000 };
static const int64_t gEndOffsets[] = { 501, 772, 930, 1085, 1244, 1380, 1543, 2015 };
TEST(WebMBuffered, BasicTests)
{
ReentrantMonitor dummy("dummy");
WebMBufferedParser parser(0);
nsTArray<WebMTimeDataOffset> mapping;
parser.Append(nullptr, 0, mapping, dummy);
EXPECT_TRUE(mapping.IsEmpty());
EXPECT_EQ(parser.mStartOffset, 0);
EXPECT_EQ(parser.mCurrentOffset, 0);
unsigned char buf[] = { 0x1a, 0x45, 0xdf, 0xa3 };
parser.Append(buf, ArrayLength(buf), mapping, dummy);
EXPECT_TRUE(mapping.IsEmpty());
EXPECT_EQ(parser.mStartOffset, 0);
EXPECT_EQ(parser.mCurrentOffset, 4);
}
TEST(WebMBuffered, RealData)
{
ReentrantMonitor dummy("dummy");
WebMBufferedParser parser(0);
nsTArray<WebMTimeDataOffset> mapping;
parser.Append(gWebMData, ArrayLength(gWebMData), mapping, dummy);
EXPECT_EQ(mapping.Length(), 8u);
EXPECT_EQ(parser.mStartOffset, 0);
EXPECT_EQ(parser.mCurrentOffset, int64_t(ArrayLength(gWebMData)));
EXPECT_EQ(parser.GetTimecodeScale(), 500000u);
for (uint32_t i = 0; i < mapping.Length(); ++i) {
EXPECT_EQ(mapping[i].mEndOffset, gEndOffsets[i]);
EXPECT_EQ(mapping[i].mSyncOffset, 361);
EXPECT_EQ(mapping[i].mTimecode, gTimecodes[i]);
}
}
TEST(WebMBuffered, RealDataAppend)
{
ReentrantMonitor dummy("dummy");
WebMBufferedParser parser(0);
nsTArray<WebMTimeDataOffset> mapping;
uint32_t arrayEntries = mapping.Length();
size_t offset = 0;
while (offset < ArrayLength(gWebMData)) {
parser.Append(gWebMData + offset, 1, mapping, dummy);
offset += 1;
EXPECT_EQ(parser.mCurrentOffset, int64_t(offset));
if (mapping.Length() != arrayEntries) {
arrayEntries = mapping.Length();
ASSERT_LE(arrayEntries, 8u);
uint32_t i = arrayEntries - 1;
EXPECT_EQ(mapping[i].mEndOffset, gEndOffsets[i]);
EXPECT_EQ(mapping[i].mSyncOffset, 361);
EXPECT_EQ(mapping[i].mTimecode, gTimecodes[i]);
EXPECT_EQ(parser.GetTimecodeScale(), 500000u);
}
}
EXPECT_EQ(mapping.Length(), 8u);
EXPECT_EQ(parser.mStartOffset, 0);
EXPECT_EQ(parser.mCurrentOffset, int64_t(ArrayLength(gWebMData)));
EXPECT_EQ(parser.GetTimecodeScale(), 500000u);
for (uint32_t i = 0; i < mapping.Length(); ++i) {
EXPECT_EQ(mapping[i].mEndOffset, gEndOffsets[i]);
EXPECT_EQ(mapping[i].mSyncOffset, 361);
EXPECT_EQ(mapping[i].mTimecode, gTimecodes[i]);
}
}

Просмотреть файл

@ -7,7 +7,8 @@
UNIFIED_SOURCES += [
'TestAudioCompactor.cpp',
'TestTrackEncoder.cpp',
'TestVideoSegment.cpp'
'TestVideoSegment.cpp',
'TestWebMBuffered.cpp'
]
if CONFIG['MOZ_WEBM_ENCODER']:

Двоичные данные
content/media/gtest/test.webm Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -78,7 +78,7 @@ function main() {
// Currently, changing the font-size on a parent doesn't force a resample (see
// bug 508206) so we have to give the animation a chance to run
setTimeout("checkAfterChangeFontSize()",100);
window.requestAnimationFrame(checkAfterChangeFontSize);
}
function checkAfterChangeFontSize() {
@ -96,7 +96,7 @@ function checkAfterChangeFontSize() {
circle.parentNode.setAttribute('font-size', '7px');
// Again, due to bug 508206 we need to give the animation a chance to resample
setTimeout("checkWhilstFrozen()",100);
window.requestAnimationFrame(checkWhilstFrozen);
}
function checkWhilstFrozen() {

Просмотреть файл

@ -396,16 +396,15 @@ ArchiveZipFileImpl::Traverse(nsCycleCollectionTraversalCallback &cb)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArchiveReader);
}
already_AddRefed<nsIDOMBlob>
already_AddRefed<mozilla::dom::DOMFileImpl>
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType)
{
nsCOMPtr<nsIDOMBlob> t =
new DOMFile(new ArchiveZipFileImpl(mFilename, mContentType,
aStart, mLength, mCentral,
mArchiveReader));
return t.forget();
nsRefPtr<DOMFileImpl> impl =
new ArchiveZipFileImpl(mFilename, mContentType, aStart, mLength, mCentral,
mArchiveReader);
return impl.forget();
}
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, DOMFileImpl)

Просмотреть файл

@ -71,9 +71,9 @@ protected:
MOZ_COUNT_DTOR(ArchiveZipFileImpl);
}
virtual already_AddRefed<nsIDOMBlob> CreateSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
virtual already_AddRefed<DOMFileImpl> CreateSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
private: // Data
ZipCentral mCentral;

Просмотреть файл

@ -100,6 +100,7 @@
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::ipc;
using namespace mozilla::layers;
using namespace mozilla::widget;
using namespace mozilla::gfx;
@ -3004,30 +3005,65 @@ nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
NS_IMETHODIMP
nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
int64_t* aResult)
int64_t* _retval)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
if (!aFile.isPrimitive()) {
JSObject* obj = aFile.toObjectOrNull();
indexedDB::IDBMutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
*aResult = mutableFile->GetFileId();
return NS_OK;
}
nsISupports* nativeObj =
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
if (blob) {
*aResult = blob->GetFileId();
return NS_OK;
}
if (aFile.isPrimitive()) {
*_retval = -1;
return NS_OK;
}
*aResult = -1;
JSObject* obj = aFile.toObjectOrNull();
indexedDB::IDBMutableFile* mutableFile = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
*_retval = mutableFile->GetFileId();
return NS_OK;
}
nsISupports* nativeObj =
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
if (blob) {
*_retval = blob->GetFileId();
return NS_OK;
}
*_retval = -1;
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
nsAString& _retval)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
if (aFile.isPrimitive()) {
_retval.Truncate();
return NS_OK;
}
JSObject* obj = aFile.toObjectOrNull();
nsISupports* nativeObj =
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(nativeObj);
if (file) {
nsString filePath;
nsresult rv = file->GetMozFullPathInternal(filePath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
_retval = filePath;
return NS_OK;
}
_retval.Truncate();
return NS_OK;
}

Просмотреть файл

@ -187,7 +187,6 @@
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/MessagePortBinding.h"
#include "mozilla/dom/indexedDB/IDBFactory.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/StructuredCloneTags.h"
@ -1574,12 +1573,6 @@ nsGlobalWindow::FreeInnerObjects()
// Kill all of the workers for this window.
mozilla::dom::workers::CancelWorkersForWindow(this);
// Close all offline storages for this window.
quota::QuotaManager* quotaManager = quota::QuotaManager::Get();
if (quotaManager) {
quotaManager->AbortCloseStoragesForWindow(this);
}
ClearAllTimeouts();
if (mIdleTimer) {
@ -10593,9 +10586,11 @@ GetIndexedDBEnabledForAboutURI(nsIURI *aURI)
return flags & nsIAboutModule::ENABLE_INDEXED_DB;
}
indexedDB::IDBFactory*
mozilla::dom::indexedDB::IDBFactory*
nsGlobalWindow::GetIndexedDB(ErrorResult& aError)
{
using mozilla::dom::indexedDB::IDBFactory;
if (!mIndexedDB) {
// If the document has the sandboxed origin flag set
// don't allow access to indexedDB.
@ -10642,8 +10637,7 @@ nsGlobalWindow::GetIndexedDB(ErrorResult& aError)
}
// This may be null if being created from a file.
aError = indexedDB::IDBFactory::Create(this, nullptr,
getter_AddRefs(mIndexedDB));
aError = IDBFactory::CreateForWindow(this, getter_AddRefs(mIndexedDB));
}
return mIndexedDB;

Просмотреть файл

@ -26,6 +26,8 @@
#include "mozilla/unused.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsContentUtils.h"
#include "nsIObserverService.h"

Просмотреть файл

@ -9,7 +9,6 @@
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
#include "mozilla/dom/ipc/Blob.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsIDOMFile.h"
@ -17,7 +16,13 @@
#include "nsTObserverArray.h"
#include "nsThreadUtils.h"
class nsIDOMBlob;
namespace mozilla {
namespace dom {
class BlobChild;
class BlobParent;
}
namespace ipc {
class UnixSocketConsumer;
}

Просмотреть файл

@ -14,6 +14,7 @@
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"

Просмотреть файл

@ -11,14 +11,20 @@
#include "BluetoothProfileManagerBase.h"
#include "BluetoothSocketObserver.h"
#include "DeviceStorage.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class BlobParent;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocket;

Просмотреть файл

@ -44,6 +44,7 @@
#include "mozilla/ipc/DBusUtils.h"
#include "mozilla/ipc/RawDBusConnection.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Monitor.h"
#include "mozilla/Mutex.h"
#include "mozilla/NullPtr.h"
#include "mozilla/StaticMutex.h"

Просмотреть файл

@ -14,6 +14,7 @@
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"

Просмотреть файл

@ -11,14 +11,20 @@
#include "BluetoothProfileManagerBase.h"
#include "BluetoothSocketObserver.h"
#include "DeviceStorage.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class BlobParent;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocket;

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "BluetoothChild.h"
#include "MainThreadUtils.h"

Просмотреть файл

@ -26,6 +26,8 @@
#include "mozilla/unused.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "nsContentUtils.h"
#include "nsIObserverService.h"
#include "nsISettingsService.h"

Просмотреть файл

@ -9,7 +9,6 @@
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
#include "mozilla/dom/ipc/Blob.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsIDOMFile.h"
@ -17,7 +16,13 @@
#include "nsTObserverArray.h"
#include "nsThreadUtils.h"
class nsIDOMBlob;
namespace mozilla {
namespace dom {
class BlobChild;
class BlobParent;
}
namespace ipc {
class UnixSocketConsumer;
}

Просмотреть файл

@ -14,6 +14,7 @@
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"

Просмотреть файл

@ -11,14 +11,20 @@
#include "BluetoothProfileManagerBase.h"
#include "BluetoothSocketObserver.h"
#include "DeviceStorage.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class BlobParent;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocket;

Просмотреть файл

@ -14,6 +14,7 @@
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"

Просмотреть файл

@ -11,14 +11,20 @@
#include "BluetoothProfileManagerBase.h"
#include "BluetoothSocketObserver.h"
#include "DeviceStorage.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class BlobParent;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocket;

Просмотреть файл

@ -1,82 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/AesKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
AesKeyAlgorithm::WrapObject(JSContext* aCx)
{
return AesKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
AesKeyAlgorithm::ToJwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CBC);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CBC);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CBC);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CTR);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CTR);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CTR);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128GCM);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192GCM);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256GCM);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
switch (mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128KW);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192KW);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256KW);
}
}
return nsString();
}
bool
AesKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_AESKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mLength, 0) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
AesKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t length, zero;
nsString name;
bool read = JS_ReadUint32Pair(aReader, &length, &zero) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new AesKeyAlgorithm(aGlobal, name, length);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_AesKeyAlgorithm_h
#define mozilla_dom_AesKeyAlgorithm_h
#include "mozilla/dom/BasicSymmetricKeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class AesKeyAlgorithm MOZ_FINAL : public BasicSymmetricKeyAlgorithm
{
public:
AesKeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName, uint16_t aLength)
: BasicSymmetricKeyAlgorithm(aGlobal, aName, aLength)
{}
~AesKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_AesKeyAlgorithm_h

Просмотреть файл

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_BasicSymmetricKeyAlgorithm_h
#define mozilla_dom_BasicSymmetricKeyAlgorithm_h
#include "mozilla/dom/KeyAlgorithm.h"
namespace mozilla {
namespace dom {
class BasicSymmetricKeyAlgorithm : public KeyAlgorithm
{
public:
BasicSymmetricKeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName, uint16_t aLength)
: KeyAlgorithm(aGlobal, aName)
, mLength(aLength)
{}
~BasicSymmetricKeyAlgorithm()
{}
uint16_t Length() const
{
return mLength;
}
protected:
uint16_t mLength;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_BasicSymmetricKeyAlgorithm_h

Просмотреть файл

@ -161,6 +161,13 @@ CryptoBuffer::ToSECItem() const
return item;
}
JSObject*
CryptoBuffer::ToUint8Array(JSContext* aCx) const
{
return Uint8Array::Create(aCx, Length(), Elements());
}
// "BigInt" comes from the WebCrypto spec
// ("unsigned long" isn't very "big", of course)
// Likewise, the spec calls for big-endian ints

Просмотреть файл

@ -40,6 +40,7 @@ public:
nsresult FromJwkBase64(const nsString& aBase64);
nsresult ToJwkBase64(nsString& aBase64);
SECItem* ToSECItem() const;
JSObject* ToUint8Array(JSContext* aCx) const;
bool GetBigIntValue(unsigned long& aRetVal);
};

Просмотреть файл

@ -10,11 +10,12 @@
#include "mozilla/dom/CryptoKey.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKey, mGlobal, mAlgorithm)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKey, mGlobal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(CryptoKey)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CryptoKey)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CryptoKey)
@ -90,10 +91,35 @@ CryptoKey::Extractable() const
return (mAttributes & EXTRACTABLE);
}
KeyAlgorithm*
CryptoKey::Algorithm() const
void
CryptoKey::GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
ErrorResult& aRv) const
{
return mAlgorithm;
bool converted = false;
JS::RootedValue val(cx);
switch (mAlgorithm.mType) {
case KeyAlgorithmProxy::AES:
converted = ToJSValue(cx, mAlgorithm.mAes, &val);
break;
case KeyAlgorithmProxy::HMAC:
converted = ToJSValue(cx, mAlgorithm.mHmac, &val);
break;
case KeyAlgorithmProxy::RSA: {
RootedDictionary<RsaHashedKeyAlgorithm> rsa(cx);
mAlgorithm.mRsa.ToKeyAlgorithm(cx, rsa);
converted = ToJSValue(cx, rsa, &val);
break;
}
case KeyAlgorithmProxy::EC:
converted = ToJSValue(cx, mAlgorithm.mEc, &val);
break;
}
if (!converted) {
aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
return;
}
aRetVal.set(&val.toObject());
}
void
@ -125,6 +151,18 @@ CryptoKey::GetUsages(nsTArray<nsString>& aRetVal) const
}
}
KeyAlgorithmProxy&
CryptoKey::Algorithm()
{
return mAlgorithm;
}
const KeyAlgorithmProxy&
CryptoKey::Algorithm() const
{
return mAlgorithm;
}
CryptoKey::KeyType
CryptoKey::GetKeyType() const
{
@ -165,12 +203,6 @@ CryptoKey::SetExtractable(bool aExtractable)
}
}
void
CryptoKey::SetAlgorithm(KeyAlgorithm* aAlgorithm)
{
mAlgorithm = aAlgorithm;
}
void
CryptoKey::ClearUsages()
{
@ -205,6 +237,12 @@ CryptoKey::AddUsage(CryptoKey::KeyUsage aUsage)
mAttributes |= aUsage;
}
bool
CryptoKey::HasAnyUsage()
{
return !!(mAttributes & USAGES_MASK);
}
bool
CryptoKey::HasUsage(CryptoKey::KeyUsage aUsage)
{
@ -217,6 +255,25 @@ CryptoKey::HasUsageOtherThan(uint32_t aUsages)
return !!(mAttributes & USAGES_MASK & ~aUsages);
}
bool
CryptoKey::IsRecognizedUsage(const nsString& aUsage)
{
KeyUsage dummy;
nsresult rv = StringToUsage(aUsage, dummy);
return NS_SUCCEEDED(rv);
}
bool
CryptoKey::AllUsagesRecognized(const Sequence<nsString>& aUsages)
{
for (uint32_t i = 0; i < aUsages.Length(); ++i) {
if (!IsRecognizedUsage(aUsages[i])) {
return false;
}
}
return true;
}
void CryptoKey::SetSymKey(const CryptoBuffer& aSymKey)
{
mSymKey = aSymKey;
@ -441,14 +498,10 @@ SECKEYPrivateKey*
CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
if (!aJwk.mKty.WasPassed()) {
return nullptr;
}
CK_OBJECT_CLASS privateKeyValue = CKO_PRIVATE_KEY;
CK_BBOOL falseValue = CK_FALSE;
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_EC)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_EC)) {
// Verify that all of the required parameters are present
CryptoBuffer x, y, d;
if (!aJwk.mCrv.WasPassed() ||
@ -459,7 +512,7 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
}
nsString namedCurve;
if (!NormalizeNamedCurveValue(aJwk.mCrv.Value(), namedCurve)) {
if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
@ -504,7 +557,7 @@ CryptoKey::PrivateKeyFromJwk(const JsonWebKey& aJwk,
PR_ARRAY_SIZE(keyTemplate));
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_RSA)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_RSA)) {
// Verify that all of the required parameters are present
CryptoBuffer n, e, d, p, q, dp, dq, qi;
if (!aJwk.mN.WasPassed() || NS_FAILED(n.FromJwkBase64(aJwk.mN.Value())) ||
@ -643,7 +696,7 @@ ECKeyToJwk(const PK11ObjectType aKeyType, void* aKey, const SECItem* aEcParams,
return false;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_EC));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_EC);
return true;
}
@ -674,7 +727,7 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
return NS_ERROR_DOM_OPERATION_ERR;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_RSA));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_RSA);
return NS_OK;
}
case ecKey: {
@ -716,11 +769,7 @@ SECKEYPublicKey*
CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
{
if (!aJwk.mKty.WasPassed()) {
return nullptr;
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_RSA)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_RSA)) {
// Verify that all of the required parameters are present
CryptoBuffer n, e;
if (!aJwk.mN.WasPassed() || NS_FAILED(n.FromJwkBase64(aJwk.mN.Value())) ||
@ -753,7 +802,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
return SECKEY_ImportDERPublicKey(pkDer.get(), CKK_RSA);
}
if (aJwk.mKty.Value().EqualsLiteral(JWK_TYPE_EC)) {
if (aJwk.mKty.EqualsLiteral(JWK_TYPE_EC)) {
// Verify that all of the required parameters are present
CryptoBuffer x, y;
if (!aJwk.mCrv.WasPassed() ||
@ -777,7 +826,7 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
key->pkcs11ID = CK_INVALID_HANDLE;
nsString namedCurve;
if (!NormalizeNamedCurveValue(aJwk.mCrv.Value(), namedCurve)) {
if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
@ -819,7 +868,7 @@ CryptoKey::PublicKeyToJwk(SECKEYPublicKey* aPubKey,
return NS_ERROR_DOM_OPERATION_ERR;
}
aRetVal.mKty.Construct(NS_LITERAL_STRING(JWK_TYPE_RSA));
aRetVal.mKty = NS_LITERAL_STRING(JWK_TYPE_RSA);
return NS_OK;
}
case ecKey:
@ -857,11 +906,11 @@ CryptoKey::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
CryptoKey::PublicKeyToSpki(mPublicKey, pub, locker);
}
return JS_WriteUint32Pair(aWriter, mAttributes, 0) &&
return JS_WriteUint32Pair(aWriter, mAttributes, CRYPTOKEY_SC_VERSION) &&
WriteBuffer(aWriter, mSymKey) &&
WriteBuffer(aWriter, priv) &&
WriteBuffer(aWriter, pub) &&
mAlgorithm->WriteStructuredClone(aWriter);
mAlgorithm.WriteStructuredClone(aWriter);
}
bool
@ -872,15 +921,15 @@ CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader)
return false;
}
uint32_t zero;
uint32_t version;
CryptoBuffer sym, priv, pub;
nsRefPtr<KeyAlgorithm> algorithm;
bool read = JS_ReadUint32Pair(aReader, &mAttributes, &zero) &&
bool read = JS_ReadUint32Pair(aReader, &mAttributes, &version) &&
(version == CRYPTOKEY_SC_VERSION) &&
ReadBuffer(aReader, sym) &&
ReadBuffer(aReader, priv) &&
ReadBuffer(aReader, pub) &&
(algorithm = KeyAlgorithm::Create(mGlobal, aReader));
mAlgorithm.ReadStructuredClone(aReader);
if (!read) {
return false;
}
@ -894,7 +943,6 @@ CryptoKey::ReadStructuredClone(JSStructuredCloneReader* aReader)
if (pub.Length() > 0) {
mPublicKey = CryptoKey::PublicKeyFromSpki(pub, locker);
}
mAlgorithm = algorithm;
// Ensure that what we've read is consistent
// If the attributes indicate a key type, should have a key of that type

Просмотреть файл

@ -14,11 +14,14 @@
#include "pk11pub.h"
#include "keyhi.h"
#include "ScopedNSSTypes.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "mozilla/dom/KeyAlgorithmProxy.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
#define CRYPTOKEY_SC_VERSION 0x00000001
class nsIGlobalObject;
namespace mozilla {
@ -100,23 +103,28 @@ public:
// WebIDL methods
void GetType(nsString& aRetVal) const;
bool Extractable() const;
KeyAlgorithm* Algorithm() const;
void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
ErrorResult& aRv) const;
void GetUsages(nsTArray<nsString>& aRetVal) const;
// The below methods are not exposed to JS, but C++ can use
// them to manipulate the object
KeyAlgorithmProxy& Algorithm();
const KeyAlgorithmProxy& Algorithm() const;
KeyType GetKeyType() const;
nsresult SetType(const nsString& aType);
void SetType(KeyType aType);
void SetExtractable(bool aExtractable);
void SetAlgorithm(KeyAlgorithm* aAlgorithm);
void ClearUsages();
nsresult AddUsage(const nsString& aUsage);
nsresult AddUsageIntersecting(const nsString& aUsage, uint32_t aUsageMask);
void AddUsage(KeyUsage aUsage);
bool HasAnyUsage();
bool HasUsage(KeyUsage aUsage);
bool HasUsageOtherThan(uint32_t aUsages);
static bool IsRecognizedUsage(const nsString& aUsage);
static bool AllUsagesRecognized(const Sequence<nsString>& aUsages);
void SetSymKey(const CryptoBuffer& aSymKey);
void SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
@ -172,7 +180,7 @@ private:
nsRefPtr<nsIGlobalObject> mGlobal;
uint32_t mAttributes; // see above
nsRefPtr<KeyAlgorithm> mAlgorithm;
KeyAlgorithmProxy mAlgorithm;
// Only one key handle should be set, according to the KeyType
CryptoBuffer mSymKey;

Просмотреть файл

@ -1,31 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/CryptoKeyPair.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CryptoKeyPair, mGlobal, mPublicKey, mPrivateKey)
NS_IMPL_CYCLE_COLLECTING_ADDREF(CryptoKeyPair)
NS_IMPL_CYCLE_COLLECTING_RELEASE(CryptoKeyPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CryptoKeyPair)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
JSObject*
CryptoKeyPair::WrapObject(JSContext* aCx)
{
return CryptoKeyPairBinding::Wrap(aCx, this);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_CryptoKeyPair_h
#define mozilla_dom_CryptoKeyPair_h
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsIGlobalObject.h"
#include "mozilla/dom/CryptoKey.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class CryptoKeyPair MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CryptoKeyPair)
public:
explicit CryptoKeyPair(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal)
, mPublicKey(new CryptoKey(aGlobal))
, mPrivateKey(new CryptoKey(aGlobal))
{
SetIsDOMBinding();
}
nsIGlobalObject* GetParentObject() const
{
return mGlobal;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
CryptoKey* PublicKey() const
{
return mPublicKey;
}
CryptoKey* PrivateKey() const
{
return mPrivateKey;
}
private:
~CryptoKeyPair() {}
nsRefPtr<nsIGlobalObject> mGlobal;
nsRefPtr<CryptoKey> mPublicKey;
nsRefPtr<CryptoKey> mPrivateKey;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CryptoKeyPair_h

Просмотреть файл

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/EcKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
EcKeyAlgorithm::WrapObject(JSContext* aCx)
{
return EcKeyAlgorithmBinding::Wrap(aCx, this);
}
bool
EcKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_ECKEYALG, 0) &&
WriteString(aWriter, mNamedCurve) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
EcKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
nsString name;
nsString namedCurve;
bool read = ReadString(aReader, namedCurve) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new EcKeyAlgorithm(aGlobal, name, namedCurve);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_EcKeyAlgorithm_h
#define mozilla_dom_EcKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class EcKeyAlgorithm : public KeyAlgorithm
{
public:
EcKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
const nsString& aNamedCurve)
: KeyAlgorithm(aGlobal, aName)
, mNamedCurve(aNamedCurve)
{}
~EcKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
void GetNamedCurve(nsString& aRetVal) const
{
aRetVal.Assign(mNamedCurve);
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
nsString mNamedCurve;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_EcKeyAlgorithm_h

Просмотреть файл

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/HmacKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(HmacKeyAlgorithm, KeyAlgorithm, mHash)
NS_IMPL_ADDREF_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
NS_IMPL_RELEASE_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HmacKeyAlgorithm)
NS_INTERFACE_MAP_END_INHERITING(KeyAlgorithm)
JSObject*
HmacKeyAlgorithm::WrapObject(JSContext* aCx)
{
return HmacKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
HmacKeyAlgorithm::ToJwkAlg() const
{
switch (mMechanism) {
case CKM_SHA_1_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS1);
case CKM_SHA256_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS256);
case CKM_SHA384_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS384);
case CKM_SHA512_HMAC: return NS_LITERAL_STRING(JWK_ALG_HS512);
}
return nsString();
}
bool
HmacKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
nsString hashName;
mHash->GetName(hashName);
return JS_WriteUint32Pair(aWriter, SCTAG_HMACKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mLength, 0) &&
WriteString(aWriter, hashName) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
HmacKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t length, zero;
nsString hash, name;
bool read = JS_ReadUint32Pair(aReader, &length, &zero) &&
ReadString(aReader, hash) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new HmacKeyAlgorithm(aGlobal, name, length, hash);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,72 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_HmacKeyAlgorithm_h
#define mozilla_dom_HmacKeyAlgorithm_h
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class HmacKeyAlgorithm MOZ_FINAL : public KeyAlgorithm
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HmacKeyAlgorithm, KeyAlgorithm)
HmacKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aLength,
const nsString& aHash)
: KeyAlgorithm(aGlobal, aName)
, mHash(new KeyAlgorithm(aGlobal, aHash))
, mLength(aLength)
{
switch (mHash->Mechanism()) {
case CKM_SHA_1: mMechanism = CKM_SHA_1_HMAC; break;
case CKM_SHA256: mMechanism = CKM_SHA256_HMAC; break;
case CKM_SHA384: mMechanism = CKM_SHA384_HMAC; break;
case CKM_SHA512: mMechanism = CKM_SHA512_HMAC; break;
default: mMechanism = UNKNOWN_CK_MECHANISM; break;
}
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
KeyAlgorithm* Hash() const
{
return mHash;
}
uint32_t Length() const
{
return mLength;
}
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
~HmacKeyAlgorithm()
{}
nsRefPtr<KeyAlgorithm> mHash;
uint32_t mLength;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HmacKeyAlgorithm_h

Просмотреть файл

@ -1,116 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/KeyAlgorithm.h"
#include "mozilla/dom/WebCryptoCommon.h"
#include "mozilla/dom/AesKeyAlgorithm.h"
#include "mozilla/dom/EcKeyAlgorithm.h"
#include "mozilla/dom/HmacKeyAlgorithm.h"
#include "mozilla/dom/RsaKeyAlgorithm.h"
#include "mozilla/dom/RsaHashedKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(KeyAlgorithm, mGlobal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(KeyAlgorithm)
NS_IMPL_CYCLE_COLLECTING_RELEASE(KeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(KeyAlgorithm)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
KeyAlgorithm::KeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName)
: mGlobal(aGlobal)
, mName(aName)
{
SetIsDOMBinding();
// Set mechanism based on algorithm name
mMechanism = MapAlgorithmNameToMechanism(aName);
// HMAC not handled here, since it requires extra info
}
KeyAlgorithm::~KeyAlgorithm()
{
}
JSObject*
KeyAlgorithm::WrapObject(JSContext* aCx)
{
return KeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
KeyAlgorithm::ToJwkAlg() const
{
return nsString();
}
void
KeyAlgorithm::GetName(nsString& aRetVal) const
{
aRetVal.Assign(mName);
}
bool
KeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return WriteString(aWriter, mName);
}
KeyAlgorithm*
KeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t tag, zero;
bool read = JS_ReadUint32Pair( aReader, &tag, &zero );
if (!read) {
return nullptr;
}
KeyAlgorithm* algorithm = nullptr;
switch (tag) {
case SCTAG_KEYALG: {
nsString name;
read = ReadString(aReader, name);
if (!read) {
return nullptr;
}
algorithm = new KeyAlgorithm(aGlobal, name);
break;
}
case SCTAG_AESKEYALG: {
algorithm = AesKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_ECKEYALG: {
algorithm = EcKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_HMACKEYALG: {
algorithm = HmacKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_RSAKEYALG: {
algorithm = RsaKeyAlgorithm::Create(aGlobal, aReader);
break;
}
case SCTAG_RSAHASHEDKEYALG: {
algorithm = RsaHashedKeyAlgorithm::Create(aGlobal, aReader);
break;
}
// No default, algorithm is already nullptr
}
return algorithm;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_KeyAlgorithm_h
#define mozilla_dom_KeyAlgorithm_h
#include "nsCycleCollectionParticipant.h"
#include "nsIGlobalObject.h"
#include "nsWrapperCache.h"
#include "pk11pub.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "js/StructuredClone.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class CryptoKey;
class KeyAlgorithm;
enum KeyAlgorithmStructuredCloneTags {
SCTAG_KEYALG,
SCTAG_AESKEYALG,
SCTAG_ECKEYALG,
SCTAG_HMACKEYALG,
SCTAG_RSAKEYALG,
SCTAG_RSAHASHEDKEYALG
};
}
namespace dom {
class KeyAlgorithm : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(KeyAlgorithm)
public:
KeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName);
nsIGlobalObject* GetParentObject() const
{
return mGlobal;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
void GetName(nsString& aRetVal) const;
virtual nsString ToJwkAlg() const;
// Structured clone support methods
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
// Helper method to look up NSS methods
// Sub-classes should assign mMechanism on constructor
CK_MECHANISM_TYPE Mechanism() const {
return mMechanism;
}
protected:
virtual ~KeyAlgorithm();
nsRefPtr<nsIGlobalObject> mGlobal;
nsString mName;
CK_MECHANISM_TYPE mMechanism;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_KeyAlgorithm_h

Просмотреть файл

@ -0,0 +1,215 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/KeyAlgorithmProxy.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
bool
KeyAlgorithmProxy::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
if (!WriteString(aWriter, mName) ||
!JS_WriteUint32Pair(aWriter, mType, KEY_ALGORITHM_SC_VERSION)) {
return false;
}
switch (mType) {
case AES:
return JS_WriteUint32Pair(aWriter, mAes.mLength, 0);
case HMAC:
return JS_WriteUint32Pair(aWriter, mHmac.mLength, 0) &&
WriteString(aWriter, mHmac.mHash.mName);
case RSA: {
return JS_WriteUint32Pair(aWriter, mRsa.mModulusLength, 0) &&
WriteBuffer(aWriter, mRsa.mPublicExponent) &&
WriteString(aWriter, mRsa.mHash.mName);
}
case EC:
return WriteString(aWriter, mEc.mNamedCurve);
}
return false;
}
bool
KeyAlgorithmProxy::ReadStructuredClone(JSStructuredCloneReader* aReader)
{
uint32_t type, version, dummy;
if (!ReadString(aReader, mName) ||
!JS_ReadUint32Pair(aReader, &type, &version)) {
return false;
}
if (version != KEY_ALGORITHM_SC_VERSION) {
return false;
}
mType = (KeyAlgorithmType) type;
switch (mType) {
case AES: {
uint32_t length;
if (!JS_ReadUint32Pair(aReader, &length, &dummy)) {
return false;
}
mAes.mLength = length;
mAes.mName = mName;
return true;
}
case HMAC: {
if (!JS_ReadUint32Pair(aReader, &mHmac.mLength, &dummy) ||
!ReadString(aReader, mHmac.mHash.mName)) {
return false;
}
mHmac.mName = mName;
return true;
}
case RSA: {
uint32_t modulusLength;
nsString hashName;
if (!JS_ReadUint32Pair(aReader, &modulusLength, &dummy) ||
!ReadBuffer(aReader, mRsa.mPublicExponent) ||
!ReadString(aReader, mRsa.mHash.mName)) {
return false;
}
mRsa.mModulusLength = modulusLength;
mRsa.mName = mName;
return true;
}
case EC: {
nsString namedCurve;
if (!ReadString(aReader, mEc.mNamedCurve)) {
return false;
}
mEc.mName = mName;
return true;
}
}
return false;
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::Mechanism() const
{
if (mType == HMAC) {
return GetMechanism(mHmac);
}
return MapAlgorithmNameToMechanism(mName);
}
nsString
KeyAlgorithmProxy::JwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CBC)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CBC);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CBC);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CBC);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_CTR)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128CTR);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192CTR);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256CTR);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_GCM)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128GCM);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192GCM);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256GCM);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_AES_KW)) {
switch (mAes.mLength) {
case 128: return NS_LITERAL_STRING(JWK_ALG_A128KW);
case 192: return NS_LITERAL_STRING(JWK_ALG_A192KW);
case 256: return NS_LITERAL_STRING(JWK_ALG_A256KW);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
nsString hashName = mHmac.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_HS1);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_HS256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_HS384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_HS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
nsString hashName = mRsa.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_RS1);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_RS256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_RS384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_RS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
nsString hashName = mRsa.mHash.mName;
if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_384);
} else if (hashName.EqualsLiteral(WEBCRYPTO_ALG_SHA512)) {
return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_512);
}
}
return nsString();
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::GetMechanism(const KeyAlgorithm& aAlgorithm)
{
// For everything but HMAC, the name determines the mechanism
// HMAC is handled by the specialization below
return MapAlgorithmNameToMechanism(aAlgorithm.mName);
}
CK_MECHANISM_TYPE
KeyAlgorithmProxy::GetMechanism(const HmacKeyAlgorithm& aAlgorithm)
{
// The use of HmacKeyAlgorithm doesn't completely prevent this
// method from being called with dictionaries that don't really
// represent HMAC key algorithms.
MOZ_ASSERT(aAlgorithm.mName.EqualsLiteral(WEBCRYPTO_ALG_HMAC));
CK_MECHANISM_TYPE hashMech;
hashMech = MapAlgorithmNameToMechanism(aAlgorithm.mHash.mName);
switch (hashMech) {
case CKM_SHA_1: return CKM_SHA_1_HMAC;
case CKM_SHA256: return CKM_SHA256_HMAC;
case CKM_SHA384: return CKM_SHA384_HMAC;
case CKM_SHA512: return CKM_SHA512_HMAC;
}
return UNKNOWN_CK_MECHANISM;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_KeyAlgorithmProxy_h
#define mozilla_dom_KeyAlgorithmProxy_h
#include "pk11pub.h"
#include "js/StructuredClone.h"
#include "mozilla/dom/KeyAlgorithmBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
#define KEY_ALGORITHM_SC_VERSION 0x00000001
namespace mozilla {
namespace dom {
// A heap-safe variant of RsaHashedKeyAlgorithm
// The only difference is that it uses CryptoBuffer instead of Uint8Array
struct RsaHashedKeyAlgorithmStorage {
nsString mName;
KeyAlgorithm mHash;
uint16_t mModulusLength;
CryptoBuffer mPublicExponent;
void
ToKeyAlgorithm(JSContext* aCx, RsaHashedKeyAlgorithm& aRsa) const
{
aRsa.mName = mName;
aRsa.mModulusLength = mModulusLength;
aRsa.mHash.mName = mHash.mName;
aRsa.mPublicExponent.Init(mPublicExponent.ToUint8Array(aCx));
aRsa.mPublicExponent.ComputeLengthAndData();
}
};
// This class encapuslates a KeyAlgorithm object, and adds several
// methods that make WebCrypto operations simpler.
struct KeyAlgorithmProxy
{
enum KeyAlgorithmType {
AES,
HMAC,
RSA,
EC
};
KeyAlgorithmType mType;
// Plain is always populated with the algorithm name
// Others are only populated for the corresponding key type
nsString mName;
AesKeyAlgorithm mAes;
HmacKeyAlgorithm mHmac;
RsaHashedKeyAlgorithmStorage mRsa;
EcKeyAlgorithm mEc;
// Structured clone
bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
bool ReadStructuredClone(JSStructuredCloneReader* aReader);
// Extract various forms of derived information
CK_MECHANISM_TYPE Mechanism() const;
nsString JwkAlg() const;
// And in static form for calling on raw KeyAlgorithm dictionaries
static CK_MECHANISM_TYPE GetMechanism(const KeyAlgorithm& aAlgorithm);
static CK_MECHANISM_TYPE GetMechanism(const HmacKeyAlgorithm& aAlgorithm);
static nsString GetJwkAlg(const KeyAlgorithm& aAlgorithm);
// Construction of the various algorithm types
void
MakeAes(const nsString& aName, uint32_t aLength)
{
mType = AES;
mName = aName;
mAes.mName = aName;
mAes.mLength = aLength;
}
void
MakeHmac(uint32_t aLength, const nsString& aHashName)
{
mType = HMAC;
mName = NS_LITERAL_STRING(WEBCRYPTO_ALG_HMAC);
mHmac.mName = NS_LITERAL_STRING(WEBCRYPTO_ALG_HMAC);
mHmac.mLength = aLength;
mHmac.mHash.mName = aHashName;
}
void
MakeRsa(const nsString& aName, uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent, const nsString& aHashName)
{
mType = RSA;
mName = aName;
mRsa.mName = aName;
mRsa.mModulusLength = aModulusLength;
mRsa.mHash.mName = aHashName;
mRsa.mPublicExponent.Assign(aPublicExponent);
}
void
MakeEc(const nsString& aName, const nsString& aNamedCurve)
{
mType = EC;
mName = aName;
mEc.mName = aName;
mEc.mNamedCurve = aNamedCurve;
}
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_KeyAlgorithmProxy_h

Просмотреть файл

@ -1,80 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/RsaHashedKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm, mHash)
NS_IMPL_ADDREF_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
NS_IMPL_RELEASE_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RsaHashedKeyAlgorithm)
NS_INTERFACE_MAP_END_INHERITING(RsaKeyAlgorithm)
JSObject*
RsaHashedKeyAlgorithm::WrapObject(JSContext* aCx)
{
return RsaHashedKeyAlgorithmBinding::Wrap(aCx, this);
}
nsString
RsaHashedKeyAlgorithm::ToJwkAlg() const
{
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
switch (mHash->Mechanism()) {
case CKM_SHA_1: return NS_LITERAL_STRING(JWK_ALG_RS1);
case CKM_SHA256: return NS_LITERAL_STRING(JWK_ALG_RS256);
case CKM_SHA384: return NS_LITERAL_STRING(JWK_ALG_RS384);
case CKM_SHA512: return NS_LITERAL_STRING(JWK_ALG_RS512);
}
}
if (mName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
switch(mHash->Mechanism()) {
case CKM_SHA_1: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP);
case CKM_SHA256: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
case CKM_SHA384: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_256);
case CKM_SHA512: return NS_LITERAL_STRING(JWK_ALG_RSA_OAEP_512);
}
}
return nsString();
}
bool
RsaHashedKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
nsString hashName;
mHash->GetName(hashName);
return JS_WriteUint32Pair(aWriter, SCTAG_RSAHASHEDKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mModulusLength, 0) &&
WriteBuffer(aWriter, mPublicExponent) &&
WriteString(aWriter, hashName) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
RsaHashedKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader) {
uint32_t modulusLength, zero;
CryptoBuffer publicExponent;
nsString name, hash;
bool read = JS_ReadUint32Pair(aReader, &modulusLength, &zero) &&
ReadBuffer(aReader, publicExponent) &&
ReadString(aReader, hash) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new RsaHashedKeyAlgorithm(aGlobal, name, modulusLength, publicExponent, hash);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_RsaHashedKeyAlgorithm_h
#define mozilla_dom_RsaHashedKeyAlgorithm_h
#include "nsAutoPtr.h"
#include "mozilla/dom/RsaKeyAlgorithm.h"
namespace mozilla {
namespace dom {
class RsaHashedKeyAlgorithm MOZ_FINAL : public RsaKeyAlgorithm
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RsaHashedKeyAlgorithm, RsaKeyAlgorithm)
RsaHashedKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent,
const nsString& aHashName)
: RsaKeyAlgorithm(aGlobal, aName, aModulusLength, aPublicExponent)
, mHash(new KeyAlgorithm(aGlobal, aHashName))
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual nsString ToJwkAlg() const MOZ_OVERRIDE;
KeyAlgorithm* Hash() const
{
return mHash;
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
private:
~RsaHashedKeyAlgorithm() {}
nsRefPtr<KeyAlgorithm> mHash;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_RsaHashedKeyAlgorithm_h

Просмотреть файл

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/RsaKeyAlgorithm.h"
#include "mozilla/dom/SubtleCryptoBinding.h"
#include "mozilla/dom/WebCryptoCommon.h"
namespace mozilla {
namespace dom {
JSObject*
RsaKeyAlgorithm::WrapObject(JSContext* aCx)
{
return RsaKeyAlgorithmBinding::Wrap(aCx, this);
}
bool
RsaKeyAlgorithm::WriteStructuredClone(JSStructuredCloneWriter* aWriter) const
{
return JS_WriteUint32Pair(aWriter, SCTAG_RSAKEYALG, 0) &&
JS_WriteUint32Pair(aWriter, mModulusLength, 0) &&
WriteBuffer(aWriter, mPublicExponent) &&
WriteString(aWriter, mName);
}
KeyAlgorithm*
RsaKeyAlgorithm::Create(nsIGlobalObject* aGlobal, JSStructuredCloneReader* aReader)
{
uint32_t modulusLength, zero;
CryptoBuffer publicExponent;
nsString name;
bool read = JS_ReadUint32Pair(aReader, &modulusLength, &zero) &&
ReadBuffer(aReader, publicExponent) &&
ReadString(aReader, name);
if (!read) {
return nullptr;
}
return new RsaKeyAlgorithm(aGlobal, name, modulusLength, publicExponent);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_RsaKeyAlgorithm_h
#define mozilla_dom_RsaKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h"
namespace mozilla {
namespace dom {
class RsaKeyAlgorithm : public KeyAlgorithm
{
public:
RsaKeyAlgorithm(nsIGlobalObject* aGlobal,
const nsString& aName,
uint32_t aModulusLength,
const CryptoBuffer& aPublicExponent)
: KeyAlgorithm(aGlobal, aName)
, mModulusLength(aModulusLength)
, mPublicExponent(aPublicExponent)
{}
~RsaKeyAlgorithm()
{}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
uint32_t ModulusLength() const
{
return mModulusLength;
}
void GetPublicExponent(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError) const
{
TypedArrayCreator<Uint8Array> creator(mPublicExponent);
JSObject* retval = creator.Create(cx);
if (!retval) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
} else {
aRetval.set(retval);
}
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;
static KeyAlgorithm* Create(nsIGlobalObject* aGlobal,
JSStructuredCloneReader* aReader);
protected:
uint32_t mModulusLength;
CryptoBuffer mPublicExponent;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_RsaKeyAlgorithm_h

Просмотреть файл

@ -9,6 +9,7 @@
#include "pk11pub.h"
#include "nsString.h"
#include "nsContentUtils.h"
#include "mozilla/dom/CryptoBuffer.h"
#include "js/StructuredClone.h"
@ -23,7 +24,6 @@
#define WEBCRYPTO_ALG_SHA512 "SHA-512"
#define WEBCRYPTO_ALG_HMAC "HMAC"
#define WEBCRYPTO_ALG_PBKDF2 "PBKDF2"
#define WEBCRYPTO_ALG_RSAES_PKCS1 "RSAES-PKCS1-v1_5"
#define WEBCRYPTO_ALG_RSASSA_PKCS1 "RSASSA-PKCS1-v1_5"
#define WEBCRYPTO_ALG_RSA_OAEP "RSA-OAEP"
#define WEBCRYPTO_ALG_ECDH "ECDH"
@ -181,8 +181,6 @@ MapAlgorithmNameToMechanism(const nsString& aName)
mechanism = CKM_SHA512;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_PBKDF2)) {
mechanism = CKM_PKCS5_PBKD2;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSAES_PKCS1)) {
mechanism = CKM_RSA_PKCS;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
mechanism = CKM_RSA_PKCS;
} else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
@ -194,14 +192,45 @@ MapAlgorithmNameToMechanism(const nsString& aName)
return mechanism;
}
#define NORMALIZED_EQUALS(aTest, aConst) \
nsContentUtils::EqualsIgnoreASCIICase(aTest, NS_LITERAL_STRING(aConst))
inline bool
NormalizeNamedCurveValue(const nsString& aNamedCurve, nsString& aDest)
NormalizeToken(const nsString& aName, nsString& aDest)
{
if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P256)) {
// Algorithm names
if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CBC)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CBC);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_CTR)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_CTR);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_GCM)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_GCM);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_AES_KW)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_AES_KW);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA1)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA1);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA256)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA256);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA384)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA384);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_SHA512)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_SHA512);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_HMAC)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_HMAC);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_PBKDF2)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_PBKDF2);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSASSA_PKCS1)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSA_OAEP)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_RSA_OAEP);
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDH)) {
aDest.AssignLiteral(WEBCRYPTO_ALG_ECDH);
// Named curve values
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P256)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P256);
} else if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P384)) {
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P384)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P384);
} else if (aNamedCurve.EqualsIgnoreCase(WEBCRYPTO_NAMED_CURVE_P521)) {
} else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P521)) {
aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P521);
} else {
return false;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,30 +5,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'AesKeyAlgorithm.h',
'BasicSymmetricKeyAlgorithm.h',
'CryptoBuffer.h',
'CryptoKey.h',
'CryptoKeyPair.h',
'EcKeyAlgorithm.h',
'HmacKeyAlgorithm.h',
'KeyAlgorithm.h',
'RsaHashedKeyAlgorithm.h',
'RsaKeyAlgorithm.h',
'KeyAlgorithmProxy.h',
'WebCryptoCommon.h',
'WebCryptoTask.h',
]
UNIFIED_SOURCES += [
'AesKeyAlgorithm.cpp',
'CryptoBuffer.cpp',
'CryptoKey.cpp',
'CryptoKeyPair.cpp',
'EcKeyAlgorithm.cpp',
'HmacKeyAlgorithm.cpp',
'KeyAlgorithm.cpp',
'RsaHashedKeyAlgorithm.cpp',
'RsaKeyAlgorithm.cpp',
'KeyAlgorithmProxy.cpp',
'WebCryptoTask.cpp',
]

Просмотреть файл

@ -71,7 +71,6 @@ TestArray.addTest(
function doExport(x) {
if (!hasKeyFields(x)) {
window.result = x;
throw "Invalid key; missing field(s)";
} else if ((x.algorithm.name != alg) ||
(x.algorithm.length != 8 * tv.raw.length) ||
@ -85,7 +84,7 @@ TestArray.addTest(
}
crypto.subtle.importKey("raw", tv.raw, alg, true, ["encrypt"])
.then(doExport, error(that))
.then(doExport)
.then(
memcmp_complete(that, tv.raw),
error(that)
@ -153,7 +152,7 @@ TestArray.addTest(
}
crypto.subtle.importKey("pkcs8", tv.pkcs8, alg, true, ["sign"])
.then(doExport, error(that))
.then(doExport)
.then(
memcmp_complete(that, tv.pkcs8),
error(that)
@ -178,24 +177,27 @@ TestArray.addTest(
"Import / export round-trip with 'spki'",
function() {
var that = this;
var alg = "RSAES-PKCS1-v1_5";
var alg = {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256"
};
function doExport(x) {
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
} else if ((x.algorithm.name != alg) ||
} else if ((x.algorithm.name != alg.name) ||
(x.algorithm.modulusLength != 1024) ||
(x.algorithm.publicExponent.byteLength != 3) ||
(x.type != "public") ||
(!x.extractable) ||
(x.usages.length != 1) ||
(x.usages[0] != 'encrypt')){
(x.usages[0] != 'verify')){
throw "Invalid key: incorrect key data";
}
return crypto.subtle.exportKey("spki", x);
}
crypto.subtle.importKey("spki", tv.spki, alg, true, ["encrypt"])
crypto.subtle.importKey("spki", tv.spki, alg, true, ["verify"])
.then(doExport, error(that))
.then(
memcmp_complete(that, tv.spki),
@ -209,7 +211,10 @@ TestArray.addTest(
"Import failure with format 'spki'",
function() {
var that = this;
var alg = "RSAES-PKCS1-v1_5";
var alg = {
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256"
};
crypto.subtle.importKey("spki", tv.negative_spki, alg, true, ["encrypt"])
.then(error(that), complete(that));
@ -382,11 +387,12 @@ TestArray.addTest(
function() {
var that = this;
var alg = {
name: "RSAES-PKCS1-v1_5",
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 1024,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"]).then(
crypto.subtle.generateKey(alg, false, ["sign", "verify"]).then(
complete(that, function(x) {
return exists(x.publicKey) &&
(x.publicKey.algorithm.name == alg.name) &&
@ -394,14 +400,14 @@ TestArray.addTest(
(x.publicKey.type == "public") &&
x.publicKey.extractable &&
(x.publicKey.usages.length == 1) &&
(x.publicKey.usages[0] == "encrypt") &&
(x.publicKey.usages[0] == "verify") &&
exists(x.privateKey) &&
(x.privateKey.algorithm.name == alg.name) &&
(x.privateKey.algorithm.modulusLength == alg.modulusLength) &&
(x.privateKey.type == "private") &&
!x.privateKey.extractable &&
(x.privateKey.usages.length == 1) &&
(x.privateKey.usages[0] == "decrypt");
(x.privateKey.usages[0] == "sign");
}),
error(that)
);
@ -414,12 +420,13 @@ TestArray.addTest(
function() {
var that = this;
var alg = {
name: "RSAES-PKCS1-v1_5",
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
modulusLength: 2299, // NSS does not like this key length
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
crypto.subtle.generateKey(alg, false, ["encrypt"])
crypto.subtle.generateKey(alg, false, ["sign"])
.then( error(that), complete(that) );
}
);
@ -455,7 +462,6 @@ TestArray.addTest(
var that = this;
function doEncrypt(x) {
console.log(x);
return crypto.subtle.encrypt(
{ name: "AES-CBC", iv: tv.aes_cbc_enc.iv },
x, tv.aes_cbc_enc.data);
@ -477,7 +483,6 @@ TestArray.addTest(
var that = this;
function encrypt(x, iv) {
console.log(x);
return crypto.subtle.encrypt(
{ name: "AES-CBC", iv: iv },
x, tv.aes_cbc_enc.data);
@ -822,58 +827,6 @@ TestArray.addTest(
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSAES-PKCS#1 encrypt/decrypt round-trip",
function () {
var that = this;
var privKey, pubKey;
var alg = {name:"RSAES-PKCS1-v1_5"};
var privKey, pubKey, data, ct, pt;
function setPriv(x) { privKey = x; }
function setPub(x) { pubKey = x; }
function doEncrypt() {
return crypto.subtle.encrypt(alg.name, pubKey, tv.rsaes.data);
}
function doDecrypt(x) {
return crypto.subtle.decrypt(alg.name, privKey, x);
}
function fail() { error(that); }
Promise.all([
crypto.subtle.importKey("pkcs8", tv.rsaes.pkcs8, alg, false, ['decrypt'])
.then(setPriv, error(that)),
crypto.subtle.importKey("spki", tv.rsaes.spki, alg, false, ['encrypt'])
.then(setPub, error(that))
]).then(doEncrypt, error(that))
.then(doDecrypt, error(that))
.then(
memcmp_complete(that, tv.rsaes.data),
error(that)
);
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSAES-PKCS#1 decryption known answer",
function () {
var that = this;
var alg = {name:"RSAES-PKCS1-v1_5"};
function doDecrypt(x) {
return crypto.subtle.decrypt(alg.name, x, tv.rsaes.result);
}
function fail() { error(that); }
crypto.subtle.importKey("pkcs8", tv.rsaes.pkcs8, alg, false, ['decrypt'])
.then( doDecrypt, fail )
.then( memcmp_complete(that, tv.rsaes.data), fail );
}
);
// -----------------------------------------------------------------------------
TestArray.addTest(
"RSASSA/SHA-1 signature",
@ -882,15 +835,12 @@ TestArray.addTest(
var alg = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-1" };
function doSign(x) {
console.log("sign");
console.log(x);
return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
}
function fail() { console.log("fail"); error(that); }
crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ['sign'])
.then( doSign, fail )
.then( memcmp_complete(that, tv.rsassa.sig1), fail );
.then( doSign )
.then( memcmp_complete(that, tv.rsassa.sig1), error(that) );
}
);
@ -904,13 +854,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig1, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return x; }),
fail
error(that)
);
}
);
@ -925,13 +874,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return !x; }),
fail
error(that)
);
}
);
@ -946,11 +894,10 @@ TestArray.addTest(
function doSign(x) {
return crypto.subtle.sign(alg.name, x, tv.rsassa.data);
}
function fail(x) { console.log(x); error(that); }
crypto.subtle.importKey("pkcs8", tv.rsassa.pkcs8, alg, false, ['sign'])
.then( doSign, fail )
.then( memcmp_complete(that, tv.rsassa.sig256), fail );
.then( doSign )
.then( memcmp_complete(that, tv.rsassa.sig256), error(that) );
}
);
@ -964,13 +911,12 @@ TestArray.addTest(
function doVerify(x) {
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig256, tv.rsassa.data);
}
function fail(x) { error(that); }
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return x; }),
fail
error(that)
);
}
);
@ -984,17 +930,14 @@ TestArray.addTest(
var use = ['sign', 'verify'];
function doVerify(x) {
console.log("verifying")
return crypto.subtle.verify(alg.name, x, tv.rsassa.sig_fail, tv.rsassa.data);
}
function fail(x) { console.log("failing"); error(that)(x); }
console.log("running")
crypto.subtle.importKey("spki", tv.rsassa.spki, alg, false, ['verify'])
.then( doVerify, fail )
.then( doVerify )
.then(
complete(that, function(x) { return !x; }),
fail
error(that)
);
}
);
@ -1175,20 +1118,18 @@ TestArray.addTest(
true, ['sign', 'verify']);
}
function temperr(x) { return function(y) { console.log("error in "+x); console.log(y); } }
Promise.all([
crypto.subtle.importKey("jwk", tv.aes_gcm_enc.key_jwk,
"AES-GCM", false, ['wrapKey','unwrapKey'])
.then(function(x) { console.log("wrapKey"); wrapKey = x; }),
.then(function(x) { wrapKey = x; }),
crypto.subtle.generateKey(genAlg, true, ['sign', 'verify'])
.then(function(x) { console.log("originalKey"); originalKey = x; return x; })
.then(function(x) { originalKey = x; return x; })
.then(doExport)
.then(function(x) { originalKeyJwk = x; })
])
.then(doWrap, temperr("initial phase"))
.then(doUnwrap, temperr("wrap"))
.then(doExport, temperr("unwrap"))
.then(doWrap)
.then(doUnwrap)
.then(doExport)
.then(
complete(that, function(x) {
return exists(x.k) && x.k == originalKeyJwk.k;
@ -1269,9 +1210,9 @@ TestArray.addTest(
Promise.all([
crypto.subtle.importKey("jwk", tv.aes_kw.wrapping_key,
"AES-KW", false, ['wrapKey','unwrapKey'])
.then(function(x) { console.log("wrapKey"); wrapKey = x; }),
.then(function(x) { wrapKey = x; }),
crypto.subtle.generateKey(genAlg, true, ['sign'])
.then(function(x) { console.log("originalKey"); originalKey = x; return x; })
.then(function(x) { originalKey = x; return x; })
.then(doExport)
.then(function(x) { originalKeyJwk = x; })
])
@ -1332,7 +1273,7 @@ TestArray.addTest(
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
return crypto.subtle.generateKey(alg, false, ["encrypt"]);
return crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"]);
}
function doGenerateRsaSsaPkcs1Key() {
@ -1364,24 +1305,7 @@ TestArray.addTest(
return crypto.subtle.generateKey(alg, false, ["sign"]).then(doSign);
}
function doCheckRSAES() {
var alg = {
name: "RSAES-PKCS1-v1_5",
modulusLength: 1024,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
function doEncrypt(x) {
var alg = {name: "RSA-OAEP", hash: "SHA-1"};
return crypto.subtle.encrypt(alg, x.publicKey, new Uint8Array());
}
return crypto.subtle.generateKey(alg, false, ["encrypt"]).then(doEncrypt);
}
doCheckRSASSA().then(error(that), function () {
doCheckRSAES().then(error(that), complete(that));
});
doCheckRSASSA().then(error(that), complete(that));
}
);
/*]]>*/</script>

Просмотреть файл

@ -103,7 +103,7 @@ TestArray.addTest(
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01])
};
return crypto.subtle.generateKey(alg, false, ["encrypt"])
return crypto.subtle.generateKey(alg, false, ["encrypt", "decrypt"])
}
function doDerive() {
@ -336,12 +336,12 @@ TestArray.addTest(
}
Promise.all([
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_priv, alg, false, ["deriveBits"])
.then(setPriv, error(that)),
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_pub, alg, false, ["deriveBits"])
.then(setPub, error(that))
]).then(doDerive, error(that))
.then(doSignAndVerify, error(that))
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_priv, alg, false, ["deriveKey"])
.then(setPriv),
crypto.subtle.importKey("jwk", tv.ecdh_p521.jwk_pub, alg, false, ["deriveKey"])
.then(setPub)
]).then(doDerive)
.then(doSignAndVerify)
.then(complete(that), error(that));
}
);

Просмотреть файл

@ -192,8 +192,6 @@ TestArray.addTest(
.then(doExport)
.then(
complete(that, function(x) {
window.jwk_priv = x;
console.log(JSON.stringify(x));
return hasBaseJwkFields(x) &&
hasFields(x, ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']) &&
x.kty == 'RSA' &&

Просмотреть файл

@ -46,7 +46,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha1.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}
@ -61,7 +60,7 @@ TestArray.addTest(
}
function fail(x) { console.log("failing"); error(that)(x); }
crypto.subtle.importKey("raw", key, alg, false, ["deriveKey"])
crypto.subtle.importKey("raw", key, alg, false, ["deriveBits"])
.then( doDerive, fail )
.then( memcmp_complete(that, tv.pbkdf2_sha1.derived), fail );
}
@ -76,7 +75,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha1.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}
@ -161,7 +159,6 @@ TestArray.addTest(
var key = tv.pbkdf2_sha256.password;
function doDerive(x) {
console.log("deriving");
if (!hasKeyFields(x)) {
throw "Invalid key; missing field(s)";
}

Просмотреть файл

@ -120,12 +120,13 @@ TestArray.addTest(
var privKey, pubKey;
function setKey(x) { pubKey = x.publicKey; privKey = x.privateKey; }
function doEncrypt(n) {
console.log("entered encrypt("+ n +")");
return function () {
return crypto.subtle.encrypt(alg, pubKey, new Uint8Array(n));
}
}
crypto.subtle.generateKey(alg, false, ['encrypt'])
crypto.subtle.generateKey(alg, false, ['encrypt', 'decrypt'])
.then(setKey, error(that))
.then(doEncrypt(214), error(that))
.then(doEncrypt(215), error(that))

Просмотреть файл

@ -7,15 +7,22 @@
#include "DataStoreDB.h"
#include "DataStoreCallbacks.h"
#include "jsapi.h"
#include "mozilla/dom/IDBDatabaseBinding.h"
#include "mozilla/dom/IDBFactoryBinding.h"
#include "mozilla/dom/IDBObjectStoreBinding.h"
#include "mozilla/dom/indexedDB/IDBDatabase.h"
#include "mozilla/dom/indexedDB/IDBEvents.h"
#include "mozilla/dom/indexedDB/IDBFactory.h"
#include "mozilla/dom/indexedDB/IDBIndex.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsIDOMEvent.h"
#include "nsIPrincipal.h"
#include "nsIXPConnect.h"
#define DATASTOREDB_VERSION 1
#define DATASTOREDB_NAME "DataStoreDB"
@ -63,7 +70,9 @@ public:
MOZ_ASSERT(version.IsNull());
#endif
return mDatabase->Close();
mDatabase->Close();
return NS_OK;
}
private:
@ -93,7 +102,36 @@ nsresult
DataStoreDB::CreateFactoryIfNeeded()
{
if (!mFactory) {
nsresult rv = IDBFactory::Create(nullptr, getter_AddRefs(mFactory));
nsresult rv;
nsCOMPtr<nsIPrincipal> principal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsIXPConnect* xpc = nsContentUtils::XPConnect();
MOZ_ASSERT(xpc);
AutoSafeJSContext cx;
nsCOMPtr<nsIXPConnectJSObjectHolder> globalHolder;
rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
JS::Rooted<JSObject*> global(cx, globalHolder->GetJSObject());
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_UNEXPECTED;
}
// The CreateSandbox call returns a proxy to the actual sandbox object. We
// don't need a proxy here.
global = js::UncheckedUnwrap(global);
JSAutoCompartment ac(cx, global);
rv = IDBFactory::CreateForDatastore(cx, global, getter_AddRefs(mFactory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -301,11 +339,7 @@ DataStoreDB::Delete()
mTransaction = nullptr;
if (mDatabase) {
rv = mDatabase->Close();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mDatabase->Close();
mDatabase = nullptr;
}

Просмотреть файл

@ -9,8 +9,9 @@
#include "DataStoreCallbacks.h"
#include "DataStoreService.h"
#include "mozilla/dom/DataStoreBinding.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "nsIDOMEvent.h"
namespace mozilla {

Просмотреть файл

@ -22,6 +22,8 @@
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/indexedDB/IDBCursor.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/dom/indexedDB/IDBTransaction.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/unused.h"

Просмотреть файл

@ -1,4 +1,4 @@
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
@ -137,7 +137,7 @@
// Uninstall the apps
function() { uninstallApp(gApps[0]); },
function() { uninstallApp(gApps[1]); },
function() { uninstallApp(gApps[1]); }
];
function runTest() {

Просмотреть файл

@ -8,7 +8,7 @@
#include "DeviceStorageFileDescriptor.h"
#include "nsDeviceStorage.h"
#include "nsDOMFile.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/ipc/BlobChild.h"
namespace mozilla {
namespace dom {

Просмотреть файл

@ -8,7 +8,7 @@
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
#include "mozilla/unused.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "ContentParent.h"
#include "nsProxyRelease.h"
#include "AppProcessChecker.h"

Просмотреть файл

@ -16,7 +16,7 @@
#include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/PBrowserChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"

Просмотреть файл

@ -8,7 +8,9 @@
#include "FileHelper.h"
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/InputStreamParams.h"
#include "MutableFile.h"
#include "nsDebug.h"
#include "nsError.h"
@ -16,6 +18,10 @@
#include "nsISeekableStream.h"
#include "nsThreadUtils.h"
#ifdef DEBUG
#include "nsXULAppAPI.h"
#endif
namespace mozilla {
namespace dom {
@ -127,7 +133,8 @@ FileInputStreamWrapper::FileInputStreamWrapper(nsISupports* aFileStream,
NS_IMPL_ISUPPORTS_INHERITED(FileInputStreamWrapper,
FileStreamWrapper,
nsIInputStream)
nsIInputStream,
nsIIPCSerializableInputStream)
NS_IMETHODIMP
FileInputStreamWrapper::Close()
@ -230,6 +237,26 @@ FileInputStreamWrapper::IsNonBlocking(bool* _retval)
return NS_OK;
}
void
FileInputStreamWrapper::Serialize(InputStreamParams& aParams,
FileDescriptorArray& /* aFDs */)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIInputStream> thisStream = do_QueryObject(this);
aParams = mozilla::ipc::SameProcessInputStreamParams(
reinterpret_cast<intptr_t>(thisStream.forget().take()));
}
bool
FileInputStreamWrapper::Deserialize(const InputStreamParams& /* aParams */,
const FileDescriptorArray& /* aFDs */)
{
MOZ_CRASH("Should never get here!");
}
FileOutputStreamWrapper::FileOutputStreamWrapper(nsISupports* aFileStream,
FileHelper* aFileHelper,
uint64_t aOffset,

Просмотреть файл

@ -11,8 +11,13 @@
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIIPCSerializableInputStream.h"
namespace mozilla {
namespace ipc {
class InputStreamParams;
} // namespace ipc
namespace dom {
class FileHelper;
@ -46,11 +51,15 @@ protected:
};
class FileInputStreamWrapper : public FileStreamWrapper,
public nsIInputStream
public nsIInputStream,
public nsIIPCSerializableInputStream
{
typedef mozilla::ipc::InputStreamParams InputStreamParams;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
FileInputStreamWrapper(nsISupports* aFileStream,
FileHelper* aFileHelper,

Просмотреть файл

@ -28,6 +28,8 @@ UNIFIED_SOURCES += [
FAIL_ON_WARNINGS = True
include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'../base',
]

Просмотреть файл

@ -13,6 +13,8 @@
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "nsDOMFile.h"
#include "nsIFile.h"
#include "nsNetUtil.h"

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PContent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/unused.h"
#include "nsDOMFile.h"

Просмотреть файл

@ -10,13 +10,13 @@
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/FileSystemRequestParent.h"
#include "mozilla/dom/PFileSystemRequestChild.h"
#include "mozilla/dom/ipc/Blob.h"
class nsIDOMFile;
namespace mozilla {
namespace dom {
class BlobParent;
class FileSystemBase;
class FileSystemParams;
class Promise;

Просмотреть файл

@ -11,6 +11,8 @@
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "nsDOMFile.h"
#include "nsIFile.h"
#include "nsStringGlue.h"

Просмотреть файл

@ -10,6 +10,8 @@
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "nsDOMFile.h"
#include "nsIFile.h"
#include "nsStringGlue.h"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

620
dom/indexedDB/ActorsChild.h Normal file
Просмотреть файл

@ -0,0 +1,620 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_indexeddb_actorschild_h__
#define mozilla_dom_indexeddb_actorschild_h__
#include "js/RootingAPI.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBCursorChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
class nsIEventTarget;
struct PRThread;
namespace mozilla {
namespace ipc {
class BackgroundChildImpl;
} // namespace ipc
namespace dom {
namespace indexedDB {
class FileInfo;
class IDBCursor;
class IDBDatabase;
class IDBFactory;
class IDBMutableFile;
class IDBOpenDBRequest;
class IDBRequest;
class IDBTransaction;
class Key;
class PBackgroundIDBFileChild;
class PermissionRequestChild;
class PermissionRequestParent;
class SerializedStructuredCloneReadInfo;
class BackgroundFactoryChild MOZ_FINAL
: public PBackgroundIDBFactoryChild
{
friend class mozilla::ipc::BackgroundChildImpl;
friend class IDBFactory;
IDBFactory* mFactory;
#ifdef DEBUG
nsCOMPtr<nsIEventTarget> mOwningThread;
#endif
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
IDBFactory*
GetDOMObject() const
{
AssertIsOnOwningThread();
return mFactory;
}
private:
// Only created by IDBFactory.
explicit BackgroundFactoryChild(IDBFactory* aFactory);
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
~BackgroundFactoryChild();
void
SendDeleteMeInternal();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBackgroundIDBFactoryRequestChild*
AllocPBackgroundIDBFactoryRequestChild(const FactoryRequestParams& aParams)
MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBFactoryRequestChild(
PBackgroundIDBFactoryRequestChild* aActor)
MOZ_OVERRIDE;
virtual PBackgroundIDBDatabaseChild*
AllocPBackgroundIDBDatabaseChild(const DatabaseSpec& aSpec,
PBackgroundIDBFactoryRequestChild* aRequest)
MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBDatabaseChild(PBackgroundIDBDatabaseChild* aActor)
MOZ_OVERRIDE;
bool
SendDeleteMe() MOZ_DELETE;
};
class BackgroundDatabaseChild;
class BackgroundRequestChildBase
{
protected:
nsRefPtr<IDBRequest> mRequest;
private:
bool mActorDestroyed;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
IDBRequest*
GetDOMObject() const
{
AssertIsOnOwningThread();
return mRequest;
}
bool
IsActorDestroyed() const
{
AssertIsOnOwningThread();
return mActorDestroyed;
}
protected:
explicit BackgroundRequestChildBase(IDBRequest* aRequest);
virtual
~BackgroundRequestChildBase();
void
NoteActorDestroyed();
};
class BackgroundFactoryRequestChild MOZ_FINAL
: public BackgroundRequestChildBase
, public PBackgroundIDBFactoryRequestChild
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
friend class IDBFactory;
friend class BackgroundFactoryChild;
friend class BackgroundDatabaseChild;
friend class PermissionRequestChild;
friend class PermissionRequestParent;
nsRefPtr<IDBFactory> mFactory;
const uint64_t mRequestedVersion;
const bool mIsDeleteOp;
public:
IDBOpenDBRequest*
GetOpenDBRequest() const;
private:
// Only created by IDBFactory.
BackgroundFactoryRequestChild(IDBFactory* aFactory,
IDBOpenDBRequest* aOpenRequest,
bool aIsDeleteOp,
uint64_t aRequestedVersion);
// Only destroyed by BackgroundFactoryChild.
~BackgroundFactoryRequestChild();
bool
HandleResponse(nsresult aResponse);
bool
HandleResponse(const OpenDatabaseRequestResponse& aResponse);
bool
HandleResponse(const DeleteDatabaseRequestResponse& aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
Recv__delete__(const FactoryRequestResponse& aResponse) MOZ_OVERRIDE;
virtual bool
RecvPermissionChallenge(const PrincipalInfo& aPrincipalInfo) MOZ_OVERRIDE;
virtual bool
RecvBlocked(const uint64_t& aCurrentVersion) MOZ_OVERRIDE;
};
class BackgroundDatabaseChild MOZ_FINAL
: public PBackgroundIDBDatabaseChild
{
friend class BackgroundFactoryChild;
friend class BackgroundFactoryRequestChild;
friend class IDBDatabase;
nsAutoPtr<DatabaseSpec> mSpec;
nsRefPtr<IDBDatabase> mTemporaryStrongDatabase;
BackgroundFactoryRequestChild* mOpenRequestActor;
IDBDatabase* mDatabase;
public:
void
AssertIsOnOwningThread() const
{
static_cast<BackgroundFactoryChild*>(Manager())->AssertIsOnOwningThread();
}
const DatabaseSpec*
Spec() const
{
AssertIsOnOwningThread();
return mSpec;
}
IDBDatabase*
GetDOMObject() const
{
AssertIsOnOwningThread();
return mDatabase;
}
private:
// Only constructed by BackgroundFactoryChild.
BackgroundDatabaseChild(const DatabaseSpec& aSpec,
BackgroundFactoryRequestChild* aOpenRequest);
// Only destroyed by BackgroundFactoryChild.
~BackgroundDatabaseChild();
void
SendDeleteMeInternal();
void
EnsureDOMObject();
void
ReleaseDOMObject();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBackgroundIDBDatabaseFileChild*
AllocPBackgroundIDBDatabaseFileChild(PBlobChild* aBlobChild)
MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBDatabaseFileChild(
PBackgroundIDBDatabaseFileChild* aActor)
MOZ_OVERRIDE;
virtual PBackgroundIDBTransactionChild*
AllocPBackgroundIDBTransactionChild(
const nsTArray<nsString>& aObjectStoreNames,
const Mode& aMode)
MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBTransactionChild(PBackgroundIDBTransactionChild* aActor)
MOZ_OVERRIDE;
virtual PBackgroundIDBVersionChangeTransactionChild*
AllocPBackgroundIDBVersionChangeTransactionChild(
const uint64_t& aCurrentVersion,
const uint64_t& aRequestedVersion,
const int64_t& aNextObjectStoreId,
const int64_t& aNextIndexId)
MOZ_OVERRIDE;
virtual bool
RecvPBackgroundIDBVersionChangeTransactionConstructor(
PBackgroundIDBVersionChangeTransactionChild* aActor,
const uint64_t& aCurrentVersion,
const uint64_t& aRequestedVersion,
const int64_t& aNextObjectStoreId,
const int64_t& aNextIndexId)
MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBVersionChangeTransactionChild(
PBackgroundIDBVersionChangeTransactionChild* aActor)
MOZ_OVERRIDE;
virtual bool
RecvVersionChange(const uint64_t& aOldVersion,
const NullableVersion& aNewVersion)
MOZ_OVERRIDE;
virtual bool
RecvInvalidate() MOZ_OVERRIDE;
bool
SendDeleteMe() MOZ_DELETE;
};
class BackgroundVersionChangeTransactionChild;
class BackgroundTransactionBase
{
friend class BackgroundVersionChangeTransactionChild;
// mTemporaryStrongTransaction is strong and is only valid until the end of
// NoteComplete() member function or until the NoteActorDestroyed() member
// function is called.
nsRefPtr<IDBTransaction> mTemporaryStrongTransaction;
protected:
// mTransaction is weak and is valid until the NoteActorDestroyed() member
// function is called.
IDBTransaction* mTransaction;
public:
#ifdef DEBUG
virtual void
AssertIsOnOwningThread() const = 0;
#else
void
AssertIsOnOwningThread() const
{ }
#endif
IDBTransaction*
GetDOMObject() const
{
AssertIsOnOwningThread();
return mTransaction;
}
protected:
BackgroundTransactionBase();
explicit BackgroundTransactionBase(IDBTransaction* aTransaction);
virtual
~BackgroundTransactionBase();
void
NoteActorDestroyed();
void
NoteComplete();
private:
// Only called by BackgroundVersionChangeTransactionChild.
void
SetDOMTransaction(IDBTransaction* aDOMObject);
};
class BackgroundTransactionChild MOZ_FINAL
: public BackgroundTransactionBase
, public PBackgroundIDBTransactionChild
{
friend class BackgroundDatabaseChild;
friend class IDBDatabase;
public:
#ifdef DEBUG
virtual void
AssertIsOnOwningThread() const MOZ_OVERRIDE;
#endif
void
SendDeleteMeInternal();
private:
// Only created by IDBDatabase.
explicit BackgroundTransactionChild(IDBTransaction* aTransaction);
// Only destroyed by BackgroundDatabaseChild.
~BackgroundTransactionChild();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
bool
RecvComplete(const nsresult& aResult) MOZ_OVERRIDE;
virtual PBackgroundIDBRequestChild*
AllocPBackgroundIDBRequestChild(const RequestParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor)
MOZ_OVERRIDE;
virtual PBackgroundIDBCursorChild*
AllocPBackgroundIDBCursorChild(const OpenCursorParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor)
MOZ_OVERRIDE;
bool
SendDeleteMe() MOZ_DELETE;
};
class BackgroundVersionChangeTransactionChild MOZ_FINAL
: public BackgroundTransactionBase
, public PBackgroundIDBVersionChangeTransactionChild
{
friend class BackgroundDatabaseChild;
IDBOpenDBRequest* mOpenDBRequest;
public:
#ifdef DEBUG
virtual void
AssertIsOnOwningThread() const MOZ_OVERRIDE;
#endif
void
SendDeleteMeInternal();
private:
// Only created by BackgroundDatabaseChild.
explicit BackgroundVersionChangeTransactionChild(IDBOpenDBRequest* aOpenDBRequest);
// Only destroyed by BackgroundDatabaseChild.
~BackgroundVersionChangeTransactionChild();
// Only called by BackgroundDatabaseChild.
void
SetDOMTransaction(IDBTransaction* aDOMObject)
{
BackgroundTransactionBase::SetDOMTransaction(aDOMObject);
}
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
bool
RecvComplete(const nsresult& aResult) MOZ_OVERRIDE;
virtual PBackgroundIDBRequestChild*
AllocPBackgroundIDBRequestChild(const RequestParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor)
MOZ_OVERRIDE;
virtual PBackgroundIDBCursorChild*
AllocPBackgroundIDBCursorChild(const OpenCursorParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor)
MOZ_OVERRIDE;
bool
SendDeleteMe() MOZ_DELETE;
};
class BackgroundRequestChild MOZ_FINAL
: public BackgroundRequestChildBase
, public PBackgroundIDBRequestChild
{
friend class BackgroundTransactionChild;
friend class BackgroundVersionChangeTransactionChild;
nsRefPtr<IDBTransaction> mTransaction;
nsTArray<nsRefPtr<FileInfo>> mFileInfos;
public:
explicit BackgroundRequestChild(IDBRequest* aRequest);
void
HoldFileInfosUntilComplete(nsTArray<nsRefPtr<FileInfo>>& aFileInfos);
private:
// Only destroyed by BackgroundTransactionChild or
// BackgroundVersionChangeTransactionChild.
~BackgroundRequestChild();
void
MaybeFinishTransactionEarly();
bool
HandleResponse(nsresult aResponse);
bool
HandleResponse(const Key& aResponse);
bool
HandleResponse(const nsTArray<Key>& aResponse);
bool
HandleResponse(const SerializedStructuredCloneReadInfo& aResponse);
bool
HandleResponse(const nsTArray<SerializedStructuredCloneReadInfo>& aResponse);
bool
HandleResponse(JS::Handle<JS::Value> aResponse);
bool
HandleResponse(uint64_t aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
Recv__delete__(const RequestResponse& aResponse) MOZ_OVERRIDE;
};
class BackgroundCursorChild MOZ_FINAL
: public PBackgroundIDBCursorChild
{
friend class BackgroundTransactionChild;
friend class BackgroundVersionChangeTransactionChild;
class DelayedDeleteRunnable;
IDBRequest* mRequest;
IDBTransaction* mTransaction;
IDBObjectStore* mObjectStore;
IDBIndex* mIndex;
IDBCursor* mCursor;
// These are only set while a request is in progress.
nsRefPtr<IDBRequest> mStrongRequest;
nsRefPtr<IDBCursor> mStrongCursor;
Direction mDirection;
#ifdef DEBUG
PRThread* mOwningThread;
#endif
public:
BackgroundCursorChild(IDBRequest* aRequest,
IDBObjectStore* aObjectStore,
Direction aDirection);
BackgroundCursorChild(IDBRequest* aRequest,
IDBIndex* aIndex,
Direction aDirection);
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
void
SendContinueInternal(const CursorRequestParams& aParams);
void
SendDeleteMeInternal();
private:
// Only destroyed by BackgroundTransactionChild or
// BackgroundVersionChangeTransactionChild.
~BackgroundCursorChild();
void
HandleResponse(nsresult aResponse);
void
HandleResponse(const void_t& aResponse);
void
HandleResponse(const ObjectStoreCursorResponse& aResponse);
void
HandleResponse(const ObjectStoreKeyCursorResponse& aResponse);
void
HandleResponse(const IndexCursorResponse& aResponse);
void
HandleResponse(const IndexKeyCursorResponse& aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
RecvResponse(const CursorResponse& aResponse) MOZ_OVERRIDE;
// Force callers to use SendContinueInternal.
bool
SendContinue(const CursorRequestParams& aParams) MOZ_DELETE;
bool
SendDeleteMe() MOZ_DELETE;
};
// XXX This doesn't belong here. However, we're not yet porting MutableFile
// stuff to PBackground so this is necessary for the time being.
void
DispatchMutableFileResult(IDBRequest* aRequest,
nsresult aResultCode,
IDBMutableFile* aMutableFile);
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_actorschild_h__

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше