Skip to content

Commit b9282b9

Browse files
soldairalexeagle
authored andcommitted
fix: support realpath.native and fix crash in mkdirp
1 parent 172caff commit b9282b9

4 files changed

Lines changed: 99 additions & 26 deletions

File tree

internal/node/bazel_require_script.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,14 @@ exports.patcher = (fs = fs$1, root) => {
7272
}
7373
root = fs.realpathSync(root);
7474
const origRealpath = fs.realpath.bind(fs);
75+
const origRealpathNative = fs.realpath.native;
7576
const origLstat = fs.lstat.bind(fs);
7677
const origStat = fs.stat.bind(fs);
7778
const origStatSync = fs.statSync.bind(fs);
7879
const origReadlink = fs.readlink.bind(fs);
7980
const origLstatSync = fs.lstatSync.bind(fs);
8081
const origRealpathSync = fs.realpathSync.bind(fs);
82+
const origRealpathSyncNative = fs.realpathSync.native;
8183
const origReadlinkSync = fs.readlinkSync.bind(fs);
8284
const origReaddir = fs.readdir.bind(fs);
8385
const origReaddirSync = fs.readdirSync.bind(fs);
@@ -149,6 +151,24 @@ exports.patcher = (fs = fs$1, root) => {
149151
}
150152
origRealpath(...args);
151153
};
154+
fs.realpath.native =
155+
(...args) => {
156+
let cb = args.length > 1 ? args[args.length - 1] : undefined;
157+
if (cb) {
158+
cb = once(cb);
159+
args[args.length - 1] = (err, str) => {
160+
if (err)
161+
return cb(err);
162+
if (isEscape(str, args[0])) {
163+
cb(false, path.resolve(args[0]));
164+
}
165+
else {
166+
cb(false, str);
167+
}
168+
};
169+
}
170+
origRealpathNative(...args);
171+
};
152172
// tslint:disable-next-line:no-any
153173
fs.readlink = (...args) => {
154174
let cb = args.length > 1 ? args[args.length - 1] : undefined;
@@ -212,6 +232,14 @@ exports.patcher = (fs = fs$1, root) => {
212232
return str;
213233
};
214234
// tslint:disable-next-line:no-any
235+
fs.realpathSync = (...args) => {
236+
const str = origRealpathSyncNative(...args);
237+
if (isEscape(str, args[0])) {
238+
return path.resolve(args[0]);
239+
}
240+
return str;
241+
};
242+
// tslint:disable-next-line:no-any
215243
fs.readlinkSync = (...args) => {
216244
args[0] = path.resolve(args[0]);
217245
const str = path.resolve(path.dirname(args[0]), origReadlinkSync(...args));
@@ -431,7 +459,8 @@ exports.patcher = (fs = fs$1, root) => {
431459
// tslint:disable-next-line:no-any
432460
const promises = {};
433461
promises.lstat = util.promisify(fs.lstat);
434-
promises.realpath = util.promisify(fs.realpath);
462+
// NOTE: node core uses the newer realpath function fs.promises.native instead of fs.realPath
463+
promises.realpath = util.promisify(fs.realpath.native);
435464
promises.readlink = util.promisify(fs.readlink);
436465
promises.readdir = util.promisify(fs.readdir);
437466
if (fs.opendir)
@@ -516,7 +545,15 @@ exports.patcher = (requireScriptName, binDir) => {
516545
const nodeDir = path.join(binDir || dir, '_node_bin');
517546
if (!process.env.NP_PATCHED_NODEJS) {
518547
// TODO: WINDOWS.
519-
fs$1.mkdirSync(nodeDir, { recursive: true });
548+
try {
549+
fs$1.mkdirSync(nodeDir, { recursive: true });
550+
}
551+
catch (e) {
552+
// with node versions that don't have recursive mkdir this may throw an error.
553+
if (e.code !== 'EEXIST') {
554+
throw e;
555+
}
556+
}
520557
if (process.platform == 'win32') {
521558
fs$1.writeFileSync(path.join(nodeDir, 'node.bat'), `@if not defined DEBUG_HELPER @ECHO OFF
522559
set NP_PATCHED_NODEJS=${nodeDir}

packages/node-patches/BUILD.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ package(default_visibility = ["//:__subpackages__"])
2121
sources = glob([
2222
"*.ts",
2323
"src/*.ts",
24-
])
24+
],exclude=["**/*.d.ts"])
2525

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

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

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

packages/node-patches/src/fs.ts

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ export const patcher = (fs: any = _fs, root: string) => {
4242
root = fs.realpathSync(root);
4343

4444
const origRealpath = fs.realpath.bind(fs);
45+
const origRealpathNative = fs.realpath.native;
4546
const origLstat = fs.lstat.bind(fs);
4647
const origStat = fs.stat.bind(fs);
4748
const origStatSync = fs.statSync.bind(fs);
4849
const origReadlink = fs.readlink.bind(fs);
4950
const origLstatSync = fs.lstatSync.bind(fs);
5051
const origRealpathSync = fs.realpathSync.bind(fs);
52+
const origRealpathSyncNative = fs.realpathSync.native;
5153
const origReadlinkSync = fs.readlinkSync.bind(fs);
5254
const origReaddir = fs.readdir.bind(fs);
5355
const origReaddirSync = fs.readdirSync.bind(fs);
@@ -129,29 +131,46 @@ export const patcher = (fs: any = _fs, root: string) => {
129131
origRealpath(...args);
130132
};
131133

132-
// tslint:disable-next-line:no-any
133-
fs.readlink = (...args: any[]) => {
134-
let cb = args.length > 1 ? args[args.length - 1] : undefined;
135-
if (cb) {
136-
cb = once(cb);
137-
args[args.length - 1] = (err: Error, str: string) => {
138-
args[0] = path.resolve(args[0]);
139-
if (str) str = path.resolve(path.dirname(args[0]), str);
140-
141-
if (err) return cb(err);
134+
fs.realpath.native =
135+
(...args) => {
136+
let cb = args.length > 1 ? args[args.length - 1] : undefined;
137+
if (cb) {
138+
cb = once(cb);
139+
args[args.length - 1] = (err: Error, str: string) => {
140+
if (err) return cb(err);
141+
if (isEscape(str, args[0])) {
142+
cb(false, path.resolve(args[0]));
143+
} else {
144+
cb(false, str);
145+
}
146+
};
147+
}
148+
origRealpathNative(...args)
149+
}
142150

143-
if (isEscape(str, args[0])) {
144-
const e = new Error('EINVAL: invalid argument, readlink \'' + args[0] + '\'');
145-
// tslint:disable-next-line:no-any
146-
(e as any).code = 'EINVAL';
147-
// if its not supposed to be a link we have to trigger an EINVAL error.
148-
return cb(e);
151+
// tslint:disable-next-line:no-any
152+
fs.readlink = (...args: any[]) => {
153+
let cb = args.length > 1 ? args[args.length - 1] : undefined;
154+
if (cb) {
155+
cb = once(cb);
156+
args[args.length - 1] = (err: Error, str: string) => {
157+
args[0] = path.resolve(args[0]);
158+
if (str) str = path.resolve(path.dirname(args[0]), str);
159+
160+
if (err) return cb(err);
161+
162+
if (isEscape(str, args[0])) {
163+
const e = new Error('EINVAL: invalid argument, readlink \'' + args[0] + '\'');
164+
// tslint:disable-next-line:no-any
165+
(e as any).code = 'EINVAL';
166+
// if its not supposed to be a link we have to trigger an EINVAL error.
167+
return cb(e);
168+
}
169+
cb(false, str);
170+
};
149171
}
150-
cb(false, str);
172+
origReadlink(...args);
151173
};
152-
}
153-
origReadlink(...args);
154-
};
155174

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

214+
// tslint:disable-next-line:no-any
215+
fs.realpathSync = (...args: any[]) => {
216+
const str = origRealpathSyncNative(...args);
217+
if (isEscape(str, args[0])) {
218+
return path.resolve(args[0]);
219+
}
220+
return str;
221+
};
222+
195223
// tslint:disable-next-line:no-any
196224
fs.readlinkSync = (...args: any[]) => {
197225
args[0] = path.resolve(args[0]);
@@ -419,7 +447,8 @@ export const patcher = (fs: any = _fs, root: string) => {
419447
// tslint:disable-next-line:no-any
420448
const promises: any = {};
421449
promises.lstat = util.promisify(fs.lstat);
422-
promises.realpath = util.promisify(fs.realpath);
450+
// NOTE: node core uses the newer realpath function fs.promises.native instead of fs.realPath
451+
promises.realpath = util.promisify(fs.realpath.native);
423452
promises.readlink = util.promisify(fs.readlink);
424453
promises.readdir = util.promisify(fs.readdir);
425454
if (fs.opendir) promises.opendir = util.promisify(fs.opendir);

packages/node-patches/src/subprocess.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@ export const patcher = (requireScriptName: string, binDir?: string) => {
1111

1212
if (!process.env.NP_PATCHED_NODEJS) {
1313
// TODO: WINDOWS.
14-
fs.mkdirSync(nodeDir, {recursive: true});
14+
try {
15+
fs.mkdirSync(nodeDir, {recursive: true});
16+
} catch (e) {
17+
// with node versions that don't have recursive mkdir this may throw an error.
18+
if (e.code !== 'EEXIST') {
19+
throw e;
20+
}
21+
}
1522
if (process.platform == 'win32') {
1623
fs.writeFileSync(path.join(nodeDir, 'node.bat'), `@if not defined DEBUG_HELPER @ECHO OFF
1724
set NP_PATCHED_NODEJS=${nodeDir}

0 commit comments

Comments
 (0)