最近使用jsoncpp偶尔崩溃令人抓狂,这才翻出来原来是2011年的bug
转一篇
http://blog.csdn.net/smilelance/article/details/7659798
这个应该也崩溃的说。
Reader::decodeLongLong( Token &token )
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
if ( length <= bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
count = sscanf( buffer, "%lld", &value );
}
再看这个bug报告
https://github.com/oftc/jsoncpp/blob/master/NEWS.txt
http://sourceforge.net/p/jsoncpp/bugs/25/
Buffer overrun: accessing 'buffer', the writable size is '32' bytes, but '33' bytes might be written.
This occurs when int(token.end_ - token.start_) generates 32.
There should be "Char buffer[bufferSize+1];" instead.
double value = 0;
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
if ( length <= bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
count = sscanf( buffer, "%lf", &value );
}
新版本改动
bool
Reader::decodeDouble( Token &token )
{
double value = 0;
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
// Sanity check to avoid buffer overflow exploits.
if (length < 0) {
return addError( "Unable to parse token length", token );
}
// Avoid using a string constant for the format control string given to
// sscanf, as this can cause hard to debug crashes on OS X. See here for more
// info:
//
// http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
char format[] = "%lf";
if ( length <= bufferSize )
{
Char buffer[bufferSize+1];
memcpy( buffer, token.start_, length );
buffer[length] = 0;
count = sscanf( buffer, format, &value );
}
else
{
std::string buffer( token.start_, token.end_ );
count = sscanf( buffer.c_str(), format, &value );
}
if ( count != 1 )
return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
currentValue() = value;
return true;
}
顺便找到这个
http://gcc.gnu.org/onlinedocs/gcc/Incompatibilities.html
- GCC normally makes string constants read-only. If several identical-looking string constants are used, GCC stores only one copy of the string.
One consequence is that you cannot call
mktemp
with a string constant argument. The functionmktemp
always alters the string its argument points to.Another consequence is that
sscanf
does not work on some very old systems when passed a string constant as its format control string or input. This is becausesscanf
incorrectly tries to write into the string constant. Likewisefscanf
andscanf
.The solution to these problems is to change the program to use
char
-array variables with initialization strings for these purposes instead of string constants.还是使用新版本为好啊