-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
fs: fix long symlinks in realpath #7548
Conversation
size_t slash_count = 0; | ||
|
||
while ((offset = str_path.find('/', offset + 1)) != std::string::npos) { | ||
if (++slash_count < 32) { |
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.
Where does 32 come from?
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.
From @saghul's comment in #7175 (comment).
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.
I think having a comment here about why 32 was chosen might be helpful.
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.
heh. true.
@saghul There a reason you mentioned 32 in your comment?
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.
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.
oops. missed that. thanks.
Possible/reasonable to add one or more tests? |
/cc @jhamhader |
Comment in OP :-)
|
Heh...I got as far as "feedback" and stopped. Last mile problems. |
static size_t CountSlashes(const char* str, size_t len) { | ||
size_t cntr = 0; | ||
for (size_t i = 0; i < len; i++) { | ||
if (str[i] == '/') cntr++; |
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.
won't this be a problem on Windows? (I this code ever gets run there, that is)
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.
I couldn't see in any of the win calls of uv_fs_realpath()
that could return ERROR_CANT_RESOLVE_FILENAME
(mapped to UV_ELOOP
). Specifically those are CreateFileW()
and pGetFinalPathNameByHandleW()
. I just added a couple tests that will push up in a moment and run CI to check.
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.
@saghul So, seems I can get ELOOP
from windows. Working on that.
Updated and running CI: https://ci.nodejs.org/job/node-test-commit/3996/ |
Hm, the PR doesn't build properly on Windows. Looking into it. On all the
Not sure why that's failing for Windows and not any other box. From
Not sure what that's about. |
cc @nodejs/platform-windows ^^^ |
If you change macro call |
It's a thing with how msvc expands #define EXPAND(X) X
#define SYNC_CALL_NO_THROW(func, path, ...) \
EXPAND(SYNC_DEST_CALL_NO_THROW(func, path, nullptr, __VA_ARGS__)) |
@bzoz Thanks much for looking into this. Does make me curious why the use of EDIT: Ah yup. I see it now. Thanks for pointing this out. Missed that the macros could be simplified, which will solve the issue. |
Realized two things. 1) this doesn't address the async call (small oversight...) and 2) it can be made more reliable than it was before. Working on both. |
Updated w/ most of it, but going to forget the "more reliable" part for now. That's an enhancement for another PR. |
Compiling but now getting an issue with the resolved path on windows. Looking into it. EDIT: Looks like it may be from exceeding |
Path length fixed. |
req.oncomplete = pathResolver; | ||
binding.realpath(pathModule._makeLong(tmpPath), options.encoding, req); | ||
}(null, '')); | ||
} |
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.
Would it make more sense to do a single async call to ResolveRealPath
instead of mirroring the C++ code in JS?
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.
I agree. Reason I did it this way was because handling/passing the async resources was being a thorn at the time. I'll see about moving this into C++.
@nodejs/platform-windows Nm. Just noticed that it didn't fail b/c the test wasn't actually running... Can repro. |
Think I got it this time. |
@trevnorris Lots of failures. :/ |
@Fishrock123 Yeah. But Windows passed! Not sure if that's progress though... |
Another CI to help me understand what's going on: https://ci.nodejs.org/job/node-test-pull-request/3248/ |
@addaleax Heh. I'm somewhere between JS and C++ here. Thanks for the reminder what I'm actually coding. |
Here we go again. CI: https://ci.nodejs.org/job/node-test-pull-request/3250/ |
Btw… is there any reason for the path delimiter to be on |
@addaleax didn't want to run |
Just wondering if a |
Hah. That would in fact be better C++. Again failed on the context switch from a temporary implementation in JS using |
Yey! No related failures. Will clean up commits. |
Retrieving the error message along with the error name is useful. So exposing to the JS API. Extend the existing error messages to include more information about the invalid error code. Also add additional UV_ERRNO_MAX range check to ErrName() to help prevent the following comment from libuv documentation on both uv_strerror() and uv_err_name(): Leaks a few bytes of memory when you call it with an unknown error code.
realpath(3) would fail if the symbolic link depth was too deep. If ELOOP is encountered then resolve the path in parts until the entire thing is resolved. This excludes if the number of symbolic links is too deep, or if they are recursive. Fixes: nodejs#7175
The test/benchmarks included also work for the previous JS implementation of fs.realpath(). In case the new implementation of realpath() needs to be reverted, we want these changes to stick around.
@trevnorris ... should this one remain open given that it looks like we're reverting the impl back to the old js impl? |
@jasnell well, if it's going to take a full major release cycle before libuv is fixed and landed then yeah. probably. though i'd like to hope that it won't. |
Marking this as blocked for now then |
This has since been fixed by reverting to js realpath, closing. @trevnorris please let me know if closing this was in error |
Checklist
make -j4 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
fs, uv
Description of change
Fixes: #7175
This definitely isn't the prettiest code I've written. Want to get feedback while I finish up the tests.
R=@bnoordhuis
R=@saghul