-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix path resolution for symlinks #23072
base: main
Are you sure you want to change the base?
Conversation
If `/a/link` is a symlink to directory `/b/c` then `/a/link/..` should be resolved to `/b/c/..` which is `/b`. Currently, we cancel out `link/..` to get `/a`. The problem is that we apply `PATH_FS.resolve` and `PATH_FS.normalize` to paths. These functions cancel `..` incorrectly. This at least partially handles the situation. `lookupPath` is modified to avoid calls that call `PATH_FS.normalize()`. We check that `mkdir`, `open`, and `stat` now work correctly.
if (!dir.endsWith("/")) { | ||
dir += "/" | ||
} | ||
return dir + path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this different to the old code?
if nodefs: | ||
self.skipTest('NODEFS in WasmFS') | ||
self.set_setting('FORCE_FILESYSTEM') | ||
self.do_runf('fs/test_symlink_resolution.c', 'success', emcc_args=args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you name this file that same as the test (i.e. include the fs_
part)
|
||
assert(truncate("a/link/../x.txt", 0) == 0); | ||
assert(chmod("a/link/../x.txt", 0777) == 0); | ||
printf("success\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 space indentation.
@@ -826,7 +829,6 @@ var SyscallsLibrary = { | |||
path = SYSCALLS.calculateAt(dirfd, path); | |||
// remove a trailing slash, if one - /a/b/ has basename of '', but | |||
// we want to create b in the context of this function | |||
path = PATH.normalize(path); | |||
if (path[path.length-1] === '/') path = path.substr(0, path.length-1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this now be while
instead of if
to handle multiple tailing slashes?
@@ -192,6 +194,12 @@ FS.staticInit(); | |||
break; | |||
} | |||
|
|||
if (parts[i] === "..") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single quotes (here and elsewhere)
If
/a/link
is a symlink to directory/b/c
then/a/link/..
should be resolved to/b/c/..
which is/b
. Currently, we cancel outlink/..
to get/a
. The problem is that we applyPATH_FS.resolve
andPATH_FS.normalize
to paths. These functions cancel..
incorrectly.This at least partially handles the situation.
lookupPath
is modified to avoid calls that callPATH_FS.normalize()
. We check thatmkdir
,open
,stat
,truncate
, andchmod
now work correctly.