mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-18 19:29:09 +00:00
Fix substring indexing and whitespace.
Fixes an off-by-one and off-by-initial-offset error, not clearing the stream between loops, and a few other edge conditions.
This commit is contained in:
@ -69,8 +69,8 @@ pfLocalizedString::pfLocalizedString(const plString & plainText)
|
|||||||
void pfLocalizedString::IParameterize(const plString & inString)
|
void pfLocalizedString::IParameterize(const plString & inString)
|
||||||
{
|
{
|
||||||
textBlock curTextBlock;
|
textBlock curTextBlock;
|
||||||
fNumArguments = 0; // Reset the argument count.
|
fNumArguments = 0; // Reset the argument count.
|
||||||
fText.clear(); // Reset the text blocks.
|
fText.clear(); // Reset the text blocks.
|
||||||
|
|
||||||
plString remainder = inString;
|
plString remainder = inString;
|
||||||
plStringStream newText;
|
plStringStream newText;
|
||||||
@ -79,61 +79,77 @@ void pfLocalizedString::IParameterize(const plString & inString)
|
|||||||
|
|
||||||
while (!remainder.IsEmpty())
|
while (!remainder.IsEmpty())
|
||||||
{
|
{
|
||||||
// Check if we have any params.
|
// Check if we have any params.
|
||||||
nextToken = remainder.Find("%");
|
nextToken = remainder.Find("%");
|
||||||
if (nextToken != -1)
|
if (nextToken != -1)
|
||||||
{
|
{
|
||||||
// Check it's not escaped.
|
// Check it's not escaped.
|
||||||
if ((nextToken > 0) && (remainder.CharAt(nextToken-1) != '\\'))
|
if ((nextToken == 0) || ((nextToken > 0) && (remainder.CharAt(nextToken-1) != '\\')))
|
||||||
{
|
{
|
||||||
// Check if it has an end.
|
// Check if it has an end (ignoring any terminators we need to cross a space to find).
|
||||||
int endToken = remainder.Substr(nextToken).Find("s");
|
int endToken = remainder.Substr(nextToken).Find("s");
|
||||||
if (endToken != -1)
|
if ((endToken != -1) && (remainder.Substr(nextToken, endToken).Find(" ") == -1))
|
||||||
{
|
{
|
||||||
// Store existing block.
|
// Store existing block if it contains anything.
|
||||||
newText << remainder;
|
newText << remainder.Substr(0, nextToken);
|
||||||
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
|
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
|
||||||
fText.push_back(curTextBlock);
|
if (!curTextBlock.fText.IsEmpty())
|
||||||
|
{
|
||||||
|
fText.push_back(curTextBlock);
|
||||||
|
newText.Truncate();
|
||||||
|
}
|
||||||
|
|
||||||
if (endToken == nextToken + 1)
|
if (endToken == nextToken + 1)
|
||||||
{
|
{
|
||||||
// Store non-indexed param block.
|
// Store non-indexed param block.
|
||||||
curTextBlock.fIsParam = true;
|
curTextBlock.fIsParam = true;
|
||||||
curTextBlock.fParamIndex = curParameter++;
|
curTextBlock.fParamIndex = curParameter++;
|
||||||
curTextBlock.fText = "";
|
curTextBlock.fText = "";
|
||||||
fText.push_back(curTextBlock);
|
fText.push_back(curTextBlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Store indexed param block.
|
// Store indexed param block.
|
||||||
curTextBlock.fIsParam = true;
|
curTextBlock.fIsParam = true;
|
||||||
curTextBlock.fParamIndex = remainder.Substr(nextToken, endToken-1).ToInt(10) - 1; // args start at 1
|
curTextBlock.fParamIndex = remainder.Substr(nextToken + 1, endToken - 1).ToInt(10) - 1; // args start at 1
|
||||||
curTextBlock.fText = "";
|
curTextBlock.fText = "";
|
||||||
fText.push_back(curTextBlock);
|
fText.push_back(curTextBlock);
|
||||||
}
|
}
|
||||||
curTextBlock.fIsParam = false;
|
curTextBlock.fIsParam = false;
|
||||||
curTextBlock.fParamIndex = 0;
|
curTextBlock.fParamIndex = 0;
|
||||||
fNumArguments++;
|
fNumArguments++;
|
||||||
|
|
||||||
// Continue using the remaining string.
|
// Continue, using the remaining string.
|
||||||
remainder = remainder.Substr(endToken+1);
|
remainder = remainder.Substr(nextToken + endToken + 1);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
// We have an unescaped but unterminated %.
|
||||||
|
// For now, let's just pretend it was escaped;
|
||||||
|
// This way they'll show up visibly in-game and will be reported.
|
||||||
|
newText << "%";
|
||||||
|
remainder = remainder.Substr(nextToken + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Copy the text up to the escape character, skip it, and continue.
|
// Copy the text up to the escape character, skip it, and continue.
|
||||||
newText << remainder.Substr(0, nextToken - 1) << '%';
|
newText << remainder.Substr(0, nextToken - 1) << '%';
|
||||||
remainder = remainder.Substr(nextToken + 1);
|
remainder = remainder.Substr(nextToken + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We're done. Copy the remaining text and finish.
|
// We're done. Copy the remaining text and finish.
|
||||||
newText << remainder;
|
newText << remainder;
|
||||||
remainder = "";
|
remainder = "";
|
||||||
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
|
curTextBlock.fText = newText.GetString().Replace("\\\\", "\\");
|
||||||
fText.push_back(curTextBlock);
|
if (!curTextBlock.fText.IsEmpty())
|
||||||
}
|
{
|
||||||
|
fText.push_back(curTextBlock);
|
||||||
|
newText.Truncate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +175,7 @@ void pfLocalizedString::IUpdatePlainText()
|
|||||||
if (curTextBlock.fIsParam)
|
if (curTextBlock.fIsParam)
|
||||||
{
|
{
|
||||||
// Fill in parameter value.
|
// Fill in parameter value.
|
||||||
ss << plString::Format("%%%ds", curTextBlock.fParamIndex + 1);
|
ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -192,8 +208,7 @@ void pfLocalizedString::IUpdateXML()
|
|||||||
if (curTextBlock.fIsParam)
|
if (curTextBlock.fIsParam)
|
||||||
{
|
{
|
||||||
// Fill in parameter value.
|
// Fill in parameter value.
|
||||||
plString paramStr = plString::Format("%%%ds", curTextBlock.fParamIndex + 1);
|
ss << "%%" << curTextBlock.fParamIndex + 1 << "s";
|
||||||
ss << paramStr;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user