You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by mb...@apache.org on 2021/08/08 21:52:15 UTC
[roller] 01/03: Added EscapeSourceCodePlugin,
a WeblogEntryPlugin to escape angle brackes from code within pre
tags.
This is an automated email from the ASF dual-hosted git repository.
mbien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/roller.git
commit 09489e6c3630fac21ff6b40c8195eecca2de1b78
Author: Michael Bien <mb...@gmail.com>
AuthorDate: Sun Jul 11 09:04:29 2021 +0200
Added EscapeSourceCodePlugin, a WeblogEntryPlugin to escape angle brackes from code within pre tags.
---
.../plugins/entry/EscapeSourceCodePlugin.java | 88 ++++++++++++
.../roller/weblogger/config/roller.properties | 3 +-
.../plugins/entry/EscapeSourceCodePluginTest.java | 157 +++++++++++++++++++++
3 files changed, 247 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePlugin.java b/app/src/main/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePlugin.java
new file mode 100644
index 0000000..845b08e
--- /dev/null
+++ b/app/src/main/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePlugin.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business.plugins.entry;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.roller.weblogger.WebloggerException;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.pojos.WeblogEntry;
+
+
+import static java.util.regex.Pattern.*;
+
+/**
+ * Escapes angle brackets inside pre tags (code tags which follow right after pre are not escaped).
+ */
+public class EscapeSourceCodePlugin implements WeblogEntryPlugin {
+
+ private static final String LT = "<"; // '<'
+
+ private static final Pattern PRE_PATTERN = Pattern.compile(
+ "<pre\\s*[^>]*>" + "(.*?)" + "</pre\\s*>", MULTILINE | DOTALL | CASE_INSENSITIVE);
+
+ private static final Pattern CODE_PATTERN = Pattern.compile(
+ "<code\\s*.[^>]*>" + "(.*?)" + "</code\\s*>", MULTILINE | DOTALL | CASE_INSENSITIVE);
+
+ @Override
+ public String getName() {
+ return "Sourcecode Escaper";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Escapes angle brackets inside pre tags, code tags are retained.";
+ }
+
+ @Override
+ public void init(Weblog weblog) throws WebloggerException {}
+
+ @Override
+ public String render(WeblogEntry entry, String str) {
+
+ StringBuilder result = new StringBuilder(str.length()+32);
+
+ Matcher pre_matcher = PRE_PATTERN.matcher(str);
+
+ while(pre_matcher.find()) {
+
+ String pre_full = pre_matcher.group(0);
+ String pre_inner = pre_matcher.group(1);
+
+ Matcher code_matcher = CODE_PATTERN.matcher(pre_inner);
+
+ if (code_matcher.find()) {
+ String code_inner = code_matcher.group(1);
+ pre_matcher.appendReplacement(result, pre_full.replace(code_inner, escape(code_inner)));
+ } else {
+ pre_matcher.appendReplacement(result, pre_full.replace(pre_inner, escape(pre_inner)));
+ }
+
+ }
+ pre_matcher.appendTail(result);
+
+ return result.toString();
+ }
+
+ // we only have to escape the opening angle bracket for valid html/xhtml
+ private static String escape(String code_inner) {
+ return code_inner.replace("<", LT);
+ }
+
+}
diff --git a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
index c82086b..af29d08 100644
--- a/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
+++ b/app/src/main/resources/org/apache/roller/weblogger/config/roller.properties
@@ -548,7 +548,8 @@ guice.backend.module=org.apache.roller.weblogger.business.jpa.JPAWebloggerModule
plugins.page=\
org.apache.roller.weblogger.business.plugins.entry.ConvertLineBreaksPlugin \
,org.apache.roller.weblogger.business.plugins.entry.ObfuscateEmailPlugin \
-,org.apache.roller.weblogger.business.plugins.entry.SmileysPlugin
+,org.apache.roller.weblogger.business.plugins.entry.SmileysPlugin\
+,org.apache.roller.weblogger.business.plugins.entry.EscapeSourceCodePlugin
# The list of configured WeblogEntryEditors available to users
diff --git a/app/src/test/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePluginTest.java b/app/src/test/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePluginTest.java
new file mode 100644
index 0000000..ff7b585
--- /dev/null
+++ b/app/src/test/java/org/apache/roller/weblogger/business/plugins/entry/EscapeSourceCodePluginTest.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business.plugins.entry;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author mbien
+ */
+public class EscapeSourceCodePluginTest {
+
+ @Test
+ public void passthrough() {
+
+ EscapeSourceCodePlugin instance = new EscapeSourceCodePlugin();
+
+ String input = "Stay a while and listen.";
+ assertEquals(input, instance.render(null, input));
+
+ input = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <p>Hello There</p>\n" +
+ " </body>\n" +
+ "</html>";
+ assertEquals(input, instance.render(null, input));
+
+ input = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <pre>Hello There</pre>\n" + // pre
+ " <code>Hello There</code>\n" + // code
+ " </body>\n" +
+ "</html>";
+ assertEquals(input, instance.render(null, input));
+
+ }
+
+ @Test
+ public void substitution1() {
+
+ EscapeSourceCodePlugin instance = new EscapeSourceCodePlugin();
+
+ String input = "<pre><></pre>";
+ String expected = "<pre><></pre>";
+
+ assertEquals(expected, instance.render(null, input));
+
+ }
+
+ @Test
+ public void substitution2() {
+
+ EscapeSourceCodePlugin instance = new EscapeSourceCodePlugin();
+
+ String input = "\n<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <pre><code class='language-java'>private final Map<String, List<?>> map = new HashMap<>();</code></pre>\n"+
+ " </body>\n" +
+ "</html>";
+
+ String expected = "\n<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <pre><code class='language-java'>private final Map<String, List<?>> map = new HashMap<>();</code></pre>\n"+
+ " </body>\n" +
+ "</html>";
+ assertEquals(expected, instance.render(null, input));
+
+ }
+
+ @Test
+ public void substitution3() {
+
+ EscapeSourceCodePlugin instance = new EscapeSourceCodePlugin();
+
+ String input = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <h3>some java</h3>\n" +
+ " <pre>\n" +
+ " <code class='language-java'>\n"+
+ " private final Map<String, List<?>> map = new HashMap<>();\n"+
+ " </code>\n" +
+ " </pre>\n" +
+ " <h3>some xml</h3>\n" +
+ " <pre>\n" +
+ " <code class='language-xml'>\n"+
+ " <foo id = '5'>\n"+
+ " <bar>asdf</bar>\n"+
+ " </foo>\n"+
+ " </code>\n" +
+ " </pre>\n" +
+ " </body>\n" +
+ "</html>";
+
+ String expected = "<!DOCTYPE html>\n" +
+ "<html>\n" +
+ " <head>\n" +
+ " <title>Hi!</title>\n" +
+ " </head>\n" +
+ " <body>\n" +
+ " <h3>some java</h3>\n" +
+ " <pre>\n" +
+ " <code class='language-java'>\n"+
+ " private final Map<String, List<?>> map = new HashMap<>();\n"+
+ " </code>\n" +
+ " </pre>\n" +
+ " <h3>some xml</h3>\n" +
+ " <pre>\n" +
+ " <code class='language-xml'>\n"+
+ " <foo id = '5'>\n"+
+ " <bar>asdf</bar>\n"+
+ " </foo>\n"+
+ " </code>\n" +
+ " </pre>\n" +
+ " </body>\n" +
+ "</html>";
+ assertEquals(expected, instance.render(null, input));
+
+ }
+
+}