Skip to content

Commit ab60b9e

Browse files
committed
rollback last changes
1 parent ab22adb commit ab60b9e

3 files changed

Lines changed: 70 additions & 75 deletions

File tree

lib/message-splitter.js

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,34 +39,6 @@ class MessageSplitter extends Transform {
3939
let groupstart = this.line ? -this.line.length : 0;
4040
let groupend = 0;
4141

42-
let checkTrailingLinebreak = data => {
43-
if (data.type === 'body' && data.node.parentNode && data.value && data.value.length) {
44-
if (data.value[data.value.length - 1] === 0x0a) {
45-
groupstart--;
46-
groupend--;
47-
pos--;
48-
if (data.value.length > 1 && data.value[data.value.length - 2] === 0x0d) {
49-
groupstart--;
50-
groupend--;
51-
pos--;
52-
if (groupstart < 0 && !this.line) {
53-
// store only <CR> as <LF> should be on the positive side
54-
this.line = Buffer.allocUnsafe(1);
55-
this.line[0] = 0x0d;
56-
}
57-
data.value = data.value.slice(0, data.value.length - 2);
58-
} else {
59-
data.value = data.value.slice(0, data.value.length - 1);
60-
}
61-
} else if (data.value[data.value.length - 1] === 0x0d) {
62-
groupstart--;
63-
groupend--;
64-
pos--;
65-
data.value = data.value.slice(0, data.value.length - 1);
66-
}
67-
}
68-
};
69-
7042
let iterateData = () => {
7143
for (let len = chunk.length; i < len; i++) {
7244
// find next <LF>
@@ -148,7 +120,6 @@ class MessageSplitter extends Transform {
148120
} else if (groupstart < 0) {
149121
groupstart = i;
150122
groupend = i;
151-
checkTrailingLinebreak(data);
152123
if (data.value && data.value.length) {
153124
this.push(data);
154125
}
@@ -166,11 +137,13 @@ class MessageSplitter extends Transform {
166137

167138
// skip last linebreak for body
168139
if (pos >= groupstart + 1 && group.type === 'body' && group.node.parentNode) {
169-
// do not include the last line ending for body
170-
if (chunk[pos - 1] === 0x0a) {
171-
pos--;
172-
if (pos >= groupstart && chunk[pos - 1] === 0x0d) {
140+
let boundary = this.checkBoundary(chunk.slice(pos));
141+
if (boundary) {
142+
if (chunk[pos - 1] === 0x0a) {
173143
pos--;
144+
if (pos >= groupstart && chunk[pos - 1] === 0x0d) {
145+
pos--;
146+
}
174147
}
175148
}
176149
}

test/message-splitter-test.js

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -451,64 +451,86 @@ module.exports['Split multipart message with embedded inline message/rfc88'] = t
451451
);
452452
};
453453

454-
module.exports['handles line break lines split into 2-byte chunks'] = test => {
454+
module.exports['handles line break lines split into n-byte chunks'] = async test => {
455455
const message = fs.readFileSync(__dirname + '/fixtures/original.txt');
456456

457457
const MAX_HEAD_SIZE = 2 * 1024 * 1024;
458-
const splitter = new MessageSplitter({
459-
ignoreEmbedded: true,
460-
maxHeadSize: MAX_HEAD_SIZE
461-
});
462-
463-
splitter.on('data', data => {
464-
switch (data.type) {
465-
case 'node':
466-
// node header block
467-
break;
468-
case 'data':
469-
// multipart message structure
470-
// this is not related to any specific 'node' block as it includes
471-
// everything between the end of some node body and between the next header
472-
console.log(JSON.stringify(data.value.toString()));
473-
break;
474-
case 'body':
475-
// Leaf element body. Includes the body for the last 'node' block. You might
476-
// have several 'body' calls for a single 'node' block
477-
console.log(JSON.stringify(data.value.toString()));
478-
// console.log(data.value.toString());
479-
break;
480-
}
481-
});
482458

483459
// Create a Transform stream that processes at most 2 bytes at a time
484-
class TwoByteChunker extends Transform {
460+
class NByteChunker extends Transform {
485461
constructor(options) {
486462
super(options);
463+
this.numOfBytes = options.numOfBytes || 2;
487464
}
488465

489466
_transform(chunk, encoding, callback) {
490-
// Process the chunk in 2-byte segments
491-
for (let i = 0; i < chunk.length; i += 2) {
492-
const twoByteChunk = chunk.slice(i, i + 2);
493-
// Push each 2-byte chunk to the output
494-
this.push(twoByteChunk);
495-
// console.log(`Processing chunk: ${JSON.stringify(twoByteChunk.toString())}`);
467+
// Process the chunk in n-byte segments
468+
for (let i = 0; i < chunk.length; i += this.numOfBytes) {
469+
const nByteChunk = chunk.slice(i, i + this.numOfBytes);
470+
// Push each n-byte chunk to the output
471+
this.push(nByteChunk);
496472
}
497473
callback();
498474
}
499475
}
500476

501-
// Create a source stream with some test data
502-
const source = Readable.from(message);
503-
504-
console.log(JSON.stringify(message.toString())); // Log raw message string for reference
505-
506-
// Pipe through our chunker
507-
const chunker = new TwoByteChunker();
477+
for (let i = 1; i <= 11; i++) {
478+
// 1 - 11 byte chunks
479+
const splitter = new MessageSplitter({
480+
ignoreEmbedded: true,
481+
maxHeadSize: MAX_HEAD_SIZE
482+
});
483+
484+
// Pipe through our chunker
485+
const chunker = new NByteChunker({ numOfBytes: i });
486+
487+
// Create a source stream with some test data
488+
const source = Readable.from(message);
489+
490+
source.pipe(chunker).pipe(splitter);
491+
492+
const collectedLines = [];
493+
494+
splitter.on('data', data => {
495+
switch (data.type) {
496+
case 'node':
497+
// node header block
498+
break;
499+
case 'data':
500+
// multipart message structure
501+
// this is not related to any specific 'node' block as it includes
502+
// everything between the end of some node body and between the next header
503+
collectedLines.push(JSON.stringify(data.value.toString()));
504+
break;
505+
case 'body':
506+
// Leaf element body. Includes the body for the last 'node' block. You might
507+
// have several 'body' calls for a single 'node' block
508+
collectedLines.push(JSON.stringify(data.value.toString()));
509+
break;
510+
}
511+
});
512+
513+
// eslint-disable-next-line no-await-in-loop
514+
await new Promise(resolve => {
515+
splitter.on('end', () => resolve());
516+
}); // Wait until splitter is done
517+
518+
for (const str of collectedLines) {
519+
// Check for lone \r or \n (without \r\n)
520+
test.equal(str.includes('\r') && !str.includes('\r\n'), false);
521+
test.equal(str.includes('\n') && !str.includes('\r\n'), false);
522+
523+
if (!str.includes('\r\n')) {
524+
// no CRLF
525+
test.equal(!str.includes('\r') && !str.includes('\r\n'), true);
526+
test.equal(!str.includes('\n') && !str.includes('\r\n'), true);
527+
continue;
528+
}
508529

509-
source.pipe(chunker).pipe(splitter);
530+
test.equal(str.includes('\r\n'), true); // has CRLF
531+
}
532+
}
510533

511-
test.expect(0);
512534
test.done();
513535
};
514536

test/rewriter-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ module.exports['Recreate message with large image one byte at a time'] = test =>
251251
output.on('end', () => {
252252
msgHash = msgHash.digest('hex');
253253

254-
test.equal(msgHash, '1b23ab848c9c6d2edba86e1d5a50bbf2');
254+
test.equal(msgHash, 'db6223cc3a59b840558b6f1817c9953d');
255255

256256
test.done();
257257
});

0 commit comments

Comments
 (0)