diff options
author | Julian Andres Klode <jak@debian.org> | 2022-05-06 16:20:52 +0000 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2022-05-06 16:20:52 +0000 |
commit | 97f16727b50dcaa4810e80d3c16639e0ce6a0958 (patch) | |
tree | 1228c44118015b13b2f94177571c6780eb861a7e | |
parent | 6778e2d672d84c962a578f6de415c666b9cf6ee1 (diff) | |
parent | 05fae6fae95d8ef6690f3d56863e3bb6a44d424c (diff) |
Merge branch 'fix/tagfilekeys' into 'main'
Consistently dealing with fields via pkgTagSection::Key
See merge request apt-team/apt!233
26 files changed, 289 insertions, 252 deletions
diff --git a/apt-pkg/CMakeLists.txt b/apt-pkg/CMakeLists.txt index 5c97493af..a40b041b8 100644 --- a/apt-pkg/CMakeLists.txt +++ b/apt-pkg/CMakeLists.txt @@ -2,7 +2,8 @@ include_directories(${PROJECT_BINARY_DIR}/include/apt-pkg) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/apt-pkg/) -execute_process(COMMAND ${TRIEHASH_EXECUTABLE} +execute_process(COMMAND grep -v "^#" "${CMAKE_CURRENT_SOURCE_DIR}/tagfile-keys.list" + COMMAND ${TRIEHASH_EXECUTABLE} --ignore-case --header ${PROJECT_BINARY_DIR}/include/apt-pkg/tagfile-keys.h --code ${CMAKE_CURRENT_BINARY_DIR}/tagfile-keys.cc @@ -10,8 +11,10 @@ execute_process(COMMAND ${TRIEHASH_EXECUTABLE} --enum-name pkgTagSection::Key --function-name pkgTagHash --include "<apt-pkg/tagfile.h>" - ${CMAKE_CURRENT_SOURCE_DIR}/tagfile-keys.list) + --include "<apt-pkg/header-is-private.h>" + /dev/stdin ) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "tagfile-keys.list") +set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/tagfile-keys.cc" PROPERTIES COMPILE_DEFINITIONS APT_COMPILING_APT) # Set the version of the library diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index f9362b0d5..d9e1e516b 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -2371,13 +2371,13 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ { std::string tagname = *type; tagname.append("-Current"); - std::string const tmp = Tags.FindS(tagname.c_str()); + auto const tmp = Tags.Find(tagname); if (tmp.empty() == true) continue; string hash; unsigned long long size; - std::stringstream ss(tmp); + std::stringstream ss(tmp.to_string()); ss.imbue(posix); ss >> hash >> size; if (unlikely(hash.empty() == true)) @@ -2441,13 +2441,13 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ std::string tagname = *type; tagname.append("-History"); - std::string const tmp = Tags.FindS(tagname.c_str()); + auto const tmp = Tags.Find(tagname); if (tmp.empty() == true) continue; string hash, filename; unsigned long long size; - std::stringstream ss(tmp); + std::stringstream ss(tmp.to_string()); ss.imbue(posix); while (ss >> hash >> size >> filename) @@ -2498,13 +2498,13 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ std::string tagname = *type; tagname.append("-Patches"); - std::string const tmp = Tags.FindS(tagname.c_str()); + auto const tmp = Tags.Find(tagname); if (tmp.empty() == true) continue; string hash, filename; unsigned long long size; - std::stringstream ss(tmp); + std::stringstream ss(tmp.to_string()); ss.imbue(posix); while (ss >> hash >> size >> filename) @@ -2536,13 +2536,13 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ { std::string tagname = *type; tagname.append("-Download"); - std::string const tmp = Tags.FindS(tagname.c_str()); + auto const tmp = Tags.Find(tagname); if (tmp.empty() == true) continue; string hash, filename; unsigned long long size; - std::stringstream ss(tmp); + std::stringstream ss(tmp.to_string()); ss.imbue(posix); // FIXME: all of pdiff supports only .gz compressed patches @@ -2613,7 +2613,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/ if (pdiff_merge == true) { // reprepro and dak add this flag if they merge patches on the server - std::string const precedence = Tags.FindS("X-Patch-Precedence"); + auto const precedence = Tags.Find("X-Patch-Precedence"); pdiff_merge = (precedence != "merged"); } diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index e6ea16c68..284fcc1cf 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -11,6 +11,7 @@ #include <apt-pkg/cachefile.h> #include <apt-pkg/cachefilter.h> #include <apt-pkg/error.h> +#include <apt-pkg/header-is-private.h> #include <apt-pkg/string_view.h> #include <apt-pkg/strutl.h> #include <iostream> @@ -20,10 +21,6 @@ #include <vector> #include <assert.h> -#ifndef APT_COMPILING_APT -#error Internal header -#endif - namespace APT { diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 267e2679a..313b1d37d 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -17,6 +17,8 @@ #include <apt-pkg/hashes.h> #include <apt-pkg/macros.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> +#include <apt-pkg/tagfile.h> #include <algorithm> #include <iostream> @@ -45,6 +47,15 @@ const char * HashString::_SupportedHashes[] = { "SHA512", "SHA256", "SHA1", "MD5Sum", "Checksum-FileSize", NULL }; +std::vector<HashString::HashSupportInfo> HashString::SupportedHashesInfo() +{ + return {{ + { "SHA512", pkgTagSection::Key::SHA512,"Checksums-Sha512", pkgTagSection::Key::Checksums_Sha512}, + { "SHA256", pkgTagSection::Key::SHA256, "Checksums-Sha256", pkgTagSection::Key::Checksums_Sha256}, + { "SHA1", pkgTagSection::Key::SHA1, "Checksums-Sha1", pkgTagSection::Key::Checksums_Sha1 }, + { "MD5Sum", pkgTagSection::Key::MD5sum, "Files", pkgTagSection::Key::Files }, + }}; +} HashString::HashString() { diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 422c1e023..e259b4e28 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -14,6 +14,11 @@ #include <apt-pkg/macros.h> +#ifdef APT_COMPILING_APT +#include <apt-pkg/string_view.h> +#include <apt-pkg/tagfile-keys.h> +#endif + #include <cstring> #include <string> #include <vector> @@ -59,6 +64,15 @@ class APT_PUBLIC HashString // return the list of hashes we support static APT_PURE const char** SupportedHashes(); +#ifdef APT_COMPILING_APT + struct APT_HIDDEN HashSupportInfo { + APT::StringView name; + pkgTagSection::Key namekey; + APT::StringView chksumsname; + pkgTagSection::Key chksumskey; + }; + APT_HIDDEN static std::vector<HashSupportInfo> SupportedHashesInfo(); +#endif }; class APT_PUBLIC HashStringList diff --git a/apt-pkg/contrib/header-is-private.h b/apt-pkg/contrib/header-is-private.h new file mode 100644 index 000000000..201a40c62 --- /dev/null +++ b/apt-pkg/contrib/header-is-private.h @@ -0,0 +1,3 @@ +#ifndef APT_COMPILING_APT +#error Internal header without ABI stability. Should only be used by apt itself! +#endif diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 2f0ebaa7b..6f47053a5 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -126,7 +126,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { if (showErrors == true) _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same", - Section.FindS("Package").c_str()); + Package().c_str()); MA = pkgCache::Version::No; } else @@ -140,7 +140,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { if (showErrors == true) _error->Warning("Unknown Multi-Arch type '%s' for package '%s'", - MultiArch.to_string().c_str(), Section.FindS("Package").c_str()); + MultiArch.to_string().c_str(), Package().c_str()); MA = pkgCache::Version::No; } @@ -241,10 +241,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) return false; if (ParseDepends(Ver,pkgTagSection::Key::Enhances,pkgCache::Dep::Enhances) == false) return false; - // Obsolete. - if (ParseDepends(Ver,pkgTagSection::Key::Optional,pkgCache::Dep::Suggests) == false) - return false; - + if (ParseProvides(Ver) == false) return false; if (not APT::KernelAutoRemoveHelper::getUname(Ver.ParentPkg().Name()).empty()) @@ -259,21 +256,20 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) // ListParser::AvailableDescriptionLanguages /*{{{*/ std::vector<std::string> debListParser::AvailableDescriptionLanguages() { - std::vector<std::string> const understood = APT::Configuration::getLanguages(true); std::vector<std::string> avail; static constexpr int prefixLen = 12; char buf[32] = "Description-"; - if (Section.Exists("Description") == true) - avail.push_back(""); - for (std::vector<std::string>::const_iterator lang = understood.begin(); lang != understood.end(); ++lang) + if (Section.Exists(pkgTagSection::Key::Description)) + avail.emplace_back(); + for (auto const &lang : APT::Configuration::getLanguages(true)) { - if (unlikely(lang->size() > sizeof(buf) - prefixLen)) { - _error->Warning("Ignoring translated description %s", lang->c_str()); + if (unlikely(lang.size() > sizeof(buf) - prefixLen)) { + _error->Warning("Ignoring translated description %s", lang.c_str()); continue; } - memcpy(buf + prefixLen, lang->c_str(), lang->size()); - if (Section.Exists(StringView(buf, prefixLen + lang->size())) == true) - avail.push_back(*lang); + memcpy(buf + prefixLen, lang.c_str(), lang.size()); + if (Section.Exists(StringView(buf, prefixLen + lang.size())) == true) + avail.push_back(lang); } return avail; } diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 32f1fa8db..c6005f1c8 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -515,10 +515,9 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro bool FoundHashSum = false; bool FoundStrongHashSum = false; - auto const SupportedHashes = HashString::SupportedHashes(); - for (int i=0; SupportedHashes[i] != NULL; i++) + for (auto const hashinfo : HashString::SupportedHashesInfo()) { - if (!Section.Find(SupportedHashes[i], Start, End)) + if (not Section.Find(hashinfo.namekey, Start, End)) continue; std::string Name; @@ -529,7 +528,7 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro if (!parseSumData(Start, End, Name, Hash, Size)) return false; - HashString const hs(SupportedHashes[i], Hash); + HashString const hs(hashinfo.name.to_string(), Hash); if (Entries.find(Name) == Entries.end()) { metaIndex::checkSum *Sum = new metaIndex::checkSum; diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 22ac219ba..e2ffaefff 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -16,6 +16,7 @@ #include <apt-pkg/fileutl.h> #include <apt-pkg/pkgcache.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <algorithm> @@ -57,13 +58,13 @@ debRecordParserBase::debRecordParserBase() : Parser(), d(NULL) {} // RecordParserBase::FileName - Return the archive filename on the site /*{{{*/ string debRecordParserBase::FileName() { - return Section.FindS("Filename"); + return Section.Find(pkgTagSection::Key::Filename).to_string(); } /*}}}*/ // RecordParserBase::Name - Return the package name /*{{{*/ string debRecordParserBase::Name() { - string Result = Section.FindS("Package"); + auto Result = Section.Find(pkgTagSection::Key::Package).to_string(); // Normalize mixed case package names to lower case, like dpkg does // See Bug#807012 for details @@ -75,7 +76,7 @@ string debRecordParserBase::Name() // RecordParserBase::Homepage - Return the package homepage /*{{{*/ string debRecordParserBase::Homepage() { - return Section.FindS("Homepage"); + return Section.Find(pkgTagSection::Key::Homepage).to_string(); } /*}}}*/ // RecordParserBase::Hashes - return the available archive hashes /*{{{*/ @@ -88,7 +89,7 @@ HashStringList debRecordParserBase::Hashes() const if (hash.empty() == false) hashes.push_back(HashString(*type, hash)); } - auto const size = Section.FindULL("Size", 0); + auto const size = Section.FindULL(pkgTagSection::Key::Size, 0); if (size != 0) hashes.FileSize(size); return hashes; @@ -97,7 +98,7 @@ HashStringList debRecordParserBase::Hashes() const // RecordParserBase::Maintainer - Return the maintainer email /*{{{*/ string debRecordParserBase::Maintainer() { - return Section.FindS("Maintainer"); + return Section.Find(pkgTagSection::Key::Maintainer).to_string(); } /*}}}*/ // RecordParserBase::RecordField - Return the value of an arbitrary field /*{{*/ @@ -129,25 +130,25 @@ string debRecordParserBase::LongDesc(std::string const &lang) l != lang.end(); ++l) { std::string const tagname = "Description-" + *l; - orig = Section.FindS(tagname.c_str()); + orig = Section.FindS(tagname); if (orig.empty() == false) break; else if (*l == "en") { - orig = Section.FindS("Description"); + orig = Section.Find(pkgTagSection::Key::Description).to_string(); if (orig.empty() == false) break; } } if (orig.empty() == true) - orig = Section.FindS("Description"); + orig = Section.Find(pkgTagSection::Key::Description).to_string(); } else { std::string const tagname = "Description-" + lang; orig = Section.FindS(tagname.c_str()); if (orig.empty() == true && lang == "en") - orig = Section.FindS("Description"); + orig = Section.Find(pkgTagSection::Key::Description).to_string(); } char const * const codeset = nl_langinfo(CODESET); @@ -165,17 +166,17 @@ static const char * const SourceVerSeparators = " ()"; // RecordParserBase::SourcePkg - Return the source package name if any /*{{{*/ string debRecordParserBase::SourcePkg() { - string Res = Section.FindS("Source"); - string::size_type Pos = Res.find_first_of(SourceVerSeparators); - if (Pos == string::npos) - return Res; - return string(Res,0,Pos); + auto Res = Section.Find(pkgTagSection::Key::Source).to_string(); + auto const Pos = Res.find_first_of(SourceVerSeparators); + if (Pos != std::string::npos) + Res.erase(Pos); + return Res; } /*}}}*/ // RecordParserBase::SourceVer - Return the source version number if present /*{{{*/ string debRecordParserBase::SourceVer() { - string Pkg = Section.FindS("Source"); + auto const Pkg = Section.Find(pkgTagSection::Key::Source).to_string(); string::size_type Pos = Pkg.find_first_of(SourceVerSeparators); if (Pos == string::npos) return ""; diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index 1fd0fdc12..311bacfdd 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -172,26 +172,19 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions(); auto const &posix = std::locale::classic(); - for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type) + for (auto const hashinfo : HashString::SupportedHashesInfo()) { - // derive field from checksum type - std::string checksumField("Checksums-"); - if (strcmp(*type, "MD5Sum") == 0) - checksumField = "Files"; // historic name for MD5 checksums - else - checksumField.append(*type); - - string const Files = Sect.FindS(checksumField.c_str()); + auto const Files = Sect.Find(hashinfo.chksumskey); if (Files.empty() == true) continue; - std::istringstream ss(Files); + std::istringstream ss(Files.to_string()); ss.imbue(posix); while (ss.good()) { std::string hash, path; unsigned long long size; - if (iIndex == nullptr && checksumField == "Files") + if (iIndex == nullptr && hashinfo.chksumskey == pkgTagSection::Key::Files) { std::string ignore; ss >> hash >> size >> ignore >> ignore >> path; @@ -200,9 +193,9 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) ss >> hash >> size >> path; if (ss.fail() || hash.empty() || path.empty()) - return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str()); + return _error->Error("Error parsing file record in %s of source package %s", hashinfo.chksumsname.to_string().c_str(), Package().c_str()); - HashString const hashString(*type, hash); + HashString const hashString(hashinfo.name.to_string(), hash); if (Base.empty() == false) path = Base + path; @@ -217,7 +210,7 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List) { // an error here indicates that we have two different hashes for the same file if (file->Hashes.push_back(hashString) == false) - return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str()); + return _error->Error("Error parsing checksum in %s of source package %s", hashinfo.chksumsname.to_string().c_str(), Package().c_str()); continue; } diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index b572d3427..1a0bbe0fd 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -12,6 +12,7 @@ #include <apt-pkg/fileutl.h> #include <apt-pkg/srcrecords.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <string> @@ -40,9 +41,9 @@ class APT_HIDDEN debSrcRecordParser : public pkgSrcRecords::Parser virtual bool Jump(unsigned long const &Off) APT_OVERRIDE {iOffset = Off; return Tags.Jump(Sect,Off);}; virtual std::string Package() const APT_OVERRIDE; - virtual std::string Version() const APT_OVERRIDE {return Sect.FindS("Version");}; - virtual std::string Maintainer() const APT_OVERRIDE {return Sect.FindS("Maintainer");}; - virtual std::string Section() const APT_OVERRIDE {return Sect.FindS("Section");}; + virtual std::string Version() const APT_OVERRIDE {return Sect.Find(pkgTagSection::Key::Version).to_string();}; + virtual std::string Maintainer() const APT_OVERRIDE {return Sect.Find(pkgTagSection::Key::Maintainer).to_string();}; + virtual std::string Section() const APT_OVERRIDE {return Sect.Find(pkgTagSection::Key::Section).to_string();}; virtual const char **Binaries() APT_OVERRIDE; virtual bool BuildDepends(std::vector<BuildDepRec> &BuildDeps, bool const &ArchOnly, bool const &StripMultiArch = true) APT_OVERRIDE; virtual unsigned long Offset() APT_OVERRIDE {return iOffset;}; diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index f7d9832a0..a5b586f5b 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -23,6 +23,7 @@ #include <apt-pkg/prettyprinters.h> #include <apt-pkg/progress.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <apt-pkg/version.h> #include <apt-pkg/versionmatch.h> @@ -310,8 +311,8 @@ bool pkgDepCache::readStateFile(OpProgress * const Prog) /*{{{*/ off_t amt = 0; bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); while(tagfile.Step(section)) { - string const pkgname = section.FindS("Package"); - string pkgarch = section.FindS("Architecture"); + auto const pkgname = section.Find(pkgTagSection::Key::Package); + auto pkgarch = section.Find(pkgTagSection::Key::Architecture); if (pkgarch.empty() == true) pkgarch = "any"; pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch); @@ -379,8 +380,8 @@ bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const Install pkgTagSection section; std::set<string> pkgs_seen; while(tagfile.Step(section)) { - string const pkgname = section.FindS("Package"); - string pkgarch = section.FindS("Architecture"); + auto const pkgname = section.Find(pkgTagSection::Key::Package); + auto pkgarch = section.Find(pkgTagSection::Key::Architecture); if (pkgarch.empty() == true) pkgarch = "native"; // Silently ignore unknown packages and packages with no actual diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index b7c0d28d2..6493a4595 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -453,7 +453,7 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progres continue; } - decltype(VersionCount) const id = section.FindULL(type.c_str(), VersionCount); + decltype(VersionCount) const id = section.FindULL(type, VersionCount); if (id == VersionCount) { _error->Warning("Unable to parse %s request with id value '%s'!", type.c_str(), section.FindS(type.c_str()).c_str()); continue; diff --git a/apt-pkg/edsp/edsplistparser.cc b/apt-pkg/edsp/edsplistparser.cc index 34b9ec934..5419069f2 100644 --- a/apt-pkg/edsp/edsplistparser.cc +++ b/apt-pkg/edsp/edsplistparser.cc @@ -19,6 +19,7 @@ #include <apt-pkg/pkgsystem.h> #include <apt-pkg/string_view.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <array> @@ -61,9 +62,7 @@ APT::StringView edspLikeListParser::Description_md5() // ListParser::VersionHash - Compute a unique hash for this version /*{{{*/ uint32_t edspLikeListParser::VersionHash() { - if (Section.Exists("APT-Hash") == true) - return Section.FindI("APT-Hash"); - else if (Section.Exists("APT-ID") == true) + if (Section.Exists("APT-ID") == true) return Section.FindI("APT-ID"); return 0; } @@ -143,8 +142,8 @@ bool eippListParser::ParseStatus(pkgCache::PkgIterator &Pkg, {"triggers-pending",pkgCache::State::TriggersPending}, {"installed",pkgCache::State::Installed}, }}; - auto const status = Section.Find("Status"); - if (status.empty() == false) + auto const status = Section.Find(pkgTagSection::Key::Status); + if (not status.empty()) { for (auto && sv: statusvalues) { diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 88c2150ff..0d569265d 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -22,6 +22,7 @@ #include <apt-pkg/metaindex.h> #include <apt-pkg/progress.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <iostream> @@ -413,8 +414,8 @@ bool IndexCopy::GrabFirst(string Path,string &To,unsigned int Depth) /* */ bool PackageCopy::GetFile(string &File,unsigned long long &Size) { - File = Section->FindS("Filename"); - Size = Section->FindULL("Size"); + File = Section->Find(pkgTagSection::Key::Filename).to_string(); + Size = Section->FindULL(pkgTagSection::Key::Size); if (File.empty() || Size == 0) return _error->Error("Cannot find filename or size tag"); return true; @@ -436,29 +437,16 @@ bool PackageCopy::RewriteEntry(FileFd &Target,string const &File) /* */ bool SourceCopy::GetFile(string &File,unsigned long long &Size) { - string Files; - - for (char const *const *type = HashString::SupportedHashes(); *type != NULL; ++type) + std::string Files; + for (auto hashinfo : HashString::SupportedHashesInfo()) { - // derive field from checksum type - std::string checksumField("Checksums-"); - if (strcmp(*type, "MD5Sum") == 0) - checksumField = "Files"; // historic name for MD5 checksums - else - checksumField.append(*type); - - Files = Section->FindS(checksumField.c_str()); - if (Files.empty() == false) + Files = Section->Find(hashinfo.chksumskey).to_string(); + if (not Files.empty()) break; } - if (Files.empty() == true) + if (Files.empty()) return false; - // Stash the / terminated directory prefix - string Base = Section->FindS("Directory"); - if (Base.empty() == false && Base[Base.length()-1] != '/') - Base += '/'; - // Read the first file triplet const char *C = Files.c_str(); string sSize; @@ -472,7 +460,8 @@ bool SourceCopy::GetFile(string &File,unsigned long long &Size) // Parse the size and append the directory Size = strtoull(sSize.c_str(), NULL, 10); - File = Base + File; + auto const Base = Section->Find(pkgTagSection::Key::Directory); + File = flCombine(Base.to_string(), File); return true; } /*}}}*/ diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index c5328c517..b30eddb37 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -21,7 +21,9 @@ #include <apt-pkg/fileutl.h> #include <apt-pkg/pkgcache.h> #include <apt-pkg/policy.h> +#include <apt-pkg/string_view.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <apt-pkg/version.h> #include <apt-pkg/versionmatch.h> @@ -425,12 +427,12 @@ bool ReadPinFile(pkgPolicy &Plcy,string File) if (Tags.Count() == 0) continue; - string Name = Tags.FindS("Package"); - if (Name.empty() == true) + auto Name = Tags.Find(pkgTagSection::Key::Package); + if (Name.empty()) return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str()); if (Name == "*") - Name = string(); - + Name = APT::StringView{}; + const char *Start; const char *End; if (Tags.Find("Pin",Start,End) == false) @@ -479,7 +481,7 @@ bool ReadPinFile(pkgPolicy &Plcy,string File) return _error->Error(_("No priority (or zero) specified for pin")); } - istringstream s(Name); + std::istringstream s(Name.to_string()); string pkg; while(!s.eof()) { diff --git a/apt-pkg/tagfile-keys.list b/apt-pkg/tagfile-keys.list index 36da3435e..4b57e46c2 100644 --- a/apt-pkg/tagfile-keys.list +++ b/apt-pkg/tagfile-keys.list @@ -1,7 +1,16 @@ +# This file is input for triehash(1) (after stripping comments) +# +# The fields listed here are accessible via pkgTagSection::Key::FIELD +# Do *NOT* edit, remove or insert new fields in the sorted section here +# as the file forms part of the ABI of the libapt library and is used +# by our apt tools. External clients are forbidden though, so if really needed +# we can use libapt Breaks: apt, but always prefer appending only. +# +# For Fields used in Packages, Sources and status files, see also tagfile-order.c Architecture +Auto-Built-Package Binary Breaks -Bugs Build-Conflicts Build-Conflicts-Arch Build-Conflicts-Indep @@ -15,7 +24,6 @@ Checksums-Md5 Checksums-Sha1 Checksums-Sha256 Checksums-Sha512 -Class Conffiles Config-Version Conflicts @@ -23,7 +31,6 @@ Depends Description Description-md5 Directory -Dm-Upload-Allowed Enhances Essential Filename @@ -32,29 +39,21 @@ Format Homepage Important Installed-Size -Installer-Menu-Item -Kernel-Version Maintainer MD5sum -MSDOS-Filename Multi-Arch -Optional Origin Original-Maintainer Package Package-List -Package_Revision -Package-Revision Package-Type Phased-Update-Percentage Pre-Depends Priority Protected Provides -Recommended Recommends Replaces -Revision Section SHA1 SHA256 @@ -64,17 +63,13 @@ Source Standards-Version Static-Built-Using Status -Subarchitecture Suggests Tag Task Testsuite Testsuite-Triggers -Triggers-Awaited -Triggers-Pending Uploaders Vcs-Arch -Vcs-Browse Vcs-Browser Vcs-Bzr Vcs-Cvs @@ -84,3 +79,4 @@ Vcs-Hg Vcs-Mtn Vcs-Svn Version +### APPEND BELOW, sort in with next ABI break ### diff --git a/apt-pkg/tagfile-order.c b/apt-pkg/tagfile-order.c index 79d6992b4..7cf188c51 100644 --- a/apt-pkg/tagfile-order.c +++ b/apt-pkg/tagfile-order.c @@ -9,12 +9,12 @@ static const char *iTFRewritePackageOrder[] = { "Package", "Package-Type", "Architecture", - "Subarchitecture", // Used only by d-i + "Subarchitecture", // NO_KEY: Used only by d-i "Version", - "Revision", // Obsolete (warning in dpkg) - "Package-Revision", // Obsolete (warning in dpkg) - "Package_Revision", // Obsolete (warning in dpkg) - "Kernel-Version", // Used only by d-i +// "Revision", // Obsolete (warning in dpkg) +// "Package-Revision", // Obsolete (warning in dpkg) +// "Package_Revision", // Obsolete (warning in dpkg) + "Kernel-Version", // NO_KEY: Used only by d-i "Built-Using", "Static-Built-Using", "Built-For-Profiles", @@ -22,35 +22,37 @@ static const char *iTFRewritePackageOrder[] = { "Multi-Arch", "Status", "Priority", - "Class", // dpkg nickname for Priority +// "Class", // Obsolete alias for Priority, warning by dpkg "Build-Essential", "Protected", + "Important", // old name of Protected "Essential", - "Installer-Menu-Item", // Used only by d-i + "Installer-Menu-Item", // NO_KEY: Used only by d-i "Section", "Source", "Origin", + "Phased-Update-Percentage", "Maintainer", "Original-Maintainer", // unknown in dpkg order - "Bugs", + "Bugs", // NO_KEY: very uncommon encounter "Config-Version", // Internal of dpkg "Conffiles", - "Triggers-Awaited", - "Triggers-Pending", + "Triggers-Awaited", // NO_KEY: Internal of dpkg + "Triggers-Pending", // NO_KEY: Internal of dpkg "Installed-Size", "Provides", "Pre-Depends", "Depends", "Recommends", - "Recommended", // dpkg nickname for Recommends +// "Recommended", // Obsolete alias for Recommends, warning by dpkg "Suggests", - "Optional", // dpkg nickname for Suggests +// "Optional", // Obsolete alias for Suggests, warning by dpkg "Conflicts", "Breaks", "Replaces", "Enhances", "Filename", - "MSDOS-Filename", // Obsolete (used by dselect) + "MSDOS-Filename", // NO_KEY: Obsolete (used by dselect) "Size", "MD5sum", "SHA1", @@ -58,6 +60,7 @@ static const char *iTFRewritePackageOrder[] = { "SHA512", "Homepage", "Description", + "Description-md5", "Tag", "Task", 0, @@ -70,13 +73,13 @@ static const char *iTFRewriteSourceOrder[] = { "Architecture", "Version", "Priority", - "Class", // dpkg nickname for Priority +// "Class", // Obsolete alias for Priority, warning by dpkg "Section", "Origin", "Maintainer", "Original-Maintainer", // unknown in dpkg order "Uploaders", - "Dm-Upload-Allowed", // Obsolete (ignored by dak) + "Dm-Upload-Allowed", // NO_KEY: Obsolete (ignored by dak) "Standards-Version", "Build-Depends", "Build-Depends-Arch", @@ -89,7 +92,7 @@ static const char *iTFRewriteSourceOrder[] = { "Homepage", "Description", "Vcs-Browser", - "Vcs-Browse", // dak only (nickname?) + "Vcs-Browse", // NO_KEY: dak only (nickname?) "Vcs-Arch", "Vcs-Bzr", "Vcs-Cvs", diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 52000c6b9..047f88986 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -626,6 +626,11 @@ bool pkgTagSection::Exists(StringView Tag) const unsigned int tmp; return Find(Tag, tmp); } +bool pkgTagSection::Exists(Key key) const +{ + unsigned int tmp; + return Find(key, tmp); +} /*}}}*/ // TagSection::Find - Locate a tag /*{{{*/ // --------------------------------------------------------------------- @@ -1051,8 +1056,8 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v { if (R->Action == Tag::REMOVE) continue; - std::string const name = ((R->Action == Tag::RENAME) ? R->Data : R->Name); - if (Exists(name.c_str())) + auto const name = ((R->Action == Tag::RENAME) ? R->Data : R->Name); + if (Exists(name)) continue; if (Order != NULL) { diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index f6bdd12c9..54562d07c 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -70,18 +70,21 @@ class APT_PUBLIC pkgTagSection std::string FindS(APT::StringView sv) const { return Find(sv).to_string(); } std::string FindRawS(APT::StringView sv) const { return FindRaw(sv).to_string(); }; +#ifdef APT_COMPILING_APT // Functions for lookup with a perfect hash function enum class Key; - APT_HIDDEN bool Find(Key key,const char *&Start, const char *&End) const; - APT_HIDDEN bool Find(Key key,unsigned int &Pos) const; - APT_HIDDEN signed int FindI(Key key,signed long Default = 0) const; - APT_HIDDEN bool FindB(Key key, bool Default = false) const; - APT_HIDDEN unsigned long long FindULL(Key key, unsigned long long const &Default = 0) const; - APT_HIDDEN bool FindFlag(Key key,uint8_t &Flags, uint8_t const Flag) const; - APT_HIDDEN bool FindFlag(Key key,unsigned long &Flags, unsigned long Flag) const; - APT_HIDDEN bool Exists(Key key) const; - APT_HIDDEN APT::StringView Find(Key key) const; - APT_HIDDEN APT::StringView FindRaw(Key key) const; + bool Find(Key key,const char *&Start, const char *&End) const; + bool Find(Key key,unsigned int &Pos) const; + signed int FindI(Key key,signed long Default = 0) const; + bool FindB(Key key, bool Default = false) const; + unsigned long long FindULL(Key key, unsigned long long const &Default = 0) const; + bool FindFlag(Key key,uint8_t &Flags, uint8_t const Flag) const; + bool FindFlag(Key key,unsigned long &Flags, unsigned long Flag) const; + bool Exists(Key key) const; + APT::StringView Find(Key key) const; + APT::StringView FindRaw(Key key) const; +#endif + bool Find(APT::StringView Tag,const char *&Start, const char *&End) const; bool Find(APT::StringView Tag,unsigned int &Pos) const; APT::StringView Find(APT::StringView Tag) const; diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc index b56b87d67..08a4fe6df 100644 --- a/apt-private/private-show.cc +++ b/apt-private/private-show.cc @@ -17,6 +17,7 @@ #include <apt-pkg/policy.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <apt-private/private-cacheset.h> @@ -233,13 +234,15 @@ static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgRecords &Recs, /*{{{*/ // make size nice std::string installed_size; - if (Tags.FindULL("Installed-Size") > 0) - strprintf(installed_size, "%sB", SizeToStr(Tags.FindULL("Installed-Size") * 1024).c_str()); + auto const installed_size_field = Tags.FindULL(pkgTagSection::Key::Installed_Size); + if (installed_size_field > 0) + installed_size = SizeToStr(installed_size_field * 1024).append("B"); else installed_size = _("unknown"); std::string package_size; - if (Tags.FindULL("Size") > 0) - strprintf(package_size, "%sB", SizeToStr(Tags.FindULL("Size")).c_str()); + auto const package_size_field = Tags.FindULL(pkgTagSection::Key::Size); + if (package_size_field > 0) + package_size = SizeToStr(package_size_field).append("B"); else package_size = _("unknown"); @@ -257,10 +260,8 @@ static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgRecords &Recs, /*{{{*/ // delete, apt-cache show has this info and most users do not care if (not _config->FindB("APT::Cache::ShowFull", false)) { - RW.push_back(pkgTagSection::Tag::Remove("MD5sum")); - RW.push_back(pkgTagSection::Tag::Remove("SHA1")); - RW.push_back(pkgTagSection::Tag::Remove("SHA256")); - RW.push_back(pkgTagSection::Tag::Remove("SHA512")); + for (char const * const * type = HashString::SupportedHashes(); *type != nullptr; ++type) + RW.push_back(pkgTagSection::Tag::Remove(*type)); RW.push_back(pkgTagSection::Tag::Remove("Filename")); RW.push_back(pkgTagSection::Tag::Remove("Multi-Arch")); RW.push_back(pkgTagSection::Tag::Remove("Conffiles")); diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 01b5dbb11..88a204110 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -28,6 +28,7 @@ #include <apt-pkg/pkgsystem.h> #include <apt-pkg/sourcelist.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <apt-pkg/version.h> @@ -170,11 +171,11 @@ bool DebFile::ParseInfo() if (Section.Scan(Control, ControlLen) == false) return false; - Package = Section.FindS("Package"); + Package = Section.Find(pkgTagSection::Key::Package).to_string(); Version = GetInstalledVer(Package); const char *Start, *Stop; - if (Section.Find("Depends", Start, Stop) == true) + if (Section.Find(pkgTagSection::Key::Depends, Start, Stop)) { while (1) { @@ -191,8 +192,8 @@ bool DebFile::ParseInfo() if (Start == Stop) break; } } - - if (Section.Find("Pre-Depends", Start, Stop) == true) + + if (Section.Find(pkgTagSection::Key::Pre_Depends, Start, Stop)) { while (1) { diff --git a/cmdline/apt-sortpkgs.cc b/cmdline/apt-sortpkgs.cc index da451708f..519825457 100644 --- a/cmdline/apt-sortpkgs.cc +++ b/cmdline/apt-sortpkgs.cc @@ -20,6 +20,7 @@ #include <apt-pkg/init.h> #include <apt-pkg/pkgsystem.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <apt-private/private-cmndline.h> @@ -85,9 +86,9 @@ static bool DoIt(string InFile) /* Fetch the name, auto-detecting if this is a source file or a package file */ - Tmp.Name = Section.FindS("Package"); - Tmp.Ver = Section.FindS("Version"); - Tmp.Arch = Section.FindS("Architecture"); + Tmp.Name = Section.Find(pkgTagSection::Key::Package).to_string(); + Tmp.Ver = Section.Find(pkgTagSection::Key::Version).to_string(); + Tmp.Arch = Section.Find(pkgTagSection::Key::Architecture).to_string(); if (Tmp.Name.empty() == true) return _error->Error(_("Unknown package record!")); diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index 5dcb98c9c..ae427b120 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -21,6 +21,7 @@ #include <apt-pkg/hashes.h> #include <apt-pkg/pkgcache.h> #include <apt-pkg/strutl.h> +#include <apt-pkg/tagfile-keys.h> #include <apt-pkg/tagfile.h> #include <algorithm> @@ -421,7 +422,7 @@ bool PackagesWriter::DoPackage(string FileName) // Lookup the override information pkgTagSection &Tags = Db.Control.Section; - string Package = Tags.FindS("Package"); + auto const Package = Tags.Find(pkgTagSection::Key::Package).to_string(); string Architecture; // if we generate a Packages file for a given arch, we use it to // look for overrides. if we run in "simple" mode without the @@ -430,9 +431,9 @@ bool PackagesWriter::DoPackage(string FileName) if(Arch != "") Architecture = Arch; else - Architecture = Tags.FindS("Architecture"); - unique_ptr<Override::Item> OverItem(Over.GetItem(Package,Architecture)); - + Architecture = Tags.Find(pkgTagSection::Key::Architecture).to_string(); + unique_ptr<Override::Item> OverItem(Over.GetItem(Package, Architecture)); + if (Package.empty() == true) return _error->Error(_("Archive had no package field")); @@ -444,10 +445,10 @@ bool PackagesWriter::DoPackage(string FileName) NewLine(1); ioprintf(c1out, _(" %s has no override entry\n"), Package.c_str()); } - + OverItem = unique_ptr<Override::Item>(new Override::Item); - OverItem->FieldOverride["Section"] = Tags.FindS("Section"); - OverItem->Priority = Tags.FindS("Priority"); + OverItem->FieldOverride["Section"] = Tags.Find(pkgTagSection::Key::Section).to_string(); + OverItem->Priority = Tags.Find(pkgTagSection::Key::Priority).to_string(); } // Strip the DirStrip prefix from the FileName and add the PathPrefix @@ -466,7 +467,7 @@ bool PackagesWriter::DoPackage(string FileName) in the package file - instead we want to ship a separated file */ string desc; if (LongDescription == false) { - desc = Tags.FindS("Description").append("\n"); + desc = Tags.Find(pkgTagSection::Key::Description).to_string().append("\n"); OverItem->FieldOverride["Description"] = desc.substr(0, desc.find('\n')).c_str(); } @@ -486,7 +487,6 @@ bool PackagesWriter::DoPackage(string FileName) Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", NewFileName)); Changes.push_back(pkgTagSection::Tag::Rewrite("Priority", OverItem->Priority)); Changes.push_back(pkgTagSection::Tag::Remove("Status")); - Changes.push_back(pkgTagSection::Tag::Remove("Optional")); string DescriptionMd5; if (LongDescription == false) { @@ -500,33 +500,20 @@ bool PackagesWriter::DoPackage(string FileName) // Rewrite the maintainer field if necessary bool MaintFailed; - string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"),MaintFailed); + string NewMaint = OverItem->SwapMaint(Tags.Find(pkgTagSection::Key::Maintainer).to_string(), MaintFailed); if (MaintFailed == true) { if (NoOverride == false) { NewLine(1); ioprintf(c1out, _(" %s maintainer is %s not %s\n"), - Package.c_str(), Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str()); + Package.c_str(), Tags.Find(pkgTagSection::Key::Maintainer).to_string().c_str(), OverItem->OldMaint.c_str()); } } if (NewMaint.empty() == false) Changes.push_back(pkgTagSection::Tag::Rewrite("Maintainer", NewMaint)); - /* Get rid of the Optional tag. This is an ugly, ugly, ugly hack that - dpkg-scanpackages does. Well sort of. dpkg-scanpackages just does renaming - but dpkg does this append bit. So we do the append bit, at least that way the - status file and package file will remain similar. There are other transforms - but optional is the only legacy one still in use for some lazy reason. */ - string OptionalStr = Tags.FindS("Optional"); - if (OptionalStr.empty() == false) - { - if (Tags.FindS("Suggests").empty() == false) - OptionalStr = Tags.FindS("Suggests") + ", " + OptionalStr; - Changes.push_back(pkgTagSection::Tag::Rewrite("Suggests", OptionalStr)); - } - for (map<string,string>::const_iterator I = OverItem->FieldOverride.begin(); I != OverItem->FieldOverride.end(); ++I) Changes.push_back(pkgTagSection::Tag::Rewrite(I->first, I->second)); @@ -628,14 +615,14 @@ SourcesWriter::SourcesWriter(FileFd * const GivenOutput, string const &DB, strin /*}}}*/ // SourcesWriter::DoPackage - Process a single package /*{{{*/ static std::string getDscHash(unsigned int const DoHashes, - Hashes::SupportedHashes const DoIt, pkgTagSection &Tags, char const * const FieldName, + Hashes::SupportedHashes const DoIt, pkgTagSection &Tags, pkgTagSection::Key const FieldKey, HashString const * const Hash, unsigned long long Size, std::string const &FileName) { - if ((DoHashes & DoIt) != DoIt || Tags.Exists(FieldName) == false || Hash == NULL) + if ((DoHashes & DoIt) != DoIt || not Tags.Exists(FieldKey) || Hash == nullptr) return ""; std::ostringstream out; out << "\n " << Hash->HashValue() << " " << std::to_string(Size) << " " << FileName - << "\n " << Tags.FindS(FieldName); + << "\n " << Tags.Find(FieldKey).to_string(); return out.str(); } bool SourcesWriter::DoPackage(string FileName) @@ -660,19 +647,20 @@ bool SourcesWriter::DoPackage(string FileName) if (Tags.Scan(Db.Dsc.Data.c_str(), Db.Dsc.Data.length()) == false) return _error->Error("Could not find a record in the DSC '%s'",FileName.c_str()); - if (Tags.Exists("Source") == false) + if (not Tags.Exists(pkgTagSection::Key::Source)) return _error->Error("Could not find a Source entry in the DSC '%s'",FileName.c_str()); Tags.Trim(); // Lookup the override information, finding first the best priority. string BestPrio; - string Bins = Tags.FindS("Binary"); + auto const Bins = Tags.Find(pkgTagSection::Key::Binary); char Buffer[Bins.length() + 1]; unique_ptr<Override::Item> OverItem(nullptr); if (Bins.empty() == false) { - strcpy(Buffer,Bins.c_str()); - + strncpy(Buffer, Bins.data(), Bins.length()); + Buffer[Bins.length()] = '\0'; + // Ignore too-long errors. char *BinList[400]; TokSplitString(',',Buffer,BinList,sizeof(BinList)/sizeof(BinList[0])); @@ -702,8 +690,8 @@ bool SourcesWriter::DoPackage(string FileName) { if (NoOverride == false) { - NewLine(1); - ioprintf(c1out, _(" %s has no override entry\n"), Tags.FindS("Source").c_str()); + NewLine(1); + ioprintf(c1out, _(" %s has no override entry\n"), Tags.Find(pkgTagSection::Key::Source).to_string().c_str()); } OverItem.reset(new Override::Item); @@ -713,15 +701,16 @@ bool SourcesWriter::DoPackage(string FileName) if (stat(FileName.c_str(), &St) != 0) return _error->Errno("fstat","Failed to stat %s",FileName.c_str()); - unique_ptr<Override::Item> SOverItem(SOver.GetItem(Tags.FindS("Source"))); + auto const Package = Tags.Find(pkgTagSection::Key::Source).to_string(); + unique_ptr<Override::Item> SOverItem(SOver.GetItem(Package)); // const unique_ptr<Override::Item> autoSOverItem(SOverItem); if (SOverItem.get() == 0) { - ioprintf(c1out, _(" %s has no source override entry\n"), Tags.FindS("Source").c_str()); - SOverItem = unique_ptr<Override::Item>(BOver.GetItem(Tags.FindS("Source"))); + ioprintf(c1out, _(" %s has no source override entry\n"), Package.c_str()); + SOverItem = unique_ptr<Override::Item>(BOver.GetItem(Package)); if (SOverItem.get() == 0) { - ioprintf(c1out, _(" %s has no binary override entry either\n"), Tags.FindS("Source").c_str()); + ioprintf(c1out, _(" %s has no binary override entry either\n"), Package.c_str()); SOverItem = unique_ptr<Override::Item>(new Override::Item); *SOverItem = *OverItem; } @@ -729,10 +718,10 @@ bool SourcesWriter::DoPackage(string FileName) // Add the dsc to the files hash list string const strippedName = flNotDir(FileName); - std::string const Files = getDscHash(DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName); - std::string ChecksumsSha1 = getDscHash(DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName); - std::string ChecksumsSha256 = getDscHash(DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName); - std::string ChecksumsSha512 = getDscHash(DoHashes, Hashes::SHA512SUM, Tags, "Checksums-Sha512", Db.HashesList.find("SHA512"), St.st_size, strippedName); + std::string const Files = getDscHash(DoHashes, Hashes::MD5SUM, Tags, pkgTagSection::Key::Files, Db.HashesList.find("MD5Sum"), St.st_size, strippedName); + std::string ChecksumsSha1 = getDscHash(DoHashes, Hashes::SHA1SUM, Tags, pkgTagSection::Key::Checksums_Sha1, Db.HashesList.find("SHA1"), St.st_size, strippedName); + std::string ChecksumsSha256 = getDscHash(DoHashes, Hashes::SHA256SUM, Tags, pkgTagSection::Key::Checksums_Sha256, Db.HashesList.find("SHA256"), St.st_size, strippedName); + std::string ChecksumsSha512 = getDscHash(DoHashes, Hashes::SHA512SUM, Tags, pkgTagSection::Key::Checksums_Sha512, Db.HashesList.find("SHA512"), St.st_size, strippedName); // Strip the DirStrip prefix from the FileName and add the PathPrefix string NewFileName; @@ -746,7 +735,6 @@ bool SourcesWriter::DoPackage(string FileName) NewFileName = flCombine(PathPrefix,NewFileName); string Directory = flNotFile(OriginalPath); - string Package = Tags.FindS("Source"); // Perform operation over all of the files string ParseJnk; @@ -764,9 +752,9 @@ bool SourcesWriter::DoPackage(string FileName) string OriginalPath = Directory + ParseJnk; // Add missing hashes to source files - if (((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM && !Tags.Exists("Checksums-Sha1")) || - ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM && !Tags.Exists("Checksums-Sha256")) || - ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM && !Tags.Exists("Checksums-Sha512"))) + if (((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM && not Tags.Exists(pkgTagSection::Key::Checksums_Sha1)) || + ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM && not Tags.Exists(pkgTagSection::Key::Checksums_Sha256)) || + ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM && not Tags.Exists(pkgTagSection::Key::Checksums_Sha512))) { if (Db.GetFileInfo(OriginalPath, false, /* DoControl */ @@ -783,21 +771,21 @@ bool SourcesWriter::DoPackage(string FileName) { if (hs->HashType() == "MD5Sum" || hs->HashType() == "Checksum-FileSize") continue; - char const * fieldname; + pkgTagSection::Key fieldkey; std::string * out; if (hs->HashType() == "SHA1") { - fieldname = "Checksums-Sha1"; + fieldkey = pkgTagSection::Key::Checksums_Sha1; out = &ChecksumsSha1; } else if (hs->HashType() == "SHA256") { - fieldname = "Checksums-Sha256"; + fieldkey = pkgTagSection::Key::Checksums_Sha256; out = &ChecksumsSha256; } else if (hs->HashType() == "SHA512") { - fieldname = "Checksums-Sha512"; + fieldkey = pkgTagSection::Key::Checksums_Sha512; out = &ChecksumsSha512; } else @@ -805,7 +793,7 @@ bool SourcesWriter::DoPackage(string FileName) _error->Warning("Ignoring unknown Checksumtype %s in SourcesWriter::DoPackages", hs->HashType().c_str()); continue; } - if (Tags.Exists(fieldname) == true) + if (Tags.Exists(fieldkey)) continue; std::ostringstream streamout; streamout << "\n " << hs->HashValue() << " " << std::to_string(Db.GetFileSize()) << " " << ParseJnk; @@ -862,14 +850,14 @@ bool SourcesWriter::DoPackage(string FileName) // Rewrite the maintainer field if necessary bool MaintFailed; - string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"), MaintFailed); + string NewMaint = OverItem->SwapMaint(Tags.Find(pkgTagSection::Key::Maintainer).to_string(), MaintFailed); if (MaintFailed == true) { if (NoOverride == false) { NewLine(1); ioprintf(c1out, _(" %s maintainer is %s not %s\n"), Package.c_str(), - Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str()); + Tags.Find(pkgTagSection::Key::Maintainer).to_string().c_str(), OverItem->OldMaint.c_str()); } } if (NewMaint.empty() == false) @@ -921,7 +909,7 @@ bool ContentsWriter::DoPackage(string FileName, string Package) // Parse the package name if (Package.empty() == true) { - Package = Db.Control.Section.FindS("Package"); + Package = Db.Control.Section.Find(pkgTagSection::Key::Package).to_string(); } Db.Contents.Add(Gen,Package); @@ -951,17 +939,9 @@ bool ContentsWriter::ReadFromPkgs(string const &PkgFile,string const &PkgCompres pkgTagSection Section; while (Tags.Step(Section) == true) { - string File = flCombine(Prefix,Section.FindS("FileName")); - string Package = Section.FindS("Section"); - if (Package.empty() == false && Package.end()[-1] != '/') - { - Package += '/'; - Package += Section.FindS("Package"); - } - else - Package += Section.FindS("Package"); - - DoPackage(File,Package); + auto File = flCombine(Prefix, Section.Find(pkgTagSection::Key::Filename).to_string()); + auto Package = flCombine(Section.Find(pkgTagSection::Key::Section).to_string(), Section.Find(pkgTagSection::Key::Package).to_string()); + DoPackage(std::move(File), std::move(Package)); if (_error->empty() == false) { _error->Error("Errors apply to file '%s'",File.c_str()); diff --git a/test/integration/test-apt-tagfile-fields-order b/test/integration/test-apt-tagfile-fields-order index 4af58aabb..aa817147d 100755 --- a/test/integration/test-apt-tagfile-fields-order +++ b/test/integration/test-apt-tagfile-fields-order @@ -5,13 +5,19 @@ TESTDIR="$(readlink -f "$(dirname "$0")")" . "$TESTDIR/framework" setupenvironment +DPKG_PERL_VERSION="$(perl -e 'use Dpkg; print "$Dpkg::PROGVERSION";')" +DPKG_OUTPUT_SORT='sort -u' +if dpkg --compare-versions "$DPKG_PERL_VERSION" '>=' '1.21.4~'; then + DPKG_OUTPUT_SORT='sort' +fi + dpkg_field_ordered_list() { local FIELDS="$(perl -e " use Dpkg::Control; use Dpkg::Control::Fields; foreach \$f (field_ordered_list(${1})) { print \"\$f\\n\"; -}" | sort -u)" +}" | $DPKG_OUTPUT_SORT )" if [ -z "$FIELDS" ]; then msgfail 'Could not get fields via libdpkg-perl' fi @@ -29,9 +35,40 @@ comparelsts() { fi } +grep -v '^#' "${SOURCEDIRECTORY}/apt-pkg/tagfile-keys.list" > tagfile-keys.list +# Hardcoding this is a bit silly, but it might help preventing issues… +msgtest 'File is append only: do not sort, remove or insert keys in' 'tagfile-keys.list' +testequal --nomsg 'Version' sed '72q;d' tagfile-keys.list + +msgtest 'List has fewer entries than pkgTagSection buckets' 'tagfile-keys.list' +ENTRIES_LIST="$(wc -l tagfile-keys.list | cut -d' ' -f 1)" +ENTRIES_BUCKET="$(grep -m 1 'AlphaIndexes\[' "${SOURCEDIRECTORY}/apt-pkg/tagfile.h" | sed -e 's#.*\[\([0-9]\+\)\].*#\1#')" +if test $ENTRIES_LIST -lt $ENTRIES_BUCKET; then + msgpass +else + echo + echo "List has $ENTRIES_LIST entries, but pkgTagSection can only store $ENTRIES_BUCKET as AlphaIndexes" + msgfail +fi + +msgtest 'Check for duplicates in' 'tagfile-keys.list' +sort tagfile-keys.list > apt.lst +testempty --nomsg uniq --repeated 'apt.lst' + +msgtest 'Check that apt knows all fields it orders' 'itself' +grep -v "// NO_KEY: " "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -ne 's#^ "\(.*\)",.*$#\1#p' | sort -u > dpkg.lst +comparelsts + +msgtest 'Check tagfile-keys.list does not contain' 'obsoleted and internal fields' +grep "// NO_KEY: " "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -ne 's#^ "\(.*\)",.*$#\1#p' > obsolete.lst +sed -n -e's#^ *// *"\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" >> obsolete.lst +sort -u obsolete.lst > obsolete-sorted.lst +sort obsolete-sorted.lst tagfile-keys.list > obsolete-keys.lst +testempty --nomsg uniq --repeat 'obsolete-keys.lst' + msgtest 'Check that apt knows all fields dpkg orders in' 'Packages' dpkg_field_ordered_list 'CTRL_INDEX_PKG' > dpkg.lst -sed -ne 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort -u > apt.lst +sed -ne 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort > apt.lst comparelsts msgtest 'Check that apt knows all fields dpkg orders in' 'status' @@ -53,30 +90,31 @@ msgtest 'Check that apt knows all fields dpkg orders in' 'dsc' dpkg_field_ordered_list 'CTRL_PKG_SRC' > dpkg.lst comparelsts -# HACK, but there is no good way to acquire sources in tests and/or to remember to run this regular manually -if [ "$USER" = 'david' ]; then - msgtest 'Check if we have somewhere the sources of' 'dpkg' - DPKGSOURCE="$(locate dpkg/lib/dpkg/parse.c | head -n 1 || true)" - if [ -z "$DPKGSOURCE" ]; then - msgskip 'Not found' - else - msgpass - msgtest 'Check that apt knows about all fields' 'dpkg parses' - sed -n 's#^.*FIELD("\(.*\)").*$#\1#p' "${DPKGSOURCE}" | sort -u > dpkg.lst - sed -ne 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort -u > apt.lst - comparelsts - fi +DPKG_SOURCE_PARSE_C="${DPKG_SOURCE_DIRECTORY}/lib/dpkg/parse.c" +msgtest 'Compare our knowledge with the source code of' 'dpkg' +if [ -z "$DPKG_SOURCE_DIRECTORY" ]; then + msgskip 'source not provided' +elif [ ! -r "$DPKG_SOURCE_PARSE_C" ]; then + msgfail 'source not found' +else + msgpass + msgtest 'Check that apt knows about all fields' 'dpkg parses' + sed -n 's#^.*FIELD("\(.*\)").*$#\1#p' "${DPKG_SOURCE_PARSE_C}" | sort -u > dpkg.lst + sed -n -e's#^ *// *"# "#' -e 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sed -n '/^Package$/,/^Package$/ p' | head -n -1 | sort > apt.lst + comparelsts +fi - msgtest 'Check if we have somewhere the sources of' 'dak' - DAKSOURCE="$(locate dak/setup/core-init.d/080_metadatakeys | head -n 1 || true)" - if [ -z "$DAKSOURCE" ]; then - msgskip 'Not found' - else - msgpass - msgtest 'Check that apt knows about all fields' 'dak knows' - # dak mixes both, so we can only check with the mixed one as well - sed -ne "s#^.* VALUES ('\(.*\)', \(.*\)).*\$#\1 \2#p" "${DAKSOURCE}" | cut -d ' ' -f 1 | sort -u > dpkg.lst - sed -ne 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sort -u > apt.lst - comparelsts - fi +DAK_SOURCE_METADATAKEYS="${DAK_SOURCE_DIRECTORY}/setup/core-init.d/080_metadatakeys" +msgtest 'Compare our knowledge with the source code of' 'dak' +if [ -z "$DAK_SOURCE_DIRECTORY" ]; then + msgskip 'source not provided' +elif [ ! -r "$DAK_SOURCE_METADATAKEYS" ]; then + msgfail 'source not found' +else + msgpass + msgtest 'Check that apt knows about all fields' 'dak knows' + # dak mixes both, so we can only check with the mixed one as well + sed -ne "s#^.* VALUES ('\(.*\)', \(.*\)).*\$#\1 \2#p" "${DAK_SOURCE_METADATAKEYS}" | cut -d ' ' -f 1 | sort -u > dpkg.lst + sed -ne 's#^ "\(.*\)",.*$#\1#p' "${SOURCEDIRECTORY}/apt-pkg/tagfile-order.c" | sort -u > apt.lst + comparelsts fi diff --git a/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum b/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum index f0a8835a2..6a66094de 100755 --- a/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum +++ b/test/integration/test-ubuntu-bug-1098738-apt-get-source-md5sum @@ -441,4 +441,4 @@ testnohash pkg-md5-agree testfailureequal 'Reading package lists... E: Error parsing checksum in Files of source package pkg-md5-disagree' aptget source -d pkg-md5-disagree testfailureequal 'Reading package lists... -E: Error parsing checksum in Checksums-SHA256 of source package pkg-sha256-disagree' aptget source -d pkg-sha256-disagree +E: Error parsing checksum in Checksums-Sha256 of source package pkg-sha256-disagree' aptget source -d pkg-sha256-disagree |