Skip to content

Commit c26d805

Browse files
authored
Fix mkdir("a/b/..") should return EEXIST (#23136)
Before this change `mkdir("a/b/..")` surprisingly makes a directory called `a/b/a`. It should raise EEXIST.
1 parent 978488b commit c26d805

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

src/library_fs.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ FS.staticInit();
182182
// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
183183
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
184184
// split the absolute path
185-
var parts = path.split('/').filter((p) => !!p && (p !== '.'));
185+
var parts = path.split('/').filter((p) => !!p);
186186

187187
// start at the root
188188
var current = FS.root;
@@ -195,6 +195,10 @@ FS.staticInit();
195195
break;
196196
}
197197

198+
if (parts[i] === '.') {
199+
continue;
200+
}
201+
198202
if (parts[i] === '..') {
199203
current_path = PATH.dirname(current_path);
200204
current = current.parent;
@@ -665,9 +669,12 @@ FS.staticInit();
665669
var lookup = FS.lookupPath(path, { parent: true });
666670
var parent = lookup.node;
667671
var name = PATH.basename(path);
668-
if (!name || name === '.' || name === '..') {
672+
if (!name) {
669673
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
670674
}
675+
if (name === '.' || name === '..') {
676+
throw new FS.ErrnoError({{{ cDefs.EEXIST }}});
677+
}
671678
var errCode = FS.mayCreate(parent, name);
672679
if (errCode) {
673680
throw new FS.ErrnoError(errCode);

test/fs/test_fs_mkdir_dotdot.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <sys/stat.h>
2+
#include <sys/types.h>
3+
#include <unistd.h>
4+
#include <sys/stat.h>
5+
#include <stdio.h>
6+
#include <fcntl.h>
7+
#include <errno.h>
8+
#include <string.h>
9+
#include <assert.h>
10+
11+
int main() {
12+
assert(mkdir("test", 0777) == 0);
13+
assert(mkdir("test/a", 0777) == 0);
14+
assert(mkdir("test/a/..", 0777) == -1);
15+
printf("error: %s\n", strerror(errno));
16+
assert(errno == EEXIST);
17+
assert(mkdir("test/a/.", 0777) == -1);
18+
printf("error: %s\n", strerror(errno));
19+
assert(errno == EEXIST);
20+
assert(mkdir("test/a/b/..", 0777) == -1);
21+
printf("error: %s\n", strerror(errno));
22+
assert(errno == ENOENT);
23+
assert(mkdir("test/a/b/.", 0777) == -1);
24+
printf("error: %s\n", strerror(errno));
25+
assert(errno == ENOENT);
26+
printf("success\n");
27+
}

test/test_core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5858,6 +5858,10 @@ def test_fs_rename_on_existing(self):
58585858
self.set_setting('FORCE_FILESYSTEM')
58595859
self.do_runf('fs/test_fs_rename_on_existing.c', 'success')
58605860

5861+
@also_with_nodefs_both
5862+
def test_fs_mkdir_dotdot(self):
5863+
self.do_runf('fs/test_fs_mkdir_dotdot.c', 'success')
5864+
58615865
def test_sigalrm(self):
58625866
self.do_runf('test_sigalrm.c', 'Received alarm!')
58635867
self.do_runf('test_sigalrm.c', 'Received alarm!', emcc_args=['-sEXIT_RUNTIME'])

0 commit comments

Comments
 (0)