OpenDDLParser: latest greatest to get fix for coverity finding ( dereferenfing possible null ptr ).

pull/749/head
Kim Kulling 2016-01-08 16:46:13 +01:00
parent 430b614a69
commit 114d76765e
9 changed files with 315 additions and 98 deletions

View File

@ -151,6 +151,16 @@ DataArrayList::~DataArrayList() {
// empty
}
size_t DataArrayList::size() {
size_t result=1;
DataArrayList *n=m_next;
while( n!=ddl_nullptr ) {
result++;
n=n->m_next;
}
return result;
}
Context::Context()
: m_root( ddl_nullptr ) {
// empty

View File

@ -29,12 +29,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
IOStreamBase::IOStreamBase()
: m_file( ddl_nullptr ) {
// empty
StreamFormatterBase::StreamFormatterBase() {
}
StreamFormatterBase::~StreamFormatterBase() {
}
std::string StreamFormatterBase::format( const std::string &statement ) {
std::string tmp( statement );
return tmp;
}
IOStreamBase::IOStreamBase( StreamFormatterBase *formatter )
: m_formatter( formatter )
, m_file( ddl_nullptr ) {
if (ddl_nullptr == m_formatter) {
m_formatter = new StreamFormatterBase;
}
}
IOStreamBase::~IOStreamBase() {
// empty
delete m_formatter;
m_formatter = ddl_nullptr;
}
bool IOStreamBase::open( const std::string &name ) {
@ -57,12 +75,12 @@ bool IOStreamBase::close() {
return true;
}
void IOStreamBase::write( const std::string &statement ) {
size_t IOStreamBase::write( const std::string &statement ) {
if (ddl_nullptr == m_file) {
return;
return 0;
}
::fwrite( statement.c_str(), sizeof( char ), statement.size(), m_file );
std::string formatStatement = m_formatter->format( statement );
return ::fwrite( formatStatement.c_str(), sizeof( char ), formatStatement.size(), m_file );
}
struct DDLNodeIterator {
@ -88,6 +106,10 @@ struct DDLNodeIterator {
return false;
}
private:
DDLNodeIterator() ddl_no_copy;
DDLNodeIterator &operator = ( const DDLNodeIterator & ) ddl_no_copy;
};
static void writeLineEnd( std::string &statement ) {
@ -410,3 +432,4 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement )
}
END_ODDLPARSER_NS

View File

@ -33,7 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# include <windows.h>
#endif // _WIN32
#define DEBUG_HEADER_NAME
BEGIN_ODDLPARSER_NS
@ -74,7 +73,10 @@ const char *getTypeToken( Value::ValueType type ) {
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
std::stringstream stream;
stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl;
stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
std::string full(in);
std::string part(full.substr(0,50));
stream << part;
callback( ddl_error_msg, stream.str() );
}
@ -83,6 +85,14 @@ static bool isIntegerType( Value::ValueType integerType ) {
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
return false;
}
return true;
}
static bool isUnsignedIntegerType( Value::ValueType integerType ) {
if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 &&
integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) {
return false;
}
return true;
}
@ -206,6 +216,9 @@ bool OpenDDLParser::parse() {
size_t pos( current - &m_buffer[ 0 ] );
while( pos < m_buffer.size() ) {
current = parseNextNode( current, end );
if(current==ddl_nullptr) {
return false;
}
pos = current - &m_buffer[ 0 ];
}
return true;
@ -218,8 +231,6 @@ bool OpenDDLParser::exportContext( Context *ctx, const std::string &filename ) {
OpenDDLExport myExporter;
return myExporter.exportContext( ctx, filename );
return false;
}
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
@ -229,12 +240,15 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) {
return in;
}
#ifdef DEBUG_HEADER_NAME
static void dumpId( Identifier *id ) {
if( ddl_nullptr != id ) {
if ( ddl_nullptr != id->m_text.m_buffer ) { }
if ( ddl_nullptr != id->m_text.m_buffer ) {
std::cout << id->m_text.m_buffer << std::endl;
}
}
}
#endif
char *OpenDDLParser::parseHeader( char *in, char *end ) {
if( ddl_nullptr == in || in == end ) {
@ -260,7 +274,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
if( *in != Grammar::CommaSeparator[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] ) {
logInvalidTokenError( in, Grammar::ClosePropertyToken, m_logCallback );
return in;
return ddl_nullptr;
}
if( ddl_nullptr != prop && *in != Grammar::CommaSeparator[ 0 ] ) {
@ -311,13 +325,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
// loop over all children ( data and nodes )
do {
in = parseStructureBody( in, end, error );
if(in == ddl_nullptr){
return ddl_nullptr;
}
} while ( *in != '}' );
in++;
} else {
in++;
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
error = true;
return in;
return ddl_nullptr;
}
in = lookForNextToken( in, end );
@ -375,7 +392,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
setNodeValues( top(), values );
setNodeReferences( top(), refs );
} else if( arrayLen > 1 ) {
in = parseDataArrayList( in, end, &dtArrayList );
in = parseDataArrayList( in, end, type, &dtArrayList );
setNodeDataArrayList( top(), dtArrayList );
} else {
std::cerr << "0 for array is invalid." << std::endl;
@ -386,6 +403,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
in = lookForNextToken( in, end );
if( *in != '}' ) {
logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
return ddl_nullptr;
} else {
//in++;
}
@ -479,7 +497,7 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
if( *in == '%' ) {
ntype = LocalName;
}
in++;
Name *currentName( ddl_nullptr );
Identifier *id( ddl_nullptr );
in = parseIdentifier( in, end, &id );
@ -510,7 +528,7 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
// get size of id
size_t idLen( 0 );
char *start( in );
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] ) {
while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
++in;
++idLen;
}
@ -631,7 +649,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
return in;
}
if( !isIntegerType( integerType ) ) {
if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) {
return in;
}
@ -642,7 +660,13 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
}
if( isNumeric( *start ) ) {
const int value( atoi( start ) );
#ifdef OPENDDL_NO_USE_CPP11
const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11
const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) );
#else
const int64 value( atoll( start ) );
const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) );
#endif
*integer = ValueAllocator::allocPrimData( integerType );
switch( integerType ) {
case Value::ddl_int8:
@ -657,6 +681,18 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
case Value::ddl_int64:
( *integer )->setInt64( ( int64 ) value );
break;
case Value::ddl_unsigned_int8:
( *integer )->setUnsignedInt8( (uint8) uvalue );
break;
case Value::ddl_unsigned_int16:
( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
break;
case Value::ddl_unsigned_int32:
( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
break;
case Value::ddl_unsigned_int64:
( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
break;
default:
break;
}
@ -665,7 +701,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
return in;
}
char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) {
char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType) {
*floating = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
@ -690,9 +726,16 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
}
if( ok ) {
const float value( ( float ) atof( start ) );
*floating = ValueAllocator::allocPrimData( Value::ddl_float );
( *floating )->setFloat( value );
if(floatType == Value::ddl_double)
{
const double value( atof( start ) );
*floating = ValueAllocator::allocPrimData( Value::ddl_double );
( *floating )->setDouble( value );
} else {
const float value( ( float ) atof( start ) );
*floating = ValueAllocator::allocPrimData( Value::ddl_float );
( *floating )->setFloat( value );
}
}
return in;
@ -856,12 +899,27 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
}
}
} else {
if (Value::ddl_int32 == type) {
in = parseIntegerLiteral( in, end, &current );
} else if (Value::ddl_float == type) {
in = parseFloatingLiteral( in, end, &current );
} else if (Value::ddl_string == type) {
in = parseStringLiteral( in, end, &current );
switch(type){
case Value::ddl_int8:
case Value::ddl_int16:
case Value::ddl_int32:
case Value::ddl_int64:
case Value::ddl_unsigned_int8:
case Value::ddl_unsigned_int16:
case Value::ddl_unsigned_int32:
case Value::ddl_unsigned_int64:
in = parseIntegerLiteral( in, end, &current, type);
break;
case Value::ddl_half:
case Value::ddl_float:
case Value::ddl_double:
in = parseFloatingLiteral( in, end, &current, type);
break;
case Value::ddl_string:
in = parseStringLiteral( in, end, &current );
break;
default:
break;
}
}
@ -895,7 +953,7 @@ static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues
return dataList;
}
char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataList ) {
*dataList = ddl_nullptr;
if( ddl_nullptr == in || in == end ) {
return in;
@ -910,7 +968,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da
do {
size_t numRefs( 0 ), numValues( 0 );
currentValue = ddl_nullptr;
Value::ValueType type( Value::ddl_none );
in = parseDataList( in, end, type, &currentValue, numValues, &refs, numRefs );
if( ddl_nullptr != currentValue ) {
if( ddl_nullptr == prev ) {

View File

@ -316,6 +316,16 @@ Value *Value::getNext() const {
return m_next;
}
size_t Value::size(){
size_t result=1;
Value *n=m_next;
while( n!=ddl_nullptr) {
result++;
n=n->m_next;
}
return result;
}
Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
if( type == Value::ddl_none || Value::ddl_types_max == type ) {
return ddl_nullptr;

View File

@ -56,9 +56,15 @@ BEGIN_ODDLPARSER_NS
#ifndef OPENDDL_NO_USE_CPP11
// All C++11 constructs
# define ddl_nullptr nullptr
# define ddl_override override
# define ddl_final final
# define ddl_no_copy = delete
#else
// Fall-back for older compilers
# define ddl_nullptr NULL
# define ddl_override
# define ddl_final
# define ddl_no_copy
#endif // OPENDDL_NO_USE_CPP11
// Forward declarations
@ -122,8 +128,8 @@ struct DLL_ODDLPARSER_EXPORT Text {
bool operator == ( const Text &rhs ) const;
private:
Text( const Text & );
Text &operator = ( const Text & );
Text( const Text & ) ddl_no_copy;
Text &operator = ( const Text & ) ddl_no_copy;
};
/// @brief Stores an OpenDDL-specific identifier type.
@ -147,8 +153,8 @@ struct DLL_ODDLPARSER_EXPORT Identifier {
bool operator == ( const Identifier &rhs ) const;
private:
Identifier( const Identifier & );
Identifier &operator = ( const Identifier & );
Identifier( const Identifier & ) ddl_no_copy;
Identifier &operator = ( const Identifier & ) ddl_no_copy;
};
/// @brief Description of the type of a name.
@ -171,8 +177,8 @@ struct DLL_ODDLPARSER_EXPORT Name {
~Name();
private:
Name( const Name & );
Name &operator = ( const Name& );
Name( const Name & ) ddl_no_copy;
Name &operator = ( const Name& ) ddl_no_copy;
};
/// @brief Stores a bundle of references.
@ -192,8 +198,8 @@ struct DLL_ODDLPARSER_EXPORT Reference {
~Reference();
private:
Reference( const Reference & );
Reference &operator = ( const Reference & );
Reference( const Reference & ) ddl_no_copy;
Reference &operator = ( const Reference & ) ddl_no_copy;
};
/// @brief Stores a property list.
@ -214,8 +220,8 @@ struct DLL_ODDLPARSER_EXPORT Property {
~Property();
private:
Property( const Property & );
Property &operator = ( const Property & );
Property( const Property & ) ddl_no_copy;
Property &operator = ( const Property & ) ddl_no_copy;
};
/// @brief Stores a data array list.
@ -230,9 +236,12 @@ struct DLL_ODDLPARSER_EXPORT DataArrayList {
/// @brief The destructor.
~DataArrayList();
/// @brief Gets the length of the array
size_t size();
private:
DataArrayList( const DataArrayList & );
DataArrayList &operator = ( const DataArrayList & );
DataArrayList( const DataArrayList & ) ddl_no_copy;
DataArrayList &operator = ( const DataArrayList & ) ddl_no_copy;
};
/// @brief Stores the context of a parsed OpenDDL declaration.
@ -249,8 +258,8 @@ struct DLL_ODDLPARSER_EXPORT Context {
void clear();
private:
Context( const Context & );
Context &operator = ( const Context & );
Context( const Context & ) ddl_no_copy;
Context &operator = ( const Context & ) ddl_no_copy;
};
END_ODDLPARSER_NS

View File

@ -27,19 +27,31 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
public:
StreamFormatterBase();
virtual ~StreamFormatterBase();
virtual std::string format( const std::string &statement );
};
//-------------------------------------------------------------------------------------------------
/// @ingroup IOStreamBase
/// @brief This class represents the stream to write out.
//-------------------------------------------------------------------------------------------------
class DLL_ODDLPARSER_EXPORT IOStreamBase {
public:
IOStreamBase();
IOStreamBase( StreamFormatterBase *formatter = ddl_nullptr );
virtual ~IOStreamBase();
virtual bool open( const std::string &anme );
virtual bool close();
virtual void write( const std::string &statement );
virtual size_t write( const std::string &statement );
private:
StreamFormatterBase *m_formatter;
FILE *m_file;
};

View File

@ -166,12 +166,12 @@ public: // parser helpers
static char *parseReference( char *in, char *end, std::vector<Name*> &names );
static char *parseBooleanLiteral( char *in, char *end, Value **boolean );
static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 );
static char *parseFloatingLiteral( char *in, char *end, Value **floating );
static char *parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType= Value::ddl_float );
static char *parseStringLiteral( char *in, char *end, Value **stringData );
static char *parseHexaLiteral( char *in, char *end, Value **data );
static char *parseProperty( char *in, char *end, Property **prop );
static char *parseDataList( char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs );
static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList );
static char *parseDataArrayList( char *in, char *end, Value::ValueType type, DataArrayList **dataList );
static const char *getVersion();
private:

View File

@ -26,19 +26,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
BEGIN_ODDLPARSER_NS
template<class T>
inline
bool isComment( T *in, T *end ) {
if( *in == '/' ) {
if( in + 1 != end ) {
if( *( in + 1 ) == '/' ) {
return true;
}
}
}
return false;
}
template<class T>
inline
bool isUpperCase( T in ) {
@ -66,7 +53,7 @@ bool isNewLine( const T in ) {
template<class T>
inline
bool isSeparator( T in ) {
if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in ) {
if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in ) {
return true;
}
return false;
@ -98,7 +85,7 @@ template<class T>
inline
bool isNumeric( const T in ) {
return ( in >= '0' && in <= '9' );
//return ( chartype_table[in] );
//return ( chartype_table[in] );
/*if (in >= '0' && in <= '9' )
return true;
@ -108,7 +95,7 @@ bool isNumeric( const T in ) {
template<class T>
inline
bool isNotEndOfToken( T *in, T *end ) {
return ( '}' != *in && ',' != *in && !isSpace( *in ) && in != end );
return ( '}' != *in && ',' != *in && !isSpace( *in ) && ')' != *in && in != end );
}
template<class T>
@ -249,4 +236,24 @@ int hex2Decimal( char in ) {
return ErrorHex2Decimal;
}
template<class T>
inline
bool isComment( T *in, T *end ) {
if ( *in=='/' ) {
if ( in+1!=end ) {
if ( *( in+1 )=='/' ) {
char *drive( ( in+2 ) );
if ( isUpperCase<T>( *drive )||isLowerCase<T>( *drive )&&*( drive+1 )=='/' ) {
return false;
} else {
return true;
}
}
}
}
return false;
}
END_ODDLPARSER_NS

View File

@ -109,44 +109,132 @@ public:
ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes
ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes
ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes
ddl_half,
ddl_float,
ddl_double,
ddl_string,
ddl_ref,
ddl_types_max
ddl_half, ///< Half data type.
ddl_float, ///< float data type
ddl_double, ///< Double data type.
ddl_string, ///< String data type.
ddl_ref, ///< Reference, used to define references to other data definitions.
ddl_types_max ///< Upper limit.
};
/// @brief The class constructor.
/// @param type [in] The value type.
Value( ValueType type );
/// @brief The class destructor.
~Value();
/// @brief Assigns a boolean to the value.
/// @param value [in9 The value.
void setBool( bool value );
/// @brief Returns the boolean value.
/// @return The boolean value.
bool getBool();
/// @brief Assigns a int8 to the value.
/// @param value [in] The value.
void setInt8( int8 value );
/// @brief Returns the int8 value.
/// @return The int8 value.
int8 getInt8();
/// @brief Assigns a int16 to the value.
/// @param value [in] The value.
void setInt16( int16 value );
/// @brief Returns the int16 value.
/// @return The int16 value.
int16 getInt16();
/// @brief Assigns a int32 to the value.
/// @param value [in] The value.
void setInt32( int32 value );
/// @brief Returns the int16 value.
/// @return The int32 value.
int32 getInt32();
/// @brief Assigns a int64 to the value.
/// @param value [in] The value.
void setInt64( int64 value );
/// @brief Returns the int16 value.
/// @return The int64 value.
int64 getInt64();
/// @brief Assigns a unsigned int8 to the value.
/// @param value [in] The value.
void setUnsignedInt8( uint8 value );
/// @brief Returns the unsigned int8 value.
/// @return The unsigned int8 value.
uint8 getUnsignedInt8() const;
/// @brief Assigns a unsigned int16 to the value.
/// @param value [in] The value.
void setUnsignedInt16( uint16 value );
/// @brief Returns the unsigned int16 value.
/// @return The unsigned int16 value.
uint16 getUnsignedInt16() const;
/// @brief Assigns a unsigned int32 to the value.
/// @param value [in] The value.
void setUnsignedInt32( uint32 value );
/// @brief Returns the unsigned int8 value.
/// @return The unsigned int32 value.
uint32 getUnsignedInt32() const;
/// @brief Assigns a unsigned int64 to the value.
/// @param value [in] The value.
void setUnsignedInt64( uint64 value );
/// @brief Returns the unsigned int64 value.
/// @return The unsigned int64 value.
uint64 getUnsignedInt64() const;
/// @brief Assigns a float to the value.
/// @param value [in] The value.
void setFloat( float value );
/// @brief Returns the float value.
/// @return The float value.
float getFloat() const;
/// @brief Assigns a double to the value.
/// @param value [in] The value.
void setDouble( double value );
/// @brief Returns the double value.
/// @return The double value.
double getDouble() const;
/// @brief Assigns a std::string to the value.
/// @param value [in] The value.
void setString( const std::string &str );
/// @brief Returns the std::string value.
/// @return The std::string value.
const char *getString() const;
/// @brief Dumps the value.
void dump();
/// @brief Assigns the next value.
/// @param next [n] The next value.
void setNext( Value *next );
/// @brief Returns the next value.
/// @return The next value.s
Value *getNext() const;
/// @brief Gets the length of the array.
/// @return The number of items in the array.
size_t size();
ValueType m_type;
size_t m_size;
unsigned char *m_data;