fixed a series of addressing bugs where the indexer could reach past basearray bounds
authorDavid Anderson <dvander@alliedmods.net>
Thu Dec 07 08:17:19 2006 +0000 (2006-12-07)
changeset 194762462458f3c
parent 193 4a3e7a100b14
child 195 625a44869e15
fixed a series of addressing bugs where the indexer could reach past basearray bounds
core/sm_trie.cpp
     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)