From 441823173f34869087c17d4819d35bf91c46e938 Mon Sep 17 00:00:00 2001 From: nnposter Date: Wed, 11 Mar 2026 17:26:38 +0000 Subject: [PATCH] Fix inconsistent results of tableaux tcopy and shallow_tcopy. Close #3287 Optimize performance when iterating over tables. --- CHANGELOG | 6 +++++- nselib/tableaux.lua | 19 +++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ad40448b9..291fba6a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,7 +15,11 @@ o [NSE][GH#2183][GH#3239] Script hostmap-crtsh now reports only true subdomains o [NSE] Function url.parse was not properly parsing URLs with query strings but empty paths. [nnposter] -o [NSE] Function tableaux.shallow_tcopy() did not work correctly for tables +o [NSE][GH#3287] Functions tableaux.tcopy and tableaux.shallow_tcopy were + not behaving the same when the input table had a custom __pairs metamethod. + Both functions now perform a raw copy, ignoring the metamethod. [nnposter] + +o [NSE] Function tableaux.shallow_tcopy did not work correctly for tables with Boolean keys. [nnposter] o [NSE] IPP print queue job details were not getting populated, having diff --git a/nselib/tableaux.lua b/nselib/tableaux.lua index 59bba5a0b..3f8fd1bec 100644 --- a/nselib/tableaux.lua +++ b/nselib/tableaux.lua @@ -15,12 +15,13 @@ local tcopy_local --- Recursively copy a table. -- -- Uses simple assignment to copy keys and values from a table, recursing into --- subtables as necessary. +-- subtables as necessary. The keys are iterated over with next(), not pairs(), +-- resulting in a "raw" copy of the input. -- @param t the table to copy -- @return a deep copy of the table function tcopy (t) local tc = {} - for k,v in pairs(t) do + for k, v in next, t do if type(v) == "table" then tc[k] = tcopy_local(v) else @@ -36,14 +37,14 @@ tcopy_local = tcopy -- Iterates over the keys of a table and copies their values into a new table. -- If any values are tables, they are copied by reference only, and modifying -- the copy will modify the original table value as well. +-- The keys are iterated over with next(), not pairs(), resulting in a "raw" +-- copy of the input. -- @param t the table to copy -- @return a shallow copy of the table function shallow_tcopy(t) - local k = next(t) local out = {} - while k ~= nil do - out[k] = t[k] - k = next(t, k) + for k, v in next, t do + out[k] = v end return out end @@ -75,15 +76,13 @@ function contains(t, item, array) return false, nil end ---- Returns the keys of a table as an array +--- Returns the raw keys of a table as an array -- @param t The table -- @return A table of keys function keys(t) local ret = {} - local k = next(t) - while k ~= nil do + for k in next, t do ret[#ret+1] = k - k = next(t, k) end return ret end