Commit a4863911 authored by Mathijs den Burger's avatar Mathijs den Burger

HHP-26 Don't normalize character references in attributes

parent db515242
/*
* Copyright 2017 Hippo B.V. (http://www.onehippo.com)
* Copyright 2017-2018 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -16,10 +16,7 @@
package org.onehippo.cms7.services.htmlprocessor.serialize;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.CompactHtmlSerializer;
import org.htmlcleaner.PrettyHtmlSerializer;
import org.htmlcleaner.Serializer;
import org.htmlcleaner.SimpleHtmlSerializer;
public class HtmlSerializerFactory {
......@@ -30,26 +27,11 @@ public class HtmlSerializerFactory {
public static Serializer create(final HtmlSerializer serializer, final CleanerProperties properties) {
switch (serializer) {
case PRETTY:
return new PrettyHtmlSerializer(properties) {
@Override
protected String escapeText(final String content) {
return CharacterReferenceNormalizer.normalize(content);
}
};
return new NormalizingPrettyHtmlSerializer(properties);
case COMPACT:
return new CompactHtmlSerializer(properties) {
@Override
protected String escapeText(final String content) {
return CharacterReferenceNormalizer.normalize(content);
}
};
return new NormalizingCompactHtmlSerializer(properties);
default:
return new SimpleHtmlSerializer(properties) {
@Override
protected String escapeText(final String content) {
return CharacterReferenceNormalizer.normalize(content);
}
};
return new NormalizingSimpleHtmlSerializer(properties);
}
}
......
/*
* Copyright 2018 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onehippo.cms7.services.htmlprocessor.serialize;
import java.io.IOException;
import java.io.Writer;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.CompactHtmlSerializer;
import org.htmlcleaner.TagNode;
class NormalizingCompactHtmlSerializer extends CompactHtmlSerializer {
private final ThreadLocal<Boolean> escapeText;
NormalizingCompactHtmlSerializer(final CleanerProperties props) {
super(props);
escapeText = ThreadLocal.withInitial(() -> true);
}
@Override
protected void serializeOpenTag(final TagNode tagNode, final Writer writer, final boolean newLine) throws IOException {
escapeText.set(false);
try {
super.serializeOpenTag(tagNode, writer, newLine);
} finally {
escapeText.set(true);
}
}
@Override
protected String escapeText(final String content) {
if (escapeText.get()) {
return CharacterReferenceNormalizer.normalize(content);
}
return content;
}
}
/*
* Copyright 2018 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onehippo.cms7.services.htmlprocessor.serialize;
import java.io.IOException;
import java.io.Writer;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.PrettyHtmlSerializer;
import org.htmlcleaner.TagNode;
class NormalizingPrettyHtmlSerializer extends PrettyHtmlSerializer {
private final ThreadLocal<Boolean> escapeText;
NormalizingPrettyHtmlSerializer(final CleanerProperties props) {
super(props);
escapeText = ThreadLocal.withInitial(() -> true);
}
@Override
protected void serializeOpenTag(final TagNode tagNode, final Writer writer, final boolean newLine) throws IOException {
escapeText.set(false);
try {
super.serializeOpenTag(tagNode, writer, newLine);
} finally {
escapeText.set(true);
}
}
@Override
protected String escapeText(final String content) {
if (escapeText.get()) {
return CharacterReferenceNormalizer.normalize(content);
}
return content;
}
}
/*
* Copyright 2018 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onehippo.cms7.services.htmlprocessor.serialize;
import java.io.IOException;
import java.io.Writer;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.SimpleHtmlSerializer;
import org.htmlcleaner.TagNode;
class NormalizingSimpleHtmlSerializer extends SimpleHtmlSerializer {
private final ThreadLocal<Boolean> escapeText;
NormalizingSimpleHtmlSerializer(final CleanerProperties props) {
super(props);
escapeText = ThreadLocal.withInitial(() -> true);
}
@Override
protected void serializeOpenTag(final TagNode tagNode, final Writer writer, final boolean newLine) throws IOException {
escapeText.set(false);
try {
super.serializeOpenTag(tagNode, writer, newLine);
} finally {
escapeText.set(true);
}
}
@Override
protected String escapeText(final String content) {
if (escapeText.get()) {
return CharacterReferenceNormalizer.normalize(content);
}
return content;
}
}
/*
* Copyright 2017 Hippo B.V. (http://www.onehippo.com)
* Copyright 2017-2018 Hippo B.V. (http://www.onehippo.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -28,6 +28,7 @@ import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.onehippo.cms7.services.htmlprocessor.filter.Element;
import org.onehippo.cms7.services.htmlprocessor.serialize.HtmlSerializer;
import org.onehippo.repository.mock.MockNode;
import static org.junit.Assert.assertEquals;
......@@ -156,6 +157,25 @@ public class HtmlProcessorTest {
}
@Test
public void characterReferencesInAttributesAreNotNormalized() throws IOException {
for (HtmlSerializer serializer : HtmlSerializer.values()) {
final HtmlProcessorConfig config = new HtmlProcessorConfig();
config.setFilter(true);
config.setSerializer(serializer);
final Element table = Element.create("table", "summary");
config.setWhitelistElements(Collections.singletonList(table));
processor = new HtmlProcessorImpl(config);
final String html = "<table summary=\"&quot; onmouseover=alert('hi')\"></table>";
final String written = processor.write(html, Collections.emptyList());
assertEquals(serializer.name(), html, written);
}
}
@Test
public void testReadVisitor() throws Exception {
final HtmlProcessorConfig htmlProcessorConfig = new HtmlProcessorConfig();
......
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