From 47a1aa7631f58f47fb59faac5eff63734b4c9aee Mon Sep 17 00:00:00 2001 From: John Niang Date: Mon, 29 Jan 2024 16:58:48 +0800 Subject: [PATCH] Fix the problem of showing 500 error while containing special chars in excerpt (#5263) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core /milestone 2.12.0 #### What this PR does / why we need it: This PR refactors building html meta by using `modelFactory#createStandaloneElementTag`. See https://github.com/halo-dev/halo/issues/4755 for more. #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/4755 #### Special notes for your reviewer: Validate via . #### Does this PR introduce a user-facing change? ```release-note 修复摘要中包含特殊字符导致无法解析页面的问题 ``` --- .../dialect/ContentTemplateHeadProcessor.java | 30 ++++++++----------- .../dialect/DuplicateMetaTagProcessor.java | 15 ++++++++-- ...tTemplateHeadProcessorIntegrationTest.java | 2 +- .../dialect/HaloProcessorDialectTest.java | 6 ++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/application/src/main/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessor.java b/application/src/main/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessor.java index 9da5479543..801270d8e3 100644 --- a/application/src/main/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessor.java +++ b/application/src/main/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessor.java @@ -2,11 +2,13 @@ import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.thymeleaf.model.AttributeValueQuotes.DOUBLE; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; @@ -15,6 +17,7 @@ import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.model.IModel; import org.thymeleaf.model.IModelFactory; +import org.thymeleaf.model.ITemplateEvent; import org.thymeleaf.processor.element.IElementModelStructureHandler; import reactor.core.publisher.Mono; import run.halo.app.theme.DefaultTemplateEnum; @@ -62,11 +65,9 @@ public Mono process(ITemplateContext context, IModel model, } return htmlMetasMono - .doOnNext(htmlMetas -> { - String metaHtml = headMetaBuilder(htmlMetas); - IModelFactory modelFactory = context.getModelFactory(); - model.add(modelFactory.createText(metaHtml)); - }) + .doOnNext( + htmlMetas -> buildMetas(context.getModelFactory(), htmlMetas).forEach(model::add) + ) .then(); } @@ -97,19 +98,12 @@ interface Meta { String CONTENT = "content"; } - private String headMetaBuilder(List> htmlMetas) { - if (htmlMetas == null) { - return StringUtils.EMPTY; - } - StringBuilder sb = new StringBuilder(); - for (Map htmlMeta : htmlMetas) { - sb.append(" { - sb.append(" ").append(k).append("=\"").append(v).append("\""); - }); - sb.append(" />\n"); - } - return sb.toString(); + private List buildMetas(IModelFactory modelFactory, + List> metas) { + return metas.stream() + .map(metaMap -> + modelFactory.createStandaloneElementTag("meta", metaMap, DOUBLE, false, true) + ).collect(Collectors.toList()); } private boolean isPostTemplate(ITemplateContext context) { diff --git a/application/src/main/java/run/halo/app/theme/dialect/DuplicateMetaTagProcessor.java b/application/src/main/java/run/halo/app/theme/dialect/DuplicateMetaTagProcessor.java index b9dac2f4dc..4554f666f9 100644 --- a/application/src/main/java/run/halo/app/theme/dialect/DuplicateMetaTagProcessor.java +++ b/application/src/main/java/run/halo/app/theme/dialect/DuplicateMetaTagProcessor.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Component; import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.model.IModel; +import org.thymeleaf.model.IProcessableElementTag; import org.thymeleaf.model.ITemplateEvent; import org.thymeleaf.model.IText; import org.thymeleaf.processor.element.IElementModelStructureHandler; @@ -59,9 +60,19 @@ public Mono process(ITemplateContext context, IModel model, IText otherText = context.getModelFactory() .createText(text); otherModel.add(new IndexedModel(i, otherText)); - } else { - otherModel.add(new IndexedModel(i, templateEvent)); + continue; } + if (templateEvent instanceof IProcessableElementTag tag) { + var indexedModel = new IndexedModel(i, tag); + if ("meta".equals(tag.getElementCompleteName())) { + var attribute = tag.getAttribute("name"); + if (attribute != null) { + uniqueMetaTags.put(attribute.getValue(), indexedModel); + continue; + } + } + } + otherModel.add(new IndexedModel(i, templateEvent)); } otherModel.addAll(uniqueMetaTags.values()); diff --git a/application/src/test/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessorIntegrationTest.java b/application/src/test/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessorIntegrationTest.java index 0ef34208ff..b7683ae4d5 100644 --- a/application/src/test/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessorIntegrationTest.java +++ b/application/src/test/java/run/halo/app/theme/dialect/ContentTemplateHeadProcessorIntegrationTest.java @@ -146,8 +146,8 @@ void overrideGlobalMetaTest() { Post detail - + diff --git a/application/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java b/application/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java index f572e1d605..178b6abdef 100644 --- a/application/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java +++ b/application/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java @@ -174,9 +174,9 @@ void contentHeadAndFooterAndPostProcessors() { Post - - - + \ + \ + \

post