Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef _CANVASUTILS_H_
7 : #define _CANVASUTILS_H_
8 :
9 : #include "CanvasRenderingContextHelper.h"
10 : #include "mozilla/CheckedInt.h"
11 : #include "mozilla/dom/ToJSValue.h"
12 : #include "jsapi.h"
13 : #include "mozilla/FloatingPoint.h"
14 :
15 : class nsIPrincipal;
16 :
17 : namespace mozilla {
18 :
19 : namespace dom {
20 : class HTMLCanvasElement;
21 : } // namespace dom
22 :
23 : namespace CanvasUtils {
24 :
25 : bool GetCanvasContextType(const nsAString& str, dom::CanvasContextType* const out_type);
26 :
27 : // Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight]
28 :
29 : inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h,
30 : int32_t realWidth, int32_t realHeight) {
31 : CheckedInt32 checked_xmost = CheckedInt32(x) + w;
32 : CheckedInt32 checked_ymost = CheckedInt32(y) + h;
33 :
34 : return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
35 : checked_xmost.isValid() &&
36 : checked_xmost.value() <= realWidth &&
37 : checked_ymost.isValid() &&
38 : checked_ymost.value() <= realHeight;
39 : }
40 :
41 : // Flag aCanvasElement as write-only if drawing an image with aPrincipal
42 : // onto it would make it such.
43 :
44 : void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
45 : nsIPrincipal *aPrincipal,
46 : bool forceWriteOnly,
47 : bool CORSUsed);
48 :
49 : // Check if the context is chrome or has the permission to drawWindow
50 : bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj);
51 :
52 : // Make a double out of |v|, treating undefined values as 0.0 (for
53 : // the sake of sparse arrays). Return true iff coercion
54 : // succeeded.
55 : bool CoerceDouble(const JS::Value& v, double* d);
56 :
57 : /* Float validation stuff */
58 : #define VALIDATE(_f) if (!IsFinite(_f)) return false
59 :
60 0 : inline bool FloatValidate (double f1) {
61 0 : VALIDATE(f1);
62 0 : return true;
63 : }
64 :
65 0 : inline bool FloatValidate (double f1, double f2) {
66 0 : VALIDATE(f1); VALIDATE(f2);
67 0 : return true;
68 : }
69 :
70 : inline bool FloatValidate (double f1, double f2, double f3) {
71 : VALIDATE(f1); VALIDATE(f2); VALIDATE(f3);
72 : return true;
73 : }
74 :
75 : inline bool FloatValidate (double f1, double f2, double f3, double f4) {
76 : VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4);
77 : return true;
78 : }
79 :
80 : inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5) {
81 : VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5);
82 : return true;
83 : }
84 :
85 : inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5, double f6) {
86 : VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5); VALIDATE(f6);
87 : return true;
88 : }
89 :
90 : #undef VALIDATE
91 :
92 : template<typename T>
93 : nsresult
94 : JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
95 : nsTArray<T>& dashes)
96 : {
97 : // The cap is pretty arbitrary. 16k should be enough for
98 : // anybody...
99 : static const uint32_t MAX_NUM_DASHES = 1 << 14;
100 :
101 : if (!patternArray.isPrimitive()) {
102 : JS::Rooted<JSObject*> obj(cx, patternArray.toObjectOrNull());
103 : uint32_t length;
104 : if (!JS_GetArrayLength(cx, obj, &length)) {
105 : // Not an array-like thing
106 : return NS_ERROR_INVALID_ARG;
107 : } else if (length > MAX_NUM_DASHES) {
108 : // Too many dashes in the pattern
109 : return NS_ERROR_ILLEGAL_VALUE;
110 : }
111 :
112 : bool haveNonzeroElement = false;
113 : for (uint32_t i = 0; i < length; ++i) {
114 : JS::Rooted<JS::Value> elt(cx);
115 : double d;
116 : if (!JS_GetElement(cx, obj, i, &elt)) {
117 : return NS_ERROR_FAILURE;
118 : }
119 : if (!(CoerceDouble(elt, &d) &&
120 : FloatValidate(d) &&
121 : d >= 0.0)) {
122 : // Pattern elements must be finite "numbers" >= 0.
123 : return NS_ERROR_INVALID_ARG;
124 : } else if (d > 0.0) {
125 : haveNonzeroElement = true;
126 : }
127 : if (!dashes.AppendElement(d, mozilla::fallible)) {
128 : return NS_ERROR_OUT_OF_MEMORY;
129 : }
130 : }
131 :
132 : if (dashes.Length() > 0 && !haveNonzeroElement) {
133 : // An all-zero pattern makes no sense.
134 : return NS_ERROR_ILLEGAL_VALUE;
135 : }
136 : } else if (!(patternArray.isUndefined() || patternArray.isNull())) {
137 : // undefined and null mean "reset to no dash". Any other
138 : // random garbage is a type error.
139 : return NS_ERROR_INVALID_ARG;
140 : }
141 :
142 : return NS_OK;
143 : }
144 :
145 : template<typename T>
146 : void
147 : DashArrayToJSVal(nsTArray<T>& dashes,
148 : JSContext* cx,
149 : JS::MutableHandle<JS::Value> retval,
150 : mozilla::ErrorResult& rv)
151 : {
152 : if (dashes.IsEmpty()) {
153 : retval.setNull();
154 : return;
155 : }
156 : JS::Rooted<JS::Value> val(cx);
157 : if (!mozilla::dom::ToJSValue(cx, dashes, retval)) {
158 : rv.Throw(NS_ERROR_OUT_OF_MEMORY);
159 : }
160 : }
161 :
162 : } // namespace CanvasUtils
163 : } // namespace mozilla
164 :
165 : #endif /* _CANVASUTILS_H_ */
|