зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1502799 - Implement origin-clean algorithm for ImageBitmap, r=aosmond
This commit is contained in:
Родитель
82a73c0629
Коммит
531924a924
|
@ -1079,6 +1079,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompos
|
|||
, mIsCapturedFrameInvalid(false)
|
||||
, mPathTransformWillUpdate(false)
|
||||
, mInvalidateCount(0)
|
||||
, mWriteOnly(false)
|
||||
{
|
||||
if (!sMaxContextsInitialized) {
|
||||
sMaxContexts = gfxPrefs::CanvasAzureAcceleratedLimit();
|
||||
|
@ -2565,7 +2566,8 @@ CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
|
|||
// nullptr and set CORSUsed to true for passing the security check in
|
||||
// CanvasUtils::DoDrawImageSecurityCheck().
|
||||
RefPtr<CanvasPattern> pat =
|
||||
new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
|
||||
new CanvasPattern(this, srcSurf, repeatMode, nullptr,
|
||||
imgBitmap.IsWriteOnly(), true);
|
||||
|
||||
return pat.forget();
|
||||
}
|
||||
|
@ -4920,6 +4922,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvas->IsWriteOnly()) {
|
||||
SetWriteOnly();
|
||||
}
|
||||
} else if (aImage.IsImageBitmap()) {
|
||||
ImageBitmap& imageBitmap = aImage.GetAsImageBitmap();
|
||||
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
|
||||
|
@ -4928,6 +4934,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
|||
return;
|
||||
}
|
||||
|
||||
if (imageBitmap.IsWriteOnly()) {
|
||||
SetWriteOnly();
|
||||
}
|
||||
|
||||
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
|
||||
}
|
||||
else {
|
||||
|
@ -5448,7 +5458,8 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
|
|||
|
||||
// Check only if we have a canvas element; if we were created with a docshell,
|
||||
// then it's special internal use.
|
||||
if (mCanvasElement && !mCanvasElement->CallerCanRead(aCx)) {
|
||||
if (IsWriteOnly() ||
|
||||
(mCanvasElement && !mCanvasElement->CallerCanRead(aCx))) {
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
|
|
|
@ -41,6 +41,7 @@ class SourceSurface;
|
|||
namespace dom {
|
||||
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
|
||||
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
|
||||
class ImageBitmap;
|
||||
class ImageData;
|
||||
class StringOrCanvasGradientOrCanvasPattern;
|
||||
class OwningStringOrCanvasGradientOrCanvasPattern;
|
||||
|
@ -1192,6 +1193,19 @@ protected:
|
|||
|
||||
friend struct CanvasBidiProcessor;
|
||||
friend class CanvasDrawObserver;
|
||||
friend class ImageBitmap;
|
||||
|
||||
void SetWriteOnly()
|
||||
{
|
||||
mWriteOnly = true;
|
||||
}
|
||||
|
||||
bool IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
||||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext);
|
||||
|
|
|
@ -471,7 +471,8 @@ CheckSecurityForElements(const nsLayoutUtils::SurfaceFromElementResult& aRes)
|
|||
*/
|
||||
template<class ElementType>
|
||||
static already_AddRefed<SourceSurface>
|
||||
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResult& aRv)
|
||||
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement,
|
||||
bool* aWriteOnly, ErrorResult& aRv)
|
||||
{
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE);
|
||||
|
@ -483,17 +484,14 @@ GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResu
|
|||
}
|
||||
|
||||
|
||||
// check origin-clean
|
||||
if (!CheckSecurityForElements(res)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// check write-only mode
|
||||
*aWriteOnly = !CheckSecurityForElements(res);
|
||||
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
gfxAlphaType aAlphaType)
|
||||
bool aWriteOnly, gfxAlphaType aAlphaType)
|
||||
: mParent(aGlobal)
|
||||
, mData(aData)
|
||||
, mSurface(nullptr)
|
||||
|
@ -501,6 +499,7 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
|||
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
|
||||
, mAlphaType(aAlphaType)
|
||||
, mAllocatedImageData(false)
|
||||
, mWriteOnly(aWriteOnly)
|
||||
{
|
||||
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
|
||||
|
||||
|
@ -763,6 +762,7 @@ ImageBitmap::ToCloneData() const
|
|||
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
|
||||
result->mSurface = surface->GetDataSurface();
|
||||
MOZ_ASSERT(result->mSurface);
|
||||
result->mWriteOnly = mWriteOnly;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -773,7 +773,8 @@ ImageBitmap::CreateFromSourceSurface(nsIGlobalObject* aGlobal,
|
|||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(aSource);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
|
||||
false /* writeOnly */);
|
||||
ret->mAllocatedImageData = true;
|
||||
return ret.forget();
|
||||
}
|
||||
|
@ -784,7 +785,8 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
|
|||
{
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mAlphaType);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, aData->mWriteOnly, aData->mAlphaType);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
|
@ -798,11 +800,8 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
|
|||
OffscreenCanvas& aOffscreenCanvas,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Check origin-clean.
|
||||
if (aOffscreenCanvas.IsWriteOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// Check write-only mode.
|
||||
bool writeOnly = aOffscreenCanvas.IsWriteOnly();
|
||||
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas,
|
||||
|
@ -818,7 +817,7 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
|
|||
RefPtr<layers::Image> data =
|
||||
CreateImageFromSurface(surface);
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
|
@ -835,9 +834,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool writeOnly = true;
|
||||
|
||||
// Get the SourceSurface out from the image element and then do security
|
||||
// checking.
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
|
||||
&writeOnly, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
|
@ -851,7 +853,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
|
@ -865,9 +867,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
|||
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
|
||||
{
|
||||
bool writeOnly = true;
|
||||
|
||||
// Get the SourceSurface out from the image element and then do security
|
||||
// checking.
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
|
||||
&writeOnly, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
|
@ -881,7 +886,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
|
@ -913,10 +918,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
|
|||
// Check security.
|
||||
nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal();
|
||||
bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE;
|
||||
if (!CheckSecurityForElements(false, CORSUsed, principal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
bool writeOnly = !CheckSecurityForElements(false, CORSUsed, principal);
|
||||
|
||||
// Create ImageBitmap.
|
||||
RefPtr<layers::Image> data = aVideoEl.GetCurrentImage();
|
||||
|
@ -924,7 +926,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
|
|||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
|
@ -943,12 +945,18 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl, aRv);
|
||||
bool writeOnly = true;
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl,
|
||||
&writeOnly, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!writeOnly) {
|
||||
writeOnly = aCanvasEl.IsWriteOnly();
|
||||
}
|
||||
|
||||
// Crop the source surface if needed.
|
||||
RefPtr<SourceSurface> croppedSurface;
|
||||
IntRect cropRect = aCropRect.valueOr(IntRect());
|
||||
|
@ -982,7 +990,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
if (needToReportMemoryAllocation) {
|
||||
ret->mAllocatedImageData = true;
|
||||
|
@ -1047,7 +1055,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
|
|||
}
|
||||
|
||||
// Create an ImageBimtap.
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, alphaType);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, false /* write-only */, alphaType);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
|
@ -1070,11 +1079,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
|||
|
||||
window->GetExtantDoc()->WarnOnceAbout(nsIDocument::eCreateImageBitmapCanvasRenderingContext2D);
|
||||
|
||||
// Check origin-clean.
|
||||
if (aCanvasCtx.GetCanvas()->IsWriteOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// Check write-only mode.
|
||||
bool writeOnly = aCanvasCtx.GetCanvas()->IsWriteOnly() || aCanvasCtx.IsWriteOnly();
|
||||
|
||||
RefPtr<SourceSurface> surface = aCanvasCtx.GetSurfaceSnapshot();
|
||||
|
||||
|
@ -1096,7 +1102,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
|
@ -1118,7 +1125,9 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
|||
}
|
||||
|
||||
RefPtr<layers::Image> data = aImageBitmap.mData;
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mAlphaType);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, aImageBitmap.mWriteOnly,
|
||||
aImageBitmap.mAlphaType);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
|
@ -1432,16 +1441,14 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
|||
uint32_t picRectWidth_;
|
||||
uint32_t picRectHeight_;
|
||||
uint32_t alphaType_;
|
||||
uint32_t dummy;
|
||||
uint32_t writeOnly;
|
||||
|
||||
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
|
||||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
|
||||
!JS_ReadUint32Pair(aReader, &alphaType_, &dummy)) {
|
||||
!JS_ReadUint32Pair(aReader, &alphaType_, &writeOnly)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(dummy == 0);
|
||||
|
||||
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
|
||||
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
|
||||
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
|
||||
|
@ -1465,7 +1472,8 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
|||
}
|
||||
#endif
|
||||
RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
|
||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aParent, img, alphaType);
|
||||
RefPtr<ImageBitmap> imageBitmap =
|
||||
new ImageBitmap(aParent, img, !!writeOnly, alphaType);
|
||||
|
||||
ErrorResult error;
|
||||
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
|
||||
|
@ -1505,7 +1513,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
|
|||
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, 0))) {
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, aImageBitmap->mWriteOnly))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1839,7 +1847,8 @@ CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedOwningThread(lay
|
|||
}
|
||||
|
||||
// Create ImageBitmap object.
|
||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, aImage);
|
||||
RefPtr<ImageBitmap> imageBitmap =
|
||||
new ImageBitmap(mGlobalObject, aImage, false /* write-only */);
|
||||
|
||||
if (mCropRect.isSome()) {
|
||||
ErrorResult rv;
|
||||
|
|
|
@ -60,6 +60,7 @@ struct ImageBitmapCloneData final
|
|||
RefPtr<gfx::DataSourceSurface> mSurface;
|
||||
gfx::IntRect mPictureRect;
|
||||
gfxAlphaType mAlphaType;
|
||||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -152,6 +153,11 @@ public:
|
|||
|
||||
void OnShutdown();
|
||||
|
||||
bool IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
|
@ -174,6 +180,7 @@ protected:
|
|||
* CreateInternal(from ImageData) method.
|
||||
*/
|
||||
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
bool aWriteOnly,
|
||||
gfxAlphaType aAlphaType = gfxAlphaType::Premult);
|
||||
|
||||
virtual ~ImageBitmap();
|
||||
|
@ -255,6 +262,13 @@ protected:
|
|||
* Whether this object allocated allocated and owns the image data.
|
||||
*/
|
||||
bool mAllocatedImageData;
|
||||
|
||||
/*
|
||||
* Write-Only flag is set to true if this image has been generated from a
|
||||
* cross-origin source. This is the opposite of what is called 'origin-clean'
|
||||
* in the spec.
|
||||
*/
|
||||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -245,8 +245,11 @@ struct TexImageSourceAdapter final : public TexImageSource
|
|||
mPboOffset = pboOffset;
|
||||
}
|
||||
|
||||
TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) {
|
||||
TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap,
|
||||
ErrorResult* out_error)
|
||||
{
|
||||
mImageBitmap = imageBitmap;
|
||||
mOut_error = out_error;
|
||||
}
|
||||
|
||||
TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "GLBlitHelper.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
|
@ -222,11 +223,16 @@ FromPboOffset(WebGLContext* webgl, TexImageTarget target,
|
|||
static UniquePtr<webgl::TexUnpackBlob>
|
||||
FromImageBitmap(WebGLContext* webgl, TexImageTarget target,
|
||||
uint32_t width, uint32_t height, uint32_t depth,
|
||||
const dom::ImageBitmap& imageBitmap)
|
||||
const dom::ImageBitmap& imageBitmap, ErrorResult* aRv)
|
||||
{
|
||||
if (imageBitmap.IsWriteOnly()) {
|
||||
aRv->Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UniquePtr<dom::ImageBitmapCloneData> cloneData = imageBitmap.ToCloneData();
|
||||
if (!cloneData) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
|
||||
|
@ -300,6 +306,14 @@ WebGLContext::FromDomElem(TexImageTarget target, uint32_t width,
|
|||
uint32_t height, uint32_t depth, const dom::Element& elem,
|
||||
ErrorResult* const out_error)
|
||||
{
|
||||
if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
|
||||
const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
|
||||
if (canvas->IsWriteOnly()) {
|
||||
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// The canvas spec says that drawImage should draw the first frame of
|
||||
// animated images. The webgl spec doesn't mention the issue, so we do the
|
||||
// same as drawImage.
|
||||
|
@ -421,7 +435,7 @@ WebGLContext::From(TexImageTarget target, GLsizei rawWidth,
|
|||
|
||||
if (src.mImageBitmap) {
|
||||
return FromImageBitmap(this, target, width, height, depth,
|
||||
*(src.mImageBitmap));
|
||||
*(src.mImageBitmap), src.mOut_error);
|
||||
}
|
||||
|
||||
if (src.mImageData) {
|
||||
|
|
|
@ -270,13 +270,22 @@ function testSecurityErrors() {
|
|||
}
|
||||
|
||||
function checkPromiseFailedWithSecurityError(p) {
|
||||
return p.then( function(reason) { ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully."); },
|
||||
function(reason) { if (reason == "SecurityError: The operation is insecure.") {
|
||||
ok(true, reason);
|
||||
}
|
||||
else {
|
||||
ok(false, "Did not get SecurityError with unclean source. Error Message: " + reason);
|
||||
}});
|
||||
return p.then(imageBitmap => {
|
||||
ok(!!imageBitmap, "ImageBitmaps are always created");
|
||||
const context = document.createElement("canvas").getContext("2d");
|
||||
context.drawImage(imageBitmap, 0, 0);
|
||||
try {
|
||||
context.getImageData(0, 0, 1, 1);
|
||||
ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
|
||||
} catch (ex) {
|
||||
if (ex == "SecurityError: The operation is insecure.") {
|
||||
ok(true, ex);
|
||||
}
|
||||
else {
|
||||
ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
|
|
|
@ -1083,7 +1083,7 @@ HTMLCanvasElement::GetSize()
|
|||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::IsWriteOnly()
|
||||
HTMLCanvasElement::IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
/**
|
||||
* Determine whether the canvas is write-only.
|
||||
*/
|
||||
bool IsWriteOnly();
|
||||
bool IsWriteOnly() const;
|
||||
|
||||
/**
|
||||
* Force the canvas to be write-only.
|
||||
|
|
|
@ -1,23 +1,4 @@
|
|||
[createImageBitmap-origin.sub.html]
|
||||
prefs: [network.http.send_window_size:0]
|
||||
[cross-origin HTMLImageElement]
|
||||
expected: FAIL
|
||||
|
||||
[cross-origin SVGImageElement]
|
||||
expected: FAIL
|
||||
|
||||
[cross-origin HTMLVideoElement]
|
||||
expected: FAIL
|
||||
|
||||
[unclean HTMLCanvasElement]
|
||||
expected: FAIL
|
||||
|
||||
[unclean ImageBitmap]
|
||||
expected: FAIL
|
||||
|
||||
[redirected to cross-origin HTMLVideoElement]
|
||||
expected: FAIL
|
||||
|
||||
[redirected to same-origin HTMLVideoElement]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче