shithub: openh264

Download patch

ref: 076b1116d644889577353f8eeffce4dd54113667
parent: a344d100ae37ac69b0e1a6ac0b9d7d5f1328b86a
author: Martin Storsjö <martin@martin.st>
date: Sun Jan 26 06:35:19 EST 2014

Fix calculating buffer positions when appending with SNPRINTF/WelsSnprintf

This fixes two separate issues.

First, with the MSVC _snprintf implementations, the return value
is negative if the buffer wasn't large enough - this would in
the worst case lead to making iBufferUsed negative, writing before
the start of the buffer.

Secondly, when both iBufferUsed and iBufferLeft are accumulated,
one can't do "iBufferLeft -= iBufferUsed;". As an example,
say the buffer is 100 bytes in total and iBufferLeft is 40 and
iBufferUsed is 60. If SNPRINTF then writes 5 more bytes to the
buffer, iBufferUsed would be 65, but if we now do
"iBufferLeft -= iBufferUsed;" then iBufferLeft would end up as
-25 even though there's 35 bytes left in the buffer to use.

Therefore, we use a separate variable to store the return value
from the latest SNPRINTF call. This is checked to make sure it
wasn't negative, and only this amount is added to iBufferUsed
and subtracted from iBufferLeft.

This is the same pattern used in codec/encoder/core/src/utils.cpp.

strftime never returns negative numbers, so those calls don't
need as much checking.

--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -90,10 +90,12 @@
   str_t chFileName[1024] = { 0 };  //for .264
   int iBufUsed = 0;
   int iBufLeft = 1023;
+  int iCurUsed;
 
   str_t chFileNameSize[1024] = { 0 }; //for .len
   int iBufUsedSize = 0;
   int iBufLeftSize = 1023;
+  int iCurUsedSize;
 #endif//OUTPUT_BIT_STREAM
 
   m_pTrace = CreateWelsTrace (Wels_Trace_Type);
@@ -106,30 +108,44 @@
 
   WelsGetTimeOfDay (&sCurTime);
 
-  iBufUsed      += WelsSnprintf (chFileName,  iBufLeft,  "bs_0x%p_", (void_t*)this);
-  iBufUsedSize += WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void_t*)this);
+  iCurUsed     = WelsSnprintf (chFileName,  iBufLeft,  "bs_0x%p_", (void_t*)this);
+  iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void_t*)this);
 
-  iBufLeft -= iBufUsed;
+  if (iCurUsed > 0) {
+    iBufUsed += iCurUsed;
+    iBufLeft -= iCurUsed;
+  }
   if (iBufLeft > 0) {
-    iBufUsed += WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
-    iBufLeft -= iBufUsed;
+    iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
+    iBufUsed += iCurUsed;
+    iBufLeft -= iCurUsed;
   }
 
-  iBufLeftSize -= iBufUsedSize;
+  if (iCurUsedSize > 0) {
+    iBufUsedSize += iCurUsedSize;
+    iBufLeftSize -= iCurUsedSize;
+  }
   if (iBufLeftSize > 0) {
-    iBufUsedSize += WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
-    iBufLeftSize -= iBufUsedSize;
+    iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
+    iBufUsedSize += iCurUsedSize;
+    iBufLeftSize -= iCurUsedSize;
   }
 
   if (iBufLeft > 0) {
-    iBufUsed += WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillsecond (&sCurTime));
-    iBufLeft -= iBufUsed;
+    iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillsecond (&sCurTime));
+    if (iCurUsed > 0) {
+      iBufUsed += iCurUsed;
+      iBufLeft -= iCurUsed;
+    }
   }
 
   if (iBufLeftSize > 0) {
-    iBufUsedSize += WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
-                                  WelsGetMillsecond (&sCurTime));
-    iBufLeftSize -= iBufUsedSize;
+    iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
+                                 WelsGetMillsecond (&sCurTime));
+    if (iCurUsedSize > 0) {
+      iBufUsedSize += iCurUsedSize;
+      iBufLeftSize -= iCurUsedSize;
+    }
   }
 
 
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -77,10 +77,12 @@
   str_t strStreamFileName[1024] = { 0 };  //for .264
   int32_t iBufferUsed = 0;
   int32_t iBufferLeft = 1023;
+  int32_t iCurUsed;
 
   str_t strLenFileName[1024] = { 0 }; //for .len
   int32_t iBufferUsedSize = 0;
   int32_t iBufferLeftSize = 1023;
+  int32_t iCurUsedSize;
 #endif//OUTPUT_BIT_STREAM
 
 #ifdef OUTPUT_BIT_STREAM
@@ -118,26 +120,29 @@
 #ifdef _WIN32
 #if defined(_MSC_VER)
 #if _MSC_VER>=1500
-  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft, iBufferLeft,      "enc_bs_0x%p_", (void*)this);
-  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
+  iCurUsed      = SNPRINTF (strStreamFileName,      iBufferLeft, iBufferLeft,      "enc_bs_0x%p_", (void*)this);
+  iCurUsedSize  = SNPRINTF (strLenFileName, iBufferLeftSize, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
 #else
-  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft,      "enc_bs_0x%p_", (void*)this);
-  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
+  iCurUsed      = SNPRINTF (strStreamFileName,      iBufferLeft,      "enc_bs_0x%p_", (void*)this);
+  iCurUsedSize  = SNPRINTF (strLenFileName, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
 #endif//_MSC_VER>=1500
 #endif//_MSC_VER
 #else
-  iBufferUsed      += SNPRINTF (strStreamFileName,      iBufferLeft,      "/tmp/enc_bs_0x%p_", (void*)this);
-  iBufferUsedSize += SNPRINTF (strLenFileName, iBufferLeftSize, "/tmp/enc_size_0x%p", (void*)this);
+  iCurUsed      = SNPRINTF (strStreamFileName,      iBufferLeft,      "/tmp/enc_bs_0x%p_", (void*)this);
+  iCurUsedSize  = SNPRINTF (strLenFileName, iBufferLeftSize, "/tmp/enc_size_0x%p", (void*)this);
 #endif//WIN32
 
 
-  iBufferLeft -= iBufferUsed;
+  if (iCurUsed > 0) {
+    iBufferUsed += iCurUsed;
+    iBufferLeft -= iCurUsed;
+  }
   if (iBufferLeft > 0) {
 #if defined(_GNUC__)
-    iBufferUsed += strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S", tTimeNow);
+    iCurUsed = strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S", tTimeNow);
 #else
 #if defined(_MSC_VER)
-    iBufferUsed += strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S",
+    iCurUsed = strftime (&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S",
 #if _MSC_VER>=1500
                              & tTimeNow
 #else
@@ -146,16 +151,20 @@
                             );
 #endif//_MSC_VER
 #endif//__GNUC__
-    iBufferLeft -= iBufferUsed;
+    iBufferUsed += iCurUsed;
+    iBufferLeft -= iCurUsed;
   }
 
-  iBufferLeftSize -= iBufferUsedSize;
+  if (iCurUsedSize > 0) {
+    iBufferUsedSize += iCurUsedSize;
+    iBufferLeftSize -= iCurUsedSize;
+  }
   if (iBufferLeftSize > 0) {
 #if defined(_GNUC__)
-    iBufferUsedSize += strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S", tTimeNow);
+    iCurUsedSize = strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S", tTimeNow);
 #else
 #if defined(_MSC_VER)
-    iBufferUsedSize += strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S",
+    iCurUsedSize = strftime (&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S",
 #if _MSC_VER>=1500
                                  & tTimeNow
 #else
@@ -164,7 +173,8 @@
                                 );
 #endif//_MSC_VER
 #endif//__GNUC__
-    iBufferLeftSize -= iBufferUsedSize;
+    iBufferUsedSize += iCurUsedSize;
+    iBufferLeftSize -= iCurUsedSize;
   }
 
   if (iBufferLeft > 0) {
@@ -171,15 +181,18 @@
 #ifdef _WIN32
 #if defined(_MSC_VER)
 #if _MSC_VER>=1500
-    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, iBufferLeft, ".%03.3u.264", tTimeb.millitm);
+    iCurUsed = SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, iBufferLeft, ".%03.3u.264", tTimeb.millitm);
 #else
-    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimeb.millitm);
+    iCurUsed = SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimeb.millitm);
 #endif//_MSC_VER>=1500
 #endif//_MSC_VER
 #else
-    iBufferUsed += SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimev.tv_usec / 1000);
+    iCurUsed = SNPRINTF (&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimev.tv_usec / 1000);
 #endif//WIN32
-    iBufferLeft -= iBufferUsed;
+    if (iCurUsed > 0) {
+      iBufferUsed += iCurUsed;
+      iBufferLeft -= iCurUsed;
+    }
   }
 
   if (iBufferLeftSize > 0) {
@@ -186,16 +199,19 @@
 #ifdef _WIN32
 #if defined(_MSC_VER)
 #if _MSC_VER>=1500
-    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, iBufferLeftSize, ".%03.3u.len",
+    iCurUsedSize = SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, iBufferLeftSize, ".%03.3u.len",
                                  tTimeb.millitm);
 #else
-    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimeb.millitm);
+    iCurUsedSize = SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimeb.millitm);
 #endif//_MSC_VER>=1500
 #endif//_MSC_VER
 #else
-    iBufferUsedSize += SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimev.tv_usec / 1000);
+    iCurUsedSize = SNPRINTF (&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimev.tv_usec / 1000);
 #endif//WIN32
-    iBufferLeftSize -= iBufferUsedSize;
+    if (iCurUsedSize > 0) {
+      iBufferUsedSize += iCurUsedSize;
+      iBufferLeftSize -= iCurUsedSize;
+    }
   }
 
 #if defined(__GNUC__)