Index: /branches/1.0/xapian-core/backends/quartz/btree.cc
===================================================================
--- /branches/1.0/xapian-core/backends/quartz/btree.cc (revision 10168)
+++ /branches/1.0/xapian-core/backends/quartz/btree.cc (revision 10402)
@@ -1240,5 +1240,7 @@
 
     for (int i = 2; i <= n; i++) {
-	next(C_, 0);
+	if (!next(C_, 0)) {
+	    throw Xapian::DatabaseCorruptError("Unexpected end of table when reading continuation of tag");
+	}
 	(void)Item(C_[0].p, C_[0].c).append_chunk(tag);
     }
@@ -1823,8 +1825,26 @@
 	    if (n == 0) return false;
 	    n--;
-	    // Check if the block is in the built-in cursor (potentially in
-	    // modified form).
-	    if (writable && n == C[0].n) {
-		memcpy(p, C[0].p, block_size);
+	    if (writable) {
+		if (n == C[0].n) {
+		    // Block is a leaf block in the built-in cursor
+		    // (potentially in modified form).
+		    memcpy(p, C[0].p, block_size);
+		} else {
+		    // Blocks in the built-in cursor may not have been written
+		    // to disk yet, so we have to check that the block number
+		    // isn't in the built-in cursor or we'll read an
+		    // uninitialised block (for which GET_LEVEL(p) will
+		    // probably return 0).
+		    int j;
+		    for (j = 1; j <= level; ++j) {
+			if (n == C[j].n) break;
+		    }
+		    if (j <= level) continue;
+
+		    // Block isn't in the built-in cursor, so the form on disk
+		    // is valid, so read it to check if it's the next level 0
+		    // block.
+		    read_block(n, p);
+		}
 	    } else {
 		read_block(n, p);
@@ -1856,8 +1876,26 @@
 	    n++;
 	    if (n > base.get_last_block()) return false;
-	    // Check if the block is in the built-in cursor (potentially in
-	    // modified form).
-	    if (writable && n == C[0].n) {
-		memcpy(p, C[0].p, block_size);
+	    if (writable) {
+		if (n == C[0].n) {
+		    // Block is a leaf block in the built-in cursor
+		    // (potentially in modified form).
+		    memcpy(p, C[0].p, block_size);
+		} else {
+		    // Blocks in the built-in cursor may not have been written
+		    // to disk yet, so we have to check that the block number
+		    // isn't in the built-in cursor or we'll read an
+		    // uninitialised block (for which GET_LEVEL(p) will
+		    // probably return 0).
+		    int j;
+		    for (j = 1; j <= level; ++j) {
+			if (n == C[j].n) break;
+		    }
+		    if (j <= level) continue;
+
+		    // Block isn't in the built-in cursor, so the form on disk
+		    // is valid, so read it to check if it's the next level 0
+		    // block.
+		    read_block(n, p);
+		}
 	    } else {
 		read_block(n, p);
Index: /branches/1.0/xapian-core/backends/quartz/btree_base.cc
===================================================================
--- /branches/1.0/xapian-core/backends/quartz/btree_base.cc (revision 8160)
+++ /branches/1.0/xapian-core/backends/quartz/btree_base.cc (revision 10402)
@@ -415,4 +415,7 @@
     bit_map[i] |= d;   /* set as 'in use' */
     bit_map_low = i;
+    if (n > last_block) {
+	last_block = n;
+    }
     return n;
 }
Index: /branches/1.0/xapian-core/backends/flint/flint_table.cc
===================================================================
--- /branches/1.0/xapian-core/backends/flint/flint_table.cc (revision 10168)
+++ /branches/1.0/xapian-core/backends/flint/flint_table.cc (revision 10402)
@@ -1258,5 +1258,7 @@
 
     for (int i = 2; i <= n; i++) {
-	next(C_, 0);
+	if (!next(C_, 0)) {
+	    throw Xapian::DatabaseCorruptError("Unexpected end of table when reading continuation of tag");
+	}
 	(void)Item_(C_[0].p, C_[0].c).append_chunk(tag);
     }
@@ -1965,8 +1967,26 @@
 	    if (n == 0) return false;
 	    n--;
-	    // Check if the block is in the built-in cursor (potentially in
-	    // modified form).
-	    if (writable && n == C[0].n) {
-		memcpy(p, C[0].p, block_size);
+	    if (writable) {
+		if (n == C[0].n) {
+		    // Block is a leaf block in the built-in cursor
+		    // (potentially in modified form).
+		    memcpy(p, C[0].p, block_size);
+		} else {
+		    // Blocks in the built-in cursor may not have been written
+		    // to disk yet, so we have to check that the block number
+		    // isn't in the built-in cursor or we'll read an
+		    // uninitialised block (for which GET_LEVEL(p) will
+		    // probably return 0).
+		    int j;
+		    for (j = 1; j <= level; ++j) {
+			if (n == C[j].n) break;
+		    }
+		    if (j <= level) continue;
+
+		    // Block isn't in the built-in cursor, so the form on disk
+		    // is valid, so read it to check if it's the next level 0
+		    // block.
+		    read_block(n, p);
+		}
 	    } else {
 		read_block(n, p);
@@ -1993,4 +2013,5 @@
     int c = C_[0].c;
     c += D2;
+    Assert((unsigned)c < block_size);
     if (c == DIR_END(p)) {
 	uint4 n = C_[0].n;
@@ -1998,8 +2019,26 @@
 	    n++;
 	    if (n > base.get_last_block()) return false;
-	    // Check if the block is in the built-in cursor (potentially in
-	    // modified form).
-	    if (writable && n == C[0].n) {
-		memcpy(p, C[0].p, block_size);
+	    if (writable) {
+		if (n == C[0].n) {
+		    // Block is a leaf block in the built-in cursor
+		    // (potentially in modified form).
+		    memcpy(p, C[0].p, block_size);
+		} else {
+		    // Blocks in the built-in cursor may not have been written
+		    // to disk yet, so we have to check that the block number
+		    // isn't in the built-in cursor or we'll read an
+		    // uninitialised block (for which GET_LEVEL(p) will
+		    // probably return 0).
+		    int j;
+		    for (j = 1; j <= level; ++j) {
+			if (n == C[j].n) break;
+		    }
+		    if (j <= level) continue;
+
+		    // Block isn't in the built-in cursor, so the form on disk
+		    // is valid, so read it to check if it's the next level 0
+		    // block.
+		    read_block(n, p);
+		}
 	    } else {
 		read_block(n, p);
Index: /branches/1.0/xapian-core/backends/flint/flint_btreebase.cc
===================================================================
--- /branches/1.0/xapian-core/backends/flint/flint_btreebase.cc (revision 10154)
+++ /branches/1.0/xapian-core/backends/flint/flint_btreebase.cc (revision 10402)
@@ -425,4 +425,7 @@
     bit_map[i] |= d;   /* set as 'in use' */
     bit_map_low = i;
+    if (n > last_block) {
+	last_block = n;
+    }
     return n;
 }
