1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string.h> 6 7 #include "base/numerics/safe_math.h" 8 #include "third_party/hunspell/google/bdict.h" 9 10 // static Verify(const char * bdict_data,size_t bdict_length)11bool hunspell::BDict::Verify(const char* bdict_data, size_t bdict_length) { 12 if (bdict_length <= sizeof(hunspell::BDict::Header)) 13 return false; 14 15 const BDict::Header* header = 16 reinterpret_cast<const hunspell::BDict::Header*>(bdict_data); 17 if (header->signature != hunspell::BDict::SIGNATURE || 18 header->major_version > hunspell::BDict::MAJOR_VERSION || 19 header->aff_offset > bdict_length || 20 header->dic_offset > bdict_length) { 21 return false; 22 } 23 24 { 25 // Make sure there is enough room for the affix header. 26 base::CheckedNumeric<uint32_t> aff_offset(header->aff_offset); 27 aff_offset += sizeof(hunspell::BDict::AffHeader); 28 if (!aff_offset.IsValid() || aff_offset.ValueOrDie() > bdict_length) 29 return false; 30 } 31 32 const hunspell::BDict::AffHeader* aff_header = 33 reinterpret_cast<const hunspell::BDict::AffHeader*>( 34 &bdict_data[header->aff_offset]); 35 36 // Make sure there is enough room for the affix group count dword. 37 { 38 base::CheckedNumeric<uint32_t> affix_group_offset( 39 aff_header->affix_group_offset); 40 affix_group_offset += sizeof(uint32_t); 41 if (!affix_group_offset.IsValid() || 42 affix_group_offset.ValueOrDie() > bdict_length) { 43 return false; 44 } 45 } 46 47 // The new BDICT header has a MD5 digest of the dictionary data. Compare the 48 // MD5 digest of the data with the one in the BDICT header. 49 if (header->major_version >= 2) { 50 base::MD5Digest digest; 51 base::MD5Sum(aff_header, bdict_length - header->aff_offset, &digest); 52 if (memcmp(&digest, &header->digest, sizeof(digest))) 53 return false; 54 } 55 56 return true; 57 } 58