immunio 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+