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,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
+