diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c6a93ca..629aada 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,14 +5,9 @@ - - - + - - - @@ -171,7 +166,7 @@ - + 1695868954392 @@ -224,7 +219,15 @@ - diff --git a/src/main/java/io/v/nutz/web/commons/ext/beetl/BeetlCustomResourceLoader.java b/src/main/java/io/v/nutz/web/commons/ext/beetl/BeetlCustomResourceLoader.java new file mode 100644 index 0000000..0a432e0 --- /dev/null +++ b/src/main/java/io/v/nutz/web/commons/ext/beetl/BeetlCustomResourceLoader.java @@ -0,0 +1,80 @@ +package io.v.nutz.web.commons.ext.beetl; + +import org.beetl.core.Resource; +import org.beetl.core.misc.BeetlUtil; +import org.beetl.core.resource.ClasspathResource; +import org.beetl.core.resource.ClasspathResourceLoader; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BeetlCustomResourceLoader extends ClasspathResourceLoader { + + @Override + public Resource getResource(String key) { + Resource resource = new ClasspathResource(key, this.getChildPath(super.getRoot(), key), this); + return resource; + } + + @Override + public String getResourceId(Resource resource, String id) { +// return resource == null ? id : BeetlUtil.getRelPath(resource.getId(), id); + return getRelPath(resource.getId(), id); + } + + /** + * 增加判断相对路径 + * 光见鬼 + */ + private String getRelPath(String siblings, String resourceId) { + // 参数校验 + if (resourceId == null || resourceId.isEmpty()) { + throw new RuntimeException("资源ID为空,参数错"); + } + + // 如果是绝对路径,直接返回(以 / 或 \ 开头) + if (resourceId.charAt(0) == '\\' || resourceId.charAt(0) == '/') { + if (BeetlUtil.isOutsideOfRoot(resourceId)) { + throw new RuntimeException("不能访问外部文件或者模板"); + } + return resourceId; + } + + // 处理相对路径 + String baseDir = siblings; + // 如果siblings是文件路径,获取其所在目录 + int lastSeparatorIndex = Math.max(siblings.lastIndexOf('/'), siblings.lastIndexOf('\\')); + if (lastSeparatorIndex > 0) { + baseDir = siblings.substring(0, lastSeparatorIndex + 1); + } + + // 分割路径 + String[] parts = resourceId.replace('\\', '/').split("/"); + List baseParts = new ArrayList<>( + Arrays.asList(baseDir.replace('\\', '/').split("/")) + ); + baseParts.removeIf(String::isEmpty); + + // 处理 ../ 和 ./ + for (String part : parts) { + if ("..".equals(part)) { + if (!baseParts.isEmpty()) { + baseParts.remove(baseParts.size() - 1); + } + } else if (!".".equals(part) && !part.isEmpty()) { + baseParts.add(part); + } + } + + // 组合最终路径 + String result = "/" + String.join("/", baseParts); + + // 检查是否访问外部文件 + if (BeetlUtil.isOutsideOfRoot(result)) { + throw new RuntimeException("不能访问外部文件或者模板"); + } + return result; + } + +}