5 -- This project is MIT/X11 licensed. Please see the |
5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. |
6 -- COPYING file in the source package for more information. |
7 -- |
7 -- |
8 |
8 |
9 |
9 |
10 local assert = assert; |
10 local error = error; |
11 local t_insert = table.insert; |
11 local t_insert = table.insert; |
12 local t_remove = table.remove; |
12 local t_remove = table.remove; |
13 local t_concat = table.concat; |
13 local t_concat = table.concat; |
14 local s_format = string.format; |
14 local s_format = string.format; |
15 local s_match = string.match; |
15 local s_match = string.match; |
43 -- luacheck: std none |
43 -- luacheck: std none |
44 |
44 |
45 local stanza_mt = { __name = "stanza" }; |
45 local stanza_mt = { __name = "stanza" }; |
46 stanza_mt.__index = stanza_mt; |
46 stanza_mt.__index = stanza_mt; |
47 |
47 |
48 local function check_name(name) |
48 local function check_name(name, name_type) |
49 assert(type(name) == "string", "tag name is not a string, "..type(name)); |
49 if type(name) ~= "string" then |
50 assert(#name > 0, "tag name is empty"); |
50 error("invalid "..name_type.." name: expected string, got "..type(name)); |
51 assert(not s_find(name, "[<>& '\"]"), "tag name contains invalid characters"); |
51 elseif #name == 0 then |
52 assert(valid_utf8(name), "tag name is invalid utf8"); |
52 error("invalid "..name_type.." name: empty string"); |
53 end |
53 elseif s_find(name, "[<>& '\"]") then |
|
54 error("invalid "..name_type.." name: contains invalid characters"); |
|
55 elseif not valid_utf8(name) then |
|
56 error("invalid "..name_type.." name: contains invalid utf8"); |
|
57 end |
|
58 end |
|
59 |
|
60 local function check_text(text, text_type) |
|
61 if type(text) ~= "string" then |
|
62 error("invalid "..text_type.." value: expected string, got "..type(text)); |
|
63 elseif not valid_utf8(text) then |
|
64 error("invalid "..text_type.." value: contains invalid utf8"); |
|
65 end |
|
66 end |
|
67 |
54 local function check_attr(attr) |
68 local function check_attr(attr) |
55 if attr ~= nil then |
69 if attr ~= nil then |
56 assert(type(attr) == "table", "attribute is not a table"); |
70 if type(attr) ~= "table" then |
|
71 error("invalid attributes, expected table got "..type(attr)); |
|
72 end |
57 for k, v in pairs(attr) do |
73 for k, v in pairs(attr) do |
58 assert(type(k) == "string", "non-string key in attributes"); |
74 check_name(k, "attribute"); |
59 assert(valid_utf8(k), "attribute name is not valid utf8"); |
75 check_text(v, "attribute"); |
60 assert(type(v) == "string", "non-string value in attributes"); |
76 if type(v) ~= "string" then |
61 assert(valid_utf8(v), "attribute value is not valid utf8"); |
77 error("invalid attribute value for '"..k.."': expected string, got "..type(v)); |
62 end |
78 elseif not valid_utf8(v) then |
63 end |
79 error("invalid attribute value for '"..k.."': contains invalid utf8"); |
64 end |
80 end |
65 local function check_text(text) |
81 end |
66 assert(type(text) == "string", "text is not a string"); |
82 end |
67 assert(valid_utf8(text), "text is not valid utf8"); |
|
68 end |
83 end |
69 |
84 |
70 local function new_stanza(name, attr, namespaces) |
85 local function new_stanza(name, attr, namespaces) |
71 assert(name) |
86 check_name(name, "tag"); |
72 check_name(name); |
|
73 check_attr(attr); |
87 check_attr(attr); |
74 local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} }; |
88 local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} }; |
75 return setmetatable(stanza, stanza_mt); |
89 return setmetatable(stanza, stanza_mt); |
76 end |
90 end |
77 |
91 |