summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/deb/deblistparser.cc85
-rw-r--r--test/libapt/parsedepends_test.cc52
2 files changed, 93 insertions, 44 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 9177d54f4..13e8fd06d 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -635,63 +635,60 @@ const char *debListParser::ParseDepends(const char *Start, const char *Stop,
// Skip whitespace
for (;I != Stop && isspace_ascii(*I) != 0; I++);
- if (unlikely(ParseArchFlags == true))
+ // Parse architecture restrictions
+ if (ParseArchFlags && I != Stop && *I == '[')
{
+ for (++I; I != Stop && isspace_ascii(*I) != 0 && *I != ']'; ++I);
+ // malformed
+ if (unlikely(I == Stop || *I == ']'))
+ return 0;
+
APT::CacheFilter::PackageArchitectureMatchesSpecification matchesArch(Arch, false);
- // Parse an architecture
- if (I != Stop && *I == '[')
+ bool Found = false;
+ bool NegArch = false;
+ while (I < Stop && *I != ']')
{
- ++I;
- // malformed
- if (unlikely(I == Stop))
- return 0;
-
+ // look for whitespace or ending ']' to end current Arch
const char *End = I;
- bool Found = false;
- bool NegArch = false;
- while (I != Stop)
- {
- // look for whitespace or ending ']'
- for (;End != Stop && !isspace_ascii(*End) && *End != ']'; ++End);
-
- if (unlikely(End == Stop))
- return 0;
-
- if (*I == '!')
- {
- NegArch = true;
- ++I;
- }
-
- std::string const arch(I, End);
- if (arch.empty() == false && matchesArch(arch.c_str()) == true)
- {
- Found = true;
- if (I[-1] != '!')
- NegArch = false;
- // we found a match, so fast-forward to the end of the wildcards
- for (; End != Stop && *End != ']'; ++End);
- }
+ for (;End < Stop && isspace_ascii(*End) == 0 && *End != ']'; ++End);
- if (*End++ == ']') {
- I = End;
- break;
- }
+ if (unlikely(End >= Stop))
+ return 0;
- I = End;
- for (;I != Stop && isspace_ascii(*I) != 0; I++);
+ bool CurNegArch = false;
+ if (*I == '!')
+ {
+ NegArch = true;
+ CurNegArch = true;
+ ++I;
}
- if (NegArch == true)
- Found = !Found;
+ if (I >= End)
+ return 0;
+ std::string const arch(I, End);
+ if (matchesArch(arch.c_str()))
+ {
+ Found = true;
+ if (not CurNegArch)
+ NegArch = false;
+ // we found a match, so fast-forward to the end of the wildcards
+ for (; End < Stop && *End != ']'; ++End);
+ }
+ else
+ for (; End < Stop && isspace_ascii(*End) != 0; ++End);
- if (Found == false)
- Package = ""; /* not for this arch */
+ I = End;
}
+ if (NegArch == true)
+ Found = not Found;
+
+ if (Found == false)
+ Package = ""; /* not for this arch */
+
// Skip whitespace
- for (;I != Stop && isspace_ascii(*I) != 0; I++);
+ for (++I; I < Stop && isspace_ascii(*I) != 0; ++I);
}
if (unlikely(ParseRestrictionsList == true))
diff --git a/test/libapt/parsedepends_test.cc b/test/libapt/parsedepends_test.cc
index 9771c5d24..296750b51 100644
--- a/test/libapt/parsedepends_test.cc
+++ b/test/libapt/parsedepends_test.cc
@@ -311,3 +311,55 @@ TEST(ParseDependsTest, SpaceHate)
EXPECT_EQ("1", Version);
EXPECT_EQ(pkgCache::Dep::Equals, Op);
}
+
+static void ArchLimitSpaceTesting(char const * const Depends)
+{
+ SCOPED_TRACE(Depends);
+ _config->Set("APT::Architecture", "amd64");
+ const char* const End = Depends + strlen(Depends);
+ const char* Start = Depends;
+ std::string Package;
+ std::string Version;
+ unsigned int Op = 29;
+
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, true, false, true, "amd64");
+ EXPECT_NE(nullptr, Start);
+ EXPECT_EQ("foobar", Package);
+ EXPECT_EQ("", Version);
+ EXPECT_EQ(pkgCache::Dep::NoOp, Op);
+
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, true, false, true, "amd64");
+ EXPECT_NE(nullptr, Start);
+ EXPECT_EQ("", Package);
+ EXPECT_EQ("", Version);
+ EXPECT_EQ(pkgCache::Dep::NoOp, Op);
+
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, true, false, true, "amd64");
+ EXPECT_EQ(End, Start);
+ EXPECT_EQ("baz", Package);
+ EXPECT_EQ("", Version);
+ EXPECT_EQ(pkgCache::Dep::NoOp, Op);
+}
+TEST(ParseDependsTest, ArchLimitSpaceNormal)
+{
+ ArchLimitSpaceTesting("foobar [i386 armhf armel amd64], blah [!arm64 !x32 !amd64], baz");
+}
+TEST(ParseDependsTest, ArchLimitSpaceLove)
+{
+ ArchLimitSpaceTesting("foobar [ i386 armhf armel amd64 ] , blah [ !arm64 !x32 !amd64 ] , baz");
+}
+TEST(ParseDependsTest, ArchLimitSpaceNoLove)
+{
+ ArchLimitSpaceTesting("foobar[i386 armhf armel amd64],blah[!arm64 !x32 !amd64],baz");
+}
+TEST(ParseDependsTest, ArchLimitBadSyntax)
+{
+ std::string Package;
+ std::string Version;
+ unsigned int Op = 29;
+ for (auto const * const Depends : { "foobar [! amd64]", "foobar []", "foobar [ ]" })
+ {
+ SCOPED_TRACE(Depends);
+ EXPECT_EQ(nullptr, debListParser::ParseDepends(Depends, Depends + strlen(Depends), Package, Version, Op, true, false, true, "amd64"));
+ }
+}