2018-11-30 22:52:05 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2009-06-26 00:30:56 +04:00
|
|
|
|
|
|
|
#ifndef _CANVASUTILS_H_
|
|
|
|
#define _CANVASUTILS_H_
|
|
|
|
|
2016-07-22 09:25:41 +03:00
|
|
|
#include "CanvasRenderingContextHelper.h"
|
2012-05-14 23:50:20 +04:00
|
|
|
#include "mozilla/CheckedInt.h"
|
2014-04-10 22:57:42 +04:00
|
|
|
#include "mozilla/dom/ToJSValue.h"
|
2013-08-24 06:42:42 +04:00
|
|
|
#include "jsapi.h"
|
2021-07-13 14:52:42 +03:00
|
|
|
#include "js/Array.h" // JS::GetArrayLength
|
|
|
|
#include "js/PropertyAndElement.h" // JS_GetElement
|
2014-10-01 13:26:00 +04:00
|
|
|
#include "mozilla/FloatingPoint.h"
|
2010-08-24 01:03:40 +04:00
|
|
|
|
2009-07-02 13:57:35 +04:00
|
|
|
class nsIPrincipal;
|
2009-06-26 00:30:56 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
2013-01-04 09:16:14 +04:00
|
|
|
namespace dom {
|
2020-11-23 19:07:43 +03:00
|
|
|
class Document;
|
2013-01-04 09:16:14 +04:00
|
|
|
class HTMLCanvasElement;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
2013-01-04 09:16:14 +04:00
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
namespace CanvasUtils {
|
|
|
|
|
2015-10-12 06:21:03 +03:00
|
|
|
bool GetCanvasContextType(const nsAString& str,
|
|
|
|
dom::CanvasContextType* const out_type);
|
2011-06-30 01:34:58 +04:00
|
|
|
|
|
|
|
// Check that the rectangle [x,y,w,h] is a subrectangle of
|
|
|
|
// [0,0,realWidth,realHeight]
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h,
|
|
|
|
int32_t realWidth, int32_t realHeight) {
|
2011-06-30 01:34:58 +04:00
|
|
|
CheckedInt32 checked_xmost = CheckedInt32(x) + w;
|
|
|
|
CheckedInt32 checked_ymost = CheckedInt32(y) + h;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
return w >= 0 && h >= 0 && x >= 0 && y >= 0 && checked_xmost.isValid() &&
|
|
|
|
checked_xmost.value() <= realWidth && checked_ymost.isValid() &&
|
|
|
|
checked_ymost.value() <= realHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flag aCanvasElement as write-only if drawing an image with aPrincipal
|
|
|
|
// onto it would make it such.
|
|
|
|
|
2013-01-04 09:16:14 +04:00
|
|
|
void DoDrawImageSecurityCheck(dom::HTMLCanvasElement* aCanvasElement,
|
2011-06-30 01:34:58 +04:00
|
|
|
nsIPrincipal* aPrincipal, bool forceWriteOnly,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool CORSUsed);
|
2011-06-30 01:34:58 +04:00
|
|
|
|
2017-02-01 23:47:59 +03:00
|
|
|
// Check if the context is chrome or has the permission to drawWindow
|
|
|
|
bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj);
|
|
|
|
|
2022-01-24 19:12:02 +03:00
|
|
|
// Check if the context has permission to use OffscreenCanvas.
|
|
|
|
bool IsOffscreenCanvasEnabled(JSContext* aCx, JSObject* aObj);
|
|
|
|
|
2017-08-22 09:23:41 +03:00
|
|
|
// Check site-specific permission and display prompt if appropriate.
|
2019-01-02 16:05:23 +03:00
|
|
|
bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx,
|
2022-02-03 23:00:25 +03:00
|
|
|
Maybe<nsIPrincipal*> aPrincipal);
|
2017-08-22 09:23:41 +03:00
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
// Make a double out of |v|, treating undefined values as 0.0 (for
|
|
|
|
// the sake of sparse arrays). Return true iff coercion
|
|
|
|
// succeeded.
|
2016-09-11 12:15:24 +03:00
|
|
|
bool CoerceDouble(const JS::Value& v, double* d);
|
2009-06-26 00:30:56 +04:00
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
/* Float validation stuff */
|
2014-10-01 13:26:00 +04:00
|
|
|
#define VALIDATE(_f) \
|
|
|
|
if (!IsFinite(_f)) return false
|
2009-06-26 00:30:56 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1, double f2) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
|
|
|
VALIDATE(f2);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
2009-06-26 00:30:56 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1, double f2, double f3) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
|
|
|
VALIDATE(f2);
|
|
|
|
VALIDATE(f3);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
2009-09-03 04:47:49 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1, double f2, double f3, double f4) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
|
|
|
VALIDATE(f2);
|
|
|
|
VALIDATE(f3);
|
|
|
|
VALIDATE(f4);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
2009-06-26 00:30:56 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1, double f2, double f3, double f4,
|
|
|
|
double f5) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
|
|
|
VALIDATE(f2);
|
|
|
|
VALIDATE(f3);
|
|
|
|
VALIDATE(f4);
|
|
|
|
VALIDATE(f5);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
inline bool FloatValidate(double f1, double f2, double f3, double f4, double f5,
|
|
|
|
double f6) {
|
2011-06-30 01:34:58 +04:00
|
|
|
VALIDATE(f1);
|
|
|
|
VALIDATE(f2);
|
|
|
|
VALIDATE(f3);
|
|
|
|
VALIDATE(f4);
|
|
|
|
VALIDATE(f5);
|
|
|
|
VALIDATE(f6);
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef VALIDATE
|
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
template <typename T>
|
2013-03-23 09:05:20 +04:00
|
|
|
nsresult JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
|
2015-07-13 09:19:12 +03:00
|
|
|
nsTArray<T>& dashes) {
|
2011-06-30 01:34:58 +04:00
|
|
|
// The cap is pretty arbitrary. 16k should be enough for
|
|
|
|
// anybody...
|
2012-03-07 03:52:55 +04:00
|
|
|
static const uint32_t MAX_NUM_DASHES = 1 << 14;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2014-04-28 07:27:54 +04:00
|
|
|
if (!patternArray.isPrimitive()) {
|
2014-04-28 06:58:52 +04:00
|
|
|
JS::Rooted<JSObject*> obj(cx, patternArray.toObjectOrNull());
|
2012-03-07 03:52:55 +04:00
|
|
|
uint32_t length;
|
2019-12-11 09:17:44 +03:00
|
|
|
if (!JS::GetArrayLength(cx, obj, &length)) {
|
2011-06-30 01:34:58 +04:00
|
|
|
// Not an array-like thing
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
} else if (length > MAX_NUM_DASHES) {
|
|
|
|
// Too many dashes in the pattern
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
bool haveNonzeroElement = false;
|
2015-05-28 21:07:44 +03:00
|
|
|
for (uint32_t i = 0; i < length; ++i) {
|
|
|
|
JS::Rooted<JS::Value> elt(cx);
|
|
|
|
double d;
|
|
|
|
if (!JS_GetElement(cx, obj, i, &elt)) {
|
2011-06-30 01:34:58 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2014-04-28 06:32:05 +04:00
|
|
|
if (!(CoerceDouble(elt, &d) && FloatValidate(d) && d >= 0.0)) {
|
2011-06-30 01:34:58 +04:00
|
|
|
// Pattern elements must be finite "numbers" >= 0.
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
} else if (d > 0.0) {
|
|
|
|
haveNonzeroElement = true;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2015-05-28 21:07:44 +03:00
|
|
|
if (!dashes.AppendElement(d, mozilla::fallible)) {
|
2011-06-30 01:34:58 +04:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dashes.Length() > 0 && !haveNonzeroElement) {
|
|
|
|
// An all-zero pattern makes no sense.
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2014-04-28 06:32:05 +04:00
|
|
|
} else if (!(patternArray.isUndefined() || patternArray.isNull())) {
|
2011-06-30 01:34:58 +04:00
|
|
|
// undefined and null mean "reset to no dash". Any other
|
|
|
|
// random garbage is a type error.
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2011-06-30 01:34:58 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2015-07-13 09:19:12 +03:00
|
|
|
void DashArrayToJSVal(nsTArray<T>& dashes, JSContext* cx,
|
2014-06-12 00:26:52 +04:00
|
|
|
JS::MutableHandle<JS::Value> retval,
|
|
|
|
mozilla::ErrorResult& rv) {
|
2011-06-30 01:34:58 +04:00
|
|
|
if (dashes.IsEmpty()) {
|
2014-06-12 00:26:52 +04:00
|
|
|
retval.setNull();
|
|
|
|
return;
|
2013-05-02 13:12:45 +04:00
|
|
|
}
|
2014-04-10 22:57:42 +04:00
|
|
|
JS::Rooted<JS::Value> val(cx);
|
2014-06-12 00:26:52 +04:00
|
|
|
if (!mozilla::dom::ToJSValue(cx, dashes, retval)) {
|
2013-05-02 13:12:45 +04:00
|
|
|
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
}
|
2011-06-30 01:34:58 +04:00
|
|
|
}
|
|
|
|
|
2019-04-16 09:58:29 +03:00
|
|
|
// returns true if write-only mode must used for this principal based on
|
|
|
|
// the incumbent global.
|
2019-06-04 09:32:37 +03:00
|
|
|
bool CheckWriteOnlySecurity(bool aCORSUsed, nsIPrincipal* aPrincipal,
|
|
|
|
bool aHadCrossOriginRedirects);
|
2019-04-16 09:58:29 +03:00
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace CanvasUtils
|
|
|
|
} // namespace mozilla
|
2009-06-26 00:30:56 +04:00
|
|
|
|
|
|
|
#endif /* _CANVASUTILS_H_ */
|