diff --git a/src/bson/BSON.cpp b/src/bson/BSON.cpp index 454b89fb1..7fd11c839 100644 --- a/src/bson/BSON.cpp +++ b/src/bson/BSON.cpp @@ -68,6 +68,13 @@ int bson_copy( bson *out, const bson *in ) { int bson_init_data( bson *b, char *data ) { b->data = data; + b->dataSize = INT_MAX; // no overflow detection for bson_iterator_next + return BSON_OK; +} + +int bson_init_data_size( bson *b, char *data, int size ) { + b->data = data; + b->dataSize = size; // used for overflow detection for bson_iterator_next return BSON_OK; } @@ -292,11 +299,13 @@ void bson_print_raw( const char *data , int depth ) { void bson_iterator_init( bson_iterator *i, const bson *b ) { i->cur = b->data + 4; i->first = 1; + i->last = b->data + b->dataSize; } void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) { i->cur = buffer + 4; i->first = 1; + i->last = NULL; } bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) { @@ -309,6 +318,8 @@ bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) { } bson_bool_t bson_iterator_more( const bson_iterator *i ) { + if (i->last && i->cur >= i->last) + return BSON_EOO; return *( i->cur ); } @@ -377,6 +388,8 @@ bson_type bson_iterator_next( bson_iterator *i ) { i->cur += 1 + strlen( i->cur + 1 ) + 1 + ds; + if (i->last && i->cur >= i->last) + return BSON_EOO; return ( bson_type )( *i->cur ); } diff --git a/src/bson/BSON.h b/src/bson/BSON.h index f4f7bcc69..92d43f2c6 100644 --- a/src/bson/BSON.h +++ b/src/bson/BSON.h @@ -200,6 +200,7 @@ typedef int bson_bool_t; typedef struct { const char *cur; bson_bool_t first; + const char *last; } bson_iterator; typedef struct { @@ -644,6 +645,19 @@ void bson_init( bson *b ); */ int bson_init_data( bson *b , char *data ); + +/** + * Initialize a BSON object, point its data pointer + * to the provided char*, and initialize the size + * + * @param b the BSON object to initialize. + * @param data the raw BSON data. + * @param size the size of the BSON data. + * + * @return BSON_OK or BSON_ERROR. + */ +int bson_init_data_size( bson *b , char *data , int size ); + /** * Initialize a BSON object, and point its data * pointer to the provided char*. We assume diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 6bc6a5fee..72ab9d708 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -506,7 +506,7 @@ void GameSave::readOPS(char * data, int dataLength) throw ParseException(ParseException::Corrupt, "Unable to decompress"); set_bson_err_handler(bson_error_handler); - bson_init_data(&b, (char*)bsonData); + bson_init_data_size(&b, (char*)bsonData, bsonDataLen); bson_iterator_init(&iter, &b); std::vector tempSigns;