From d800cbb9d83ebd3cbf518119cdb4717008c0c3ed Mon Sep 17 00:00:00 2001
From: Kalle Olavi Niemitalo <kon@iki.fi>
Date: Thu, 21 Jun 2012 22:20:11 +0300
Subject: [PATCH] Treat _("string") as format string only if needed

There were many calls like SetMessage(_("Screenshot made.")), where
the called function treated the translated string as a format string
even though no format arguments were passed along.  Because the
original string did not contain any percent signs, xgettext did not
add the c-format flag to the entry in the PO file, and translators
then could have added percent signs without knowing that they had to
be doubled.

Change such calls to e.g. SetMessage("%s", _("Screenshot made.")), so
that percent signs in the translated string have no special effect.
Suggested by Jarod42.

This change does not help against intentionally malicious PO files
because there still are many translatable format strings.  Just search
for c-format in languages/*.po to see.  However, the change should
help against inadvertent mistakes.
---
 engine/action/action_build.cpp |    2 +-
 engine/game/player.cpp         |    8 ++++----
 engine/game/replay.cpp         |    8 ++++----
 engine/network/network.cpp     |    4 ++--
 engine/ui/interface.cpp        |    2 +-
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/engine/action/action_build.cpp b/engine/action/action_build.cpp
index 97e7749..7f16852 100644
--- a/engine/action/action_build.cpp
+++ b/engine/action/action_build.cpp
@@ -128,7 +128,7 @@ static void MoveToLocation(CUnit *unit)
 			}
 
 			unit->Player->Notify(NotifyYellow, unit->X, unit->Y,
-				_("You cannot reach building place"));
+				"%s", _("You cannot reach building place"));
 			if (unit->Player->AiEnabled) {
 				AiCanNotReach(unit, unit->Orders[0]->Type);
 			}
diff --git a/engine/game/player.cpp b/engine/game/player.cpp
index da539a5..a6f901c 100644
--- a/engine/game/player.cpp
+++ b/engine/game/player.cpp
@@ -699,15 +699,15 @@ int CPlayer::CheckLimits(const CUnitType *type) const
 	//
 	if (NumUnits < UnitMax) {
 		if (type->Building && NumBuildings >= BuildingLimit) {
-			Notify(NotifyYellow, -1, -1, _("Building Limit Reached"));
+			Notify(NotifyYellow, -1, -1, "%s", _("Building Limit Reached"));
 			return -1;
 		}
 		if (!type->Building && (TotalNumUnits - NumBuildings) >= UnitLimit) {
-			Notify(NotifyYellow, -1, -1, _("Unit Limit Reached"));
+			Notify(NotifyYellow, -1, -1, "%s", _("Unit Limit Reached"));
 			return -2;
 		}
 		if (TotalNumUnits >= TotalUnitLimit) {
-			Notify(NotifyYellow, -1, -1, _("Total Unit Limit Reached"));
+			Notify(NotifyYellow, -1, -1, "%s", _("Total Unit Limit Reached"));
 			return -4;
 		}
 		if (UnitTypesCount[type->Slot] >=  Allow.Units[type->Slot]) {
@@ -717,7 +717,7 @@ int CPlayer::CheckLimits(const CUnitType *type) const
 		}
 		return 1;
 	} else {
-		Notify(NotifyYellow, -1, -1, _("Cannot create more units."));
+		Notify(NotifyYellow, -1, -1, "%s", _("Cannot create more units."));
 		if (AiEnabled) {
 			// AiNoMoreUnits(player, type);
 		}
diff --git a/engine/game/replay.cpp b/engine/game/replay.cpp
index fb20873..1188033 100644
--- a/engine/game/replay.cpp
+++ b/engine/game/replay.cpp
@@ -763,7 +763,7 @@ static void DoNextReplay(void)
 #ifdef DEBUG
 		if (!ReplayStep->SyncRandSeed) {
 			// Replay without the 'sync info
-			ThisPlayer->Notify(NotifyYellow, -1, -1, _("No sync info for this replay !"));
+			ThisPlayer->Notify(NotifyYellow, -1, -1, "%s", _("No sync info for this replay !"));
 		} else {
 			ThisPlayer->Notify(NotifyYellow, -1, -1, _("Replay got out of sync (%lu) !"), GameCycle);
 			DebugPrint("OUT OF SYNC %u != %u\n" _C_ SyncRandSeed _C_ ReplayStep->SyncRandSeed);
@@ -774,7 +774,7 @@ static void DoNextReplay(void)
 			// return;
 		}
 #else
-		ThisPlayer->Notify(NotifyYellow, -1, -1, _("Replay got out of sync !"));
+		ThisPlayer->Notify(NotifyYellow, -1, -1, "%s", _("Replay got out of sync !"));
 		ReplayStep = 0;
 		NextLogCycle = ~0UL;
 		return;
@@ -872,7 +872,7 @@ static void ReplayEachCycle(void)
 	}
 
 	if (!ReplayStep) {
-		SetMessage(_("End of replay"));
+		SetMessage("%s", _("End of replay"));
 		GameObserve = false;
 		return;
 	}
@@ -886,7 +886,7 @@ static void ReplayEachCycle(void)
 	} while (ReplayStep && (NextLogCycle == ~0UL || NextLogCycle == GameCycle));
 
 	if (!ReplayStep) {
-		SetMessage(_("End of replay"));
+		SetMessage("%s", _("End of replay"));
 		GameObserve = false;
 	}
 }
diff --git a/engine/network/network.cpp b/engine/network/network.cpp
index 9a2f8a1..05fe0e4 100644
--- a/engine/network/network.cpp
+++ b/engine/network/network.cpp
@@ -1163,7 +1163,7 @@ static void ParseNetworkCommand(const CNetworkCommandQueue *ncq)
 			if (ply != NetworkSyncSeeds[GameCycle & 0xFF] ||
 					ntohs(ncq->Data.Unit) != NetworkSyncHashs[GameCycle & 0xFF]) {
 
-				SetMessage(_("Network out of sync"));
+				SetMessage("%s", _("Network out of sync"));
 				DebugPrint("\nNetwork out of sync %x!=%x! %d!=%d! Cycle %lu\n\n" _C_
 					ply _C_ NetworkSyncSeeds[GameCycle & 0xFF] _C_
 					ntohs(ncq->Data.Unit) _C_ NetworkSyncHashs[GameCycle & 0xFF] _C_ GameCycle);
@@ -1412,7 +1412,7 @@ void NetworkRecover(void)
 				NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Type = MessageQuit;
 				NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Data = nc;
 				PlayerQuit[Hosts[i].PlyNr] = 1;
-				SetMessage(_("Timed out"));
+				SetMessage("%s", _("Timed out"));
 
 				ncq = &NetworkIn[n & 0xFF][Hosts[i].PlyNr][0];
 				np.Header.Cycle = ncq->Time & 0xFF;
diff --git a/engine/ui/interface.cpp b/engine/ui/interface.cpp
index dff320c..7e23858 100644
--- a/engine/ui/interface.cpp
+++ b/engine/ui/interface.cpp
@@ -908,7 +908,7 @@ int HandleKeyModifiersDown(unsigned key, unsigned keychar)
 		case SDLK_PRINT:
 			Screenshot();
 			if (GameRunning) {
-				SetMessage(_("Screenshot made."));
+				SetMessage("%s", _("Screenshot made."));
 			}
 			return 1;
 		default:
-- 
1.7.10

