fs: unguarded fs.watchFile cache statWatchers checking fixed
Use hasOwnProperty to check filepath cache; previous code could fail if a filepath duplicated a chained property name. Fixes #1637.
This commit is contained in:
parent
e58c036c27
commit
7dc2c492e9
10
lib/fs.js
10
lib/fs.js
@ -617,6 +617,9 @@ StatWatcher.prototype.stop = function() {
|
|||||||
|
|
||||||
|
|
||||||
var statWatchers = {};
|
var statWatchers = {};
|
||||||
|
function inStatWatchers(filename) {
|
||||||
|
return Object.prototype.hasOwnProperty.call(statWatchers, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fs.watchFile = function(filename) {
|
fs.watchFile = function(filename) {
|
||||||
@ -639,11 +642,10 @@ fs.watchFile = function(filename) {
|
|||||||
if (options.persistent === undefined) options.persistent = true;
|
if (options.persistent === undefined) options.persistent = true;
|
||||||
if (options.interval === undefined) options.interval = 0;
|
if (options.interval === undefined) options.interval = 0;
|
||||||
|
|
||||||
if (statWatchers[filename]) {
|
if (inStatWatchers(filename)) {
|
||||||
stat = statWatchers[filename];
|
stat = statWatchers[filename];
|
||||||
} else {
|
} else {
|
||||||
statWatchers[filename] = new StatWatcher();
|
stat = statWatchers[filename] = new StatWatcher();
|
||||||
stat = statWatchers[filename];
|
|
||||||
stat.start(filename, options.persistent, options.interval);
|
stat.start(filename, options.persistent, options.interval);
|
||||||
}
|
}
|
||||||
stat.addListener('change', listener);
|
stat.addListener('change', listener);
|
||||||
@ -652,7 +654,7 @@ fs.watchFile = function(filename) {
|
|||||||
|
|
||||||
fs.unwatchFile = function(filename) {
|
fs.unwatchFile = function(filename) {
|
||||||
var stat;
|
var stat;
|
||||||
if (statWatchers[filename]) {
|
if (inStatWatchers(filename)) {
|
||||||
stat = statWatchers[filename];
|
stat = statWatchers[filename];
|
||||||
stat.stop();
|
stat.stop();
|
||||||
statWatchers[filename] = undefined;
|
statWatchers[filename] = undefined;
|
||||||
|
@ -27,13 +27,33 @@ var assert = require('assert');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var watchSeenOne = 0;
|
||||||
|
var watchSeenTwo = 0;
|
||||||
|
|
||||||
var filename = path.join(common.fixturesDir, 'watch.txt');
|
var startDir = process.cwd();
|
||||||
fs.writeFileSync(filename, "hello");
|
var testDir = common.fixturesDir;
|
||||||
|
|
||||||
|
var filenameOne = 'watch.txt';
|
||||||
|
var filepathOne = path.join(testDir, filenameOne);
|
||||||
|
|
||||||
|
var filenameTwo = 'hasOwnProperty';
|
||||||
|
var filepathTwo = filenameTwo;
|
||||||
|
var filepathTwoAbs = path.join(testDir, filenameTwo);
|
||||||
|
|
||||||
|
|
||||||
|
process.addListener('exit', function() {
|
||||||
|
fs.unlinkSync(filepathOne);
|
||||||
|
fs.unlinkSync(filepathTwoAbs);
|
||||||
|
assert.equal(1, watchSeenOne);
|
||||||
|
assert.equal(1, watchSeenTwo);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
fs.writeFileSync(filepathOne, "hello");
|
||||||
|
|
||||||
assert.throws(
|
assert.throws(
|
||||||
function() {
|
function() {
|
||||||
fs.watchFile(filename);
|
fs.watchFile(filepathOne);
|
||||||
},
|
},
|
||||||
function(e) {
|
function(e) {
|
||||||
return e.message === 'watchFile requires a listener function';
|
return e.message === 'watchFile requires a listener function';
|
||||||
@ -42,14 +62,40 @@ assert.throws(
|
|||||||
|
|
||||||
assert.doesNotThrow(
|
assert.doesNotThrow(
|
||||||
function() {
|
function() {
|
||||||
fs.watchFile(filename, function(curr, prev) {
|
fs.watchFile(filepathOne, function(curr, prev) {
|
||||||
fs.unwatchFile(filename);
|
fs.unwatchFile(filepathOne);
|
||||||
fs.unlinkSync(filename);
|
++watchSeenOne;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
fs.writeFileSync(filename, "world");
|
fs.writeFileSync(filepathOne, "world");
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
process.chdir(testDir);
|
||||||
|
|
||||||
|
fs.writeFileSync(filepathTwoAbs, "howdy");
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
function() {
|
||||||
|
fs.watchFile(filepathTwo);
|
||||||
|
},
|
||||||
|
function(e) {
|
||||||
|
return e.message === 'watchFile requires a listener function';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.doesNotThrow(
|
||||||
|
function() {
|
||||||
|
fs.watchFile(filepathTwo, function(curr, prev) {
|
||||||
|
fs.unwatchFile(filepathTwo);
|
||||||
|
++watchSeenTwo;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
fs.writeFileSync(filepathTwoAbs, "pardner");
|
||||||
|
}, 1000);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user