mirror of
https://github.com/dawidd6/action-send-mail.git
synced 2026-10-09 18:04:08 +07:00
Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
109 lines
3.6 KiB
JavaScript
109 lines
3.6 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const node_stream_1 = require("node:stream");
|
|
// bytes inserted into the output, shared as they are only ever copied by Buffer.concat
|
|
const INSERT_LF = Buffer.from('\n');
|
|
const INSERT_LF_DOT = Buffer.from('\n.');
|
|
const INSERT_CR = Buffer.from('\r');
|
|
const INSERT_DOT = Buffer.from('.');
|
|
/**
|
|
* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
|
|
* Also makes sure that only <CR><LF> sequences are used for linebreaks, bare CR and bare LF
|
|
* are both turned into <CR><LF>
|
|
*
|
|
* @param options Stream options
|
|
*/
|
|
class DataStream extends node_stream_1.Transform {
|
|
constructor(options) {
|
|
super(options);
|
|
this.options = options || {};
|
|
this.inByteCount = 0;
|
|
this.outByteCount = 0;
|
|
this.lastByte = false;
|
|
}
|
|
/**
|
|
* Escapes dots
|
|
* @internal
|
|
*/
|
|
_transform(chunk, encoding, done) {
|
|
const chunks = [];
|
|
let chunklen = 0;
|
|
let i, len, lastPos = 0;
|
|
let buf;
|
|
if (!chunk || !chunk.length) {
|
|
return done();
|
|
}
|
|
if (typeof chunk === 'string') {
|
|
chunk = Buffer.from(chunk);
|
|
}
|
|
this.inByteCount += chunk.length;
|
|
for (i = 0, len = chunk.length; i < len; i++) {
|
|
const byte = chunk[i];
|
|
const prev = i ? chunk[i - 1] : this.lastByte;
|
|
let insert = false;
|
|
if (prev === 0x0d && byte !== 0x0a) {
|
|
// a bare CR becomes CRLF. A receiver that treats a lone CR as a line end would
|
|
// otherwise see "\r.\r" as the end of the data (SMTP smuggling), so a dot
|
|
// following it is stuffed like at the start of any other line
|
|
insert = byte === 0x2e ? INSERT_LF_DOT : INSERT_LF;
|
|
}
|
|
else if (byte === 0x0a && prev !== 0x0d) {
|
|
// a bare LF becomes CRLF
|
|
insert = INSERT_CR;
|
|
}
|
|
else if (byte === 0x2e && (prev === 0x0a || prev === false)) {
|
|
// a dot at the start of a line
|
|
insert = INSERT_DOT;
|
|
}
|
|
if (insert) {
|
|
if (i > lastPos) {
|
|
buf = chunk.slice(lastPos, i);
|
|
chunks.push(buf);
|
|
chunklen += buf.length;
|
|
}
|
|
chunks.push(insert);
|
|
chunklen += insert.length;
|
|
lastPos = i;
|
|
}
|
|
}
|
|
if (chunks.length) {
|
|
// add last piece
|
|
if (lastPos < chunk.length) {
|
|
buf = chunk.slice(lastPos);
|
|
chunks.push(buf);
|
|
chunklen += buf.length;
|
|
}
|
|
this.outByteCount += chunklen;
|
|
this.push(Buffer.concat(chunks, chunklen));
|
|
}
|
|
else {
|
|
this.outByteCount += chunk.length;
|
|
this.push(chunk);
|
|
}
|
|
this.lastByte = chunk[chunk.length - 1];
|
|
done();
|
|
}
|
|
/**
|
|
* Finalizes the stream with a dot on a single line
|
|
* @internal
|
|
*/
|
|
_flush(done) {
|
|
let buf;
|
|
if (this.lastByte === 0x0a) {
|
|
buf = Buffer.from('.\r\n');
|
|
}
|
|
else if (this.lastByte === 0x0d) {
|
|
buf = Buffer.from('\n.\r\n');
|
|
}
|
|
else {
|
|
buf = Buffer.from('\r\n.\r\n');
|
|
}
|
|
this.outByteCount += buf.length;
|
|
this.push(buf);
|
|
done();
|
|
}
|
|
}
|
|
exports.default = DataStream;
|
|
module.exports = exports.default;
|
|
Object.defineProperty(module.exports, 'default', { value: exports.default, enumerable: false, writable: true, configurable: true });
|