1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/canvas/src/CanvasUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef _CANVASUTILS_H_ 1.10 +#define _CANVASUTILS_H_ 1.11 + 1.12 +#include "mozilla/CheckedInt.h" 1.13 +#include "mozilla/dom/ToJSValue.h" 1.14 +#include "jsapi.h" 1.15 + 1.16 +class nsIPrincipal; 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 +namespace gfx { 1.21 +class Matrix; 1.22 +} 1.23 + 1.24 +namespace dom { 1.25 +class HTMLCanvasElement; 1.26 +} 1.27 + 1.28 +namespace CanvasUtils { 1.29 + 1.30 + 1.31 +// Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight] 1.32 + 1.33 +inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h, 1.34 + int32_t realWidth, int32_t realHeight) { 1.35 + CheckedInt32 checked_xmost = CheckedInt32(x) + w; 1.36 + CheckedInt32 checked_ymost = CheckedInt32(y) + h; 1.37 + 1.38 + return w >= 0 && h >= 0 && x >= 0 && y >= 0 && 1.39 + checked_xmost.isValid() && 1.40 + checked_xmost.value() <= realWidth && 1.41 + checked_ymost.isValid() && 1.42 + checked_ymost.value() <= realHeight; 1.43 +} 1.44 + 1.45 +// Flag aCanvasElement as write-only if drawing an image with aPrincipal 1.46 +// onto it would make it such. 1.47 + 1.48 +void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement, 1.49 + nsIPrincipal *aPrincipal, 1.50 + bool forceWriteOnly, 1.51 + bool CORSUsed); 1.52 + 1.53 +bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx); 1.54 + 1.55 +// Make a double out of |v|, treating undefined values as 0.0 (for 1.56 +// the sake of sparse arrays). Return true iff coercion 1.57 +// succeeded. 1.58 +bool CoerceDouble(JS::Value v, double* d); 1.59 + 1.60 + /* Float validation stuff */ 1.61 +#define VALIDATE(_f) if (!NS_finite(_f)) return false 1.62 + 1.63 +inline bool FloatValidate (double f1) { 1.64 + VALIDATE(f1); 1.65 + return true; 1.66 +} 1.67 + 1.68 +inline bool FloatValidate (double f1, double f2) { 1.69 + VALIDATE(f1); VALIDATE(f2); 1.70 + return true; 1.71 +} 1.72 + 1.73 +inline bool FloatValidate (double f1, double f2, double f3) { 1.74 + VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); 1.75 + return true; 1.76 +} 1.77 + 1.78 +inline bool FloatValidate (double f1, double f2, double f3, double f4) { 1.79 + VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); 1.80 + return true; 1.81 +} 1.82 + 1.83 +inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5) { 1.84 + VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5); 1.85 + return true; 1.86 +} 1.87 + 1.88 +inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5, double f6) { 1.89 + VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5); VALIDATE(f6); 1.90 + return true; 1.91 +} 1.92 + 1.93 +#undef VALIDATE 1.94 + 1.95 +template<typename T> 1.96 +nsresult 1.97 +JSValToDashArray(JSContext* cx, const JS::Value& val, 1.98 + FallibleTArray<T>& dashArray); 1.99 + 1.100 +template<typename T> 1.101 +JS::Value 1.102 +DashArrayToJSVal(FallibleTArray<T>& dashArray, 1.103 + JSContext* cx, mozilla::ErrorResult& rv); 1.104 + 1.105 +template<typename T> 1.106 +nsresult 1.107 +JSValToDashArray(JSContext* cx, const JS::Value& patternArray, 1.108 + FallibleTArray<T>& dashes) 1.109 +{ 1.110 + // The cap is pretty arbitrary. 16k should be enough for 1.111 + // anybody... 1.112 + static const uint32_t MAX_NUM_DASHES = 1 << 14; 1.113 + 1.114 + if (!JSVAL_IS_PRIMITIVE(patternArray)) { 1.115 + JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(patternArray)); 1.116 + uint32_t length; 1.117 + if (!JS_GetArrayLength(cx, obj, &length)) { 1.118 + // Not an array-like thing 1.119 + return NS_ERROR_INVALID_ARG; 1.120 + } else if (length > MAX_NUM_DASHES) { 1.121 + // Too many dashes in the pattern 1.122 + return NS_ERROR_ILLEGAL_VALUE; 1.123 + } 1.124 + 1.125 + bool haveNonzeroElement = false; 1.126 + for (uint32_t i = 0; i < length; ++i) { 1.127 + JS::Rooted<JS::Value> elt(cx); 1.128 + double d; 1.129 + if (!JS_GetElement(cx, obj, i, &elt)) { 1.130 + return NS_ERROR_FAILURE; 1.131 + } 1.132 + if (!(CoerceDouble(elt, &d) && 1.133 + FloatValidate(d) && 1.134 + d >= 0.0)) { 1.135 + // Pattern elements must be finite "numbers" >= 0. 1.136 + return NS_ERROR_INVALID_ARG; 1.137 + } else if (d > 0.0) { 1.138 + haveNonzeroElement = true; 1.139 + } 1.140 + if (!dashes.AppendElement(d)) { 1.141 + return NS_ERROR_OUT_OF_MEMORY; 1.142 + } 1.143 + } 1.144 + 1.145 + if (dashes.Length() > 0 && !haveNonzeroElement) { 1.146 + // An all-zero pattern makes no sense. 1.147 + return NS_ERROR_ILLEGAL_VALUE; 1.148 + } 1.149 + } else if (!(JSVAL_IS_VOID(patternArray) || JSVAL_IS_NULL(patternArray))) { 1.150 + // undefined and null mean "reset to no dash". Any other 1.151 + // random garbage is a type error. 1.152 + return NS_ERROR_INVALID_ARG; 1.153 + } 1.154 + 1.155 + return NS_OK; 1.156 +} 1.157 + 1.158 +template<typename T> 1.159 +void 1.160 +DashArrayToJSVal(FallibleTArray<T>& dashes, 1.161 + JSContext* cx, 1.162 + JS::MutableHandle<JS::Value> retval, 1.163 + mozilla::ErrorResult& rv) 1.164 +{ 1.165 + if (dashes.IsEmpty()) { 1.166 + retval.setNull(); 1.167 + return; 1.168 + } 1.169 + JS::Rooted<JS::Value> val(cx); 1.170 + if (!mozilla::dom::ToJSValue(cx, dashes, retval)) { 1.171 + rv.Throw(NS_ERROR_OUT_OF_MEMORY); 1.172 + } 1.173 +} 1.174 + 1.175 +} 1.176 +} 1.177 + 1.178 +#endif /* _CANVASUTILS_H_ */