LibWeb: Clamp and censor top-level calc results

We now clamp the values returned from calc into the allowed range (where
we know it) and censor any `NaN`s to `0` both when we resolve and when
we serialize.

Gains us 76 WPT passes.
This commit is contained in:
Callum Law 2025-08-06 16:29:12 +12:00 committed by Sam Atkins
commit 778da0175e
Notes: github-actions[bot] 2025-08-11 16:11:10 +00:00
15 changed files with 361 additions and 74 deletions

View file

@ -2,36 +2,36 @@ Harness status: OK
Found 140 tests
70 Pass
70 Fail
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [NaNpx]
84 Pass
56 Fail
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [-8.50705e+37px]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0) should be [0px]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [NaNpx]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [NaNpx]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [NaNpx]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [NaNpx]
Fail CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [NaNpx]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [NaNpx]
Pass CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [8.50705e+37px]
Pass CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [1.70141e+38px]
Pass CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [2.552115e+38px]
Pass CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [3.40282e+38px]
Pass CSS Transitions: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [4.2535250000000006e+38px]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [-8.50705e+37px]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0) should be [0px]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [NaNpx]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [NaNpx]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [NaNpx]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [NaNpx]
Fail CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [NaNpx]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [NaNpx]
Pass CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [8.50705e+37px]
Pass CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [1.70141e+38px]
Pass CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [2.552115e+38px]
Pass CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [3.40282e+38px]
Pass CSS Transitions with transition: all: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [4.2535250000000006e+38px]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [-3.40282e+38px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0) should be [0px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [NaNpx]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [NaNpx]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [NaNpx]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [NaNpx]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [NaNpx]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [NaNpx]
Fail CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [3.40282e+38px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [3.40282e+38px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [3.40282e+38px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [3.40282e+38px]
Pass CSS Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [3.40282e+38px]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (-0.25) should be [-3.40282e+38px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0) should be [0px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [NaNpx]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [NaNpx]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [NaNpx]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [NaNpx]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [NaNpx]
Fail Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.25) should be [3.40282e+38px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.5) should be [3.40282e+38px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (0.75) should be [3.40282e+38px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1) should be [3.40282e+38px]
Pass Web Animations: property <left> from [0px] to [calc(infinity * 1px)] at (1.25) should be [3.40282e+38px]
Fail CSS Transitions: property <left> from [calc(50% - 25px)] to [calc(100% - 10px)] at (-0.25) should be [-10px]
Fail CSS Transitions: property <left> from [calc(50% - 25px)] to [calc(100% - 10px)] at (0) should be [0px]
Fail CSS Transitions: property <left> from [calc(50% - 25px)] to [calc(100% - 10px)] at (0.25) should be [10px]

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 45 tests
26 Pass
19 Fail
33 Pass
12 Fail
Pass Property width value 'calc(NaN * 1px)'
Pass Property width value 'calc(NaN * 1%)'
Pass Property width value 'calc(infinity * 1px)'
@ -30,13 +30,13 @@ Pass Property margin-left value 'calc(-infinity * 1%)'
Pass Property margin-left value 'calc(max(10000px, 0px) + min(-infinity * 1px, infinity * 1px))'
Pass Property margin-left value 'calc(-infinity * 1px - infinity * 1px)'
Pass Property margin-left value 'calc(min(-infinity * 1px, 10px))'
Fail Property animation-duration value 'calc(NaN * 1s)'
Fail Property animation-duration value 'calc(infinity * 1s)'
Fail Property animation-duration value 'calc(1 / 0 * 1s)'
Fail Property animation-duration value 'calc(max(infinity * 1s, 10s)'
Fail Property transition-delay value 'calc(-infinity* 1s)'
Fail Property transition-delay value 'calc(max(10000s, 0s) + min(-infinity * 1s, infinity * 1s))'
Fail Property transition-delay value 'calc(min(-infinity * 1s, 10s))'
Pass Property animation-duration value 'calc(NaN * 1s)'
Pass Property animation-duration value 'calc(infinity * 1s)'
Pass Property animation-duration value 'calc(1 / 0 * 1s)'
Pass Property animation-duration value 'calc(max(infinity * 1s, 10s)'
Pass Property transition-delay value 'calc(-infinity* 1s)'
Pass Property transition-delay value 'calc(max(10000s, 0s) + min(-infinity * 1s, infinity * 1s))'
Pass Property transition-delay value 'calc(min(-infinity * 1s, 10s))'
Fail Property rotate(calc(infinity * 1deg)) value expected same with rotate(0deg) in +/-0.0001
Fail Property rotate(calc(-infinity * 1deg)) value expected same with rotate(0deg) in +/-0.0001
Fail Property rotate(calc(NaN * 1deg)) value expected same with rotate(0deg) in +/-0.0001

View file

@ -0,0 +1,18 @@
Harness status: OK
Found 12 tests
11 Pass
1 Fail
Pass testing tab-size: calc(2 * 3)
Pass testing tab-size: calc(2 * -4)
Pass testing opacity: calc(2 / 4)
Pass testing tab-size: calc(2 / 4)
Pass testing opacity: calc(2 / 4) * 1px
Fail testing opacity: calc(90%)
Pass testing tab-size: calc(1 + 1px)
Pass testing tab-size: calc(1 + 100%)
Pass testing tab-size: calc(100%)
Pass testing tab-size: calc(10px) bla
Pass testing tab-size: calc(bla) 10px
Pass testing tab-size: calc(10px)

View file

@ -0,0 +1,31 @@
Harness status: OK
Found 25 tests
19 Pass
6 Fail
Pass min(1em, 110px / 10px * 1px) should be used-value-equivalent to 10px
Pass max(10px, 110px / 10px * 1px) should be used-value-equivalent to 11px
Pass max(1em + 2px, 110px / 10px * 1px) should be used-value-equivalent to 12px
Pass max(1em + 2%, 110px / 10px * 1px) should be used-value-equivalent to 12px
Pass clamp(110px / 10px * 1px, 1em + 200%, 200% * 1% / 1em) should be used-value-equivalent to 20px
Pass calc(3 + sign(10px / 1rem - sign(1em + 1px))) should be used-value-equivalent to 3
Pass calc(10em / 1em) should be used-value-equivalent to 10
Pass calc(10em / 1rem) should be used-value-equivalent to 10
Pass calc(10em / 1px) should be used-value-equivalent to 100
Pass calc(1px / 10em * NaN) should be used-value-equivalent to 0
Pass Property width value 'calc(1px * 10em / 0em)'
Pass Property width value 'calc(1px / 1px * 10em * infinity)'
Fail Property margin-left value 'calc(1px * 10em / -0em)'
Pass Property z-index value 'calc(10em / 0em)'
Pass sign(-0em / 1px) should be used-value-equivalent to 0
Fail clamp(-1, 1 / sign(-0em / 1px), 1) should be used-value-equivalent to -1
Fail sign( 0cqi / 1px) should be used-value-equivalent to 0
Fail clamp(-1, 1 / sign( 0cqi / 1px), 1) should be used-value-equivalent to 1
Pass sign(atan2(-0cap / 1px, 0em / 1px)) should be used-value-equivalent to 0
Fail clamp(-1, 1 / sign(atan2(-0cap / 1px, 0em / 1px)), 1) should be used-value-equivalent to -1
Pass sign(exp(-1vh / 0px)) should be used-value-equivalent to 0
Pass clamp(-1, 1 / sign(exp(-1vh / 0px)), 1) should be used-value-equivalent to 1
Fail calc(20cqw / 1rem) should be used-value-equivalent to 2
Pass Property animation-duration value 'calc(2s / (10s - 10s) * 1s)'
Pass subtraction of angle unit: deg minus turn