mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 00:07:01 +00:00
fix: stop crafted .eml headers from stalling the parser by moving to postal-mime 4.2
This commit is contained in:
Generated
+8
-5
@@ -34,7 +34,7 @@
|
||||
"expo-status-bar": "~3.0.9",
|
||||
"expo-web-browser": "~15.0.8",
|
||||
"jszip": "^3.10.1",
|
||||
"postal-mime": "^3.0.0",
|
||||
"postal-mime": "^4.2.0",
|
||||
"react": "19.1.0",
|
||||
"react-native": "0.81.5",
|
||||
"react-native-android-widget": "0.22.1",
|
||||
@@ -8940,10 +8940,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postal-mime": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-3.0.0.tgz",
|
||||
"integrity": "sha512-Z4a9ar2Bv3YpK3IXag+Yda30k7bMZfpRuUGyqtHnZ2pjHG8Bl62EhZIk4n1dzv00gfzP9g+94e9kd8+XmjVWLA==",
|
||||
"license": "MIT-0"
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postal-mime/-/postal-mime-4.2.0.tgz",
|
||||
"integrity": "sha512-QG5Rh8wY/zjwFF1lKWcBbwWcAWR5jWodmMPL4gMik43XDLebtWoAAPyG0lrE2kYYZ5IHTASrepGuGO0YIwNKAg==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.49",
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@
|
||||
"expo-status-bar": "~3.0.9",
|
||||
"expo-web-browser": "~15.0.8",
|
||||
"jszip": "^3.10.1",
|
||||
"postal-mime": "^3.0.0",
|
||||
"postal-mime": "^4.2.0",
|
||||
"react": "19.1.0",
|
||||
"react-native": "0.81.5",
|
||||
"react-native-android-widget": "0.22.1",
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
diff --git a/node_modules/postal-mime/src/base64-decoder.js b/node_modules/postal-mime/src/base64-decoder.js
|
||||
index 93c2aea..ba6e3f1 100644
|
||||
--- a/node_modules/postal-mime/src/base64-decoder.js
|
||||
+++ b/node_modules/postal-mime/src/base64-decoder.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { decodeBase64, blobToArrayBuffer } from './decode-strings.js';
|
||||
+import { decodeBase64, concatChunks } from './decode-strings.js';
|
||||
|
||||
export default class Base64Decoder {
|
||||
constructor(opts) {
|
||||
@@ -49,6 +49,6 @@ export default class Base64Decoder {
|
||||
finalize() {
|
||||
this.flushRemainder();
|
||||
|
||||
- return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return concatChunks(this.chunks);
|
||||
}
|
||||
}
|
||||
diff --git a/node_modules/postal-mime/src/decode-strings.js b/node_modules/postal-mime/src/decode-strings.js
|
||||
index a5e058e..f255e8d 100644
|
||||
--- a/node_modules/postal-mime/src/decode-strings.js
|
||||
+++ b/node_modules/postal-mime/src/decode-strings.js
|
||||
@@ -145,6 +145,23 @@ export function getDecoder(charset) {
|
||||
* @param {Blob} blob Blob to convert
|
||||
* @returns {ArrayBuffer} Converted value
|
||||
*/
|
||||
+// React Native's Blob cannot be built from ArrayBuffers or typed arrays, so
|
||||
+// the decoders join their chunks here instead of through a Blob.
|
||||
+export function concatChunks(chunks) {
|
||||
+ const parts = chunks.map(chunk => {
|
||||
+ if (typeof chunk === 'string') return textEncoder.encode(chunk);
|
||||
+ if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
|
||||
+ return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
||||
+ });
|
||||
+ const out = new Uint8Array(parts.reduce((n, part) => n + part.byteLength, 0));
|
||||
+ let pos = 0;
|
||||
+ for (const part of parts) {
|
||||
+ out.set(part, pos);
|
||||
+ pos += part.byteLength;
|
||||
+ }
|
||||
+ return out.buffer;
|
||||
+}
|
||||
+
|
||||
export async function blobToArrayBuffer(blob) {
|
||||
if ('arrayBuffer' in blob) {
|
||||
return await blob.arrayBuffer();
|
||||
diff --git a/node_modules/postal-mime/src/pass-through-decoder.js b/node_modules/postal-mime/src/pass-through-decoder.js
|
||||
index ad1c222..1e1d012 100644
|
||||
--- a/node_modules/postal-mime/src/pass-through-decoder.js
|
||||
+++ b/node_modules/postal-mime/src/pass-through-decoder.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { blobToArrayBuffer } from './decode-strings.js';
|
||||
+import { concatChunks } from './decode-strings.js';
|
||||
|
||||
export default class PassThroughDecoder {
|
||||
constructor() {
|
||||
@@ -12,6 +12,6 @@ export default class PassThroughDecoder {
|
||||
|
||||
finalize() {
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return concatChunks(this.chunks);
|
||||
}
|
||||
}
|
||||
diff --git a/node_modules/postal-mime/src/qp-decoder.js b/node_modules/postal-mime/src/qp-decoder.js
|
||||
index adee72c..3973673 100644
|
||||
--- a/node_modules/postal-mime/src/qp-decoder.js
|
||||
+++ b/node_modules/postal-mime/src/qp-decoder.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { blobToArrayBuffer, hexNibble } from './decode-strings.js';
|
||||
+import { concatChunks, hexNibble } from './decode-strings.js';
|
||||
|
||||
const CHR_EQUALS = 0x3d;
|
||||
const CHR_LF = 0x0a;
|
||||
@@ -83,6 +83,6 @@ export default class QPDecoder {
|
||||
this.flushBuffer();
|
||||
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return concatChunks(this.chunks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
diff --git a/node_modules/postal-mime/dist/cjs/chunk-writer.js b/node_modules/postal-mime/dist/cjs/chunk-writer.js
|
||||
index aac95eb..3425832 100644
|
||||
--- a/node_modules/postal-mime/dist/cjs/chunk-writer.js
|
||||
+++ b/node_modules/postal-mime/dist/cjs/chunk-writer.js
|
||||
@@ -57,7 +57,7 @@ class ChunkWriter {
|
||||
finalize() {
|
||||
this.flush();
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return (0, decode_strings_js_1.blobToArrayBuffer)(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return (0, decode_strings_js_1.concatChunks)(this.chunks);
|
||||
}
|
||||
}
|
||||
exports.default = ChunkWriter;
|
||||
diff --git a/node_modules/postal-mime/dist/cjs/decode-strings.js b/node_modules/postal-mime/dist/cjs/decode-strings.js
|
||||
index 40c59f6..74b0c41 100644
|
||||
--- a/node_modules/postal-mime/dist/cjs/decode-strings.js
|
||||
+++ b/node_modules/postal-mime/dist/cjs/decode-strings.js
|
||||
@@ -8,6 +8,7 @@ exports.decodeUtf8OrWindows1252 = decodeUtf8OrWindows1252;
|
||||
exports.decodeCharset = decodeCharset;
|
||||
exports.decodeText = decodeText;
|
||||
exports.blobToArrayBuffer = blobToArrayBuffer;
|
||||
+exports.concatChunks = concatChunks;
|
||||
exports.hexNibble = hexNibble;
|
||||
exports.foldLineBreaks = foldLineBreaks;
|
||||
exports.decodeWord = decodeWord;
|
||||
@@ -461,6 +462,22 @@ function decodeText(bytes, charset, html) {
|
||||
}
|
||||
return (decoder.encoding === 'x-user-defined' ? getDecoder('windows-1252') : decoder).decode(view);
|
||||
}
|
||||
+// React Native's Blob cannot be built from ArrayBuffers or typed arrays, so
|
||||
+// the decoders join their chunks here instead of through a Blob.
|
||||
+function concatChunks(chunks) {
|
||||
+ const parts = chunks.map(chunk => {
|
||||
+ if (typeof chunk === 'string') return exports.textEncoder.encode(chunk);
|
||||
+ if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
|
||||
+ return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
||||
+ });
|
||||
+ const out = new Uint8Array(parts.reduce((n, part) => n + part.byteLength, 0));
|
||||
+ let pos = 0;
|
||||
+ for (const part of parts) {
|
||||
+ out.set(part, pos);
|
||||
+ pos += part.byteLength;
|
||||
+ }
|
||||
+ return out.buffer;
|
||||
+}
|
||||
/**
|
||||
* Converts a Blob into an ArrayBuffer
|
||||
* @param blob Blob to convert
|
||||
diff --git a/node_modules/postal-mime/dist/cjs/pass-through-decoder.js b/node_modules/postal-mime/dist/cjs/pass-through-decoder.js
|
||||
index 755a1a7..d7f4ebc 100644
|
||||
--- a/node_modules/postal-mime/dist/cjs/pass-through-decoder.js
|
||||
+++ b/node_modules/postal-mime/dist/cjs/pass-through-decoder.js
|
||||
@@ -68,7 +68,7 @@ class PassThroughDecoder {
|
||||
}
|
||||
this.flushRun();
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return (0, decode_strings_js_1.blobToArrayBuffer)(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return (0, decode_strings_js_1.concatChunks)(this.chunks);
|
||||
}
|
||||
}
|
||||
exports.default = PassThroughDecoder;
|
||||
diff --git a/node_modules/postal-mime/dist/esm/chunk-writer.js b/node_modules/postal-mime/dist/esm/chunk-writer.js
|
||||
index eb22f8a..ceebace 100644
|
||||
--- a/node_modules/postal-mime/dist/esm/chunk-writer.js
|
||||
+++ b/node_modules/postal-mime/dist/esm/chunk-writer.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { blobToArrayBuffer } from './decode-strings.js';
|
||||
+import { concatChunks } from './decode-strings.js';
|
||||
/**
|
||||
* Collects decoded content in fixed size chunks, so memory follows the number of bytes
|
||||
* written rather than the number of writes. Decoders that write many short runs, such as
|
||||
@@ -55,7 +55,7 @@ export default class ChunkWriter {
|
||||
finalize() {
|
||||
this.flush();
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return concatChunks(this.chunks);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=chunk-writer.js.map
|
||||
\ No newline at end of file
|
||||
diff --git a/node_modules/postal-mime/dist/esm/decode-strings.js b/node_modules/postal-mime/dist/esm/decode-strings.js
|
||||
index 7108f8d..3dbd459 100644
|
||||
--- a/node_modules/postal-mime/dist/esm/decode-strings.js
|
||||
+++ b/node_modules/postal-mime/dist/esm/decode-strings.js
|
||||
@@ -443,6 +443,22 @@ export function decodeText(bytes, charset, html) {
|
||||
}
|
||||
return (decoder.encoding === 'x-user-defined' ? getDecoder('windows-1252') : decoder).decode(view);
|
||||
}
|
||||
+// React Native's Blob cannot be built from ArrayBuffers or typed arrays, so
|
||||
+// the decoders join their chunks here instead of through a Blob.
|
||||
+export function concatChunks(chunks) {
|
||||
+ const parts = chunks.map(chunk => {
|
||||
+ if (typeof chunk === 'string') return textEncoder.encode(chunk);
|
||||
+ if (chunk instanceof ArrayBuffer) return new Uint8Array(chunk);
|
||||
+ return new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
||||
+ });
|
||||
+ const out = new Uint8Array(parts.reduce((n, part) => n + part.byteLength, 0));
|
||||
+ let pos = 0;
|
||||
+ for (const part of parts) {
|
||||
+ out.set(part, pos);
|
||||
+ pos += part.byteLength;
|
||||
+ }
|
||||
+ return out.buffer;
|
||||
+}
|
||||
/**
|
||||
* Converts a Blob into an ArrayBuffer
|
||||
* @param blob Blob to convert
|
||||
diff --git a/node_modules/postal-mime/dist/esm/pass-through-decoder.js b/node_modules/postal-mime/dist/esm/pass-through-decoder.js
|
||||
index 4d493af..39e6ad5 100644
|
||||
--- a/node_modules/postal-mime/dist/esm/pass-through-decoder.js
|
||||
+++ b/node_modules/postal-mime/dist/esm/pass-through-decoder.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import { blobToArrayBuffer } from './decode-strings.js';
|
||||
+import { concatChunks } from './decode-strings.js';
|
||||
// Hands the body through as it is, the line endings included.
|
||||
//
|
||||
// The line break is written when the next line arrives, not after each line. The CRLF in
|
||||
@@ -66,7 +66,7 @@ export default class PassThroughDecoder {
|
||||
}
|
||||
this.flushRun();
|
||||
// convert an array of arraybuffers into a blob and then back into a single arraybuffer
|
||||
- return blobToArrayBuffer(new Blob(this.chunks, { type: 'application/octet-stream' }));
|
||||
+ return concatChunks(this.chunks);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=pass-through-decoder.js.map
|
||||
\ No newline at end of file
|
||||
@@ -4,7 +4,7 @@ import PostalMime from 'postal-mime';
|
||||
// React Native's Blob only takes strings and other Blobs; building one from an
|
||||
// ArrayBuffer or typed array throws. postal-mime used to join every decoded
|
||||
// part through such a Blob, so an .eml with an attachment could not be
|
||||
// previewed on the device (patches/postal-mime+3.0.0.patch).
|
||||
// previewed on the device (patches/postal-mime+4.2.0.patch).
|
||||
class ReactNativeBlob {
|
||||
constructor(parts: unknown[] = []) {
|
||||
if (parts.some((p) => p instanceof ArrayBuffer || ArrayBuffer.isView(p))) {
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
},
|
||||
{
|
||||
"name": "postal-mime",
|
||||
"version": "3.0.0",
|
||||
"version": "4.2.0",
|
||||
"license": "MIT-0",
|
||||
"url": "https://postal-mime.postalsys.com"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user