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.
- checksums.yaml +7 -0
- data/LICENSE +234 -0
- data/README.md +147 -0
- data/bin/immunio +5 -0
- data/lib/immunio.rb +29 -0
- data/lib/immunio/agent.rb +260 -0
- data/lib/immunio/authentication.rb +96 -0
- data/lib/immunio/blocked_app.rb +38 -0
- data/lib/immunio/channel.rb +432 -0
- data/lib/immunio/cli.rb +39 -0
- data/lib/immunio/context.rb +114 -0
- data/lib/immunio/errors.rb +43 -0
- data/lib/immunio/immunio_ca.crt +45 -0
- data/lib/immunio/logger.rb +87 -0
- data/lib/immunio/plugins/action_dispatch.rb +45 -0
- data/lib/immunio/plugins/action_view.rb +431 -0
- data/lib/immunio/plugins/active_record.rb +707 -0
- data/lib/immunio/plugins/active_record_relation.rb +370 -0
- data/lib/immunio/plugins/authlogic.rb +80 -0
- data/lib/immunio/plugins/csrf.rb +24 -0
- data/lib/immunio/plugins/devise.rb +40 -0
- data/lib/immunio/plugins/environment_reporter.rb +69 -0
- data/lib/immunio/plugins/eval.rb +51 -0
- data/lib/immunio/plugins/exception_handler.rb +55 -0
- data/lib/immunio/plugins/gems_tracker.rb +5 -0
- data/lib/immunio/plugins/haml.rb +36 -0
- data/lib/immunio/plugins/http_finisher.rb +50 -0
- data/lib/immunio/plugins/http_tracker.rb +203 -0
- data/lib/immunio/plugins/io.rb +96 -0
- data/lib/immunio/plugins/redirect.rb +42 -0
- data/lib/immunio/plugins/warden.rb +66 -0
- data/lib/immunio/processor.rb +234 -0
- data/lib/immunio/rails.rb +26 -0
- data/lib/immunio/request.rb +139 -0
- data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
- data/lib/immunio/rufus_lua_ext/state.rb +157 -0
- data/lib/immunio/rufus_lua_ext/table.rb +137 -0
- data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
- data/lib/immunio/version.rb +5 -0
- data/lib/immunio/vm.rb +291 -0
- data/lua-hooks/ext/all.c +78 -0
- data/lua-hooks/ext/bitop/README +22 -0
- data/lua-hooks/ext/bitop/bit.c +189 -0
- data/lua-hooks/ext/extconf.rb +38 -0
- data/lua-hooks/ext/libinjection/COPYING +37 -0
- data/lua-hooks/ext/libinjection/libinjection.h +65 -0
- data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
- data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
- data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
- data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
- data/lua-hooks/ext/libinjection/lualib.c +109 -0
- data/lua-hooks/ext/lpeg/HISTORY +90 -0
- data/lua-hooks/ext/lpeg/lpcap.c +537 -0
- data/lua-hooks/ext/lpeg/lpcap.h +43 -0
- data/lua-hooks/ext/lpeg/lpcode.c +986 -0
- data/lua-hooks/ext/lpeg/lpcode.h +34 -0
- data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
- data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
- data/lua-hooks/ext/lpeg/lpprint.c +244 -0
- data/lua-hooks/ext/lpeg/lpprint.h +35 -0
- data/lua-hooks/ext/lpeg/lptree.c +1238 -0
- data/lua-hooks/ext/lpeg/lptree.h +77 -0
- data/lua-hooks/ext/lpeg/lptypes.h +149 -0
- data/lua-hooks/ext/lpeg/lpvm.c +355 -0
- data/lua-hooks/ext/lpeg/lpvm.h +58 -0
- data/lua-hooks/ext/lpeg/makefile +55 -0
- data/lua-hooks/ext/lpeg/re.html +498 -0
- data/lua-hooks/ext/lpeg/test.lua +1409 -0
- data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
- data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
- data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
- data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
- data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
- data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
- data/lua-hooks/ext/lua-snapshot/README.md +18 -0
- data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
- data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
- data/lua-hooks/ext/lua/COPYRIGHT +34 -0
- data/lua-hooks/ext/lua/lapi.c +1087 -0
- data/lua-hooks/ext/lua/lapi.h +16 -0
- data/lua-hooks/ext/lua/lauxlib.c +652 -0
- data/lua-hooks/ext/lua/lauxlib.h +174 -0
- data/lua-hooks/ext/lua/lbaselib.c +659 -0
- data/lua-hooks/ext/lua/lcode.c +831 -0
- data/lua-hooks/ext/lua/lcode.h +76 -0
- data/lua-hooks/ext/lua/ldblib.c +398 -0
- data/lua-hooks/ext/lua/ldebug.c +638 -0
- data/lua-hooks/ext/lua/ldebug.h +33 -0
- data/lua-hooks/ext/lua/ldo.c +519 -0
- data/lua-hooks/ext/lua/ldo.h +57 -0
- data/lua-hooks/ext/lua/ldump.c +164 -0
- data/lua-hooks/ext/lua/lfunc.c +174 -0
- data/lua-hooks/ext/lua/lfunc.h +34 -0
- data/lua-hooks/ext/lua/lgc.c +710 -0
- data/lua-hooks/ext/lua/lgc.h +110 -0
- data/lua-hooks/ext/lua/linit.c +38 -0
- data/lua-hooks/ext/lua/liolib.c +556 -0
- data/lua-hooks/ext/lua/llex.c +463 -0
- data/lua-hooks/ext/lua/llex.h +81 -0
- data/lua-hooks/ext/lua/llimits.h +128 -0
- data/lua-hooks/ext/lua/lmathlib.c +263 -0
- data/lua-hooks/ext/lua/lmem.c +86 -0
- data/lua-hooks/ext/lua/lmem.h +49 -0
- data/lua-hooks/ext/lua/loadlib.c +705 -0
- data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
- data/lua-hooks/ext/lua/lobject.c +214 -0
- data/lua-hooks/ext/lua/lobject.h +381 -0
- data/lua-hooks/ext/lua/lopcodes.c +102 -0
- data/lua-hooks/ext/lua/lopcodes.h +268 -0
- data/lua-hooks/ext/lua/loslib.c +243 -0
- data/lua-hooks/ext/lua/lparser.c +1339 -0
- data/lua-hooks/ext/lua/lparser.h +82 -0
- data/lua-hooks/ext/lua/lstate.c +214 -0
- data/lua-hooks/ext/lua/lstate.h +169 -0
- data/lua-hooks/ext/lua/lstring.c +111 -0
- data/lua-hooks/ext/lua/lstring.h +31 -0
- data/lua-hooks/ext/lua/lstrlib.c +871 -0
- data/lua-hooks/ext/lua/ltable.c +588 -0
- data/lua-hooks/ext/lua/ltable.h +40 -0
- data/lua-hooks/ext/lua/ltablib.c +287 -0
- data/lua-hooks/ext/lua/ltm.c +75 -0
- data/lua-hooks/ext/lua/ltm.h +54 -0
- data/lua-hooks/ext/lua/lua.c +392 -0
- data/lua-hooks/ext/lua/lua.def +131 -0
- data/lua-hooks/ext/lua/lua.h +388 -0
- data/lua-hooks/ext/lua/lua.rc +28 -0
- data/lua-hooks/ext/lua/lua_dll.rc +26 -0
- data/lua-hooks/ext/lua/luac.c +200 -0
- data/lua-hooks/ext/lua/luac.rc +1 -0
- data/lua-hooks/ext/lua/luaconf.h +763 -0
- data/lua-hooks/ext/lua/luaconf.h.in +724 -0
- data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
- data/lua-hooks/ext/lua/lualib.h +53 -0
- data/lua-hooks/ext/lua/lundump.c +227 -0
- data/lua-hooks/ext/lua/lundump.h +36 -0
- data/lua-hooks/ext/lua/lvm.c +767 -0
- data/lua-hooks/ext/lua/lvm.h +36 -0
- data/lua-hooks/ext/lua/lzio.c +82 -0
- data/lua-hooks/ext/lua/lzio.h +67 -0
- data/lua-hooks/ext/lua/print.c +227 -0
- data/lua-hooks/ext/luautf8/README.md +152 -0
- data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
- data/lua-hooks/ext/luautf8/unidata.h +3064 -0
- data/lua-hooks/lib/boot.lua +254 -0
- data/lua-hooks/lib/encode.lua +4 -0
- data/lua-hooks/lib/lexers/LICENSE +21 -0
- data/lua-hooks/lib/lexers/bash.lua +134 -0
- data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
- data/lua-hooks/lib/lexers/css.lua +216 -0
- data/lua-hooks/lib/lexers/html.lua +106 -0
- data/lua-hooks/lib/lexers/javascript.lua +68 -0
- data/lua-hooks/lib/lexers/lexer.lua +1575 -0
- data/lua-hooks/lib/lexers/markers.lua +33 -0
- 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
|
+
|