-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProfileValidator.lua
More file actions
103 lines (88 loc) · 2.49 KB
/
ProfileValidator.lua
File metadata and controls
103 lines (88 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
local AceAddon = LibStub("AceAddon-3.0")
local addon = AceAddon and AceAddon:GetAddon("SimpleUnitFrames", true)
if not addon then
return
end
local DEFAULT_MAX_DEPTH = 20
local DEFAULT_MAX_NODES = 50000
local function IsUnsupportedType(valueType)
return valueType == "function" or valueType == "thread" or valueType == "userdata"
end
local function FormatPathSegment(key)
local keyType = type(key)
if keyType == "string" then
return "." .. key
elseif keyType == "number" then
return "[" .. tostring(key) .. "]"
elseif keyType == "boolean" then
return "[" .. tostring(key) .. "]"
elseif keyType == "table" then
return ".[table-key]"
end
return ".[key:" .. keyType .. "]"
end
function addon:ValidateImportTree(root, maxDepth, maxNodes)
if type(root) ~= "table" then
return false, "Imported data is not a table."
end
local depthLimit = tonumber(maxDepth) or DEFAULT_MAX_DEPTH
local nodeLimit = tonumber(maxNodes) or DEFAULT_MAX_NODES
if depthLimit < 1 then
depthLimit = DEFAULT_MAX_DEPTH
end
if nodeLimit < 1 then
nodeLimit = DEFAULT_MAX_NODES
end
local seen = {}
local stack = {
{ node = root, depth = 1, path = "root" },
}
local nodeCount = 0
while #stack > 0 do
local current = stack[#stack]
stack[#stack] = nil
local node = current.node
local depth = current.depth
local path = current.path
if depth > depthLimit then
return false, ("Import nesting is too deep near %s (max depth %d)."):
format(path, depthLimit)
end
nodeCount = nodeCount + 1
if nodeCount > nodeLimit then
return false, ("Import data is too large (max %d table nodes)."):
format(nodeLimit)
end
if seen[node] then
return false, "Import contains cyclic or repeated table references and cannot be safely imported."
end
seen[node] = true
for key, value in pairs(node) do
local keyType = type(key)
if IsUnsupportedType(keyType) then
return false, ("Import contains unsupported key type '%s' near %s."):
format(keyType, path)
end
local valueType = type(value)
if IsUnsupportedType(valueType) then
return false, ("Import contains unsupported value type '%s' near %s%s."):
format(valueType, path, FormatPathSegment(key))
end
if keyType == "table" then
stack[#stack + 1] = {
node = key,
depth = depth + 1,
path = path .. ".[table-key]",
}
end
if valueType == "table" then
stack[#stack + 1] = {
node = value,
depth = depth + 1,
path = path .. FormatPathSegment(key),
}
end
end
end
return true
end