From 26d50b8e63f79e48652840a54567b059d1f73766 Mon Sep 17 00:00:00 2001 From: grant-kun Date: Thu, 13 Oct 2022 13:18:42 -0500 Subject: adding stuff --- src/quoted-printable.js | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/quoted-printable.js (limited to 'src/quoted-printable.js') diff --git a/src/quoted-printable.js b/src/quoted-printable.js new file mode 100644 index 0000000..87f2329 --- /dev/null +++ b/src/quoted-printable.js @@ -0,0 +1,153 @@ +/*! https://mths.be/quoted-printable v<%= version %> by @mathias | MIT license */ +;(function(root) { + + // Detect free variables `exports`. + var freeExports = typeof exports == 'object' && exports; + + // Detect free variable `module`. + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + + // Detect free variable `global`, from Node.js or Browserified code, and use + // it as `root`. + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + var decode = function(input) { + return input + // https://tools.ietf.org/html/rfc2045#section-6.7, rule 3: + // “Therefore, when decoding a `Quoted-Printable` body, any trailing white + // space on a line must be deleted, as it will necessarily have been added + // by intermediate transport agents.” + .replace(/[\t\x20]$/gm, '') + // Remove hard line breaks preceded by `=`. Proper `Quoted-Printable`- + // encoded data only contains CRLF line endings, but for compatibility + // reasons we support separate CR and LF too. + .replace(/=(?:\r\n?|\n|$)/g, '') + // Decode escape sequences of the form `=XX` where `XX` is any + // combination of two hexidecimal digits. For optimal compatibility, + // lowercase hexadecimal digits are supported as well. See + // https://tools.ietf.org/html/rfc2045#section-6.7, note 1. + .replace(/=([a-fA-F0-9]{2})/g, function($0, $1) { + var codePoint = parseInt($1, 16); + return stringFromCharCode(codePoint); + }); + }; + + var handleTrailingCharacters = function(string) { + return string + .replace(/\x20$/, '=20') // Handle trailing space. + .replace(/\t$/, '=09') // Handle trailing tab. + }; + + var regexUnsafeSymbols = /<%= unsafeSymbols %>/g; + var encode = function(string) { + + // Encode symbols that are definitely unsafe (i.e. unsafe in any context). + var encoded = string.replace(regexUnsafeSymbols, function(symbol) { + if (symbol > '\xFF') { + throw RangeError( + '`quotedPrintable.encode()` expects extended ASCII input only. ' + + 'Don\u2019t forget to encode the input first using a character ' + + 'encoding like UTF-8.' + ); + } + var codePoint = symbol.charCodeAt(0); + var hexadecimal = codePoint.toString(16).toUpperCase(); + return '=' + ('0' + hexadecimal).slice(-2); + }); + + // Limit lines to 76 characters (not counting the CRLF line endings). + var lines = encoded.split(/\r\n?|\n/g); + var lineIndex = -1; + var lineCount = lines.length; + var result = []; + while (++lineIndex < lineCount) { + var line = lines[lineIndex]; + // Leave room for the trailing `=` for soft line breaks. + var LINE_LENGTH = 75; + var index = 0; + var length = line.length; + while (index < length) { + var buffer = encoded.slice(index, index + LINE_LENGTH); + // If this line ends with `=`, optionally followed by a single uppercase + // hexadecimal digit, we broke an escape sequence in half. Fix it by + // moving these characters to the next line. + if (/=$/.test(buffer)) { + buffer = buffer.slice(0, LINE_LENGTH - 1); + index += LINE_LENGTH - 1; + } else if (/=[A-F0-9]$/.test(buffer)) { + buffer = buffer.slice(0, LINE_LENGTH - 2); + index += LINE_LENGTH - 2; + } else { + index += LINE_LENGTH; + } + result.push(buffer); + } + } + + // Encode space and tab characters at the end of encoded lines. Note that + // with the current implementation, this can only occur at the very end of + // the encoded string — every other line ends with `=` anyway. + var lastLineLength = buffer.length; + if (/[\t\x20]$/.test(buffer)) { + // There’s a space or a tab at the end of the last encoded line. Remove + // this line from the `result` array, as it needs to change. + result.pop(); + if (lastLineLength + 2 <= LINE_LENGTH + 1) { + // It’s possible to encode the character without exceeding the line + // length limit. + result.push( + handleTrailingCharacters(buffer) + ); + } else { + // It’s not possible to encode the character without exceeding the line + // length limit. Remvoe the character from the line, and insert a new + // line that contains only the encoded character. + result.push( + buffer.slice(0, lastLineLength - 1), + handleTrailingCharacters( + buffer.slice(lastLineLength - 1, lastLineLength) + ) + ); + } + } + + // `Quoted-Printable` uses CRLF. + return result.join('=\r\n'); + }; + + var quotedPrintable = { + 'encode': encode, + 'decode': decode, + 'version': '<%= version %>' + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define(function() { + return quotedPrintable; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+ + freeModule.exports = quotedPrintable; + } else { // in Narwhal or RingoJS v0.7.0- + for (var key in quotedPrintable) { + quotedPrintable.hasOwnProperty(key) && (freeExports[key] = quotedPrintable[key]); + } + } + } else { // in Rhino or a web browser + root.quotedPrintable = quotedPrintable; + } + +}(this)); -- cgit v1.2.3