Comparing version 5.1.4 to 5.2.0
@@ -10,3 +10,3 @@ 'use strict'; | ||
const constants = require('constants'); | ||
const getPathParts = require('./filesystem.js').getPathParts; | ||
const {getPathParts, getRealPath} = require('./filesystem.js'); | ||
@@ -264,6 +264,4 @@ const MODE_TO_KTYPE = { | ||
if (process.platform === 'win32' && realPath.startsWith('\\\\?\\')) { | ||
// Remove win32 file namespace prefix \\?\ | ||
realPath = realPath.slice(4); | ||
} | ||
// Remove win32 file namespace prefix \\?\ | ||
realPath = getRealPath(realPath); | ||
@@ -1079,2 +1077,34 @@ if (encoding === 'buffer') { | ||
return maybeCallback(normalizeCallback(callback), ctx, this, function () { | ||
let filepath = deBuffer(pathname); | ||
let item = this._system.getItem(filepath); | ||
let links = 0; | ||
while (item instanceof SymbolicLink) { | ||
if (links > MAX_LINKS) { | ||
throw new FSError('ELOOP', filepath); | ||
} | ||
filepath = path.resolve(path.dirname(filepath), item.getPath()); | ||
item = this._system.getItem(filepath); | ||
++links; | ||
} | ||
if (!item) { | ||
throw new FSError('ENOENT', pathname); | ||
} | ||
item.setATime(new Date(atime * 1000)); | ||
item.setMTime(new Date(mtime * 1000)); | ||
}); | ||
}; | ||
/** | ||
* Update timestamps. | ||
* @param {string} pathname Path to item. | ||
* @param {number} atime Access time (in seconds). | ||
* @param {number} mtime Modification time (in seconds). | ||
* @param {function(Error)} callback Optional callback. | ||
* @param {object} ctx Context object (optional), only for nodejs v10+. | ||
* @return {*} The return if no callback is provided. | ||
*/ | ||
Binding.prototype.lutimes = function (pathname, atime, mtime, callback, ctx) { | ||
markSyscall(ctx, 'utimes'); | ||
return maybeCallback(normalizeCallback(callback), ctx, this, function () { | ||
pathname = deBuffer(pathname); | ||
@@ -1085,2 +1115,3 @@ const item = this._system.getItem(pathname); | ||
} | ||
// lutimes doesn't follow symlink | ||
item.setATime(new Date(atime * 1000)); | ||
@@ -1105,3 +1136,13 @@ item.setMTime(new Date(mtime * 1000)); | ||
const descriptor = this.getDescriptorById(fd); | ||
const item = descriptor.getItem(); | ||
let item = descriptor.getItem(); | ||
let filepath = this._system.getFilepath(item); | ||
let links = 0; | ||
while (item instanceof SymbolicLink) { | ||
if (links > MAX_LINKS) { | ||
throw new FSError('ELOOP', filepath); | ||
} | ||
filepath = path.resolve(path.dirname(filepath), item.getPath()); | ||
item = this._system.getItem(filepath); | ||
++links; | ||
} | ||
item.setATime(new Date(atime * 1000)); | ||
@@ -1292,16 +1333,11 @@ item.setMTime(new Date(mtime * 1000)); | ||
if (mode && process.getuid && process.getgid) { | ||
const itemMode = item.getMode(); | ||
if (item.getUid() === process.getuid()) { | ||
if ((itemMode & (mode * 64)) !== mode * 64) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
} else if (item.getGid() === process.getgid()) { | ||
if ((itemMode & (mode * 8)) !== mode * 8) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
} else { | ||
if ((itemMode & mode) !== mode) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
if (mode & constants.R_OK && !item.canRead()) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
if (mode & constants.W_OK && !item.canWrite()) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
if (mode & constants.X_OK && !item.canExecute()) { | ||
throw new FSError('EACCES', filepath); | ||
} | ||
} | ||
@@ -1308,0 +1344,0 @@ }); |
@@ -12,10 +12,15 @@ 'use strict'; | ||
function toNamespacedPath(filePath) { | ||
return path.toNamespacedPath | ||
? path.toNamespacedPath(filePath) | ||
: path._makeLong(filePath); | ||
// on Win32, change filepath from \\?\c:\a\b to C:\a\b | ||
function getRealPath(filepath) { | ||
if (isWindows && filepath.startsWith('\\\\?\\')) { | ||
// Remove win32 file namespace prefix \\?\ | ||
return filepath[4].toUpperCase() + filepath.slice(5); | ||
} | ||
return filepath; | ||
} | ||
function getPathParts(filepath) { | ||
const parts = toNamespacedPath(path.resolve(filepath)).split(path.sep); | ||
// path.toNamespacedPath is only for Win32 system. | ||
// on other platform, it returns the path unmodified. | ||
const parts = path.toNamespacedPath(path.resolve(filepath)).split(path.sep); | ||
parts.shift(); | ||
@@ -26,2 +31,4 @@ if (isWindows) { | ||
const q = parts.shift(); // should be '?' | ||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#win32-file-namespaces | ||
// Win32 File Namespaces prefix \\?\ | ||
const base = '\\\\' + q + '\\' + parts.shift().toLowerCase(); | ||
@@ -135,3 +142,32 @@ parts.unshift(base); | ||
function _getFilepath(item, itemPath, wanted) { | ||
if (item === wanted) { | ||
return itemPath; | ||
} | ||
if (item instanceof Directory) { | ||
for (const name of item.list()) { | ||
const got = _getFilepath( | ||
item.getItem(name), | ||
path.join(itemPath, name), | ||
wanted | ||
); | ||
if (got) { | ||
return got; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
/** | ||
* Get file path from a file system item. | ||
* @param {Item} item a file system item. | ||
* @return {string} file path for the item (or null if not found). | ||
*/ | ||
FileSystem.prototype.getFilepath = function (item) { | ||
const namespacedPath = _getFilepath(this._root, isWindows ? '' : '/', item); | ||
return getRealPath(namespacedPath); | ||
}; | ||
/** | ||
* Populate a directory with an item. | ||
@@ -335,2 +371,2 @@ * @param {Directory} directory The directory to populate. | ||
exports.getPathParts = getPathParts; | ||
exports.toNamespacedPath = toNamespacedPath; | ||
exports.getRealPath = getRealPath; |
@@ -16,4 +16,2 @@ 'use strict'; | ||
const toNamespacedPath = FileSystem.toNamespacedPath; | ||
const realProcessProps = { | ||
@@ -157,3 +155,3 @@ cwd: process.cwd, | ||
if (realBinding._mockedBinding) { | ||
if (!fs.statSync(toNamespacedPath(directory)).isDirectory()) { | ||
if (!fs.statSync(path.toNamespacedPath(directory)).isDirectory()) { | ||
throw new FSError('ENOTDIR'); | ||
@@ -160,0 +158,0 @@ } |
{ | ||
"name": "mock-fs", | ||
"description": "A configurable mock file system. You know, for testing.", | ||
"version": "5.1.4", | ||
"version": "5.2.0", | ||
"main": "lib/index.js", | ||
@@ -6,0 +6,0 @@ "homepage": "https://github.com/tschaub/mock-fs", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100556
2782