@memberjunction/global 6.2.0-edge.4 → 6.2.0-edge.6
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.
- package/dist/ClassFactory.d.ts +16 -3
- package/dist/ClassFactory.d.ts.map +1 -1
- package/dist/ClassFactory.js +112 -48
- package/dist/ClassFactory.js.map +1 -1
- package/dist/DeepDiff.d.ts +2 -0
- package/dist/DeepDiff.d.ts.map +1 -1
- package/dist/DeepDiff.js +40 -38
- package/dist/DeepDiff.js.map +1 -1
- package/dist/KeyedSerialTaskQueue.d.ts +18 -1
- package/dist/KeyedSerialTaskQueue.d.ts.map +1 -1
- package/dist/KeyedSerialTaskQueue.js +24 -3
- package/dist/KeyedSerialTaskQueue.js.map +1 -1
- package/dist/ObjectCache.d.ts +1 -0
- package/dist/ObjectCache.d.ts.map +1 -1
- package/dist/ObjectCache.js +14 -22
- package/dist/ObjectCache.js.map +1 -1
- package/dist/SQLExpressionValidator.d.ts +70 -41
- package/dist/SQLExpressionValidator.d.ts.map +1 -1
- package/dist/SQLExpressionValidator.js +183 -134
- package/dist/SQLExpressionValidator.js.map +1 -1
- package/dist/SQLScreeningScanner.d.ts +117 -0
- package/dist/SQLScreeningScanner.d.ts.map +1 -0
- package/dist/SQLScreeningScanner.js +475 -0
- package/dist/SQLScreeningScanner.js.map +1 -0
- package/dist/__tests__/FieldSecurityEgressCompliance.test.d.ts +2 -0
- package/dist/__tests__/FieldSecurityEgressCompliance.test.d.ts.map +1 -0
- package/dist/__tests__/FieldSecurityEgressCompliance.test.js +228 -0
- package/dist/__tests__/FieldSecurityEgressCompliance.test.js.map +1 -0
- package/dist/__tests__/KeyedSerialTaskQueue.test.js +92 -0
- package/dist/__tests__/KeyedSerialTaskQueue.test.js.map +1 -1
- package/dist/__tests__/ProofOfPossession.test.d.ts +2 -0
- package/dist/__tests__/ProofOfPossession.test.d.ts.map +1 -0
- package/dist/__tests__/ProofOfPossession.test.js +123 -0
- package/dist/__tests__/ProofOfPossession.test.js.map +1 -0
- package/dist/__tests__/SQLExpressionValidator.dialect.test.d.ts +2 -0
- package/dist/__tests__/SQLExpressionValidator.dialect.test.d.ts.map +1 -0
- package/dist/__tests__/SQLExpressionValidator.dialect.test.js +183 -0
- package/dist/__tests__/SQLExpressionValidator.dialect.test.js.map +1 -0
- package/dist/__tests__/SQLExpressionValidator.security.test.js +176 -2
- package/dist/__tests__/SQLExpressionValidator.security.test.js.map +1 -1
- package/dist/__tests__/SQLScreeningScanner.test.d.ts +2 -0
- package/dist/__tests__/SQLScreeningScanner.test.d.ts.map +1 -0
- package/dist/__tests__/SQLScreeningScanner.test.js +172 -0
- package/dist/__tests__/SQLScreeningScanner.test.js.map +1 -0
- package/dist/__tests__/SQLScreeningScanner.tokens.test.d.ts +2 -0
- package/dist/__tests__/SQLScreeningScanner.tokens.test.d.ts.map +1 -0
- package/dist/__tests__/SQLScreeningScanner.tokens.test.js +82 -0
- package/dist/__tests__/SQLScreeningScanner.tokens.test.js.map +1 -0
- package/dist/__tests__/UUIDCompliance.test.js +4 -4
- package/dist/__tests__/UUIDCompliance.test.js.map +1 -1
- package/dist/__tests__/UserScopedCacheKey.test.d.ts +2 -0
- package/dist/__tests__/UserScopedCacheKey.test.d.ts.map +1 -0
- package/dist/__tests__/UserScopedCacheKey.test.js +25 -0
- package/dist/__tests__/UserScopedCacheKey.test.js.map +1 -0
- package/dist/__tests__/util.valuesEqual.test.d.ts +2 -0
- package/dist/__tests__/util.valuesEqual.test.d.ts.map +1 -0
- package/dist/__tests__/util.valuesEqual.test.js +37 -0
- package/dist/__tests__/util.valuesEqual.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/util/ProofOfPossession.d.ts +68 -0
- package/dist/util/ProofOfPossession.d.ts.map +1 -0
- package/dist/util/ProofOfPossession.js +163 -0
- package/dist/util/ProofOfPossession.js.map +1 -0
- package/dist/util/UserScopedCacheKey.d.ts +42 -0
- package/dist/util/UserScopedCacheKey.d.ts.map +1 -0
- package/dist/util/UserScopedCacheKey.js +49 -0
- package/dist/util/UserScopedCacheKey.js.map +1 -0
- package/dist/util.d.ts +25 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +38 -0
- package/dist/util.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Dialect-aware SQL scanner for MemberJunction's SQL denylist screens.
|
|
3
|
+
*
|
|
4
|
+
* A denylist screen is only as good as its idea of which text is code. This scanner reads SQL the
|
|
5
|
+
* way SQL Server or PostgreSQL splits it into tokens and marks every string literal, quoted
|
|
6
|
+
* identifier and comment, so a screen checks exactly the text the database runs as code. When it
|
|
7
|
+
* cannot read the text the way the database would, it reports that, so the screen rejects the text
|
|
8
|
+
* instead of guessing.
|
|
9
|
+
*
|
|
10
|
+
* Used by `SQLExpressionValidator` and `DatabaseProviderBase.ValidateUserProvidedSQLClause`.
|
|
11
|
+
*
|
|
12
|
+
* @module @memberjunction/global/SQLScreeningScanner
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Every dialect {@link ScanSQLForScreening} knows. A screen that does not know which database will
|
|
16
|
+
* run the SQL must accept it under each one.
|
|
17
|
+
*/
|
|
18
|
+
export const SQL_SCREENING_DIALECTS = ['sqlserver', 'postgresql'];
|
|
19
|
+
const LEXICAL_RULES = {
|
|
20
|
+
sqlserver: {
|
|
21
|
+
BracketIdentifiers: true,
|
|
22
|
+
PostgresStrings: false,
|
|
23
|
+
UnicodeEscapeIdentifiers: false,
|
|
24
|
+
// Letters and digits of any script. Other non-ASCII characters are not part of a word: SQL
|
|
25
|
+
// Server reads a currency symbol such as ¥ as the start of a money literal, so in `¥1SELECT`
|
|
26
|
+
// the keyword is a separate token.
|
|
27
|
+
WordStart: /[\p{L}_@#]/u,
|
|
28
|
+
WordPart: /[\p{L}\p{N}_@#$]/u,
|
|
29
|
+
BareExponent: true,
|
|
30
|
+
},
|
|
31
|
+
postgresql: {
|
|
32
|
+
BracketIdentifiers: false,
|
|
33
|
+
PostgresStrings: true,
|
|
34
|
+
UnicodeEscapeIdentifiers: true,
|
|
35
|
+
WordStart: /[A-Za-z_\u0080-]/,
|
|
36
|
+
WordPart: /[A-Za-z0-9_$\u0080-]/,
|
|
37
|
+
BareExponent: false,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const DIGIT = /[0-9]/;
|
|
41
|
+
const WHITESPACE = /\s/;
|
|
42
|
+
/** Whitespace every server skips. Other Unicode spaces count as a token when finding the leading word. */
|
|
43
|
+
const ASCII_WHITESPACE = /[ \t\n\r\f\v]/;
|
|
44
|
+
const NON_ASCII = /[^\x00-\x7f]/;
|
|
45
|
+
/**
|
|
46
|
+
* A numeric literal at `lastIndex` (sticky). An exponent needs digits, so in PostgreSQL's `1e'…'`
|
|
47
|
+
* the `e` is left to open an E'…' string.
|
|
48
|
+
*/
|
|
49
|
+
const NUMBER = /0[xX][0-9A-Fa-f]*|(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?/y;
|
|
50
|
+
/** A PostgreSQL `$$` or `$tag$` delimiter at `lastIndex` (sticky). */
|
|
51
|
+
const DOLLAR_DELIMITER = /\$(?:[A-Za-z_\u0080-][A-Za-z0-9_\u0080-]*)?\$/y;
|
|
52
|
+
/** Characters PostgreSQL does not accept as a `UESCAPE` character. */
|
|
53
|
+
const INVALID_UESCAPE = /[0-9A-Fa-f+'"\s]/;
|
|
54
|
+
/** A `UESCAPE` keyword at `lastIndex` (sticky), any case, not followed by a word character. */
|
|
55
|
+
const UESCAPE_KEYWORD = /uescape(?![A-Za-z0-9_$\u0080-\uffff])/iy;
|
|
56
|
+
/** Line breaks other than `\n` and `\r\n`. Servers disagree on whether they end a `--` comment. */
|
|
57
|
+
const AMBIGUOUS_LINE_BREAKS = new Set(['\r', '\u000b', '\u000c', '\u0085', '
', '
']);
|
|
58
|
+
/**
|
|
59
|
+
* Reads `sql` the way `dialect` splits it into tokens. Returns the string literals, quoted
|
|
60
|
+
* identifiers and comments it contains, and the code that remains.
|
|
61
|
+
*
|
|
62
|
+
* Both dialects: `'…'` and `N'…'` strings, in which `''` is an escaped quote and a backslash is an
|
|
63
|
+
* ordinary character; `"…"` identifiers with `""` escapes; `--` comments to the end of the line; and
|
|
64
|
+
* nested block comments. SQL Server adds `[…]` identifiers with `]]` escapes. PostgreSQL adds `E'…'`
|
|
65
|
+
* strings, in which a backslash escapes the next character, dollar-quoted strings (`$$…$$`,
|
|
66
|
+
* `$tag$…$tag$`), and `U&"…"` identifiers, read as one identifier whose `\XXXX` and `\+XXXXXX`
|
|
67
|
+
* escapes (or those of the character a following `UESCAPE '<c>'` names) are decoded, so the name is
|
|
68
|
+
* the one PostgreSQL resolves; a `[` is code there.
|
|
69
|
+
*
|
|
70
|
+
* 🚨 Do not add backslash escapes to plain `'…'` strings. Neither server honors them (PostgreSQL is
|
|
71
|
+
* assumed to run with `standard_conforming_strings = on`, its default since 9.1), and a scanner that
|
|
72
|
+
* does reads `x = 'a\') ; DROP TABLE t; --'` as one literal while the database runs the DROP.
|
|
73
|
+
*
|
|
74
|
+
* The scan stops and reports an error, instead of guessing, when:
|
|
75
|
+
* - a string, quoted identifier, dollar-quoted string or block comment is not closed;
|
|
76
|
+
* - the text contains a NUL character;
|
|
77
|
+
* - a `--` comment contains a line break other than `\n` or `\r\n`;
|
|
78
|
+
* - a PostgreSQL `E'…'` string is followed by another quoted segment, which PostgreSQL can join to
|
|
79
|
+
* it and read with backslash escapes;
|
|
80
|
+
* - a PostgreSQL `U&"…"` identifier has an escape or a `UESCAPE` clause PostgreSQL would reject;
|
|
81
|
+
* - on SQL Server, a number is followed by `e` and a word character (`1EXEC` splits two ways).
|
|
82
|
+
*
|
|
83
|
+
* @param sql The clause, expression or query to read
|
|
84
|
+
* @param dialect The dialect whose lexical rules apply
|
|
85
|
+
*/
|
|
86
|
+
export function ScanSQLForScreening(sql, dialect) {
|
|
87
|
+
return new SQLScreeningScanner(sql, dialect).Scan();
|
|
88
|
+
}
|
|
89
|
+
/** One left-to-right pass over the input, with the dialect's rules. */
|
|
90
|
+
class SQLScreeningScanner {
|
|
91
|
+
constructor(sql, dialect) {
|
|
92
|
+
this.sql = sql;
|
|
93
|
+
this.dialect = dialect;
|
|
94
|
+
this.spans = [];
|
|
95
|
+
this.code = [];
|
|
96
|
+
this.codeWithIdentifiers = [];
|
|
97
|
+
this.tokens = [];
|
|
98
|
+
this.commentCount = 0;
|
|
99
|
+
this.pos = 0;
|
|
100
|
+
/** Offset of the first token that is not whitespace or a comment, once one is reached. */
|
|
101
|
+
this.leadingTokenStart = null;
|
|
102
|
+
this.leadingWord = null;
|
|
103
|
+
this.rules = LEXICAL_RULES[dialect];
|
|
104
|
+
}
|
|
105
|
+
Scan() {
|
|
106
|
+
if (!SQL_SCREENING_DIALECTS.includes(this.dialect))
|
|
107
|
+
return this.stop(`"${this.dialect}" is not a known SQL dialect`);
|
|
108
|
+
if (this.sql.includes('\0'))
|
|
109
|
+
return this.stop('the text contains a NUL character');
|
|
110
|
+
while (this.pos < this.sql.length) {
|
|
111
|
+
const error = this.readToken();
|
|
112
|
+
if (error !== null)
|
|
113
|
+
return this.stop(error);
|
|
114
|
+
}
|
|
115
|
+
return this.result(null);
|
|
116
|
+
}
|
|
117
|
+
/** Reads the token at `pos`. Returns why the text cannot be classified, or null. */
|
|
118
|
+
readToken() {
|
|
119
|
+
const c = this.sql[this.pos];
|
|
120
|
+
const next = this.sql[this.pos + 1] ?? '';
|
|
121
|
+
if (c === '-' && next === '-')
|
|
122
|
+
return this.readLineComment();
|
|
123
|
+
if (c === '/' && next === '*')
|
|
124
|
+
return this.readBlockComment();
|
|
125
|
+
if (this.leadingTokenStart === null && !ASCII_WHITESPACE.test(c))
|
|
126
|
+
this.leadingTokenStart = this.pos;
|
|
127
|
+
if (c === "'")
|
|
128
|
+
return this.readString(this.pos + 1);
|
|
129
|
+
if ((c === 'N' || c === 'n') && next === "'")
|
|
130
|
+
return this.readString(this.pos + 2);
|
|
131
|
+
if (this.rules.PostgresStrings && (c === 'E' || c === 'e') && next === "'")
|
|
132
|
+
return this.readEscapeString();
|
|
133
|
+
if (this.rules.PostgresStrings && c === '$') {
|
|
134
|
+
const delimiter = this.dollarDelimiterAt(this.pos);
|
|
135
|
+
if (delimiter !== null)
|
|
136
|
+
return this.readDollarString(delimiter);
|
|
137
|
+
}
|
|
138
|
+
if (this.rules.UnicodeEscapeIdentifiers && (c === 'U' || c === 'u') && next === '&' && this.sql[this.pos + 2] === '"') {
|
|
139
|
+
return this.readUnicodeEscapeIdentifier();
|
|
140
|
+
}
|
|
141
|
+
if (c === '"')
|
|
142
|
+
return this.readQuotedIdentifier('"');
|
|
143
|
+
if (this.rules.BracketIdentifiers && c === '[')
|
|
144
|
+
return this.readQuotedIdentifier(']');
|
|
145
|
+
if (DIGIT.test(c) || (c === '.' && DIGIT.test(next)))
|
|
146
|
+
return this.readNumber();
|
|
147
|
+
if (this.rules.WordStart.test(c))
|
|
148
|
+
return this.readWord();
|
|
149
|
+
if (!WHITESPACE.test(c))
|
|
150
|
+
this.pushToken('symbol', c, this.pos, this.pos + 1);
|
|
151
|
+
this.emitCode(this.pos + 1);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
/** Reads a `'…'` string whose content starts at `contentStart`. */
|
|
155
|
+
readString(contentStart) {
|
|
156
|
+
const end = this.findQuoteEnd(contentStart, "'", false);
|
|
157
|
+
if (end === -1)
|
|
158
|
+
return 'a string literal is not closed';
|
|
159
|
+
this.emitSpan('string', end);
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
/** Reads a PostgreSQL `E'…'` string, in which a backslash escapes the next character. */
|
|
163
|
+
readEscapeString() {
|
|
164
|
+
const end = this.findQuoteEnd(this.pos + 2, "'", true);
|
|
165
|
+
if (end === -1)
|
|
166
|
+
return "an E'…' string is not closed";
|
|
167
|
+
if (this.quoteFollows(end)) {
|
|
168
|
+
return "an E'…' string is followed by another quoted segment, which PostgreSQL can read as part of it";
|
|
169
|
+
}
|
|
170
|
+
this.emitSpan('string', end);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
/** Reads a PostgreSQL dollar-quoted string that opens with `delimiter`. */
|
|
174
|
+
readDollarString(delimiter) {
|
|
175
|
+
const close = this.sql.indexOf(delimiter, this.pos + delimiter.length);
|
|
176
|
+
if (close === -1)
|
|
177
|
+
return 'a dollar-quoted string is not closed';
|
|
178
|
+
this.emitSpan('string', close + delimiter.length);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/** Reads a `"…"` or `[…]` identifier; `close` is its closing character. */
|
|
182
|
+
readQuotedIdentifier(close) {
|
|
183
|
+
const end = this.findQuoteEnd(this.pos + 1, close, false);
|
|
184
|
+
if (end === -1)
|
|
185
|
+
return 'a quoted identifier is not closed';
|
|
186
|
+
const name = this.sql.slice(this.pos + 1, end - 1).split(close + close).join(close);
|
|
187
|
+
this.emitSpan('identifier', end, name);
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Reads a PostgreSQL `U&"…"` identifier and any `UESCAPE '<c>'` clause after it as one
|
|
192
|
+
* identifier whose name is the decoded text.
|
|
193
|
+
*/
|
|
194
|
+
readUnicodeEscapeIdentifier() {
|
|
195
|
+
const end = this.findQuoteEnd(this.pos + 3, '"', false);
|
|
196
|
+
if (end === -1)
|
|
197
|
+
return 'a quoted identifier is not closed';
|
|
198
|
+
const clause = this.readUEscapeClause(end);
|
|
199
|
+
if (clause.Error !== null)
|
|
200
|
+
return clause.Error;
|
|
201
|
+
const body = this.sql.slice(this.pos + 3, end - 1).split('""').join('"');
|
|
202
|
+
const name = decodeUnicodeEscapes(body, clause.Escape);
|
|
203
|
+
if (name === null)
|
|
204
|
+
return 'a U&"…" identifier has an escape PostgreSQL would reject';
|
|
205
|
+
this.emitSpan('identifier', clause.End, name);
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The escape character of a `U&"…"` identifier that ends at `from`: the one a following
|
|
210
|
+
* `UESCAPE '<c>'` clause names, or a backslash. `End` is the offset just past the clause, or
|
|
211
|
+
* `from` when there is none.
|
|
212
|
+
*/
|
|
213
|
+
readUEscapeClause(from) {
|
|
214
|
+
const keywordStart = this.triviaEnd(from);
|
|
215
|
+
UESCAPE_KEYWORD.lastIndex = keywordStart;
|
|
216
|
+
if (!UESCAPE_KEYWORD.test(this.sql))
|
|
217
|
+
return { Escape: '\\', End: from, Error: null };
|
|
218
|
+
const quote = this.triviaEnd(UESCAPE_KEYWORD.lastIndex);
|
|
219
|
+
const escape = this.sql[quote + 1] ?? '';
|
|
220
|
+
const valid = this.sql[quote] === "'" && this.sql[quote + 2] === "'" && this.sql[quote + 3] !== "'" && escape !== '' && !INVALID_UESCAPE.test(escape);
|
|
221
|
+
return valid
|
|
222
|
+
? { Escape: escape, End: quote + 3, Error: null }
|
|
223
|
+
: { Escape: '', End: from, Error: 'a UESCAPE clause does not name one valid escape character' };
|
|
224
|
+
}
|
|
225
|
+
/** Offset of the first character at or after `from` that is not whitespace or inside a comment. */
|
|
226
|
+
triviaEnd(from) {
|
|
227
|
+
let j = from;
|
|
228
|
+
while (j < this.sql.length) {
|
|
229
|
+
if (WHITESPACE.test(this.sql[j])) {
|
|
230
|
+
j++;
|
|
231
|
+
}
|
|
232
|
+
else if (this.sql[j] === '-' && this.sql[j + 1] === '-') {
|
|
233
|
+
j = this.lineEnd(j);
|
|
234
|
+
}
|
|
235
|
+
else if (this.sql[j] === '/' && this.sql[j + 1] === '*') {
|
|
236
|
+
const close = this.blockCommentEnd(j);
|
|
237
|
+
if (close === -1)
|
|
238
|
+
return j;
|
|
239
|
+
j = close;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
return j;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return j;
|
|
246
|
+
}
|
|
247
|
+
/** Offset just past the nested block comment that opens at `from`, or -1 when it is not closed. */
|
|
248
|
+
blockCommentEnd(from) {
|
|
249
|
+
let depth = 0;
|
|
250
|
+
let j = from;
|
|
251
|
+
while (j < this.sql.length) {
|
|
252
|
+
if (this.sql[j] === '/' && this.sql[j + 1] === '*') {
|
|
253
|
+
depth++;
|
|
254
|
+
j += 2;
|
|
255
|
+
}
|
|
256
|
+
else if (this.sql[j] === '*' && this.sql[j + 1] === '/') {
|
|
257
|
+
depth--;
|
|
258
|
+
j += 2;
|
|
259
|
+
if (depth === 0)
|
|
260
|
+
return j;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
j++;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return -1;
|
|
267
|
+
}
|
|
268
|
+
/** Reads a `--` comment, which ends at the end of the line. */
|
|
269
|
+
readLineComment() {
|
|
270
|
+
let j = this.pos + 2;
|
|
271
|
+
while (j < this.sql.length && this.sql[j] !== '\n') {
|
|
272
|
+
if (this.sql[j] === '\r' && this.sql[j + 1] === '\n')
|
|
273
|
+
break;
|
|
274
|
+
if (AMBIGUOUS_LINE_BREAKS.has(this.sql[j])) {
|
|
275
|
+
return 'a -- comment contains a line break that database servers read differently';
|
|
276
|
+
}
|
|
277
|
+
j++;
|
|
278
|
+
}
|
|
279
|
+
this.commentCount++;
|
|
280
|
+
this.emitSpan('comment', j);
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
/** Reads a block comment. Block comments nest on both SQL Server and PostgreSQL. */
|
|
284
|
+
readBlockComment() {
|
|
285
|
+
const end = this.blockCommentEnd(this.pos);
|
|
286
|
+
if (end === -1)
|
|
287
|
+
return 'a block comment is not closed';
|
|
288
|
+
this.commentCount++;
|
|
289
|
+
this.emitSpan('comment', end);
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
/** Reads a number. A word written against it is a separate token, so a space is added between. */
|
|
293
|
+
readNumber() {
|
|
294
|
+
NUMBER.lastIndex = this.pos;
|
|
295
|
+
const match = NUMBER.exec(this.sql);
|
|
296
|
+
const end = this.pos + (match ? match[0].length : 1);
|
|
297
|
+
const following = this.sql[end] ?? '';
|
|
298
|
+
const afterThat = this.sql[end + 1] ?? '';
|
|
299
|
+
if (this.rules.BareExponent && (following === 'e' || following === 'E') && this.rules.WordStart.test(afterThat)) {
|
|
300
|
+
return 'a number is followed by a word that starts with E, which the server can read as part of the number';
|
|
301
|
+
}
|
|
302
|
+
this.pushToken('number', this.sql.slice(this.pos, end), this.pos, end);
|
|
303
|
+
this.emitCode(end);
|
|
304
|
+
if (following !== '' && this.rules.WordStart.test(following))
|
|
305
|
+
this.emitBoundary();
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
/** Reads an unquoted keyword or identifier. */
|
|
309
|
+
readWord() {
|
|
310
|
+
let j = this.pos + 1;
|
|
311
|
+
while (j < this.sql.length && this.rules.WordPart.test(this.sql[j]))
|
|
312
|
+
j++;
|
|
313
|
+
if (this.pos === this.leadingTokenStart && !NON_ASCII.test(this.sql[j] ?? '')) {
|
|
314
|
+
this.leadingWord = this.sql.slice(this.pos, j);
|
|
315
|
+
}
|
|
316
|
+
this.pushToken('word', this.sql.slice(this.pos, j), this.pos, j);
|
|
317
|
+
this.emitCode(j);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Offset just past the `close` character that ends a quoted run whose content starts at `from`,
|
|
322
|
+
* or -1 when none does. A doubled `close` is an escaped one; with `backslashEscapes`, so is any
|
|
323
|
+
* character after a backslash.
|
|
324
|
+
*/
|
|
325
|
+
findQuoteEnd(from, close, backslashEscapes) {
|
|
326
|
+
let j = from;
|
|
327
|
+
while (j < this.sql.length) {
|
|
328
|
+
const ch = this.sql[j];
|
|
329
|
+
if (backslashEscapes && ch === '\\') {
|
|
330
|
+
j += 2;
|
|
331
|
+
}
|
|
332
|
+
else if (ch !== close) {
|
|
333
|
+
j++;
|
|
334
|
+
}
|
|
335
|
+
else if (this.sql[j + 1] === close) {
|
|
336
|
+
j += 2;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
return j + 1;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return -1;
|
|
343
|
+
}
|
|
344
|
+
/** Whether only whitespace and `--` comments come between `from` and the next `'`. */
|
|
345
|
+
quoteFollows(from) {
|
|
346
|
+
let j = from;
|
|
347
|
+
while (j < this.sql.length) {
|
|
348
|
+
const ch = this.sql[j];
|
|
349
|
+
if (ch === "'")
|
|
350
|
+
return true;
|
|
351
|
+
if (ch === '-' && this.sql[j + 1] === '-') {
|
|
352
|
+
j = this.lineEnd(j);
|
|
353
|
+
}
|
|
354
|
+
else if (WHITESPACE.test(ch)) {
|
|
355
|
+
j++;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
/** Offset of the first `\n` or `\r` at or after `from`, or the input length. */
|
|
364
|
+
lineEnd(from) {
|
|
365
|
+
let j = from;
|
|
366
|
+
while (j < this.sql.length && this.sql[j] !== '\n' && this.sql[j] !== '\r')
|
|
367
|
+
j++;
|
|
368
|
+
return j;
|
|
369
|
+
}
|
|
370
|
+
/** The `$$` or `$tag$` delimiter at `at`, or null when the `$` does not open a dollar-quoted string. */
|
|
371
|
+
dollarDelimiterAt(at) {
|
|
372
|
+
DOLLAR_DELIMITER.lastIndex = at;
|
|
373
|
+
return DOLLAR_DELIMITER.exec(this.sql)?.[0] ?? null;
|
|
374
|
+
}
|
|
375
|
+
/** Copies code up to `end` into both projections. */
|
|
376
|
+
emitCode(end) {
|
|
377
|
+
const text = this.sql.slice(this.pos, end);
|
|
378
|
+
this.code.push(text);
|
|
379
|
+
this.codeWithIdentifiers.push(text);
|
|
380
|
+
this.pos = end;
|
|
381
|
+
}
|
|
382
|
+
/** Records a span up to `end` and writes a space for it, or an identifier's bare name. */
|
|
383
|
+
emitSpan(kind, end, identifierName) {
|
|
384
|
+
this.spans.push({ Kind: kind, Start: this.pos, End: end });
|
|
385
|
+
if (kind === 'string')
|
|
386
|
+
this.pushToken('string', this.sql.slice(this.pos, end), this.pos, end);
|
|
387
|
+
if (kind === 'identifier')
|
|
388
|
+
this.pushToken('identifier', identifierName ?? '', this.pos, end);
|
|
389
|
+
this.code.push(' ');
|
|
390
|
+
this.codeWithIdentifiers.push(identifierName === undefined ? ' ' : ` ${identifierName} `);
|
|
391
|
+
this.pos = end;
|
|
392
|
+
}
|
|
393
|
+
/** Records one token. */
|
|
394
|
+
pushToken(kind, text, start, end) {
|
|
395
|
+
this.tokens.push({ Kind: kind, Text: text, Start: start, End: end });
|
|
396
|
+
}
|
|
397
|
+
/** Writes a token boundary that the input leaves implicit. */
|
|
398
|
+
emitBoundary() {
|
|
399
|
+
this.code.push(' ');
|
|
400
|
+
this.codeWithIdentifiers.push(' ');
|
|
401
|
+
}
|
|
402
|
+
/** Ends the scan at `pos`, leaving the unread text as written. */
|
|
403
|
+
stop(error) {
|
|
404
|
+
this.emitCode(this.sql.length);
|
|
405
|
+
return this.result(error);
|
|
406
|
+
}
|
|
407
|
+
result(error) {
|
|
408
|
+
return {
|
|
409
|
+
Dialect: this.dialect,
|
|
410
|
+
Classified: error === null,
|
|
411
|
+
Error: error,
|
|
412
|
+
Spans: this.spans,
|
|
413
|
+
CommentCount: this.commentCount,
|
|
414
|
+
Code: this.code.join(''),
|
|
415
|
+
CodeWithIdentifiers: this.codeWithIdentifiers.join(''),
|
|
416
|
+
LeadingWord: this.leadingWord,
|
|
417
|
+
Tokens: this.tokens,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* The text of a PostgreSQL `U&"…"` identifier (its doubled quotes already undone) with its Unicode
|
|
423
|
+
* escapes decoded: `<escape>XXXX` (four hex digits), `<escape>+XXXXXX` (six), and a doubled escape
|
|
424
|
+
* character for the character itself. A surrogate pair may be written as two escapes. Null when
|
|
425
|
+
* PostgreSQL would reject an escape: a malformed one, a lone surrogate, U+0000, or past U+10FFFF.
|
|
426
|
+
*
|
|
427
|
+
* @param body The text between the quotes
|
|
428
|
+
* @param escape The escape character: a backslash, or the one a `UESCAPE` clause names
|
|
429
|
+
*/
|
|
430
|
+
function decodeUnicodeEscapes(body, escape) {
|
|
431
|
+
let out = '';
|
|
432
|
+
let i = 0;
|
|
433
|
+
while (i < body.length) {
|
|
434
|
+
if (body[i] !== escape) {
|
|
435
|
+
out += body[i++];
|
|
436
|
+
}
|
|
437
|
+
else if (body[i + 1] === escape) {
|
|
438
|
+
out += escape;
|
|
439
|
+
i += 2;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
const decoded = decodeEscapedCodePoint(body, i, escape);
|
|
443
|
+
if (decoded === null)
|
|
444
|
+
return null;
|
|
445
|
+
out += String.fromCodePoint(decoded.CodePoint);
|
|
446
|
+
i = decoded.Next;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return out;
|
|
450
|
+
}
|
|
451
|
+
/** The code point the escape at `at` writes, joining a surrogate pair, and the offset after it. */
|
|
452
|
+
function decodeEscapedCodePoint(body, at, escape) {
|
|
453
|
+
const first = readEscape(body, at);
|
|
454
|
+
if (first === null)
|
|
455
|
+
return null;
|
|
456
|
+
if (first.CodePoint >= 0xdc00 && first.CodePoint <= 0xdfff)
|
|
457
|
+
return null;
|
|
458
|
+
if (first.CodePoint < 0xd800 || first.CodePoint > 0xdbff)
|
|
459
|
+
return first;
|
|
460
|
+
const second = body[first.Next] === escape ? readEscape(body, first.Next) : null;
|
|
461
|
+
if (second === null || second.CodePoint < 0xdc00 || second.CodePoint > 0xdfff)
|
|
462
|
+
return null;
|
|
463
|
+
return { CodePoint: 0x10000 + ((first.CodePoint - 0xd800) << 10) + (second.CodePoint - 0xdc00), Next: second.Next };
|
|
464
|
+
}
|
|
465
|
+
/** One `<escape>XXXX` or `<escape>+XXXXXX` escape at `at`, or null when it is malformed or out of range. */
|
|
466
|
+
function readEscape(body, at) {
|
|
467
|
+
const long = body[at + 1] === '+';
|
|
468
|
+
const start = at + (long ? 2 : 1);
|
|
469
|
+
const hex = body.slice(start, start + (long ? 6 : 4));
|
|
470
|
+
if (!/^[0-9A-Fa-f]+$/.test(hex) || hex.length !== (long ? 6 : 4))
|
|
471
|
+
return null;
|
|
472
|
+
const codePoint = parseInt(hex, 16);
|
|
473
|
+
return codePoint === 0 || codePoint > 0x10ffff ? null : { CodePoint: codePoint, Next: start + hex.length };
|
|
474
|
+
}
|
|
475
|
+
//# sourceMappingURL=SQLScreeningScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQLScreeningScanner.js","sourceRoot":"","sources":["../src/SQLScreeningScanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAmC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AA6FlG,MAAM,aAAa,GAA8C;IAC7D,SAAS,EAAE;QACP,kBAAkB,EAAE,IAAI;QACxB,eAAe,EAAE,KAAK;QACtB,wBAAwB,EAAE,KAAK;QAC/B,2FAA2F;QAC3F,6FAA6F;QAC7F,mCAAmC;QACnC,SAAS,EAAE,aAAa;QACxB,QAAQ,EAAE,mBAAmB;QAC7B,YAAY,EAAE,IAAI;KACrB;IACD,UAAU,EAAE;QACR,kBAAkB,EAAE,KAAK;QACzB,eAAe,EAAE,IAAI;QACrB,wBAAwB,EAAE,IAAI;QAC9B,SAAS,EAAE,mBAAmB;QAC9B,QAAQ,EAAE,uBAAuB;QACjC,YAAY,EAAE,KAAK;KACtB;CACJ,CAAC;AAEF,MAAM,KAAK,GAAG,OAAO,CAAC;AACtB,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,0GAA0G;AAC1G,MAAM,gBAAgB,GAAG,eAAe,CAAC;AACzC,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,GAAG,yEAAyE,CAAC;AAEzF,sEAAsE;AACtE,MAAM,gBAAgB,GAAG,kDAAkD,CAAC;AAE5E,sEAAsE;AACtE,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C,+FAA+F;AAC/F,MAAM,eAAe,GAAG,yCAAyC,CAAC;AAElE,mGAAmG;AACnG,MAAM,qBAAqB,GAAwB,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE;CAC/F,EAAE;CACF,CAAC,CAAC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,OAA4B;IACzE,OAAO,IAAI,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,uEAAuE;AACvE,MAAM,mBAAmB;IAYrB,YACqB,GAAW,EACX,OAA4B;QAD5B,QAAG,GAAH,GAAG,CAAQ;QACX,YAAO,GAAP,OAAO,CAAqB;QAZhC,UAAK,GAAuB,EAAE,CAAC;QAC/B,SAAI,GAAa,EAAE,CAAC;QACpB,wBAAmB,GAAa,EAAE,CAAC;QACnC,WAAM,GAAwB,EAAE,CAAC;QAC1C,iBAAY,GAAG,CAAC,CAAC;QACjB,QAAG,GAAG,CAAC,CAAC;QAChB,0FAA0F;QAClF,sBAAiB,GAAkB,IAAI,CAAC;QACxC,gBAAW,GAAkB,IAAI,CAAC;QAMtC,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAEM,IAAI;QACP,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,8BAA8B,CAAC,CAAC;QACrH,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,oFAAoF;IAC5E,SAAS;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC;QACpG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACnF,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC3G,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnD,IAAI,SAAS,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpH,OAAO,IAAI,CAAC,2BAA2B,EAAE,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,IAAI,CAAC,KAAK,CAAC,kBAAkB,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACtF,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/E,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,mEAAmE;IAC3D,UAAU,CAAC,YAAoB;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,gCAAgC,CAAC;QACxD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,yFAAyF;IACjF,gBAAgB;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACvD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,8BAA8B,CAAC;QACtD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,+FAA+F,CAAC;QAC3G,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,2EAA2E;IACnE,gBAAgB,CAAC,SAAiB;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,sCAAsC,CAAC;QAChE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,2EAA2E;IACnE,oBAAoB,CAAC,KAAgB;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,mCAAmC,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpF,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,2BAA2B;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,mCAAmC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,0DAA0D,CAAC;QACrF,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CAAC,IAAY;QAClC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1C,eAAe,CAAC,SAAS,GAAG,YAAY,CAAC;QACzC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACrF,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtJ,OAAO,KAAK;YACR,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;YACjD,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,2DAA2D,EAAE,CAAC;IACxG,CAAC;IAED,mGAAmG;IAC3F,SAAS,CAAC,IAAY;QAC1B,IAAI,CAAC,GAAG,IAAI,CAAC;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B,CAAC,EAAE,CAAC;YACR,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxD,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxD,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBACtC,IAAI,KAAK,KAAK,CAAC,CAAC;oBAAE,OAAO,CAAC,CAAC;gBAC3B,CAAC,GAAG,KAAK,CAAC;YACd,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,CAAC;YACb,CAAC;QACL,CAAC;QACD,OAAO,CAAC,CAAC;IACb,CAAC;IAED,mGAAmG;IAC3F,eAAe,CAAC,IAAY;QAChC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,GAAG,IAAI,CAAC;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACjD,KAAK,EAAE,CAAC;gBACR,CAAC,IAAI,CAAC,CAAC;YACX,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxD,KAAK,EAAE,CAAC;gBACR,CAAC,IAAI,CAAC,CAAC;gBACP,IAAI,KAAK,KAAK,CAAC;oBAAE,OAAO,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,CAAC,EAAE,CAAC;YACR,CAAC;QACL,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACd,CAAC;IAED,+DAA+D;IACvD,eAAe;QACnB,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI;gBAAE,MAAM;YAC5D,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,OAAO,2EAA2E,CAAC;YACvF,CAAC;YACD,CAAC,EAAE,CAAC;QACR,CAAC;QACD,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,oFAAoF;IAC5E,gBAAgB;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,+BAA+B,CAAC;QACvD,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,kGAAkG;IAC1F,UAAU;QACd,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9G,OAAO,oGAAoG,CAAC;QAChH,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,SAAS,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,+CAA+C;IACvC,QAAQ;QACZ,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,IAAY,EAAE,KAAa,EAAE,gBAAyB;QACvE,IAAI,CAAC,GAAG,IAAI,CAAC;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,gBAAgB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBAClC,CAAC,IAAI,CAAC,CAAC;YACX,CAAC;iBAAM,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;gBACtB,CAAC,EAAE,CAAC;YACR,CAAC;iBAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBACnC,CAAC,IAAI,CAAC,CAAC;YACX,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;QACL,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACd,CAAC;IAED,sFAAsF;IAC9E,YAAY,CAAC,IAAY;QAC7B,IAAI,CAAC,GAAG,IAAI,CAAC;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,EAAE,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC5B,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC7B,CAAC,EAAE,CAAC;YACR,CAAC;iBAAM,CAAC;gBACJ,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,gFAAgF;IACxE,OAAO,CAAC,IAAY;QACxB,IAAI,CAAC,GAAG,IAAI,CAAC;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,CAAC,EAAE,CAAC;QAChF,OAAO,CAAC,CAAC;IACb,CAAC;IAED,wGAAwG;IAChG,iBAAiB,CAAC,EAAU;QAChC,gBAAgB,CAAC,SAAS,GAAG,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IAED,qDAAqD;IAC7C,QAAQ,CAAC,GAAW;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IAED,0FAA0F;IAClF,QAAQ,CAAC,IAA0B,EAAE,GAAW,EAAE,cAAuB;QAC7E,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3D,IAAI,IAAI,KAAK,QAAQ;YAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC9F,IAAI,IAAI,KAAK,YAAY;YAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,cAAc,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7F,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,cAAc,GAAG,CAAC,CAAC;QAC1F,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IAED,yBAAyB;IACjB,SAAS,CAAC,IAA2B,EAAE,IAAY,EAAE,KAAa,EAAE,GAAW;QACnF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,8DAA8D;IACtD,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,kEAAkE;IAC1D,IAAI,CAAC,KAAa;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAEO,MAAM,CAAC,KAAoB;QAC/B,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,KAAK,KAAK,IAAI;YAC1B,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;SACtB,CAAC;IACN,CAAC;CACJ;AAED;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAAC,IAAY,EAAE,MAAc;IACtD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YACrB,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YAChC,GAAG,IAAI,MAAM,CAAC;YACd,CAAC,IAAI,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACJ,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACxD,IAAI,OAAO,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAClC,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC/C,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QACrB,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,mGAAmG;AACnG,SAAS,sBAAsB,CAAC,IAAY,EAAE,EAAU,EAAE,MAAc;IACpE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,KAAK,CAAC,SAAS,IAAI,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACxE,IAAI,KAAK,CAAC,SAAS,GAAG,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG,MAAM;QAAE,OAAO,KAAK,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3F,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AACxH,CAAC;AAED,4GAA4G;AAC5G,SAAS,UAAU,CAAC,IAAY,EAAE,EAAU;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;IAClC,MAAM,KAAK,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,SAAS,KAAK,CAAC,IAAI,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;AAC/G,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldSecurityEgressCompliance.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/FieldSecurityEgressCompliance.test.ts"],"names":[],"mappings":""}
|