Yeah, not surprisingly it's more complicated than I had thought. It was helpful for me to change the Validator code and run the test suite to see what happens. (I'm currently working with 5.3.4.Final; it seems SafeHtmlValidator hasn't changed since this issue was resolved. I tried working with master branch, but a completely unrelated test currently fails, so I checked out 5.3.4.Final and did testing with that tag.) Here's my modified/simplified SafeHtmlValidator:
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http: */
package org.hibernate.validator.internal.constraintvalidators.hv;
import java.util.Iterator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.hibernate.validator.constraints.SafeHtml;
/**
* Validate that the string does not contain malicious code.
*
* It uses <a href="http:>JSoup</a> as the underlying parser/sanitizer library.
*
* @author George Gastaldi
* @author Hardy Ferentschik
*/
public class SafeHtmlValidator implements ConstraintValidator<SafeHtml, CharSequence> {
private Whitelist whitelist;
@Override
public void initialize(SafeHtml safeHtmlAnnotation) {
switch ( safeHtmlAnnotation.whitelistType() ) {
case BASIC:
whitelist = Whitelist.basic();
break;
case BASIC_WITH_IMAGES:
whitelist = Whitelist.basicWithImages();
break;
case NONE:
whitelist = Whitelist.none();
break;
case RELAXED:
whitelist = Whitelist.relaxed();
break;
case SIMPLE_TEXT:
whitelist = Whitelist.simpleText();
break;
}
whitelist.addTags( safeHtmlAnnotation.additionalTags() );
for ( SafeHtml.Tag tag : safeHtmlAnnotation.additionalTagsWithAttributes() ) {
whitelist.addAttributes( tag.name(), tag.attributes() );
}
}
@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
if ( value == null ) {
return true;
}
return Jsoup.isValid( value.toString(), whitelist );
}
}
The "trouble" with this change is that one of the test suite methods for this issue then fails: SafeHtmlValidatorTest#testValidationOfValidFragment():
@Test
@TestForIssue(jiraKey = "HV-873")
public void testValidationOfValidFragment() throws Exception {
descriptor.setValue( "whitelistType", WhiteListType.RELAXED );
assertTrue( getSafeHtmlValidator().isValid( "<td>1234qwer</td>", null ) );
}
It seems that "validity" now has a quite specific meaning for "body fragment": it means that the fragment must now also parse correctly if inserted directly inside a <body> tag. So although <td> is one of the permitted tags for "relaxed" mode, it has to be included inside <table><tr>.... So, to get the suite to pass, I had to replace the above test method with:
@Test
@TestForIssue(jiraKey = "HV-873")
public void testValidationOfInvalidFragment2() throws Exception {
descriptor.setValue( "whitelistType", WhiteListType.RELAXED );
assertFalse( getSafeHtmlValidator().isValid( "<td>1234qwer</td>", null ) );
}
@Test
@TestForIssue(jiraKey = "HV-873")
public void testValidationOfValidFragment() throws Exception {
descriptor.setValue( "whitelistType", WhiteListType.RELAXED );
assertTrue( getSafeHtmlValidator().isValid( "<table><tr><td>1234qwer</td></tr></table>", null ) );
}
So maybe this is not a desirable change to make, after all. |