From bcc6cc5bcadb20005ae03c8c4a4eb87006f0d222 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 25 Mar 2019 16:30:28 +0800 Subject: js: Allow serving files > 4GB in size Currently, the javascript NBD server only handles files of sizes that are representable in 32 bits. Although we can't do full 64-bit offsets with Javascript's number representation, we should be able to handle up to Number.MAX_SAFE_INTEGER. This change adds support for using the top-32 bit field in file sizes and read request offsets. Reported-by: Lei YU Signed-off-by: Jeremy Kerr Change-Id: I41dee58c3913cba49c5cd73ebdd5d6fb56786d25 --- web/js/nbd.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'web') diff --git a/web/js/nbd.js b/web/js/nbd.js index 1de4d3b..b58d9aa 100644 --- a/web/js/nbd.js +++ b/web/js/nbd.js @@ -195,9 +195,10 @@ function NBDServer(endpoint, file) n += 124; var resp = new ArrayBuffer(n); var view = new DataView(resp, 0, 10); - /* export size. todo: 64 bits? */ - view.setUint32(0, 0); - view.setUint32(4, this.file.size & 0xffffffff); + /* export size. */ + var size = this.file.size; + view.setUint32(0, Math.floor(size / (2**32))); + view.setUint32(4, size & 0xffffffff); /* transmission flags: read-only */ view.setUint16(8, NBD_FLAG_HAS_FLAGS | NBD_FLAG_READ_ONLY); this.ws.send(resp); @@ -305,17 +306,23 @@ function NBDServer(endpoint, file) this._handle_cmd_read = function(req) { - if (req.offset_msB) + var offset; + + offset = (req.offset_msB * 2**32) + req.offset_lsB; + + if (offset > Number.MAX_SAFE_INTEGER) + return ENOSPC; + + if (offset + req.length > Number.MAX_SAFE_INTEGER) return ENOSPC; - if (req.offset_lsB + req.length > file.size) + if (offset + req.length > file.size) return ENOSPC; this._log("read: 0x" + req.length.toString(16) + - " bytes, offset 0x" + req.offset_lsB.toString(16)); + " bytes, offset 0x" + offset.toString(16)); - var blob = this.file.slice(req.offset_lsB, - req.offset_lsB + req.length); + var blob = this.file.slice(offset, offset + req.length); var reader = new FileReader(); reader.onload = (function(ev) { -- cgit v1.2.3