diff --git a/nse_main.cc b/nse_main.cc index a93d456..e2bba66 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -236,6 +236,35 @@ static int l_xml_newline(lua_State *L) return 0; } +static int l_tcopy_helper(lua_State *L, int idx=1) +{ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushnil(L); + while (lua_next(L, idx) != 0) { + /* -3 = new table, -2 = key, -1 = value */ + if (lua_istable(L, -1)) { + lua_pushvalue(L, -2); + l_tcopy_helper(L, -2); /* pushes copy of table to top (value) of stack */ + lua_rawset(L, -5); + lua_pop(L, 1); + } + else { + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_rawset(L, -5); + lua_pop(L, 1); + } + } + return 1; +} +/* (0, +1) */ +static int l_tcopy(lua_State *L) +{ + return l_tcopy_helper(L, 1); +} + + static void open_cnse (lua_State *L) { static const luaL_Reg nse[] = { @@ -253,6 +282,7 @@ static void open_cnse (lua_State *L) {"xml_end_tag", l_xml_end_tag}, {"xml_write_escaped", l_xml_write_escaped}, {"xml_newline", l_xml_newline}, + {"tcopy", l_tcopy}, {NULL, NULL} }; diff --git a/nse_main.lua b/nse_main.lua index 819ef6c..36aca00 100644 --- a/nse_main.lua +++ b/nse_main.lua @@ -227,18 +227,7 @@ local function loadscript (filename) end -- recursively copy a table, for host/port tables --- not very rigorous, but it doesn't need to be -local function tcopy (t) - local tc = {}; - for k,v in pairs(t) do - if type(v) == "table" then - tc[k] = tcopy(v); - else - tc[k] = v; - end - end - return tc; -end +local tcopy = cnse.tcopy -- copies the host table while preserving the registry local function host_copy(t) diff --git a/nselib/http.lua b/nselib/http.lua index aedde98..d86d711 100644 --- a/nselib/http.lua +++ b/nselib/http.lua @@ -244,16 +244,12 @@ end local function skip_lws(s, pos) local _, e - while true do - while string.match(s, "^[ \t]", pos) do - pos = pos + 1 - end - _, e = string.find(s, "^\r?\n[ \t]", pos) - if not e then - return pos - end + _, e = string.find(s, "^[ \t]*", pos) + while e do pos = e + 1 + _, e = string.find(s, "^\r?\n[ \t]+", pos) end + return pos end @@ -643,14 +639,15 @@ local function parse_header(header, response) local pos local name, words local s, e + local header_len = #header response.header = {} response.rawheader = stdnse.strsplit("\r?\n", header) pos = 1 - while pos <= #header do + while pos <= header_len do -- Get the field name. e, name = get_token(header, pos) - if not name or e > #header or string.sub(header, e, e) ~= ":" then + if not name or e > header_len or string.sub(header, e, e) ~= ":" then return nil, string.format("Can't get header field name at %q", string.sub(header, pos, pos + 30)) end pos = e + 1 @@ -659,14 +656,10 @@ local function parse_header(header, response) pos = skip_lws(header, pos) -- Get non-space words separated by LWS, then join them with a single space. words = {} - while pos <= #header and not string.match(header, "^\r?\n", pos) do - s = pos - while not string.match(header, "^[ \t]", pos) and - not string.match(header, "^\r?\n", pos) do - pos = pos + 1 - end - words[#words + 1] = string.sub(header, s, pos - 1) - pos = skip_lws(header, pos) + while pos <= header_len and not string.match(header, "^\r?\n", pos) do + s, e = string.find(header, "^[^%s]*", pos) + words[#words + 1] = string.sub(header, s, e) + pos = skip_lws(header, e+1) end -- Set it in our table.