From 3347b7a00682a0498a2602ce3e4e72c2c3d49c75 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 16 May 2024 22:15:26 +0000 Subject: Deal better with spurious spaces in arch restrictions Another instance of our parser written for sane clean input, but nowadays used also for user-provided input which can contain very many strange formatting and especially white spaces all over the place. Closes: #1071219 --- apt-pkg/deb/deblistparser.cc | 85 +++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 44 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') 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)) -- cgit v1.2.3-70-g09d2