From f07402d234940740bbf2b34cc416131443a32346 Mon Sep 17 00:00:00 2001 From: Jaiwanth Date: Mon, 19 Jul 2021 13:17:19 +0530 Subject: [PATCH] Fix types and precompute blob sizes to avoid overflows --- src/components/views/messages/MImageBody.tsx | 2 +- src/utils/exportUtils/HtmlExport.tsx | 18 +++++++++++------- src/utils/exportUtils/JSONExport.ts | 12 +++++++----- src/utils/exportUtils/PlainTextExport.ts | 16 ++++++++++------ src/utils/exportUtils/ZipStream.ts | 4 ++-- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/components/views/messages/MImageBody.tsx b/src/components/views/messages/MImageBody.tsx index 7987ed007d..ee18046678 100644 --- a/src/components/views/messages/MImageBody.tsx +++ b/src/components/views/messages/MImageBody.tsx @@ -179,7 +179,7 @@ export default class MImageBody extends React.Component { }; protected getContentUrl(): string { - const content = this.props.mxEvent.getContent(); + const content: IMediaEventContent= this.props.mxEvent.getContent(); if (this.props.forExport) return content.url || content.file.url; const media = mediaFromContent(content); if (media.isEncrypted) { diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index 51ca9877bf..e545a32a17 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -306,13 +306,17 @@ export default class HTMLExporter extends Exporter { if (this.exportOptions.attachmentsIncluded) { try { const blob = await this.getMediaBlob(mxEv); - this.totalSize += blob.size; - const filePath = this.getFilePath(mxEv); - eventTile = await this.getEventTile(mxEv, joined, filePath); - if (this.totalSize > this.exportOptions.maxSize - 1024 * 512) { - this.exportOptions.attachmentsIncluded = false; + if (this.totalSize + blob.size > this.exportOptions.maxSize) { + eventTile = await this.getEventTile(this.createModifiedEvent(this.mediaOmitText, mxEv), joined); + } else { + this.totalSize += blob.size; + const filePath = this.getFilePath(mxEv); + eventTile = await this.getEventTile(mxEv, joined, filePath); + if (this.totalSize == this.exportOptions.maxSize) { + this.exportOptions.attachmentsIncluded = false; + } + this.addFile(filePath, blob); } - this.addFile(filePath, blob); } catch (e) { console.log("Error while fetching file" + e); eventTile = await this.getEventTile( @@ -339,7 +343,7 @@ export default class HTMLExporter extends Exporter { content += this._wantsDateSeparator(event, prevEvent) ? this.getDateSeparator(event) : ""; const shouldBeJoined = !this._wantsDateSeparator(event, prevEvent) - && shouldFormContinuation(prevEvent, event); + && shouldFormContinuation(prevEvent, event, false); const body = await this.createMessageBody(event, shouldBeJoined); this.totalSize += Buffer.byteLength(body); content += body; diff --git a/src/utils/exportUtils/JSONExport.ts b/src/utils/exportUtils/JSONExport.ts index ed42936787..417a7a40f4 100644 --- a/src/utils/exportUtils/JSONExport.ts +++ b/src/utils/exportUtils/JSONExport.ts @@ -45,11 +45,13 @@ export default class JSONExporter extends Exporter { if (this.exportOptions.attachmentsIncluded && this.isAttachment(mxEv)) { try { const blob = await this.getMediaBlob(mxEv); - this.totalSize += blob.size; - const filePath = this.getFilePath(mxEv); - this.addFile(filePath, blob); - if (this.totalSize > this.exportOptions.maxSize - 1024 * 1024) { - this.exportOptions.attachmentsIncluded = false; + if (this.totalSize + blob.size < this.exportOptions.maxSize) { + this.totalSize += blob.size; + const filePath = this.getFilePath(mxEv); + if (this.totalSize == this.exportOptions.maxSize) { + this.exportOptions.attachmentsIncluded = false; + } + this.addFile(filePath, blob); } } catch (err) { console.log("Error fetching file: " + err); diff --git a/src/utils/exportUtils/PlainTextExport.ts b/src/utils/exportUtils/PlainTextExport.ts index 109fa78162..00efab0f33 100644 --- a/src/utils/exportUtils/PlainTextExport.ts +++ b/src/utils/exportUtils/PlainTextExport.ts @@ -66,12 +66,16 @@ export default class PlainTextExporter extends Exporter { if (this.exportOptions.attachmentsIncluded) { try { const blob = await this.getMediaBlob(mxEv); - this.totalSize += blob.size; - const filePath = this.getFilePath(mxEv); - mediaText = " (" + _t("File Attached") + ")"; - this.addFile(filePath, blob); - if (this.totalSize > this.exportOptions.maxSize - 1024 * 1024) { - this.exportOptions.attachmentsIncluded = false; + if (this.totalSize + blob.size > this.exportOptions.maxSize) { + mediaText = ` (${this.mediaOmitText})`; + } else { + this.totalSize += blob.size; + const filePath = this.getFilePath(mxEv); + mediaText = " (" + _t("File Attached") + ")"; + this.addFile(filePath, blob); + if (this.totalSize == this.exportOptions.maxSize) { + this.exportOptions.attachmentsIncluded = false; + } } } catch (error) { mediaText = " (" + _t("Error fetching file") + ")"; diff --git a/src/utils/exportUtils/ZipStream.ts b/src/utils/exportUtils/ZipStream.ts index bf8020b7b6..2ee355f09c 100644 --- a/src/utils/exportUtils/ZipStream.ts +++ b/src/utils/exportUtils/ZipStream.ts @@ -223,8 +223,8 @@ export default function streamToZIP(underlyingSource: UnderlyingSource) { function closeZip() { let length = 0; let index = 0; - let indexFilename; - let file; + let indexFilename: number; + let file: any; for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { file = files[filenames[indexFilename]];