From 002b55f8f763b582c8dd26e7ec0268cba898aca4 Mon Sep 17 00:00:00 2001 From: Peter Swimm Date: Sun, 18 Oct 2026 17:15:26 -0700 Subject: [PATCH] Fix a stack overflow when saving a long XML attribute TinyXML writes the project through Tiny2NosStub's fprintf, which formatted every piece into a 256 byte stack buffer with vsprintf. An attribute longer than that, such as a sample with a very long file name, ran past it, overwriting the stack and leaving the project file cut short mid-write. Now it formats with vsnprintf, and prints anything longer into a heap buffer of the right size. Assisted-by: Claude (LLM) --- sources/Externals/TinyXML/Tiny2NosStub.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sources/Externals/TinyXML/Tiny2NosStub.cpp b/sources/Externals/TinyXML/Tiny2NosStub.cpp index b52fe9d05..110f983ed 100644 --- a/sources/Externals/TinyXML/Tiny2NosStub.cpp +++ b/sources/Externals/TinyXML/Tiny2NosStub.cpp @@ -1,15 +1,27 @@ #include "Tiny2NosStub.h" #include "System/Console/Trace.h" #include +#include #include void fprintf(I_File *f,char *fmt,...) { char buffer[256] ; va_list args; va_start(args,fmt); - - vsprintf(buffer,fmt,args); - int len=strlen(buffer) ; - f->Write(buffer,1,len) ; - + int len = vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + if (len<0) return ; + if (len<(int)sizeof(buffer)) { + f->Write(buffer,1,len) ; + return ; + } + // Longer than the buffer (an attribute can be, like a plugin's + // state): print it again on the heap rather than past the stack + char *big=(char *)malloc(len+1) ; + if (!big) return ; + va_start(args,fmt); + vsnprintf(big,len+1,fmt,args) ; + va_end(args); + f->Write(big,1,len) ; + free(big) ; } ;