Fixed bug: check vsnprintf result in String::printf(). Update held string length after printf.
git-svn-id: http://yate.null.ro/svn/yate/trunk@6071 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
0a03513e64
commit
d6ffcbd0a9
|
@ -1024,7 +1024,7 @@ String& String::append(double value, unsigned int decimals)
|
||||||
return operator+=(buf);
|
return operator+=(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* string_printf(unsigned int length, const char* format, va_list& va)
|
static char* string_printf(unsigned int& length, const char* format, va_list& va)
|
||||||
{
|
{
|
||||||
if (TelEngine::null(format) || !length)
|
if (TelEngine::null(format) || !length)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1033,8 +1033,41 @@ static char* string_printf(unsigned int length, const char* format, va_list& va)
|
||||||
Debug("String",DebugFail,"malloc(%d) returned NULL!",length);
|
Debug("String",DebugFail,"malloc(%d) returned NULL!",length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Remember vsnprintf:
|
||||||
|
// standard:
|
||||||
|
// - buffer size and returned value include the terminating NULL char
|
||||||
|
// - returns -1 on error
|
||||||
|
// Windows:
|
||||||
|
// - it doesn't write terminating NULL if there is no space
|
||||||
|
// - returns -1 on error or buffer length is less than number of bytes to write
|
||||||
|
// - returned value doesn't include the terminating NULL char (even if it was written to output)
|
||||||
|
buf[length] = 0;
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
errno = 0;
|
||||||
int len = ::vsnprintf(buf,length,format,va);
|
int len = ::vsnprintf(buf,length,format,va);
|
||||||
buf[len] = 0;
|
#else
|
||||||
|
int len = ::vsnprintf(buf,length + 1,format,va);
|
||||||
|
#endif
|
||||||
|
if (len < 0) {
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
XDebug("String",DebugGoOn,"string_printf() incomplete write");
|
||||||
|
buf[length] = 0;
|
||||||
|
length = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
::free(buf);
|
||||||
|
Debug("String",DebugGoOn,"string_printf(): vsnprintf() failed!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (len < (int)length)
|
||||||
|
length = len;
|
||||||
|
#ifdef XDEBUG
|
||||||
|
else if (len > (int)length || buf[len])
|
||||||
|
Debug("String",DebugGoOn,"string_printf() incomplete write");
|
||||||
|
#endif
|
||||||
|
buf[length] = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,6 +1083,7 @@ String& String::printf(unsigned int length, const char* format, ...)
|
||||||
}
|
}
|
||||||
char* old = m_string;
|
char* old = m_string;
|
||||||
m_string = buf;
|
m_string = buf;
|
||||||
|
m_length = length;
|
||||||
::free(old);
|
::free(old);
|
||||||
changed();
|
changed();
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -1068,6 +1102,7 @@ String& String::printf(const char* format, ...)
|
||||||
}
|
}
|
||||||
char* old = m_string;
|
char* old = m_string;
|
||||||
m_string = buf;
|
m_string = buf;
|
||||||
|
m_length = len;
|
||||||
::free(old);
|
::free(old);
|
||||||
changed();
|
changed();
|
||||||
return *this;
|
return *this;
|
||||||
|
|
Loading…
Reference in New Issue