This file is indexed.

/usr/lib/ruby/vendor_ruby/wikicloth/extensions/lua/luawrapper.lua is in ruby-wikicloth 0.8.1+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
-- Lua parser extensions for MediaWiki - Wrapper for Lua interpreter
-- (c) 2008 Fran Rogers - see 'COPYING' for license

-- Creates a new sandbox environment for scripts to safely run in.
function make_sandbox()
  -- Dummy function that returns nil, to quietly replace unsafe functions
  local function dummy(...)
    return nil
  end

  -- Deep-copy an object; optionally replace all its leaf members with the
  -- value 'override' if it's non-nil
  local function deepcopy(object, override)
    local lookup_table = {}
    local function _copy(object, override)
      if type(object) ~= "table" then
	return object
      elseif lookup_table[object] then
	return lookup_table[object]
      end
      local new_table = {}
      lookup_table[object] = new_table
      for index, value in pairs(object) do
	if override ~= nil then
	  value = override
	end
	new_table[_copy(index)] = _copy(value, override)
      end
      return setmetatable(new_table, _copy(getmetatable(object), override))
    end
    return _copy(object, override)
  end

  -- Our new environment
  local env = {}

  -- "_OUTPUT" will accumulate the results of print() and friends
  env._OUTPUT = ""

  -- _OUTPUT wrapper for io.write()
  local function writewrapper(...)
    local out = ""
    for n = 1, select("#", ...) do
      if out == "" then
	out = tostring(select(n, ...))
      else
	out = out .. tostring(select(n, ...))
      end
    end
    env._OUTPUT = env._OUTPUT .. out
  end

  -- _OUTPUT wrapper for io.stdout:output()
  local function outputwrapper(file)
    if file == nil then
      local file = {}
      file.close = dummy
      file.lines = dummy
      file.read = dummy
      file.flush = dummy
      file.seek = dummy
      file.setvbuf = dummy
      function file:write(...) writewrapper(...); end
      return file
    else
      return nil
    end
  end

  -- _OUTPUT wrapper for print()
  local function printwrapper(...)
    local out = ""
    for n = 1, select("#", ...) do
      if out == "" then
	out = tostring(select(n, ...))
      else
	out = out .. '\t' .. tostring(select(n, ...))
      end
    end
    env._OUTPUT =env._OUTPUT .. out .. "\n"
  end

  -- Safe wrapper for loadstring()
  local oldloadstring = loadstring
  local function safeloadstring(s, chunkname)
    local f, message = oldloadstring(s, chunkname)
    if not f then
      return f, message
    end
    setfenv(f, getfenv(2))
    return f
  end

  -- Populate the sandbox environment
  env.assert = _G.assert
  env.error = _G.error
  env._G = env
  env.ipairs = _G.ipairs
  env.loadstring = safeloadstring
  env.next = _G.next
  env.pairs = _G.pairs
  env.pcall = _G.pcall
  env.print = printwrapper
  env.write = writewrapper
  env.select = _G.select
  env.tonumber = _G.tonumber
  env.tostring = _G.tostring
  env.type = _G.type
  env.unpack = _G.unpack
  env._VERSION = _G._VERSION
  env.xpcall = _G.xpcall
  env.coroutine = deepcopy(_G.coroutine)
  env.string = deepcopy(_G.string)
  env.string.dump = nil
  env.table = deepcopy(_G.table)
  env.math = deepcopy(_G.math)
  env.io = {}
  env.io.write = writewrapper
  env.io.flush = dummy
  env.io.type = typewrapper
  env.io.output = outputwrapper
  env.io.stdout = outputwrapper()
  env.os = {}
  env.os.clock = _G.os.clock
  -- env.os.date = _G.os.date
  env.os.difftime = _G.os.difftime
  env.os.time = _G.os.time

  -- Return the new sandbox environment
  return env
end

-- Creates a new debug hook that aborts with 'error("LOC_LIMIT")' after 
-- 'maxlines' lines have been passed, or 'error("RECURSION_LIMIT")' after 
-- 'maxcalls' levels of recursion have been entered.
function make_hook(maxlines, maxcalls, diefunc)
  local lines = 0
  local calls = 0
  function _hook(event, ...)
    if event == "line" then
      lines = lines + 1
      if lines > maxlines then
	error("LOC_LIMIT")
      end
    elseif event == "call" then
      calls = calls + 1
      if calls > maxcalls then
	error("RECURSION_LIMIT")
      end
    elseif event == "return" then
      calls = calls - 1
    end
  end
  return _hook
end

-- Creates and returns a function, 'wrap(input)', which reads a string into 
-- a Lua chunk and executes it in a persistent sandbox environment, returning 
-- 'output, err' where 'output' is the combined output of print() and friends 
-- from within the chunk and 'err' is either nil or an error incurred while 
-- executing the chunk; or halting after 'maxlines' lines or 'maxcalls' levels 
-- of recursion.
function make_wrapper(maxlines, maxcalls)
  -- Create the debug hook and sandbox environment.
  local hook = make_hook(maxlines, maxcalls)
  local env = make_sandbox()
  
  -- The actual 'wrap()' function.
  -- All of the above variables will be bound in its closure.
  function _wrap(chunkstr)
    local chunk, err, done
    -- Clear any leftover output from the last call
    env._OUTPUT = ""
    err = nil
    
    -- Load the string into a chunk; fail on error
    chunk, err = loadstring(chunkstr)
    if err ~= nil then
      return nil, err
    end
    
    -- Set the chunk's environment, enable the debug hook, and execute it
    setfenv(chunk, env)
    co = coroutine.create(chunk)
    debug.sethook(co, hook, "crl")
    done, err = coroutine.resume(co)
    
    if done == true then
      err = nil
    end
    
    -- Collect and return the results
    return env._OUTPUT, err
  end
  return _wrap
end

-- Listen on stdin for Lua chunks, parse and execute them, and print the 
-- results of each on stdout.
function main(arg)
  if #arg ~= 2 then
    io.stderr:write(string.format("usage: %s MAXLINES MAXCALLS\n", arg[0]))
    os.exit(1)
  end

  -- Create a wrapper function, wrap()
  local wrap = make_wrapper(tonumber(arg[1]), tonumber(arg[2]))

  -- Turn off buffering, and loop through the input
  io.stdout:setvbuf("no")
  while true do
    -- Read in a chunk
    local chunkstr = ""
    while true do
      local line = io.stdin:read("*l")
      if chunkstr == "" and line == nil then
	-- On EOF, exit.
	os.exit(0)
      elseif line == "." or line == nil then
	-- Finished this chunk; move on to the next step
	break
      elseif chunkstr ~= "" then
	chunkstr = chunkstr .. "\n" .. line
      else
	chunkstr = line
      end
    end

    -- Parse and execute the chunk
    local res, err
    res, err = wrap(chunkstr, env, hook)

    -- Write out the results
    if err == nil then
      io.stdout:write("'", res, "', true\n.\n")
    else
      io.stdout:write("'", err, "', false\n.\n")
    end
  end
end

-- If called as a script instead of imported as a library, run main().
if arg ~= nil then
  main(arg)
end