diff options
Diffstat (limited to 'tex/context/base/luat-iop.lua')
-rw-r--r-- | tex/context/base/luat-iop.lua | 390 |
1 files changed, 195 insertions, 195 deletions
diff --git a/tex/context/base/luat-iop.lua b/tex/context/base/luat-iop.lua index 52f14683e..bcbfac73a 100644 --- a/tex/context/base/luat-iop.lua +++ b/tex/context/base/luat-iop.lua @@ -1,195 +1,195 @@ -if not modules then modules = { } end modules ['luat-iop'] = { - version = 1.001, - comment = "companion to luat-lib.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- this paranoid stuff in web2c ... we cannot hook checks into the --- input functions because one can always change the callback but --- we can feed back specific patterns and paths into the next --- mechanism - --- os.execute os.exec os.spawn io.fopen --- os.remove lfs.chdir lfs.mkdir --- io.open zip.open epdf.open mlib.new - --- cache - -local topattern, find = string.topattern, string.find - -local report_limiter = logs.reporter("system","limiter") - --- the basic methods - -local function match(ruleset,name) - local n = #ruleset - if n > 0 then - for i=1,n do - local r = ruleset[i] - if find(name,r[1]) then - return r[2] - end - end - return false - else - -- nothing defined (or any) - return true - end -end - -local function protect(ruleset,proc) - return function(name,...) - if name == "" then - -- report_limiter("no access permitted: <no name>") -- can happen in mplib code - return nil, "no name given" - elseif match(ruleset,name) then - return proc(name,...) - else - report_limiter("no access permitted for %a",name) - return nil, name .. ": no access permitted" - end - end -end - -function io.limiter(preset) - preset = preset or { } - local ruleset = { } - for i=1,#preset do - local p = preset[i] - local what, spec = p[1] or "", p[2] or "" - if spec == "" then - -- skip 'm - elseif what == "tree" then - resolvers.dowithpath(spec, function(r) - local spec = resolvers.resolve(r) or "" - if spec ~= "" then - ruleset[#ruleset+1] = { topattern(spec,true), true } - end - end) - elseif what == "permit" then - ruleset[#ruleset+1] = { topattern(spec,true), true } - elseif what == "forbid" then - ruleset[#ruleset+1] = { topattern(spec,true), false } - end - end - if #ruleset > 0 then - return { - match = function(name) return match (ruleset,name) end, - protect = function(proc) return protect(ruleset,proc) end, - } - else - return { - match = function(name) return true end, - protect = proc, - } - end -end - --- a few handlers - -io.i_limiters = { } -io.o_limiters = { } - -function io.i_limiter(v) - local i = io.i_limiters[v] - if i then - local i_limiter = io.limiter(i) - function io.i_limiter() - return i_limiter - end - return i_limiter - end -end - -function io.o_limiter(v) - local o = io.o_limiters[v] - if o then - local o_limiter = io.limiter(o) - function io.o_limiter() - return o_limiter - end - return o_limiter - end -end - --- the real thing (somewhat fuzzy as we need to know what gets done) - -local i_opener, i_limited = io.open, false -local o_opener, o_limited = io.open, false - -local function i_register(v) - if not i_limited then - local i_limiter = io.i_limiter(v) - if i_limiter then - local protect = i_limiter.protect - i_opener = protect(i_opener) - i_limited = true - report_limiter("input mode set to %a",v) - end - end -end - -local function o_register(v) - if not o_limited then - local o_limiter = io.o_limiter(v) - if o_limiter then - local protect = o_limiter.protect - o_opener = protect(o_opener) - o_limited = true - report_limiter("output mode set to %a",v) - end - end -end - -function io.open(name,method) - if method and find(method,"[wa]") then - return o_opener(name,method) - else - return i_opener(name,method) - end -end - -directives.register("system.inputmode", i_register) -directives.register("system.outputmode", o_register) - -local i_limited = false -local o_limited = false - -local function i_register(v) - if not i_limited then - local i_limiter = io.i_limiter(v) - if i_limiter then - local protect = i_limiter.protect - lfs.chdir = protect(lfs.chdir) -- needs checking - i_limited = true - end - end -end - -local function o_register(v) - if not o_limited then - local o_limiter = io.o_limiter(v) - if o_limiter then - local protect = o_limiter.protect - os.remove = protect(os.remove) -- rather okay - lfs.chdir = protect(lfs.chdir) -- needs checking - lfs.mkdir = protect(lfs.mkdir) -- needs checking - o_limited = true - end - end -end - -directives.register("system.inputmode", i_register) -directives.register("system.outputmode", o_register) - --- the definitions - -local limiters = resolvers.variable("limiters") - -if limiters then - io.i_limiters = limiters.input or { } - io.o_limiters = limiters.output or { } -end - +if not modules then modules = { } end modules ['luat-iop'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this paranoid stuff in web2c ... we cannot hook checks into the
+-- input functions because one can always change the callback but
+-- we can feed back specific patterns and paths into the next
+-- mechanism
+
+-- os.execute os.exec os.spawn io.fopen
+-- os.remove lfs.chdir lfs.mkdir
+-- io.open zip.open epdf.open mlib.new
+
+-- cache
+
+local topattern, find = string.topattern, string.find
+
+local report_limiter = logs.reporter("system","limiter")
+
+-- the basic methods
+
+local function match(ruleset,name)
+ local n = #ruleset
+ if n > 0 then
+ for i=1,n do
+ local r = ruleset[i]
+ if find(name,r[1]) then
+ return r[2]
+ end
+ end
+ return false
+ else
+ -- nothing defined (or any)
+ return true
+ end
+end
+
+local function protect(ruleset,proc)
+ return function(name,...)
+ if name == "" then
+ -- report_limiter("no access permitted: <no name>") -- can happen in mplib code
+ return nil, "no name given"
+ elseif match(ruleset,name) then
+ return proc(name,...)
+ else
+ report_limiter("no access permitted for %a",name)
+ return nil, name .. ": no access permitted"
+ end
+ end
+end
+
+function io.limiter(preset)
+ preset = preset or { }
+ local ruleset = { }
+ for i=1,#preset do
+ local p = preset[i]
+ local what, spec = p[1] or "", p[2] or ""
+ if spec == "" then
+ -- skip 'm
+ elseif what == "tree" then
+ resolvers.dowithpath(spec, function(r)
+ local spec = resolvers.resolve(r) or ""
+ if spec ~= "" then
+ ruleset[#ruleset+1] = { topattern(spec,true), true }
+ end
+ end)
+ elseif what == "permit" then
+ ruleset[#ruleset+1] = { topattern(spec,true), true }
+ elseif what == "forbid" then
+ ruleset[#ruleset+1] = { topattern(spec,true), false }
+ end
+ end
+ if #ruleset > 0 then
+ return {
+ match = function(name) return match (ruleset,name) end,
+ protect = function(proc) return protect(ruleset,proc) end,
+ }
+ else
+ return {
+ match = function(name) return true end,
+ protect = proc,
+ }
+ end
+end
+
+-- a few handlers
+
+io.i_limiters = { }
+io.o_limiters = { }
+
+function io.i_limiter(v)
+ local i = io.i_limiters[v]
+ if i then
+ local i_limiter = io.limiter(i)
+ function io.i_limiter()
+ return i_limiter
+ end
+ return i_limiter
+ end
+end
+
+function io.o_limiter(v)
+ local o = io.o_limiters[v]
+ if o then
+ local o_limiter = io.limiter(o)
+ function io.o_limiter()
+ return o_limiter
+ end
+ return o_limiter
+ end
+end
+
+-- the real thing (somewhat fuzzy as we need to know what gets done)
+
+local i_opener, i_limited = io.open, false
+local o_opener, o_limited = io.open, false
+
+local function i_register(v)
+ if not i_limited then
+ local i_limiter = io.i_limiter(v)
+ if i_limiter then
+ local protect = i_limiter.protect
+ i_opener = protect(i_opener)
+ i_limited = true
+ report_limiter("input mode set to %a",v)
+ end
+ end
+end
+
+local function o_register(v)
+ if not o_limited then
+ local o_limiter = io.o_limiter(v)
+ if o_limiter then
+ local protect = o_limiter.protect
+ o_opener = protect(o_opener)
+ o_limited = true
+ report_limiter("output mode set to %a",v)
+ end
+ end
+end
+
+function io.open(name,method)
+ if method and find(method,"[wa]") then
+ return o_opener(name,method)
+ else
+ return i_opener(name,method)
+ end
+end
+
+directives.register("system.inputmode", i_register)
+directives.register("system.outputmode", o_register)
+
+local i_limited = false
+local o_limited = false
+
+local function i_register(v)
+ if not i_limited then
+ local i_limiter = io.i_limiter(v)
+ if i_limiter then
+ local protect = i_limiter.protect
+ lfs.chdir = protect(lfs.chdir) -- needs checking
+ i_limited = true
+ end
+ end
+end
+
+local function o_register(v)
+ if not o_limited then
+ local o_limiter = io.o_limiter(v)
+ if o_limiter then
+ local protect = o_limiter.protect
+ os.remove = protect(os.remove) -- rather okay
+ lfs.chdir = protect(lfs.chdir) -- needs checking
+ lfs.mkdir = protect(lfs.mkdir) -- needs checking
+ o_limited = true
+ end
+ end
+end
+
+directives.register("system.inputmode", i_register)
+directives.register("system.outputmode", o_register)
+
+-- the definitions
+
+local limiters = resolvers.variable("limiters")
+
+if limiters then
+ io.i_limiters = limiters.input or { }
+ io.o_limiters = limiters.output or { }
+end
+
|