@ -16,7 +16,7 @@
namespace leveldb {
namespace leveldb {
inline uint32_t Block : : NumRestarts ( ) const {
inline uint32_t Block : : NumRestarts ( ) const {
assert ( size_ > = 2 * sizeof ( uint32_t ) ) ;
assert ( size_ > = sizeof ( uint32_t ) ) ;
return DecodeFixed32 ( data_ + size_ - sizeof ( uint32_t ) ) ;
return DecodeFixed32 ( data_ + size_ - sizeof ( uint32_t ) ) ;
}
}
@ -27,11 +27,12 @@ Block::Block(const BlockContents& contents)
if ( size_ < sizeof ( uint32_t ) ) {
if ( size_ < sizeof ( uint32_t ) ) {
size_ = 0 ; // Error marker
size_ = 0 ; // Error marker
} else {
} else {
restart_offset_ = size_ - ( 1 + NumRestarts ( ) ) * sizeof ( uint32_t ) ;
if ( restart_offset_ > size_ - sizeof ( uint32_t ) ) {
// The size is too small for NumRestarts() and therefore
// restart_offset_ wrapped around.
size_t max_restarts_allowed = ( size_ - sizeof ( uint32_t ) ) / sizeof ( uint32_t ) ;
if ( NumRestarts ( ) > max_restarts_allowed ) {
// The size is too small for NumRestarts()
size_ = 0 ;
size_ = 0 ;
} else {
restart_offset_ = size_ - ( 1 + NumRestarts ( ) ) * sizeof ( uint32_t ) ;
}
}
}
}
}
}
@ -253,7 +254,7 @@ class Block::Iter : public Iterator {
} ;
} ;
Iterator * Block : : NewIterator ( const Comparator * cmp ) {
Iterator * Block : : NewIterator ( const Comparator * cmp ) {
if ( size_ < 2 * sizeof ( uint32_t ) ) {
if ( size_ < sizeof ( uint32_t ) ) {
return NewErrorIterator ( Status : : Corruption ( " bad block contents " ) ) ;
return NewErrorIterator ( Status : : Corruption ( " bad block contents " ) ) ;
}
}
const uint32_t num_restarts = NumRestarts ( ) ;
const uint32_t num_restarts = NumRestarts ( ) ;