1
2
3
4
5
6
7
8
9
10LUATEXCOREVERSION = 1.161
11
12
13
14
15
16
17
18
19local saferoption = status.safer_option
20local shellescape = status.shell_escape
21local kpseused = status.kpse_used
22
23if kpseused == 1 then
24
25 local type = type
26 local gsub = string.gsub
27 local find = string.find
28
29 local mt = getmetatable(io.stderr)
30 local mt_lines = mt.lines
31
32 local kpse_checkpermission = kpse.check_permission
33 local kpse_recordinputfile = kpse.record_input_file
34 local kpse_recordoutputfile = kpse.record_output_file
35
36 local kpse_outputnameok = kpse.out_name_ok
37 local kpse_inputnameok = kpse.in_name_ok
38
39 local io_open = io.open
40 local io_popen = kpse.popen or io.popen
41 local io_lines = io.lines
42
43 local fio_readline = fio.readline
44
45 local write_nl = texio.write_nl
46
47 io.saved_lines = io_lines
48 mt.saved_lines = mt_lines
49
50
51
52
53
54 local function validinput(name,how)
55 if type(how) ~= "string" or how == "" then
56 how = "r"
57 end
58 return not find(how,"w") and kpse_inputnameok(name) and io_open(name,how)
59 end
60
61 local function validoutput(name,how)
62 return type(how) == "string" and find(how,"w") and kpse_outputnameok(name) and io_open(name,how)
63 end
64
65 local function luatex_io_open(name,how)
66 local handle = validinput(name,how)
67 if handle then
68 kpse_recordinputfile(name,"r")
69 else
70 handle = validoutput(name,how)
71 if handle then
72 kpse_recordoutputfile(name,"w")
73 end
74 end
75 return handle
76 end
77
78 local function luatex_io_open_readonly(name,how)
79 local handle = validinput(name,how)
80 if handle then
81 kpse_recordinputfile(name,"r")
82 end
83 return handle
84 end
85
86
87
88
89
90
91
92
93
94
95
96 local error, type = error, type
97
98 local function luatex_io_lines(name,how)
99 if type(name) == "string" then
100 local handle = validinput(name,how)
101 if handle then
102 kpse_recordinputfile(name,"r")
103 return function()
104 local l = fio_readline(f)
105 if not l then
106 f:close()
107 end
108 return l
109 end
110 else
111
112 error("patched 'io.lines' can't open '" .. name .. "'")
113 end
114 else
115 return io_lines()
116 end
117 end
118
119 local function luatex_io_readline(f)
120 return function()
121 return fio_readline(f)
122 end
123 end
124
125 io.lines = luatex_io_lines
126 mt.lines = luatex_io_readline
127
128 io.open = luatex_io_open
129
130 io.popen = io_popen
131
132else
133
134
135
136end
137
138
139
140if saferoption == 1 then
141
142 local write_nl = texio.write_nl
143 local format = string.format
144
145 local function installdummy(str,f)
146 local reported = false
147 return function(...)
148 if not reported then
149 write_nl(format("safer option set, function %q is %s",
150 str,f and "limited" or "disabled"))
151 reported = true
152 end
153 if f then
154 return f(...)
155 end
156 end
157 end
158
159 local function installlimit(str,f)
160 local reported = false
161 end
162
163 os.execute = installdummy("os.execute")
164 os.spawn = installdummy("os.spawn")
165 os.exec = installdummy("os.exec")
166 os.setenv = installdummy("os.setenv")
167 os.tempdir = installdummy("os.tempdir")
168
169 io.popen = installdummy("io.popen")
170 io.open = installdummy("io.open",luatex_io_open_readonly)
171
172 os.kpsepopen = io.popen
173
174 os.rename = installdummy("os.rename")
175 os.remove = installdummy("os.remove")
176
177 io.tmpfile = installdummy("io.tmpfile")
178 io.output = installdummy("io.output")
179
180 lfs.chdir = installdummy("lfs.chdir")
181 lfs.lock = installdummy("lfs.lock")
182 lfs.touch = installdummy("lfs.touch")
183 lfs.rmdir = installdummy("lfs.rmdir")
184 lfs.mkdir = installdummy("lfs.mkdir")
185
186 debug = nil
187 package.loaded.debug = nil
188
189
190
191end
192
193
194
195if saferoption == 1 or shellescape ~= 1 then
196
197 package.loadlib = function() end
198 package.searchers[4] = nil
199 package.searchers[3] = nil
200
201 if os.setenv then
202 os.setenv = function(...) end
203 end
204
205 ffi = require('ffi')
206
207 if ffi then
208 for k, v in next, ffi do
209 if k ~= 'gc' then
210 ffi[k] = nil
211 end
212 end
213 end
214
215 ffi = nil
216
217
218
219
220
221 package.loaded .ffi = nil
222 package.preload.ffi = error
223
224end
225
226if md5 then
227
228 local sum = md5.sum
229 local gsub = string.gsub
230 local format = string.format
231 local byte = string.byte
232
233 if not md5.sumhexa then
234 function md5.sumhexa(k)
235 return (gsub(sum(k), ".", function(c)
236 return format("%02x",byte(c))
237 end))
238 end
239 end
240
241 if not md5.sumHEXA then
242 function md5.sumHEXA(k)
243 return (gsub(sum(k), ".", function(c)
244 return format("%02X",byte(c))
245 end))
246 end
247 end
248
249end
250
251
252
253if not unpack then
254 unpack = table.unpack
255end
256
257if not package.loaders then
258 package.loaders = package.searchers
259end
260
261if not loadstring then
262 loadstring = load
263end
264
265
266
267if bit32 then
268
269
270
271elseif utf8 then
272
273
274
275 bit32 = load ( [[
276local select = select -- instead of: arg = { ... }
277
278bit32 = {
279 bnot = function (a)
280 return ~a & 0xFFFFFFFF
281 end,
282 band = function (x, y, z, ...)
283 if not z then
284 return ((x or -1) & (y or -1)) & 0xFFFFFFFF
285 else
286 local res = x & y & z
287 for i=1,select("#",...) do
288 res = res & select(i,...)
289 end
290 return res & 0xFFFFFFFF
291 end
292 end,
293 bor = function (x, y, z, ...)
294 if not z then
295 return ((x or 0) | (y or 0)) & 0xFFFFFFFF
296 else
297 local res = x | y | z
298 for i=1,select("#",...) do
299 res = res | select(i,...)
300 end
301 return res & 0xFFFFFFFF
302 end
303 end,
304 bxor = function (x, y, z, ...)
305 if not z then
306 return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
307 else
308 local res = x ~ y ~ z
309 for i=1,select("#",...) do
310 res = res ~ select(i,...)
311 end
312 return res & 0xFFFFFFFF
313 end
314 end,
315 btest = function (x, y, z, ...)
316 if not z then
317 return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
318 else
319 local res = x & y & z
320 for i=1,select("#",...) do
321 res = res & select(i,...)
322 end
323 return (res & 0xFFFFFFFF) ~= 0
324 end
325 end,
326 lshift = function (a, b)
327 return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
328 end,
329 rshift = function (a, b)
330 return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
331 end,
332 arshift = function (a, b)
333 a = a & 0xFFFFFFFF
334 if b <= 0 or (a & 0x80000000) == 0 then
335 return (a >> b) & 0xFFFFFFFF
336 else
337 return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
338 end
339 end,
340 lrotate = function (a ,b)
341 b = b & 31
342 a = a & 0xFFFFFFFF
343 a = (a << b) | (a >> (32 - b))
344 return a & 0xFFFFFFFF
345 end,
346 rrotate = function (a, b)
347 b = -b & 31
348 a = a & 0xFFFFFFFF
349 a = (a << b) | (a >> (32 - b))
350 return a & 0xFFFFFFFF
351 end,
352 extract = function (a, f, w)
353 return (a >> f) & ~(-1 << (w or 1))
354 end,
355 replace = function (a, v, f, w)
356 local mask = ~(-1 << (w or 1))
357 return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
358 end,
359}
360 ]] )
361
362elseif bit then
363
364
365
366 bit32 = load ( [[
367local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
368
369bit32 = {
370 arshift = bit.arshift,
371 band = band,
372 bnot = bnot,
373 bor = bit.bor,
374 bxor = bit.bxor,
375 btest = function(...)
376 return band(...) ~= 0
377 end,
378 extract = function(a,f,w)
379 return band(rshift(a,f),2^(w or 1)-1)
380 end,
381 lrotate = bit.rol,
382 lshift = lshift,
383 replace = function(a,v,f,w)
384 local mask = 2^(w or 1)-1
385 return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
386 end,
387 rrotate = bit.ror,
388 rshift = rshift,
389}
390 ]] )
391
392else
393
394
395
396 bit32 = require("bit32")
397
398end
399
400
401
402do
403
404 local loaded = package.loaded
405
406 if not loaded.socket then loaded.socket = loaded["socket.core"] end
407 if not loaded.mime then loaded.mime = loaded["mime.core"] end
408
409 if not loaded.lfs then loaded.lfs = lfs end
410
411end
412
413do
414
415 local lfsattributes = lfs.attributes
416 local symlinkattributes = lfs.symlinkattributes
417
418
419
420 if not lfs.isfile then
421 function lfs.isfile(name)
422 local m = lfsattributes(name,"mode")
423 return m == "file" or m == "link"
424 end
425 end
426
427 if not lfs.isdir then
428 function lfs.isdir(name)
429 local m = lfsattributes(name,"mode")
430 return m == "directory"
431 end
432 end
433
434
435
436 if not lfs.shortname then
437 function lfs.shortname(name)
438 return name
439 end
440 end
441
442
443
444 if not lfs.readlink then
445 function lfs.readlink(name)
446 return symlinkattributes(name,"target") or nil
447 end
448 end
449
450end
451
452
453
454if utilities and utilities.merger and utilities.merger.compact then
455
456 local byte, format, gmatch, gsub = string.byte, string.format, string.gmatch, string.gsub
457 local concat = table.concat
458
459 local data = io.loaddata('luatex-core.lua')
460
461 data = gsub(data,'%-%-%s*start%s*omit.-%-%-%s*stop%s*omit%s*','')
462 data = gsub(data,'\r\n','\n')
463
464 local t = { }
465 local r = { }
466 local n = 0
467 local s = utilities.merger.compact(data)
468
469 t[#t+1] = '/* generated from and by luatex-core.lua */'
470 t[#t+1] = ''
471 t[#t+1] = '#include "lua.h"'
472 t[#t+1] = '#include "lauxlib.h"'
473 t[#t+1] = ''
474 t[#t+1] = 'int load_luatex_core_lua (lua_State * L);'
475 t[#t+1] = ''
476 t[#t+1] = 'int load_luatex_core_lua (lua_State * L)'
477 t[#t+1] = '{'
478 t[#t+1] = ' static unsigned char luatex_core_lua[] = {'
479 for c in gmatch(data,'.') do
480 if n == 16 then
481 n = 1
482 t[#t+1] = ' ' .. concat(r,', ') .. ','
483 else
484 n = n + 1
485 end
486 r[n] = format('0x%02x',byte(c))
487 end
488 n = n + 1
489 r[n] = '0x00'
490 t[#t+1] = ' ' .. concat(r,', ',1,n)
491 t[#t+1] = ' };'
492
493 t[#t+1] = ' return luaL_dostring(L, (const char*) luatex_core_lua);'
494 t[#t+1] = '}'
495
496 io.savedata('luatex-core.c',concat(t,'\n'))
497 io.savedata('luatex-core-stripped.lua',s)
498
499end
500
501
502 |