Skip to content
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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hoodmane
Copy link
Contributor

@hoodmane hoodmane commented Dec 4, 2024

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, stat, truncate, and chmod now work correctly.

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;
Copy link
Collaborator

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)
Copy link
Collaborator

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");
Copy link
Collaborator

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);
Copy link
Collaborator

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] === "..") {
Copy link
Collaborator

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants