Changeset - r14951:e24469d4e684
[Not reviewed]
master
0 3 0
yexo - 14 years ago 2010-04-06 21:16:36
yexo@openttd.org
(svn r19569) -Fix: possible buffer underflow in newgrf string code
3 files changed with 5 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/newgrf_text.cpp
Show inline comments
 
@@ -627,25 +627,25 @@ void RewindTextRefStack()
 
{
 
	_newgrf_textrefstack->RewindStack();
 
}
 

	
 
/**
 
 * FormatString for NewGRF specific "magic" string control codes
 
 * @param scc   the string control code that has been read
 
 * @param buff  the buffer we're writing to
 
 * @param str   the string that we need to write
 
 * @param argv  the OpenTTD stack of values
 
 * @return the string control code to "execute" now
 
 */
 
uint RemapNewGRFStringControlCode(uint scc, char **buff, const char **str, int64 *argv)
 
uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const char **str, int64 *argv)
 
{
 
	if (_newgrf_textrefstack->used) {
 
		switch (scc) {
 
			default: NOT_REACHED();
 
			case SCC_NEWGRF_PRINT_SIGNED_BYTE:    *argv = _newgrf_textrefstack->PopSignedByte();    break;
 
			case SCC_NEWGRF_PRINT_SIGNED_WORD:    *argv = _newgrf_textrefstack->PopSignedWord();    break;
 
			case SCC_NEWGRF_PRINT_QWORD_CURRENCY: *argv = _newgrf_textrefstack->PopUnsignedQWord(); break;
 

	
 
			case SCC_NEWGRF_PRINT_DWORD_CURRENCY:
 
			case SCC_NEWGRF_PRINT_DWORD:          *argv = _newgrf_textrefstack->PopSignedDWord();   break;
 

	
 
			case SCC_NEWGRF_PRINT_HEX_BYTE:       *argv = _newgrf_textrefstack->PopUnsignedByte();  break;
 
@@ -654,25 +654,25 @@ uint RemapNewGRFStringControlCode(uint s
 
			case SCC_NEWGRF_PRINT_HEX_WORD:
 
			case SCC_NEWGRF_PRINT_WORD_SPEED:
 
			case SCC_NEWGRF_PRINT_WORD_LITRES:
 
			case SCC_NEWGRF_PRINT_UNSIGNED_WORD:  *argv = _newgrf_textrefstack->PopUnsignedWord();  break;
 

	
 
			case SCC_NEWGRF_PRINT_DATE:
 
			case SCC_NEWGRF_PRINT_MONTH_YEAR:     *argv = _newgrf_textrefstack->PopSignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; break;
 

	
 
			case SCC_NEWGRF_DISCARD_WORD:         _newgrf_textrefstack->PopUnsignedWord(); break;
 

	
 
			case SCC_NEWGRF_ROTATE_TOP_4_WORDS:   _newgrf_textrefstack->RotateTop4Words(); break;
 
			case SCC_NEWGRF_PUSH_WORD:            _newgrf_textrefstack->PushWord(Utf8Consume(str)); break;
 
			case SCC_NEWGRF_UNPRINT:              *buff -= Utf8Consume(str); break;
 
			case SCC_NEWGRF_UNPRINT:              *buff = max(*buff - Utf8Consume(str), buf_start); break;
 

	
 
			case SCC_NEWGRF_PRINT_STRING_ID:
 
				*argv = TTDPStringIDToOTTDStringIDMapping(_newgrf_textrefstack->PopUnsignedWord());
 
				break;
 
		}
 
	}
 

	
 
	switch (scc) {
 
		default: NOT_REACHED();
 
		case SCC_NEWGRF_PRINT_DWORD:
 
		case SCC_NEWGRF_PRINT_SIGNED_WORD:
 
		case SCC_NEWGRF_PRINT_SIGNED_BYTE:
src/newgrf_text.h
Show inline comments
 
@@ -19,17 +19,17 @@ StringID GetGRFStringID(uint32 grfid, ui
 
const char *GetGRFStringPtr(uint16 stringid);
 
void CleanUpStrings();
 
void SetCurrentGrfLangID(byte language_id);
 
char *TranslateTTDPatchCodes(uint32 grfid, const char *str);
 

	
 
bool CheckGrfLangID(byte lang_id, byte grf_version);
 

	
 
void PrepareTextRefStackUsage(byte numEntries);
 
void StopTextRefStackUsage();
 
void SwitchToNormalRefStack();
 
void SwitchToErrorRefStack();
 
void RewindTextRefStack();
 
uint RemapNewGRFStringControlCode(uint scc, char **buff, const char **str, int64 *argv);
 
uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const char **str, int64 *argv);
 

	
 
StringID TTDPStringIDToOTTDStringIDMapping(StringID string);
 

	
 
#endif /* NEWGRF_TEXT_H */
src/strings.cpp
Show inline comments
 
@@ -545,29 +545,30 @@ uint ConvertSpeedToDisplaySpeed(uint spe
 
 * @return the converted speed.
 
 */
 
uint ConvertDisplaySpeedToSpeed(uint speed)
 
{
 
	return ((speed << units[_settings_game.locale.units].s_s) + units[_settings_game.locale.units].s_m / 2) / units[_settings_game.locale.units].s_m;
 
}
 

	
 
static char *FormatString(char *buff, const char *str, int64 *argv, uint casei, const char *last)
 
{
 
	WChar b;
 
	int64 *argv_orig = argv;
 
	uint modifier = 0;
 
	char *buf_start = buff;
 

	
 
	while ((b = Utf8Consume(&str)) != '\0') {
 
		if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) {
 
			/* We need to pass some stuff as it might be modified; oh boy. */
 
			b = RemapNewGRFStringControlCode(b, &buff, &str, argv);
 
			b = RemapNewGRFStringControlCode(b, buf_start, &buff, &str, argv);
 
			if (b == 0) continue;
 
		}
 

	
 
		switch (b) {
 
			case SCC_SETX: // {SETX}
 
				if (buff + Utf8CharLen(SCC_SETX) + 1 < last) {
 
					buff += Utf8Encode(buff, SCC_SETX);
 
					*buff++ = *str++;
 
				}
 
				break;
 

	
 
			case SCC_SETXY: // {SETXY}
0 comments (0 inline, 0 general)