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

add support for inline style css functions #511

Merged
merged 3 commits into from
Oct 10, 2024
Merged
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
32 changes: 31 additions & 1 deletion src/main/java/org/owasp/validator/css/CssValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,40 @@ public String lexicalValueToString(LexicalUnit lu) {
return "inherit";
case LexicalUnit.SAC_OPERATOR_COMMA:
return ",";
case LexicalUnit.SAC_FUNCTION:
StringBuilder builder = new StringBuilder();

// Append the function name, e.g., "var"
builder.append(lu.getFunctionName()).append("(");

LexicalUnit params = lu.getParameters();
while (params != null) {
String paramsValue = lexicalValueToString(params);
if (paramsValue == null) {
return null;
}
builder.append(paramsValue);
params = params.getNextLexicalUnit();
if (params != null) {
builder.append(", ");
}
}

// Check for fallback (some functions like "var" have fallback values)
LexicalUnit fallback = lu.getPreviousLexicalUnit();
if (fallback != null) {
String fallbackValue = lexicalValueToString(fallback);
if (fallbackValue == null) {
return null;
}
builder.append(", ").append(fallbackValue);
}

builder.append(")");
return builder.toString();
case LexicalUnit.SAC_ATTR:
case LexicalUnit.SAC_COUNTER_FUNCTION:
case LexicalUnit.SAC_COUNTERS_FUNCTION:
case LexicalUnit.SAC_FUNCTION:
case LexicalUnit.SAC_RECT_FUNCTION:
case LexicalUnit.SAC_SUB_EXPRESSION:
case LexicalUnit.SAC_UNICODERANGE:
Expand Down
102 changes: 102 additions & 0 deletions src/test/java/org/owasp/validator/css/CssValidatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.owasp.validator.css;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.apache.batik.css.parser.CSSLexicalUnit;
import org.junit.Test;
import org.w3c.css.sac.LexicalUnit;

public class CssValidatorTest {
@Test
public void testLexicalValueToStringSacFunction() {
CssValidator cssValidator = new CssValidator(null);

final CSSLexicalUnit param =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "--ds-text-purple", null);
final CSSLexicalUnit varFunc = CSSLexicalUnit.createFunction("var", param, null);

assertEquals("var(--ds-text-purple)", cssValidator.lexicalValueToString(varFunc));

final CSSLexicalUnit hslaParam = CSSLexicalUnit.createInteger(100, null);
final CSSLexicalUnit hslaParam1 = CSSLexicalUnit.createDimension(98, "%", hslaParam);
final CSSLexicalUnit hslaParam2 = CSSLexicalUnit.createDimension(50, "%", hslaParam1);
CSSLexicalUnit.createFloat(LexicalUnit.SAC_REAL, 0.3f, hslaParam2);

final CSSLexicalUnit hslaFunc = CSSLexicalUnit.createFunction("hsla", hslaParam, null);
assertEquals("hsla(100, 98.0%, 50.0%, 0.3)", cssValidator.lexicalValueToString(hslaFunc));
}

@Test
public void testLexicalValueToStringSacFunctionTwoParams() {
CssValidator cssValidator = new CssValidator(null);

final CSSLexicalUnit param =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "--ds-text-purple", null);
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "#FFFFFF", param);
final CSSLexicalUnit func = CSSLexicalUnit.createFunction("var", param, null);

assertEquals("var(--ds-text-purple, #FFFFFF)", cssValidator.lexicalValueToString(func));
}

@Test
public void testLexicalValueToStringUnsupported() {
CssValidator cssValidator = new CssValidator(null);
final CSSLexicalUnit param =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "section", null);
final CSSLexicalUnit func =
CSSLexicalUnit.createPredefinedFunction(LexicalUnit.SAC_COUNTER_FUNCTION, param, null);
assertNull(cssValidator.lexicalValueToString(func));
}

@Test
public void testLexicalValueToStringNestedVarsWithFallback() {
CssValidator cssValidator = new CssValidator(null);

// Create fallback first: --ds-text-purple, #FFFFFF
final CSSLexicalUnit param =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "--ds-text-purple", null);
final CSSLexicalUnit fallback =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "#FFFFFF", null);

// Create first var() function with fallback
final CSSLexicalUnit function = CSSLexicalUnit.createFunction("var", param, fallback);

// Check if the output is as expected for first var()
assertEquals("var(--ds-text-purple, #FFFFFF)", cssValidator.lexicalValueToString(function));

// Create outer variable: --custom-prop
final CSSLexicalUnit outerParam =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "--custom-prop", null);

// Create outer var() with the first function as fallback
final CSSLexicalUnit outerFunction = CSSLexicalUnit.createFunction("var", outerParam, function);

// Ensure the output is as expected for the nested var() function
assertEquals(
"var(--custom-prop, var(--ds-text-purple, #FFFFFF))",
cssValidator.lexicalValueToString(outerFunction));
}

@Test
public void testDefaultPolicyUrlFunction() {
CssValidator cssValidator = new CssValidator(null);

// Test a simple url function
final CSSLexicalUnit urlParam =
CSSLexicalUnit.createString(LexicalUnit.SAC_STRING_VALUE, "http://example.com", null);
final CSSLexicalUnit urlFunc = CSSLexicalUnit.createFunction("url", urlParam, null);

assertEquals("url(http://example.com)", cssValidator.lexicalValueToString(urlFunc));
}

@Test
public void testSacUriWithValidUrl() {
CssValidator cssValidator = new CssValidator(null);

// Test with a valid URL, which should be allowed
final CSSLexicalUnit validUrl =
CSSLexicalUnit.createString(LexicalUnit.SAC_URI, "https://example.com", null);
assertEquals("url(https://example.com)", cssValidator.lexicalValueToString(validUrl));
}
}
Loading