Skip to content

Commit

Permalink
Warn for bad input to CanvasFilter
Browse files Browse the repository at this point in the history
If the "filter" key to a new CanvasFilter is unsupported or empty it
will now warn the user in the console.
See discussion here: whatwg/html#6763

I'm out of ideas for how to test this as there appears to be no way to
catch the warning in javascript.

Bug: 1272819
Change-Id: I2847b5efd126e29bd3228a4de540671c21087539
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3296334
Reviewed-by: Fernando Serboncini <[email protected]>
Commit-Queue: Aaron Krajeski <[email protected]>
Cr-Commit-Position: refs/heads/main@{#961977}
NOKEYCHECK=True
GitOrigin-RevId: 3c24d94ae972621f005e42d6f74e0b6588fb44d5
  • Loading branch information
mysteryDate authored and copybara-github committed Jan 21, 2022
1 parent c04719c commit b8e5eda
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 19 deletions.
7 changes: 4 additions & 3 deletions blink/renderer/modules/canvas/canvas2d/canvas_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace blink {
CanvasFilter::CanvasFilter(FilterOperations filter_operations)
: filter_operations_(filter_operations) {}

CanvasFilter* CanvasFilter::Create(const V8CanvasFilterInput* init,
CanvasFilter* CanvasFilter::Create(ExecutionContext* execution_context,
const V8CanvasFilterInput* init,
ExceptionState& exception_state) {
HeapVector<ScriptValue> filter_array;

Expand All @@ -26,8 +27,8 @@ CanvasFilter* CanvasFilter::Create(const V8CanvasFilterInput* init,
}

FilterOperations filter_operations =
CanvasFilterOperationResolver::CreateFilterOperations(filter_array,
exception_state);
CanvasFilterOperationResolver::CreateFilterOperations(
execution_context, filter_array, exception_state);

return MakeGarbageCollected<CanvasFilter>(filter_operations);
}
Expand Down
3 changes: 2 additions & 1 deletion blink/renderer/modules/canvas/canvas2d/canvas_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class MODULES_EXPORT CanvasFilter final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();

public:
static CanvasFilter* Create(const V8CanvasFilterInput* init,
static CanvasFilter* Create(ExecutionContext* execution_context,
const V8CanvasFilterInput* init,
ExceptionState& exception_state);

explicit CanvasFilter(FilterOperations filter_operations);
Expand Down
2 changes: 1 addition & 1 deletion blink/renderer/modules/canvas/canvas2d/canvas_filter.idl
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ typedef (object or FrozenArray<object>) CanvasFilterInput;
Exposed=(Window,Worker,PaintWorklet), RuntimeEnabled=NewCanvas2DAPI
] interface CanvasFilter {

[RaisesException] constructor(CanvasFilterInput init);
[CallWith=ExecutionContext, RaisesException] constructor(CanvasFilterInput init);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_operation_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/svg/svg_enumeration_map.h"
#include "third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h"
#include "third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h"

namespace blink {

namespace {
int num_canvas_filter_errors_to_console_allowed_ = 64;

BlurFilterOperation* ResolveBlur(const Dictionary& blur_dict,
ExceptionState& exception_state) {
absl::optional<double> std_deviation =
Expand Down Expand Up @@ -278,6 +282,7 @@ TurbulenceFilterOperation* ResolveTurbulence(const Dictionary& dict,
} // namespace

FilterOperations CanvasFilterOperationResolver::CreateFilterOperations(
ExecutionContext* execution_context,
HeapVector<ScriptValue> filters,
ExceptionState& exception_state) {
FilterOperations operations;
Expand All @@ -286,15 +291,11 @@ FilterOperations CanvasFilterOperationResolver::CreateFilterOperations(
Dictionary filter_dict = Dictionary(filter);
absl::optional<String> name =
filter_dict.Get<IDLString>("filter", exception_state);
if (!name)
continue;

if (name == "gaussianBlur") {
if (auto* blur_operation = ResolveBlur(filter_dict, exception_state)) {
operations.Operations().push_back(blur_operation);
}
}
if (name == "colorMatrix") {
} else if (name == "colorMatrix") {
String type = filter_dict.Get<IDLString>("type", exception_state)
.value_or("matrix");
if (type == "hueRotate") {
Expand All @@ -317,24 +318,43 @@ FilterOperations CanvasFilterOperationResolver::CreateFilterOperations(
ResolveColorMatrix(filter_dict, exception_state)) {
operations.Operations().push_back(color_matrix_operation);
}
}
if (name == "convolveMatrix") {
} else if (name == "convolveMatrix") {
if (auto* convolve_operation =
ResolveConvolveMatrix(filter_dict, exception_state)) {
operations.Operations().push_back(convolve_operation);
}
}
if (name == "componentTransfer") {
} else if (name == "componentTransfer") {
if (auto* component_transfer_operation =
ResolveComponentTransfer(filter_dict, exception_state)) {
operations.Operations().push_back(component_transfer_operation);
}
}
if (name == "turbulence") {
} else if (name == "turbulence") {
if (auto* turbulence_operation =
ResolveTurbulence(filter_dict, exception_state)) {
operations.Operations().push_back(turbulence_operation);
}
} else {
num_canvas_filter_errors_to_console_allowed_--;
if (num_canvas_filter_errors_to_console_allowed_ < 0)
continue;
const String& message =
(!name.has_value())
? "CanvasFilters require key 'filter' to specify filter type."
: String::Format(
"\"%s\" is not among supported CanvasFilter types.",
name->Utf8().c_str());
execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::blink::ConsoleMessageSource::kRendering,
mojom::blink::ConsoleMessageLevel::kWarning, message));
if (num_canvas_filter_errors_to_console_allowed_ == 0) {
const String& message =
"CanvasFilter: too many errors, no more errors will be reported to "
"the console for this process.";
execution_context->AddConsoleMessage(
MakeGarbageCollected<ConsoleMessage>(
mojom::blink::ConsoleMessageSource::kRendering,
mojom::blink::ConsoleMessageLevel::kWarning, message));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ namespace blink {
// third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h but
// the input is a from a canvas filter object instead of a CSSValue.
// CanvasFilters are created in javascript by passing in dictionaries like so:
// ctx.filter = new CanvasFilter({blur: {stdDeviation: 5}});
// ctx.filter = new CanvasFilter({filter: "gaussianBlur", stdDeviation: 5});
// This class resolves these inputs into FilterOperations that can be used by
// CanvasRenderingContext2DState's GetFilter() functions.
class MODULES_EXPORT CanvasFilterOperationResolver {
STATIC_ONLY(CanvasFilterOperationResolver);

public:
static FilterOperations CreateFilterOperations(HeapVector<ScriptValue>,
ExceptionState&);
static FilterOperations CreateFilterOperations(
ExecutionContext* execution_context,
HeapVector<ScriptValue>,
ExceptionState&);
};

} // namespace blink
Expand Down

0 comments on commit b8e5eda

Please sign in to comment.