summaryrefslogtreecommitdiff
path: root/dom/canvas
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2017-09-27 11:06:31 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-02-02 19:38:38 +0100
commit8d29182cf055a03b37475f65a70b6abf321f96d9 (patch)
treeb54fd74458706e5aad149d01d9dde2b57fd8a2b7 /dom/canvas
parent100db2d197aac98e3e9e0f59e4cbe7d902373cba (diff)
downloaduxp-8d29182cf055a03b37475f65a70b6abf321f96d9.tar.gz
Add canvas data poisoning option.
Tag #61.
Diffstat (limited to 'dom/canvas')
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp73
1 files changed, 59 insertions, 14 deletions
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 2ed39627e8..b0a430fe41 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -68,6 +68,8 @@
#include "CanvasImageCache.h"
#include <algorithm>
+#include <stdlib.h>
+#include <time.h>
#include "jsapi.h"
#include "jsfriendapi.h"
@@ -2083,6 +2085,18 @@ CanvasRenderingContext2D::GetInputStream(const char* aMimeType,
return NS_ERROR_FAILURE;
}
+ bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
+ if (PoisonData) {
+ srand(time(NULL));
+ // Image buffer is always a packed BGRA array (BGRX -> BGR[FF])
+ // so always 4-byte pixels.
+ // GetImageBuffer => SurfaceToPackedBGRA [=> ConvertBGRXToBGRA]
+ for (int32_t j = 0; j < mWidth * mHeight * 4; ++j) {
+ if (imageBuffer[j] !=0 && imageBuffer[j] != 255)
+ imageBuffer[j] += rand() % 3 - 1;
+ }
+ }
+
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
format, encoder, aEncoderOptions,
aStream);
@@ -5698,6 +5712,14 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
return imageData.forget();
}
+inline uint8_t PoisonValue(uint8_t v)
+{
+ if (v==0 || v==255)
+ return v; //don't fuzz edges to prevent overflow/underflow
+
+ return v + rand() %3 -1;
+}
+
nsresult
CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
int32_t aX,
@@ -5712,6 +5734,10 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
MOZ_ASSERT(aWidth && aHeight);
+ bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
+ if (PoisonData)
+ srand(time(NULL));
+
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.isValid()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
@@ -5784,21 +5810,31 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
uint8_t* dst = data + dstWriteRect.y * (aWidth * 4) + dstWriteRect.x * 4;
+ uint8_t a,r,g,b;
+
if (mOpaque) {
for (int32_t j = 0; j < dstWriteRect.height; ++j) {
for (int32_t i = 0; i < dstWriteRect.width; ++i) {
// XXX Is there some useful swizzle MMX we can use here?
#if MOZ_LITTLE_ENDIAN
- uint8_t b = *src++;
- uint8_t g = *src++;
- uint8_t r = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
src++;
#else
src++;
- uint8_t r = *src++;
- uint8_t g = *src++;
- uint8_t b = *src++;
+ r = *src++;
+ g = *src++;
+ b = *src++;
#endif
+
+ // Poison data for trackers if enabled
+ if (PoisonData) {
+ PoisonValue(r);
+ PoisonValue(g);
+ PoisonValue(b);
+ }
+
*dst++ = r;
*dst++ = g;
*dst++ = b;
@@ -5812,16 +5848,25 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
for (int32_t i = 0; i < dstWriteRect.width; ++i) {
// XXX Is there some useful swizzle MMX we can use here?
#if MOZ_LITTLE_ENDIAN
- uint8_t b = *src++;
- uint8_t g = *src++;
- uint8_t r = *src++;
- uint8_t a = *src++;
+ b = *src++;
+ g = *src++;
+ r = *src++;
+ a = *src++;
#else
- uint8_t a = *src++;
- uint8_t r = *src++;
- uint8_t g = *src++;
- uint8_t b = *src++;
+ a = *src++;
+ r = *src++;
+ g = *src++;
+ b = *src++;
#endif
+
+ // Poison data for trackers if enabled
+ if (PoisonData) {
+ PoisonValue(a);
+ PoisonValue(r);
+ PoisonValue(g);
+ PoisonValue(b);
+ }
+
// Convert to non-premultiplied color
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];