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

Skip to content

Commit 0065bfc

Browse files
Test that validate_cycler does not execute code passed in
1 parent 09b61ac commit 0065bfc

2 files changed

Lines changed: 12 additions & 8 deletions

File tree

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ def _convert_validator_spec(key, conv):
11791179
"axes.formatter.offset_threshold": validate_int,
11801180
"axes.unicode_minus": validate_bool,
11811181
# This entry can be either a cycler object or a string repr of a
1182-
# cycler-object, which gets eval()'ed to create the object.
1182+
# cycler-object, which is parsed safely via AST.
11831183
"axes.prop_cycle": validate_cycler,
11841184
# If "data", axes limits are set close to the data.
11851185
# If "round_numbers" axes limits are set to the nearest round numbers.

lib/matplotlib/tests/test_rcparams.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,9 @@ def generate_validator_testcases(valid):
276276
(cycler(mew=[2, 5]),
277277
cycler('markeredgewidth', [2, 5])),
278278
),
279-
# This is *so* incredibly important: validate_cycler() eval's
280-
# an arbitrary string! I think I have it locked down enough,
281-
# and that is what this is testing.
282-
# TODO: Note that these tests are actually insufficient, as it may
283-
# be that they raised errors, but still did an action prior to
284-
# raising the exception. We should devise some additional tests
285-
# for that...
279+
# validate_cycler() parses an arbitrary string using a safe
280+
# AST-based parser (no eval). These tests verify that only valid
281+
# cycler expressions are accepted.
286282
'fail': ((4, ValueError), # Gotta be a string or Cycler object
287283
('cycler("bleh, [])', ValueError), # syntax error
288284
('Cycler("linewidth", [1, 2, 3])',
@@ -464,6 +460,14 @@ def test_validate_cycler_bad_color_string():
464460
validate_cycler("cycler('color', 'foo')")
465461

466462

463+
def test_validate_cycler_no_code_execution():
464+
# List comprehensions are arbitrary code. The old eval()-based parser
465+
# would execute this successfully, but the AST-based parser rejects it
466+
# because only literal values are allowed in cycler arguments.
467+
with pytest.raises(ValueError):
468+
validate_cycler("cycler('color', [x for x in ['r', 'g', 'b']])")
469+
470+
467471
@pytest.mark.parametrize('weight, parsed_weight', [
468472
('bold', 'bold'),
469473
('BOLD', ValueError), # weight is case-sensitive

0 commit comments

Comments
 (0)