Skip to content

Commit febd44b

Browse files
authored
Use Node's path helpers under NODERAWFS (#17849)
Ensures that absolute paths are handled correctly on Windows as well. Using these helpers should be safe, since binaries linked with -sNODERAWFS can only be used on Node.js, see: emscripten/src/library_noderawfs.js Line 28 in e98554f throw new Error("NODERAWFS is currently only supported on Node.js environment.") Context: #16296 Resolves: #17360. Resolves: #17819. Supersedes: #17821.
1 parent 77f127e commit febd44b

File tree

6 files changed

+55
-6
lines changed

6 files changed

+55
-6
lines changed

src/library_async.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ mergeInto(LibraryManager.library, {
456456
return Asyncify.handleSleep((wakeUp) => {
457457
var _url = UTF8ToString(url);
458458
var _file = UTF8ToString(file);
459-
_file = PATH_FS.resolve(FS.cwd(), _file);
459+
_file = PATH_FS.resolve(_file);
460460
var destinationDirectory = PATH.dirname(_file);
461461
FS.createPreloadedFile(
462462
destinationDirectory,

src/library_fs.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ FS.staticInit();` +
119119
// paths
120120
//
121121
lookupPath: (path, opts = {}) => {
122-
path = PATH_FS.resolve(FS.cwd(), path);
122+
path = PATH_FS.resolve(path);
123123

124124
if (!path) return { path: '', node: null };
125125

@@ -133,8 +133,8 @@ FS.staticInit();` +
133133
throw new FS.ErrnoError({{{ cDefine('ELOOP') }}});
134134
}
135135

136-
// split the path
137-
var parts = PATH.normalizeArray(path.split('/').filter((p) => !!p), false);
136+
// split the absolute path
137+
var parts = path.split('/').filter((p) => !!p);
138138

139139
// start at the root
140140
var current = FS.root;

src/library_nodepath.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @license
3+
* Copyright 2022 The Emscripten Authors
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
// This implementation ensures that Windows-style paths are being
8+
// used when running on a Windows operating system - see:
9+
// https://nodejs.org/api/path.html#path_windows_vs_posix
10+
// It's only used/needed when linking with `-sNODERAWFS`, as that
11+
// will replace all normal filesystem access with direct Node.js
12+
// operations. Hence, using `nodePath` should be safe here.
13+
14+
mergeInto(LibraryManager.library, {
15+
$PATH: {
16+
isAbs: (path) => nodePath['isAbsolute'](path),
17+
normalize: (path) => nodePath['normalize'](path),
18+
dirname: (path) => nodePath['dirname'](path),
19+
basename: (path) => nodePath['basename'](path),
20+
join: function () {
21+
return nodePath['join'].apply(null, arguments);
22+
},
23+
join2: (l, r) => nodePath['join'](l, r),
24+
},
25+
// The FS-using parts are split out into a separate object, so simple path
26+
// usage does not require the FS.
27+
$PATH_FS__deps: ['$FS'],
28+
$PATH_FS__docs: '/** @type{{resolve: function(...*)}} */',
29+
$PATH_FS: {
30+
resolve: function () {
31+
var paths = Array.prototype.slice.call(arguments, 0);
32+
paths.unshift(FS.cwd());
33+
return nodePath['posix']['resolve'].apply(null, paths);
34+
},
35+
relative: (from, to) => nodePath['posix']['relative'](from || FS.cwd(), to || FS.cwd()),
36+
}
37+
});

src/modules.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ global.LibraryManager = {
9191
libraries.push('library_nodefs.js');
9292
}
9393
libraries.push('library_noderawfs.js');
94+
// NODERAWFS overwrites library_path.js
95+
libraries.push('library_nodepath.js');
9496
}
9597
} else if (WASMFS) {
9698
libraries.push('library_wasmfs.js');

src/settings.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -944,8 +944,7 @@ var FORCE_FILESYSTEM = false;
944944
// Node.js to access the real local filesystem on your OS, the code will not
945945
// necessarily be portable between OSes - it will be as portable as a Node.js
946946
// program would be, which means that differences in how the underlying OS
947-
// handles permissions and errors and so forth may be noticeable. This has
948-
// mostly been tested on Linux so far.
947+
// handles permissions and errors and so forth may be noticeable.
949948
// [link]
950949
var NODERAWFS = false;
951950

test/test_other.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8488,6 +8488,17 @@ def test_noderawfs_disables_embedding(self):
84888488
err = self.expect_fail(base + ['--embed-file', 'somefile'])
84898489
self.assertContained(expected, err)
84908490

8491+
def test_noderawfs_access_abspath(self):
8492+
create_file('foo', 'bar')
8493+
create_file('access.c', r'''
8494+
#include <unistd.h>
8495+
int main(int argc, char** argv) {
8496+
return access(argv[1], F_OK);
8497+
}
8498+
''')
8499+
self.run_process([EMCC, 'access.c', '-sNODERAWFS'])
8500+
self.run_js('a.out.js', args=[os.path.abspath('foo')])
8501+
84918502
@disabled('https://github.com/nodejs/node/issues/18265')
84928503
def test_node_code_caching(self):
84938504
self.run_process([EMCC, test_file('hello_world.c'),

0 commit comments

Comments
 (0)