Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/CanvasUtils.h
Line
Count
Source (jump to first uncovered line)
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 "CanvasRenderingContextHelper.h"
10
#include "mozilla/CheckedInt.h"
11
#include "mozilla/dom/ToJSValue.h"
12
#include "jsapi.h"
13
#include "mozilla/FloatingPoint.h"
14
15
class nsIPrincipal;
16
17
namespace mozilla {
18
19
namespace dom {
20
class HTMLCanvasElement;
21
} // namespace dom
22
23
namespace CanvasUtils {
24
25
bool GetCanvasContextType(const nsAString& str, dom::CanvasContextType* const out_type);
26
27
// Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight]
28
29
inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h,
30
                            int32_t realWidth, int32_t realHeight) {
31
    CheckedInt32 checked_xmost  = CheckedInt32(x) + w;
32
    CheckedInt32 checked_ymost  = CheckedInt32(y) + h;
33
34
    return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
35
        checked_xmost.isValid() &&
36
        checked_xmost.value() <= realWidth &&
37
        checked_ymost.isValid() &&
38
        checked_ymost.value() <= realHeight;
39
}
40
41
// Flag aCanvasElement as write-only if drawing an image with aPrincipal
42
// onto it would make it such.
43
44
void DoDrawImageSecurityCheck(dom::HTMLCanvasElement *aCanvasElement,
45
                              nsIPrincipal *aPrincipal,
46
                              bool forceWriteOnly,
47
                              bool CORSUsed);
48
49
// Check if the context is chrome or has the permission to drawWindow
50
bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj);
51
52
// Check site-specific permission and display prompt if appropriate.
53
bool IsImageExtractionAllowed(nsIDocument *aDocument, JSContext *aCx, nsIPrincipal& aPrincipal);
54
55
// Make a double out of |v|, treating undefined values as 0.0 (for
56
// the sake of sparse arrays).  Return true iff coercion
57
// succeeded.
58
bool CoerceDouble(const JS::Value& v, double* d);
59
60
    /* Float validation stuff */
61
0
#define VALIDATE(_f)  if (!IsFinite(_f)) return false
62
63
0
inline bool FloatValidate (double f1) {
64
0
    VALIDATE(f1);
65
0
    return true;
66
0
}
67
68
0
inline bool FloatValidate (double f1, double f2) {
69
0
    VALIDATE(f1); VALIDATE(f2);
70
0
    return true;
71
0
}
72
73
inline bool FloatValidate (double f1, double f2, double f3) {
74
    VALIDATE(f1); VALIDATE(f2); VALIDATE(f3);
75
    return true;
76
}
77
78
inline bool FloatValidate (double f1, double f2, double f3, double f4) {
79
    VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4);
80
    return true;
81
}
82
83
inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5) {
84
    VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5);
85
    return true;
86
}
87
88
inline bool FloatValidate (double f1, double f2, double f3, double f4, double f5, double f6) {
89
    VALIDATE(f1); VALIDATE(f2); VALIDATE(f3); VALIDATE(f4); VALIDATE(f5); VALIDATE(f6);
90
    return true;
91
}
92
93
#undef VALIDATE
94
95
template<typename T>
96
nsresult
97
JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
98
                 nsTArray<T>& dashes)
99
{
100
    // The cap is pretty arbitrary.  16k should be enough for
101
    // anybody...
102
    static const uint32_t MAX_NUM_DASHES = 1 << 14;
103
104
    if (!patternArray.isPrimitive()) {
105
        JS::Rooted<JSObject*> obj(cx, patternArray.toObjectOrNull());
106
        uint32_t length;
107
        if (!JS_GetArrayLength(cx, obj, &length)) {
108
            // Not an array-like thing
109
            return NS_ERROR_INVALID_ARG;
110
        } else if (length > MAX_NUM_DASHES) {
111
            // Too many dashes in the pattern
112
            return NS_ERROR_ILLEGAL_VALUE;
113
        }
114
115
        bool haveNonzeroElement = false;
116
        for (uint32_t i = 0; i < length; ++i) {
117
            JS::Rooted<JS::Value> elt(cx);
118
            double d;
119
            if (!JS_GetElement(cx, obj, i, &elt)) {
120
                return NS_ERROR_FAILURE;
121
            }
122
            if (!(CoerceDouble(elt, &d) &&
123
                  FloatValidate(d) &&
124
                  d >= 0.0)) {
125
                // Pattern elements must be finite "numbers" >= 0.
126
                return NS_ERROR_INVALID_ARG;
127
            } else if (d > 0.0) {
128
                haveNonzeroElement = true;
129
            }
130
            if (!dashes.AppendElement(d, mozilla::fallible)) {
131
                return NS_ERROR_OUT_OF_MEMORY;
132
            }
133
        }
134
135
        if (dashes.Length() > 0 && !haveNonzeroElement) {
136
            // An all-zero pattern makes no sense.
137
            return NS_ERROR_ILLEGAL_VALUE;
138
        }
139
    } else if (!(patternArray.isUndefined() || patternArray.isNull())) {
140
        // undefined and null mean "reset to no dash".  Any other
141
        // random garbage is a type error.
142
        return NS_ERROR_INVALID_ARG;
143
    }
144
145
    return NS_OK;
146
}
147
148
template<typename T>
149
void
150
DashArrayToJSVal(nsTArray<T>& dashes,
151
                 JSContext* cx,
152
                 JS::MutableHandle<JS::Value> retval,
153
                 mozilla::ErrorResult& rv)
154
{
155
    if (dashes.IsEmpty()) {
156
        retval.setNull();
157
        return;
158
    }
159
    JS::Rooted<JS::Value> val(cx);
160
    if (!mozilla::dom::ToJSValue(cx, dashes, retval)) {
161
        rv.Throw(NS_ERROR_OUT_OF_MEMORY);
162
    }
163
}
164
165
} // namespace CanvasUtils
166
} // namespace mozilla
167
168
#endif /* _CANVASUTILS_H_ */