UNPKG

imapflow

Version:

IMAP Client for Node

190 lines (168 loc) 6.04 kB
/* eslint object-shorthand:0, new-cap: 0, no-useless-concat: 0 */ 'use strict'; /** * @module imap-formal-syntax * * Defines the IMAP formal syntax character classes and validation rules as specified * in RFC 3501 Section 9 (http://tools.ietf.org/html/rfc3501#section-9). * * Each exported method returns a string of allowed characters for a given IMAP grammar * production rule (e.g., ATOM-CHAR, ASTRING-CHAR, TEXT-CHAR). Results are memoized after * the first call by replacing the method with a function that returns the cached value. * * Also exports a {@link module:imap-formal-syntax.verify|verify} function for validating * strings against a set of allowed characters. */ /** * Generates a string containing all characters in the given Unicode code point range (inclusive). * * @param {number} start - The starting character code point. * @param {number} end - The ending character code point. * @returns {string} A string containing all characters from start to end. */ function expandRange(start, end) { let chars = []; for (let i = start; i <= end; i++) { chars.push(i); } return String.fromCharCode(...chars); } /** * Returns a new string with all characters from the exclude string removed from the source string. * * @param {string} source - The source string to filter. * @param {string} exclude - A string of characters to exclude from the source. * @returns {string} The source string with excluded characters removed. */ function excludeChars(source, exclude) { return Array.prototype.filter.call(source, ch => exclude.indexOf(ch) < 0).join(''); } module.exports = { /** @returns {string} All 7-bit US-ASCII characters excluding NUL (0x01-0x7F). */ CHAR() { let value = expandRange(0x01, 0x7f); this.CHAR = function () { return value; }; return value; }, /** @returns {string} All 8-bit characters excluding NUL (0x01-0xFF). */ CHAR8() { let value = expandRange(0x01, 0xff); this.CHAR8 = function () { return value; }; return value; }, /** @returns {string} The space character (0x20). */ SP() { return ' '; }, /** @returns {string} All control characters (0x00-0x1F and 0x7F). */ CTL() { let value = expandRange(0x00, 0x1f) + '\x7F'; this.CTL = function () { return value; }; return value; }, /** @returns {string} The double-quote character. */ DQUOTE() { return '"'; }, /** @returns {string} All uppercase and lowercase ASCII alphabetic characters (A-Z, a-z). */ ALPHA() { let value = expandRange(0x41, 0x5a) + expandRange(0x61, 0x7a); this.ALPHA = function () { return value; }; return value; }, /** @returns {string} All ASCII digit characters (0-9). */ DIGIT() { let value = expandRange(0x30, 0x39); this.DIGIT = function () { return value; }; return value; }, /** @returns {string} Characters allowed in an IMAP ATOM (CHAR minus atom-specials). */ 'ATOM-CHAR'() { let value = excludeChars(this.CHAR(), this['atom-specials']()); this['ATOM-CHAR'] = function () { return value; }; return value; }, /** @returns {string} Characters allowed in an IMAP ASTRING (ATOM-CHAR plus resp-specials). */ 'ASTRING-CHAR'() { let value = this['ATOM-CHAR']() + this['resp-specials'](); this['ASTRING-CHAR'] = function () { return value; }; return value; }, /** @returns {string} Characters allowed in IMAP text (CHAR minus CR and LF). */ 'TEXT-CHAR'() { let value = excludeChars(this.CHAR(), '\r\n'); this['TEXT-CHAR'] = function () { return value; }; return value; }, /** @returns {string} Characters that are special in ATOMs and must be excluded: "(", ")", "{", SP, CTL, list-wildcards, quoted-specials, resp-specials. */ 'atom-specials'() { let value = '(' + ')' + '{' + this.SP() + this.CTL() + this['list-wildcards']() + this['quoted-specials']() + this['resp-specials'](); this['atom-specials'] = function () { return value; }; return value; }, /** @returns {string} The LIST wildcard characters ("%" and "*"). */ 'list-wildcards'() { return '%' + '*'; }, /** @returns {string} Characters that are special inside quoted strings (DQUOTE and backslash). */ 'quoted-specials'() { let value = this.DQUOTE() + '\\'; this['quoted-specials'] = function () { return value; }; return value; }, /** @returns {string} The response-special character ("]"). */ 'resp-specials'() { return ']'; }, /** @returns {string} Characters allowed in an IMAP tag (ASTRING-CHAR minus "+"). */ tag() { let value = excludeChars(this['ASTRING-CHAR'](), '+'); this.tag = function () { return value; }; return value; }, /** @returns {string} Characters allowed in an IMAP command name (ALPHA, DIGIT, and hyphen). */ command() { let value = this.ALPHA() + this.DIGIT() + '-'; this.command = function () { return value; }; return value; }, /** * Verifies that every character in the given string is within the set of allowed characters. * * @param {string} str - The string to validate. * @param {string} allowedChars - A string containing all allowed characters. * @returns {number} The index of the first disallowed character, or -1 if all characters are valid. */ verify(str, allowedChars) { for (let i = 0, len = str.length; i < len; i++) { if (allowedChars.indexOf(str.charAt(i)) < 0) { return i; } } return -1; } };