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,77 @@
1
+ /*
2
+ ** $Id: lptree.h,v 1.2 2013/03/24 13:51:12 roberto Exp $
3
+ */
4
+
5
+ #if !defined(lptree_h)
6
+ #define lptree_h
7
+
8
+
9
+ #include "lptypes.h"
10
+
11
+
12
+ /*
13
+ ** types of trees
14
+ */
15
+ typedef enum TTag {
16
+ TChar = 0, TSet, TAny, /* standard PEG elements */
17
+ TTrue, TFalse,
18
+ TRep,
19
+ TSeq, TChoice,
20
+ TNot, TAnd,
21
+ TCall,
22
+ TOpenCall,
23
+ TRule, /* sib1 is rule's pattern, sib2 is 'next' rule */
24
+ TGrammar, /* sib1 is initial (and first) rule */
25
+ TBehind, /* match behind */
26
+ TCapture, /* regular capture */
27
+ TRunTime /* run-time capture */
28
+ } TTag;
29
+
30
+ /* number of siblings for each tree */
31
+ extern const byte numsiblings[];
32
+
33
+
34
+ /*
35
+ ** Tree trees
36
+ ** The first sibling of a tree (if there is one) is immediately after
37
+ ** the tree. A reference to a second sibling (ps) is its position
38
+ ** relative to the position of the tree itself. A key in ktable
39
+ ** uses the (unique) address of the original tree that created that
40
+ ** entry. NULL means no data.
41
+ */
42
+ typedef struct TTree {
43
+ byte tag;
44
+ byte cap; /* kind of capture (if it is a capture) */
45
+ unsigned short key; /* key in ktable for Lua data (0 if no key) */
46
+ union {
47
+ int ps; /* occasional second sibling */
48
+ int n; /* occasional counter */
49
+ } u;
50
+ } TTree;
51
+
52
+
53
+ /*
54
+ ** A complete pattern has its tree plus, if already compiled,
55
+ ** its corresponding code
56
+ */
57
+ typedef struct Pattern {
58
+ union LpegInstruction *code;
59
+ int codesize;
60
+ TTree tree[1];
61
+ } Pattern;
62
+
63
+
64
+ /* number of siblings for each tree */
65
+ extern const byte numsiblings[];
66
+
67
+ /* access to siblings */
68
+ #define sib1(t) ((t) + 1)
69
+ #define sib2(t) ((t) + (t)->u.ps)
70
+
71
+
72
+
73
+
74
+
75
+
76
+ #endif
77
+
@@ -0,0 +1,149 @@
1
+ /*
2
+ ** $Id: lptypes.h,v 1.10 2014/12/12 17:11:35 roberto Exp $
3
+ ** LPeg - PEG pattern matching for Lua
4
+ ** Copyright 2007-2014, Lua.org & PUC-Rio (see 'lpeg.html' for license)
5
+ ** written by Roberto Ierusalimschy
6
+ */
7
+
8
+ #if !defined(lptypes_h)
9
+ #define lptypes_h
10
+
11
+
12
+ #if !defined(LPEG_DEBUG)
13
+ #define NDEBUG
14
+ #endif
15
+
16
+ #include <assert.h>
17
+ #include <limits.h>
18
+
19
+ #include "../lua/lua.h"
20
+
21
+
22
+ #define VERSION "0.12.1"
23
+
24
+
25
+ #define PATTERN_T "lpeg-pattern"
26
+ #define MAXSTACKIDX "lpeg-maxstack"
27
+
28
+
29
+ /*
30
+ ** compatibility with Lua 5.2
31
+ */
32
+ #if (LUA_VERSION_NUM >= 502)
33
+
34
+ #undef lua_equal
35
+ #define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
36
+
37
+ #undef lua_getfenv
38
+ #define lua_getfenv lua_getuservalue
39
+ #undef lua_setfenv
40
+ #define lua_setfenv lua_setuservalue
41
+
42
+ #undef lua_objlen
43
+ #define lua_objlen lua_rawlen
44
+
45
+ #undef luaL_register
46
+ #define luaL_register(L,n,f) \
47
+ { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); }
48
+
49
+ #endif
50
+
51
+
52
+ /* default maximum size for call/backtrack stack */
53
+ #if !defined(MAXBACK)
54
+ #define MAXBACK 100
55
+ #endif
56
+
57
+
58
+ /* maximum number of rules in a grammar */
59
+ #if !defined(MAXRULES)
60
+ #define MAXRULES 1000
61
+ #endif
62
+
63
+
64
+
65
+ /* initial size for capture's list */
66
+ #define INITCAPSIZE 32
67
+
68
+
69
+ /* index, on Lua stack, for subject */
70
+ #define SUBJIDX 2
71
+
72
+ /* number of fixed arguments to 'match' (before capture arguments) */
73
+ #define FIXEDARGS 3
74
+
75
+ /* index, on Lua stack, for capture list */
76
+ #define caplistidx(ptop) ((ptop) + 2)
77
+
78
+ /* index, on Lua stack, for pattern's ktable */
79
+ #define ktableidx(ptop) ((ptop) + 3)
80
+
81
+ /* index, on Lua stack, for backtracking stack */
82
+ #define stackidx(ptop) ((ptop) + 4)
83
+
84
+
85
+
86
+ typedef unsigned char byte;
87
+
88
+
89
+ #define BITSPERCHAR 8
90
+
91
+ #define CHARSETSIZE ((UCHAR_MAX/BITSPERCHAR) + 1)
92
+
93
+
94
+
95
+ typedef struct Charset {
96
+ byte cs[CHARSETSIZE];
97
+ } Charset;
98
+
99
+
100
+
101
+ #define loopset(v,b) { int v; for (v = 0; v < CHARSETSIZE; v++) {b;} }
102
+
103
+ /* access to charset */
104
+ #define treebuffer(t) ((byte *)((t) + 1))
105
+
106
+ /* number of slots needed for 'n' bytes */
107
+ #define bytes2slots(n) (((n) - 1) / sizeof(TTree) + 1)
108
+
109
+ /* set 'b' bit in charset 'cs' */
110
+ #define setchar(cs,b) ((cs)[(b) >> 3] |= (1 << ((b) & 7)))
111
+
112
+
113
+ /*
114
+ ** in capture LpegInstructions, 'kind' of capture and its offset are
115
+ ** packed in field 'aux', 4 bits for each
116
+ */
117
+ #define getkind(op) ((op)->i.aux & 0xF)
118
+ #define getoff(op) (((op)->i.aux >> 4) & 0xF)
119
+ #define joinkindoff(k,o) ((k) | ((o) << 4))
120
+
121
+ #define MAXOFF 0xF
122
+ #define MAXAUX 0xFF
123
+
124
+
125
+ /* maximum number of bytes to look behind */
126
+ #define MAXBEHIND MAXAUX
127
+
128
+
129
+ /* maximum size (in elements) for a pattern */
130
+ #define MAXPATTSIZE (SHRT_MAX - 10)
131
+
132
+
133
+ /* size (in elements) for an LpegInstruction plus extra l bytes */
134
+ #define instsize(l) (((l) + sizeof(LpegInstruction) - 1)/sizeof(LpegInstruction) + 1)
135
+
136
+
137
+ /* size (in elements) for a ISet LpegInstruction */
138
+ #define CHARSETINSTSIZE instsize(CHARSETSIZE)
139
+
140
+ /* size (in elements) for a IFunc LpegInstruction */
141
+ #define funcinstsize(p) ((p)->i.aux + 2)
142
+
143
+
144
+
145
+ #define testchar(st,c) (((int)(st)[((c) >> 3)] & (1 << ((c) & 7))))
146
+
147
+
148
+ #endif
149
+
@@ -0,0 +1,355 @@
1
+ /*
2
+ ** $Id: lpvm.c,v 1.5 2013/04/12 16:29:49 roberto Exp $
3
+ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
4
+ */
5
+
6
+ #include <limits.h>
7
+ #include <string.h>
8
+
9
+
10
+ #include "../lua/lua.h"
11
+ #include "../lua/lauxlib.h"
12
+
13
+ #include "lpcap.h"
14
+ #include "lptypes.h"
15
+ #include "lpvm.h"
16
+ #include "lpprint.h"
17
+
18
+
19
+ /* initial size for call/backtrack stack */
20
+ #if !defined(INITBACK)
21
+ #define INITBACK 100
22
+ #endif
23
+
24
+
25
+ #define getoffset(p) (((p) + 1)->offset)
26
+
27
+ static const LpegInstruction giveup = {{IGiveup, 0, 0}};
28
+
29
+
30
+ /*
31
+ ** {======================================================
32
+ ** Virtual Machine
33
+ ** =======================================================
34
+ */
35
+
36
+
37
+ typedef struct Stack {
38
+ const char *s; /* saved position (or NULL for calls) */
39
+ const LpegInstruction *p; /* next LpegInstruction */
40
+ int caplevel;
41
+ } Stack;
42
+
43
+
44
+ #define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop)))
45
+
46
+
47
+ /*
48
+ ** Double the size of the array of captures
49
+ */
50
+ static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) {
51
+ Capture *newc;
52
+ if (captop >= INT_MAX/((int)sizeof(Capture) * 2))
53
+ luaL_error(L, "too many captures");
54
+ newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture));
55
+ memcpy(newc, cap, captop * sizeof(Capture));
56
+ lua_replace(L, caplistidx(ptop));
57
+ return newc;
58
+ }
59
+
60
+
61
+ /*
62
+ ** Double the size of the stack
63
+ */
64
+ static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) {
65
+ Stack *stack = getstackbase(L, ptop);
66
+ Stack *newstack;
67
+ int n = *stacklimit - stack; /* current stack size */
68
+ int max, newn;
69
+ lua_getfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX);
70
+ max = lua_tointeger(L, -1); /* maximum allowed size */
71
+ lua_pop(L, 1);
72
+ if (n >= max) /* already at maximum size? */
73
+ luaL_error(L, "too many pending calls/choices");
74
+ newn = 2 * n; /* new size */
75
+ if (newn > max) newn = max;
76
+ newstack = (Stack *)lua_newuserdata(L, newn * sizeof(Stack));
77
+ memcpy(newstack, stack, n * sizeof(Stack));
78
+ lua_replace(L, stackidx(ptop));
79
+ *stacklimit = newstack + newn;
80
+ return newstack + n; /* return next position */
81
+ }
82
+
83
+
84
+ /*
85
+ ** Interpret the result of a dynamic capture: false -> fail;
86
+ ** true -> keep current position; number -> next position.
87
+ ** Return new subject position. 'fr' is stack index where
88
+ ** is the result; 'curr' is current subject position; 'limit'
89
+ ** is subject's size.
90
+ */
91
+ static int resdyncaptures (lua_State *L, int fr, int curr, int limit) {
92
+ lua_Integer res;
93
+ if (!lua_toboolean(L, fr)) { /* false value? */
94
+ lua_settop(L, fr - 1); /* remove results */
95
+ return -1; /* and fail */
96
+ }
97
+ else if (lua_isboolean(L, fr)) /* true? */
98
+ res = curr; /* keep current position */
99
+ else {
100
+ res = lua_tointeger(L, fr) - 1; /* new position */
101
+ if (res < curr || res > limit)
102
+ luaL_error(L, "invalid position returned by match-time capture");
103
+ }
104
+ lua_remove(L, fr); /* remove first result (offset) */
105
+ return res;
106
+ }
107
+
108
+
109
+ /*
110
+ ** Add capture values returned by a dynamic capture to the capture list
111
+ ** 'base', nested inside a group capture. 'fd' indexes the first capture
112
+ ** value, 'n' is the number of values (at least 1).
113
+ */
114
+ static void adddyncaptures (const char *s, Capture *base, int n, int fd) {
115
+ int i;
116
+ /* Cgroup capture is already there */
117
+ assert(base[0].kind == Cgroup && base[0].siz == 0);
118
+ base[0].idx = 0; /* make it an anonymous group */
119
+ for (i = 1; i <= n; i++) { /* add runtime captures */
120
+ base[i].kind = Cruntime;
121
+ base[i].siz = 1; /* mark it as closed */
122
+ base[i].idx = fd + i - 1; /* stack index of capture value */
123
+ base[i].s = s;
124
+ }
125
+ base[i].kind = Cclose; /* close group */
126
+ base[i].siz = 1;
127
+ base[i].s = s;
128
+ }
129
+
130
+
131
+ /*
132
+ ** Remove dynamic captures from the Lua stack (called in case of failure)
133
+ */
134
+ static int removedyncap (lua_State *L, Capture *capture,
135
+ int level, int last) {
136
+ int id = finddyncap(capture + level, capture + last); /* index of 1st cap. */
137
+ int top = lua_gettop(L);
138
+ if (id == 0) return 0; /* no dynamic captures? */
139
+ lua_settop(L, id - 1); /* remove captures */
140
+ return top - id + 1; /* number of values removed */
141
+ }
142
+
143
+
144
+ /*
145
+ ** Opcode interpreter
146
+ */
147
+ const char *lpeg_match (lua_State *L, const char *o, const char *s, const char *e,
148
+ LpegInstruction *op, Capture *capture, int ptop) {
149
+ Stack stackbase[INITBACK];
150
+ Stack *stacklimit = stackbase + INITBACK;
151
+ Stack *stack = stackbase; /* point to first empty slot in stack */
152
+ int capsize = INITCAPSIZE;
153
+ int captop = 0; /* point to first empty slot in captures */
154
+ int ndyncap = 0; /* number of dynamic captures (in Lua stack) */
155
+ const LpegInstruction *p = op; /* current LpegInstruction */
156
+ stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++;
157
+ lua_pushlightuserdata(L, stackbase);
158
+ for (;;) {
159
+ #if defined(DEBUG)
160
+ printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
161
+ s, stack - getstackbase(L, ptop), ndyncap, captop);
162
+ printinst(op, p);
163
+ printcaplist(capture, capture + captop);
164
+ #endif
165
+ assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
166
+ switch ((Opcode)p->i.code) {
167
+ case IEnd: {
168
+ assert(stack == getstackbase(L, ptop) + 1);
169
+ capture[captop].kind = Cclose;
170
+ capture[captop].s = NULL;
171
+ return s;
172
+ }
173
+ case IGiveup: {
174
+ assert(stack == getstackbase(L, ptop));
175
+ return NULL;
176
+ }
177
+ case IRet: {
178
+ assert(stack > getstackbase(L, ptop) && (stack - 1)->s == NULL);
179
+ p = (--stack)->p;
180
+ continue;
181
+ }
182
+ case IAny: {
183
+ if (s < e) { p++; s++; }
184
+ else goto fail;
185
+ continue;
186
+ }
187
+ case ITestAny: {
188
+ if (s < e) p += 2;
189
+ else p += getoffset(p);
190
+ continue;
191
+ }
192
+ case IChar: {
193
+ if ((byte)*s == p->i.aux && s < e) { p++; s++; }
194
+ else goto fail;
195
+ continue;
196
+ }
197
+ case ITestChar: {
198
+ if ((byte)*s == p->i.aux && s < e) p += 2;
199
+ else p += getoffset(p);
200
+ continue;
201
+ }
202
+ case ISet: {
203
+ int c = (byte)*s;
204
+ if (testchar((p+1)->buff, c) && s < e)
205
+ { p += CHARSETINSTSIZE; s++; }
206
+ else goto fail;
207
+ continue;
208
+ }
209
+ case ITestSet: {
210
+ int c = (byte)*s;
211
+ if (testchar((p + 2)->buff, c) && s < e)
212
+ p += 1 + CHARSETINSTSIZE;
213
+ else p += getoffset(p);
214
+ continue;
215
+ }
216
+ case IBehind: {
217
+ int n = p->i.aux;
218
+ if (n > s - o) goto fail;
219
+ s -= n; p++;
220
+ continue;
221
+ }
222
+ case ISpan: {
223
+ for (; s < e; s++) {
224
+ int c = (byte)*s;
225
+ if (!testchar((p+1)->buff, c)) break;
226
+ }
227
+ p += CHARSETINSTSIZE;
228
+ continue;
229
+ }
230
+ case IJmp: {
231
+ p += getoffset(p);
232
+ continue;
233
+ }
234
+ case IChoice: {
235
+ if (stack == stacklimit)
236
+ stack = doublestack(L, &stacklimit, ptop);
237
+ stack->p = p + getoffset(p);
238
+ stack->s = s;
239
+ stack->caplevel = captop;
240
+ stack++;
241
+ p += 2;
242
+ continue;
243
+ }
244
+ case ICall: {
245
+ if (stack == stacklimit)
246
+ stack = doublestack(L, &stacklimit, ptop);
247
+ stack->s = NULL;
248
+ stack->p = p + 2; /* save return address */
249
+ stack++;
250
+ p += getoffset(p);
251
+ continue;
252
+ }
253
+ case ICommit: {
254
+ assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
255
+ stack--;
256
+ p += getoffset(p);
257
+ continue;
258
+ }
259
+ case IPartialCommit: {
260
+ assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
261
+ (stack - 1)->s = s;
262
+ (stack - 1)->caplevel = captop;
263
+ p += getoffset(p);
264
+ continue;
265
+ }
266
+ case IBackCommit: {
267
+ assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL);
268
+ s = (--stack)->s;
269
+ captop = stack->caplevel;
270
+ p += getoffset(p);
271
+ continue;
272
+ }
273
+ case IFailTwice:
274
+ assert(stack > getstackbase(L, ptop));
275
+ stack--;
276
+ /* go through */
277
+ case IFail:
278
+ fail: { /* pattern failed: try to backtrack */
279
+ do { /* remove pending calls */
280
+ assert(stack > getstackbase(L, ptop));
281
+ s = (--stack)->s;
282
+ } while (s == NULL);
283
+ if (ndyncap > 0) /* is there matchtime captures? */
284
+ ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
285
+ captop = stack->caplevel;
286
+ p = stack->p;
287
+ continue;
288
+ }
289
+ case ICloseRunTime: {
290
+ CapState cs;
291
+ int rem, res, n;
292
+ int fr = lua_gettop(L) + 1; /* stack index of first result */
293
+ cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop;
294
+ n = runtimecap(&cs, capture + captop, s, &rem); /* call function */
295
+ captop -= n; /* remove nested captures */
296
+ fr -= rem; /* 'rem' items were popped from Lua stack */
297
+ res = resdyncaptures(L, fr, s - o, e - o); /* get result */
298
+ if (res == -1) /* fail? */
299
+ goto fail;
300
+ s = o + res; /* else update current position */
301
+ n = lua_gettop(L) - fr + 1; /* number of new captures */
302
+ ndyncap += n - rem; /* update number of dynamic captures */
303
+ if (n > 0) { /* any new capture? */
304
+ if ((captop += n + 2) >= capsize) {
305
+ capture = doublecap(L, capture, captop, ptop);
306
+ capsize = 2 * captop;
307
+ }
308
+ /* add new captures to 'capture' list */
309
+ adddyncaptures(s, capture + captop - n - 2, n, fr);
310
+ }
311
+ p++;
312
+ continue;
313
+ }
314
+ case ICloseCapture: {
315
+ const char *s1 = s;
316
+ assert(captop > 0);
317
+ /* if possible, turn capture into a full capture */
318
+ if (capture[captop - 1].siz == 0 &&
319
+ s1 - capture[captop - 1].s < UCHAR_MAX) {
320
+ capture[captop - 1].siz = s1 - capture[captop - 1].s + 1;
321
+ p++;
322
+ continue;
323
+ }
324
+ else {
325
+ capture[captop].siz = 1; /* mark entry as closed */
326
+ capture[captop].s = s;
327
+ goto pushcapture;
328
+ }
329
+ }
330
+ case IOpenCapture:
331
+ capture[captop].siz = 0; /* mark entry as open */
332
+ capture[captop].s = s;
333
+ goto pushcapture;
334
+ case IFullCapture:
335
+ capture[captop].siz = getoff(p) + 1; /* save capture size */
336
+ capture[captop].s = s - getoff(p);
337
+ /* goto pushcapture; */
338
+ pushcapture: {
339
+ capture[captop].idx = p->i.key;
340
+ capture[captop].kind = getkind(p);
341
+ if (++captop >= capsize) {
342
+ capture = doublecap(L, capture, captop, ptop);
343
+ capsize = 2 * captop;
344
+ }
345
+ p++;
346
+ continue;
347
+ }
348
+ default: assert(0); return NULL;
349
+ }
350
+ }
351
+ }
352
+
353
+ /* }====================================================== */
354
+
355
+