fs: ensure readFile[Sync] reads from the beginning
It would previously read from the current file position, which can be non-zero if the `fd` has been read from or written to. This contradicts the documentation which states that it "reads the entire contents of a file". PR-URL: https://github.com/nodejs/node/pull/9699 Fixes: https://github.com/nodejs/node/issues/9671 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
This commit is contained in:
parent
f18b4632b9
commit
4444e731f2
10
lib/fs.js
10
lib/fs.js
@ -310,7 +310,7 @@ ReadFileContext.prototype.read = function() {
|
||||
req.oncomplete = readFileAfterRead;
|
||||
req.context = this;
|
||||
|
||||
binding.read(this.fd, buffer, offset, length, -1, req);
|
||||
binding.read(this.fd, buffer, offset, length, this.pos, req);
|
||||
};
|
||||
|
||||
ReadFileContext.prototype.close = function(err) {
|
||||
@ -447,11 +447,11 @@ function tryCreateBuffer(size, fd, isUserFd) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function tryReadSync(fd, isUserFd, buffer, pos, len) {
|
||||
function tryReadSync(fd, isUserFd, buffer, pos, len, offset) {
|
||||
var threw = true;
|
||||
var bytesRead;
|
||||
try {
|
||||
bytesRead = fs.readSync(fd, buffer, pos, len);
|
||||
bytesRead = fs.readSync(fd, buffer, pos, len, offset);
|
||||
threw = false;
|
||||
} finally {
|
||||
if (threw && !isUserFd) fs.closeSync(fd);
|
||||
@ -480,7 +480,7 @@ fs.readFileSync = function(path, options) {
|
||||
|
||||
if (size !== 0) {
|
||||
do {
|
||||
bytesRead = tryReadSync(fd, isUserFd, buffer, pos, size - pos);
|
||||
bytesRead = tryReadSync(fd, isUserFd, buffer, pos, size - pos, pos);
|
||||
pos += bytesRead;
|
||||
} while (bytesRead !== 0 && pos < size);
|
||||
} else {
|
||||
@ -488,7 +488,7 @@ fs.readFileSync = function(path, options) {
|
||||
// the kernel lies about many files.
|
||||
// Go ahead and try to read some bytes.
|
||||
buffer = Buffer.allocUnsafe(8192);
|
||||
bytesRead = tryReadSync(fd, isUserFd, buffer, 0, 8192);
|
||||
bytesRead = tryReadSync(fd, isUserFd, buffer, 0, 8192, pos);
|
||||
if (bytesRead !== 0) {
|
||||
buffers.push(buffer.slice(0, bytesRead));
|
||||
}
|
||||
|
23
test/parallel/test-fs-readfile-fd-offset.js
Normal file
23
test/parallel/test-fs-readfile-fd-offset.js
Normal file
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const filename = path.join(common.tmpDir, 'readfile.txt');
|
||||
const dataExpected = 'a'.repeat(100);
|
||||
fs.writeFileSync(filename, dataExpected);
|
||||
const fileLength = dataExpected.length;
|
||||
|
||||
['r', 'a+'].forEach((mode) => {
|
||||
const fd = fs.openSync(filename, mode);
|
||||
assert.strictEqual(fs.readFileSync(fd).length, fileLength);
|
||||
|
||||
// Reading again should result in the same length.
|
||||
assert.strictEqual(fs.readFileSync(fd).length, fileLength);
|
||||
|
||||
fs.readFile(fd, common.mustCall((err, buf) => {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(buf.length, fileLength);
|
||||
}));
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user