I tried implementing it, and ended up with the attached patch. However, it doesn't fix the llvm bug, so I'll have to trace further -- it might be a different problem.
diff -u doxygen-1.4.6/debian/changelog doxygen-1.4.6/debian/changelog --- doxygen-1.4.6/debian/changelog +++ doxygen-1.4.6/debian/changelog @@ -1,3 +1,10 @@ +doxygen (1.4.6-2.1) unstable; urgency=low + + * Non-maintainer upload. + * Fix buffer overflows in QCString::sprintf(). (Closes: #357722) + + -- Steinar H. Gunderson <[EMAIL PROTECTED]> Sat, 3 Jun 2006 13:28:13 +0200 + doxygen (1.4.6-2) unstable; urgency=low * Fix build error with g++-4.1 (closes: #358208). only in patch2: unchanged: --- doxygen-1.4.6.orig/qtools/qcstring.cpp +++ doxygen-1.4.6/qtools/qcstring.cpp @@ -577,43 +577,42 @@ /*! - Implemented as a call to the native vsprintf() (see your C-library + Implemented as a call to the native vsnprintf() (see your C-library manual). - If your string is shorter than 256 characters, this sprintf() calls - resize(256) to decrease the chance of memory corruption. The string is - resized back to its natural length before sprintf() returns. - - Example: - \code - QCString s; - s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars - - QCString big( 25000 ); // very long string - big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars - \endcode - - \warning All vsprintf() implementations will write past the end of - the target string (*this) if the format specification and arguments - happen to be longer than the target string, and some will also fail - if the target string is longer than some arbitrary implementation - limit. - - Giving user-supplied arguments to sprintf() is begging for trouble. - Sooner or later someone \e will paste a 3000-character line into - your application. + This function takes some special care to avoid overflowing the buffer. + It uses vsnprintf() instead of vsprintf(), and if the entire string was + used, it increases the buffer length successively until there is enough + room. The string is resized back to its natural length before sprintf() + returns. */ QCString &QCString::sprintf( const char *format, ... ) { detach(); - va_list ap; - va_start( ap, format ); - if ( size() < 256 ) - QByteArray::resize( 256 ); // make string big enough - vsprintf( data(), format, ap ); + + bool finish; + if ( size() < 256 ) { // useful starting point + QByteArray::resize( 256 ); + } + + do { + va_list ap; + va_start( ap, format ); + int ret = vsnprintf( data(), size(), format, ap ); + va_end( ap ); + + finish = false; + if ( ret > size() ) { + QByteArray::resize( ret + 1 ); + } else if ( ret == -1 ) { // glibc pre-2.1 + QByteArray::resize( size() * 2 ); + } else { + finish = true; + } + } while ( !finish ); + resize( qstrlen(data()) + 1 ); // truncate - va_end( ap ); return *this; }