Use va_copy in the v1 LogF macro before the sizing pass#144
Open
JustinMDotNet wants to merge 1 commit into
Open
Use va_copy in the v1 LogF macro before the sizing pass#144JustinMDotNet wants to merge 1 commit into
JustinMDotNet wants to merge 1 commit into
Conversation
The LogF macro starts a single va_list, passes it to _vscprintf / _vscwprintf to size the buffer, and then reuses the same va_list for vsnprintf_s / _vsnwprintf_s. Per the C standard, a va_list is in an indeterminate state after a vararg consumer reads from it, and any further use without va_copy or a fresh va_start is undefined behavior. This happens to work on MSVC x64 today because va_list is effectively a char* there. It will not work on ARM64, on a future MSVC that changes the representation, or on plugins built against a CRT with stricter va_list semantics. Since this is the entire formatted- logging surface for v1 plugins, getting it wrong breaks every plugin's logger at once. Copy args into a second va_list for the count_fn call and end that copy immediately, leaving the original args intact for format_fn. Fixes wopss#135 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #135.
What this changes
In the
LogFmacro insrc/dll/v1/Logger.cpp, copyargsinto a secondva_listbefore the sizing call and end the copy immediately after. The originalva_listis left intact for the formatting call.Why
The previous code passed the same
va_listto_vscprintf/_vscwprintfand then again tovsnprintf_s/_vsnwprintf_s. Per the C standard ava_listis in an indeterminate state after a vararg consumer reads from it; reusing it withoutva_copyor a freshva_startis undefined behavior.This happens to work on MSVC x64 today because the
va_listthere is effectively achar*and survives the call. It is still UB, and it breaks on:va_listhas a different representation.va_listlayout.va_listsemantics.This macro is the entire formatted-logging surface for v1 plugins (
TraceF,DebugF,InfoF,WarnF,ErrorF,CriticalFand the wide variants), so getting it wrong breaks every plugin's formatted logger at once.What I tested
Local rebuild. The change is small enough that the diff is the audit. No behavior change is expected on the current toolchain because the original code happens to do the right thing there; this is preventative.