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

Support more HTML elements and CSS attributes and fix CSS filter crashes #990

Merged
merged 20 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8584c21
Allow bdi and main elements and auto value of dir attribute
torusrxxx Oct 17, 2024
7cf3133
Add elements figcaption,figure,mark,rp,rt,ruby
torusrxxx Oct 19, 2024
35a00bf
Add CSS global values revert,revert-layer, attribute writing-mode, up…
torusrxxx Oct 19, 2024
453a446
Add CSS colors rebeccapurple and rgba modern format
torusrxxx Oct 19, 2024
3d857a5
Add fonts system-ui,ui-serif,ui-sans-serif,ui-monospace,ui-rounded,em…
torusrxxx Oct 19, 2024
8617f30
Add more pseudo classes
torusrxxx Oct 19, 2024
ba0d911
Add inline-start,inline-end values of float CSS attribute
torusrxxx Oct 19, 2024
278a10f
Update CSS attributes clear,overflow,text-underline-position
torusrxxx Oct 19, 2024
86f216d
Fix StringIndexOutOfBoundsException when filtering "tr:tenth-child {}"
torusrxxx Oct 22, 2024
46f36f7
Add font size xxx-large and selector tests
torusrxxx Oct 22, 2024
5e0d013
Add background-blend-mode and mix-blend-mode and CSS tests
torusrxxx Oct 24, 2024
e33b534
Fix text-shadow parsing
torusrxxx Oct 25, 2024
c814ae1
Add attributes block-size,inline-size, length values min-content,max-…
torusrxxx Oct 25, 2024
cc74d98
fix NullPointerException with text-emphasis, fix deprecated attribute…
torusrxxx Oct 28, 2024
9591dba
Add tab-size,font-kerning, update word-break
torusrxxx Oct 28, 2024
47e72cc
Add object-fit
torusrxxx Oct 28, 2024
598c52f
Support "reversed" attribute of <ol> element
torusrxxx Oct 29, 2024
5b9f643
Add more types to list-style-type and also allow string
torusrxxx Oct 31, 2024
2dc724b
Add max-block-size,max-inline-size,min-block-size,min-inline-size
torusrxxx Nov 4, 2024
2bc2fc2
Fix text-wrap having nonstandard values
torusrxxx Nov 6, 2024
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
14 changes: 5 additions & 9 deletions src/freenet/client/filter/CSSTokenizerFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import freenet.support.Fields;
import freenet.support.Logger;
import freenet.support.api.Bucket;
import freenet.support.io.Closer;
import freenet.support.io.FileBucket;

/** Comprehensive CSS2.1 filter. The old jflex-based filter was very far
Expand Down Expand Up @@ -1030,7 +1029,7 @@ else if("font-family".equalsIgnoreCase(element))
}
else if("font-size".equalsIgnoreCase(element))
{
elementVerifiers.put(element,new CSSPropertyVerifier(Arrays.asList("xx-small","x-small","small","medium","large","x-large","xx-large","larger","smaller"),ElementInfo.VISUALMEDIA,Arrays.asList("le","pe")));
elementVerifiers.put(element,new CSSPropertyVerifier(Arrays.asList("xx-small","x-small","small","medium","large","x-large","xx-large","xxx-large","larger","smaller"),ElementInfo.VISUALMEDIA,Arrays.asList("le","pe")));
allelementVerifiers.remove(element);
}
else if("font-style".equalsIgnoreCase(element))
Expand Down Expand Up @@ -4871,18 +4870,15 @@ public static void main(String arg[]) throws Throwable {
fout.delete();
final Bucket inputBucket = new FileBucket(fin, true, false, false, false);
final Bucket outputBucket = new FileBucket(fout, false, true, false, false);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = inputBucket.getInputStream();
outputStream = outputBucket.getOutputStream();
try (
InputStream inputStream = inputBucket.getInputStream();
OutputStream outputStream = outputBucket.getOutputStream()
) {
ArneBab marked this conversation as resolved.
Show resolved Hide resolved
Logger.setupStdoutLogging(Logger.LogLevel.DEBUG, "");

ContentFilter.filter(inputStream, outputStream, "text/css",
new URI("http://127.0.0.1:8888/freenet:USK@ZupQjDFZSc3I4orBpl1iTEAPZKo2733RxCUbZ2Q7iH0,EO8Tuf8SP3lnDjQdAPdCM2ve2RaUEN8m-hod3tQ5oQE,AQACAAE/jFreesite/19/Style/"), null, null, null, null);
} finally {
Closer.close(inputStream);
Closer.close(outputStream);
inputBucket.free();
outputBucket.free();
}
Expand Down
43 changes: 25 additions & 18 deletions src/freenet/client/filter/ElementInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public class ElementInfo {
"visited", // privacy risk (see BANNED_PSEUDOCLASS below)
"hover",
"active",
"checked",
"checked", // forms
"focus",
"focus-within",
"first-line",
Expand All @@ -193,23 +193,23 @@ public class ElementInfo {
"after",
"target",
ArneBab marked this conversation as resolved.
Show resolved Hide resolved
"any-link",
ArneBab marked this conversation as resolved.
Show resolved Hide resolved
"default",
"default", // forms
"defined", // Javascript only (BANNED_PSEUDOCLASS)
"disabled", // forms
"empty",
"enabled", // forms
"focus-visible",
"indeterminate", // forms
"in-range",
"invalid",
"in-range", // forms
"invalid", // forms
"only-child",
"only-of-type",
"optional",
"out-of-range",
"placeholder-shown",
"read-only",
"read-write",
"required",
"optional", // forms
"out-of-range", // forms
"placeholder-shown", // forms
"read-only", // forms
"read-write", // forms
"required", // forms
"root"
)));

Expand Down Expand Up @@ -427,11 +427,16 @@ public static boolean isBannedPseudoClass(String cname)
// Pseudo-classes can be chained, at least dynamic ones can, see CSS2.1 section 5.11.3
String[] split = cname.split(":");
for(String s : split)
if(isBannedPseudoClass(s)) return true;
if(isBannedPseudoClass2(s)) return true;
ArneBab marked this conversation as resolved.
Show resolved Hide resolved
return false;
} else {
return isBannedPseudoClass2(cname);
}
cname=cname.toLowerCase();
return BANNED_PSEUDOCLASS.contains(cname);
}

private static boolean isBannedPseudoClass2(String cname)
{
return BANNED_PSEUDOCLASS.contains(cname.toLowerCase());
}

public static boolean isValidPseudoClass(String cname)
Expand All @@ -440,20 +445,23 @@ public static boolean isValidPseudoClass(String cname)
// Pseudo-classes can be chained, at least dynamic ones can, see CSS2.1 section 5.11.3
String[] split = cname.split(":");
for(String s : split)
if(!isValidPseudoClass(s)) return false;
if(!isValidPseudoClass2(s)) return false;
return true;
} else {
return isValidPseudoClass2(cname);
}
}

private static boolean isValidPseudoClass2(String cname)
{
cname=cname.toLowerCase();
if(PSEUDOCLASS.contains(cname))
return true;


else if(cname.startsWith("lang") && Pattern.matches("[\\w\\-*]{1,30}", getPseudoClassArg(cname, "lang")))
{
// More than 8000 valid BCP-47 language codes. Just let through all of them.
return true;
}

else if(cname.startsWith("nth-child") && FilterUtils.isNth(getPseudoClassArg(cname, "nth-child")))
return true;
else if(cname.startsWith("nth-last-child") && FilterUtils.isNth(getPseudoClassArg(cname, "nth-last-child")))
Expand All @@ -466,7 +474,6 @@ else if(cname.startsWith("dir")) {
String arg = getPseudoClassArg(cname, "dir");
return arg.equalsIgnoreCase("ltr") || arg.equalsIgnoreCase("rtl");
}

return false;
}

Expand Down
48 changes: 47 additions & 1 deletion test/freenet/client/filter/CSSParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,58 @@ public class CSSParserTest {
static {
CSS_SELECTOR_LEVEL4.put("div:dir(ltr) {}", "div:dir(ltr)");
CSS_SELECTOR_LEVEL4.put("div:dir(rtl) {}", "div:dir(rtl)");
CSS_SELECTOR_LEVEL4.put(":target {}", ":target");
CSS_SELECTOR_LEVEL4.put(":any-link {}", ":any-link");
CSS_SELECTOR_LEVEL4.put(":empty {}", ":empty");
CSS_SELECTOR_LEVEL4.put(":focus-visible {}", ":focus-visible");
CSS_SELECTOR_LEVEL4.put(":only-child {}", ":only-child");
CSS_SELECTOR_LEVEL4.put(":only-of-type {}", ":only-of-type");
CSS_SELECTOR_LEVEL4.put(":root {font-size: xxx-large;}", ":root {font-size: xxx-large;}");
// forms
CSS_SELECTOR_LEVEL4.put("input:default {}", "input:default");
CSS_SELECTOR_LEVEL4.put("input:disabled {}", "input:disabled");
CSS_SELECTOR_LEVEL4.put("input:enabled {}", "input:enabled");
CSS_SELECTOR_LEVEL4.put("input:indeterminate {}", "input:indeterminate");
CSS_SELECTOR_LEVEL4.put("input:in-range {}", "input:in-range");
CSS_SELECTOR_LEVEL4.put("input:invalid {}", "input:invalid");
CSS_SELECTOR_LEVEL4.put("input:optional {}", "input:optional");
CSS_SELECTOR_LEVEL4.put("input:out-of-range {}", "input:out-of-range");
CSS_SELECTOR_LEVEL4.put("input:placeholder-shown {}", "input:placeholder-shown");
CSS_SELECTOR_LEVEL4.put("input:read-only {}", "input:read-only");
CSS_SELECTOR_LEVEL4.put("input:read-write {}", "input:read-write");
CSS_SELECTOR_LEVEL4.put("input:required {}", "input:required");
}

private final static HashSet<String> CSS_BAD_SELECTOR_LEVEL4= new HashSet<>();
static {
// not dir
CSS_BAD_SELECTOR_LEVEL4.add("div:bidir(ltr) {}");
CSS_BAD_SELECTOR_LEVEL4.add("div:dir {}"); // missing ltr or rtl
// missing ltr or rtl
CSS_BAD_SELECTOR_LEVEL4.add("div:dir {}");
// these selectors don't have arguments
CSS_BAD_SELECTOR_LEVEL4.add(":target() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":any-link() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":empty() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":focus-visible() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":only-child() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":only-of-type() {}");
CSS_BAD_SELECTOR_LEVEL4.add(":root() {}");
// these forms selectors don't have arguments
CSS_BAD_SELECTOR_LEVEL4.add("input:default() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:disabled() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:enabled() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:indeterminate() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:in-range() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:invalid() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:optional() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:out-of-range() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:placeholder-shown() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:read-only() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:read-write() {}");
CSS_BAD_SELECTOR_LEVEL4.add("input:required() {}");
// banned
CSS_BAD_SELECTOR_LEVEL4.add(":defined {}");
CSS_BAD_SELECTOR_LEVEL4.add(":defined() {}");
}

private static final String CSS_STRING_NEWLINES = "* { content: \"this string does not terminate\n}\nbody {\nbackground: url(http://www.google.co.uk/intl/en_uk/images/logo.gif); }\n\" }";
Expand Down