From 262a8bac6d49ad8b1d417543e72c601441fbf711 Mon Sep 17 00:00:00 2001 From: ggmini Date: Mon, 15 Jun 2026 00:07:35 +0200 Subject: [PATCH 1/4] fix: added workaround for uv_write on MSVC --- cli/cli.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/cli/cli.cpp b/cli/cli.cpp index ab85b5c5..6012c72b 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -14,6 +14,23 @@ #include "../src/checksum.h" #include "uv.h" +#if defined(_MSC_VER) && !defined(_llvm__) //TODO: check which msc ver bricked this && _MSC_VER +#define WIN_UV_WRITE_WORKAROUND +#endif + +#if defined WIN_UV_WRITE_WORKAROUND +struct heap_write_req { + uv_write_t req; + char* data; // allocated copy of dynamic text (nullptr if none) +}; + +static void heap_write_cb(uv_write_t* r, int /*status*/) { + heap_write_req* wr = reinterpret_cast(r); + if (wr->data) free(wr->data); + free(wr); +} +#endif + void show_version() { fprintf(stderr, "maxcso v%s\n", maxcso::VERSION); } @@ -492,9 +509,28 @@ int main(int argc, char *argv[]) { unsigned int nbufs = 0; if (formatting) { +#ifdef WIN_UV_WRITE_WORKAROUND + heap_write_req* wr = (heap_write_req*)malloc(sizeof(*wr)); + if (!wr) return; + // copy status string + size_t len = statusInfo.size(); + char* copy = (char*)malloc(len + 1); + if (!copy) { free(wr); return; } + memcpy(copy, statusInfo.c_str(), len + 1); + wr->data = copy; + + uv_buf_t bufs[2]; + unsigned nbufs = 0; + bufs[nbufs++] = ::uv_buf_init(ANSI_RESET_LINE); // literal OK + bufs[nbufs++] = ::uv_buf_init(copy, (unsigned)len); // heap copy + + int rc = uv_write(&wr->req, reinterpret_cast(&tty), bufs, nbufs, heap_write_cb); + if (rc != 0) { free(copy); free(wr); /* handle error if needed */ } +#else bufs[nbufs++] = uv_buf_init(ANSI_RESET_LINE); bufs[nbufs++] = uv_buf_init(statusInfo); uv_write(&write_req, reinterpret_cast(&tty), bufs, nbufs, nullptr); +#endif } else { fprintf(stderr, "%s", statusInfo.c_str()); } @@ -512,8 +548,27 @@ int main(int argc, char *argv[]) { const std::string prefix = status == maxcso::TASK_SUCCESS ? "" : "Error while processing "; statusInfo = (formatting ? ANSI_RESET_LINE : "") + prefix + task->input + ": " + reason + "\n"; if (formatting) { +#ifdef WIN_UV_WRITE_WORKAROUND + heap_write_req* wr = (heap_write_req*)malloc(sizeof(*wr)); + if (!wr) return; + // copy status string + size_t len = statusInfo.size(); + char* copy = (char*)malloc(len + 1); + if (!copy) { free(wr); return; } + memcpy(copy, statusInfo.c_str(), len + 1); + wr->data = copy; + + uv_buf_t bufs[2]; + unsigned nbufs = 0; + bufs[nbufs++] = ::uv_buf_init(ANSI_RESET_LINE); // literal OK + bufs[nbufs++] = ::uv_buf_init(copy, (unsigned)len); // heap copy + + int rc = uv_write(&wr->req, reinterpret_cast(&tty), bufs, nbufs, heap_write_cb); + if (rc != 0) { free(copy); free(wr); /* handle error if needed */ } +#else bufs[0] = uv_buf_init(statusInfo); uv_write(&write_req, reinterpret_cast(&tty), bufs, 1, nullptr); +#endif } else { fprintf(stderr, "%s", statusInfo.c_str()); } From 1acf2726543b6612dd83c4b96105e36c161d0da0 Mon Sep 17 00:00:00 2001 From: ggmini Date: Mon, 15 Jun 2026 22:01:28 +0200 Subject: [PATCH 2/4] fix: hid some variables from msvc --- cli/cli.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cli/cli.cpp b/cli/cli.cpp index 6012c72b..7d610ce2 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -453,8 +453,10 @@ int main(int argc, char *argv[]) { std::fill(std::begin(history), std::end(history), History{0, next}); std::string statusInfo; +#ifndef WIN_UV_WRITE_WORKAROUND uv_write_t write_req; uv_buf_t bufs[2]; +#endif maxcso::ProgressCallback progress = [&] (const maxcso::Task *task, maxcso::TaskStatus status, int64_t pos, int64_t total, int64_t written) { if (!formatting) { @@ -507,7 +509,10 @@ int main(int argc, char *argv[]) { statusInfo = task->input + ": " + statusInfo; } +#ifndef WIN_UV_WRITE_WORKAROUND unsigned int nbufs = 0; +#endif // DEBUG + if (formatting) { #ifdef WIN_UV_WRITE_WORKAROUND heap_write_req* wr = (heap_write_req*)malloc(sizeof(*wr)); From a1d3eb72519c406424fff4cf0c4745a53cce8ffc Mon Sep 17 00:00:00 2001 From: ggmini Date: Tue, 16 Jun 2026 13:07:21 +0200 Subject: [PATCH 3/4] fix: workaround only applied to Debug Builds --- cli/cli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cli.cpp b/cli/cli.cpp index 7d610ce2..38b3028e 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -14,7 +14,7 @@ #include "../src/checksum.h" #include "uv.h" -#if defined(_MSC_VER) && !defined(_llvm__) //TODO: check which msc ver bricked this && _MSC_VER +#if defined(_MSC_VER) && !defined(NDEBUG) #define WIN_UV_WRITE_WORKAROUND #endif From 239d99638265f8540a2569b107351812990147d8 Mon Sep 17 00:00:00 2001 From: ggmini Date: Thu, 18 Jun 2026 15:30:31 +0200 Subject: [PATCH 4/4] docs: added documentation for the workaround --- cli/cli.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/cli.cpp b/cli/cli.cpp index 38b3028e..3c5e6115 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -14,7 +14,9 @@ #include "../src/checksum.h" #include "uv.h" -#if defined(_MSC_VER) && !defined(NDEBUG) +//When compiling on MSVC an assertion will trigger in the libuv library on uv_write. +//This is a workaround to avoid it. The workarund is only applied to MSVC Debug builds. +#if defined(_MSC_VER) && !defined(NDEBUG) #define WIN_UV_WRITE_WORKAROUND #endif