Make the JSON parser less fragile

This commit is contained in:
Nathan Hourt 2014-09-08 10:12:42 -04:00
parent 21db937ba7
commit 9b6facea3f
2 changed files with 14 additions and 9 deletions

View file

@ -44,8 +44,9 @@ namespace fc
} }
template<typename T> template<typename T>
void skip_white_space( T& in ) bool skip_white_space( T& in )
{ {
bool skipped = false;
while( true ) while( true )
{ {
switch( in.peek() ) switch( in.peek() )
@ -54,10 +55,11 @@ namespace fc
case '\t': case '\t':
case '\n': case '\n':
case '\r': case '\r':
skipped = true;
in.get(); in.get();
break; break;
default: default:
return; return skipped;
} }
} }
} }
@ -162,8 +164,9 @@ namespace fc
if( in.peek() == ',' ) if( in.peek() == ',' )
{ {
in.get(); in.get();
continue;
} }
skip_white_space(in); if( skip_white_space(in) ) continue;
string key = stringFromStream( in ); string key = stringFromStream( in );
skip_white_space(in); skip_white_space(in);
if( in.peek() != ':' ) if( in.peek() != ':' )
@ -207,8 +210,12 @@ namespace fc
while( in.peek() != ']' ) while( in.peek() != ']' )
{ {
while( in.peek() == ',' ) if( in.peek() == ',' )
{
in.get(); in.get();
continue;
}
if( skip_white_space(in) ) continue;
ar.push_back( variant_from_stream(in) ); ar.push_back( variant_from_stream(in) );
skip_white_space(in); skip_white_space(in);
} }
@ -400,11 +407,8 @@ namespace fc
case EOF: case EOF:
FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" ); FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
default: default:
// ilog( "unhandled char '${c}' int ${int}", ("c", fc::string( &c, 1 ) )("int", int(c)) ); FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
return stringFromToken(in); ("c", c)("s", stringFromToken(in)) );
in.get(); //
ilog( "unhandled char '${c}' int ${int}", ("c", fc::string( &c, 1 ) )("int", int(c)) );
return variant();
} }
} }
return variant(); return variant();

View file

@ -535,6 +535,7 @@ void from_variant( const variant& var, uint32_t& vo )
vo = static_cast<uint32_t>(var.as_uint64()); vo = static_cast<uint32_t>(var.as_uint64());
} }
void to_variant( const int32_t& var, variant& vo ) { vo = int64_t(var); }
void from_variant( const variant& var, int32_t& vo ) void from_variant( const variant& var, int32_t& vo )
{ {
vo = static_cast<int32_t>(var.as_int64()); vo = static_cast<int32_t>(var.as_int64());