Skip to content

Commit c0e7fc8

Browse files
committed
fix(qwp): save win32 errno at the failure point in the open_file siblings
Completes the errno-capture pattern 958a36d established for open_file/ fsyncDir0: seven sites across five natives -- length0 (CreateFileW and GetFileSizeEx failures), mkdir0, remove0, rename0, and findFirst0 (both the utf8_to_wide and FindFirstFileW failures) -- called SaveLastError() only AFTER free()/CloseHandle(), either of which may overwrite the thread's last-error value (HeapFree can SetLastError). The saved errno for a failed operation could therefore be an unrelated code or 0. Inert to behavior: repo-wide, nothing branches on the saved value for these operations -- fsyncDir0 was the sole control-flow consumer and already reads its own capture via GetSavedLastError() -- so the exposure was wrong [errno=N] diagnostics in Windows failure messages. Save now happens at the failure point; cleanup follows on every path unchanged. Windows-only TU: verified by mechanical review (order-only transform, brace/paren balance identical, statement-level clobber audit clean); compile coverage via the native build pipeline.
1 parent ab2b3b6 commit c0e7fc8

1 file changed

Lines changed: 25 additions & 8 deletions

File tree

core/src/main/c/windows/files.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,18 +360,24 @@ JNIEXPORT jlong JNICALL Java_io_questdb_client_std_Files_length0
360360
OPEN_EXISTING,
361361
FILE_ATTRIBUTE_NORMAL,
362362
NULL);
363-
free(wide);
364363
if (h == INVALID_HANDLE_VALUE) {
364+
/* Save the CreateFileW failure code BEFORE free(): any subsequent
365+
* API/CRT call (HeapFree can SetLastError) may overwrite the
366+
* thread's last-error value -- same pattern as open_file(). */
365367
SaveLastError();
368+
free(wide);
366369
return -1;
367370
}
371+
free(wide);
368372
LARGE_INTEGER sz;
369373
BOOL ok = GetFileSizeEx(h, &sz);
370-
CloseHandle(h);
371374
if (!ok) {
375+
/* Save before CloseHandle() can clobber the last-error value. */
372376
SaveLastError();
377+
CloseHandle(h);
373378
return -1;
374379
}
380+
CloseHandle(h);
375381
return (jlong) sz.QuadPart;
376382
}
377383

@@ -414,11 +420,13 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_mkdir0
414420
return -1;
415421
}
416422
BOOL ok = CreateDirectoryW(wide, NULL);
417-
free(wide);
418423
if (!ok) {
424+
/* Save before free() can clobber the last-error value. */
419425
SaveLastError();
426+
free(wide);
420427
return -1;
421428
}
429+
free(wide);
422430
return 0;
423431
}
424432

@@ -447,11 +455,13 @@ JNIEXPORT jboolean JNICALL Java_io_questdb_client_std_Files_remove0
447455
} else {
448456
ok = DeleteFileW(wide);
449457
}
450-
free(wide);
451458
if (!ok) {
459+
/* Save before free() can clobber the last-error value. */
452460
SaveLastError();
461+
free(wide);
453462
return JNI_FALSE;
454463
}
464+
free(wide);
455465
return JNI_TRUE;
456466
}
457467

@@ -469,12 +479,15 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_rename0
469479
return -1;
470480
}
471481
BOOL ok = MoveFileExW(oldW, newW, MOVEFILE_REPLACE_EXISTING);
472-
free(oldW);
473-
free(newW);
474482
if (!ok) {
483+
/* Save before free() can clobber the last-error value. */
475484
SaveLastError();
485+
free(oldW);
486+
free(newW);
476487
return -1;
477488
}
489+
free(oldW);
490+
free(newW);
478491
return 0;
479492
}
480493

@@ -512,24 +525,28 @@ JNIEXPORT jlong JNICALL Java_io_questdb_client_std_Files_findFirst0
512525
pattern[pathLen] = '\0';
513526

514527
wchar_t *wide = utf8_to_wide(pattern);
515-
free(pattern);
516528
if (!wide) {
529+
/* Save before free() can clobber the last-error value. */
517530
SaveLastError();
531+
free(pattern);
518532
return 0;
519533
}
534+
free(pattern);
520535

521536
qdb_find_t *find = (qdb_find_t *) malloc(sizeof(qdb_find_t));
522537
if (!find) {
523538
free(wide);
524539
return 0;
525540
}
526541
find->handle = FindFirstFileW(wide, &find->data);
527-
free(wide);
528542
if (find->handle == INVALID_HANDLE_VALUE) {
543+
/* Save before free() can clobber the last-error value. */
529544
SaveLastError();
545+
free(wide);
530546
free(find);
531547
return 0;
532548
}
549+
free(wide);
533550
find->hasEntry = 1;
534551
win_findname_to_utf8(find);
535552
return (jlong) (uintptr_t) find;

0 commit comments

Comments
 (0)