Skip to content

Commit

Permalink
Fix Format function to not cut of last character
Browse files Browse the repository at this point in the history
This fixes broke game save

The beginning of a saved game looked like this:
00000000: 6c6f 6361 6c20 6f6c 6443 7265 6174 6555  local oldCreateU
00000010: 6e69 7420 3d20 4372 6561 7465 556e 6974  nit = CreateUnit
00000020: 006c 6f63 616c 206f 6c64 5365 7452 6573  .local oldSetRes
00000030: 6f75 7263 6573 4865 6c64 203d 2053 6574  ourcesHeld = Set
00000040: 5265 736f 7572 6365 7348 656c 6400 6c6f  ResourcesHeld.lo

The newlines are replaced by null-characters so games could not be
loaded again
  • Loading branch information
zzam committed Oct 27, 2024
1 parent ac030c8 commit d7a987a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ set(stratagus_tests_SRCS
tests/main.cpp
tests/stratagus/test_action_built.cpp
tests/stratagus/test_depend.cpp
tests/stratagus/test_format.cpp
tests/stratagus/test_luacallback.cpp
tests/stratagus/test_missile_fire.cpp
tests/stratagus/test_trigger.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/include/stratagus.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ std::string Format(const char *format, Ts... args)
#endif
const auto len = snprintf(nullptr, 0, format, args...);
std::string res(len, '\0');
snprintf(res.data(), res.size(), format, args...);
// len+1: writing a '\0' over the existing '\0' should be fine
snprintf(res.data(), len + 1, format, args...);
#ifndef _MSC_VER
# pragma GCC diagnostic pop
#endif
Expand Down
48 changes: 48 additions & 0 deletions tests/stratagus/test_format.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name test_format.cpp - Test file for function Format. */
//
// (c) Copyright 2024 by Matthias Schwarzott
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; only version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//

#include <doctest.h>

#include "stratagus.h"

TEST_CASE("Format")
{
CHECK("" == Format(""));
CHECK("1" == Format("1"));
CHECK("12" == Format("12"));
CHECK("12\n" == Format("12\n"));
CHECK("abc\n" == Format("%s", "abc\n"));
CHECK("abc\n" == Format("%s\n", "abc"));
CHECK("12345" == Format("%d", 12345));
CHECK(" x" == Format("%*s", 10, "x"));
std::string result = Format("%*s", 100, "x");
CHECK(result[98] == ' ');
CHECK(result[99] == 'x');
CHECK(result.size() == 100);
}

0 comments on commit d7a987a

Please sign in to comment.