From 42bd71a3dc9204df68cc7c0fe983937497328391 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Thu, 15 Feb 2024 01:33:06 +0100 Subject: [PATCH] Add error status and check if too many bytes are received --- public/lang/en.json | 3 ++- public/scripts/network.js | 30 ++++++++++++++++++------------ public/scripts/ui.js | 14 +++++++++----- public/styles/styles-deferred.css | 10 +++++++--- public/styles/styles-main.css | 1 + 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/public/lang/en.json b/public/lang/en.json index f91af81..06ec120 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -185,6 +185,7 @@ "transferring": "Sending…", "receiving": "Receiving…", "transfer-complete": "Sent", - "receive-complete": "Received" + "receive-complete": "Received", + "error": "Error" } } diff --git a/public/scripts/network.js b/public/scripts/network.js index 03fe35f..9de6502 100644 --- a/public/scripts/network.js +++ b/public/scripts/network.js @@ -590,7 +590,7 @@ class Peer { } _abortTransfer() { - Events.fire('set-progress', {peerId: this._peerId, progress: 0, status: null}); + Events.fire('set-progress', {peerId: this._peerId, progress: 0, status: 'error'}); this._reset(); } @@ -847,23 +847,24 @@ class Peer { } _onChunkReceived(chunk) { - if(this._state !== Peer.STATE_RECEIVE_PROCEEDING || !this._digester || !(chunk.byteLength || chunk.size)) { + if (this._state !== Peer.STATE_RECEIVE_PROCEEDING || !this._digester || !chunk.byteLength) { this._sendState(); return; } - this._digester.unchunk(chunk); - - let progress = (this._totalBytesReceived + this._digester._bytesReceived) / this._acceptedRequest.totalSize; - - if (isNaN(progress)) progress = 1 - - if (progress > 1) { + try { + this._digester.unchunk(chunk); + } + catch (e) { this._abortTransfer(); - Logger.error("Too many bytes received. Abort!"); + Logger.error(e); return; } + let progress = this._digester + ? (this._totalBytesReceived + this._digester._bytesReceived) / this._acceptedRequest.totalSize + : 1; + Events.fire('set-progress', {peerId: this._peerId, progress: progress, status: 'receive'}); // occasionally notify sender about our progress @@ -1834,8 +1835,12 @@ class FileDigester { unchunk(chunk) { this._buffer.push(chunk); - this._bytesReceived += chunk.byteLength || chunk.size; - this._bytesReceivedSinceLastTime += chunk.byteLength || chunk.size; + this._bytesReceived += chunk.byteLength; + this._bytesReceivedSinceLastTime += chunk.byteLength; + + if (this._bytesReceived > this._size) { + throw new Error("Too many bytes received. Abort!"); + } // If more than half of maxBytesWithoutConfirmation received -> send confirmation if (2 * this._bytesReceivedSinceLastTime > this._maxBytesWithoutConfirmation) { @@ -1843,6 +1848,7 @@ class FileDigester { this._bytesReceivedSinceLastTime = 0; } + // File not completely received -> Wait for next chunk. if (this._bytesReceived < this._size) return; // We are done receiving. Preferably use a file worker to process the file to prevent exceeding of available RAM diff --git a/public/scripts/ui.js b/public/scripts/ui.js index c02537c..b5a755c 100644 --- a/public/scripts/ui.js +++ b/public/scripts/ui.js @@ -729,7 +729,8 @@ class PeerUI { this._progressQueue.unshift({progress: progress, status: status}); this.setProgress(0.5, status); return; - } else if (progressSpillsOverFull) { + } + else if (progressSpillsOverFull) { this._progressQueue.unshift({progress: progress, status: status}); this.setProgress(1, status); return; @@ -755,7 +756,8 @@ class PeerUI { this.$progress.classList.remove('animate'); this.$progress.classList.remove('over50'); this.$progress.classList.add('animate'); - } else if (this._currentProgress === 0.5) { + } + else if (this._currentProgress === 0.5) { this.$progress.classList.remove('animate'); this.$progress.classList.add('over50'); this.$progress.classList.add('animate'); @@ -763,7 +765,8 @@ class PeerUI { if (this._currentProgress < progress) { this.$progress.classList.add('animate'); - } else { + } + else { this.$progress.classList.remove('animate'); } @@ -800,14 +803,15 @@ class PeerUI { "process": Localization.getTranslation("peer-ui.processing"), "wait": Localization.getTranslation("peer-ui.waiting"), "transfer-complete": Localization.getTranslation("peer-ui.transfer-complete"), - "receive-complete": Localization.getTranslation("peer-ui.receive-complete") + "receive-complete": Localization.getTranslation("peer-ui.receive-complete"), + "error": Localization.getTranslation("peer-ui.error") }[status]; this.$el.setAttribute('status', status); this.$el.querySelector('.status').innerText = statusName; this._currentStatus = status; - if (status.indexOf("-complete") || status === "receive-complete") { + if (["transfer-complete", "receive-complete", "error"].includes(status)) { this.statusTimeout = setTimeout(() => { this.setProgress(0, null); }, 10000); diff --git a/public/styles/styles-deferred.css b/public/styles/styles-deferred.css index f7f4020..367b7a9 100644 --- a/public/styles/styles-deferred.css +++ b/public/styles/styles-deferred.css @@ -188,8 +188,8 @@ x-peer:not(.type-public-id) .highlight-room-public-id { display: none; } -x-peer:is(:not([status]), [status$=-complete]):hover, -x-peer:is(:not([status]), [status$=-complete]):focus { +x-peer:is(:not([status]), [status$=-complete], [status=error]):hover, +x-peer:is(:not([status]), [status$=-complete], [status=error]):focus { transform: scale(1.05); } @@ -249,7 +249,7 @@ x-peer[status] .device-name { display: none; } -x-peer[status]:not([status$=-complete]) { +x-peer[status]:not([status$=-complete]):not([status=error]) { pointer-events: none; } @@ -261,6 +261,10 @@ x-peer[status$=-complete] .status { color: var(--primary-color); } +x-peer[status=error] .status { + color: var(--error-color); +} + @keyframes pop { 0% { transform: scale(0.7); diff --git a/public/styles/styles-main.css b/public/styles/styles-main.css index b274bd6..6652014 100644 --- a/public/styles/styles-main.css +++ b/public/styles/styles-main.css @@ -921,6 +921,7 @@ x-peers:empty~x-instructions { body { /* Constant colors */ --primary-color: #4285f4; + --error-color: #ff6b6b; --paired-device-color: #00a69c; --public-room-color: #ed9d01; --accent-color: var(--primary-color);