Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsScriptableRegion.h"
8 #include <stdint.h> // for uint32_t
9 #include <sys/types.h> // for int32_t
10 #include "js/RootingAPI.h" // for Rooted
11 #include "js/Value.h" // for INT_TO_JSVAL, etc
12 #include "jsapi.h" // for JS_DefineElement, etc
13 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
14 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
15 #include "nsID.h"
16 #include "nsRect.h" // for nsIntRect
17 #include "nscore.h" // for NS_IMETHODIMP
19 class JSObject;
20 struct JSContext;
22 nsScriptableRegion::nsScriptableRegion()
23 {
24 }
26 NS_IMPL_ISUPPORTS(nsScriptableRegion, nsIScriptableRegion)
28 NS_IMETHODIMP nsScriptableRegion::Init()
29 {
30 return NS_OK;
31 }
33 NS_IMETHODIMP nsScriptableRegion::SetToRegion(nsIScriptableRegion *aRegion)
34 {
35 aRegion->GetRegion(&mRegion);
36 return NS_OK;
37 }
39 NS_IMETHODIMP nsScriptableRegion::SetToRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
40 {
41 mRegion = nsIntRect(aX, aY, aWidth, aHeight);
42 return NS_OK;
43 }
45 NS_IMETHODIMP nsScriptableRegion::IntersectRegion(nsIScriptableRegion *aRegion)
46 {
47 nsIntRegion region;
48 aRegion->GetRegion(®ion);
49 mRegion.And(mRegion, region);
50 return NS_OK;
51 }
53 NS_IMETHODIMP nsScriptableRegion::IntersectRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
54 {
55 mRegion.And(mRegion, nsIntRect(aX, aY, aWidth, aHeight));
56 return NS_OK;
57 }
59 NS_IMETHODIMP nsScriptableRegion::UnionRegion(nsIScriptableRegion *aRegion)
60 {
61 nsIntRegion region;
62 aRegion->GetRegion(®ion);
63 mRegion.Or(mRegion, region);
64 return NS_OK;
65 }
67 NS_IMETHODIMP nsScriptableRegion::UnionRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
68 {
69 mRegion.Or(mRegion, nsIntRect(aX, aY, aWidth, aHeight));
70 return NS_OK;
71 }
73 NS_IMETHODIMP nsScriptableRegion::SubtractRegion(nsIScriptableRegion *aRegion)
74 {
75 nsIntRegion region;
76 aRegion->GetRegion(®ion);
77 mRegion.Sub(mRegion, region);
78 return NS_OK;
79 }
81 NS_IMETHODIMP nsScriptableRegion::SubtractRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight)
82 {
83 mRegion.Sub(mRegion, nsIntRect(aX, aY, aWidth, aHeight));
84 return NS_OK;
85 }
87 NS_IMETHODIMP nsScriptableRegion::IsEmpty(bool *isEmpty)
88 {
89 *isEmpty = mRegion.IsEmpty();
90 return NS_OK;
91 }
93 NS_IMETHODIMP nsScriptableRegion::IsEqualRegion(nsIScriptableRegion *aRegion, bool *isEqual)
94 {
95 nsIntRegion region;
96 aRegion->GetRegion(®ion);
97 *isEqual = mRegion.IsEqual(region);
98 return NS_OK;
99 }
101 NS_IMETHODIMP nsScriptableRegion::GetBoundingBox(int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight)
102 {
103 nsIntRect boundRect = mRegion.GetBounds();
104 *aX = boundRect.x;
105 *aY = boundRect.y;
106 *aWidth = boundRect.width;
107 *aHeight = boundRect.height;
108 return NS_OK;
109 }
111 NS_IMETHODIMP nsScriptableRegion::Offset(int32_t aXOffset, int32_t aYOffset)
112 {
113 mRegion.MoveBy(aXOffset, aYOffset);
114 return NS_OK;
115 }
117 NS_IMETHODIMP nsScriptableRegion::ContainsRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool *containsRect)
118 {
119 *containsRect = mRegion.Contains(nsIntRect(aX, aY, aWidth, aHeight));
120 return NS_OK;
121 }
124 NS_IMETHODIMP nsScriptableRegion::GetRegion(nsIntRegion* outRgn)
125 {
126 *outRgn = mRegion;
127 return NS_OK;
128 }
130 NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS::Value> aRects)
131 {
132 uint32_t numRects = mRegion.GetNumRects();
134 if (!numRects) {
135 aRects.setNull();
136 return NS_OK;
137 }
139 JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4));
140 if (!destArray) {
141 return NS_ERROR_OUT_OF_MEMORY;
142 }
144 aRects.setObject(*destArray);
146 uint32_t n = 0;
147 nsIntRegionRectIterator iter(mRegion);
148 const nsIntRect *rect;
150 while ((rect = iter.Next())) {
151 if (!JS_DefineElement(aCx, destArray, n, INT_TO_JSVAL(rect->x), nullptr, nullptr, JSPROP_ENUMERATE) ||
152 !JS_DefineElement(aCx, destArray, n + 1, INT_TO_JSVAL(rect->y), nullptr, nullptr, JSPROP_ENUMERATE) ||
153 !JS_DefineElement(aCx, destArray, n + 2, INT_TO_JSVAL(rect->width), nullptr, nullptr, JSPROP_ENUMERATE) ||
154 !JS_DefineElement(aCx, destArray, n + 3, INT_TO_JSVAL(rect->height), nullptr, nullptr, JSPROP_ENUMERATE)) {
155 return NS_ERROR_FAILURE;
156 }
157 n += 4;
158 }
160 return NS_OK;
161 }