-
Notifications
You must be signed in to change notification settings - Fork 30.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
process: EnvGetter to use libuv #14641
process: EnvGetter to use libuv #14641
Conversation
Context: MSDN recommends checking for
|
Not ready yet, sorry |
src/node.cc
Outdated
// not found. | ||
if ((result > 0 || GetLastError() == ERROR_SUCCESS) && | ||
result < arraysize(buffer)) { | ||
// happen. If GetLastError() == ERROR_SUCCESS the variable was not found. |
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.
comment says "== ERROR_SUCCESS" and means "ERROR_ENVVAR_NOT_FOUND"
Is there any chance of this landing in the next 8.x release or even a 8.5.1? |
@refack FYI, there is a |
Facing this issue now. Did this get released yet? If so, which version? |
I am also facing this right now. Any updates? :) |
I'll pick this up again. |
6a02a6a
to
2968191
Compare
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.
Mostly LGTM. Does this still fix the referenced issue?
src/node.cc
Outdated
const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer); | ||
Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer); | ||
return info.GetReturnValue().Set(rc); | ||
char buffer[32767]; |
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.
Could you keep the comment about how this value was chosen?
src/node.cc
Outdated
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 || | ||
GetLastError() == ERROR_SUCCESS) { | ||
GetEnvironmentVariableW(key_ptr, nullptr, 0); | ||
if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) { |
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.
Is it safe to ignore the return value of GetEnvironmentVariableW
?
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.
That was the working assumption at the time. But I just missed this part of the patch, I want to use uv_os_getenv
here as well.
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.
uv_os_getenv()
will return UV_ENOENT
in this case instead of ERROR_ENVVAR_NOT_FOUND
.
src/node.cc
Outdated
Local<String> rc = String::NewFromTwoByte(isolate, two_byte_buffer); | ||
return info.GetReturnValue().Set(rc); | ||
char buffer[32767]; | ||
int ret = uv_os_getenv(*key, buffer, arraysize(buffer)); |
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.
Shouldn't the final argument just be sizeof(buffer)
?
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.
After reading the manual I figured it should be 🤦♂️
size_t buf_size = sizeof(buffer);
uv_os_getenv(*key, buffer, &buf_size);
src/node.cc
Outdated
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 || | ||
GetLastError() == ERROR_SUCCESS) { | ||
GetEnvironmentVariableW(key_ptr, nullptr, 0); | ||
if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) { |
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.
uv_os_getenv()
will return UV_ENOENT
in this case instead of ERROR_ENVVAR_NOT_FOUND
.
src/node.cc
Outdated
// On POSIX there is not explicitly defined size limit, but on Windows | ||
// environment variables have a maximum size limit of 2**15 - 1. | ||
char buffer[32768]; | ||
size_t buf_size = arraysize(buffer); |
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.
Still arraysize()
😄
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 thought I had woken up. Apparently not, so I need more coffee.
src/node.cc
Outdated
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); | ||
GetEnvironmentVariableW(key_ptr, nullptr, 0); | ||
if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) { | ||
// We are only interested in exsistance, so we can keep the buffer small. |
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.
exsistance -> existence
src/node.cc
Outdated
if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) { | ||
// We are only interested in exsistance, so we can keep the buffer small. | ||
char buffer[256]; | ||
size_t = sizeof(buffer); |
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.
Does this compile?
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.
Well obviously not (which means my way of locally compiling is broken. I was trying to not compile everything 'cause Windows)
c529f55
to
ead9c39
Compare
Fails 1 test on windows with: not ok 300 parallel/test-os
---
duration_ms: 0.147
severity: fail
stack: |-
assert.js:42
throw new errors.AssertionError({
^
AssertionError [ERR_ASSERTION]: '/temp' === '/tmp'
at Object.<anonymous> (c:\workspace\node-test-binary-windows\test\parallel\test-os.js:52:10)
at Module._compile (module.js:644:30)
at Object.Module._extensions..js (module.js:655:10)
at Module.load (module.js:563:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:685:10)
at startup (bootstrap_node.js:192:16)
at bootstrap_node.js:627:3
... |
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 || | ||
GetLastError() == ERROR_SUCCESS) { | ||
// We are only interested in existence, so we can keep the buffer small. | ||
char buffer[256]; |
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.
If you're only interested in existence, couldn't you go much smaller than 256?
CI: https://ci.nodejs.org/job/node-test-pull-request/11670/ So there may be a bug in the test, it's using an undefined behaviour to delete variables ( Lines 50 to 55 in 283b949
I'm wondering is we should fix the test, or turn env.VAR = '' into an actual env var deletion?
@cjihrig @nodejs/testing PTAL |
Can you explain why that is undefined behaviour? |
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.
Hm – what about setenv
? It would be nice to have consistency on that side as well, right?
It's
while the actual value (via WIN32 api is Line 897 in 088bba3
The bug behind this PR is that in some cases the value is stringified to |
I'll try to write a failing test |
Is there any reason that |
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.
Needs work and should be checked carefully for performance regressions.
// environment variables have a maximum size limit of 2**15 - 1. | ||
char buffer[32768]; | ||
size_t buf_size = sizeof(buffer); | ||
int ret = uv_os_getenv(*key, buffer, &buf_size); |
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.
You should retry with a bigger buffer when ret == UV_ENOBUFS
, otherwise you introduce an arbitrary size restriction on Unices that wasn't there before.
(And also, can you rename it to err
for consistency?)
char buffer[256]; | ||
size_t buf_size = sizeof(buffer); | ||
int ret = uv_os_getenv(*key, buffer, &buf_size); | ||
if (ret != UV_ENOENT) { |
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.
Reads uninitialized memory when ret == UV_ENOBUFS
(i.e., buffer too small.)
rc = 0; | ||
if (key_ptr[0] == L'=') { | ||
#ifdef _WIN32 | ||
if (key[0] == L'=') { |
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.
Just '='
, not L'='
.
Ping @refack |
Closing due to long inactivity. Please feel free to reopen. |
Fixes: #14593
Refs: Maximus5/ConEmu#1209
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
process