imapflow 2.3.0 → 2.4.1
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/CHANGELOG.md +19 -0
- package/SECURITY.md +126 -55
- package/dist/cjs/commands/append.d.ts +1 -1
- package/dist/cjs/commands/append.js +15 -4
- package/dist/cjs/commands/compress.js +2 -2
- package/dist/cjs/commands/idle.js +2 -3
- package/dist/cjs/commands/status.js +2 -4
- package/dist/cjs/connection-deadline.d.ts +1 -1
- package/dist/cjs/connection-deadline.js +2 -4
- package/dist/cjs/download.js +22 -19
- package/dist/cjs/errors.d.ts +15 -0
- package/dist/cjs/errors.js +22 -0
- package/dist/cjs/handler/imap-compiler.d.ts +4 -4
- package/dist/cjs/handler/imap-compiler.js +18 -18
- package/dist/cjs/handler/imap-parser.js +28 -3
- package/dist/cjs/handler/imap-stream.js +9 -8
- package/dist/cjs/handler/limits.d.ts +1 -1
- package/dist/cjs/handler/limits.js +5 -7
- package/dist/cjs/handler/parser-instance.js +23 -38
- package/dist/cjs/handler/token-parser.d.ts +12 -0
- package/dist/cjs/handler/token-parser.js +44 -104
- package/dist/cjs/imap-flow.d.ts +4 -3
- package/dist/cjs/imap-flow.js +72 -72
- package/dist/cjs/package-info.d.ts +1 -1
- package/dist/cjs/package-info.js +1 -1
- package/dist/cjs/proxy-connection.js +2 -5
- package/dist/cjs/search-compiler.js +2 -3
- package/dist/cjs/tools.d.ts +2 -2
- package/dist/cjs/tools.js +8 -11
- package/dist/esm/commands/append.d.ts +1 -1
- package/dist/esm/commands/append.js +15 -4
- package/dist/esm/commands/compress.js +2 -2
- package/dist/esm/commands/idle.js +2 -3
- package/dist/esm/commands/status.js +2 -4
- package/dist/esm/connection-deadline.d.ts +1 -1
- package/dist/esm/connection-deadline.js +2 -4
- package/dist/esm/download.js +22 -19
- package/dist/esm/errors.d.ts +15 -0
- package/dist/esm/errors.js +21 -0
- package/dist/esm/handler/imap-compiler.d.ts +4 -4
- package/dist/esm/handler/imap-compiler.js +18 -18
- package/dist/esm/handler/imap-parser.js +28 -3
- package/dist/esm/handler/imap-stream.js +9 -8
- package/dist/esm/handler/limits.d.ts +1 -1
- package/dist/esm/handler/limits.js +5 -7
- package/dist/esm/handler/parser-instance.js +23 -38
- package/dist/esm/handler/token-parser.d.ts +12 -0
- package/dist/esm/handler/token-parser.js +44 -104
- package/dist/esm/imap-flow.d.ts +4 -3
- package/dist/esm/imap-flow.js +73 -73
- package/dist/esm/package-info.d.ts +1 -1
- package/dist/esm/package-info.js +1 -1
- package/dist/esm/proxy-connection.js +2 -5
- package/dist/esm/search-compiler.js +2 -3
- package/dist/esm/tools.d.ts +2 -2
- package/dist/esm/tools.js +9 -12
- package/package.json +6 -6
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const imap_formal_syntax_js_1 = __importDefault(require("./imap-formal-syntax.js"));
|
|
8
|
+
const errors_js_1 = require("../errors.js");
|
|
8
9
|
// A single element of a sequence-set as defined by the RFC 9051 grammar: a number
|
|
9
10
|
// or a range, where "*" stands for the largest number in use. Digit strings are not
|
|
10
11
|
// range-checked here (a server rejects "0" or an overlong number on its own); the
|
|
@@ -46,13 +47,11 @@ const CRLF = /[\r\n]/;
|
|
|
46
47
|
*/
|
|
47
48
|
const quoteString = (value) => {
|
|
48
49
|
if (NOT_QUOTABLE.test(value)) {
|
|
49
|
-
|
|
50
|
-
error.code = 'InvalidStringValue';
|
|
51
|
-
throw error;
|
|
50
|
+
throw (0, errors_js_1.createImapError)('Unquotable character in IMAP string value', 'InvalidStringValue');
|
|
52
51
|
}
|
|
53
52
|
return '"' + value.replace(/["\\]/g, char => '\\' + char) + '"';
|
|
54
53
|
};
|
|
55
|
-
|
|
54
|
+
function compiler(response, options) {
|
|
56
55
|
let { asArray, isLogging, literalPlus, literalMinus } = options || {};
|
|
57
56
|
const respParts = [];
|
|
58
57
|
// Formats an entry (string, number or Buffer) into the Buffer that is written to
|
|
@@ -67,9 +66,7 @@ async function compiler(response, options) {
|
|
|
67
66
|
const emitEntry = (entry, opts) => {
|
|
68
67
|
let { returnEmpty, raw } = opts || {};
|
|
69
68
|
if (!raw && !isLogging && (typeof entry === 'string' || Buffer.isBuffer(entry)) && CRLF.test(entry.toString('latin1'))) {
|
|
70
|
-
|
|
71
|
-
error.code = 'InvalidTokenValue';
|
|
72
|
-
throw error;
|
|
69
|
+
throw (0, errors_js_1.createImapError)('Line terminator in IMAP token', 'InvalidTokenValue');
|
|
73
70
|
}
|
|
74
71
|
if (typeof entry === 'string') {
|
|
75
72
|
return Buffer.from(entry);
|
|
@@ -93,7 +90,7 @@ async function compiler(response, options) {
|
|
|
93
90
|
// Set right after the compiler writes "(" or "[" itself, so the first element inside gets no
|
|
94
91
|
// leading space
|
|
95
92
|
let afterOpener = false;
|
|
96
|
-
let walk =
|
|
93
|
+
let walk = (node, options) => {
|
|
97
94
|
options = options || {};
|
|
98
95
|
// Add a space separator when:
|
|
99
96
|
// - The previous token was a LITERAL. Literal data ends exactly at its declared length, so
|
|
@@ -125,7 +122,7 @@ async function compiler(response, options) {
|
|
|
125
122
|
if (subArray && !Array.isArray(child)) {
|
|
126
123
|
subArray = false;
|
|
127
124
|
}
|
|
128
|
-
|
|
125
|
+
walk(child, { subArray });
|
|
129
126
|
}
|
|
130
127
|
resp.push(emitEntry(')'));
|
|
131
128
|
afterOpener = false;
|
|
@@ -159,6 +156,11 @@ async function compiler(response, options) {
|
|
|
159
156
|
resp.push(emitEntry(logPlaceholder(node.value.length, 'literal')));
|
|
160
157
|
}
|
|
161
158
|
else {
|
|
159
|
+
// The size marker must match the bytes emitEntry() writes, and it writes
|
|
160
|
+
// nothing for a value that is not a Buffer or a string
|
|
161
|
+
if (node.value && !Buffer.isBuffer(node.value) && typeof node.value !== 'string') {
|
|
162
|
+
throw (0, errors_js_1.createImapError)('Literal value must be a Buffer or a string', 'InvalidTokenValue');
|
|
163
|
+
}
|
|
162
164
|
// The literal size marker counts octets - string values are written as
|
|
163
165
|
// UTF-8, so their UTF-16 .length would undercount multi-byte characters
|
|
164
166
|
let literalLength = !node.value ? 0 : Buffer.isBuffer(node.value) ? node.value.length : Buffer.byteLength(node.value.toString());
|
|
@@ -213,9 +215,7 @@ async function compiler(response, options) {
|
|
|
213
215
|
if (!isLogging) {
|
|
214
216
|
val = node.value === null || node.value === undefined ? '' : node.value.toString();
|
|
215
217
|
if (!isValidSequenceSet(val)) {
|
|
216
|
-
|
|
217
|
-
error.code = 'InvalidSequenceSet';
|
|
218
|
-
throw error;
|
|
218
|
+
throw (0, errors_js_1.createImapError)('Invalid sequence set value', 'InvalidSequenceSet');
|
|
219
219
|
}
|
|
220
220
|
resp.push(emitEntry(val, { raw: true }));
|
|
221
221
|
}
|
|
@@ -230,9 +230,7 @@ async function compiler(response, options) {
|
|
|
230
230
|
// this check runs first only to raise the more specific InvalidTextValue code.
|
|
231
231
|
if (node.value) {
|
|
232
232
|
if (!isLogging && CRLF.test(node.value.toString())) {
|
|
233
|
-
|
|
234
|
-
error.code = 'InvalidTextValue';
|
|
235
|
-
throw error;
|
|
233
|
+
throw (0, errors_js_1.createImapError)('Line terminator in IMAP text value', 'InvalidTextValue');
|
|
236
234
|
}
|
|
237
235
|
resp.push(emitEntry(node.value));
|
|
238
236
|
}
|
|
@@ -267,7 +265,7 @@ async function compiler(response, options) {
|
|
|
267
265
|
resp.push(emitEntry('['));
|
|
268
266
|
afterOpener = true;
|
|
269
267
|
for (let child of node.section) {
|
|
270
|
-
|
|
268
|
+
walk(child);
|
|
271
269
|
}
|
|
272
270
|
resp.push(emitEntry(']'));
|
|
273
271
|
afterOpener = false;
|
|
@@ -286,13 +284,15 @@ async function compiler(response, options) {
|
|
|
286
284
|
if (response.attributes) {
|
|
287
285
|
let attributes = Array.isArray(response.attributes) ? response.attributes : [].concat(response.attributes);
|
|
288
286
|
for (let child of attributes) {
|
|
289
|
-
|
|
287
|
+
walk(child);
|
|
290
288
|
}
|
|
291
289
|
}
|
|
292
290
|
if (resp.length) {
|
|
293
291
|
respParts.push(resp);
|
|
294
292
|
}
|
|
295
|
-
|
|
293
|
+
// A part with a single entry (the data of a synchronizing literal) is used as is: copying a
|
|
294
|
+
// large message only to send it doubles its memory
|
|
295
|
+
const compiled = respParts.map(part => (part.length === 1 ? part[0] : Buffer.concat(part)));
|
|
296
296
|
// without asArray there is a single part, returned as is instead of copied
|
|
297
297
|
return asArray ? compiled : compiled.length === 1 ? compiled[0] : Buffer.concat(compiled);
|
|
298
298
|
}
|
|
@@ -6,6 +6,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.default = parser;
|
|
7
7
|
const imap_formal_syntax_js_1 = __importDefault(require("./imap-formal-syntax.js"));
|
|
8
8
|
const parser_instance_js_1 = require("./parser-instance.js");
|
|
9
|
+
const errors_js_1 = require("../errors.js");
|
|
10
|
+
const limits_js_1 = require("./limits.js");
|
|
11
|
+
// The codes the parser raises on purpose: the numbered ParserErrorN codes, ParserErrorExchange,
|
|
12
|
+
// the nesting limit and the inline literal size limit
|
|
13
|
+
const PARSER_ERROR_CODES = /^(?:ParserError\d+|ParserErrorExchange|MAX_IMAP_NESTING_REACHED|LiteralTooLarge)$/;
|
|
14
|
+
/**
|
|
15
|
+
* Anything the parser throws other than one of its own coded errors - a TypeError from a parser
|
|
16
|
+
* bug, a RangeError from runaway recursion or a bad Buffer offset (which carries a Node code), a
|
|
17
|
+
* thrown non-Error - is re-raised as a coded `ParserErrorInternal`, so callers that match on
|
|
18
|
+
* codes still handle it and settle the command the line belonged to. The fuzz suite treats this
|
|
19
|
+
* code as a failure, so the guard does not hide parser bugs from the tests.
|
|
20
|
+
*
|
|
21
|
+
* @param err - The thrown value
|
|
22
|
+
* @param input - The line that was being parsed
|
|
23
|
+
* @returns The error to rethrow
|
|
24
|
+
*/
|
|
25
|
+
function asParserError(err, input) {
|
|
26
|
+
if (err instanceof Error && PARSER_ERROR_CODES.test(err.code || '')) {
|
|
27
|
+
return err;
|
|
28
|
+
}
|
|
29
|
+
return (0, errors_js_1.createImapError)(`Unexpected parser failure: ${err instanceof Error ? err.message : String(err)}`, 'ParserErrorInternal', {
|
|
30
|
+
parserContext: (0, limits_js_1.boundedInput)(input.toString()),
|
|
31
|
+
...(err instanceof Error ? { _err: err } : {})
|
|
32
|
+
});
|
|
33
|
+
}
|
|
9
34
|
/**
|
|
10
35
|
* Parses a raw IMAP command or response buffer into a structured object.
|
|
11
36
|
* Handles edge cases such as null-byte-padded responses from buggy servers and
|
|
@@ -26,7 +51,7 @@ async function parser(command, options) {
|
|
|
26
51
|
// Workaround for buggy IMAP servers that pad responses with leading NUL (\x00) bytes.
|
|
27
52
|
// Some servers (observed in the wild) prepend null bytes to their output, which would
|
|
28
53
|
// cause parsing to fail. We strip them and note how many were removed for diagnostics.
|
|
29
|
-
if (command[0] === 0) {
|
|
54
|
+
if (Buffer.isBuffer(command) && command[0] === 0) {
|
|
30
55
|
// find the first non null byte and trim
|
|
31
56
|
let firstNonNull = -1;
|
|
32
57
|
for (let i = 0; i < command.length; i++) {
|
|
@@ -39,7 +64,7 @@ async function parser(command, options) {
|
|
|
39
64
|
// All bytes are null, treat as a BAD response
|
|
40
65
|
return { tag: '*', command: 'BAD', attributes: [] };
|
|
41
66
|
}
|
|
42
|
-
command = command.
|
|
67
|
+
command = command.subarray(firstNonNull);
|
|
43
68
|
nullBytesRemoved = firstNonNull;
|
|
44
69
|
}
|
|
45
70
|
const parserInstance = new parser_instance_js_1.ParserInstance(command, options);
|
|
@@ -71,7 +96,7 @@ async function parser(command, options) {
|
|
|
71
96
|
}
|
|
72
97
|
}
|
|
73
98
|
catch (err) {
|
|
74
|
-
let error = err;
|
|
99
|
+
let error = asParserError(err, command);
|
|
75
100
|
if (error.code === 'ParserErrorExchange' && error.parserContext && error.parserContext.value) {
|
|
76
101
|
return error.parserContext.value;
|
|
77
102
|
}
|
|
@@ -4,6 +4,7 @@ exports.ImapStream = void 0;
|
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
5
|
const logger_js_1 = require("../logger.js");
|
|
6
6
|
const limits_js_1 = require("./limits.js");
|
|
7
|
+
const errors_js_1 = require("../errors.js");
|
|
7
8
|
const LINE = 0x01;
|
|
8
9
|
const LITERAL = 0x02;
|
|
9
10
|
const LF = 0x0a;
|
|
@@ -180,10 +181,10 @@ class ImapStream extends node_stream_1.Transform {
|
|
|
180
181
|
if (lineLength <= this.maxLineLength) {
|
|
181
182
|
return true;
|
|
182
183
|
}
|
|
183
|
-
const err =
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
const err = (0, errors_js_1.createImapError)(`Line length ${lineLength} exceeds maximum allowed size of ${this.maxLineLength} bytes`, 'LineTooLarge', {
|
|
185
|
+
lineLength,
|
|
186
|
+
maxSize: this.maxLineLength
|
|
187
|
+
});
|
|
187
188
|
return this.failStream(err);
|
|
188
189
|
}
|
|
189
190
|
/**
|
|
@@ -206,10 +207,10 @@ class ImapStream extends node_stream_1.Transform {
|
|
|
206
207
|
}
|
|
207
208
|
return true;
|
|
208
209
|
}
|
|
209
|
-
const err =
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
const err = (0, errors_js_1.createImapError)(`Response size ${total} exceeds maximum allowed size of ${this.maxResponseSize} bytes`, 'ResponseTooLarge', {
|
|
211
|
+
responseSize: total,
|
|
212
|
+
maxSize: this.maxResponseSize
|
|
213
|
+
});
|
|
213
214
|
return this.failStream(err);
|
|
214
215
|
}
|
|
215
216
|
/**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// defaults in the ImapFlowOptions type describe both paths.
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createLiteralTooLargeError = exports.normalizeLimit = exports.boundedInput = exports.ERROR_CONTEXT_LENGTH = exports.MAX_RESPONSE_SIZE = exports.MAX_LINE_SIZE = exports.MAX_LITERAL_SIZE = void 0;
|
|
7
|
+
const errors_js_1 = require("../errors.js");
|
|
7
8
|
// Maximum allowed literal size: 1GB (1073741824 bytes)
|
|
8
9
|
exports.MAX_LITERAL_SIZE = 1024 * 1024 * 1024;
|
|
9
10
|
// Default maximum length of a single line (a response without a literal). Matches the literal cap:
|
|
@@ -56,11 +57,8 @@ exports.normalizeLimit = normalizeLimit;
|
|
|
56
57
|
* @param reason - What the bound was, when it is not the configured maximum.
|
|
57
58
|
* @returns The error to emit or throw.
|
|
58
59
|
*/
|
|
59
|
-
const createLiteralTooLargeError = (literalSize, maxSize, reason) => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
err.maxSize = maxSize;
|
|
64
|
-
return err;
|
|
65
|
-
};
|
|
60
|
+
const createLiteralTooLargeError = (literalSize, maxSize, reason) => (0, errors_js_1.createImapError)(`Literal size ${literalSize} exceeds ${reason || `maximum allowed size of ${maxSize} bytes`}`, 'LiteralTooLarge', {
|
|
61
|
+
literalSize,
|
|
62
|
+
maxSize
|
|
63
|
+
});
|
|
66
64
|
exports.createLiteralTooLargeError = createLiteralTooLargeError;
|
|
@@ -8,6 +8,7 @@ exports.ParserInstance = void 0;
|
|
|
8
8
|
const imap_formal_syntax_js_1 = __importDefault(require("./imap-formal-syntax.js"));
|
|
9
9
|
const token_parser_js_1 = require("./token-parser.js");
|
|
10
10
|
const limits_js_1 = require("./limits.js");
|
|
11
|
+
const errors_js_1 = require("../errors.js");
|
|
11
12
|
/**
|
|
12
13
|
* Parses a single IMAP response line into its structural components: tag, command,
|
|
13
14
|
* and attributes. Handles status responses (OK, NO, BAD, PREAUTH, BYE) with their
|
|
@@ -143,10 +144,7 @@ class ParserInstance {
|
|
|
143
144
|
async getElement(syntax) {
|
|
144
145
|
let match, element, errPos;
|
|
145
146
|
if (/^\s/.test(this.remainder)) {
|
|
146
|
-
|
|
147
|
-
error.code = 'ParserError1';
|
|
148
|
-
error.parserContext = this.errorContext();
|
|
149
|
-
throw error;
|
|
147
|
+
throw (0, errors_js_1.createImapError)(`Unexpected whitespace at position ${this.pos} [E1]`, 'ParserError1', { parserContext: this.errorContext() });
|
|
150
148
|
}
|
|
151
149
|
if ((match = this.remainder.match(/^\s*[^\s]+(?=\s|$)/))) {
|
|
152
150
|
element = match[0];
|
|
@@ -156,29 +154,24 @@ class ParserInstance {
|
|
|
156
154
|
// "Server Unavailable." instead of a proper IMAP tagged/untagged response.
|
|
157
155
|
// We detect this specific pattern and convert it into a synthetic BAD response
|
|
158
156
|
// so the rest of the parser can handle it gracefully.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
throw (0, errors_js_1.createImapError)(`Server returned an error: ${this.input}`, 'ParserErrorExchange', {
|
|
158
|
+
parserContext: {
|
|
159
|
+
...this.errorContext(element),
|
|
160
|
+
value: {
|
|
161
|
+
tag: '*',
|
|
162
|
+
command: 'BAD',
|
|
163
|
+
attributes: [{ type: 'TEXT', value: this.input }]
|
|
164
|
+
}
|
|
167
165
|
}
|
|
168
|
-
};
|
|
169
|
-
throw error;
|
|
166
|
+
});
|
|
170
167
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
throw error;
|
|
168
|
+
throw (0, errors_js_1.createImapError)(`Unexpected char at position ${this.pos + errPos} [E2: ${JSON.stringify(element.charAt(errPos))}]`, 'ParserError2', {
|
|
169
|
+
parserContext: this.errorContext(element)
|
|
170
|
+
});
|
|
175
171
|
}
|
|
176
172
|
}
|
|
177
173
|
else {
|
|
178
|
-
|
|
179
|
-
error.code = 'ParserError3';
|
|
180
|
-
error.parserContext = this.errorContext();
|
|
181
|
-
throw error;
|
|
174
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E3]`, 'ParserError3', { parserContext: this.errorContext() });
|
|
182
175
|
}
|
|
183
176
|
this.pos += match[0].length;
|
|
184
177
|
this.remainder = this.remainder.slice(match[0].length);
|
|
@@ -196,16 +189,12 @@ class ParserInstance {
|
|
|
196
189
|
// special case, empty + response
|
|
197
190
|
return;
|
|
198
191
|
}
|
|
199
|
-
|
|
200
|
-
error.code = 'ParserError4';
|
|
201
|
-
error.parserContext = this.errorContext();
|
|
202
|
-
throw error;
|
|
192
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E4]`, 'ParserError4', { parserContext: this.errorContext() });
|
|
203
193
|
}
|
|
204
194
|
if (imap_formal_syntax_js_1.default.verify(this.remainder.charAt(0), imap_formal_syntax_js_1.default.SP()) >= 0) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
throw error;
|
|
195
|
+
throw (0, errors_js_1.createImapError)(`Unexpected char at position ${this.pos} [E5: ${JSON.stringify(this.remainder.charAt(0))}]`, 'ParserError5', {
|
|
196
|
+
parserContext: this.errorContext(this.remainder)
|
|
197
|
+
});
|
|
209
198
|
}
|
|
210
199
|
this.pos++;
|
|
211
200
|
this.remainder = this.remainder.slice(1);
|
|
@@ -220,16 +209,12 @@ class ParserInstance {
|
|
|
220
209
|
*/
|
|
221
210
|
async getAttributes() {
|
|
222
211
|
if (!this.remainder.length) {
|
|
223
|
-
|
|
224
|
-
error.code = 'ParserError6';
|
|
225
|
-
error.parserContext = this.errorContext();
|
|
226
|
-
throw error;
|
|
212
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E6]`, 'ParserError6', { parserContext: this.errorContext() });
|
|
227
213
|
}
|
|
228
214
|
if (/^\s/.test(this.remainder)) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
throw error;
|
|
215
|
+
throw (0, errors_js_1.createImapError)(`Unexpected whitespace at position ${this.pos} [E7]`, 'ParserError7', {
|
|
216
|
+
parserContext: this.errorContext(this.remainder)
|
|
217
|
+
});
|
|
233
218
|
}
|
|
234
219
|
const tokenParser = new token_parser_js_1.TokenParser(this, this.pos, this.remainder, this.options);
|
|
235
220
|
return await tokenParser.getAttributes();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ImapFlowError, type ParserErrorCode } from '../errors.js';
|
|
1
2
|
import type { ImapAttributeList, ParserOptions } from './types.js';
|
|
2
3
|
import type { ParserInstance } from './parser-instance.js';
|
|
3
4
|
/**
|
|
@@ -58,6 +59,17 @@ export declare class TokenParser {
|
|
|
58
59
|
* from the input, i.e. when no pre-parsed literal buffers were supplied. Defaults to 1GB.
|
|
59
60
|
*/
|
|
60
61
|
constructor(parent: TokenParserParent | ParserInstance, startPos?: number | undefined, str?: string | null | undefined, options?: ParserOptions | undefined);
|
|
62
|
+
/**
|
|
63
|
+
* Builds a numbered parser error that carries a bounded copy of the input and the position
|
|
64
|
+
* (and character, when there is one) where parsing failed.
|
|
65
|
+
*
|
|
66
|
+
* @param message - The error message
|
|
67
|
+
* @param code - The numbered parser error code
|
|
68
|
+
* @param pos - Position of the failure in the original input
|
|
69
|
+
* @param chr - The offending character
|
|
70
|
+
* @returns The error to throw
|
|
71
|
+
*/
|
|
72
|
+
parserError(message: string, code: ParserErrorCode, pos: number, chr?: string | undefined): ImapFlowError;
|
|
61
73
|
/**
|
|
62
74
|
* Processes the input string and returns the parsed attributes as a flat array of typed objects.
|
|
63
75
|
* Each attribute is an object with a `type` (e.g., "ATOM", "STRING", "LITERAL", "SEQUENCE")
|