fix: 优化 escape 和 unescape 在解析某些特殊字符串时的潜在问题 (#2628)

* fix: 修复 escape 未转义 unicode 中 & 字符的问题

* chore: update

* fix: 优化 unescape 替换顺序,确保为 escape 替换的反向顺序

* chore: update
2.9.x-stable
贤心 2025-04-15 13:23:32 +08:00
parent 28da41f5ac
commit aedd2862a6
2 changed files with 21 additions and 21 deletions

View File

@ -20,19 +20,20 @@
<span>{{= item.site || '' }}</span> <span>{{= item.site || '' }}</span>
</li> </li>
{{# }); }} {{# }); }}
{{# if(d.list.length === 0){ }} {{# if(d.list.length === 0){ }}
无数据 无数据
{{# } }} {{# } }}
</ul> </ul>
&lt;/textarea> &lt;/textarea>
</div> </div>
<div class="layui-col-xs6 laytpl-demo"> <div class="layui-col-xs6 laytpl-demo">
<div>数据</div> <div>数据</div>
&lt;textarea id="ID-tpl-data"&gt; &lt;textarea id="ID-tpl-data"&gt;
{ {
"title": "Layui 常用模块", "title": "Layui 常用组件",
"desc": "<a style=\"color:blue;\">一段带 HTML 的内容</a>",
"list": [ "list": [
{ {
"modname": "弹层", "modname": "弹层",
@ -71,7 +72,7 @@
</div> </div>
<div class="layui-clear"></div> <div class="layui-clear"></div>
<!-- import layui --> <!-- import layui -->
<script> <script>
layui.use(function(){ layui.use(function(){
var laytpl = layui.laytpl; var laytpl = layui.laytpl;
@ -91,9 +92,9 @@ layui.use(function(){
}() }()
}; };
}; };
var data = get(); var data = get();
// 耗时计算 // 耗时计算
var startTime = new Date().getTime(), timer = function(startTime, title){ var startTime = new Date().getTime(), timer = function(startTime, title){
var endTime = new Date().getTime(); var endTime = new Date().getTime();
@ -108,20 +109,20 @@ layui.use(function(){
timer(startTime); timer(startTime);
$('#ID-tpl-view').html(view); $('#ID-tpl-view').html(view);
}); });
// 编辑 // 编辑
$('.laytpl-demo textarea').on('input propertychange', function(){ $('.laytpl-demo textarea').on('input propertychange', function(){
var data = get(); var data = get();
if(!data.data) return; if(!data.data) return;
// 计算模板渲染耗时 // 计算模板渲染耗时
var startTime = new Date().getTime(); var startTime = new Date().getTime();
// 若模板有变化,则重新解析模板;若模板没变,数据有变化,则从模板缓存中直接渲染(效率大增) // 若模板有变化,则重新解析模板;若模板没变,数据有变化,则从模板缓存中直接渲染(效率大增)
if(this.id === 'ID-tpl-src'){ if(this.id === 'ID-tpl-src'){
thisTpl.parse(data.template, data.data); // 解析模板 thisTpl.parse(data.template, data.data); // 解析模板
} }
// 执行渲染 // 执行渲染
thisTpl.render(data.data, function(view){ thisTpl.render(data.data, function(view){
timer(startTime); timer(startTime);

View File

@ -323,25 +323,24 @@ layui.define('jquery', function(exports){
// 转义 html // 转义 html
escape: function(html){ escape: function(html){
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g; var exp = /[<"'>]|&(?=#?[a-zA-Z0-9]+)/g;
if(html === undefined || html === null) return ''; if (html === undefined || html === null) return '';
html += ''; html += '';
if(!exp.test(html)) return html; if (!exp.test(html)) return html;
return html.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;') return html.replace(/&(?=#?[a-zA-Z0-9]+;?)/g, '&amp;')
.replace(/</g, '&lt;').replace(/>/g, '&gt;') .replace(/</g, '&lt;').replace(/>/g, '&gt;')
.replace(/'/g, '&#39;').replace(/"/g, '&quot;'); .replace(/'/g, '&#39;').replace(/"/g, '&quot;');
}, },
// 还原转义的 html // 还原转义的 html
unescape: function(html){ unescape: function(html){
if(html === undefined || html === null) html = ''; if (html === undefined || html === null) return '';
html += '';
return html.replace(/\&amp;/g, '&') return String(html).replace(/\&quot;/g, '"').replace(/\&#39;/g, '\'')
.replace(/\&lt;/g, '<').replace(/\&gt;/g, '>') .replace(/\&gt;/g, '>').replace(/\&lt;/g, '<')
.replace(/\&#39;/g, '\'').replace(/\&quot;/g, '"'); .replace(/\&amp;/g, '&');
}, },
// 打开新窗口 // 打开新窗口