Package: doxygen
Version: 1.4.6-2
Severity: normal
Tags: patch

Hi,

Attached is the diff for my doxygen 1.4.6-2.1 NMU.
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,11 @@
+doxygen (1.4.6-2.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix buffer overflows in QCString::sprintf() and SCString::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;
 }
 
only in patch2:
unchanged:
--- doxygen-1.4.6.orig/qtools/scstring.cpp
+++ doxygen-1.4.6/qtools/scstring.cpp
@@ -130,20 +130,41 @@
 
 SCString &SCString::sprintf( const char *format, ... )
 {
-  va_list ap;
-  va_start( ap, format );
-  uint l = length();
-  const uint minlen=256;
+  int l = length();
+  const int minlen=256;
+  bool finish;
+  
   if (l<minlen)
   {
     if (m_data) 
       m_data = (char *)realloc(m_data,minlen);
     else
       m_data = (char *)malloc(minlen);
+    l = minlen;
   }
-  vsprintf( m_data, format, ap );
-  resize( qstrlen(m_data) + 1 );              // truncate
-  va_end( ap );
+    
+  do {
+    va_list ap;
+    va_start(ap, format);
+    int ret = vsnprintf(m_data, l, format, ap);
+    va_end(ap);
+
+    finish = false;
+    if (ret >= l)
+    {
+      l = ret + 1;
+      resize(l);
+    }
+    else if (ret == -1)      // glibc pre-2.1
+    {                   
+      l *= 2;
+      resize(l);
+    } else {
+      finish = true;
+    }
+  } while ( !finish );
+    
+  resize( qstrlen(m_data) + 1 );               // truncate
   return *this;
 }
 

Reply via email to