diff options
| author | Max Horn | 2011-01-06 21:11:24 +0000 | 
|---|---|---|
| committer | Max Horn | 2011-01-06 21:11:24 +0000 | 
| commit | 4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f (patch) | |
| tree | 47b453d24a6b96c85303e239d5559a62109a33ce | |
| parent | fc130351f3cd5ca53607d109e31948dddc6db4a3 (diff) | |
| download | scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.tar.gz scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.tar.bz2 scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.zip  | |
AGI: Rewrote predictive code matcher
The new code is simpler, avoids a potential buffer overrun
(by avoiding to to use a buffer in the first place), and
hopefully has slightly more sane matching properties.
svn-id: r55135
| -rw-r--r-- | engines/agi/predictive.cpp | 52 | 
1 files changed, 21 insertions, 31 deletions
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp index 3ab3f31e03..0230b9bd74 100644 --- a/engines/agi/predictive.cpp +++ b/engines/agi/predictive.cpp @@ -555,43 +555,33 @@ void AgiEngine::loadDict() {  }  bool AgiEngine::matchWord() { -	if (_currentCode.empty()) { +	// If no text has been entered, then there is no match. +	if (_currentCode.empty())  		return false; -	} -	// Lookup word in the dictionary -	int line = 0, cmpRes = 0, len = 0; -	char target[MAXWORDLEN]; - -	strncpy(target, _currentCode.c_str(), MAXWORDLEN); -	strcat(target, " "); - -	// do the search at most two times: -	// first try to match the exact code, by matching also the space after the code -	// if there is not an exact match, do it once more for the best matching prefix (drop the space) -	len = _currentCode.size() + 1; -	for (int i = 0; i < 2; ++i) { -		// Perform a binary search. -		int hi = _predictiveDictLineCount - 1; -		int lo = 0; -		while (lo <= hi) { -			line = (lo + hi) / 2; -			cmpRes = strncmp(_predictiveDictLine[line], target, len); -			if (cmpRes > 0) -				hi = line - 1; -			else if (cmpRes < 0) -				lo = line + 1; -			else -				break; -		} -		if (cmpRes == 0)  // Exact match found? -> stop now -			break; -		len--;  // Remove the trailing space +	// If the currently entered text is too long, it cannot match anything. +	if (_currentCode.size() > MAXWORDLEN) +		return false; + +	// Perform a binary search on the dictionary to find the first +	// entry that has _currentCode as a prefix. +	int hi = _predictiveDictLineCount - 1; +	int lo = 0; +	int line = 0; +	while (lo < hi) { +		line = (lo + hi) / 2; +		int cmpVal = strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size()); +		if (cmpVal > 0) +			hi = line - 1; +		else if (cmpVal < 0) +			lo = line + 1; +		else +			hi = line;  	}  	_currentWord.clear();  	_wordNumber = 0; -	if (!strncmp(_predictiveDictLine[line], target, len)) { +	if (0 == strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size())) {  		_predictiveDictActLine = _predictiveDictLine[line];  		char tmp[MAXLINELEN];  		strncpy(tmp, _predictiveDictActLine, MAXLINELEN);  | 
