diff options
author | ptaylor <paul.e.taylor@me.com> | 2019-03-31 17:26:06 -0700 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-05-02 01:42:03 +0200 |
commit | b884ceb518d5a63c1d5a85ca9b7e87b04e02ab4b (patch) | |
tree | 0c50a243a657979b90c4dc822e8917dcc6d396f4 /lib/internal/fs/streams.js | |
parent | caf9d3c1d040c0bfd99e063770ea4d5e9f961f88 (diff) | |
download | android-node-v8-b884ceb518d5a63c1d5a85ca9b7e87b04e02ab4b.tar.gz android-node-v8-b884ceb518d5a63c1d5a85ca9b7e87b04e02ab4b.tar.bz2 android-node-v8-b884ceb518d5a63c1d5a85ca9b7e87b04e02ab4b.zip |
fs: align fs.ReadStream buffer pool writes to 8-byte boundary
Prevents alignment issues when creating a typed array from a buffer.
Fixes: https://github.com/nodejs/node/issues/24817
PR-URL: https://github.com/nodejs/node/pull/24838
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'lib/internal/fs/streams.js')
-rw-r--r-- | lib/internal/fs/streams.js | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index 97a8856797..dfff08dbbd 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -51,6 +51,10 @@ function checkPosition(pos, name) { } } +function roundUpToMultipleOf8(n) { + return (n + 7) & ~7; // Align to 8 byte boundary. +} + function ReadStream(path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); @@ -172,10 +176,18 @@ ReadStream.prototype._read = function(n) { // Now that we know how much data we have actually read, re-wind the // 'used' field if we can, and otherwise allow the remainder of our // reservation to be used as a new pool later. - if (start + toRead === thisPool.used && thisPool === pool) - thisPool.used += bytesRead - toRead; - else if (toRead - bytesRead > kMinPoolSpace) - poolFragments.push(thisPool.slice(start + bytesRead, start + toRead)); + if (start + toRead === thisPool.used && thisPool === pool) { + const newUsed = thisPool.used + bytesRead - toRead; + thisPool.used = roundUpToMultipleOf8(newUsed); + } else { + // Round down to the next lowest multiple of 8 to ensure the new pool + // fragment start and end positions are aligned to an 8 byte boundary. + const alignedEnd = (start + toRead) & ~7; + const alignedStart = roundUpToMultipleOf8(start + bytesRead); + if (alignedEnd - alignedStart >= kMinPoolSpace) { + poolFragments.push(thisPool.slice(alignedStart, alignedEnd)); + } + } if (bytesRead > 0) { this.bytesRead += bytesRead; @@ -189,7 +201,8 @@ ReadStream.prototype._read = function(n) { // Move the pool positions, and internal position for reading. if (this.pos !== undefined) this.pos += toRead; - pool.used += toRead; + + pool.used = roundUpToMultipleOf8(pool.used + toRead); }; ReadStream.prototype._destroy = function(err, cb) { |