windows: fix memory leak in WinapiErrnoException

Fix https://github.com/joyent/node/issues/2341

Reviewed-By: Fedor Indutny <fedor@indutny.com>
This commit is contained in:
Alexis Campailla 2014-08-05 15:33:16 +02:00 committed by Fedor Indutny
parent 6ea5d16731
commit 93f3b640d0

View File

@ -833,7 +833,7 @@ Local<Value> UVException(Isolate* isolate,
#ifdef _WIN32 #ifdef _WIN32
// Does about the same as strerror(), // Does about the same as strerror(),
// but supports all windows error messages // but supports all windows error messages
static const char *winapi_strerror(const int errorno) { static const char *winapi_strerror(const int errorno, bool* must_free) {
char *errmsg = NULL; char *errmsg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
@ -841,6 +841,8 @@ static const char *winapi_strerror(const int errorno) {
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL); MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL);
if (errmsg) { if (errmsg) {
*must_free = true;
// Remove trailing newlines // Remove trailing newlines
for (int i = strlen(errmsg) - 1; for (int i = strlen(errmsg) - 1;
i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) { i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) {
@ -850,6 +852,7 @@ static const char *winapi_strerror(const int errorno) {
return errmsg; return errmsg;
} else { } else {
// FormatMessage failed // FormatMessage failed
*must_free = false;
return "Unknown error"; return "Unknown error";
} }
} }
@ -862,8 +865,9 @@ Local<Value> WinapiErrnoException(Isolate* isolate,
const char* path) { const char* path) {
Environment* env = Environment::GetCurrent(isolate); Environment* env = Environment::GetCurrent(isolate);
Local<Value> e; Local<Value> e;
bool must_free = false;
if (!msg || !msg[0]) { if (!msg || !msg[0]) {
msg = winapi_strerror(errorno); msg = winapi_strerror(errorno, &must_free);
} }
Local<String> message = OneByteString(env->isolate(), msg); Local<String> message = OneByteString(env->isolate(), msg);
@ -890,6 +894,9 @@ Local<Value> WinapiErrnoException(Isolate* isolate,
obj->Set(env->syscall_string(), OneByteString(isolate, syscall)); obj->Set(env->syscall_string(), OneByteString(isolate, syscall));
} }
if (must_free)
LocalFree((HLOCAL)msg);
return e; return e;
} }
#endif #endif