mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Use local functions instead of anonymous functions for gsub (less GC overhead)
This commit is contained in:
@@ -78,6 +78,10 @@ local function clamp (args, i, j, mask)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function _fromhex (s)
|
||||||
|
return char(tonumber(s, 16))
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns a binary packed string.
|
--- Returns a binary packed string.
|
||||||
--
|
--
|
||||||
-- The format string describes how the parameters (<code>p1</code>,
|
-- The format string describes how the parameters (<code>p1</code>,
|
||||||
@@ -107,7 +111,7 @@ function _ENV.pack (format, ...)
|
|||||||
assert(n > 0, "n cannot be 0") -- original bin library allowed this, it doesn't make sense
|
assert(n > 0, "n cannot be 0") -- original bin library allowed this, it doesn't make sense
|
||||||
local new = "=" -- !! in original bin library, hex strings are always native
|
local new = "=" -- !! in original bin library, hex strings are always native
|
||||||
for j = i, i+n-1 do
|
for j = i, i+n-1 do
|
||||||
args[j] = tostring(args[j]):gsub("%s*(%S%S?)%s*", function (s) return char(tonumber(s, 16)) end)
|
args[j] = tostring(args[j]):gsub("%s*(%S%S?)%s*", _fromhex)
|
||||||
new = new .. ("c%d"):format(#args[j])
|
new = new .. ("c%d"):format(#args[j])
|
||||||
end
|
end
|
||||||
new = new .. endianness -- restore old endianness
|
new = new .. endianness -- restore old endianness
|
||||||
@@ -208,15 +212,24 @@ do
|
|||||||
assert(_ENV.pack("<C2SIL", 0x123, 0xfff1, 0x1ffff, 0x112345678, 0x1234567812345678) == "\x23\xf1\xff\xff\x78\x56\x34\x12\x78\x56\x34\x12\x78\x56\x34\x12")
|
assert(_ENV.pack("<C2SIL", 0x123, 0xfff1, 0x1ffff, 0x112345678, 0x1234567812345678) == "\x23\xf1\xff\xff\x78\x56\x34\x12\x78\x56\x34\x12\x78\x56\x34\x12")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function _fmt_hex (c)
|
||||||
|
return ("%02X"):format(c:byte())
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _fmt_bin (c)
|
||||||
|
local n = tobinary(c:byte())
|
||||||
|
return ("0"):rep(8-#n)..n
|
||||||
|
end
|
||||||
|
|
||||||
local function unpacker (fixer, status, ...)
|
local function unpacker (fixer, status, ...)
|
||||||
if not status then return 1 end
|
if not status then return 1 end
|
||||||
-- Lua's unpack gives the stop index last:
|
-- Lua's unpack gives the stop index last:
|
||||||
local list = pack(...)
|
local list = pack(...)
|
||||||
for i, v in ipairs(fixer) do
|
for i, v in ipairs(fixer) do
|
||||||
if v.what == "H" then
|
if v.what == "H" then
|
||||||
list[v.which] = list[v.which]:gsub(".", function (c) return ("%02X"):format(c:byte()) end)
|
list[v.which] = list[v.which]:gsub(".", _fmt_hex)
|
||||||
elseif v.what == "B" then
|
elseif v.what == "B" then
|
||||||
list[v.which] = list[v.which]:gsub(".", function (c) local n = tobinary(c:byte()); return ("0"):rep(8-#n)..n end)
|
list[v.which] = list[v.which]:gsub(".", _fmt_bin)
|
||||||
else
|
else
|
||||||
assert(false)
|
assert(false)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -680,9 +680,28 @@ end
|
|||||||
|
|
||||||
|
|
||||||
local bin_lookup = {
|
local bin_lookup = {
|
||||||
[0]="0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
|
["0"]="0000",
|
||||||
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111",
|
["1"]="0001",
|
||||||
|
["2"]="0010",
|
||||||
|
["3"]="0011",
|
||||||
|
["4"]="0100",
|
||||||
|
["5"]="0101",
|
||||||
|
["6"]="0110",
|
||||||
|
["7"]="0111",
|
||||||
|
["8"]="1000",
|
||||||
|
["9"]="1001",
|
||||||
|
["a"]="1010",
|
||||||
|
["b"]="1011",
|
||||||
|
["c"]="1100",
|
||||||
|
["d"]="1101",
|
||||||
|
["e"]="1110",
|
||||||
|
["f"]="1111",
|
||||||
}
|
}
|
||||||
|
setmetatable(bin_lookup, {
|
||||||
|
__index = function()
|
||||||
|
error("Error in ipOps.hex_to_bin: Expected string representing a hexadecimal number.")
|
||||||
|
end
|
||||||
|
})
|
||||||
---
|
---
|
||||||
-- Converts a string of hexadecimal digits into the corresponding string of
|
-- Converts a string of hexadecimal digits into the corresponding string of
|
||||||
-- binary digits.
|
-- binary digits.
|
||||||
@@ -699,14 +718,7 @@ hex_to_bin = function( hex )
|
|||||||
return nil, "Error in ipOps.hex_to_bin: Expected string"
|
return nil, "Error in ipOps.hex_to_bin: Expected string"
|
||||||
end
|
end
|
||||||
|
|
||||||
local status, result = pcall( string.gsub, hex, ".", function(nibble)
|
local status, result = pcall( string.gsub, string.lower(hex), ".", bin_lookup)
|
||||||
local n = bin_lookup[tonumber(nibble, 16)]
|
|
||||||
if n then
|
|
||||||
return n
|
|
||||||
else
|
|
||||||
error("Error in ipOps.hex_to_bin: Expected string representing a hexadecimal number.")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
if status then
|
if status then
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
@@ -820,7 +832,7 @@ end
|
|||||||
do
|
do
|
||||||
for _, h in ipairs({
|
for _, h in ipairs({
|
||||||
{"a", "1010"},
|
{"a", "1010"},
|
||||||
{"aa", "10101010"},
|
{"aA", "10101010"},
|
||||||
{"12", "00010010"},
|
{"12", "00010010"},
|
||||||
{"54321", "01010100001100100001"},
|
{"54321", "01010100001100100001"},
|
||||||
{"123error", false},
|
{"123error", false},
|
||||||
|
|||||||
@@ -445,6 +445,9 @@ end
|
|||||||
-- Helpers
|
-- Helpers
|
||||||
|
|
||||||
|
|
||||||
|
local function _hex_str (x)
|
||||||
|
return string.char(tonumber(x, 16))
|
||||||
|
end
|
||||||
--- Convert a MAC address string (like <code>"00:23:ae:5d:3b:10"</code>) to
|
--- Convert a MAC address string (like <code>"00:23:ae:5d:3b:10"</code>) to
|
||||||
-- a raw six-byte long.
|
-- a raw six-byte long.
|
||||||
-- @param str MAC address string.
|
-- @param str MAC address string.
|
||||||
@@ -453,9 +456,7 @@ function mactobin(str)
|
|||||||
if not str then
|
if not str then
|
||||||
return nil, "MAC was not specified."
|
return nil, "MAC was not specified."
|
||||||
end
|
end
|
||||||
return (str:gsub("(%x%x)[^%x]?", function (x)
|
return (str:gsub("(%x%x)[^%x]?", _hex_str))
|
||||||
return string.char(tonumber(x, 16))
|
|
||||||
end))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Generate the link-local IPv6 address from the MAC address.
|
--- Generate the link-local IPv6 address from the MAC address.
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ end
|
|||||||
-- This pattern must match the percent sign '%' since it is used in
|
-- This pattern must match the percent sign '%' since it is used in
|
||||||
-- escaping.
|
-- escaping.
|
||||||
local FILESYSTEM_UNSAFE = "[^a-zA-Z0-9._-]"
|
local FILESYSTEM_UNSAFE = "[^a-zA-Z0-9._-]"
|
||||||
|
local function _escape_helper (c)
|
||||||
|
return format("%%%02x", byte(c))
|
||||||
|
end
|
||||||
---
|
---
|
||||||
-- Escape a string to remove bytes and strings that may have meaning to
|
-- Escape a string to remove bytes and strings that may have meaning to
|
||||||
-- a filesystem, such as slashes.
|
-- a filesystem, such as slashes.
|
||||||
@@ -97,9 +100,7 @@ function filename_escape(s)
|
|||||||
elseif s == ".." then
|
elseif s == ".." then
|
||||||
return "%2e%2e"
|
return "%2e%2e"
|
||||||
else
|
else
|
||||||
return (gsub(s, FILESYSTEM_UNSAFE, function (c)
|
return (gsub(s, FILESYSTEM_UNSAFE, _escape_helper))
|
||||||
return format("%%%02x", byte(c))
|
|
||||||
end))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -57,12 +57,17 @@ local function make_set(t)
|
|||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function hex_esc (c)
|
||||||
|
return string.format("%%%02x", string.byte(c))
|
||||||
|
end
|
||||||
|
|
||||||
-- these are allowed within a path segment, along with alphanum
|
-- these are allowed within a path segment, along with alphanum
|
||||||
-- other characters must be escaped
|
-- other characters must be escaped
|
||||||
local segment_set = make_set {
|
local segment_set = make_set {
|
||||||
"-", "_", ".", "!", "~", "*", "'", "(",
|
"-", "_", ".", "!", "~", "*", "'", "(",
|
||||||
")", ":", "@", "&", "=", "+", "$", ",",
|
")", ":", "@", "&", "=", "+", "$", ",",
|
||||||
}
|
}
|
||||||
|
setmetatable(segment_set, { __index = hex_esc })
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Protects a path segment, to prevent it from interfering with the
|
-- Protects a path segment, to prevent it from interfering with the
|
||||||
@@ -70,10 +75,7 @@ local segment_set = make_set {
|
|||||||
-- @param s Binary string to be encoded.
|
-- @param s Binary string to be encoded.
|
||||||
-- @return Escaped representation of string.
|
-- @return Escaped representation of string.
|
||||||
local function protect_segment(s)
|
local function protect_segment(s)
|
||||||
return string.gsub(s, "([^A-Za-z0-9_.~-])", function (c)
|
return string.gsub(s, "([^A-Za-z0-9_.~-])", segment_set)
|
||||||
if segment_set[c] then return c
|
|
||||||
else return string.format("%%%02x", string.byte(c)) end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -115,25 +117,26 @@ end
|
|||||||
-- @return Escaped representation of string.
|
-- @return Escaped representation of string.
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
function escape(s)
|
function escape(s)
|
||||||
local ret = string.gsub(s, "([^A-Za-z0-9_.~-])", function(c)
|
return (string.gsub(s, "([^A-Za-z0-9_.~-])", hex_esc))
|
||||||
return string.format("%%%02x", string.byte(c))
|
|
||||||
end)
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function hex_unesc (hex)
|
||||||
|
return string.char(base.tonumber(hex, 16))
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Decodes an escaped hexadecimal string.
|
-- Decodes an escaped hexadecimal string.
|
||||||
-- @param s Hexadecimal-encoded string.
|
-- @param s Hexadecimal-encoded string.
|
||||||
-- @return Decoded string.
|
-- @return Decoded string.
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
function unescape(s)
|
function unescape(s)
|
||||||
local ret = string.gsub(s, "%%(%x%x)", function(hex)
|
return (string.gsub(s, "%%(%x%x)", hex_unesc))
|
||||||
return string.char(base.tonumber(hex, 16))
|
|
||||||
end)
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function normalize_escape (s)
|
||||||
|
return escape(unescape(s))
|
||||||
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Parses a URL and returns a table with all its parts according to RFC 3986.
|
-- Parses a URL and returns a table with all its parts according to RFC 3986.
|
||||||
@@ -171,14 +174,7 @@ function parse(url, default)
|
|||||||
-- remove whitespace
|
-- remove whitespace
|
||||||
-- url = string.gsub(url, "%s", "")
|
-- url = string.gsub(url, "%s", "")
|
||||||
-- Decode unreserved characters
|
-- Decode unreserved characters
|
||||||
url = string.gsub(url, "%%(%x%x)", function(hex)
|
url = string.gsub(url, "%%%x%x", normalize_escape)
|
||||||
local char = string.char(base.tonumber(hex, 16))
|
|
||||||
if string.match(char, "[a-zA-Z0-9._~-]") then
|
|
||||||
return char
|
|
||||||
end
|
|
||||||
-- Hex encodings that are not unreserved must be preserved.
|
|
||||||
return nil
|
|
||||||
end)
|
|
||||||
-- get fragment
|
-- get fragment
|
||||||
url = string.gsub(url, "#(.*)$", function(f)
|
url = string.gsub(url, "#(.*)$", function(f)
|
||||||
parsed.fragment = f
|
parsed.fragment = f
|
||||||
@@ -353,6 +349,11 @@ function build_path(parsed, unsafe)
|
|||||||
return table.concat(path)
|
return table.concat(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local entities = {
|
||||||
|
["amp"] = "&",
|
||||||
|
["lt"] = "<",
|
||||||
|
["gt"] = ">"
|
||||||
|
}
|
||||||
---
|
---
|
||||||
-- Breaks a query string into name/value pairs.
|
-- Breaks a query string into name/value pairs.
|
||||||
--
|
--
|
||||||
@@ -369,9 +370,7 @@ function parse_query(query)
|
|||||||
local parsed = {}
|
local parsed = {}
|
||||||
local pos = 1
|
local pos = 1
|
||||||
|
|
||||||
query = string.gsub(query, "&", "&")
|
query = string.gsub(query, "&([ampltg]+);", entities)
|
||||||
query = string.gsub(query, "<", "<")
|
|
||||||
query = string.gsub(query, ">", ">")
|
|
||||||
|
|
||||||
local function ginsert(qstr)
|
local function ginsert(qstr)
|
||||||
local pos = qstr:find("=", 1, true)
|
local pos = qstr:find("=", 1, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user