Commit 91057d4c authored by Darren Shen's avatar Darren Shen Committed by Commit Bot

[css-typed-om] Fix crash for css-wide keywords in custom properties.

When converting CSSCustomPropertyDeclaration to CSSUnparsedValues, we
used to assume that CSSCustomPropertyDeclaration will always have a
CSSVariableData, but it turns out that css-wide keywords are stored
as a CSSValueID instead of a CSSVariableData.

This patch handles css-wide keywords on CSSUnparsedValues correctly.

We added a unit test and not a WPT since this is likely a blink-only
implementation detail.

Bug: 824740
Change-Id: Iefbdca4abc736562b81f5c6a3f0332975b842961
Reviewed-on: https://chromium-review.googlesource.com/977141
Commit-Queue: Darren Shen <shend@chromium.org>
Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545729}
parent e6cb368b
...@@ -1706,6 +1706,7 @@ jumbo_source_set("unit_tests") { ...@@ -1706,6 +1706,7 @@ jumbo_source_set("unit_tests") {
"css/cssom/CSSResourceValueTest.cpp", "css/cssom/CSSResourceValueTest.cpp",
"css/cssom/CSSStyleImageValueTest.cpp", "css/cssom/CSSStyleImageValueTest.cpp",
"css/cssom/CSSUnitValueTest.cpp", "css/cssom/CSSUnitValueTest.cpp",
"css/cssom/CSSUnparsedValueTest.cpp",
"css/cssom/PrepopulatedComputedStylePropertyMapTest.cpp", "css/cssom/PrepopulatedComputedStylePropertyMapTest.cpp",
"css/invalidation/InvalidationSetTest.cpp", "css/invalidation/InvalidationSetTest.cpp",
"css/invalidation/StyleInvalidatorTest.cpp", "css/invalidation/StyleInvalidatorTest.cpp",
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "core/css/cssom/CSSUnparsedValue.h" #include "core/css/cssom/CSSUnparsedValue.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSVariableData.h" #include "core/css/CSSVariableData.h"
#include "core/css/CSSVariableReferenceValue.h" #include "core/css/CSSVariableReferenceValue.h"
#include "core/css/cssom/CSSStyleVariableReferenceValue.h" #include "core/css/cssom/CSSStyleVariableReferenceValue.h"
...@@ -66,16 +67,26 @@ HeapVector<CSSUnparsedSegment> ParserTokenRangeToTokens( ...@@ -66,16 +67,26 @@ HeapVector<CSSUnparsedSegment> ParserTokenRangeToTokens(
CSSUnparsedValue* CSSUnparsedValue::FromCSSValue( CSSUnparsedValue* CSSUnparsedValue::FromCSSValue(
const CSSVariableReferenceValue& value) { const CSSVariableReferenceValue& value) {
DCHECK(value.VariableDataValue()); DCHECK(value.VariableDataValue());
return FromCSSValue(*value.VariableDataValue()); return FromCSSVariableData(*value.VariableDataValue());
} }
CSSUnparsedValue* CSSUnparsedValue::FromCSSValue(const CSSVariableData& value) { CSSUnparsedValue* CSSUnparsedValue::FromCSSValue(
const CSSCustomPropertyDeclaration& value) {
if (const CSSVariableData* data = value.Value())
return FromCSSVariableData(*data);
// Otherwise, it's a CSS-wide keyword
return FromString(value.CustomCSSText());
}
CSSUnparsedValue* CSSUnparsedValue::FromCSSVariableData(
const CSSVariableData& value) {
return CSSUnparsedValue::Create(ParserTokenRangeToTokens(value.TokenRange())); return CSSUnparsedValue::Create(ParserTokenRangeToTokens(value.TokenRange()));
} }
CSSUnparsedSegment CSSUnparsedValue::AnonymousIndexedGetter( CSSUnparsedSegment CSSUnparsedValue::AnonymousIndexedGetter(
unsigned index, unsigned index,
ExceptionState& exception_state) { ExceptionState& exception_state) const {
if (index < tokens_.size()) if (index < tokens_.size())
return tokens_[index]; return tokens_[index];
return {}; return {};
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
namespace blink { namespace blink {
class CSSVariableReferenceValue; class CSSVariableReferenceValue;
class CSSCustomPropertyDeclaration;
class CSSVariableData; class CSSVariableData;
using CSSUnparsedSegment = StringOrCSSVariableReferenceValue; using CSSUnparsedSegment = StringOrCSSVariableReferenceValue;
...@@ -30,13 +31,14 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue { ...@@ -30,13 +31,14 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
return Create(HeapVector<CSSUnparsedSegment>()); return Create(HeapVector<CSSUnparsedSegment>());
} }
static CSSUnparsedValue* FromCSSValue(const CSSVariableReferenceValue&); static CSSUnparsedValue* FromCSSValue(const CSSVariableReferenceValue&);
static CSSUnparsedValue* FromCSSValue(const CSSVariableData&); static CSSUnparsedValue* FromCSSValue(const CSSCustomPropertyDeclaration&);
static CSSUnparsedValue* FromCSSVariableData(const CSSVariableData&);
const CSSValue* ToCSSValue() const override; const CSSValue* ToCSSValue() const override;
StyleValueType GetType() const override { return kUnparsedType; } StyleValueType GetType() const override { return kUnparsedType; }
CSSUnparsedSegment AnonymousIndexedGetter(unsigned, ExceptionState&); CSSUnparsedSegment AnonymousIndexedGetter(unsigned, ExceptionState&) const;
bool AnonymousIndexedSetter(unsigned, bool AnonymousIndexedSetter(unsigned,
const CSSUnparsedSegment&, const CSSUnparsedSegment&,
ExceptionState&); ExceptionState&);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/cssom/CSSUnparsedValue.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
TEST(CSSUnparsedValueTest, FromCustomPropertyDeclarationWithCSSWideKeyword) {
const auto* initial_value =
CSSCustomPropertyDeclaration::Create("--var", CSSValueInitial);
const auto* unparsed_value = CSSUnparsedValue::FromCSSValue(*initial_value);
ASSERT_NE(nullptr, unparsed_value);
ASSERT_EQ(1U, unparsed_value->length());
const auto& item =
unparsed_value->AnonymousIndexedGetter(0, ASSERT_NO_EXCEPTION);
ASSERT_TRUE(item.IsString());
EXPECT_EQ("initial", item.GetAsString());
}
} // namespace blink
...@@ -105,10 +105,8 @@ CSSStyleValue* CreateStyleValueWithProperty(CSSPropertyID property_id, ...@@ -105,10 +105,8 @@ CSSStyleValue* CreateStyleValueWithProperty(CSSPropertyID property_id,
if (value.IsVariableReferenceValue()) if (value.IsVariableReferenceValue())
return CSSUnparsedValue::FromCSSValue(ToCSSVariableReferenceValue(value)); return CSSUnparsedValue::FromCSSValue(ToCSSVariableReferenceValue(value));
if (value.IsCustomPropertyDeclaration()) { if (value.IsCustomPropertyDeclaration()) {
const CSSVariableData* variable_data = return CSSUnparsedValue::FromCSSValue(
ToCSSCustomPropertyDeclaration(value).Value(); ToCSSCustomPropertyDeclaration(value));
DCHECK(variable_data);
return CSSUnparsedValue::FromCSSValue(*variable_data);
} }
if (!CSSOMTypes::IsPropertySupported(property_id)) if (!CSSOMTypes::IsPropertySupported(property_id))
...@@ -166,7 +164,7 @@ CSSStyleValueVector StyleValueFactory::FromString( ...@@ -166,7 +164,7 @@ CSSStyleValueVector StyleValueFactory::FromString(
CSSVariableData::Create(range, false /* is_animation_tainted */, CSSVariableData::Create(range, false /* is_animation_tainted */,
false /* needs variable resolution */); false /* needs variable resolution */);
CSSStyleValueVector values; CSSStyleValueVector values;
values.push_back(CSSUnparsedValue::FromCSSValue(*variable_data)); values.push_back(CSSUnparsedValue::FromCSSVariableData(*variable_data));
return values; return values;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment