fixed a series of addressing bugs where the indexer could reach past basearray bounds
fixed a series of addressing bugs where the indexer could reach past basearray bounds
1.1 --- a/core/sm_trie.cpp Wed Dec 06 23:35:51 2006 +0000
1.2 +++ b/core/sm_trie.cpp Thu Dec 07 08:17:19 2006 +0000
1.3 @@ -290,7 +290,7 @@
1.4 keyptr++;
1.5
1.6 /* Check if this slot is supposed to be empty or is a collision */
1.7 - if (node->mode == Node_Unused || node->parent != lastidx)
1.8 + if ((curidx > trie->baseSize) || node->mode == Node_Unused || node->parent != lastidx)
1.9 {
1.10 return false;
1.11 } else if (node->mode == Node_Term) {
1.12 @@ -349,12 +349,24 @@
1.13 /* Check if this slot is supposed to be empty. If so, we need to handle CASES 1/2:
1.14 * Insertion without collisions
1.15 */
1.16 - if (node->mode == Node_Unused)
1.17 + if ( (curidx > trie->baseSize) || (node->mode == Node_Unused) )
1.18 {
1.19 - /* Assign backcheck reference */
1.20 + if (curidx > trie->baseSize)
1.21 + {
1.22 + if (!sm_trie_grow(trie))
1.23 + {
1.24 + return false;
1.25 + }
1.26 + node = &trie->base[curidx];
1.27 + }
1.28 node->parent = lastidx;
1.29 - node->idx = x_addstring(trie, keyptr);
1.30 - node->mode = Node_Term;
1.31 + if (*keyptr == '\0')
1.32 + {
1.33 + node->mode = Node_Arc;
1.34 + } else {
1.35 + node->idx = x_addstring(trie, keyptr);
1.36 + node->mode = Node_Term;
1.37 + }
1.38 node->valset = true;
1.39 node->value = value;
1.40
1.41 @@ -383,7 +395,14 @@
1.42 unsigned int outgoing_list[256];
1.43 unsigned int outgoing_count = 0; /* count the current index here */
1.44 cur = &base[outgoing_base] + 1;
1.45 - for (unsigned int i=1; i<=255; i++,cur++)
1.46 + unsigned int outgoing_limit = 255;
1.47 +
1.48 + if (outgoing_base + outgoing_limit > trie->baseSize)
1.49 + {
1.50 + outgoing_limit = trie->baseSize - outgoing_base;
1.51 + }
1.52 +
1.53 + for (unsigned int i=1; i<=outgoing_limit; i++,cur++)
1.54 {
1.55 if (cur->mode == Node_Unused || cur->parent != lastidx)
1.56 {
1.57 @@ -400,7 +419,14 @@
1.58 unsigned int incoming_list[256];
1.59 unsigned int incoming_base = base[node->parent].idx;
1.60 unsigned int incoming_count = 0;
1.61 + unsigned int incoming_limit = 255;
1.62 cur = &base[incoming_base] + 1;
1.63 +
1.64 + if (incoming_base + incoming_limit > trie->baseSize)
1.65 + {
1.66 + incoming_limit = trie->baseSize - incoming_limit;
1.67 + }
1.68 +
1.69 for (unsigned int i=1; i<=255; i++,cur++)
1.70 {
1.71 if (cur->mode == Node_Arc || cur->mode == Node_Term)
1.72 @@ -437,6 +463,7 @@
1.73 lastidx = newidx;
1.74 }
1.75 base[newidx] = base[oldidx];
1.76 + assert(base[base[newidx].parent].mode == Node_Arc);
1.77 memset(&base[oldidx], 0, sizeof(TrieNode));
1.78 /* If we are not a terminator, we have children we must take care of */
1.79 if (base[newidx].mode == Node_Arc)
1.80 @@ -480,6 +507,7 @@
1.81 lastidx = newidx;
1.82 }
1.83 base[newidx] = base[oldidx];
1.84 + assert(base[base[newidx].parent].mode == Node_Arc);
1.85 memset(&base[oldidx], 0, sizeof(TrieNode));
1.86 /* If we are not a terminator, we have children we must take care of */
1.87 if (base[newidx].mode == Node_Arc)