From 86301645de1fc594ca94a2a722fce813c16966b1 Mon Sep 17 00:00:00 2001 From: Marius Date: Mon, 14 May 2012 10:40:15 +0300 Subject: beta 2012.05.14 09:19 --- tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4077 -> 4073 bytes tex/context/base/context-version.png | Bin 105837 -> 105608 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/data-bin.lua | 4 +- tex/context/base/data-zip.lua | 12 + tex/context/base/font-ctx.lua | 13 ++ tex/context/base/font-sty.mkvi | 10 +- tex/context/base/l-dir.lua | 12 +- tex/context/base/lpdf-epd.lua | 16 ++ tex/context/base/luat-exe.lua | 64 ++++-- tex/context/base/luat-iop.lua | 243 ++++++++++++--------- tex/context/base/mlib-run.lua | 65 ++++-- tex/context/base/status-files.pdf | Bin 24332 -> 24330 bytes tex/context/base/status-lua.pdf | Bin 178832 -> 178784 bytes tex/context/base/strc-con.mkvi | 3 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 2 +- 19 files changed, 304 insertions(+), 148 deletions(-) (limited to 'tex') diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 8797cb81e..59c540b93 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.05.11 13:19} +\newcontextversion{2012.05.14 09:19} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 3296f06da..d04de763b 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.05.11 13:19} +\newcontextversion{2012.05.14 09:19} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 73ddb663a..4fe170955 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 76b308b51..be09ece3b 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index a327be3e5..e0433384f 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2012.05.11 13:19} +\edef\contextversion{2012.05.14 09:19} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 9c1146866..bebc6dee7 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -23,7 +23,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2012.05.11 13:19} +\edef\contextversion{2012.05.14 09:19} %D For those who want to use this: diff --git a/tex/context/base/data-bin.lua b/tex/context/base/data-bin.lua index b18526c77..1d1e8b749 100644 --- a/tex/context/base/data-bin.lua +++ b/tex/context/base/data-bin.lua @@ -14,13 +14,13 @@ function resolvers.findbinfile(filename,filetype) end function resolvers.openbinfile(filename) - return methodhandler('loaders',filename) + return methodhandler('loaders',filename) -- a bit weird: load end function resolvers.loadbinfile(filename,filetype) local fname = methodhandler('finders',filename,filetype) if fname and fname ~= "" then - return resolvers.openbinfile(fname) + return resolvers.openbinfile(fname) -- a bit weird: open else return resolvers.loaders.notfound() end diff --git a/tex/context/base/data-zip.lua b/tex/context/base/data-zip.lua index 6a50d2aa9..1d2f2d4f6 100644 --- a/tex/context/base/data-zip.lua +++ b/tex/context/base/data-zip.lua @@ -31,6 +31,18 @@ local archives = zip.archives zip.registeredfiles = zip.registeredfiles or { } local registeredfiles = zip.registeredfiles +local limited = false + +directives.register("system.inputmode", function(v) + if not limited then + local i_limiter = io.i_limiter(v) + if i_limiter then + zip.open = i_limiter.protect(zip.open) + limited = true + end + end +end) + local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then return "zip:///" .. str diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 5680ee69e..4b324a6db 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -99,6 +99,19 @@ local nulldata = { constructors.enhanceparameters(nulldata.parameters) -- official copies for us +local limited = false + +directives.register("system.inputmode", function(v) + if not limited then + local i_limiter = io.i_limiter(v) + if i_limiter then + fontloader.open = i_limiter.protect(fontloader.open) + fontloader.info = i_limiter.protect(fontloader.info) + limited = true + end + end +end) + function definers.resetnullfont() -- resetting is needed because tikz misuses nullfont local parameters = nulldata.parameters diff --git a/tex/context/base/font-sty.mkvi b/tex/context/base/font-sty.mkvi index 9291f3b0a..d8f01afa7 100644 --- a/tex/context/base/font-sty.mkvi +++ b/tex/context/base/font-sty.mkvi @@ -157,7 +157,15 @@ \doubleexpandafter\m_current_convert_font \fi\fi} -%D Low level switches (downward compatible): +%D Low level switches (downward compatible, but we keep them as one can use +%D them in styles): +%D +%D \starttyping +%D \usemodule[abr-02] +%D \setuphead[chapter][style=\bfb] +%D \setupfooter[style=\dontconvertfont\bf] +%D \chapter{This is \TEX} +%D \stoptyping \unexpanded\def\dontconvertfont{\c_font_current_alternative_style_index\plustwo} % needs checking in usage \unexpanded\def\redoconvertfont{\c_font_current_alternative_style_index\plusone} % needs checking in usage diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua index ee831f98a..71de3114e 100644 --- a/tex/context/base/l-dir.lua +++ b/tex/context/base/l-dir.lua @@ -23,8 +23,6 @@ local attributes = lfs.attributes local walkdir = lfs.dir local isdir = lfs.isdir local isfile = lfs.isfile -local mkdir = lfs.mkdir -local chdir = lfs.chdir local currentdir = lfs.currentdir -- handy @@ -292,7 +290,7 @@ if onwindows then pth = pth .. "/" .. s end if make_indeed and not isdir(pth) then - mkdir(pth) + lfs.mkdir(pth) end end return pth, (isdir(pth) == true) @@ -335,7 +333,7 @@ else pth = pth .. "/" .. s end if make_indeed and not first and not isdir(pth) then - mkdir(pth) + lfs.mkdir(pth) end end else @@ -343,7 +341,7 @@ else for s in gmatch(str,"[^/]+") do pth = pth .. "/" .. s if make_indeed and not isdir(pth) then - mkdir(pth) + lfs.mkdir(pth) end end end @@ -378,10 +376,10 @@ if onwindows then first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = currentdir() - if chdir(first) then + if lfs.chdir(first) then first = dir.current() end - chdir(d) + lfs.chdir(d) end end if not first then diff --git a/tex/context/base/lpdf-epd.lua b/tex/context/base/lpdf-epd.lua index 3e917dba2..76d258cef 100644 --- a/tex/context/base/lpdf-epd.lua +++ b/tex/context/base/lpdf-epd.lua @@ -27,6 +27,22 @@ local lower, match, char, find, sub = string.lower, string.match, string.char, s local concat = table.concat local toutf = string.toutf +-- a bit of protection + +local limited = false + +directives.register("system.inputmode", function(v) + if not limited then + local i_limiter = io.i_limiter(v) + if i_limiter then + epdf.open = i_limiter.protect(epdf.open) + limited = true + end + end +end) + +-- + function epdf.type(o) local t = lower(match(tostring(o),"[^ :]+")) return t or "?" diff --git a/tex/context/base/luat-exe.lua b/tex/context/base/luat-exe.lua index 42c17ded5..0e9a94313 100644 --- a/tex/context/base/luat-exe.lua +++ b/tex/context/base/luat-exe.lua @@ -17,8 +17,16 @@ resolvers.executers = resolvers.executers or { } local executers = resolvers.executers local permitted = { } + local osexecute = os.execute +local osexec = os.exec +local osspawn = os.spawn +local iopopen = io.popen + local execute = osexecute +local exec = osexec +local spawn = osspawn +local popen = iopopen local function register(...) local t = { ... } @@ -28,33 +36,47 @@ local function register(...) end end -local function finalize() -- todo: os.exec, todo: report ipv print - execute = function(...) - -- todo: make more clever first split - local t, name, arguments = { ... }, "", "" - local one = t[1] - if #t == 1 then - if type(one) == 'table' then - name, arguments = one, concat(t," ",2,#t) +local function prepare(...) + -- todo: make more clever first split + local t = { ... } + local one = t[1] + if #t == 1 then + if type(one) == 'table' then + return one, concat(t," ",2,#t) + else + local name, arguments = match(one,"^(.-)%s+(.+)$") + if name and arguments then + return name, arguments else - name, arguments = match(one,"^(.-)%s+(.+)$") - if not (name and arguments) then - name, arguments = one, "" - end + return one, "" end - else - name, arguments = one, concat(t," ",2,#t) end + else + return one, concat(t," ",2,#t) + end +end + +local function executer(action) + return function(...) + local name, arguments = prepare(...) for k=1,#permitted do local v = permitted[k] if find(name,v) then - osexecute(name .. " " .. arguments) + return action(name .. " " .. arguments) -- print("executed: " .. name .. " " .. arguments) else report_executers("not permitted: %s %s",name,arguments) end end + return action("") end +end + +local function finalize() -- todo: os.exec, todo: report ipv print + execute = executer(osexecute) + exec = executer(osexec) + spawn = executer(osspawn) + popen = executer(iopopen) finalize = function() report_executers("already finalized") end @@ -62,11 +84,17 @@ local function finalize() -- todo: os.exec, todo: report ipv print report_executers("already finalized, no registration permitted") end os.execute = execute + os.exec = exec + os.spawn = spawn + io.popen = popen end -executers.finalize = function(...) finalize(...) end -executers.register = function(...) register(...) end -executers.execute = function(...) execute (...) end +executers.finalize = function(...) return finalize(...) end +executers.register = function(...) return register(...) end +executers.execute = function(...) return execute (...) end +executers.exec = function(...) return exec (...) end +executers.spawn = function(...) return spawn (...) end +executers.popen = function(...) return popen (...) end local execution_mode directives.register("system.executionmode", function(v) execution_mode = v end) local execution_list directives.register("system.executionlist", function(v) execution_list = v end) diff --git a/tex/context/base/luat-iop.lua b/tex/context/base/luat-iop.lua index 091639de2..5512b258e 100644 --- a/tex/context/base/luat-iop.lua +++ b/tex/context/base/luat-iop.lua @@ -11,138 +11,185 @@ if not modules then modules = { } end modules ['luat-iop'] = { -- we can feed back specific patterns and paths into the next -- mechanism -local lower, find, sub = string.lower, string.find, string.sub +-- os.execute os.exec os.spawn io.fopen +-- os.remove lfs.chdir lfs.mkdir +-- io.open zip.open epdf.open mlib.new -local allocate = utilities.storage.allocate +-- cache -local ioinp = io.inp if not ioinp then ioinp = { } io.inp = ioinp end -local ioout = io.out if not ioout then ioout = { } io.out = ioout end +local topattern, find = string.topattern, string.find -ioinp.modes, ioout.modes = allocate(), allocate() +local report_limiter = logs.reporter("system","limiter") -local inp_blocked, inp_permitted = { }, { } -local out_blocked, out_permitted = { }, { } +-- the basic methods -local function i_inhibit(name) inp_blocked [#inp_blocked +1] = name end -local function o_inhibit(name) out_blocked [#out_blocked +1] = name end -local function i_permit (name) inp_permitted[#inp_permitted+1] = name end -local function o_permit (name) out_permitted[#out_permitted+1] = name end - -ioinp.inhibit, ioinp.permit = i_inhibit, o_permit -ioout.inhibit, ioout.permit = o_inhibit, o_permit - -local blockedopeners = { } -- *.open(name,method) - -function io.registeropener(func) - blockedopeners[#blockedopeners+1] = func +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 checked(name,blocked,permitted) - local n = lower(name) - for _,b in next, blocked do - if find(n,b) then - for _,p in next, permitted do - if find(n,p) then - return true - end - end - return false +local function protect(ruleset,proc) + return function(name,...) + if name == "" then + -- report_limiter("no access permitted: ") -- can happen in mplib code + return nil, "no name given" + elseif match(ruleset,name) then + return proc(name,...) + else + report_limiter("no access permitted: %s",name) + return nil, name .. ": no access permitted" end end - return true end -function io.finalizeopeners(func) - if #out_blocked > 0 or #inp_blocked > 0 then - local open = func -- why not directly? - return function(name,method) - if method and find(method,'[wa]') then - if #out_blocked > 0 and not checked(name,out_blocked,out_permitted) then - -- print("writing to " .. name .. " is not permitted") - return nil +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 - else - if #inp_blocked > 0 and not checked(name,inp_blocked,inp_permitted) then - -- print("reading from " .. name .. " is not permitted") - return nil - end - end - return open(name,method) + 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 func + return { + match = function(name) return true end, + protect = proc, + } end end ---~ io.inp.inhibit('^%.') ---~ io.inp.inhibit('^/etc') ---~ io.inp.inhibit('/windows/') ---~ io.inp.inhibit('/winnt/') ---~ io.inp.permit('c:/windows/wmsetup.log') - ---~ io.open = io.finalizeopeners(io.open) +-- a few handlers ---~ f = io.open('.tex') print(f) ---~ f = io.open('tufte.tex') print(f) ---~ f = io.open('t:/sources/tufte.tex') print(f) ---~ f = io.open('/etc/passwd') print(f) ---~ f = io.open('c:/windows/crap.log') print(f) ---~ f = io.open('c:/windows/wmsetup.log') print(f) +io.i_limiters = { } +io.o_limiters = { } --- restricted - -function ioinp.modes.restricted() - i_inhibit('^%.[%a]') +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 ioout.modes.restricted() - o_inhibit('^%.[%a]') +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 --- paranoid +-- the real thing (somewhat fuzzy as we need to know what gets done) -function ioinp.modes.paranoid() - i_inhibit('.*') - i_inhibit('%.%.') - i_permit('^%./') - i_permit('[^/]') - resolvers.dowithpath('TEXMF',i_permit) -end +local i_opener, i_limited = io.open, false +local o_opener, o_limited = io.open, false -function ioout.modes.paranoid() - o_inhibit('.*') - resolvers.dowithpath('TEXMFOUTPUT',o_permit) +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: %s",v) + end + end end --- handy +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: %s",v) + end + end +end -function ioinp.modes.handy() - i_inhibit('%.%.') - if os.type == 'windows' then - i_inhibit('/windows/') - i_inhibit('/winnt/') +function io.open(name,method) + if method and find(method,"[wa]") then + return o_opener(name,method) else - i_inhibit('^/etc') + return i_opener(name,method) end end -function ioout.modes.handy() - o_inhibit('.*') - o_permit('%./') - o_permit('^%./') - o_permit('[^/]') +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 -local input_mode directives.register("system.inputmode", function(v) input_mode = v end) -local output_mode directives.register("system.outputmode", function(v) output_mode = v end) +directives.register("system.inputmode", i_register) +directives.register("system.outputmode", o_register) + +-- the definitions + +local limiters = resolvers.variable("limiters") -function io.checkopeners() - local inp = input_mode or resolvers.variable("input_mode") -- or ... will become obsolete - local out = output_mode or resolvers.variable("output_mode") -- or ... will become obsolete - inp = inp and ioinp.modes[inp] - out = out and ioinp.modes[out] - if inp then inp() end - if out then out() end +if limiters then + io.i_limiters = limiters.input or { } + io.o_limiters = limiters.output or { } end ---~ io.checkopeners() diff --git a/tex/context/base/mlib-run.lua b/tex/context/base/mlib-run.lua index dd172f884..f42b53594 100644 --- a/tex/context/base/mlib-run.lua +++ b/tex/context/base/mlib-run.lua @@ -58,30 +58,63 @@ function metapost.resetlastlog() metapost.lastlog = "" end +-- local function realfinder(name, mode, ftype) +-- if mode == "w" then +-- return name +-- elseif file.is_qualified_path(name) then +-- return name +-- else +-- return resolvers.findfile(name,ftype) +-- end +-- end + +local function i_finder(name, mode, ftype) -- fake message for mpost.map and metafun.mpvi + name = file.is_qualified_path(name) and name or resolvers.findfile(name,ftype) + if not (find(name,"/metapost/context/base/") or find(name,"/metapost/context/") or find(name,"/metapost/base/")) then + local data, found, forced = metapost.checktexts(io.loaddata(name) or "") + if found then + local temp = luatex.registertempfile(name,true) + io.savedata(temp,data) + name = temp + end + end + return name +end + +local function o_finder(name, mode, ftype) + return name +end + local function finder(name, mode, ftype) if mode == "w" then - return name - elseif file.is_qualified_path(name) then - return name + return o_finder(name, mode, ftype) else - return resolvers.findfile(name,ftype) + return i_finder(name, mode, ftype) end end -local function finder(name, mode, ftype) - if mode ~= "w" then - name = file.is_qualified_path(name) and name or resolvers.findfile(name,ftype) - if not (find(name,"/metapost/context/base/") or find(name,"/metapost/context/") or find(name,"/metapost/base/")) then - local data, found, forced = metapost.checktexts(io.loaddata(name) or "") - if found then - local temp = luatex.registertempfile(name,true) - io.savedata(temp,data) - name = temp - end +local i_limited = false +local o_limited = false + +directives.register("system.inputmode", function(v) + if not i_limited then + local i_limiter = io.i_limiter(v) + if i_limiter then + i_finder = i_limiter.protect(i_finder) + i_limited = true end end - return name -end +end) + +directives.register("system.outputmode", function(v) + if not o_limited then + local o_limiter = io.o_limiter(v) + if o_limiter then + o_finder = o_limiter.protect(o_finder) + o_limited = true + end + end +end) -- -- -- diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 4cb9e63b8..0ab6170e3 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 5c252820b..ec6d3a5cb 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi index 72ca50189..3068fda0b 100644 --- a/tex/context/base/strc-con.mkvi +++ b/tex/context/base/strc-con.mkvi @@ -480,7 +480,8 @@ \noindent \leftskip\leftconstructionskip \rightskip\dimexpr\rightconstructionskip+\constructionsheadwidth\relax - \strc_constructions_pure_hang_box\raggedleft + %\strc_constructions_pure_hang_box\raggedleft + \strc_constructions_set_pure_box\v!flushright \rlap { \hskip\dimexpr\hsize-\leftskip-\rightskip\relax \copy\constructionheadbox diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index b1d15c50d..a8de54f84 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 05/11/12 13:19:54 +-- merge date : 05/14/12 09:19:00 do -- begin closure to overcome local limits and interference -- cgit v1.2.3