File r1969-Fix-CVE-2019-9687-heap-based-buffer-overflow.patch of Package podofo.34527

diff --git src/base/PdfString.cpp src/base/PdfString.cpp
index fd87c7e..e5555e8 100644
--- src/base/PdfString.cpp
+++ src/base/PdfString.cpp
@@ -627,7 +627,19 @@ void PdfString::InitUtf8()
                                                     this->GetUnicodeLength(), 
                                                     reinterpret_cast<pdf_utf8*>(pBuffer), lBufferLen, ePdfStringConversion_Lenient );
 
-        pBuffer[lUtf8-1] = '\0';
+        if (lUtf8 + 1 > lBufferLen) // + 1 to account for 2 bytes termination here vs. 1 byte there
+        {
+            pBuffer = static_cast<char*>(podofo_realloc( pBuffer, lUtf8 + 1 ) );
+            if( !pBuffer )
+            {
+                PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
+            }
+            if (lUtf8 - 1 > lBufferLen)
+                lUtf8 = PdfString::ConvertUTF16toUTF8( reinterpret_cast<const pdf_utf16be*>(m_buffer.GetBuffer()),
+                                                       this->GetUnicodeLength(), reinterpret_cast<pdf_utf8*>(pBuffer), lUtf8 + 1);
+        }
+
+        pBuffer[lUtf8 - 1] = '\0';
         pBuffer[lUtf8] = '\0';
         m_sUtf8 = pBuffer;
         podofo_free( pBuffer );
@@ -811,6 +823,7 @@ pdf_long PdfString::ConvertUTF16toUTF8( const pdf_utf16be* pszUtf16, pdf_utf8* p
     return ConvertUTF16toUTF8( pszUtf16, lLen, pszUtf8, lLenUtf8 );
 }
 
+// returns used, or if not enough memory passed in, needed length incl. 1 byte termination
 pdf_long PdfString::ConvertUTF16toUTF8( const pdf_utf16be* pszUtf16, pdf_long lLenUtf16, 
                                     pdf_utf8* pszUtf8, pdf_long lLenUtf8, 
                                     EPdfStringConversion eConversion  )
@@ -828,12 +841,21 @@ pdf_long PdfString::ConvertUTF16toUTF8( const pdf_utf16be* pszUtf16, pdf_long lL
     size_t sLength = lLenUtf16;
     size_t resultBufLength = lLenUtf8;
 
-    u16_to_u8 ( s, sLength, pResultBuf, &resultBufLength);
+    uint8_t* pReturnBuf = u16_to_u8( s, sLength, pResultBuf, &resultBufLength );
+    if (pReturnBuf != pResultBuf)
+    {
+        free(pReturnBuf); // allocated by libunistring, so don't use podofo_free()
+        PdfError::LogMessage( eLogSeverity_Warning, "Output string size too little to hold it\n" );
+        return resultBufLength + 1;
+    }
 
     pdf_long lBufferLen = PODOFO_MIN( static_cast<pdf_long>(resultBufLength + 1), lLenUtf8 );
 
-    // Make sure buffer is 0 termnated
-    pszUtf8[resultBufLength] = 0; 
+    // Make sure buffer is 0 terminated
+    if ( static_cast<pdf_long>(resultBufLength + 1) <= lLenUtf8 )
+        pszUtf8[resultBufLength] = 0;
+    else
+        return resultBufLength + 1; // means: check for this in the caller to detect non-termination
     
     return lBufferLen;
 }
openSUSE Build Service is sponsored by