Skip to content

Commit 0e4b1f9

Browse files
kimushureconbot
authored andcommitted
fix(windows): Fix read & write bugs for windows (#1364)
* Fix OVERLAPPED initialization * Fix buffer overrun for writing and reading * Remove unsafe memset for non-POD structures * Fix thread handle leak
1 parent 6ed7b3b commit 0e4b1f9

File tree

3 files changed

+6
-12
lines changed

3 files changed

+6
-12
lines changed

src/serialport.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ NAN_METHOD(Open) {
5454
}
5555

5656
OpenBaton* baton = new OpenBaton();
57-
memset(baton, 0, sizeof(OpenBaton));
5857
strcpy(baton->path, *path);
5958
baton->baudRate = getIntFromObject(options, "baudRate");
6059
baton->dataBits = getIntFromObject(options, "dataBits");
@@ -125,7 +124,6 @@ NAN_METHOD(Update) {
125124
}
126125

127126
ConnectionOptionsBaton* baton = new ConnectionOptionsBaton();
128-
memset(baton, 0, sizeof(ConnectionOptionsBaton));
129127

130128
baton->fd = fd;
131129
baton->baudRate = getIntFromObject(options, "baudRate");
@@ -169,7 +167,6 @@ NAN_METHOD(Close) {
169167
}
170168

171169
VoidBaton* baton = new VoidBaton();
172-
memset(baton, 0, sizeof(VoidBaton));
173170
baton->fd = Nan::To<v8::Int32>(info[0]).ToLocalChecked()->Value();
174171
baton->callback.Reset(info[1].As<v8::Function>());
175172

@@ -210,7 +207,6 @@ NAN_METHOD(Flush) {
210207
v8::Local<v8::Function> callback = info[1].As<v8::Function>();
211208

212209
VoidBaton* baton = new VoidBaton();
213-
memset(baton, 0, sizeof(VoidBaton));
214210
baton->fd = fd;
215211
baton->callback.Reset(callback);
216212

@@ -261,7 +257,6 @@ NAN_METHOD(Set) {
261257
v8::Local<v8::Function> callback = info[2].As<v8::Function>();
262258

263259
SetBaton* baton = new SetBaton();
264-
memset(baton, 0, sizeof(SetBaton));
265260
baton->fd = fd;
266261
baton->callback.Reset(callback);
267262
baton->brk = getBoolFromObject(options, "brk");
@@ -308,7 +303,6 @@ NAN_METHOD(Get) {
308303
}
309304

310305
GetBaton* baton = new GetBaton();
311-
memset(baton, 0, sizeof(GetBaton));
312306
baton->fd = fd;
313307
baton->cts = false;
314308
baton->dsr = false;
@@ -360,7 +354,6 @@ NAN_METHOD(Drain) {
360354
}
361355

362356
VoidBaton* baton = new VoidBaton();
363-
memset(baton, 0, sizeof(VoidBaton));
364357
baton->fd = fd;
365358
baton->callback.Reset(info[1].As<v8::Function>());
366359

src/serialport_unix.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ int setup(int fd, OpenBaton *data) {
284284

285285
// Copy the connection options into the ConnectionOptionsBaton to set the baud rate
286286
ConnectionOptionsBaton* connectionOptions = new ConnectionOptionsBaton();
287-
memset(connectionOptions, 0, sizeof(ConnectionOptionsBaton));
288287
connectionOptions->fd = fd;
289288
connectionOptions->baudRate = data->baudRate;
290289

src/serialport_win.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ NAN_METHOD(Write) {
286286
}
287287

288288
WriteBaton* baton = new WriteBaton();
289-
memset(baton, 0, sizeof(WriteBaton));
290289
baton->fd = fd;
291290
baton->buffer.Reset(buffer);
292291
baton->bufferData = bufferData;
@@ -320,14 +319,14 @@ DWORD __stdcall WriteThread(LPVOID param) {
320319
WriteBaton* baton = static_cast<WriteBaton*>(param);
321320

322321
OVERLAPPED* ov = new OVERLAPPED;
323-
memset(ov, 0, sizeof(ov));
322+
memset(ov, 0, sizeof(OVERLAPPED));
324323
ov->hEvent = static_cast<void*>(baton);
325324

326325
while (!baton->complete) {
327326
char* offsetPtr = baton->bufferData + baton->offset;
328327
// WriteFileEx requires calling GetLastError even upon success. Clear the error beforehand.
329328
SetLastError(0);
330-
WriteFileEx((HANDLE)baton->fd, offsetPtr, static_cast<DWORD>(baton->bufferLength), ov, WriteIOCompletion);
329+
WriteFileEx((HANDLE)baton->fd, offsetPtr, static_cast<DWORD>(baton->bufferLength - baton->offset), ov, WriteIOCompletion);
331330
// Error codes when call is successful, such as ERROR_MORE_DATA.
332331
DWORD lastError = GetLastError();
333332
if (lastError != ERROR_SUCCESS) {
@@ -350,6 +349,7 @@ void EIO_AfterWrite(uv_async_t* req) {
350349
Nan::HandleScope scope;
351350
WriteBaton* baton = static_cast<WriteBaton*>(req->data);
352351
WaitForSingleObject(baton->hThread, INFINITE);
352+
CloseHandle(baton->hThread);
353353
delete req;
354354

355355
v8::Local<v8::Value> argv[1];
@@ -404,7 +404,6 @@ NAN_METHOD(Read) {
404404
}
405405

406406
ReadBaton* baton = new ReadBaton();
407-
memset(baton, 0, sizeof(ReadBaton));
408407
baton->fd = fd;
409408
baton->offset = offset;
410409
baton->bytesToRead = bytesToRead;
@@ -434,6 +433,7 @@ void __stdcall ReadIOCompletion(DWORD errorCode, DWORD bytesTransferred, OVERLAP
434433
return;
435434
}
436435
if (bytesTransferred) {
436+
baton->bytesToRead -= bytesTransferred;
437437
baton->bytesRead += bytesTransferred;
438438
baton->offset += bytesTransferred;
439439
}
@@ -454,6 +454,7 @@ void __stdcall ReadIOCompletion(DWORD errorCode, DWORD bytesTransferred, OVERLAP
454454
char* offsetPtr = baton->bufferData + baton->offset;
455455

456456
// ReadFile, unlike ReadFileEx, needs an event in the overlapped structure.
457+
memset(ov, 0, sizeof(OVERLAPPED));
457458
ov->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
458459
if (!ReadFile((HANDLE)baton->fd, offsetPtr, baton->bytesToRead, &bytesTransferred, ov)) {
459460
errorCode = GetLastError();
@@ -526,6 +527,7 @@ void EIO_AfterRead(uv_async_t* req) {
526527
Nan::HandleScope scope;
527528
ReadBaton* baton = static_cast<ReadBaton*>(req->data);
528529
WaitForSingleObject(baton->hThread, INFINITE);
530+
CloseHandle(baton->hThread);
529531
delete req;
530532

531533
v8::Local<v8::Value> argv[2];

0 commit comments

Comments
 (0)