Implement calc-mix()
LayoutTests/imported/w3c/web-platform-tests/css/css-values/calc-mix-computed.tentative-expected.txt
WebKit의 CSS calc 시스템은 두 가지 병렬 트리 표현을 사용합니다. CSSCalcTree는 파싱/CSS 수준의 형태로, 파싱·검증·직렬화 단계에서 활용됩니다. StyleCalculationTree는 해석된/스타일 수준의 형태로, cascade와 computed value 해석 단계에서 사용됩니다. 새로운 calc 함수를 추가할 때는 두 트리 모두에서 복사·단순화·평가·직렬화·computed-style 의존성 추적 등 전체 pass를 거쳐야 합니다.
이 commit은 CSS Values Level 5에 정의된 calc-mix() 함수를 구현합니다. calc-mix()는 calc 항목 목록에 대한 가중 평균을 계산하는 함수로, parser·단순화·평가·직렬화·type 해석·스타일 해석 등 전체 pipeline에 걸쳐 구현되었습니다. 구현은 새로 도입된 CSSCalcMixEnabled preference 플래그로 활성화를 제어합니다.
calc-mix()는 가중 평균 노드를 도입합니다. 이 노드의 의미론은 percentage weight를 정규화하는 과정을 요구합니다. 합이 100%가 되지 않거나, 완전히 생략되거나, 모두 0%인 경우까지 모두 처리해야 합니다. 또한 이질적인 피연산자에 걸쳐 결과 type을 해석하는 과정도 필요합니다. 이 commit은 csswg-drafts issue #13839를 명시적으로 참조하며, 미확정된 spec 영역에서 구현이 독자적으로 판단을 내려야 하는 부분이 있음을 인정하고 있습니다.
Significance
WebKit에서 가장 복잡한 CSS 서브시스템 전반에 상당한 규모의 새로운 attack surface가 추가되었습니다. spec에는 단순화 의미론에 관한 미결 사항도 남아 있습니다. Weight 정규화, 이질적인 type 혼합, weight 인자 내의 tree-context 함수는 각각 spec이 명확히 정의하지 않은 edge case를 만들어냅니다. 구현은 이를 독자적으로 처리해야 합니다.
Audit directions
- Weight normalization logic. 테스트를 보면, weight 합이 100%를 초과할 때는 재정규화(
calc-mix(1 75%, 3 75%)→ 2)하지만, 100% 미만일 때는 나머지를 조용히 버립니다(calc-mix(1 25%, 3 25%)→ 1). 이 두 동작 사이의 경계 조건 자체가 모호합니다. 자동 분배 weight(calc-mix(1 25%, 3 25%, 5, 7)→ 4)와의 상호작용을 고려하면, floating-point 정밀도 버그 및 off-by-one 오류가 발생할 가능성이 높습니다. - Zero-weight type resolution. 모든 weight가 0%인 경우에도, 피연산자 type 분석을 바탕으로 올바른 type의 zero 값(
0%vs0px)을 생성해야 합니다. 이는 type 해석과 zero-value 의미론이 결합된 퇴화된 경로입니다. 이때 type 해석 결정의 순서가 미묘하며, 단위가 혼합된 입력에서 예상치 못한 결과를 초래할 가능성이 있습니다. - Heterogeneous type mixing. 단일
calc-mix()에서em,px,%를 함께 사용하면,CSSCalcTree+Simplification단계에서 단위가 혼합된 가중 합을 처리해야 합니다. 이 코드 영역은 과거calc()에서 type confusion 버그가 반복적으로 발생한 지점입니다. sibling-index()inside weight arguments. Spec은 weight percentage 안에서 tree-context 함수의 사용을 허용합니다.CSSCalcTree+ComputedStyleDependencies.cpp의 의존성 추적기가 이러한 의존성을 올바르게 상위로 전파해야 합니다. 의존성 annotation이 누락되면 computed value가 stale 상태가 됩니다.- Simplification under spec ambiguity. csswg-drafts #13839가 미해결 상태인 만큼, 단순화 pass는 spec이 나중에 번복할 수도 있는 결정을 단독으로 내리고 있습니다. 테스트에서는
calc-mix()가sign(),max(), 중첩된calc()와 함께 동작해야 함을 보여줍니다. 구현에 내재된 단순화 가정은 이러한 조합 지점에서 잘못된 결과를 초래할 가능성이 있습니다.