Comparison

util/stanza.lua @ 8599:62bfc85a53c8

util.stanza: Add stricter validation for data passed to stanza builder API
author Matthew Wild <mwild1@gmail.com>
date Fri, 16 Mar 2018 14:51:24 +0000
parent 8555:4f0f5b49bb03
child 8626:20532f191f8d
comparison
equal deleted inserted replaced
8598:282d544d48f4 8599:62bfc85a53c8
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 t_insert = table.insert; 11 local t_insert = table.insert;
11 local t_remove = table.remove; 12 local t_remove = table.remove;
12 local t_concat = table.concat; 13 local t_concat = table.concat;
13 local s_format = string.format; 14 local s_format = string.format;
14 local s_match = string.match; 15 local s_match = string.match;
21 local s_gsub = string.gsub; 22 local s_gsub = string.gsub;
22 local s_sub = string.sub; 23 local s_sub = string.sub;
23 local s_find = string.find; 24 local s_find = string.find;
24 local os = os; 25 local os = os;
25 26
27 local valid_utf8 = require "util.encodings".utf8.valid;
28
26 local do_pretty_printing = not os.getenv("WINDIR"); 29 local do_pretty_printing = not os.getenv("WINDIR");
27 local getstyle, getstring; 30 local getstyle, getstring;
28 if do_pretty_printing then 31 if do_pretty_printing then
29 local ok, termcolours = pcall(require, "util.termcolours"); 32 local ok, termcolours = pcall(require, "util.termcolours");
30 if ok then 33 if ok then
40 -- luacheck: std none 43 -- luacheck: std none
41 44
42 local stanza_mt = { __name = "stanza" }; 45 local stanza_mt = { __name = "stanza" };
43 stanza_mt.__index = stanza_mt; 46 stanza_mt.__index = stanza_mt;
44 47
48 local function check_name(name)
49 assert(type(name) == "string", "tag name is not a string, "..type(name));
50 assert(#name > 0, "tag name is empty");
51 assert(not s_find(name, "[<>& '\"]"), "tag name contains invalid characters");
52 assert(valid_utf8(name), "tag name is invalid utf8");
53 end
54 local function check_attr(attr)
55 if attr ~= nil then
56 assert(type(attr) == "table", "attribute is not a table");
57 for k, v in pairs(attr) do
58 assert(type(k) == "string", "non-string key in attributes");
59 assert(valid_utf8(k), "attribute name is not valid utf8");
60 assert(type(v) == "string", "non-string value in attributes");
61 assert(valid_utf8(v), "attribute value is not valid utf8");
62 end
63 end
64 end
65 local function check_text(text)
66 assert(type(text) == "string", "text is not a string");
67 assert(valid_utf8(text), "text is not valid utf8");
68 end
69
45 local function new_stanza(name, attr, namespaces) 70 local function new_stanza(name, attr, namespaces)
71 assert(name)
72 check_name(name);
73 check_attr(attr);
46 local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} }; 74 local stanza = { name = name, attr = attr or {}, namespaces = namespaces, tags = {} };
47 return setmetatable(stanza, stanza_mt); 75 return setmetatable(stanza, stanza_mt);
48 end 76 end
49 77
50 local function is_stanza(s) 78 local function is_stanza(s)
67 t_insert(last_add, s); 95 t_insert(last_add, s);
68 return self; 96 return self;
69 end 97 end
70 98
71 function stanza_mt:text(text) 99 function stanza_mt:text(text)
100 check_text(text);
72 local last_add = self.last_add; 101 local last_add = self.last_add;
73 (last_add and last_add[#last_add] or self):add_direct_child(text); 102 (last_add and last_add[#last_add] or self):add_direct_child(text);
74 return self; 103 return self;
75 end 104 end
76 105