|
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 "mozilla/CheckedInt.h" |
|
10 #include "mozilla/dom/ToJSValue.h" |
|
11 #include "jsapi.h" |
|
12 |
|
13 class nsIPrincipal; |
|
14 |
|
15 namespace mozilla { |
|
16 |
|
17 namespace gfx { |
|
18 class Matrix; |
|
19 } |
|
20 |
|
21 namespace dom { |
|
22 class HTMLCanvasElement; |
|
23 } |
|
24 |
|
25 namespace CanvasUtils { |
|
26 |
|
27 |
|
28 // Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight] |
|
29 |
|
30 inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h, |
|
31 int32_t realWidth, int32_t realHeight) { |
|
32 CheckedInt32 checked_xmost = CheckedInt32(x) + w; |
|
33 CheckedInt32 checked_ymost = CheckedInt32(y) + h; |
|
34 |
|
35 return w >= 0 && h >= 0 && x >= 0 && y >= 0 && |
|
36 checked_xmost.isValid() && |
|
37 checked_xmost.value() <= realWidth && |
|
38 checked_ymost.isValid() && |
|
39 checked_ymost.value() <= realHeight; |
|
40 } |
|
41 |
|
42 // Flag aCanvasElement as write-only if drawing an image with aPrincipal |
|
43 // onto it would make it such. |
|
44 |
|
45 void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement, |
|
46 nsIPrincipal *aPrincipal, |
|
47 bool forceWriteOnly, |
|
48 bool CORSUsed); |
|
49 |
|
50 bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx); |
|
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(JS::Value v, double* d); |
|
56 |
|
57 /* Float validation stuff */ |
|
58 #define VALIDATE(_f) if (!NS_finite(_f)) return false |
|
59 |
|
60 inline bool FloatValidate (double f1) { |
|
61 VALIDATE(f1); |
|
62 return true; |
|
63 } |
|
64 |
|
65 inline bool FloatValidate (double f1, double f2) { |
|
66 VALIDATE(f1); VALIDATE(f2); |
|
67 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& val, |
|
95 FallibleTArray<T>& dashArray); |
|
96 |
|
97 template<typename T> |
|
98 JS::Value |
|
99 DashArrayToJSVal(FallibleTArray<T>& dashArray, |
|
100 JSContext* cx, mozilla::ErrorResult& rv); |
|
101 |
|
102 template<typename T> |
|
103 nsresult |
|
104 JSValToDashArray(JSContext* cx, const JS::Value& patternArray, |
|
105 FallibleTArray<T>& dashes) |
|
106 { |
|
107 // The cap is pretty arbitrary. 16k should be enough for |
|
108 // anybody... |
|
109 static const uint32_t MAX_NUM_DASHES = 1 << 14; |
|
110 |
|
111 if (!JSVAL_IS_PRIMITIVE(patternArray)) { |
|
112 JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(patternArray)); |
|
113 uint32_t length; |
|
114 if (!JS_GetArrayLength(cx, obj, &length)) { |
|
115 // Not an array-like thing |
|
116 return NS_ERROR_INVALID_ARG; |
|
117 } else if (length > MAX_NUM_DASHES) { |
|
118 // Too many dashes in the pattern |
|
119 return NS_ERROR_ILLEGAL_VALUE; |
|
120 } |
|
121 |
|
122 bool haveNonzeroElement = false; |
|
123 for (uint32_t i = 0; i < length; ++i) { |
|
124 JS::Rooted<JS::Value> elt(cx); |
|
125 double d; |
|
126 if (!JS_GetElement(cx, obj, i, &elt)) { |
|
127 return NS_ERROR_FAILURE; |
|
128 } |
|
129 if (!(CoerceDouble(elt, &d) && |
|
130 FloatValidate(d) && |
|
131 d >= 0.0)) { |
|
132 // Pattern elements must be finite "numbers" >= 0. |
|
133 return NS_ERROR_INVALID_ARG; |
|
134 } else if (d > 0.0) { |
|
135 haveNonzeroElement = true; |
|
136 } |
|
137 if (!dashes.AppendElement(d)) { |
|
138 return NS_ERROR_OUT_OF_MEMORY; |
|
139 } |
|
140 } |
|
141 |
|
142 if (dashes.Length() > 0 && !haveNonzeroElement) { |
|
143 // An all-zero pattern makes no sense. |
|
144 return NS_ERROR_ILLEGAL_VALUE; |
|
145 } |
|
146 } else if (!(JSVAL_IS_VOID(patternArray) || JSVAL_IS_NULL(patternArray))) { |
|
147 // undefined and null mean "reset to no dash". Any other |
|
148 // random garbage is a type error. |
|
149 return NS_ERROR_INVALID_ARG; |
|
150 } |
|
151 |
|
152 return NS_OK; |
|
153 } |
|
154 |
|
155 template<typename T> |
|
156 void |
|
157 DashArrayToJSVal(FallibleTArray<T>& dashes, |
|
158 JSContext* cx, |
|
159 JS::MutableHandle<JS::Value> retval, |
|
160 mozilla::ErrorResult& rv) |
|
161 { |
|
162 if (dashes.IsEmpty()) { |
|
163 retval.setNull(); |
|
164 return; |
|
165 } |
|
166 JS::Rooted<JS::Value> val(cx); |
|
167 if (!mozilla::dom::ToJSValue(cx, dashes, retval)) { |
|
168 rv.Throw(NS_ERROR_OUT_OF_MEMORY); |
|
169 } |
|
170 } |
|
171 |
|
172 } |
|
173 } |
|
174 |
|
175 #endif /* _CANVASUTILS_H_ */ |