Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dont crash due to invalid var() values #977

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 33 additions & 10 deletions weasyprint/css/computed_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
from ..urls import get_link_attribute
from .properties import INHERITED, INITIAL_VALUES, Dimension
from .utils import (
ANGLE_TO_RADIANS, LENGTH_UNITS, LENGTHS_TO_PIXELS, check_var_function,
safe_urljoin)
ANGLE_TO_RADIANS, LENGTH_UNITS, LENGTHS_TO_PIXELS, InvalidValues,
check_var_function, safe_urljoin)

ZERO_PIXELS = Dimension(0, 'px')

Expand Down Expand Up @@ -226,10 +226,14 @@ def compute(element, pseudo_type, specified, computed, parent_style,
new_value = None
else:
prop = PROPERTIES[name.replace('_', '-')]
if prop.wants_base_url:
new_value = prop(computed_value, base_url)
else:
new_value = prop(computed_value)
# catch InvalidValues, e.g. for transform
try:
if prop.wants_base_url:
new_value = prop(computed_value, base_url)
else:
new_value = prop(computed_value)
except InvalidValues:
new_value = None

# See https://drafts.csswg.org/css-variables/#invalid-variables
if new_value is None:
Expand All @@ -248,6 +252,9 @@ def compute(element, pseudo_type, specified, computed, parent_style,
value = INITIAL_VALUES[name]
else:
value = new_value
# no value, no fallback, no need for a function call
if value is None:
function = None

if function is not None:
value = function(computer, name, value)
Expand Down Expand Up @@ -297,7 +304,9 @@ def length_or_percentage_tuple(computer, name, values):
@register_computer('clip')
def length_tuple(computer, name, values):
"""Compute the properties with a list of lengths."""
return tuple(length(computer, name, value, pixels_only=True)
# be aware of parent_style/initial values being plain numbers
return tuple(value if isinstance(value, (int, float)) else
length(computer, name, value, pixels_only=True)
for value in values)


Expand Down Expand Up @@ -539,14 +548,21 @@ def bookmark_label(computer, name, values):
def string_set(computer, name, values):
"""Compute the ``string-set`` property."""
# Spec asks for strings after custom keywords, but we allow content-lists
return tuple(
(string_set[0], _content_list(computer, string_set[1]))
for string_set in values)
# The initial value of 'none' can get here by improper var()
if values == 'none':
return ()
else:
return tuple(
(string_set[0], _content_list(computer, string_set[1]))
for string_set in values)


@register_computer('content')
def content(computer, name, values):
"""Compute the ``content`` property."""
# take care for INITIAL_VALUES['content']
if values == 'normal':
return 'inhibit' if computer['pseudo_type'] else 'contents'
if len(values) == 1:
value, = values
if value == 'normal':
Expand Down Expand Up @@ -611,6 +627,9 @@ def font_size(computer, name, value):
return keyword_values[-i - 1]
else:
return parent_font_size * 0.8
elif isinstance(value, int):
# Due to improper var() the unit-less parent value can get here
return value
elif value.unit == '%':
return value.value * parent_font_size / 100.
else:
Expand Down Expand Up @@ -730,6 +749,10 @@ def word_spacing(computer, name, value):
"""Compute the ``word-spacing`` property."""
if value == 'normal':
return 0
elif isinstance(value, int):
# The initial value can get here, but length() would fail as
# it does not have a 'unit' attribute.
return value
else:
return length(computer, name, value, pixels_only=True)

Expand Down
13 changes: 13 additions & 0 deletions weasyprint/tests/test_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

"""

from ..css.properties import KNOWN_PROPERTIES
from .test_boxes import render_pages as parse


Expand Down Expand Up @@ -95,3 +96,15 @@ def test_variable_initial():
body, = html.children
paragraph, = body.children
assert paragraph.width == 10


def test_variable_fallback():
parse('''
<style>
div {
--var: improperValue;
%s
}
</style>
<div></div>
''' % ''.join(name + ': var(--var);\n' for name in KNOWN_PROPERTIES))