Skip to content

Commit

Permalink
fix: support realpath.native and fix crash in mkdirp
Browse files Browse the repository at this point in the history
  • Loading branch information
soldair authored and alexeagle committed Dec 4, 2019
1 parent 172caff commit b9282b9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 26 deletions.
41 changes: 39 additions & 2 deletions internal/node/bazel_require_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ exports.patcher = (fs = fs$1, root) => {
}
root = fs.realpathSync(root);
const origRealpath = fs.realpath.bind(fs);
const origRealpathNative = fs.realpath.native;
const origLstat = fs.lstat.bind(fs);
const origStat = fs.stat.bind(fs);
const origStatSync = fs.statSync.bind(fs);
const origReadlink = fs.readlink.bind(fs);
const origLstatSync = fs.lstatSync.bind(fs);
const origRealpathSync = fs.realpathSync.bind(fs);
const origRealpathSyncNative = fs.realpathSync.native;
const origReadlinkSync = fs.readlinkSync.bind(fs);
const origReaddir = fs.readdir.bind(fs);
const origReaddirSync = fs.readdirSync.bind(fs);
Expand Down Expand Up @@ -149,6 +151,24 @@ exports.patcher = (fs = fs$1, root) => {
}
origRealpath(...args);
};
fs.realpath.native =
(...args) => {
let cb = args.length > 1 ? args[args.length - 1] : undefined;
if (cb) {
cb = once(cb);
args[args.length - 1] = (err, str) => {
if (err)
return cb(err);
if (isEscape(str, args[0])) {
cb(false, path.resolve(args[0]));
}
else {
cb(false, str);
}
};
}
origRealpathNative(...args);
};
// tslint:disable-next-line:no-any
fs.readlink = (...args) => {
let cb = args.length > 1 ? args[args.length - 1] : undefined;
Expand Down Expand Up @@ -212,6 +232,14 @@ exports.patcher = (fs = fs$1, root) => {
return str;
};
// tslint:disable-next-line:no-any
fs.realpathSync = (...args) => {
const str = origRealpathSyncNative(...args);
if (isEscape(str, args[0])) {
return path.resolve(args[0]);
}
return str;
};
// tslint:disable-next-line:no-any
fs.readlinkSync = (...args) => {
args[0] = path.resolve(args[0]);
const str = path.resolve(path.dirname(args[0]), origReadlinkSync(...args));
Expand Down Expand Up @@ -431,7 +459,8 @@ exports.patcher = (fs = fs$1, root) => {
// tslint:disable-next-line:no-any
const promises = {};
promises.lstat = util.promisify(fs.lstat);
promises.realpath = util.promisify(fs.realpath);
// NOTE: node core uses the newer realpath function fs.promises.native instead of fs.realPath
promises.realpath = util.promisify(fs.realpath.native);
promises.readlink = util.promisify(fs.readlink);
promises.readdir = util.promisify(fs.readdir);
if (fs.opendir)
Expand Down Expand Up @@ -516,7 +545,15 @@ exports.patcher = (requireScriptName, binDir) => {
const nodeDir = path.join(binDir || dir, '_node_bin');
if (!process.env.NP_PATCHED_NODEJS) {
// TODO: WINDOWS.
fs$1.mkdirSync(nodeDir, { recursive: true });
try {
fs$1.mkdirSync(nodeDir, { recursive: true });
}
catch (e) {
// with node versions that don't have recursive mkdir this may throw an error.
if (e.code !== 'EEXIST') {
throw e;
}
}
if (process.platform == 'win32') {
fs$1.writeFileSync(path.join(nodeDir, 'node.bat'), `@if not defined DEBUG_HELPER @ECHO OFF
set NP_PATCHED_NODEJS=${nodeDir}
Expand Down
4 changes: 2 additions & 2 deletions packages/node-patches/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ package(default_visibility = ["//:__subpackages__"])
sources = glob([
"*.ts",
"src/*.ts",
])
],exclude=["**/*.d.ts"])

js = [s.replace(".ts", ".js") for s in sources]

tests = glob(["test/**/*.ts"])
tests = glob(["test/**/*.ts"],exclude=["**/*.d.ts"])

test_js = [t.replace(".ts", ".js") for t in tests]

Expand Down
71 changes: 50 additions & 21 deletions packages/node-patches/src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ export const patcher = (fs: any = _fs, root: string) => {
root = fs.realpathSync(root);

const origRealpath = fs.realpath.bind(fs);
const origRealpathNative = fs.realpath.native;
const origLstat = fs.lstat.bind(fs);
const origStat = fs.stat.bind(fs);
const origStatSync = fs.statSync.bind(fs);
const origReadlink = fs.readlink.bind(fs);
const origLstatSync = fs.lstatSync.bind(fs);
const origRealpathSync = fs.realpathSync.bind(fs);
const origRealpathSyncNative = fs.realpathSync.native;
const origReadlinkSync = fs.readlinkSync.bind(fs);
const origReaddir = fs.readdir.bind(fs);
const origReaddirSync = fs.readdirSync.bind(fs);
Expand Down Expand Up @@ -129,29 +131,46 @@ export const patcher = (fs: any = _fs, root: string) => {
origRealpath(...args);
};

// tslint:disable-next-line:no-any
fs.readlink = (...args: any[]) => {
let cb = args.length > 1 ? args[args.length - 1] : undefined;
if (cb) {
cb = once(cb);
args[args.length - 1] = (err: Error, str: string) => {
args[0] = path.resolve(args[0]);
if (str) str = path.resolve(path.dirname(args[0]), str);

if (err) return cb(err);
fs.realpath.native =
(...args) => {
let cb = args.length > 1 ? args[args.length - 1] : undefined;
if (cb) {
cb = once(cb);
args[args.length - 1] = (err: Error, str: string) => {
if (err) return cb(err);
if (isEscape(str, args[0])) {
cb(false, path.resolve(args[0]));
} else {
cb(false, str);
}
};
}
origRealpathNative(...args)
}

if (isEscape(str, args[0])) {
const e = new Error('EINVAL: invalid argument, readlink \'' + args[0] + '\'');
// tslint:disable-next-line:no-any
(e as any).code = 'EINVAL';
// if its not supposed to be a link we have to trigger an EINVAL error.
return cb(e);
// tslint:disable-next-line:no-any
fs.readlink = (...args: any[]) => {
let cb = args.length > 1 ? args[args.length - 1] : undefined;
if (cb) {
cb = once(cb);
args[args.length - 1] = (err: Error, str: string) => {
args[0] = path.resolve(args[0]);
if (str) str = path.resolve(path.dirname(args[0]), str);

if (err) return cb(err);

if (isEscape(str, args[0])) {
const e = new Error('EINVAL: invalid argument, readlink \'' + args[0] + '\'');
// tslint:disable-next-line:no-any
(e as any).code = 'EINVAL';
// if its not supposed to be a link we have to trigger an EINVAL error.
return cb(e);
}
cb(false, str);
};
}
cb(false, str);
origReadlink(...args);
};
}
origReadlink(...args);
};

// tslint:disable-next-line:no-any
fs.lstatSync = (...args: any[]) => {
Expand Down Expand Up @@ -192,6 +211,15 @@ export const patcher = (fs: any = _fs, root: string) => {
return str;
};

// tslint:disable-next-line:no-any
fs.realpathSync = (...args: any[]) => {
const str = origRealpathSyncNative(...args);
if (isEscape(str, args[0])) {
return path.resolve(args[0]);
}
return str;
};

// tslint:disable-next-line:no-any
fs.readlinkSync = (...args: any[]) => {
args[0] = path.resolve(args[0]);
Expand Down Expand Up @@ -419,7 +447,8 @@ export const patcher = (fs: any = _fs, root: string) => {
// tslint:disable-next-line:no-any
const promises: any = {};
promises.lstat = util.promisify(fs.lstat);
promises.realpath = util.promisify(fs.realpath);
// NOTE: node core uses the newer realpath function fs.promises.native instead of fs.realPath
promises.realpath = util.promisify(fs.realpath.native);
promises.readlink = util.promisify(fs.readlink);
promises.readdir = util.promisify(fs.readdir);
if (fs.opendir) promises.opendir = util.promisify(fs.opendir);
Expand Down
9 changes: 8 additions & 1 deletion packages/node-patches/src/subprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ export const patcher = (requireScriptName: string, binDir?: string) => {

if (!process.env.NP_PATCHED_NODEJS) {
// TODO: WINDOWS.
fs.mkdirSync(nodeDir, {recursive: true});
try {
fs.mkdirSync(nodeDir, {recursive: true});
} catch (e) {
// with node versions that don't have recursive mkdir this may throw an error.
if (e.code !== 'EEXIST') {
throw e;
}
}
if (process.platform == 'win32') {
fs.writeFileSync(path.join(nodeDir, 'node.bat'), `@if not defined DEBUG_HELPER @ECHO OFF
set NP_PATCHED_NODEJS=${nodeDir}
Expand Down

0 comments on commit b9282b9

Please sign in to comment.