diff --git a/content/canvas/src/CustomQS_Canvas.h b/content/canvas/src/CustomQS_Canvas.h new file mode 100644 index 000000000000..731b3032279e --- /dev/null +++ b/content/canvas/src/CustomQS_Canvas.h @@ -0,0 +1,52 @@ +/* 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/. */ + +#ifndef CustomQS_Canvas_h +#define CustomQS_Canvas_h + +#include "jsapi.h" + +static bool +GetPositiveInt(JSContext* cx, JSObject& obj, const char* name, uint32_t* out) +{ + JS::Value temp; + int32_t signedInt; + if (!JS_GetProperty(cx, &obj, name, &temp) || + !JS_ValueToECMAInt32(cx, temp, &signedInt)) { + return false; + } + if (signedInt <= 0) { + return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR); + } + *out = uint32_t(signedInt); + return true; +} + +static bool +GetImageData(JSContext* cx, const JS::Value& imageData, + uint32_t* width, uint32_t* height, JS::Anchor* array) +{ + if (!imageData.isObject()) { + return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR); + } + + JSObject& dataObject = imageData.toObject(); + + if (!GetPositiveInt(cx, dataObject, "width", width) || + !GetPositiveInt(cx, dataObject, "height", height)) { + return false; + } + + JS::Value temp; + if (!JS_GetProperty(cx, &dataObject, "data", &temp)) { + return false; + } + if (!temp.isObject()) { + return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR); + } + array->set(&temp.toObject()); + return true; +} + +#endif // CustomQS_Canvas_h diff --git a/content/canvas/src/CustomQS_Canvas2D.h b/content/canvas/src/CustomQS_Canvas2D.h index d935457b3e96..89cd4d012d8d 100644 --- a/content/canvas/src/CustomQS_Canvas2D.h +++ b/content/canvas/src/CustomQS_Canvas2D.h @@ -42,6 +42,7 @@ #include "nsIDOMCanvasRenderingContext2D.h" #include "CheckedInt.h" #include "nsMathUtils.h" +#include "CustomQS_Canvas.h" #include "jsapi.h" @@ -219,32 +220,6 @@ CreateImageData(JSContext* cx, return true; } -static bool -GetImageDataDimensions(JSContext *cx, JSObject *dataObject, uint32_t *width, uint32_t *height) -{ - jsval temp; - int32_t wi, hi; - - // Need to check that dataObject is ImageData object. That's hard for the moment - // because they're just vanilla objects in our implementation. - // Let's guess, if the object has valid width and height then it's suitable - // for this operation. - if (!JS_GetProperty(cx, dataObject, "width", &temp) || - !JS_ValueToECMAInt32(cx, temp, &wi)) - return false; - - if (!JS_GetProperty(cx, dataObject, "height", &temp) || - !JS_ValueToECMAInt32(cx, temp, &hi)) - return false; - - if (wi <= 0 || hi <= 0) - return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR); - - *width = uint32_t(wi); - *height = uint32_t(hi); - return true; -} - static JSBool nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsval *vp) { @@ -258,16 +233,11 @@ nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsv jsval *argv = JS_ARGV(cx, vp); if (argc == 1) { - // The specification asks to throw NOT_SUPPORTED if first argument is NULL, - // An object is expected, so throw an exception for all primitives. - if (JSVAL_IS_PRIMITIVE(argv[0])) - return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR); - - JSObject *dataObject = JSVAL_TO_OBJECT(argv[0]); - uint32_t data_width, data_height; - if (!GetImageDataDimensions(cx, dataObject, &data_width, &data_height)) + JS::Anchor darray; + if (!GetImageData(cx, argv[0], &data_width, &data_height, &darray)) { return false; + } return CreateImageData(cx, data_width, data_height, NULL, 0, 0, vp); } @@ -370,10 +340,11 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval jsval *argv = JS_ARGV(cx, vp); - if (JSVAL_IS_PRIMITIVE(argv[0])) - return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR); - - JSObject *dataObject = JSVAL_TO_OBJECT(argv[0]); + uint32_t w, h; + JS::Anchor darray; + if (!GetImageData(cx, argv[0], &w, &h, &darray)) { + return false; + } double xd, yd; if (!JS_ValueToNumber(cx, argv[1], &xd) || @@ -388,13 +359,6 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval int32_t x = JS_DoubleToInt32(xd); int32_t y = JS_DoubleToInt32(yd); - // Grab width, height, and the dense array from the dataObject. - JS::AutoValueRooter tv(cx); - - uint32_t w, h; - if (!GetImageDataDimensions(cx, dataObject, &w, &h)) - return JS_FALSE; - // the optional dirty rect bool hasDirtyRect = false; int32_t dirtyX = 0, @@ -424,24 +388,16 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval hasDirtyRect = true; } - if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr())) - return JS_FALSE; - - if (JSVAL_IS_PRIMITIVE(tv.jsval_value())) - return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR); - - JSObject *darray = JSVAL_TO_OBJECT(tv.jsval_value()); - JS::AutoValueRooter tsrc_tvr(cx); JSObject *tsrc = NULL; - if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] || - js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED]) + if (js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] || + js::GetObjectClass(darray.get()) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED]) { - tsrc = js::TypedArray::getTypedArray(darray); - } else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) { + tsrc = darray.get(); + } else if (JS_IsArrayObject(cx, darray.get()) || js_IsTypedArray(darray.get())) { // ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array - JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray); + JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_UINT8, darray.get()); if (!nobj) return JS_FALSE; diff --git a/content/canvas/src/CustomQS_WebGL.h b/content/canvas/src/CustomQS_WebGL.h index 6d21d6e08a43..9a88e035a18a 100644 --- a/content/canvas/src/CustomQS_WebGL.h +++ b/content/canvas/src/CustomQS_WebGL.h @@ -42,6 +42,7 @@ #include "jsapi.h" #include "jstypedarray.h" +#include "CustomQS_Canvas.h" #define GET_INT32_ARG(var, index) \ int32_t var; \ @@ -479,33 +480,16 @@ TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object) // Failed to interpret object as an Element, now try to interpret it as // ImageData. - JSObject* imageData = &object->toObject(); - - jsval js_width, js_height, js_data; - if (!JS_GetProperty(cx, imageData, "width", &js_width) || - !JS_GetProperty(cx, imageData, "height", &js_height) || - !JS_GetProperty(cx, imageData, "data", &js_data)) { + uint32_t int_width, int_height; + JS::Anchor obj_data; + if (!GetImageData(cx, *object, &int_width, &int_height, &obj_data)) { return false; } - if (js_width == JSVAL_VOID || - js_height == JSVAL_VOID || - !js_data.isObject()) - { - return xpc_qsThrow(cx, NS_ERROR_FAILURE); - } - int32_t int_width, int_height; - JSObject *obj_data = JSVAL_TO_OBJECT(js_data); - if (!JS_ValueToECMAInt32(cx, js_width, &int_width) || - !JS_ValueToECMAInt32(cx, js_height, &int_height)) - { - return false; - } - if (!js_IsTypedArray(obj_data)) - { + if (!js_IsTypedArray(obj_data.get())) { return xpc_qsThrow(cx, NS_ERROR_FAILURE); } - nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data); + nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data.get()); return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv); } diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index 61c751271125..97388e6c53d2 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -49,6 +49,7 @@ LIBRARY_NAME = gkconcvs_s LIBXUL_LIBRARY = 1 EXPORTS = \ + CustomQS_Canvas.h \ CustomQS_Canvas2D.h \ CustomQS_WebGL.h \ $(NULL) diff --git a/content/canvas/test/test_canvas.html b/content/canvas/test/test_canvas.html index 6df50da8110e..45eb618aed51 100644 --- a/content/canvas/test/test_canvas.html +++ b/content/canvas/test/test_canvas.html @@ -7681,7 +7681,7 @@ var _thrown = undefined; try {

Canvas test: 2d.imageData.create1.zero - bug 630040

- +

FAIL (fallback content)