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,174 @@
1
+ /*
2
+ ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
3
+ ** Auxiliary functions for building Lua libraries
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+ #ifndef lauxlib_h
9
+ #define lauxlib_h
10
+
11
+
12
+ #include <stddef.h>
13
+ #include <stdio.h>
14
+
15
+ #include "lua.h"
16
+
17
+
18
+ #if defined(LUA_COMPAT_GETN)
19
+ LUALIB_API int (luaL_getn) (lua_State *L, int t);
20
+ LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
21
+ #else
22
+ #define luaL_getn(L,i) ((int)lua_objlen(L, i))
23
+ #define luaL_setn(L,i,j) ((void)0) /* no op! */
24
+ #endif
25
+
26
+ #if defined(LUA_COMPAT_OPENLIB)
27
+ #define luaI_openlib luaL_openlib
28
+ #endif
29
+
30
+
31
+ /* extra error code for `luaL_load' */
32
+ #define LUA_ERRFILE (LUA_ERRERR+1)
33
+
34
+
35
+ typedef struct luaL_Reg {
36
+ const char *name;
37
+ lua_CFunction func;
38
+ } luaL_Reg;
39
+
40
+
41
+
42
+ LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
43
+ const luaL_Reg *l, int nup);
44
+ LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
45
+ const luaL_Reg *l);
46
+ LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
47
+ LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
48
+ LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
49
+ LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
50
+ LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
51
+ size_t *l);
52
+ LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
53
+ const char *def, size_t *l);
54
+ LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
55
+ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
56
+
57
+ LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
58
+ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
59
+ lua_Integer def);
60
+
61
+ LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
62
+ LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
63
+ LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
64
+
65
+ LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
66
+ LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
67
+
68
+ LUALIB_API void (luaL_where) (lua_State *L, int lvl);
69
+ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
70
+
71
+ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
72
+ const char *const lst[]);
73
+
74
+ LUALIB_API int (luaL_ref) (lua_State *L, int t);
75
+ LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
76
+
77
+ LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
78
+ LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
79
+ const char *name);
80
+ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
81
+
82
+ LUALIB_API lua_State *(luaL_newstate) (void);
83
+
84
+
85
+ LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
86
+ const char *r);
87
+
88
+ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
89
+ const char *fname, int szhint);
90
+
91
+
92
+
93
+
94
+ /*
95
+ ** ===============================================================
96
+ ** some useful macros
97
+ ** ===============================================================
98
+ */
99
+
100
+ #define luaL_argcheck(L, cond,numarg,extramsg) \
101
+ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
102
+ #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
103
+ #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
104
+ #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
105
+ #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
106
+ #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
107
+ #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
108
+
109
+ #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
110
+
111
+ #define luaL_dofile(L, fn) \
112
+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
113
+
114
+ #define luaL_dostring(L, s) \
115
+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
116
+
117
+ #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
118
+
119
+ #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
120
+
121
+ /*
122
+ ** {======================================================
123
+ ** Generic Buffer manipulation
124
+ ** =======================================================
125
+ */
126
+
127
+
128
+
129
+ typedef struct luaL_Buffer {
130
+ char *p; /* current position in buffer */
131
+ int lvl; /* number of strings in the stack (level) */
132
+ lua_State *L;
133
+ char buffer[LUAL_BUFFERSIZE];
134
+ } luaL_Buffer;
135
+
136
+ #define luaL_addchar(B,c) \
137
+ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
138
+ (*(B)->p++ = (char)(c)))
139
+
140
+ /* compatibility only */
141
+ #define luaL_putchar(B,c) luaL_addchar(B,c)
142
+
143
+ #define luaL_addsize(B,n) ((B)->p += (n))
144
+
145
+ LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
146
+ LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
147
+ LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
148
+ LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
149
+ LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
150
+ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
151
+
152
+
153
+ /* }====================================================== */
154
+
155
+
156
+ /* compatibility with ref system */
157
+
158
+ /* pre-defined references */
159
+ #define LUA_NOREF (-2)
160
+ #define LUA_REFNIL (-1)
161
+
162
+ #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
163
+ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
164
+
165
+ #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
166
+
167
+ #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
168
+
169
+
170
+ #define luaL_reg luaL_Reg
171
+
172
+ #endif
173
+
174
+
@@ -0,0 +1,659 @@
1
+ /*
2
+ ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
3
+ ** Basic library
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+
9
+ #include <ctype.h>
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+
14
+ #define lbaselib_c
15
+ #define LUA_LIB
16
+
17
+ #include "lua.h"
18
+
19
+ #include "lauxlib.h"
20
+ #include "lualib.h"
21
+
22
+
23
+
24
+
25
+ /*
26
+ ** If your system does not support `stdout', you can just remove this function.
27
+ ** If you need, you can define your own `print' function, following this
28
+ ** model but changing `fputs' to put the strings at a proper place
29
+ ** (a console window or a log file, for instance).
30
+ */
31
+ static int luaB_print (lua_State *L) {
32
+ int n = lua_gettop(L); /* number of arguments */
33
+ int i;
34
+ lua_getglobal(L, "tostring");
35
+ for (i=1; i<=n; i++) {
36
+ const char *s;
37
+ lua_pushvalue(L, -1); /* function to be called */
38
+ lua_pushvalue(L, i); /* value to print */
39
+ lua_call(L, 1, 1);
40
+ s = lua_tostring(L, -1); /* get result */
41
+ if (s == NULL)
42
+ return luaL_error(L, LUA_QL("tostring") " must return a string to "
43
+ LUA_QL("print"));
44
+ if (i>1) fputs("\t", stdout);
45
+ fputs(s, stdout);
46
+ lua_pop(L, 1); /* pop result */
47
+ }
48
+ fputs("\n", stdout);
49
+ /*
50
+ ** XXX This fflush is needed because print is used to output debug
51
+ ** information which should not be buffered. This change does not affect
52
+ ** the behavior of the print function but it might affect its performance.
53
+ */
54
+ fflush(stdout);
55
+ return 0;
56
+ }
57
+
58
+
59
+ static int luaB_tonumber (lua_State *L) {
60
+ int base = luaL_optint(L, 2, 10);
61
+ if (base == 10) { /* standard conversion */
62
+ luaL_checkany(L, 1);
63
+ if (lua_isnumber(L, 1)) {
64
+ lua_pushnumber(L, lua_tonumber(L, 1));
65
+ return 1;
66
+ }
67
+ }
68
+ else {
69
+ const char *s1 = luaL_checkstring(L, 1);
70
+ char *s2;
71
+ unsigned long n;
72
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
73
+ n = strtoul(s1, &s2, base);
74
+ if (s1 != s2) { /* at least one valid digit? */
75
+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
76
+ if (*s2 == '\0') { /* no invalid trailing characters? */
77
+ lua_pushnumber(L, (lua_Number)n);
78
+ return 1;
79
+ }
80
+ }
81
+ }
82
+ lua_pushnil(L); /* else not a number */
83
+ return 1;
84
+ }
85
+
86
+
87
+ static int luaB_error (lua_State *L) {
88
+ int level = luaL_optint(L, 2, 1);
89
+ lua_settop(L, 1);
90
+ if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
91
+ luaL_where(L, level);
92
+ lua_pushvalue(L, 1);
93
+ lua_concat(L, 2);
94
+ }
95
+ return lua_error(L);
96
+ }
97
+
98
+
99
+ static int luaB_getmetatable (lua_State *L) {
100
+ luaL_checkany(L, 1);
101
+ if (!lua_getmetatable(L, 1)) {
102
+ lua_pushnil(L);
103
+ return 1; /* no metatable */
104
+ }
105
+ luaL_getmetafield(L, 1, "__metatable");
106
+ return 1; /* returns either __metatable field (if present) or metatable */
107
+ }
108
+
109
+
110
+ static int luaB_setmetatable (lua_State *L) {
111
+ int t = lua_type(L, 2);
112
+ luaL_checktype(L, 1, LUA_TTABLE);
113
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
114
+ "nil or table expected");
115
+ if (luaL_getmetafield(L, 1, "__metatable"))
116
+ luaL_error(L, "cannot change a protected metatable");
117
+ lua_settop(L, 2);
118
+ lua_setmetatable(L, 1);
119
+ return 1;
120
+ }
121
+
122
+
123
+ static void getfunc (lua_State *L, int opt) {
124
+ if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
125
+ else {
126
+ lua_Debug ar;
127
+ int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
128
+ luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
129
+ if (lua_getstack(L, level, &ar) == 0)
130
+ luaL_argerror(L, 1, "invalid level");
131
+ lua_getinfo(L, "f", &ar);
132
+ if (lua_isnil(L, -1))
133
+ luaL_error(L, "no function environment for tail call at level %d",
134
+ level);
135
+ }
136
+ }
137
+
138
+
139
+ static int luaB_getfenv (lua_State *L) {
140
+ getfunc(L, 1);
141
+ if (lua_iscfunction(L, -1)) /* is a C function? */
142
+ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
143
+ else
144
+ lua_getfenv(L, -1);
145
+ return 1;
146
+ }
147
+
148
+
149
+ static int luaB_setfenv (lua_State *L) {
150
+ luaL_checktype(L, 2, LUA_TTABLE);
151
+ getfunc(L, 0);
152
+ lua_pushvalue(L, 2);
153
+ if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
154
+ /* change environment of current thread */
155
+ lua_pushthread(L);
156
+ lua_insert(L, -2);
157
+ lua_setfenv(L, -2);
158
+ return 0;
159
+ }
160
+ else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
161
+ luaL_error(L,
162
+ LUA_QL("setfenv") " cannot change environment of given object");
163
+ return 1;
164
+ }
165
+
166
+
167
+ static int luaB_rawequal (lua_State *L) {
168
+ luaL_checkany(L, 1);
169
+ luaL_checkany(L, 2);
170
+ lua_pushboolean(L, lua_rawequal(L, 1, 2));
171
+ return 1;
172
+ }
173
+
174
+
175
+ static int luaB_rawget (lua_State *L) {
176
+ luaL_checktype(L, 1, LUA_TTABLE);
177
+ luaL_checkany(L, 2);
178
+ lua_settop(L, 2);
179
+ lua_rawget(L, 1);
180
+ return 1;
181
+ }
182
+
183
+ static int luaB_rawset (lua_State *L) {
184
+ luaL_checktype(L, 1, LUA_TTABLE);
185
+ luaL_checkany(L, 2);
186
+ luaL_checkany(L, 3);
187
+ lua_settop(L, 3);
188
+ lua_rawset(L, 1);
189
+ return 1;
190
+ }
191
+
192
+
193
+ static int luaB_gcinfo (lua_State *L) {
194
+ lua_pushinteger(L, lua_getgccount(L));
195
+ return 1;
196
+ }
197
+
198
+
199
+ static int luaB_collectgarbage (lua_State *L) {
200
+ static const char *const opts[] = {"stop", "restart", "collect",
201
+ "count", "step", "setpause", "setstepmul", NULL};
202
+ static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
203
+ LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
204
+ int o = luaL_checkoption(L, 1, "collect", opts);
205
+ int ex = luaL_optint(L, 2, 0);
206
+ int res = lua_gc(L, optsnum[o], ex);
207
+ switch (optsnum[o]) {
208
+ case LUA_GCCOUNT: {
209
+ int b = lua_gc(L, LUA_GCCOUNTB, 0);
210
+ lua_pushnumber(L, res + ((lua_Number)b/1024));
211
+ return 1;
212
+ }
213
+ case LUA_GCSTEP: {
214
+ lua_pushboolean(L, res);
215
+ return 1;
216
+ }
217
+ default: {
218
+ lua_pushnumber(L, res);
219
+ return 1;
220
+ }
221
+ }
222
+ }
223
+
224
+
225
+ static int luaB_type (lua_State *L) {
226
+ luaL_checkany(L, 1);
227
+ lua_pushstring(L, luaL_typename(L, 1));
228
+ return 1;
229
+ }
230
+
231
+
232
+ static int luaB_next (lua_State *L) {
233
+ luaL_checktype(L, 1, LUA_TTABLE);
234
+ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
235
+ if (lua_next(L, 1))
236
+ return 2;
237
+ else {
238
+ lua_pushnil(L);
239
+ return 1;
240
+ }
241
+ }
242
+
243
+
244
+ static int luaB_pairs (lua_State *L) {
245
+ luaL_checktype(L, 1, LUA_TTABLE);
246
+ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
247
+ lua_pushvalue(L, 1); /* state, */
248
+ lua_pushnil(L); /* and initial value */
249
+ return 3;
250
+ }
251
+
252
+
253
+ static int ipairsaux (lua_State *L) {
254
+ int i = luaL_checkint(L, 2);
255
+ luaL_checktype(L, 1, LUA_TTABLE);
256
+ i++; /* next value */
257
+ lua_pushinteger(L, i);
258
+ lua_rawgeti(L, 1, i);
259
+ return (lua_isnil(L, -1)) ? 0 : 2;
260
+ }
261
+
262
+
263
+ static int luaB_ipairs (lua_State *L) {
264
+ luaL_checktype(L, 1, LUA_TTABLE);
265
+ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
266
+ lua_pushvalue(L, 1); /* state, */
267
+ lua_pushinteger(L, 0); /* and initial value */
268
+ return 3;
269
+ }
270
+
271
+
272
+ static int load_aux (lua_State *L, int status) {
273
+ if (status == 0) /* OK? */
274
+ return 1;
275
+ else {
276
+ lua_pushnil(L);
277
+ lua_insert(L, -2); /* put before error message */
278
+ return 2; /* return nil plus error message */
279
+ }
280
+ }
281
+
282
+
283
+ static int luaB_loadstring (lua_State *L) {
284
+ size_t l;
285
+ const char *s = luaL_checklstring(L, 1, &l);
286
+ const char *chunkname = luaL_optstring(L, 2, s);
287
+ return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
288
+ }
289
+
290
+
291
+ static int luaB_loadfile (lua_State *L) {
292
+ const char *fname = luaL_optstring(L, 1, NULL);
293
+ return load_aux(L, luaL_loadfile(L, fname));
294
+ }
295
+
296
+
297
+ /*
298
+ ** Reader for generic `load' function: `lua_load' uses the
299
+ ** stack for internal stuff, so the reader cannot change the
300
+ ** stack top. Instead, it keeps its resulting string in a
301
+ ** reserved slot inside the stack.
302
+ */
303
+ static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
304
+ (void)ud; /* to avoid warnings */
305
+ luaL_checkstack(L, 2, "too many nested functions");
306
+ lua_pushvalue(L, 1); /* get function */
307
+ lua_call(L, 0, 1); /* call it */
308
+ if (lua_isnil(L, -1)) {
309
+ *size = 0;
310
+ return NULL;
311
+ }
312
+ else if (lua_isstring(L, -1)) {
313
+ lua_replace(L, 3); /* save string in a reserved stack slot */
314
+ return lua_tolstring(L, 3, size);
315
+ }
316
+ else luaL_error(L, "reader function must return a string");
317
+ return NULL; /* to avoid warnings */
318
+ }
319
+
320
+
321
+ static int luaB_load (lua_State *L) {
322
+ int status;
323
+ const char *cname = luaL_optstring(L, 2, "=(load)");
324
+ luaL_checktype(L, 1, LUA_TFUNCTION);
325
+ lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
326
+ status = lua_load(L, generic_reader, NULL, cname);
327
+ return load_aux(L, status);
328
+ }
329
+
330
+
331
+ static int luaB_dofile (lua_State *L) {
332
+ const char *fname = luaL_optstring(L, 1, NULL);
333
+ int n = lua_gettop(L);
334
+ if (luaL_loadfile(L, fname) != 0) lua_error(L);
335
+ lua_call(L, 0, LUA_MULTRET);
336
+ return lua_gettop(L) - n;
337
+ }
338
+
339
+
340
+ static int luaB_assert (lua_State *L) {
341
+ luaL_checkany(L, 1);
342
+ if (!lua_toboolean(L, 1))
343
+ return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
344
+ return lua_gettop(L);
345
+ }
346
+
347
+
348
+ static int luaB_unpack (lua_State *L) {
349
+ int i, e, n;
350
+ luaL_checktype(L, 1, LUA_TTABLE);
351
+ i = luaL_optint(L, 2, 1);
352
+ e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
353
+ if (i > e) return 0; /* empty range */
354
+ n = e - i + 1; /* number of elements */
355
+ if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
356
+ return luaL_error(L, "too many results to unpack");
357
+ lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
358
+ while (i++ < e) /* push arg[i + 1...e] */
359
+ lua_rawgeti(L, 1, i);
360
+ return n;
361
+ }
362
+
363
+
364
+ static int luaB_select (lua_State *L) {
365
+ int n = lua_gettop(L);
366
+ if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
367
+ lua_pushinteger(L, n-1);
368
+ return 1;
369
+ }
370
+ else {
371
+ int i = luaL_checkint(L, 1);
372
+ if (i < 0) i = n + i;
373
+ else if (i > n) i = n;
374
+ luaL_argcheck(L, 1 <= i, 1, "index out of range");
375
+ return n - i;
376
+ }
377
+ }
378
+
379
+
380
+ static int luaB_pcall (lua_State *L) {
381
+ int status;
382
+ luaL_checkany(L, 1);
383
+ status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
384
+ lua_pushboolean(L, (status == 0));
385
+ lua_insert(L, 1);
386
+ return lua_gettop(L); /* return status + all results */
387
+ }
388
+
389
+
390
+ static int luaB_xpcall (lua_State *L) {
391
+ int status;
392
+ luaL_checkany(L, 2);
393
+ lua_settop(L, 2);
394
+ lua_insert(L, 1); /* put error function under function to be called */
395
+ status = lua_pcall(L, 0, LUA_MULTRET, 1);
396
+ lua_pushboolean(L, (status == 0));
397
+ lua_replace(L, 1);
398
+ return lua_gettop(L); /* return status + all results */
399
+ }
400
+
401
+
402
+ static int luaB_tostring (lua_State *L) {
403
+ luaL_checkany(L, 1);
404
+ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
405
+ return 1; /* use its value */
406
+ switch (lua_type(L, 1)) {
407
+ case LUA_TNUMBER:
408
+ lua_pushstring(L, lua_tostring(L, 1));
409
+ break;
410
+ case LUA_TSTRING:
411
+ lua_pushvalue(L, 1);
412
+ break;
413
+ case LUA_TBOOLEAN:
414
+ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
415
+ break;
416
+ case LUA_TNIL:
417
+ lua_pushliteral(L, "nil");
418
+ break;
419
+ default:
420
+ lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
421
+ break;
422
+ }
423
+ return 1;
424
+ }
425
+
426
+
427
+ static int luaB_newproxy (lua_State *L) {
428
+ lua_settop(L, 1);
429
+ lua_newuserdata(L, 0); /* create proxy */
430
+ if (lua_toboolean(L, 1) == 0)
431
+ return 1; /* no metatable */
432
+ else if (lua_isboolean(L, 1)) {
433
+ lua_newtable(L); /* create a new metatable `m' ... */
434
+ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
435
+ lua_pushboolean(L, 1);
436
+ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
437
+ }
438
+ else {
439
+ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
440
+ if (lua_getmetatable(L, 1)) {
441
+ lua_rawget(L, lua_upvalueindex(1));
442
+ validproxy = lua_toboolean(L, -1);
443
+ lua_pop(L, 1); /* remove value */
444
+ }
445
+ luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
446
+ lua_getmetatable(L, 1); /* metatable is valid; get it */
447
+ }
448
+ lua_setmetatable(L, 2);
449
+ return 1;
450
+ }
451
+
452
+
453
+ static const luaL_Reg base_funcs[] = {
454
+ {"assert", luaB_assert},
455
+ {"collectgarbage", luaB_collectgarbage},
456
+ {"dofile", luaB_dofile},
457
+ {"error", luaB_error},
458
+ {"gcinfo", luaB_gcinfo},
459
+ {"getfenv", luaB_getfenv},
460
+ {"getmetatable", luaB_getmetatable},
461
+ {"loadfile", luaB_loadfile},
462
+ {"load", luaB_load},
463
+ {"loadstring", luaB_loadstring},
464
+ {"next", luaB_next},
465
+ {"pcall", luaB_pcall},
466
+ {"print", luaB_print},
467
+ {"rawequal", luaB_rawequal},
468
+ {"rawget", luaB_rawget},
469
+ {"rawset", luaB_rawset},
470
+ {"select", luaB_select},
471
+ {"setfenv", luaB_setfenv},
472
+ {"setmetatable", luaB_setmetatable},
473
+ {"tonumber", luaB_tonumber},
474
+ {"tostring", luaB_tostring},
475
+ {"type", luaB_type},
476
+ {"unpack", luaB_unpack},
477
+ {"xpcall", luaB_xpcall},
478
+ {NULL, NULL}
479
+ };
480
+
481
+
482
+ /*
483
+ ** {======================================================
484
+ ** Coroutine library
485
+ ** =======================================================
486
+ */
487
+
488
+ #define CO_RUN 0 /* running */
489
+ #define CO_SUS 1 /* suspended */
490
+ #define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
491
+ #define CO_DEAD 3
492
+
493
+ static const char *const statnames[] =
494
+ {"running", "suspended", "normal", "dead"};
495
+
496
+ static int costatus (lua_State *L, lua_State *co) {
497
+ if (L == co) return CO_RUN;
498
+ switch (lua_status(co)) {
499
+ case LUA_YIELD:
500
+ return CO_SUS;
501
+ case 0: {
502
+ lua_Debug ar;
503
+ if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
504
+ return CO_NOR; /* it is running */
505
+ else if (lua_gettop(co) == 0)
506
+ return CO_DEAD;
507
+ else
508
+ return CO_SUS; /* initial state */
509
+ }
510
+ default: /* some error occured */
511
+ return CO_DEAD;
512
+ }
513
+ }
514
+
515
+
516
+ static int luaB_costatus (lua_State *L) {
517
+ lua_State *co = lua_tothread(L, 1);
518
+ luaL_argcheck(L, co, 1, "coroutine expected");
519
+ lua_pushstring(L, statnames[costatus(L, co)]);
520
+ return 1;
521
+ }
522
+
523
+
524
+ static int auxresume (lua_State *L, lua_State *co, int narg) {
525
+ int status = costatus(L, co);
526
+ if (!lua_checkstack(co, narg))
527
+ luaL_error(L, "too many arguments to resume");
528
+ if (status != CO_SUS) {
529
+ lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
530
+ return -1; /* error flag */
531
+ }
532
+ lua_xmove(L, co, narg);
533
+ lua_setlevel(L, co);
534
+ status = lua_resume(co, narg);
535
+ if (status == 0 || status == LUA_YIELD) {
536
+ int nres = lua_gettop(co);
537
+ if (!lua_checkstack(L, nres + 1))
538
+ luaL_error(L, "too many results to resume");
539
+ lua_xmove(co, L, nres); /* move yielded values */
540
+ return nres;
541
+ }
542
+ else {
543
+ lua_xmove(co, L, 1); /* move error message */
544
+ return -1; /* error flag */
545
+ }
546
+ }
547
+
548
+
549
+ static int luaB_coresume (lua_State *L) {
550
+ lua_State *co = lua_tothread(L, 1);
551
+ int r;
552
+ luaL_argcheck(L, co, 1, "coroutine expected");
553
+ r = auxresume(L, co, lua_gettop(L) - 1);
554
+ if (r < 0) {
555
+ lua_pushboolean(L, 0);
556
+ lua_insert(L, -2);
557
+ return 2; /* return false + error message */
558
+ }
559
+ else {
560
+ lua_pushboolean(L, 1);
561
+ lua_insert(L, -(r + 1));
562
+ return r + 1; /* return true + `resume' returns */
563
+ }
564
+ }
565
+
566
+
567
+ static int luaB_auxwrap (lua_State *L) {
568
+ lua_State *co = lua_tothread(L, lua_upvalueindex(1));
569
+ int r = auxresume(L, co, lua_gettop(L));
570
+ if (r < 0) {
571
+ if (lua_isstring(L, -1)) { /* error object is a string? */
572
+ luaL_where(L, 1); /* add extra info */
573
+ lua_insert(L, -2);
574
+ lua_concat(L, 2);
575
+ }
576
+ lua_error(L); /* propagate error */
577
+ }
578
+ return r;
579
+ }
580
+
581
+
582
+ static int luaB_cocreate (lua_State *L) {
583
+ lua_State *NL = lua_newthread(L);
584
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
585
+ "Lua function expected");
586
+ lua_pushvalue(L, 1); /* move function to top */
587
+ lua_xmove(L, NL, 1); /* move function from L to NL */
588
+ return 1;
589
+ }
590
+
591
+
592
+ static int luaB_cowrap (lua_State *L) {
593
+ luaB_cocreate(L);
594
+ lua_pushcclosure(L, luaB_auxwrap, 1);
595
+ return 1;
596
+ }
597
+
598
+
599
+ static int luaB_yield (lua_State *L) {
600
+ return lua_yield(L, lua_gettop(L));
601
+ }
602
+
603
+
604
+ static int luaB_corunning (lua_State *L) {
605
+ if (lua_pushthread(L))
606
+ lua_pushnil(L); /* main thread is not a coroutine */
607
+ return 1;
608
+ }
609
+
610
+
611
+ static const luaL_Reg co_funcs[] = {
612
+ {"create", luaB_cocreate},
613
+ {"resume", luaB_coresume},
614
+ {"running", luaB_corunning},
615
+ {"status", luaB_costatus},
616
+ {"wrap", luaB_cowrap},
617
+ {"yield", luaB_yield},
618
+ {NULL, NULL}
619
+ };
620
+
621
+ /* }====================================================== */
622
+
623
+
624
+ static void auxopen (lua_State *L, const char *name,
625
+ lua_CFunction f, lua_CFunction u) {
626
+ lua_pushcfunction(L, u);
627
+ lua_pushcclosure(L, f, 1);
628
+ lua_setfield(L, -2, name);
629
+ }
630
+
631
+
632
+ static void base_open (lua_State *L) {
633
+ /* set global _G */
634
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
635
+ lua_setglobal(L, "_G");
636
+ /* open lib into global table */
637
+ luaL_register(L, "_G", base_funcs);
638
+ lua_pushliteral(L, LUA_VERSION);
639
+ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
640
+ /* `ipairs' and `pairs' need auxiliary functions as upvalues */
641
+ auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
642
+ auxopen(L, "pairs", luaB_pairs, luaB_next);
643
+ /* `newproxy' needs a weaktable as upvalue */
644
+ lua_createtable(L, 0, 1); /* new table `w' */
645
+ lua_pushvalue(L, -1); /* `w' will be its own metatable */
646
+ lua_setmetatable(L, -2);
647
+ lua_pushliteral(L, "kv");
648
+ lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
649
+ lua_pushcclosure(L, luaB_newproxy, 1);
650
+ lua_setglobal(L, "newproxy"); /* set global `newproxy' */
651
+ }
652
+
653
+
654
+ LUALIB_API int luaopen_base (lua_State *L) {
655
+ base_open(L);
656
+ luaL_register(L, LUA_COLIBNAME, co_funcs);
657
+ return 2;
658
+ }
659
+