summaryrefslogtreecommitdiff
path: root/lib/internal/fs/streams.js
diff options
context:
space:
mode:
authorptaylor <paul.e.taylor@me.com>2019-03-31 17:26:06 -0700
committerAnna Henningsen <anna@addaleax.net>2019-05-02 01:42:03 +0200
commitb884ceb518d5a63c1d5a85ca9b7e87b04e02ab4b (patch)
tree0c50a243a657979b90c4dc822e8917dcc6d396f4 /lib/internal/fs/streams.js
parentcaf9d3c1d040c0bfd99e063770ea4d5e9f961f88 (diff)
downloadandroid-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.js23
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) {