trac-pro.lua /size: 5841 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
trac-pro
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to luat-lib.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
local
getmetatable
,
setmetatable
,
rawset
,
type
,
next
=
getmetatable
,
setmetatable
,
rawset
,
type
,
next
10 11
-- The protection implemented here is probably not that tight but good enough to catch
12
-- problems due to naive usage.
13
--
14
-- There's a more extensive version (trac-xxx.lua) that supports nesting.
15
--
16
-- This will change when we have _ENV in lua 5.2+
17 18
local
trace_namespaces
=
false
trackers
.
register
(
"
system.namespaces
"
,
function
(
v
)
trace_namespaces
=
v
end
)
19 20
local
report_system
=
logs
.
reporter
(
"
system
"
,
"
protection
"
)
21 22
namespaces
=
namespaces
or
{
}
23
local
namespaces
=
namespaces
24 25
local
registered
=
{
}
26 27
local
function
report_index
(
k
,
name
)
28
if
trace_namespaces
then
29
report_system
(
"
reference to %a in protected namespace %a: %s
"
,
k
,
name
)
30
debugger
.
showtraceback
(
report_system
)
31
else
32
report_system
(
"
reference to %a in protected namespace %a
"
,
k
,
name
)
33
end
34
end
35 36
local
function
report_newindex
(
k
,
name
)
37
if
trace_namespaces
then
38
report_system
(
"
assignment to %a in protected namespace %a: %s
"
,
k
,
name
)
39
debugger
.
showtraceback
(
report_system
)
40
else
41
report_system
(
"
assignment to %a in protected namespace %a
"
,
k
,
name
)
42
end
43
end
44 45
local
function
register
(
name
)
46
local
data
=
name
=
=
"
global
"
and
_G
or
_G
[
name
]
47
if
not
data
then
48
return
-- error
49
end
50
registered
[
name
]
=
data
51
local
m
=
getmetatable
(
data
)
52
if
not
m
then
53
m
=
{
}
54
setmetatable
(
data
,
m
)
55
end
56
local
index
,
newindex
=
{
}
,
{
}
57
m
.
__saved__index
=
m
.
__index
58
m
.
__no__index
=
function
(
t
,
k
)
59
if
not
index
[
k
]
then
60
index
[
k
]
=
true
61
report_index
(
k
,
name
)
62
end
63
return
nil
64
end
65
m
.
__saved__newindex
=
m
.
__newindex
66
m
.
__no__newindex
=
function
(
t
,
k
,
v
)
67
if
not
newindex
[
k
]
then
68
newindex
[
k
]
=
true
69
report_newindex
(
k
,
name
)
70
end
71
rawset
(
t
,
k
,
v
)
72
end
73
m
.
__protection__depth
=
0
74
end
75 76
local
function
private
(
name
)
-- maybe save name
77
local
data
=
registered
[
name
]
78
if
not
data
then
79
data
=
_G
[
name
]
80
if
not
data
then
81
data
=
{
}
82
_G
[
name
]
=
data
83
end
84
register
(
name
)
85
end
86
return
data
87
end
88 89
local
function
protect
(
name
)
90
local
data
=
registered
[
name
]
91
if
not
data
then
92
return
93
end
94
local
m
=
getmetatable
(
data
)
95
local
pd
=
m
.
__protection__depth
96
if
pd
>
0
then
97
m
.
__protection__depth
=
pd
+
1
98
else
99
m
.
__save_d_index
,
m
.
__saved__newindex
=
m
.
__index
,
m
.
__newindex
100
m
.
__index
,
m
.
__newindex
=
m
.
__no__index
,
m
.
__no__newindex
101
m
.
__protection__depth
=
1
102
end
103
end
104 105
local
function
unprotect
(
name
)
106
local
data
=
registered
[
name
]
107
if
not
data
then
108
return
109
end
110
local
m
=
getmetatable
(
data
)
111
local
pd
=
m
.
__protection__depth
112
if
pd
>
1
then
113
m
.
__protection__depth
=
pd
-
1
114
else
115
m
.
__index
,
m
.
__newindex
=
m
.
__saved__index
,
m
.
__saved__newindex
116
m
.
__protection__depth
=
0
117
end
118
end
119 120
local
function
protectall
(
)
121
for
name
,
_
in
next
,
registered
do
122
if
name
~
=
"
global
"
then
123
protect
(
name
)
124
end
125
end
126
end
127 128
local
function
unprotectall
(
)
129
for
name
,
_
in
next
,
registered
do
130
if
name
~
=
"
global
"
then
131
unprotect
(
name
)
132
end
133
end
134
end
135 136
namespaces
.
register
=
register
-- register when defined
137
namespaces
.
private
=
private
-- allocate and register if needed
138
namespaces
.
protect
=
protect
139
namespaces
.
unprotect
=
unprotect
140
namespaces
.
protectall
=
protectall
141
namespaces
.
unprotectall
=
unprotectall
142 143
namespaces
.
private
(
"
namespaces
"
)
registered
=
{
}
register
(
"
global
"
)
-- unreachable
144 145
directives
.
register
(
"
system.protect
"
,
function
(
v
)
146
if
v
then
147
protectall
(
)
148
else
149
unprotectall
(
)
150
end
151
end
)
152 153
directives
.
register
(
"
system.checkglobals
"
,
function
(
v
)
154
if
v
then
155
report_system
(
"
enabling global namespace guard
"
)
156
protect
(
"
global
"
)
157
else
158
report_system
(
"
disabling global namespace guard
"
)
159
unprotect
(
"
global
"
)
160
end
161
end
)
162 163
-- dummy section (will go to luat-dum.lua)
164 165
--~ if not namespaces.private then
166
--~ -- somewhat protected
167
--~ local registered = { }
168
--~ function namespaces.private(name)
169
--~ local data = registered[name]
170
--~ if data then
171
--~ return data
172
--~ end
173
--~ local data = _G[name]
174
--~ if not data then
175
--~ data = { }
176
--~ _G[name] = data
177
--~ end
178
--~ registered[name] = data
179
--~ return data
180
--~ end
181
--~ function namespaces.protectall(list)
182
--~ for name, data in next, list or registered do
183
--~ setmetatable(data, { __newindex = function() print(string.format("table %s is protected",name)) end })
184
--~ end
185
--~ end
186
--~ namespaces.protectall { namespaces = namespaces }
187
--~ end
188 189
--~ directives.enable("system.checkglobals")
190 191
--~ namespaces.register("resolvers","trackers")
192
--~ namespaces.protect("resolvers")
193
--~ namespaces.protect("resolvers")
194
--~ namespaces.protect("resolvers")
195
--~ namespaces.unprotect("resolvers")
196
--~ namespaces.unprotect("resolvers")
197
--~ namespaces.unprotect("resolvers")
198
--~ namespaces.protect("trackers")
199 200
--~ resolvers.x = true
201
--~ resolvers.y = true
202
--~ trackers.a = ""
203
--~ resolvers.z = true
204
--~ oeps = { }
205 206
--~ resolvers = namespaces.private("resolvers")
207
--~ fonts = namespaces.private("fonts")
208
--~ directives.enable("system.protect")
209
--~ namespaces.protectall()
210
--~ resolvers.xx = { }
211