Skip to content

Commit ba6cbce

Browse files
mysteryDateChromium LUCI CQ
authored and
Chromium LUCI CQ
committed
Test outside of IDL conversions for CanvasFilter
From the discussion here (whatwg/html#6763) we need to explicitly test all possible types of inputs for filter attributes. Bug: 1201359 Change-Id: I5ef5905298a17310e4eb54c3c01ab8d6b7973737 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3320960 Reviewed-by: Yi Xu <[email protected]> Reviewed-by: Domenic Denicola <[email protected]> Commit-Queue: Aaron Krajeski <[email protected]> Cr-Commit-Position: refs/heads/main@{#951163}
1 parent 1aa4dbb commit ba6cbce

11 files changed

+233
-11
lines changed

third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,13 @@ ComponentTransferFunction GetComponentTransferFunction(
121121
const StringView& key,
122122
const Dictionary& filter,
123123
ExceptionState& exception_state) {
124+
ComponentTransferFunction result;
125+
// An earlier stage threw an error
126+
if (exception_state.HadException())
127+
return result;
124128
Dictionary transfer_dict;
125129
filter.Get(key, transfer_dict);
126130

127-
ComponentTransferFunction result;
128131
result.slope =
129132
transfer_dict.Get<IDLDouble>("slope", exception_state).value_or(1);
130133
result.intercept =
@@ -136,11 +139,6 @@ ComponentTransferFunction GetComponentTransferFunction(
136139
result.offset =
137140
transfer_dict.Get<IDLDouble>("offset", exception_state).value_or(0);
138141

139-
absl::optional<Vector<float>> table_values =
140-
transfer_dict.Get<IDLSequence<IDLFloat>>("tableValues", exception_state);
141-
if (table_values)
142-
result.table_values.AppendVector(table_values.value());
143-
144142
String type = transfer_dict.Get<IDLString>("type", exception_state)
145143
.value_or("identity");
146144
if (type == "identity")
@@ -154,6 +152,11 @@ ComponentTransferFunction GetComponentTransferFunction(
154152
else if (type == "discrete")
155153
result.type = FECOMPONENTTRANSFER_TYPE_DISCRETE;
156154

155+
absl::optional<Vector<float>> table_values =
156+
transfer_dict.Get<IDLSequence<IDLFloat>>("tableValues", exception_state);
157+
if (table_values)
158+
result.table_values.AppendVector(table_values.value());
159+
157160
return result;
158161
}
159162

third_party/blink/web_tests/external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ <h1>2d.filter.canvasFilterObject.blur.exceptions</h1>
2020
_addTest(function(canvas, ctx) {
2121

2222
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
23-
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
23+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
2424
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
25+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
26+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
27+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
2528

2629

2730
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<body>
2+
<canvas id="canvas" width="300" height="300"></canvas>
3+
</body>
4+
<script>
5+
var ctx = document.getElementById('canvas').getContext('2d');
6+
7+
// preserveAlpha for convolveMatrix is the only boolean so far implemented
8+
function drawWithConvolveFilter(x, y, preserveAlphaValue) {
9+
ctx.filter = new CanvasFilter({
10+
filter: "convolveMatrix",
11+
kernelMatrix: [[1, 0], [0, 1]],
12+
preserveAlpha: preserveAlphaValue,
13+
});
14+
ctx.fillRect(x, y, 30, 30);
15+
}
16+
17+
ctx.fillStyle = "rgba(255,0,255,0.5)";
18+
let x = 10;
19+
let y = 10;
20+
for (var i = 0; i < 6; i++) {
21+
drawWithConvolveFilter(x, y, true);
22+
x += 40;
23+
}
24+
y = 50;
25+
x = 10;
26+
for (var i = 0; i < 5; i++) {
27+
drawWithConvolveFilter(x, y, false);
28+
x += 40;
29+
}
30+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<head>
2+
<link rel="match" href="canvas-filter-boolean-conversion-expected.html">
3+
</head>
4+
<body>
5+
<canvas id="canvas" width="300" height="300"></canvas>
6+
</body>
7+
<script>
8+
// Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
9+
// as input to the CanvasFilter resolver when a bool is the intended result.
10+
var ctx = document.getElementById('canvas').getContext('2d');
11+
12+
// preserveAlpha for convolveMatrix is the only boolean so far implemented
13+
function drawWithConvolveFilter(x, y, preserveAlphaValue) {
14+
ctx.filter = new CanvasFilter({
15+
filter: "convolveMatrix",
16+
kernelMatrix: [[1, 0], [0, 1]],
17+
preserveAlpha: preserveAlphaValue,
18+
});
19+
ctx.fillRect(x, y, 30, 30);
20+
}
21+
22+
const trueTestCases = [
23+
true,
24+
{ valueOf() { return false; }},
25+
"foo",
26+
1,
27+
{},
28+
[]
29+
];
30+
31+
const falseTestCases = [
32+
false,
33+
"",
34+
0,
35+
null,
36+
undefined,
37+
];
38+
39+
ctx.fillStyle = "rgba(255,0,255,0.5)";
40+
let x = 10;
41+
let y = 10;
42+
for (tc of trueTestCases) {
43+
drawWithConvolveFilter(x, y, tc);
44+
x += 40;
45+
}
46+
y = 50;
47+
x = 10;
48+
for (tc of falseTestCases) {
49+
drawWithConvolveFilter(x, y, tc);
50+
x += 40;
51+
}
52+
53+
ctx.filter = new CanvasFilter({
54+
filter: "componentTransfer",
55+
funcR: {type: "discrete", tableValues: 0.5},
56+
});
57+
ctx.fillRect(10, 10, 100, 100);
58+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<body>
2+
<canvas id="canvas" width="300" height="300"></canvas>
3+
</body>
4+
<script>
5+
var ctx = document.getElementById('canvas').getContext('2d');
6+
// Null and False both evaluate to zero
7+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
8+
ctx.fillRect(10, 10, 30, 30);
9+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
10+
ctx.fillRect(50, 10, 30, 30);
11+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 0});
12+
ctx.fillRect(90, 10, 30, 30);
13+
// True evaluates to one
14+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 1});
15+
ctx.fillRect(130, 10, 30, 30);
16+
// String, Number and Object should all work
17+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
18+
ctx.fillRect(10, 50, 30, 30);
19+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
20+
ctx.fillRect(50, 50, 30, 30);
21+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
22+
ctx.fillRect(90, 50, 30, 30);
23+
// Valid sequence
24+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
25+
ctx.fillRect(130, 50, 30, 30);
26+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<head>
2+
<link rel="match" href="canvas-filter-long-conversion-expected.html">
3+
</head>
4+
<body>
5+
<canvas id="canvas" width="300" height="300"></canvas>
6+
</body>
7+
<script>
8+
// Test the built-in ECMAScript types Undefined, Null, Boolean, String, Number, and Object
9+
// as input to the CanvasFilter resolver when a long is the intended result.
10+
var ctx = document.getElementById('canvas').getContext('2d');
11+
12+
// Null, False and [] evaluate to zero
13+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: null});
14+
ctx.fillRect(10, 10, 30, 30);
15+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: false});
16+
ctx.fillRect(50, 10, 30, 30);
17+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: []});
18+
ctx.fillRect(90, 10, 30, 30);
19+
// True evaluates to one
20+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: true});
21+
ctx.fillRect(130, 10, 30, 30);
22+
// String, Number and Object should all work
23+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "5"});
24+
ctx.fillRect(10, 50, 30, 30);
25+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
26+
ctx.fillRect(50, 50, 30, 30);
27+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: { valueOf() { return 5; }}});
28+
ctx.fillRect(90, 50, 30, 30);
29+
// Valid sequence
30+
ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [5]});
31+
ctx.fillRect(130, 50, 30, 30);
32+
33+
// Undefined and other inputs that throw exceptions are tested in:
34+
// html/canvas/element/filters/2d.filter.canvasFilterObject.blur.exceptions.html
35+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE html>
2+
<title>Canvas test: canvas-filter-sequence-conversion</title>
3+
<script src="/resources/testharness.js"></script>
4+
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/html/canvas/resources/canvas-tests.js"></script>
6+
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
7+
<body class="show_output">
8+
9+
<h1>canvas-filter-sequence-conversion</h1>
10+
<p class="desc">Test converting types into sequences</p>
11+
12+
13+
<p class="output">Actual output:</p>
14+
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
15+
16+
<ul id="d"></ul>
17+
<script>
18+
var t = async_test("Test pixels on CanvasFilter() various inputs to tableValues (which is a sequence)");
19+
_addTest(function(canvas, ctx) {
20+
21+
// Inputs to parameters that are expecting sequence<long>. Results are either the value of the
22+
// red pixel drawing using the resultant filter or that we expect this input to throw an error.
23+
const testCases = [
24+
{input: [], result: 0},
25+
{input: [0.5], result: 127},
26+
{input: ["0.5"], result: 127},
27+
{input: 1, result: "throws"},
28+
{input: {}, result: "throws"},
29+
{input: false, result: "throws"},
30+
{input: true, result: "throws"},
31+
{input: NaN, result: "throws"},
32+
{input: { valueOf() { return [1]; }}, result: "throws"},
33+
];
34+
35+
// A simple filter that just overrides the red channel if successful.
36+
function makeFilter(value) {
37+
return new CanvasFilter({
38+
filter: "componentTransfer",
39+
funcR: {type: "table", tableValues: value}
40+
});
41+
}
42+
43+
for (const tc of testCases) {
44+
if (tc.result === "throws") {
45+
assert_throws_js(TypeError, function(){ makeFilter(tc.input) });
46+
} else {
47+
ctx.reset();
48+
ctx.filter = makeFilter(tc.input);
49+
ctx.fillRect(0, 0, 100, 100);
50+
_assertPixelApprox(canvas, 5, 5, tc.result,0,0,255, "5,5", `${tc.result},0,0,255`, 2);
51+
}
52+
}
53+
t.done();
54+
});
55+
</script>

third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ <h1>2d.filter.canvasFilterObject.blur.exceptions</h1>
2121
var ctx = offscreenCanvas.getContext('2d');
2222

2323
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
24-
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
24+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
2525
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
26+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
27+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
28+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
2629
t.done();
2730

2831
});

third_party/blink/web_tests/external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.blur.exceptions.worker.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ var offscreenCanvas = new OffscreenCanvas(100, 50);
1717
var ctx = offscreenCanvas.getContext('2d');
1818

1919
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur"}); });
20-
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null}); });
20+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined}); });
2121
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"}); });
22+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]}); });
23+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN}); });
24+
assert_throws_js(TypeError, function() { ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}}); });
2225
t.done();
2326

2427
});

third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/filters.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@
6161
desc: Test exceptions on CanvasFilter() blur.object
6262
code: |
6363
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur"});
64-
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null});
64+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined});
6565
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"});
66+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]});
67+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN});
68+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}});
6669
6770
- name: 2d.filter.canvasFilterObject.colorMatrix
6871
desc: Test the functionality of ColorMatrix filters in CanvasFilter objects

third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/filters.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828
desc: Test exceptions on CanvasFilter() blur.object
2929
code: |
3030
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur"});
31-
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDevation: null});
31+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: undefined});
3232
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: "foo"});
33+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: [1,2]});
34+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: NaN});
35+
@assert throws TypeError ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: {}});
3336
t.done();
3437
3538
- name: 2d.filter.canvasFilterObject.colorMatrix

0 commit comments

Comments
 (0)