Skip to content

Commit 587b2c4

Browse files
authored
fix for issues with char duplication (#309)
* fix for issues with char duplication * fixes and tests
1 parent ef11e6a commit 587b2c4

File tree

5 files changed

+68
-16
lines changed

5 files changed

+68
-16
lines changed

.github/workflows/linux_coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
analyze:
5757
name: Coverage Check Foreign
5858
if: github.repository_owner != 'ParadoxGameConverters'
59-
runs-on: ubuntu-22.04
59+
runs-on: ubuntu-latest
6060

6161
strategy:
6262
fail-fast: false

Parser.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,9 @@ std::string commonItems::getNextLexeme(std::istream& theStream)
270270
auto inLiteralQuote = false;
271271
unsigned char previousCharacter = '\0';
272272

273-
while (true)
273+
char inputChar;
274+
while (theStream >> inputChar)
274275
{
275-
char inputChar;
276-
theStream >> inputChar;
277-
if (theStream.eof())
278-
break;
279276
if (!inQuotes && inputChar == '#')
280277
{
281278
std::string bitBucket;

ParserHelpers.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -451,19 +451,13 @@ stringOfItem::stringOfItem(std::istream& theStream)
451451
{
452452
bool inQuotes = false;
453453
auto braceDepth = 1;
454-
while (true)
454+
unsigned char previousCharacter = '\0';
455+
char inputChar;
456+
while (theStream >> inputChar)
455457
{
456-
if (theStream.eof())
457-
{
458-
return;
459-
}
460-
461-
char inputChar;
462-
theStream >> inputChar;
463-
464458
theString += inputChar;
465459

466-
if (inputChar == '\"')
460+
if (inputChar == '\"' && previousCharacter != '\\')
467461
{
468462
if (!inQuotes)
469463
{
@@ -486,6 +480,7 @@ stringOfItem::stringOfItem(std::istream& theStream)
486480
return;
487481
}
488482
}
483+
previousCharacter = inputChar;
489484
}
490485
}
491486
}

tests/ParserHelperTests.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ TEST(ParserHelper_Tests, IgnoreItemIgnoresAssignedBracedItem)
5252
ASSERT_EQ(" More text", std::string{buffer});
5353
}
5454

55+
TEST(ParserHelper_Tests, IgnoreItemIgnoresMisquotedItem)
56+
{
57+
std::stringstream input{"= \\\"ignore_me\" More text"};
58+
input >> std::noskipws;
59+
commonItems::ignoreItem("unused", input);
60+
61+
char buffer[256];
62+
input.getline(buffer, sizeof buffer);
63+
ASSERT_EQ("More text", std::string{buffer});
64+
}
65+
66+
TEST(ParserHelper_Tests, IgnoreItemIgnoresMisquotedBracedItem)
67+
{
68+
std::stringstream input{"= { \\\"ignore_me\" } More text"};
69+
input >> std::noskipws;
70+
commonItems::ignoreItem("unused", input);
71+
72+
char buffer[256];
73+
input.getline(buffer, sizeof buffer);
74+
ASSERT_EQ(" More text", std::string{buffer});
75+
}
76+
5577
TEST(ParserHelper_Tests, IgnoreItemIgnoresAssignedBracedItemOnExistsEquals)
5678
{
5779
std::stringstream input{"?= { { ignore_me } } More text"};
@@ -867,6 +889,21 @@ TEST(ParserHelper_Tests, StringOfItemGetsStringAfterEquals)
867889
}
868890

869891

892+
TEST(ParserHelper_Tests, StringOfItemHandlesMismatchedQuotes)
893+
{
894+
std::stringstream input;
895+
input >> std::noskipws;
896+
input << "= {\n";
897+
input << "\tfoo = \"some junk\\\"\" \n";
898+
input << "\tbar = baz\n";
899+
input << "}";
900+
901+
const commonItems::stringOfItem theItem(input);
902+
903+
ASSERT_EQ(input.str(), theItem.getString());
904+
}
905+
906+
870907
TEST(ParserHelper_Tests, StringOfItemsConvertsItemsWithinBracesToStrings)
871908
{
872909
std::stringstream input;

tests/ParserTests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,29 @@ TEST(Parser_Tests, QuotedRegexesAreQuotedlyMatched)
387387
EXPECT_EQ("value", test.value);
388388
}
389389

390+
TEST(Parser_Tests, MisQuotedRegexesAreQuotedlyMatched)
391+
{
392+
std::stringstream input{R"("\"key" = value)"};
393+
class Test: commonItems::parser
394+
{
395+
public:
396+
explicit Test(std::istream& stream)
397+
{
398+
registerRegex(R"([k\"\\ey]+)", [this](const std::string& keyword, std::istream& theStream) {
399+
key = keyword;
400+
value = commonItems::getString(theStream);
401+
});
402+
parseStream(stream);
403+
}
404+
std::string key;
405+
std::string value;
406+
};
407+
const auto test = Test(input);
408+
409+
EXPECT_EQ("\"\\\"key\"", test.key);
410+
EXPECT_EQ("value", test.value);
411+
}
412+
390413
TEST(Parser_Tests, CatchAllCatchesQuotedKeys)
391414
{
392415
std::stringstream input{"\"key\" = value"};

0 commit comments

Comments
 (0)