From 02f2175d177ea43704b912fa9e19eb4452797c07 Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Wed, 24 Sep 2025 18:12:28 +0200 Subject: [PATCH] Integrate fix-secformat patch from vkdoom-git AUR package --- src/common/scripting/dap/GameInterfaces.h | 31 ++++++----- .../scripting/dap/Nodes/ArrayStateNode.cpp | 7 +-- .../scripting/dap/Nodes/StackStateNode.cpp | 13 +++-- .../scripting/dap/Nodes/StatePointerNode.cpp | 19 ++++--- .../scripting/dap/Nodes/ValueStateNode.cpp | 50 +++++++++++++----- src/common/scripting/dap/PexCache.cpp | 22 ++++---- src/common/scripting/dap/Utilities.h | 52 +++++++++++++++---- src/common/scripting/dap/ZScriptDebugger.cpp | 19 ++++--- 8 files changed, 132 insertions(+), 81 deletions(-) diff --git a/src/common/scripting/dap/GameInterfaces.h b/src/common/scripting/dap/GameInterfaces.h index e4fedc56e..85aa45c59 100644 --- a/src/common/scripting/dap/GameInterfaces.h +++ b/src/common/scripting/dap/GameInterfaces.h @@ -1,18 +1,17 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include "common/console/c_cvars.h" - #include "Utilities.h" + #include "actor.h" +#include "c_cvars.h" +#include "c_dispatch.h" +#include "dobject.h" #include "filesystem.h" #include "resourcefile.h" - +#include "types.h" +#include "vm.h" +#include "vmintern.h" +#include "zstring.h" struct FState; namespace DebugServer @@ -776,7 +775,7 @@ static std::string GetParameterName(const VMFrame *m_stackFrame, int paramidx) return params[paramidx].GetChars(); } } - return StringFormat("%s%d", ARG, paramidx - GetImplicitParmeterCount(m_stackFrame)); + return StringFormat("%s%zu", ARG, paramidx - GetImplicitParmeterCount(m_stackFrame)); } static FrameLocalsState GetLocalsState(const VMFrame *p_stackFrame); @@ -847,7 +846,7 @@ static bool GetRegisterValueChecked(const VMFrame *m_stackFrame, uint8_t regType case REGT_INT: if (idx >= m_stackFrame->NumRegD) { - LogError("GetRegisterValue: Function %s, int reg idx %d > %d", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegD); + LogError("GetRegisterValue: Function %s, int reg idx %d > %hu", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegD); value = VMValue(); return false; } @@ -856,7 +855,7 @@ static bool GetRegisterValueChecked(const VMFrame *m_stackFrame, uint8_t regType case REGT_FLOAT: if (idx >= m_stackFrame->NumRegF) { - LogError("GetRegisterValue: Function %s, float reg idx %d > %d", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegF); + LogError("GetRegisterValue: Function %s, float reg idx %d > %hu", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegF); value = VMValue(); return false; } @@ -864,7 +863,7 @@ static bool GetRegisterValueChecked(const VMFrame *m_stackFrame, uint8_t regType case REGT_STRING: if (idx >= m_stackFrame->NumRegS) { - LogError("GetRegisterValue: Function %s, string reg idx %d > %d", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegS); + LogError("GetRegisterValue: Function %s, string reg idx %d > %hu", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegS); value = VMValue(); return false; } @@ -873,14 +872,14 @@ static bool GetRegisterValueChecked(const VMFrame *m_stackFrame, uint8_t regType case REGT_POINTER: if (idx >= m_stackFrame->NumRegA) { - LogError("GetRegisterValue: Function %s, pointer reg idx %d > %d", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegA); + LogError("GetRegisterValue: Function %s, pointer reg idx %d > %hu", m_stackFrame->Func->PrintableName, idx, m_stackFrame->NumRegA); value = VMValue(); return false; } break; default: { - LogError("GetRegisterValue: Function %s, invalid reg type %d", m_stackFrame->Func->PrintableName, regType); + LogError("GetRegisterValue: Function %s, invalid reg type %hu", m_stackFrame->Func->PrintableName, regType); value = VMValue(); return false; } @@ -1011,7 +1010,7 @@ static FrameLocalsState GetLocalsState(const VMFrame *p_stackFrame) state.RegCount = local.RegCount; if (local.type->RegCount != local.RegCount) { - LogError("GetReg: RegCount mismatch for %s: %d != %d", local_name, local.type->RegCount, local.RegCount); + LogError("GetReg: RegCount mismatch for %s: %hu != %d", local_name, local.type->RegCount, local.RegCount); } assert(fields.empty() || fields[0].second->Type->RegType == REGT_FLOAT); state.RegNum = NumRegFloat; diff --git a/src/common/scripting/dap/Nodes/ArrayStateNode.cpp b/src/common/scripting/dap/Nodes/ArrayStateNode.cpp index 36d75e2e1..d2d481cf7 100644 --- a/src/common/scripting/dap/Nodes/ArrayStateNode.cpp +++ b/src/common/scripting/dap/Nodes/ArrayStateNode.cpp @@ -1,9 +1,10 @@ #include "ArrayStateNode.h" #include "common/scripting/dap/GameInterfaces.h" +#include "common/scripting/dap/RuntimeState.h" +#include "common/scripting/dap/Utilities.h" + #include "dobject.h" #include "vm.h" -#include -#include namespace DebugServer { @@ -96,7 +97,7 @@ bool ArrayStateNode::SerializeToProtocol(dap::Variable &variable) } else { - variable.value = StringFormat("%s[%d]", elementTypeName.c_str(), variable.indexedVariables.value(0)); + variable.value = StringFormat("%s[%ld]", elementTypeName.c_str(), static_cast(variable.indexedVariables.value(0))); if (m_type->toPointer()) { variable.value += StringFormat(" (%p)", m_value.a); diff --git a/src/common/scripting/dap/Nodes/StackStateNode.cpp b/src/common/scripting/dap/Nodes/StackStateNode.cpp index b632302b9..1be859ca5 100644 --- a/src/common/scripting/dap/Nodes/StackStateNode.cpp +++ b/src/common/scripting/dap/Nodes/StackStateNode.cpp @@ -1,10 +1,9 @@ -#include "StackStateNode.h" - -#include -#include - #include + #include "StackFrameStateNode.h" +#include "StackStateNode.h" +#include "common/scripting/dap/RuntimeState.h" +#include "common/scripting/dap/Utilities.h" namespace DebugServer { @@ -19,13 +18,13 @@ bool StackStateNode::SerializeToProtocol(dap::Thread &thread) const if (frames.empty()) { - thread.name = StringFormat("(%d)", thread.id); + thread.name = StringFormat("(%ld)", static_cast(thread.id)); } else { const auto frame = frames.back(); const auto name = frame->Func ? frame->Func->PrintableName : ""; - thread.name = StringFormat("%s (%d)", name, thread.id); + thread.name = StringFormat("%s (%ld)", name, static_cast(thread.id)); } return true; diff --git a/src/common/scripting/dap/Nodes/StatePointerNode.cpp b/src/common/scripting/dap/Nodes/StatePointerNode.cpp index 70bd1c818..ed8711d3d 100644 --- a/src/common/scripting/dap/Nodes/StatePointerNode.cpp +++ b/src/common/scripting/dap/Nodes/StatePointerNode.cpp @@ -1,13 +1,12 @@ -#include "StatePointerNode.h" - -#include "types.h" -#include "ValueStateNode.h" -#include -#include -#include -#include -#include #include "DummyNode.h" +#include "StatePointerNode.h" +#include "ValueStateNode.h" +#include "common/scripting/dap/Utilities.h" + +#include "dobject.h" +#include "info.h" +#include "symbols.h" +#include "types.h" namespace DebugServer { @@ -170,7 +169,7 @@ bool StatePointerNode::GetChildNode(std::string name, std::shared_ptrStateFlags, StringJoin(strings, " | ").c_str()); + std::string value = StringFormat("%hu (%s)", state->StateFlags, StringJoin(strings, " | ").c_str()); node = std::make_shared("StateFlags", value, "StateFlags"); return true; } diff --git a/src/common/scripting/dap/Nodes/ValueStateNode.cpp b/src/common/scripting/dap/Nodes/ValueStateNode.cpp index c0aa5b758..21e30da3e 100644 --- a/src/common/scripting/dap/Nodes/ValueStateNode.cpp +++ b/src/common/scripting/dap/Nodes/ValueStateNode.cpp @@ -1,20 +1,44 @@ +#include "common/scripting/dap/GameInterfaces.h" +#include "common/scripting/dap/Utilities.h" #include "ValueStateNode.h" -#include "actor.h" - -#include -#include "common/scripting/dap/GameInterfaces.h" +#include "info.h" +#include "palettecontainer.h" +#include "s_soundinternal.h" +#include "texturemanager.h" #include "types.h" #include "vm.h" -#include -#include -#include -#include namespace DebugServer { -static const char *basicTypeNames[] = {"NONE", "uint32", "int32", "uint16", "int16", "uint8", "int8", "float", "double", "bool", "string", - "name", "SpriteID", "TextureID", "TranslationID", "Sound", "Color", "Enum", "StateLabel", "pointer", "VoidPointer", nullptr}; +static const char *basicTypeNames[] = { + "NONE", + + "uint32", + "int32", + "uint16", + "int16", + "uint8", + "int8", + "float", + "double", + "bool", + "string", + + "name", + "SpriteID", + "TextureID", + "TranslationID", + "Sound", + "Color", + "Enum", + "StateLabel", + + "pointer", + "VoidPointer", + + nullptr +}; ValueStateNode::ValueStateNode(std::string name, VMValue variable, PType *type, PClass *stateOwningClass) : StateNodeNamedVariable(name), m_variable(variable), m_type(type), m_StateOwningClass(stateOwningClass) @@ -97,9 +121,9 @@ dap::Variable ValueStateNode::ToVariable(const VMValue &m_variable, PType *m_typ { // explicitly not TYPE_IntNotInt int64_t val = TruncateVMValue(&m_variable, basic_type).i; if (basic_type == BASIC_uint32 || basic_type == BASIC_uint16 || basic_type == BASIC_uint8){ - variable.value = StringFormat("%u", val); + variable.value = StringFormat("%lu", val); } else { - variable.value = StringFormat("%d", val); + variable.value = StringFormat("%ld", val); } } else if (m_type->isFloat()) @@ -166,7 +190,7 @@ dap::Variable ValueStateNode::ToVariable(const VMValue &m_variable, PType *m_typ uint8_t g = (soundval >> 8) & 0xFF; uint8_t b = soundval & 0xFF; // hex format - variable.value = StringFormat("Color #%08X (a: %d, r: %d, g: %d, b: %d)", soundval, a, r, g, b); + variable.value = StringFormat("Color #%08X (a: %hu, r: %hu, g: %hu, b: %hu)", soundval, a, r, g, b); } else if (m_type == TypeStateLabel) { diff --git a/src/common/scripting/dap/PexCache.cpp b/src/common/scripting/dap/PexCache.cpp index d2a08be95..5fc5f2566 100644 --- a/src/common/scripting/dap/PexCache.cpp +++ b/src/common/scripting/dap/PexCache.cpp @@ -1,14 +1,12 @@ -#include "PexCache.h" -#include "Utilities.h" -#include "GameInterfaces.h" - -#include #include #include -#include -#include + +#include "GameInterfaces.h" +#include "PexCache.h" +#include "Utilities.h" + +#include "filesystem.h" #include "resourcefile.h" -#include "RuntimeState.h" namespace DebugServer { @@ -40,7 +38,7 @@ void PexCache::PrintOutAllLoadedScripts() scripts_lock scriptLock(m_scriptsMutex); for (auto &script : m_scripts) { - Printf("Loaded %d functions from script: %s", script.second->GetFunctionCount(), script.second->GetQualifiedPath().c_str()); + Printf("Loaded %zu functions from script: %s", script.second->GetFunctionCount(), script.second->GetQualifiedPath().c_str()); } } @@ -579,13 +577,13 @@ uint64_t PexCache::AddDisassemblyLines(VMScriptFunction *func, DisassemblyMap &i } if (comment_pos == std::string::npos) { - LogError("!!!!!!Disassembly line %d has no comment!!!!!", i); + LogError("!!!!!!Disassembly line %zu has no comment!!!!!", i); continue; } } if (line.size() < 19) { - LogError("!!!!!!Disassembly line %d too short!!!!!", i); + LogError("!!!!!!Disassembly line %zu too short!!!!!", i); continue; } // lines go like this: @@ -647,7 +645,7 @@ uint64_t PexCache::AddDisassemblyLines(VMScriptFunction *func, DisassemblyMap &i currCodePointer++; instruction = MakeInstruction( - func, ref, "--", StringFormat("%02X%02X%02X%02X", currCodePointer->op, currCodePointer->a, currCodePointer->b, currCodePointer->c), StringFormat("; jmp %08X", currCodePointer->i24), ipnum + 4, resolved_symbol); + func, ref, "--", StringFormat("%02hX%02hX%02hX%02hX", currCodePointer->op, currCodePointer->a, currCodePointer->b, currCodePointer->c), StringFormat("; jmp %08X", currCodePointer->i24), ipnum + 4, resolved_symbol); min_line = std::min(min_line, instruction->line); if (instruction->line > -1) { diff --git a/src/common/scripting/dap/Utilities.h b/src/common/scripting/dap/Utilities.h index 81c5a7883..5de936f62 100644 --- a/src/common/scripting/dap/Utilities.h +++ b/src/common/scripting/dap/Utilities.h @@ -1,12 +1,14 @@ #pragma once -#include -#include -#include -#include -#include #include #include +#include +#include + +#include + +#include "printf.h" + namespace DebugServer { @@ -56,7 +58,25 @@ inline size_t CaseInsensitiveFind(const std::string &s1, const std::string &s2) return std::distance(s1.begin(), pos); } -template std::string StringFormat(const char *fmt, Args... args) +// if we use std::format, this wouldn't be needed -- we could also turn these into c style vargs, but I think that would be misguided +#if defined(__clang__) && __clang_major__ >= 15 +# define PRINTF_FORMAT(STR_INDEX, FIRST) __attribute__((format(printf, STR_INDEX, FIRST))) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgcc-compat" +// for GCC and older Clang, this feature is unsupported on templates, so the attribute is disabled +// WARNING: This means no compile-time format string checking will occur on these compilers. +#elif defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-security" +# define PRINTF_FORMAT(STR_INDEX, FIRST) +#else +// For other compilers (like MSVC), the attribute is also empty. +# define PRINTF_FORMAT(STR_INDEX, FIRST) +#endif + +template +PRINTF_FORMAT(1, 2) +std::string StringFormat(const char* fmt, Args... args) { const size_t size = snprintf(nullptr, 0, fmt, args...); std::string buf; @@ -98,23 +118,35 @@ static inline std::string StripColorCodes(const std::string &str) return copy.Data(); } -template void LogInternal(const char *fmt, Args... args) +template +PRINTF_FORMAT(1, 2) +void LogInternal(const char *fmt, Args... args) { Printf(PRINT_HIGH | PRINT_NODAPEVENT | PRINT_NONOTIFY, "%s\n", StringFormat(fmt, args...).c_str()); } -template void LogInternalError(const char *fmt, Args... args) +template +PRINTF_FORMAT(1, 2) +void LogInternalError(const char *fmt, Args... args) { Printf(PRINT_HIGH | PRINT_NODAPEVENT | PRINT_NONOTIFY, TEXTCOLOR_RED "%s\n", StringFormat(fmt, args...).c_str()); } -template void Log(const char *fmt, Args... args) +template +PRINTF_FORMAT(1, 2) +void Log(const char *fmt, Args... args) { Printf(PRINT_HIGH | PRINT_NONOTIFY, "%s\n", StringFormat(fmt, args...).c_str()); } -template void LogError(const char *fmt, Args... args) +template +PRINTF_FORMAT(1, 2) +void LogError(const char *fmt, Args... args) { Printf(PRINT_HIGH | PRINT_NONOTIFY, TEXTCOLOR_RED "%s\n", StringFormat(fmt, args...).c_str()); } +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic pop +#endif + #define RETURN_DAP_ERROR(message) \ LogError("%s", message); \ return dap::Error(message); diff --git a/src/common/scripting/dap/ZScriptDebugger.cpp b/src/common/scripting/dap/ZScriptDebugger.cpp index b9bfc1c87..c83b4383e 100644 --- a/src/common/scripting/dap/ZScriptDebugger.cpp +++ b/src/common/scripting/dap/ZScriptDebugger.cpp @@ -1,17 +1,16 @@ -#include "ZScriptDebugger.h" - #include #include + #include #include -#include "Utilities.h" #include "GameInterfaces.h" +#include "Nodes/LocalScopeStateNode.h" #include "Nodes/StackFrameStateNode.h" #include "Nodes/StateNodeBase.h" -#include "Nodes/CVarScopeStateNode.h" -#include "common/scripting/dap/Nodes/LocalScopeStateNode.h" - +#include "RuntimeState.h" +#include "Utilities.h" +#include "ZScriptDebugger.h" // This is the main class that handles the debug session and the debug requests/responses and events @@ -444,7 +443,7 @@ dap::ResponseOrError ZScriptDebugger::GetScopes(const dap:: std::vector> frameScopes; if (request.frameId < 0) { - RETURN_DAP_ERROR(StringFormat("Invalid frameId %d", request.frameId).c_str()); + RETURN_DAP_ERROR(StringFormat("Invalid frameId %ld", static_cast(request.frameId)).c_str()); } auto frameId = static_cast(request.frameId); if (!m_runtimeState->ResolveChildrenByParentId(frameId, frameScopes)) @@ -484,7 +483,7 @@ dap::ResponseOrError ZScriptDebugger::GetVariables(const if (!m_runtimeState->ResolveChildrenByParentId(static_cast(request.variablesReference), variableNodes, start, maxCount)) { // Don't log, this happens as a result of a variables request being sent after a step request that invalidates the state - return dap::Error(StringFormat("No such variablesReference %d", request.variablesReference).c_str()); + return dap::Error(StringFormat("No such variablesReference %ld", static_cast(request.variablesReference)).c_str()); } bool only_indexed = request.filter.value("") == "indexed"; bool only_named = request.filter.value("") == "named"; @@ -641,11 +640,11 @@ dap::ResponseOrError ZScriptDebugger::Evaluate(const dap: if( m_runtimeState->ResolveStateById(frameId, _frameNode)){ auto frameNode = std::dynamic_pointer_cast(_frameNode); if (!frameNode){ - RETURN_DAP_ERROR(StringFormat("Could not find frameId %d", frameId).c_str()); + RETURN_DAP_ERROR(StringFormat("Could not find frameId %ld", frameId).c_str()); } auto frameNodePath = m_runtimeState->GetPathById(frameNode->GetId()); if(frameNodePath.empty()){ - RETURN_DAP_ERROR(StringFormat("Could not find frameId %d", frameId).c_str()); + RETURN_DAP_ERROR(StringFormat("Could not find frameId %ld", frameId).c_str()); } // try locals first std::string localsPath = StringFormat("%s.%s", frameNodePath.c_str(), StackFrameStateNode::LOCAL_SCOPE_NAME);