immunio 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,76 @@
1
+ /*
2
+ ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
3
+ ** Code generator for Lua
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+ #ifndef lcode_h
8
+ #define lcode_h
9
+
10
+ #include "llex.h"
11
+ #include "lobject.h"
12
+ #include "lopcodes.h"
13
+ #include "lparser.h"
14
+
15
+
16
+ /*
17
+ ** Marks the end of a patch list. It is an invalid value both as an absolute
18
+ ** address, and as a list link (would link an element to itself).
19
+ */
20
+ #define NO_JUMP (-1)
21
+
22
+
23
+ /*
24
+ ** grep "ORDER OPR" if you change these enums
25
+ */
26
+ typedef enum BinOpr {
27
+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
28
+ OPR_CONCAT,
29
+ OPR_NE, OPR_EQ,
30
+ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
31
+ OPR_AND, OPR_OR,
32
+ OPR_NOBINOPR
33
+ } BinOpr;
34
+
35
+
36
+ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37
+
38
+
39
+ #define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
40
+
41
+ #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
42
+
43
+ #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
44
+
45
+ LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
46
+ LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
47
+ LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
48
+ LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
49
+ LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
50
+ LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
51
+ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
52
+ LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
53
+ LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
54
+ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
55
+ LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
56
+ LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
57
+ LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
58
+ LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
59
+ LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
60
+ LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
61
+ LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
62
+ LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
63
+ LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
64
+ LUAI_FUNC int luaK_jump (FuncState *fs);
65
+ LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
66
+ LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
67
+ LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
68
+ LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
69
+ LUAI_FUNC int luaK_getlabel (FuncState *fs);
70
+ LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
71
+ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
72
+ LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
73
+ LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
74
+
75
+
76
+ #endif
@@ -0,0 +1,398 @@
1
+ /*
2
+ ** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 roberto Exp $
3
+ ** Interface from Lua to its debug API
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ #define ldblib_c
13
+ #define LUA_LIB
14
+
15
+ #include "lua.h"
16
+
17
+ #include "lauxlib.h"
18
+ #include "lualib.h"
19
+
20
+
21
+
22
+ static int db_getregistry (lua_State *L) {
23
+ lua_pushvalue(L, LUA_REGISTRYINDEX);
24
+ return 1;
25
+ }
26
+
27
+
28
+ static int db_getmetatable (lua_State *L) {
29
+ luaL_checkany(L, 1);
30
+ if (!lua_getmetatable(L, 1)) {
31
+ lua_pushnil(L); /* no metatable */
32
+ }
33
+ return 1;
34
+ }
35
+
36
+
37
+ static int db_setmetatable (lua_State *L) {
38
+ int t = lua_type(L, 2);
39
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
40
+ "nil or table expected");
41
+ lua_settop(L, 2);
42
+ lua_pushboolean(L, lua_setmetatable(L, 1));
43
+ return 1;
44
+ }
45
+
46
+
47
+ static int db_getfenv (lua_State *L) {
48
+ luaL_checkany(L, 1);
49
+ lua_getfenv(L, 1);
50
+ return 1;
51
+ }
52
+
53
+
54
+ static int db_setfenv (lua_State *L) {
55
+ luaL_checktype(L, 2, LUA_TTABLE);
56
+ lua_settop(L, 2);
57
+ if (lua_setfenv(L, 1) == 0)
58
+ luaL_error(L, LUA_QL("setfenv")
59
+ " cannot change environment of given object");
60
+ return 1;
61
+ }
62
+
63
+
64
+ static void settabss (lua_State *L, const char *i, const char *v) {
65
+ lua_pushstring(L, v);
66
+ lua_setfield(L, -2, i);
67
+ }
68
+
69
+
70
+ static void settabsi (lua_State *L, const char *i, int v) {
71
+ lua_pushinteger(L, v);
72
+ lua_setfield(L, -2, i);
73
+ }
74
+
75
+
76
+ static lua_State *getthread (lua_State *L, int *arg) {
77
+ if (lua_isthread(L, 1)) {
78
+ *arg = 1;
79
+ return lua_tothread(L, 1);
80
+ }
81
+ else {
82
+ *arg = 0;
83
+ return L;
84
+ }
85
+ }
86
+
87
+
88
+ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
89
+ if (L == L1) {
90
+ lua_pushvalue(L, -2);
91
+ lua_remove(L, -3);
92
+ }
93
+ else
94
+ lua_xmove(L1, L, 1);
95
+ lua_setfield(L, -2, fname);
96
+ }
97
+
98
+
99
+ static int db_getinfo (lua_State *L) {
100
+ lua_Debug ar;
101
+ int arg;
102
+ lua_State *L1 = getthread(L, &arg);
103
+ const char *options = luaL_optstring(L, arg+2, "flnSu");
104
+ if (lua_isnumber(L, arg+1)) {
105
+ if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
106
+ lua_pushnil(L); /* level out of range */
107
+ return 1;
108
+ }
109
+ }
110
+ else if (lua_isfunction(L, arg+1)) {
111
+ lua_pushfstring(L, ">%s", options);
112
+ options = lua_tostring(L, -1);
113
+ lua_pushvalue(L, arg+1);
114
+ lua_xmove(L, L1, 1);
115
+ }
116
+ else
117
+ return luaL_argerror(L, arg+1, "function or level expected");
118
+ if (!lua_getinfo(L1, options, &ar))
119
+ return luaL_argerror(L, arg+2, "invalid option");
120
+ lua_createtable(L, 0, 2);
121
+ if (strchr(options, 'S')) {
122
+ settabss(L, "source", ar.source);
123
+ settabss(L, "short_src", ar.short_src);
124
+ settabsi(L, "linedefined", ar.linedefined);
125
+ settabsi(L, "lastlinedefined", ar.lastlinedefined);
126
+ settabss(L, "what", ar.what);
127
+ }
128
+ if (strchr(options, 'l'))
129
+ settabsi(L, "currentline", ar.currentline);
130
+ if (strchr(options, 'u'))
131
+ settabsi(L, "nups", ar.nups);
132
+ if (strchr(options, 'n')) {
133
+ settabss(L, "name", ar.name);
134
+ settabss(L, "namewhat", ar.namewhat);
135
+ }
136
+ if (strchr(options, 'L'))
137
+ treatstackoption(L, L1, "activelines");
138
+ if (strchr(options, 'f'))
139
+ treatstackoption(L, L1, "func");
140
+ return 1; /* return table */
141
+ }
142
+
143
+
144
+ static int db_getlocal (lua_State *L) {
145
+ int arg;
146
+ lua_State *L1 = getthread(L, &arg);
147
+ lua_Debug ar;
148
+ const char *name;
149
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
150
+ return luaL_argerror(L, arg+1, "level out of range");
151
+ name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
152
+ if (name) {
153
+ lua_xmove(L1, L, 1);
154
+ lua_pushstring(L, name);
155
+ lua_pushvalue(L, -2);
156
+ return 2;
157
+ }
158
+ else {
159
+ lua_pushnil(L);
160
+ return 1;
161
+ }
162
+ }
163
+
164
+
165
+ static int db_setlocal (lua_State *L) {
166
+ int arg;
167
+ lua_State *L1 = getthread(L, &arg);
168
+ lua_Debug ar;
169
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
170
+ return luaL_argerror(L, arg+1, "level out of range");
171
+ luaL_checkany(L, arg+3);
172
+ lua_settop(L, arg+3);
173
+ lua_xmove(L, L1, 1);
174
+ lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
175
+ return 1;
176
+ }
177
+
178
+
179
+ static int auxupvalue (lua_State *L, int get) {
180
+ const char *name;
181
+ int n = luaL_checkint(L, 2);
182
+ luaL_checktype(L, 1, LUA_TFUNCTION);
183
+ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
184
+ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
185
+ if (name == NULL) return 0;
186
+ lua_pushstring(L, name);
187
+ lua_insert(L, -(get+1));
188
+ return get + 1;
189
+ }
190
+
191
+
192
+ static int db_getupvalue (lua_State *L) {
193
+ return auxupvalue(L, 1);
194
+ }
195
+
196
+
197
+ static int db_setupvalue (lua_State *L) {
198
+ luaL_checkany(L, 3);
199
+ return auxupvalue(L, 0);
200
+ }
201
+
202
+
203
+
204
+ static const char KEY_HOOK = 'h';
205
+
206
+
207
+ static void hookf (lua_State *L, lua_Debug *ar) {
208
+ static const char *const hooknames[] =
209
+ {"call", "return", "line", "count", "tail return"};
210
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
211
+ lua_rawget(L, LUA_REGISTRYINDEX);
212
+ lua_pushlightuserdata(L, L);
213
+ lua_rawget(L, -2);
214
+ if (lua_isfunction(L, -1)) {
215
+ lua_pushstring(L, hooknames[(int)ar->event]);
216
+ if (ar->currentline >= 0)
217
+ lua_pushinteger(L, ar->currentline);
218
+ else lua_pushnil(L);
219
+ lua_assert(lua_getinfo(L, "lS", ar));
220
+ lua_call(L, 2, 0);
221
+ }
222
+ }
223
+
224
+
225
+ static int makemask (const char *smask, int count) {
226
+ int mask = 0;
227
+ if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
228
+ if (strchr(smask, 'r')) mask |= LUA_MASKRET;
229
+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
230
+ if (count > 0) mask |= LUA_MASKCOUNT;
231
+ return mask;
232
+ }
233
+
234
+
235
+ static char *unmakemask (int mask, char *smask) {
236
+ int i = 0;
237
+ if (mask & LUA_MASKCALL) smask[i++] = 'c';
238
+ if (mask & LUA_MASKRET) smask[i++] = 'r';
239
+ if (mask & LUA_MASKLINE) smask[i++] = 'l';
240
+ smask[i] = '\0';
241
+ return smask;
242
+ }
243
+
244
+
245
+ static void gethooktable (lua_State *L) {
246
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
247
+ lua_rawget(L, LUA_REGISTRYINDEX);
248
+ if (!lua_istable(L, -1)) {
249
+ lua_pop(L, 1);
250
+ lua_createtable(L, 0, 1);
251
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
252
+ lua_pushvalue(L, -2);
253
+ lua_rawset(L, LUA_REGISTRYINDEX);
254
+ }
255
+ }
256
+
257
+
258
+ static int db_sethook (lua_State *L) {
259
+ int arg, mask, count;
260
+ lua_Hook func;
261
+ lua_State *L1 = getthread(L, &arg);
262
+ if (lua_isnoneornil(L, arg+1)) {
263
+ lua_settop(L, arg+1);
264
+ func = NULL; mask = 0; count = 0; /* turn off hooks */
265
+ }
266
+ else {
267
+ const char *smask = luaL_checkstring(L, arg+2);
268
+ luaL_checktype(L, arg+1, LUA_TFUNCTION);
269
+ count = luaL_optint(L, arg+3, 0);
270
+ func = hookf; mask = makemask(smask, count);
271
+ }
272
+ gethooktable(L);
273
+ lua_pushlightuserdata(L, L1);
274
+ lua_pushvalue(L, arg+1);
275
+ lua_rawset(L, -3); /* set new hook */
276
+ lua_pop(L, 1); /* remove hook table */
277
+ lua_sethook(L1, func, mask, count); /* set hooks */
278
+ return 0;
279
+ }
280
+
281
+
282
+ static int db_gethook (lua_State *L) {
283
+ int arg;
284
+ lua_State *L1 = getthread(L, &arg);
285
+ char buff[5];
286
+ int mask = lua_gethookmask(L1);
287
+ lua_Hook hook = lua_gethook(L1);
288
+ if (hook != NULL && hook != hookf) /* external hook? */
289
+ lua_pushliteral(L, "external hook");
290
+ else {
291
+ gethooktable(L);
292
+ lua_pushlightuserdata(L, L1);
293
+ lua_rawget(L, -2); /* get hook */
294
+ lua_remove(L, -2); /* remove hook table */
295
+ }
296
+ lua_pushstring(L, unmakemask(mask, buff));
297
+ lua_pushinteger(L, lua_gethookcount(L1));
298
+ return 3;
299
+ }
300
+
301
+
302
+ static int db_debug (lua_State *L) {
303
+ for (;;) {
304
+ char buffer[250];
305
+ fputs("lua_debug> ", stderr);
306
+ if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
307
+ strcmp(buffer, "cont\n") == 0)
308
+ return 0;
309
+ if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
310
+ lua_pcall(L, 0, 0, 0)) {
311
+ fputs(lua_tostring(L, -1), stderr);
312
+ fputs("\n", stderr);
313
+ }
314
+ lua_settop(L, 0); /* remove eventual returns */
315
+ }
316
+ }
317
+
318
+
319
+ #define LEVELS1 12 /* size of the first part of the stack */
320
+ #define LEVELS2 10 /* size of the second part of the stack */
321
+
322
+ static int db_errorfb (lua_State *L) {
323
+ int level;
324
+ int firstpart = 1; /* still before eventual `...' */
325
+ int arg;
326
+ lua_State *L1 = getthread(L, &arg);
327
+ lua_Debug ar;
328
+ if (lua_isnumber(L, arg+2)) {
329
+ level = (int)lua_tointeger(L, arg+2);
330
+ lua_pop(L, 1);
331
+ }
332
+ else
333
+ level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
334
+ if (lua_gettop(L) == arg)
335
+ lua_pushliteral(L, "");
336
+ else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
337
+ else lua_pushliteral(L, "\n");
338
+ lua_pushliteral(L, "stack traceback:");
339
+ while (lua_getstack(L1, level++, &ar)) {
340
+ if (level > LEVELS1 && firstpart) {
341
+ /* no more than `LEVELS2' more levels? */
342
+ if (!lua_getstack(L1, level+LEVELS2, &ar))
343
+ level--; /* keep going */
344
+ else {
345
+ lua_pushliteral(L, "\n\t..."); /* too many levels */
346
+ while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
347
+ level++;
348
+ }
349
+ firstpart = 0;
350
+ continue;
351
+ }
352
+ lua_pushliteral(L, "\n\t");
353
+ lua_getinfo(L1, "Snl", &ar);
354
+ lua_pushfstring(L, "%s:", ar.short_src);
355
+ if (ar.currentline > 0)
356
+ lua_pushfstring(L, "%d:", ar.currentline);
357
+ if (*ar.namewhat != '\0') /* is there a name? */
358
+ lua_pushfstring(L, " in function " LUA_QS, ar.name);
359
+ else {
360
+ if (*ar.what == 'm') /* main? */
361
+ lua_pushfstring(L, " in main chunk");
362
+ else if (*ar.what == 'C' || *ar.what == 't')
363
+ lua_pushliteral(L, " ?"); /* C function or tail call */
364
+ else
365
+ lua_pushfstring(L, " in function <%s:%d>",
366
+ ar.short_src, ar.linedefined);
367
+ }
368
+ lua_concat(L, lua_gettop(L) - arg);
369
+ }
370
+ lua_concat(L, lua_gettop(L) - arg);
371
+ return 1;
372
+ }
373
+
374
+
375
+ static const luaL_Reg dblib[] = {
376
+ {"debug", db_debug},
377
+ {"getfenv", db_getfenv},
378
+ {"gethook", db_gethook},
379
+ {"getinfo", db_getinfo},
380
+ {"getlocal", db_getlocal},
381
+ {"getregistry", db_getregistry},
382
+ {"getmetatable", db_getmetatable},
383
+ {"getupvalue", db_getupvalue},
384
+ {"setfenv", db_setfenv},
385
+ {"sethook", db_sethook},
386
+ {"setlocal", db_setlocal},
387
+ {"setmetatable", db_setmetatable},
388
+ {"setupvalue", db_setupvalue},
389
+ {"traceback", db_errorfb},
390
+ {NULL, NULL}
391
+ };
392
+
393
+
394
+ LUALIB_API int luaopen_debug (lua_State *L) {
395
+ luaL_register(L, LUA_DBLIBNAME, dblib);
396
+ return 1;
397
+ }
398
+