8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 19:23:03 +01:00

Fixed bug CORE-3844 : Validation not detects one specific case of index corruption

This commit is contained in:
hvlad 2012-05-11 19:38:36 +00:00
parent 9886cf8afc
commit a6a8f05dd5

View File

@ -1459,6 +1459,7 @@ RTN Vdr::walk_index(thread_db* tdbb, bool validate, jrd_rel* relation,
}
const bool unique = (root_page.irt_rpt[id].irt_flags & (irt_unique | idx_primary));
const bool descending = (root_page.irt_rpt[id].irt_flags & irt_descending);
temporary_key nullKey, *null_key = 0;
if (unique)
@ -1585,6 +1586,47 @@ RTN Vdr::walk_index(thread_db* tdbb, bool validate, jrd_rel* relation,
}
}
// Two checks below are about case where one (shorter) key is
// a full prefix of another (longer) key, for example:
// 'aa' and 'aaa', '' and 'a', etc
// in ascending index short key is less then long key ('aa' < 'aaa')
// the only exception is end-of-level node with zero length
if (!firstNode && !descending && !node.isEndLevel &&
node.prefix < key.key_length && node.length == 0)
{
duplicateNode = false;
corrupt(tdbb, true, VAL_INDEX_PAGE_CORRUPT, relation,
id + 1, next, page->btr_level, node.nodePointer - (UCHAR*)page,
__FILE__, __LINE__);
}
// in descending index short key is greater then long key ('aaa' < 'aa')
// the only exception is first node after start-of-level node at
// non-leaf level (also known as degenerate node)
if (!firstNode && descending &&
node.prefix == key.key_length && node.length > 0)
{
bool ok = (page->btr_left_sibling == 0 && page->btr_level > 0 &&
key.key_length == 0);
if (ok)
{
IndexNode first;
const UCHAR* p = first.readNode(page->btr_nodes + page->btr_jump_size, false);
ok = (node.nodePointer == p);
}
if (!ok)
{
duplicateNode = false;
corrupt(tdbb, true, VAL_INDEX_PAGE_CORRUPT, relation,
id + 1, next, page->btr_level, node.nodePointer - (UCHAR*)page,
__FILE__, __LINE__);
}
}
if (!duplicateNode && nullKeyNode)
{
nullKeyHandled = true;