Skip to content

Commit 6d1960c

Browse files
committed
Merge branch 'main' into update_libcxx_libcxxabi_19
2 parents a5a76c3 + fb14f6d commit 6d1960c

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

src/library_fs.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,17 @@ FS.staticInit();
172172
// paths
173173
//
174174
lookupPath(path, opts = {}) {
175-
path = PATH_FS.resolve(path);
176-
177175
if (!path) return { path: '', node: null };
178176
opts.follow_mount ??= true
179177

178+
if (!PATH.isAbs(path)) {
179+
path = FS.cwd() + '/' + path;
180+
}
181+
180182
// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
181183
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
182184
// split the absolute path
183-
var parts = path.split('/').filter((p) => !!p);
185+
var parts = path.split('/').filter((p) => !!p && (p !== '.'));
184186

185187
// start at the root
186188
var current = FS.root;
@@ -193,6 +195,12 @@ FS.staticInit();
193195
break;
194196
}
195197

198+
if (parts[i] === '..') {
199+
current_path = PATH.dirname(current_path);
200+
current = current.parent;
201+
continue;
202+
}
203+
196204
current_path = PATH.join2(current_path, parts[i]);
197205
try {
198206
current = FS.lookupNode(current, parts[i]);
@@ -218,7 +226,10 @@ FS.staticInit();
218226
throw new FS.ErrnoError({{{ cDefs.ENOSYS }}});
219227
}
220228
var link = current.node_ops.readlink(current);
221-
path = PATH_FS.resolve(PATH.dirname(current_path), link, ...parts.slice(i + 1));
229+
if (!PATH.isAbs(link)) {
230+
link = PATH.dirname(current_path) + '/' + link;
231+
}
232+
path = link + '/' + parts.slice(i + 1).join('/');
222233
continue linkloop;
223234
}
224235
}
@@ -1045,7 +1056,6 @@ FS.staticInit();
10451056
if (typeof path == 'object') {
10461057
node = path;
10471058
} else {
1048-
path = PATH.normalize(path);
10491059
// noent_okay makes it so that if the final component of the path
10501060
// doesn't exist, lookupPath returns `node: undefined`. `path` will be
10511061
// updated to point to the target of all symlinks.

src/library_syscall.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ var SyscallsLibrary = {
3838
}
3939
return dir;
4040
}
41-
return PATH.join2(dir, path);
41+
return dir + '/' + path;
4242
},
4343

4444
doStat(func, path, buf) {
@@ -833,10 +833,6 @@ var SyscallsLibrary = {
833833
__syscall_mkdirat: (dirfd, path, mode) => {
834834
path = SYSCALLS.getStr(path);
835835
path = SYSCALLS.calculateAt(dirfd, path);
836-
// remove a trailing slash, if one - /a/b/ has basename of '', but
837-
// we want to create b in the context of this function
838-
path = PATH.normalize(path);
839-
if (path[path.length-1] === '/') path = path.substr(0, path.length-1);
840836
FS.mkdir(path, mode, 0);
841837
return 0;
842838
},
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <unistd.h>
2+
#include <fcntl.h>
3+
#include <fcntl.h>
4+
#include <unistd.h>
5+
#include <sys/stat.h>
6+
#include <assert.h>
7+
#include <stdio.h>
8+
#include <string.h>
9+
#if defined(__EMSCRIPTEN__)
10+
#include "emscripten.h"
11+
#endif
12+
13+
void makedir(const char *dir) {
14+
int rtn = mkdir(dir, 0777);
15+
assert(rtn == 0);
16+
}
17+
18+
void changedir(const char *dir) {
19+
int rtn = chdir(dir);
20+
assert(rtn == 0);
21+
}
22+
23+
static void create_file(const char *path) {
24+
printf("creating: %s\n", path);
25+
int fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0777);
26+
assert(fd >= 0);
27+
28+
close(fd);
29+
}
30+
31+
void setup() {
32+
#if defined(__EMSCRIPTEN__) && defined(NODEFS)
33+
makedir("working");
34+
EM_ASM(FS.mount(NODEFS, { root: '.' }, 'working'));
35+
changedir("working");
36+
#endif
37+
makedir("a");
38+
makedir("b");
39+
makedir("b/c");
40+
symlink("../b/c", "a/link");
41+
}
42+
43+
44+
int main() {
45+
setup();
46+
create_file("a/link/../x.txt");
47+
struct stat statBuf;
48+
assert(stat("a/link/../x.txt", &statBuf) == 0);
49+
assert(stat("b/x.txt", &statBuf) == 0);
50+
makedir("a/link/../d");
51+
assert(stat("a/link/../d", &statBuf) == 0);
52+
assert(stat("b/d", &statBuf) == 0);
53+
54+
assert(truncate("a/link/../x.txt", 0) == 0);
55+
assert(chmod("a/link/../x.txt", 0777) == 0);
56+
printf("success\n");
57+
}

test/test_core.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5781,6 +5781,8 @@ def test_fs_write(self):
57815781
def test_fs_emptyPath(self):
57825782
self.do_run_in_out_file_test('fs/test_emptyPath.c')
57835783

5784+
@no_windows('https://github.com/emscripten-core/emscripten/issues/8882')
5785+
@crossplatform
57845786
@also_with_noderawfs
57855787
def test_fs_enotdir(self):
57865788
self.do_run_in_out_file_test('fs/test_enotdir.c')
@@ -5874,6 +5876,20 @@ def test_fs_64bit(self):
58745876
self.set_setting('FORCE_FILESYSTEM')
58755877
self.do_runf('fs/test_64bit.c', 'success')
58765878

5879+
@requires_node
5880+
@parameterized({
5881+
'': ([],),
5882+
'nodefs': (['-DNODEFS', '-lnodefs.js'],),
5883+
'noderawfs': (['-sNODERAWFS'],),
5884+
})
5885+
def test_fs_symlink_resolution(self, args):
5886+
nodefs = '-DNODEFS' in args or '-sNODERAWFS' in args
5887+
if self.get_setting('WASMFS'):
5888+
if nodefs:
5889+
self.skipTest('NODEFS in WasmFS')
5890+
self.set_setting('FORCE_FILESYSTEM')
5891+
self.do_runf('fs/test_fs_symlink_resolution.c', 'success', emcc_args=args)
5892+
58775893
@parameterized({
58785894
'': ([],),
58795895
'nodefs': (['-DNODEFS', '-lnodefs.js'],),

test/wasmfs/wasmfs_mkdir.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,7 @@ int main() {
6666
// Try to make the root directory.
6767
errno = 0;
6868
mkdir("/", 0777);
69-
#ifdef WASMFS
7069
assert(errno == EEXIST);
71-
#else
72-
assert(errno == EINVAL);
73-
#endif
7470

7571
// Try to make a directory that exists already.
7672
errno = 0;

0 commit comments

Comments
 (0)