Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 545f974

Browse files
Restrict webagg toolbar events to the actual toolbar items
1 parent a01f57d commit 545f974

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

lib/matplotlib/backends/backend_webagg_core.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,11 @@ def _handle_key(self, event):
349349
handle_key_press = handle_key_release = _handle_key
350350

351351
def handle_toolbar_button(self, event):
352-
# TODO: Be more suspicious of the input
353-
getattr(self.toolbar, event['name'])()
352+
name = event['name']
353+
allowed = {item[3] for item in self.toolbar.toolitems if item[3] is not None}
354+
if name not in allowed:
355+
return
356+
getattr(self.toolbar, name)()
354357

355358
def handle_refresh(self, event):
356359
if self.manager:

lib/matplotlib/tests/test_backend_webagg.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import os
22
import sys
3+
from unittest.mock import MagicMock
34
import pytest
45

56
import matplotlib.backends.backend_webagg_core
7+
from matplotlib.backends.backend_webagg_core import (
8+
FigureCanvasWebAggCore, NavigationToolbar2WebAgg,
9+
)
610
from matplotlib.testing import subprocess_run_for_testing
711

812

@@ -30,3 +34,22 @@ def test_webagg_fallback(backend):
3034
def test_webagg_core_no_toolbar():
3135
fm = matplotlib.backends.backend_webagg_core.FigureManagerWebAgg
3236
assert fm._toolbar2_class is None
37+
38+
39+
def test_toolbar_button_dispatch_allowlist():
40+
"""Only declared toolbar items should be dispatched."""
41+
fig = MagicMock()
42+
canvas = FigureCanvasWebAggCore(fig)
43+
canvas.toolbar = MagicMock(spec=NavigationToolbar2WebAgg)
44+
canvas.toolbar.toolitems = NavigationToolbar2WebAgg.toolitems
45+
46+
# Valid toolbar action should be dispatched.
47+
canvas.handle_toolbar_button({'name': 'home'})
48+
canvas.toolbar.home.assert_called_once()
49+
50+
# Invalid names should be silently ignored.
51+
canvas.toolbar.reset_mock()
52+
canvas.handle_toolbar_button({'name': '__init__'})
53+
canvas.handle_toolbar_button({'name': 'not_a_real_button'})
54+
# No methods should have been called.
55+
assert canvas.toolbar.method_calls == []

0 commit comments

Comments
 (0)