From f359b7e8c03884cd9f097d4b3ff8b8b8be8053ba Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 1 Dec 2015 14:09:23 +0100 Subject: require explicit paths to dsc/control as we do for deb files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise a user is subject to unexpected content-injection depending on which directory she happens to start apt in. This also cleans up the code requiring less implementation details in build-dep which is always good. Technically, this is an ABI break as we override virtual methods, but that they weren't overridden was a mistake resulting in pure classes, which shouldn't be pure, so they were unusable – and as they are new in 1.1 nobody is using them yet (and hopefully ever as they are borderline implementation details). Closes: 806693 --- apt-pkg/deb/debindexfile.cc | 18 +++++ apt-pkg/deb/debindexfile.h | 13 +++- apt-pkg/sourcelist.cc | 8 ++- apt-private/private-source.cc | 113 ++++++++++++++++-------------- test/integration/test-apt-get-build-dep | 15 +++- test/integration/test-apt-get-install-deb | 1 + 6 files changed, 108 insertions(+), 60 deletions(-) diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index 708b40a96..c11efd0ae 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -277,6 +277,24 @@ pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const if (Exists() == false) return NULL; return new debDscRecordParser(File, this); +} +std::string debDscFileIndex::GetComponent() const +{ + return "local-dsc"; +} +std::string debDscFileIndex::GetArchitecture() const +{ + return "source"; +} +uint8_t debDscFileIndex::GetIndexFlags() const +{ + return pkgCache::Flag::LocalSource; +} + /*}}}*/ +// ControlFile Index - a directory with a debian/control file /*{{{*/ +std::string debDebianSourceDirIndex::GetComponent() const +{ + return "local-control"; } /*}}}*/ diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index e96a4761e..890141dff 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -152,7 +152,13 @@ public: class debDscFileIndex : public pkgDebianIndexRealFile { void * const d; - public: + +protected: + virtual std::string GetComponent() const APT_OVERRIDE; + virtual std::string GetArchitecture() const APT_OVERRIDE; + virtual uint8_t GetIndexFlags() const APT_OVERRIDE; + +public: virtual const Type *GetType() const APT_OVERRIDE APT_CONST; virtual pkgSrcRecords::Parser *CreateSrcParser() const APT_OVERRIDE; virtual bool HasPackages() const APT_OVERRIDE {return false;}; @@ -163,7 +169,10 @@ class debDscFileIndex : public pkgDebianIndexRealFile class debDebianSourceDirIndex : public debDscFileIndex { - public: +protected: + virtual std::string GetComponent() const APT_OVERRIDE; + +public: virtual const Type *GetType() const APT_OVERRIDE APT_CONST; }; diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 1e6b831be..6773b069f 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -544,11 +544,17 @@ void pkgSourceList::AddVolatileFile(pkgIndexFile * const File) /*{{{*/ /*}}}*/ bool pkgSourceList::AddVolatileFile(std::string const &File) /*{{{*/ { + // Note: FileExists matches directories and links, too! if (File.empty() || FileExists(File) == false) return false; - if (flExtension(File) == "deb") + std::string const ext = flExtension(File); + if (ext == "deb") AddVolatileFile(new debDebPkgFileIndex(File)); + else if (ext == "dsc") + AddVolatileFile(new debDscFileIndex(File)); + else if (FileExists(flCombine(File, "debian/control"))) + AddVolatileFile(new debDscFileIndex(flCombine(File, "debian/control"))); else return false; diff --git a/apt-private/private-source.cc b/apt-private/private-source.cc index 546aa523f..52487248f 100644 --- a/apt-private/private-source.cc +++ b/apt-private/private-source.cc @@ -915,9 +915,39 @@ static bool InstallBuildDepsLoop(CacheFile &Cache, std::string const &Src, // --------------------------------------------------------------------- /* This function will look at the build depends list of the given source package and install the necessary packages to make it true, or fail. */ +static std::vector GetBuildDeps(pkgSrcRecords::Parser * const Last, + char const * const Src, bool const StripMultiArch, std::string const &hostArch) +{ + std::vector BuildDeps; + // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary + if (hostArch.empty() == false) + { + std::string nativeArch = _config->Find("APT::Architecture"); + _config->Set("APT::Architecture", hostArch); + bool Success = Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch); + _config->Set("APT::Architecture", nativeArch); + if (Success == false) + { + _error->Error(_("Unable to get build-dependency information for %s"), Src); + return {}; + } + } + else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false) + { + _error->Error(_("Unable to get build-dependency information for %s"), Src); + return {}; + } + + if (BuildDeps.empty() == true) + ioprintf(c1out,_("%s has no build depends.\n"), Src); + + return BuildDeps; +} bool DoBuildDep(CommandLine &CmdL) { CacheFile Cache; + std::vector VolatileCmdL; + Cache.GetSourceList()->AddVolatileFiles(CmdL, &VolatileCmdL); _config->Set("APT::Install-Recommends", false); @@ -926,7 +956,7 @@ bool DoBuildDep(CommandLine &CmdL) if (Cache.Open(WantLock) == false) return false; - if (CmdL.FileSize() <= 1) + if (CmdL.FileSize() <= 1 && VolatileCmdL.empty()) return _error->Error(_("Must specify at least one package to check builddeps for")); // Read the source list @@ -974,64 +1004,39 @@ bool DoBuildDep(CommandLine &CmdL) return false; } - unsigned J = 0; - for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) + // FIXME: Avoid volatile sources == cmdline assumption { - std::string Src; - pkgSrcRecords::Parser *Last = 0; - std::unique_ptr LastOwner; - - // an unpacked debian source tree - using APT::String::Startswith; - if ((Startswith(*I, "./") || Startswith(*I, "/")) && - DirectoryExists(*I)) - { - ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), *I); - // FIXME: how can we make this more elegant? - std::string TypeName = "Debian control file"; - pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); - if(Type != NULL) - LastOwner.reset(Last = Type->CreateSrcPkgParser(*I)); - } - // if its a local file (e.g. .dsc) use this - else if (FileExists(*I)) + auto const VolatileSources = List->GetVolatileFiles(); + if (VolatileSources.size() == VolatileCmdL.size()) { - ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), *I); - - // see if we can get a parser for this pkgIndexFile type - std::string TypeName = "Debian " + flExtension(*I) + " file"; - pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str()); - if(Type != NULL) - LastOwner.reset(Last = Type->CreateSrcPkgParser(*I)); - } else { - // normal case, search the cache for the source file - Last = FindSrc(*I,SrcRecs,Src,Cache); - } - - if (Last == 0) - return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); - - // Process the build-dependencies - std::vector BuildDeps; - // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary - if (hostArch.empty() == false) - { - std::string nativeArch = _config->Find("APT::Architecture"); - _config->Set("APT::Architecture", hostArch); - bool Success = Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch); - _config->Set("APT::Architecture", nativeArch); - if (Success == false) - return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str()); + for (size_t i = 0; i < VolatileSources.size(); ++i) + { + char const * const Src = VolatileCmdL[i]; + if (DirectoryExists(Src)) + ioprintf(c1out, _("Note, using directory '%s' to get the build dependencies\n"), Src); + else + ioprintf(c1out, _("Note, using file '%s' to get the build dependencies\n"), Src); + std::unique_ptr Last(VolatileSources[i]->CreateSrcParser()); + if (Last == nullptr) + return _error->Error(_("Unable to find a source package for %s"), Src); + + auto const BuildDeps = GetBuildDeps(Last.get(), Src, StripMultiArch, hostArch); + if (InstallBuildDepsLoop(Cache, Src, BuildDeps, StripMultiArch, hostArch) == false) + return false; + } } - else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false) - return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str()); + else + _error->Error("Implementation error: Volatile sources (%lu) and commandline elements (%lu) do not match!", VolatileSources.size(), VolatileCmdL.size()); + } - if (BuildDeps.empty() == true) - { - ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str()); - continue; - } + for (const char **I = CmdL.FileList + 1; *I != 0; ++I) + { + std::string Src; + pkgSrcRecords::Parser * const Last = FindSrc(*I,SrcRecs,Src,Cache); + if (Last == nullptr) + return _error->Error(_("Unable to find a source package for %s"), *I); + auto const BuildDeps = GetBuildDeps(Last, Src.c_str(), StripMultiArch, hostArch); if (InstallBuildDepsLoop(Cache, Src, BuildDeps, StripMultiArch, hostArch) == false) return false; } diff --git a/test/integration/test-apt-get-build-dep b/test/integration/test-apt-get-build-dep index 6df49d782..a8e6f6843 100755 --- a/test/integration/test-apt-get-build-dep +++ b/test/integration/test-apt-get-build-dep @@ -39,7 +39,7 @@ EOF test2vcardbuilddep() { testsuccessequal "Reading package lists... Building dependency tree... -Note, using file '2vcard_0.5-3.dsc' to get the build dependencies +Note, using file './2vcard_0.5-3.dsc' to get the build dependencies The following packages will be REMOVED: build-conflict The following NEW packages will be installed: @@ -49,7 +49,12 @@ Remv build-conflict [1] Inst build-essential (1 stable [i386]) Inst debhelper (7 stable [i386]) Conf build-essential (1 stable [i386]) -Conf debhelper (7 stable [i386])" aptget build-dep -s 2vcard_0.5-3.dsc +Conf debhelper (7 stable [i386])" aptget build-dep -s ./2vcard_0.5-3.dsc +testfailure aptget build-dep --simulate 2vcard_0.5-3.dsc +cd downloaded +testsuccess aptget build-dep --simulate ../2vcard_0.5-3.dsc +testsuccess aptget build-dep --simulate "$(readlink -f ../2vcard_0.5-3.dsc)" +cd .. } test2vcardbuilddep @@ -129,7 +134,11 @@ Inst build-essential (1 stable [i386]) Inst debhelper (7 stable [i386]) Conf build-essential (1 stable [i386]) Conf debhelper (7 stable [i386])" aptget build-dep --simulate ./foo-1.0 - +testfailure aptget build-dep --simulate foo-1.0 +cd downloaded +testsuccess aptget build-dep --simulate ../foo-1.0 +testsuccess aptget build-dep --simulate "$(readlink -f ../foo-1.0)" +cd .. testfailureequal 'Reading package lists... Building dependency tree... diff --git a/test/integration/test-apt-get-install-deb b/test/integration/test-apt-get-install-deb index 4daac881f..a3600b54b 100755 --- a/test/integration/test-apt-get-install-deb +++ b/test/integration/test-apt-get-install-deb @@ -43,6 +43,7 @@ E: Unable to correct problems, you have held broken packages." aptget install ./ testdpkgnotinstalled 'foo' 'foo:i386' testsuccess aptget install ./incoming/foo_1.0_i386.deb -o Debug::pkgCacheGen=1 testdpkginstalled 'foo:i386' +testfailure aptget install incoming/foo_1.0_i386.deb -o Debug::pkgCacheGen=1 cd downloaded testsuccess aptget install "$(readlink -f ../incoming/foo_1.0_i386.deb)" -o Debug::pkgCacheGen=1 -y --allow-downgrades testsuccess aptget install ../incoming/foo_1.0_i386.deb -o Debug::pkgCacheGen=1 -y --allow-downgrades -- cgit v1.2.3