fix: xml parser (#2140)

This commit is contained in:
yetone
2025-06-04 04:50:18 +08:00
committed by GitHub
parent 28f0bf75d0
commit 690f25a89e

View File

@@ -57,7 +57,7 @@ local function parseAttributes(attrStr)
if not attrStr or attrStr == "" then return attrs end if not attrStr or attrStr == "" then return attrs end
-- 匹配属性模式name="value" 或 name='value' -- 匹配属性模式name="value" 或 name='value'
for name, value in attrStr:gmatch("([-_%w]+)%s*=%s*[\"']([^\"']*)[\"']") do for name, value in attrStr:gmatch("([_%w]+)%s*=%s*[\"']([^\"']*)[\"']") do
attrs[name] = value attrs[name] = value
end end
return attrs return attrs
@@ -97,11 +97,11 @@ local function isValidXmlTag(tag, xmlContent, tagStart)
if not tag:match("^<[^<>]*>$") then return false end if not tag:match("^<[^<>]*>$") then return false end
-- 检查是否是合法的标签格式 -- 检查是否是合法的标签格式
if tag:match("^</[-_%w]+>$") then return true end -- 结束标签 if tag:match("^</[_%w]+>$") then return true end -- 结束标签
if tag:match("^<[-_%w]+[^>]*/>$") then return true end -- 自闭合标签 if tag:match("^<[_%w]+[^>]*/>$") then return true end -- 自闭合标签
if tag:match("^<[-_%w]+[^>]*>$") then if tag:match("^<[_%w]+[^>]*>$") then
-- 对于开始标签,进行额外的上下文检查 -- 对于开始标签,进行额外的上下文检查
local tagName = tag:match("^<([-_%w]+)") local tagName = tag:match("^<([_%w]+)")
-- 检查是否存在对应的结束标签 -- 检查是否存在对应的结束标签
local closingTag = "</" .. tagName .. ">" local closingTag = "</" .. tagName .. ">"
@@ -152,17 +152,17 @@ function StreamParser:parseBuffer()
local remaining = self.buffer:sub(self.position) local remaining = self.buffer:sub(self.position)
-- 查找下一个标签 -- 查找下一个标签
local tagStart, tagEnd = remaining:find("<[^>]*>") local tagStart, tagEnd = remaining:find("</?[%w_]+>")
if not tagStart then if not tagStart then
-- 检查是否有未完成的开始标签(以<开始但没有>结束) -- 检查是否有未完成的开始标签(以<开始但没有>结束)
local incompleteStart = remaining:find("<[^>]*$") local incompleteStart = remaining:find("<[%w_]+$")
if incompleteStart then if incompleteStart then
local incompleteContent = remaining:sub(incompleteStart) local incompleteContent = remaining:sub(incompleteStart)
-- 确保这确实是一个未完成的标签,而不是文本中的<符号 -- 确保这确实是一个未完成的标签,而不是文本中的<符号
if incompleteContent:match("^<[%w_-]") then if incompleteContent:match("^<[%w_]") then
-- 尝试解析未完成的开始标签 -- 尝试解析未完成的开始标签
local tagName = incompleteContent:match("^<([%w_-]+)") local tagName = incompleteContent:match("^<([%w_]+)")
if tagName then if tagName then
-- 处理未完成标签前的文本 -- 处理未完成标签前的文本
if incompleteStart > 1 then if incompleteStart > 1 then
@@ -347,8 +347,8 @@ function StreamParser:parseBuffer()
local currentDepth = #self.stack local currentDepth = #self.stack
if currentDepth >= 1 then if currentDepth >= 1 then
-- 检查是否是当前元素的结束标签 -- 检查是否是当前元素的结束标签
if tag:match("^</[-_%w]+>$") and self.current then if tag:match("^</[_%w]+>$") and self.current then
local tagName = tag:match("^</([-_%w]+)>$") local tagName = tag:match("^</([_%w]+)>$")
if self.current._name == tagName then if self.current._name == tagName then
-- 这是当前元素的结束标签,正常处理 -- 这是当前元素的结束标签,正常处理
if not self:processTag(tag) then if not self:processTag(tag) then
@@ -396,9 +396,9 @@ end
-- 处理单个标签 -- 处理单个标签
function StreamParser:processTag(tag) function StreamParser:processTag(tag)
if tag:match("^</[-_%w]+>$") then if tag:match("^</[_%w]+>$") then
-- 结束标签 -- 结束标签
local tagName = tag:match("^</([-_%w]+)>$") local tagName = tag:match("^</([_%w]+)>$")
if self.current and self.current._name == tagName then if self.current and self.current._name == tagName then
-- 标记当前元素为完成状态 -- 标记当前元素为完成状态
self.current._state = "complete" self.current._state = "complete"
@@ -412,9 +412,9 @@ function StreamParser:processTag(tag)
self.last_error = "Mismatched closing tag: " .. tagName self.last_error = "Mismatched closing tag: " .. tagName
return false return false
end end
elseif tag:match("^<[-_%w]+[^>]*/>$") then elseif tag:match("^<[_%w]+[^>]*/>$") then
-- 自闭合标签 -- 自闭合标签
local tagName, attrs = tag:match("^<([-_%w]+)([^>]*)/>") local tagName, attrs = tag:match("^<([_%w]+)([^>]*)/>")
local element = { local element = {
_name = tagName, _name = tagName,
_attr = parseAttributes(attrs), _attr = parseAttributes(attrs),
@@ -429,9 +429,9 @@ function StreamParser:processTag(tag)
if not self.current.children then self.current.children = {} end if not self.current.children then self.current.children = {} end
table.insert(self.current.children, element) table.insert(self.current.children, element)
end end
elseif tag:match("^<[-_%w]+[^>]*>$") then elseif tag:match("^<[_%w]+[^>]*>$") then
-- 开始标签 -- 开始标签
local tagName, attrs = tag:match("^<([-_%w]+)([^>]*)>") local tagName, attrs = tag:match("^<([_%w]+)([^>]*)>")
local element = { local element = {
_name = tagName, _name = tagName,
_attr = parseAttributes(attrs), _attr = parseAttributes(attrs),