Software /
code /
prosody
Comparison
util/format.lua @ 11638:5f4a657136bc
util.format: Escape ASCII control characters in output
This should offer some protection against doing evil things to
terminals. Doesn't protect against pure broken UTF-8 garbage however.
See #734
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 15 Jun 2021 23:24:23 +0200 |
parent | 10035:386f085820e6 |
child | 11644:fc1b8fe94d04 |
comparison
equal
deleted
inserted
replaced
11637:19cddf92fcc2 | 11638:5f4a657136bc |
---|---|
11 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; | 11 return n % 1 == 0 and n <= 9007199254740992 and n >= -9007199254740992 and "integer" or "float"; |
12 end | 12 end |
13 | 13 |
14 -- In Lua 5.3+ these formats throw an error if given a float | 14 -- In Lua 5.3+ these formats throw an error if given a float |
15 local expects_integer = { c = true, d = true, i = true, o = true, u = true, X = true, x = true, }; | 15 local expects_integer = { c = true, d = true, i = true, o = true, u = true, X = true, x = true, }; |
16 -- Printable Unicode replacements for control characters | |
17 local control_symbols = { | |
18 -- 0x00 .. 0x1F --> U+2400 .. U+241F, 0x7F --> U+2421 | |
19 ["\000"] = "\226\144\128", ["\001"] = "\226\144\129", ["\002"] = "\226\144\130", | |
20 ["\003"] = "\226\144\131", ["\004"] = "\226\144\132", ["\005"] = "\226\144\133", | |
21 ["\006"] = "\226\144\134", ["\007"] = "\226\144\135", ["\008"] = "\226\144\136", | |
22 ["\009"] = "\226\144\137", ["\010"] = "\226\144\138", ["\011"] = "\226\144\139", | |
23 ["\012"] = "\226\144\140", ["\013"] = "\226\144\141", ["\014"] = "\226\144\142", | |
24 ["\015"] = "\226\144\143", ["\016"] = "\226\144\144", ["\017"] = "\226\144\145", | |
25 ["\018"] = "\226\144\146", ["\019"] = "\226\144\147", ["\020"] = "\226\144\148", | |
26 ["\021"] = "\226\144\149", ["\022"] = "\226\144\150", ["\023"] = "\226\144\151", | |
27 ["\024"] = "\226\144\152", ["\025"] = "\226\144\153", ["\026"] = "\226\144\154", | |
28 ["\027"] = "\226\144\155", ["\028"] = "\226\144\156", ["\029"] = "\226\144\157", | |
29 ["\030"] = "\226\144\158", ["\031"] = "\226\144\159", ["\127"] = "\226\144\161", | |
30 }; | |
16 | 31 |
17 local function format(formatstring, ...) | 32 local function format(formatstring, ...) |
18 local args = pack(...); | 33 local args = pack(...); |
19 local args_length = args.n; | 34 local args_length = args.n; |
20 | 35 |
43 spec = "<%s>"; | 58 spec = "<%s>"; |
44 elseif option == "q" then | 59 elseif option == "q" then |
45 args[i] = dump(arg); | 60 args[i] = dump(arg); |
46 spec = "%s"; | 61 spec = "%s"; |
47 elseif option == "s" then | 62 elseif option == "s" then |
48 args[i] = tostring(arg); | 63 args[i] = tostring(arg):gsub("[%z\1-31\127]", control_symbols); |
49 elseif type(arg) ~= "number" then -- arg isn't number as expected? | 64 elseif type(arg) ~= "number" then -- arg isn't number as expected? |
50 args[i] = tostring(arg); | 65 args[i] = tostring(arg); |
51 spec = "[%s]"; | 66 spec = "[%s]"; |
52 elseif expects_integer[option] and num_type(arg) ~= "integer" then | 67 elseif expects_integer[option] and num_type(arg) ~= "integer" then |
53 args[i] = tostring(arg); | 68 args[i] = tostring(arg); |